summaryrefslogtreecommitdiffstats
path: root/src/tpm2
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/tpm2/ACT.h257
-rw-r--r--src/tpm2/ACTCommands.c81
-rw-r--r--src/tpm2/ACT_SetTimeout_fp.h79
-rw-r--r--src/tpm2/ACT_spt.c317
-rw-r--r--src/tpm2/ACT_spt_fp.h95
-rw-r--r--src/tpm2/ActivateCredential_fp.h88
-rw-r--r--src/tpm2/AlgorithmCap.c244
-rw-r--r--src/tpm2/AlgorithmCap_fp.h78
-rw-r--r--src/tpm2/AlgorithmTests.c964
-rw-r--r--src/tpm2/AlgorithmTests_fp.h73
-rw-r--r--src/tpm2/AsymmetricCommands.c299
-rw-r--r--src/tpm2/Attest_spt.c209
-rw-r--r--src/tpm2/Attest_spt_fp.h92
-rw-r--r--src/tpm2/AttestationCommands.c544
-rw-r--r--src/tpm2/AuditCommands.c112
-rw-r--r--src/tpm2/BackwardsCompatibility.h49
-rw-r--r--src/tpm2/BackwardsCompatibilityObject.c238
-rw-r--r--src/tpm2/BackwardsCompatibilityObject.h47
-rw-r--r--src/tpm2/BaseTypes.h85
-rw-r--r--src/tpm2/Bits.c114
-rw-r--r--src/tpm2/Bits_fp.h98
-rw-r--r--src/tpm2/BnConvert.c299
-rw-r--r--src/tpm2/BnMath.c651
-rw-r--r--src/tpm2/BnMemory.c205
-rw-r--r--src/tpm2/Cancel.c100
-rw-r--r--src/tpm2/Capabilities.h76
-rw-r--r--src/tpm2/CapabilityCommands.c215
-rw-r--r--src/tpm2/CertifyCreation_fp.h95
-rw-r--r--src/tpm2/CertifyX509_fp.h93
-rw-r--r--src/tpm2/Certify_fp.h93
-rw-r--r--src/tpm2/ChangeEPS_fp.h79
-rw-r--r--src/tpm2/ChangePPS_fp.h79
-rw-r--r--src/tpm2/ClearControl_fp.h79
-rw-r--r--src/tpm2/Clear_fp.h78
-rw-r--r--src/tpm2/Clock.c346
-rw-r--r--src/tpm2/ClockCommands.c109
-rw-r--r--src/tpm2/ClockRateAdjust_fp.h81
-rw-r--r--src/tpm2/ClockSet_fp.h81
-rw-r--r--src/tpm2/CommandAttributeData.h958
-rw-r--r--src/tpm2/CommandAttributes.h88
-rw-r--r--src/tpm2/CommandAudit.c262
-rw-r--r--src/tpm2/CommandAudit_fp.h97
-rw-r--r--src/tpm2/CommandCodeAttributes.c559
-rw-r--r--src/tpm2/CommandCodeAttributes_fp.h125
-rw-r--r--src/tpm2/CommandDispatchData.h4623
-rw-r--r--src/tpm2/CommandDispatcher.c409
-rw-r--r--src/tpm2/CommandDispatcher_fp.h75
-rw-r--r--src/tpm2/Commit_fp.h94
-rw-r--r--src/tpm2/CompilerDependencies.h193
-rw-r--r--src/tpm2/ContextCommands.c458
-rw-r--r--src/tpm2/ContextLoad_fp.h84
-rw-r--r--src/tpm2/ContextSave_fp.h84
-rw-r--r--src/tpm2/Context_spt.c204
-rw-r--r--src/tpm2/Context_spt_fp.h88
-rw-r--r--src/tpm2/CreateLoaded_fp.h90
-rw-r--r--src/tpm2/CreatePrimary_fp.h96
-rw-r--r--src/tpm2/Create_fp.h96
-rw-r--r--src/tpm2/CryptEccData.c618
-rw-r--r--src/tpm2/CryptSelfTest.c225
-rw-r--r--src/tpm2/CryptSelfTest_fp.h87
-rw-r--r--src/tpm2/CryptUtil.c1739
-rw-r--r--src/tpm2/DA.c240
-rw-r--r--src/tpm2/DA_fp.h87
-rw-r--r--src/tpm2/DebugHelpers.c160
-rw-r--r--src/tpm2/DebugHelpers_fp.h83
-rw-r--r--src/tpm2/DictionaryAttackLockReset_fp.h79
-rw-r--r--src/tpm2/DictionaryAttackParameters_fp.h86
-rw-r--r--src/tpm2/DictionaryCommands.c104
-rw-r--r--src/tpm2/Duplicate_fp.h91
-rw-r--r--src/tpm2/DuplicationCommands.c352
-rw-r--r--src/tpm2/EACommands.c1164
-rw-r--r--src/tpm2/ECC_Parameters_fp.h84
-rw-r--r--src/tpm2/ECDH_KeyGen_fp.h85
-rw-r--r--src/tpm2/ECDH_ZGen_fp.h86
-rw-r--r--src/tpm2/EC_Ephemeral_fp.h84
-rw-r--r--src/tpm2/EccTestData.h155
-rw-r--r--src/tpm2/EncryptDecrypt2_fp.h93
-rw-r--r--src/tpm2/EncryptDecrypt_fp.h93
-rw-r--r--src/tpm2/EncryptDecrypt_spt.c166
-rw-r--r--src/tpm2/EncryptDecrypt_spt_fp.h75
-rw-r--r--src/tpm2/Entity.c507
-rw-r--r--src/tpm2/Entity_fp.h90
-rw-r--r--src/tpm2/Entropy.c184
-rw-r--r--src/tpm2/EphemeralCommands.c190
-rw-r--r--src/tpm2/EventSequenceComplete_fp.h88
-rw-r--r--src/tpm2/EvictControl_fp.h82
-rw-r--r--src/tpm2/ExecCommand.c317
-rw-r--r--src/tpm2/ExecCommand_fp.h73
-rw-r--r--src/tpm2/FlushContext_fp.h78
-rw-r--r--src/tpm2/GetCapability_fp.h90
-rw-r--r--src/tpm2/GetCommandAuditDigest_fp.h91
-rw-r--r--src/tpm2/GetRandom_fp.h84
-rw-r--r--src/tpm2/GetSessionAuditDigest_fp.h93
-rw-r--r--src/tpm2/GetTestResult_fp.h79
-rw-r--r--src/tpm2/GetTime_fp.h91
-rw-r--r--src/tpm2/Global.c83
-rw-r--r--src/tpm2/Global.h1350
-rw-r--r--src/tpm2/GpMacros.h354
-rw-r--r--src/tpm2/HMAC_Start_fp.h88
-rw-r--r--src/tpm2/HMAC_fp.h88
-rw-r--r--src/tpm2/Handle.c213
-rw-r--r--src/tpm2/Handle_fp.h87
-rw-r--r--src/tpm2/HashCommands.c381
-rw-r--r--src/tpm2/HashSequenceStart_fp.h88
-rw-r--r--src/tpm2/HashTestData.h210
-rw-r--r--src/tpm2/Hash_fp.h89
-rw-r--r--src/tpm2/Hierarchy.c273
-rw-r--r--src/tpm2/HierarchyChangeAuth_fp.h80
-rw-r--r--src/tpm2/HierarchyCommands.c514
-rw-r--r--src/tpm2/HierarchyControl_fp.h83
-rw-r--r--src/tpm2/Hierarchy_fp.h93
-rw-r--r--src/tpm2/Import_fp.h93
-rw-r--r--src/tpm2/IncrementalSelfTest_fp.h84
-rw-r--r--src/tpm2/IntegrityCommands.c411
-rw-r--r--src/tpm2/InternalRoutines.h146
-rw-r--r--src/tpm2/IoBuffers.c145
-rw-r--r--src/tpm2/IoBuffers_fp.h87
-rw-r--r--src/tpm2/KdfTestData.h100
-rw-r--r--src/tpm2/LibtpmsCallbacks.c178
-rw-r--r--src/tpm2/LibtpmsCallbacks.h50
-rw-r--r--src/tpm2/LoadExternal_fp.h87
-rw-r--r--src/tpm2/Load_fp.h88
-rw-r--r--src/tpm2/Locality.c99
-rw-r--r--src/tpm2/LocalityPlat.c87
-rw-r--r--src/tpm2/Locality_fp.h71
-rw-r--r--src/tpm2/MAC_Start_fp.h88
-rw-r--r--src/tpm2/MAC_fp.h88
-rw-r--r--src/tpm2/MakeCredential_fp.h89
-rw-r--r--src/tpm2/ManagementCommands.c113
-rw-r--r--src/tpm2/Manufacture.c206
-rw-r--r--src/tpm2/Manufacture_fp.h81
-rw-r--r--src/tpm2/Marshal.c2313
-rw-r--r--src/tpm2/Marshal_fp.h400
-rw-r--r--src/tpm2/MathOnByteBuffers.c266
-rw-r--r--src/tpm2/MathOnByteBuffers_fp.h110
-rw-r--r--src/tpm2/Memory.c287
-rw-r--r--src/tpm2/Memory_fp.h139
-rw-r--r--src/tpm2/MinMax.h73
-rw-r--r--src/tpm2/NV.h162
-rw-r--r--src/tpm2/NVCommands.c707
-rw-r--r--src/tpm2/NVDynamic.c1679
-rw-r--r--src/tpm2/NVDynamic_fp.h253
-rw-r--r--src/tpm2/NVMarshal.c4916
-rw-r--r--src/tpm2/NVMarshal.h61
-rw-r--r--src/tpm2/NVMem.c494
-rw-r--r--src/tpm2/NVReserved.c230
-rw-r--r--src/tpm2/NVReserved_fp.h113
-rw-r--r--src/tpm2/NV_Certify_fp.h98
-rw-r--r--src/tpm2/NV_ChangeAuth_fp.h81
-rw-r--r--src/tpm2/NV_DefineSpace_fp.h83
-rw-r--r--src/tpm2/NV_Extend_fp.h83
-rw-r--r--src/tpm2/NV_GlobalWriteLock_fp.h79
-rw-r--r--src/tpm2/NV_Increment_fp.h81
-rw-r--r--src/tpm2/NV_ReadLock_fp.h81
-rw-r--r--src/tpm2/NV_ReadPublic_fp.h85
-rw-r--r--src/tpm2/NV_Read_fp.h89
-rw-r--r--src/tpm2/NV_SetBits_fp.h83
-rw-r--r--src/tpm2/NV_UndefineSpaceSpecial_fp.h81
-rw-r--r--src/tpm2/NV_UndefineSpace_fp.h81
-rw-r--r--src/tpm2/NV_WriteLock_fp.h81
-rw-r--r--src/tpm2/NV_Write_fp.h85
-rw-r--r--src/tpm2/NV_spt.c179
-rw-r--r--src/tpm2/NV_spt_fp.h87
-rw-r--r--src/tpm2/OIDs.h280
-rw-r--r--src/tpm2/Object.c970
-rw-r--r--src/tpm2/ObjectChangeAuth_fp.h89
-rw-r--r--src/tpm2/ObjectCommands.c549
-rw-r--r--src/tpm2/Object_fp.h236
-rw-r--r--src/tpm2/Object_spt.c1419
-rw-r--r--src/tpm2/Object_spt_fp.h250
-rw-r--r--src/tpm2/PCR.c1185
-rw-r--r--src/tpm2/PCR_Allocate_fp.h89
-rw-r--r--src/tpm2/PCR_Event_fp.h85
-rw-r--r--src/tpm2/PCR_Extend_fp.h81
-rw-r--r--src/tpm2/PCR_Read_fp.h85
-rw-r--r--src/tpm2/PCR_Reset_fp.h78
-rw-r--r--src/tpm2/PCR_SetAuthPolicy_fp.h85
-rw-r--r--src/tpm2/PCR_SetAuthValue_fp.h81
-rw-r--r--src/tpm2/PCR_fp.h197
-rw-r--r--src/tpm2/PP.c182
-rw-r--r--src/tpm2/PPPlat.c112
-rw-r--r--src/tpm2/PP_Commands_fp.h80
-rw-r--r--src/tpm2/PP_fp.h89
-rw-r--r--src/tpm2/PRNG_TestVectors.h110
-rw-r--r--src/tpm2/Platform.h75
-rw-r--r--src/tpm2/PlatformACT.c353
-rw-r--r--src/tpm2/PlatformACT.h210
-rw-r--r--src/tpm2/PlatformACT_fp.h104
-rw-r--r--src/tpm2/PlatformClock.h89
-rw-r--r--src/tpm2/PlatformData.c70
-rw-r--r--src/tpm2/PlatformData.h142
-rw-r--r--src/tpm2/Platform_fp.h407
-rw-r--r--src/tpm2/PolicyAuthValue_fp.h79
-rw-r--r--src/tpm2/PolicyAuthorizeNV_fp.h82
-rw-r--r--src/tpm2/PolicyAuthorize_fp.h86
-rw-r--r--src/tpm2/PolicyCommandCode_fp.h80
-rw-r--r--src/tpm2/PolicyCounterTimer_fp.h85
-rw-r--r--src/tpm2/PolicyCpHash_fp.h81
-rw-r--r--src/tpm2/PolicyDuplicationSelect_fp.h85
-rw-r--r--src/tpm2/PolicyGetDigest_fp.h84
-rw-r--r--src/tpm2/PolicyLocality_fp.h81
-rw-r--r--src/tpm2/PolicyNV_fp.h88
-rw-r--r--src/tpm2/PolicyNameHash_fp.h81
-rw-r--r--src/tpm2/PolicyNvWritten_fp.h81
-rw-r--r--src/tpm2/PolicyOR_fp.h81
-rw-r--r--src/tpm2/PolicyPCR_fp.h82
-rw-r--r--src/tpm2/PolicyPassword_fp.h79
-rw-r--r--src/tpm2/PolicyPhysicalPresence_fp.h78
-rw-r--r--src/tpm2/PolicyRestart_fp.h79
-rw-r--r--src/tpm2/PolicySecret_fp.h95
-rw-r--r--src/tpm2/PolicySigned_fp.h96
-rw-r--r--src/tpm2/PolicyTemplate_fp.h81
-rw-r--r--src/tpm2/PolicyTicket_fp.h89
-rw-r--r--src/tpm2/Policy_spt.c300
-rw-r--r--src/tpm2/Policy_spt_fp.h110
-rw-r--r--src/tpm2/Power.c109
-rw-r--r--src/tpm2/PowerPlat.c128
-rw-r--r--src/tpm2/Power_fp.h79
-rw-r--r--src/tpm2/PrimeData.c441
-rw-r--r--src/tpm2/PropertyCap.c610
-rw-r--r--src/tpm2/PropertyCap_fp.h74
-rw-r--r--src/tpm2/Quote_fp.h91
-rw-r--r--src/tpm2/RSA_Decrypt_fp.h90
-rw-r--r--src/tpm2/RSA_Encrypt_fp.h89
-rw-r--r--src/tpm2/RandomCommands.c94
-rw-r--r--src/tpm2/ReadClock_fp.h77
-rw-r--r--src/tpm2/ReadPublic_fp.h84
-rw-r--r--src/tpm2/Response.c105
-rw-r--r--src/tpm2/ResponseCodeProcessing.c81
-rw-r--r--src/tpm2/ResponseCodeProcessing_fp.h71
-rw-r--r--src/tpm2/Response_fp.h73
-rw-r--r--src/tpm2/Rewrap_fp.h92
-rw-r--r--src/tpm2/RsaTestData.h425
-rw-r--r--src/tpm2/RunCommand.c105
-rw-r--r--src/tpm2/SelfTest.h130
-rw-r--r--src/tpm2/SelfTest_fp.h78
-rw-r--r--src/tpm2/SequenceComplete_fp.h92
-rw-r--r--src/tpm2/SequenceUpdate_fp.h82
-rw-r--r--src/tpm2/Session.c835
-rw-r--r--src/tpm2/SessionCommands.c175
-rw-r--r--src/tpm2/SessionProcess.c1990
-rw-r--r--src/tpm2/SessionProcess_fp.h97
-rw-r--r--src/tpm2/Session_fp.h158
-rw-r--r--src/tpm2/SetAlgorithmSet_fp.h81
-rw-r--r--src/tpm2/SetCommandCodeAuditStatus_fp.h84
-rw-r--r--src/tpm2/SetPrimaryPolicy_fp.h80
-rw-r--r--src/tpm2/Shutdown_fp.h79
-rw-r--r--src/tpm2/Sign_fp.h89
-rw-r--r--src/tpm2/SigningCommands.c156
-rw-r--r--src/tpm2/Simulator_fp.h212
-rw-r--r--src/tpm2/StartAuthSession_fp.h97
-rw-r--r--src/tpm2/StartupCommands.c349
-rw-r--r--src/tpm2/Startup_fp.h84
-rw-r--r--src/tpm2/StateMarshal.c98
-rw-r--r--src/tpm2/StateMarshal.h53
-rw-r--r--src/tpm2/StirRandom_fp.h78
-rw-r--r--src/tpm2/SupportLibraryFunctionPrototypes_fp.h156
-rw-r--r--src/tpm2/SymmetricCommands.c350
-rw-r--r--src/tpm2/SymmetricTest.h138
-rw-r--r--src/tpm2/SymmetricTestData.h400
-rw-r--r--src/tpm2/TPMB.h97
-rw-r--r--src/tpm2/TPMCmdp.c364
-rw-r--r--src/tpm2/TcpServerPosix_fp.h131
-rw-r--r--src/tpm2/TestParms_fp.h79
-rw-r--r--src/tpm2/TestingCommands.c108
-rw-r--r--src/tpm2/Ticket.c236
-rw-r--r--src/tpm2/Ticket_fp.h104
-rw-r--r--src/tpm2/Time.c273
-rw-r--r--src/tpm2/Time_fp.h99
-rw-r--r--src/tpm2/Tpm.h81
-rw-r--r--src/tpm2/TpmAlgorithmDefines.h405
-rw-r--r--src/tpm2/TpmAsn1.c508
-rw-r--r--src/tpm2/TpmAsn1.h137
-rw-r--r--src/tpm2/TpmAsn1_fp.h152
-rw-r--r--src/tpm2/TpmBuildSwitches.h364
-rw-r--r--src/tpm2/TpmError.h84
-rw-r--r--src/tpm2/TpmFail.c527
-rw-r--r--src/tpm2/TpmFail_fp.h114
-rw-r--r--src/tpm2/TpmProfile.h865
-rw-r--r--src/tpm2/TpmSizeChecks.c229
-rw-r--r--src/tpm2/TpmSizeChecks_fp.h67
-rw-r--r--src/tpm2/TpmTcpProtocol.h140
-rw-r--r--src/tpm2/TpmTypes.h2473
-rw-r--r--src/tpm2/Unique.c109
-rw-r--r--src/tpm2/Unmarshal.c4532
-rw-r--r--src/tpm2/Unmarshal_fp.h477
-rw-r--r--src/tpm2/Unseal_fp.h83
-rw-r--r--src/tpm2/Utils.h54
-rw-r--r--src/tpm2/VendorString.h108
-rw-r--r--src/tpm2/Vendor_TCG_Test.c76
-rw-r--r--src/tpm2/Vendor_TCG_Test_fp.h79
-rw-r--r--src/tpm2/VerifySignature_fp.h88
-rw-r--r--src/tpm2/Volatile.c119
-rw-r--r--src/tpm2/Volatile.h47
-rw-r--r--src/tpm2/X509.h142
-rw-r--r--src/tpm2/X509_ECC.c173
-rw-r--r--src/tpm2/X509_ECC_fp.h83
-rw-r--r--src/tpm2/X509_RSA.c249
-rw-r--r--src/tpm2/X509_RSA_fp.h78
-rw-r--r--src/tpm2/X509_spt.c318
-rw-r--r--src/tpm2/X509_spt_fp.h98
-rw-r--r--src/tpm2/ZGen_2Phase_fp.h93
-rw-r--r--src/tpm2/_TPM_Hash_Data_fp.h72
-rw-r--r--src/tpm2/_TPM_Hash_End_fp.h71
-rw-r--r--src/tpm2/_TPM_Hash_Start_fp.h71
-rw-r--r--src/tpm2/_TPM_Init_fp.h73
-rw-r--r--src/tpm2/crypto/CryptCmac_fp.h86
-rw-r--r--src/tpm2/crypto/CryptDes_fp.h82
-rw-r--r--src/tpm2/crypto/CryptEcc.h103
-rw-r--r--src/tpm2/crypto/CryptEccCrypt_fp.h67
-rw-r--r--src/tpm2/crypto/CryptEccKeyExchange_fp.h78
-rw-r--r--src/tpm2/crypto/CryptEccMain_fp.h232
-rw-r--r--src/tpm2/crypto/CryptEccSignature_fp.h111
-rw-r--r--src/tpm2/crypto/CryptHash.h343
-rw-r--r--src/tpm2/crypto/CryptHash_fp.h219
-rw-r--r--src/tpm2/crypto/CryptPrimeSieve_fp.h101
-rw-r--r--src/tpm2/crypto/CryptPrime_fp.h104
-rw-r--r--src/tpm2/crypto/CryptRand.h193
-rw-r--r--src/tpm2/crypto/CryptRand_fp.h158
-rw-r--r--src/tpm2/crypto/CryptRsa.h99
-rw-r--r--src/tpm2/crypto/CryptRsa_fp.h139
-rw-r--r--src/tpm2/crypto/CryptSelfTest_fp.h87
-rw-r--r--src/tpm2/crypto/CryptSmac_fp.h98
-rw-r--r--src/tpm2/crypto/CryptSym.h142
-rw-r--r--src/tpm2/crypto/CryptSym_fp.h111
-rw-r--r--src/tpm2/crypto/CryptTest.h93
-rw-r--r--src/tpm2/crypto/CryptUtil_fp.h232
-rw-r--r--src/tpm2/crypto/openssl/BnConvert_fp.h108
-rw-r--r--src/tpm2/crypto/openssl/BnMath_fp.h163
-rw-r--r--src/tpm2/crypto/openssl/BnMemory_fp.h108
-rw-r--r--src/tpm2/crypto/openssl/BnValues.h329
-rw-r--r--src/tpm2/crypto/openssl/ConsttimeUtils.h117
-rw-r--r--src/tpm2/crypto/openssl/CryptCmac.c210
-rw-r--r--src/tpm2/crypto/openssl/CryptDes.c189
-rw-r--r--src/tpm2/crypto/openssl/CryptEccKeyExchange.c373
-rw-r--r--src/tpm2/crypto/openssl/CryptEccMain.c866
-rw-r--r--src/tpm2/crypto/openssl/CryptEccSignature.c1043
-rw-r--r--src/tpm2/crypto/openssl/CryptHash.c871
-rw-r--r--src/tpm2/crypto/openssl/CryptPrime.c440
-rw-r--r--src/tpm2/crypto/openssl/CryptPrimeSieve.c554
-rw-r--r--src/tpm2/crypto/openssl/CryptRand.c881
-rw-r--r--src/tpm2/crypto/openssl/CryptRsa.c1634
-rw-r--r--src/tpm2/crypto/openssl/CryptSmac.c156
-rw-r--r--src/tpm2/crypto/openssl/CryptSym.c771
-rw-r--r--src/tpm2/crypto/openssl/ExpDCache.c200
-rw-r--r--src/tpm2/crypto/openssl/ExpDCache_fp.h75
-rw-r--r--src/tpm2/crypto/openssl/Helpers.c625
-rw-r--r--src/tpm2/crypto/openssl/Helpers_fp.h117
-rw-r--r--src/tpm2/crypto/openssl/LibSupport.h98
-rw-r--r--src/tpm2/crypto/openssl/TpmToOsslDesSupport.c119
-rw-r--r--src/tpm2/crypto/openssl/TpmToOsslDesSupport_fp.h83
-rw-r--r--src/tpm2/crypto/openssl/TpmToOsslHash.h219
-rw-r--r--src/tpm2/crypto/openssl/TpmToOsslMath.c736
-rw-r--r--src/tpm2/crypto/openssl/TpmToOsslMath.h164
-rw-r--r--src/tpm2/crypto/openssl/TpmToOsslMath_fp.h152
-rw-r--r--src/tpm2/crypto/openssl/TpmToOsslSupport.c129
-rw-r--r--src/tpm2/crypto/openssl/TpmToOsslSupport_fp.h83
-rw-r--r--src/tpm2/crypto/openssl/TpmToOsslSym.h197
-rw-r--r--src/tpm2/crypto/openssl/consttime.txt76
-rw-r--r--src/tpm2/crypto/openssl/consttime.txt'58
-rwxr-xr-xsrc/tpm2/gensymtestsdata.sh195
-rw-r--r--src/tpm2/swap.h120
362 files changed, 93034 insertions, 0 deletions
diff --git a/src/tpm2/ACT.h b/src/tpm2/ACT.h
new file mode 100644
index 0000000..ec609af
--- /dev/null
+++ b/src/tpm2/ACT.h
@@ -0,0 +1,257 @@
+/********************************************************************************/
+/* */
+/* Authenticated Countdown Timer */
+/* Written by Ken Goldman */
+/* IBM Thomas J. Watson Research Center */
+/* $Id$ */
+/* */
+/* Licenses and Notices */
+/* */
+/* 1. Copyright Licenses: */
+/* */
+/* - Trusted Computing Group (TCG) grants to the user of the source code in */
+/* this specification (the "Source Code") a worldwide, irrevocable, */
+/* nonexclusive, royalty free, copyright license to reproduce, create */
+/* derivative works, distribute, display and perform the Source Code and */
+/* derivative works thereof, and to grant others the rights granted herein. */
+/* */
+/* - The TCG grants to the user of the other parts of the specification */
+/* (other than the Source Code) the rights to reproduce, distribute, */
+/* display, and perform the specification solely for the purpose of */
+/* developing products based on such documents. */
+/* */
+/* 2. Source Code Distribution Conditions: */
+/* */
+/* - Redistributions of Source Code must retain the above copyright licenses, */
+/* this list of conditions and the following disclaimers. */
+/* */
+/* - Redistributions in binary form must reproduce the above copyright */
+/* licenses, this list of conditions and the following disclaimers in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* 3. Disclaimers: */
+/* */
+/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
+/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
+/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
+/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
+/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
+/* information on specification licensing rights available through TCG */
+/* membership agreements. */
+/* */
+/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
+/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
+/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
+/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
+/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
+/* */
+/* - Without limitation, TCG and its members and licensors disclaim all */
+/* liability, including liability for infringement of any proprietary */
+/* rights, relating to use of information in this specification and to the */
+/* implementation of this specification, and TCG disclaims all liability for */
+/* cost of procurement of substitute goods or services, lost profits, loss */
+/* of use, loss of data or any incidental, consequential, direct, indirect, */
+/* or special damages, whether under contract, tort, warranty or otherwise, */
+/* arising in any way out of use or reliance upon this specification or any */
+/* information herein. */
+/* */
+/* (c) Copyright IBM Corp. and others, 2019 */
+/* */
+/********************************************************************************/
+
+// 5.24 ACT.h
+
+#ifndef _ACT_H_
+#define _ACT_H_
+#include "TpmProfile.h"
+#if !(defined RH_ACT_0) || (RH_ACT_0 != YES)
+# undef RH_ACT_0
+# define RH_ACT_0 NO
+# define IF_ACT_0_IMPLEMENTED(op)
+#else
+# define IF_ACT_0_IMPLEMENTED(op) op(0)
+#endif
+#if !(defined RH_ACT_1) || (RH_ACT_1 != YES)
+# undef RH_ACT_1
+# define RH_ACT_1 NO
+# define IF_ACT_1_IMPLEMENTED(op)
+#else
+# define IF_ACT_1_IMPLEMENTED(op) op(1)
+#endif
+#if !(defined RH_ACT_2) || (RH_ACT_2 != YES)
+# undef RH_ACT_2
+# define RH_ACT_2 NO
+# define IF_ACT_2_IMPLEMENTED(op)
+#else
+# define IF_ACT_2_IMPLEMENTED(op) op(2)
+#endif
+#if !(defined RH_ACT_3) || (RH_ACT_3 != YES)
+# undef RH_ACT_3
+# define RH_ACT_3 NO
+# define IF_ACT_3_IMPLEMENTED(op)
+#else
+# define IF_ACT_3_IMPLEMENTED(op) op(3)
+#endif
+#if !(defined RH_ACT_4) || (RH_ACT_4 != YES)
+# undef RH_ACT_4
+# define RH_ACT_4 NO
+# define IF_ACT_4_IMPLEMENTED(op)
+#else
+# define IF_ACT_4_IMPLEMENTED(op) op(4)
+#endif
+#if !(defined RH_ACT_5) || (RH_ACT_5 != YES)
+# undef RH_ACT_5
+# define RH_ACT_5 NO
+# define IF_ACT_5_IMPLEMENTED(op)
+#else
+# define IF_ACT_5_IMPLEMENTED(op) op(5)
+#endif
+#if !(defined RH_ACT_6) || (RH_ACT_6 != YES)
+# undef RH_ACT_6
+# define RH_ACT_6 NO
+# define IF_ACT_6_IMPLEMENTED(op)
+#else
+# define IF_ACT_6_IMPLEMENTED(op) op(6)
+#endif
+#if !(defined RH_ACT_7) || (RH_ACT_7 != YES)
+# undef RH_ACT_7
+# define RH_ACT_7 NO
+# define IF_ACT_7_IMPLEMENTED(op)
+#else
+# define IF_ACT_7_IMPLEMENTED(op) op(7)
+#endif
+#if !(defined RH_ACT_8) || (RH_ACT_8 != YES)
+# undef RH_ACT_8
+# define RH_ACT_8 NO
+# define IF_ACT_8_IMPLEMENTED(op)
+#else
+# define IF_ACT_8_IMPLEMENTED(op) op(8)
+#endif
+#if !(defined RH_ACT_9) || (RH_ACT_9 != YES)
+# undef RH_ACT_9
+# define RH_ACT_9 NO
+# define IF_ACT_9_IMPLEMENTED(op)
+#else
+# define IF_ACT_9_IMPLEMENTED(op) op(9)
+#endif
+#if !(defined RH_ACT_A) || (RH_ACT_A != YES)
+# undef RH_ACT_A
+# define RH_ACT_A NO
+# define IF_ACT_A_IMPLEMENTED(op)
+#else
+# define IF_ACT_A_IMPLEMENTED(op) op(A)
+#endif
+#if !(defined RH_ACT_B) || (RH_ACT_B != YES)
+# undef RH_ACT_B
+# define RH_ACT_B NO
+# define IF_ACT_B_IMPLEMENTED(op)
+#else
+# define IF_ACT_B_IMPLEMENTED(op) op(B)
+#endif
+#if !(defined RH_ACT_C) || (RH_ACT_C != YES)
+# undef RH_ACT_C
+# define RH_ACT_C NO
+# define IF_ACT_C_IMPLEMENTED(op)
+#else
+# define IF_ACT_C_IMPLEMENTED(op) op(C)
+#endif
+#if !(defined RH_ACT_D) || (RH_ACT_D != YES)
+# undef RH_ACT_D
+# define RH_ACT_D NO
+# define IF_ACT_D_IMPLEMENTED(op)
+#else
+# define IF_ACT_D_IMPLEMENTED(op) op(D)
+#endif
+#if !(defined RH_ACT_E) || (RH_ACT_E != YES)
+# undef RH_ACT_E
+# define RH_ACT_E NO
+# define IF_ACT_E_IMPLEMENTED(op)
+#else
+# define IF_ACT_E_IMPLEMENTED(op) op(E)
+#endif
+#if !(defined RH_ACT_F) || (RH_ACT_F != YES)
+# undef RH_ACT_F
+# define RH_ACT_F NO
+# define IF_ACT_F_IMPLEMENTED(op)
+#else
+# define IF_ACT_F_IMPLEMENTED(op) op(F)
+#endif
+#ifndef TPM_RH_ACT_0
+#error Need numeric definition for TPM_RH_ACT_0
+#endif
+#ifndef TPM_RH_ACT_1
+# define TPM_RH_ACT_1 (TPM_RH_ACT_0 + 1)
+#endif
+#ifndef TPM_RH_ACT_2
+# define TPM_RH_ACT_2 (TPM_RH_ACT_0 + 2)
+#endif
+#ifndef TPM_RH_ACT_3
+# define TPM_RH_ACT_3 (TPM_RH_ACT_0 + 3)
+#endif
+#ifndef TPM_RH_ACT_4
+# define TPM_RH_ACT_4 (TPM_RH_ACT_0 + 4)
+#endif
+#ifndef TPM_RH_ACT_5
+# define TPM_RH_ACT_5 (TPM_RH_ACT_0 + 5)
+#endif
+#ifndef TPM_RH_ACT_6
+# define TPM_RH_ACT_6 (TPM_RH_ACT_0 + 6)
+#endif
+#ifndef TPM_RH_ACT_7
+# define TPM_RH_ACT_7 (TPM_RH_ACT_0 + 7)
+#endif
+#ifndef TPM_RH_ACT_8
+# define TPM_RH_ACT_8 (TPM_RH_ACT_0 + 8)
+#endif
+#ifndef TPM_RH_ACT_9
+# define TPM_RH_ACT_9 (TPM_RH_ACT_0 + 9)
+#endif
+#ifndef TPM_RH_ACT_A
+# define TPM_RH_ACT_A (TPM_RH_ACT_0 + 0xA)
+#endif
+#ifndef TPM_RH_ACT_B
+# define TPM_RH_ACT_B (TPM_RH_ACT_0 + 0xB)
+#endif
+#ifndef TPM_RH_ACT_C
+# define TPM_RH_ACT_C (TPM_RH_ACT_0 + 0xC)
+#endif
+#ifndef TPM_RH_ACT_D
+# define TPM_RH_ACT_D (TPM_RH_ACT_0 + 0xD)
+#endif
+#ifndef TPM_RH_ACT_E
+# define TPM_RH_ACT_E (TPM_RH_ACT_0 + 0xE)
+#endif
+#ifndef TPM_RH_ACT_F
+# define TPM_RH_ACT_F (TPM_RH_ACT_0 + 0xF)
+#endif
+#define FOR_EACH_ACT(op) \
+ IF_ACT_0_IMPLEMENTED(op) \
+ IF_ACT_1_IMPLEMENTED(op) \
+ IF_ACT_2_IMPLEMENTED(op) \
+ IF_ACT_3_IMPLEMENTED(op) \
+ IF_ACT_4_IMPLEMENTED(op) \
+ IF_ACT_5_IMPLEMENTED(op) \
+ IF_ACT_6_IMPLEMENTED(op) \
+ IF_ACT_7_IMPLEMENTED(op) \
+ IF_ACT_8_IMPLEMENTED(op) \
+ IF_ACT_9_IMPLEMENTED(op) \
+ IF_ACT_A_IMPLEMENTED(op) \
+ IF_ACT_B_IMPLEMENTED(op) \
+ IF_ACT_C_IMPLEMENTED(op) \
+ IF_ACT_D_IMPLEMENTED(op) \
+ IF_ACT_E_IMPLEMENTED(op) \
+ IF_ACT_F_IMPLEMENTED(op)
+
+// This is the mask for ACT that are implemented
+
+//#define ACT_MASK(N) | (1 << 0x##N)
+//#define ACT_IMPLEMENTED_MASK (0 FOR_EACH_ACT(ACT_MASK))
+#define CASE_ACT_HANDLE(N) case TPM_RH_ACT_##N:
+#define CASE_ACT_NUMBER(N) case 0x##N:
+typedef struct ACT_STATE
+{
+ UINT32 remaining;
+ TPM_ALG_ID hashAlg;
+ TPM2B_DIGEST authPolicy;
+} ACT_STATE, *P_ACT_STATE;
+#endif // _ACT_H_
diff --git a/src/tpm2/ACTCommands.c b/src/tpm2/ACTCommands.c
new file mode 100644
index 0000000..7a66db7
--- /dev/null
+++ b/src/tpm2/ACTCommands.c
@@ -0,0 +1,81 @@
+/********************************************************************************/
+/* */
+/* Authenticated COuntdown Timer Commands */
+/* Written by Ken Goldman */
+/* IBM Thomas J. Watson Research Center */
+/* $Id$ */
+/* */
+/* Licenses and Notices */
+/* */
+/* 1. Copyright Licenses: */
+/* */
+/* - Trusted Computing Group (TCG) grants to the user of the source code in */
+/* this specification (the "Source Code") a worldwide, irrevocable, */
+/* nonexclusive, royalty free, copyright license to reproduce, create */
+/* derivative works, distribute, display and perform the Source Code and */
+/* derivative works thereof, and to grant others the rights granted herein. */
+/* */
+/* - The TCG grants to the user of the other parts of the specification */
+/* (other than the Source Code) the rights to reproduce, distribute, */
+/* display, and perform the specification solely for the purpose of */
+/* developing products based on such documents. */
+/* */
+/* 2. Source Code Distribution Conditions: */
+/* */
+/* - Redistributions of Source Code must retain the above copyright licenses, */
+/* this list of conditions and the following disclaimers. */
+/* */
+/* - Redistributions in binary form must reproduce the above copyright */
+/* licenses, this list of conditions and the following disclaimers in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* 3. Disclaimers: */
+/* */
+/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
+/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
+/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
+/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
+/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
+/* information on specification licensing rights available through TCG */
+/* membership agreements. */
+/* */
+/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
+/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
+/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
+/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
+/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
+/* */
+/* - Without limitation, TCG and its members and licensors disclaim all */
+/* liability, including liability for infringement of any proprietary */
+/* rights, relating to use of information in this specification and to the */
+/* implementation of this specification, and TCG disclaims all liability for */
+/* cost of procurement of substitute goods or services, lost profits, loss */
+/* of use, loss of data or any incidental, consequential, direct, indirect, */
+/* or special damages, whether under contract, tort, warranty or otherwise, */
+/* arising in any way out of use or reliance upon this specification or any */
+/* information herein. */
+/* */
+/* (c) Copyright IBM Corp. and others, 2019 */
+/* */
+/********************************************************************************/
+
+#include "Tpm.h"
+#include "ACT_SetTimeout_fp.h"
+#if CC_ACT_SetTimeout // Conditional expansion of this file
+
+/* Error Returns Meaning */
+/* TPM_RC_RETRY returned when an update for the selected ACT is already pending */
+/* TPM_RC_VALUE attempt to disable signaling from an ACT that has not expired */
+TPM_RC
+TPM2_ACT_SetTimeout(
+ ACT_SetTimeout_In *in // IN: input parameter list
+ )
+{
+ // If 'startTimeout' is UINT32_MAX, then this is an attempt to disable the ACT
+ // and turn off the signaling for the ACT. This is only valid if the ACT
+ // is signaling.
+ if((in->startTimeout == UINT32_MAX) && !ActGetSignaled(in->actHandle))
+ return TPM_RC_VALUE + RC_ACT_SetTimeout_startTimeout;
+ return ActCounterUpdate(in->actHandle, in->startTimeout);
+}
+#endif // CC_ACT_SetTimeout
diff --git a/src/tpm2/ACT_SetTimeout_fp.h b/src/tpm2/ACT_SetTimeout_fp.h
new file mode 100644
index 0000000..8137538
--- /dev/null
+++ b/src/tpm2/ACT_SetTimeout_fp.h
@@ -0,0 +1,79 @@
+/********************************************************************************/
+/* */
+/* TPM2_ACT_SetTimeout Header */
+/* Written by Ken Goldman */
+/* IBM Thomas J. Watson Research Center */
+/* $Id$ */
+/* */
+/* Licenses and Notices */
+/* */
+/* 1. Copyright Licenses: */
+/* */
+/* - Trusted Computing Group (TCG) grants to the user of the source code in */
+/* this specification (the "Source Code") a worldwide, irrevocable, */
+/* nonexclusive, royalty free, copyright license to reproduce, create */
+/* derivative works, distribute, display and perform the Source Code and */
+/* derivative works thereof, and to grant others the rights granted herein. */
+/* */
+/* - The TCG grants to the user of the other parts of the specification */
+/* (other than the Source Code) the rights to reproduce, distribute, */
+/* display, and perform the specification solely for the purpose of */
+/* developing products based on such documents. */
+/* */
+/* 2. Source Code Distribution Conditions: */
+/* */
+/* - Redistributions of Source Code must retain the above copyright licenses, */
+/* this list of conditions and the following disclaimers. */
+/* */
+/* - Redistributions in binary form must reproduce the above copyright */
+/* licenses, this list of conditions and the following disclaimers in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* 3. Disclaimers: */
+/* */
+/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
+/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
+/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
+/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
+/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
+/* information on specification licensing rights available through TCG */
+/* membership agreements. */
+/* */
+/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
+/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
+/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
+/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
+/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
+/* */
+/* - Without limitation, TCG and its members and licensors disclaim all */
+/* liability, including liability for infringement of any proprietary */
+/* rights, relating to use of information in this specification and to the */
+/* implementation of this specification, and TCG disclaims all liability for */
+/* cost of procurement of substitute goods or services, lost profits, loss */
+/* of use, loss of data or any incidental, consequential, direct, indirect, */
+/* or special damages, whether under contract, tort, warranty or otherwise, */
+/* arising in any way out of use or reliance upon this specification or any */
+/* information herein. */
+/* */
+/* (c) Copyright IBM Corp. and others, 2019 */
+/* */
+/********************************************************************************/
+
+#ifndef ACT_SETTIMEOUT_FP_H
+#define ACT_SETTIMEOUT_FP_H
+
+typedef struct {
+ TPMI_RH_ACT actHandle;
+ UINT32 startTimeout;
+} ACT_SetTimeout_In;
+
+#define RC_ACT_SetTimeout_actHandle (TPM_RC_H + TPM_RC_1)
+#define RC_ACT_SetTimeout_startTimeout (TPM_RC_H + TPM_RC_2)
+
+TPM_RC
+TPM2_ACT_SetTimeout(
+ ACT_SetTimeout_In *in // IN: input parameter list
+ );
+
+
+#endif
diff --git a/src/tpm2/ACT_spt.c b/src/tpm2/ACT_spt.c
new file mode 100644
index 0000000..5b19c85
--- /dev/null
+++ b/src/tpm2/ACT_spt.c
@@ -0,0 +1,317 @@
+/********************************************************************************/
+/* */
+/* ACT Command Support */
+/* Written by Ken Goldman */
+/* IBM Thomas J. Watson Research Center */
+/* $Id: Object_spt.c 1490 2019-07-26 21:13:22Z kgoldman $ */
+/* */
+/* Licenses and Notices */
+/* */
+/* 1. Copyright Licenses: */
+/* */
+/* - Trusted Computing Group (TCG) grants to the user of the source code in */
+/* this specification (the "Source Code") a worldwide, irrevocable, */
+/* nonexclusive, royalty free, copyright license to reproduce, create */
+/* derivative works, distribute, display and perform the Source Code and */
+/* derivative works thereof, and to grant others the rights granted herein. */
+/* */
+/* - The TCG grants to the user of the other parts of the specification */
+/* (other than the Source Code) the rights to reproduce, distribute, */
+/* display, and perform the specification solely for the purpose of */
+/* developing products based on such documents. */
+/* */
+/* 2. Source Code Distribution Conditions: */
+/* */
+/* - Redistributions of Source Code must retain the above copyright licenses, */
+/* this list of conditions and the following disclaimers. */
+/* */
+/* - Redistributions in binary form must reproduce the above copyright */
+/* licenses, this list of conditions and the following disclaimers in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* 3. Disclaimers: */
+/* */
+/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
+/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
+/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
+/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
+/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
+/* information on specification licensing rights available through TCG */
+/* membership agreements. */
+/* */
+/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
+/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
+/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
+/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
+/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
+/* */
+/* - Without limitation, TCG and its members and licensors disclaim all */
+/* liability, including liability for infringement of any proprietary */
+/* rights, relating to use of information in this specification and to the */
+/* implementation of this specification, and TCG disclaims all liability for */
+/* cost of procurement of substitute goods or services, lost profits, loss */
+/* of use, loss of data or any incidental, consequential, direct, indirect, */
+/* or special damages, whether under contract, tort, warranty or otherwise, */
+/* arising in any way out of use or reliance upon this specification or any */
+/* information herein. */
+/* */
+/* (c) Copyright IBM Corp. and others, 2016 - 2020 */
+/* */
+/********************************************************************************/
+
+/* 7.8 ACT Support (ACT_spt.c) */
+/* 7.8.1 Introduction */
+/* This code implements the ACT update code. It does not use a mutex. This code uses a platform
+ service (_plat__ACT_UpdateCounter()) that returns false if the update is not accepted. If this
+ occurs, then TPM_RC_RETRY should be sent to the caller so that they can retry the operation
+ later. The implementation of this is platform dependent but the reference uses a simple flag to
+ indicate that an update is pending and the only process that can clear that flag is the process
+ that does the actual update. */
+
+/* 7.8.2 Includes */
+
+#include "Tpm.h"
+#include "ACT_spt_fp.h"
+#include "Platform_fp.h"
+#include "PlatformACT_fp.h" /* added kgold */
+
+/* 7.8.3 Functions */
+/* 7.8.3.1 _ActResume() */
+/* This function does the resume processing for an ACT. It updates the saved count and turns
+ signaling back on if necessary. */
+#ifndef __ACT_DISABLED // libtpms added
+static void
+_ActResume(
+ UINT32 act, //IN: the act number
+ ACT_STATE *actData //IN: pointer to the saved ACT data
+ )
+{
+ // If the act was non-zero, then restore the counter value.
+ if(actData->remaining > 0)
+ _plat__ACT_UpdateCounter(act, actData->remaining);
+ // if the counter was zero and the ACT signaling, enable the signaling.
+ else if(go.signaledACT & (1 << act))
+ _plat__ACT_SetSignaled(act, TRUE);
+}
+#endif // libtpms added
+/* 7.8.3.2 ActStartup() */
+/* This function is called by TPM2_Startup() to initialize the ACT counter values. */
+BOOL
+ActStartup(
+ STARTUP_TYPE type
+ )
+{
+ // Reset all the ACT hardware
+ _plat__ACT_Initialize();
+
+ // If this not a cold start, copy all the current 'signaled' settings to
+ // 'preservedSignaled'.
+#ifndef __ACT_DISABLED // libtpms added
+ if (g_powerWasLost)
+ go.preservedSignaled = 0;
+ else
+ go.preservedSignaled |= go.signaledACT;
+#endif // libtpms added
+
+ // For TPM_RESET or TPM_RESTART, the ACTs will all be disabled and the output
+ // de-asserted.
+ if(type != SU_RESUME)
+ {
+#ifndef __ACT_DISABLED // libtpms added
+ go.signaledACT = 0;
+#endif // libtpms added
+#define CLEAR_ACT_POLICY(N) \
+ go.ACT_##N.hashAlg = TPM_ALG_NULL; \
+ go.ACT_##N.authPolicy.b.size = 0;
+
+ FOR_EACH_ACT(CLEAR_ACT_POLICY)
+
+ }
+ else
+ {
+ // Resume each of the implemented ACT
+#define RESUME_ACT(N) _ActResume(0x##N, &go.ACT_##N);
+
+ FOR_EACH_ACT(RESUME_ACT)
+ }
+ // set no ACT updated since last startup. This is to enable the halving of the
+ // timeout value
+ s_ActUpdated = 0;
+ _plat__ACT_EnableTicks(TRUE);
+ return TRUE;
+}
+/* 7.8.3.3 _ActSaveState() */
+/* Get the counter state and the signaled state for an ACT. If the ACT has not been updated since
+ the last time it was saved, then divide the count by 2. */
+#ifndef __ACT_DISABLED // libtpms added
+static void
+_ActSaveState(
+ UINT32 act,
+ P_ACT_STATE actData
+ )
+{
+ actData->remaining = _plat__ACT_GetRemaining(act);
+ // If the ACT hasn't been updated since the last startup, then it should be
+ // be halved.
+ if((s_ActUpdated & (1 << act)) == 0)
+ {
+ // Don't halve if the count is set to max or if halving would make it zero
+ if((actData->remaining != UINT32_MAX) && (actData->remaining > 1))
+ actData->remaining /= 2;
+ }
+ if(_plat__ACT_GetSignaled(act))
+ go.signaledACT |= (1 << act);
+}
+/* 7.8.3.4 ActGetSignaled() */
+/* This function returns the state of the signaled flag associated with an ACT. */
+BOOL
+ActGetSignaled(
+ TPM_RH actHandle
+ )
+{
+ UINT32 act = actHandle - TPM_RH_ACT_0;
+ //
+ return _plat__ACT_GetSignaled(act);
+}
+#endif // libtpms added
+/* 7.8.3.5 ActShutdown() */
+/* This function saves the current state of the counters */
+BOOL
+ActShutdown(
+ TPM_SU state //IN: the type of the shutdown.
+ )
+{
+ // if this is not shutdown state, then the only type of startup is TPM_RESTART
+ // so the timer values will be cleared. If this is shutdown state, get the current
+ // countdown and signaled values. Plus, if the counter has not been updated
+ // since the last restart, divide the time by 2 so that there is no attack on the
+ // countdown by saving the countdown state early and then not using the TPM.
+ if(state == TPM_SU_STATE)
+ {
+ // This will be populated as each of the ACT is queried
+#ifndef __ACT_DISABLED // libtpms added
+ go.signaledACT = 0;
+#endif // libtpms added
+ // Get the current count and the signaled state
+#define SAVE_ACT_STATE(N) _ActSaveState(0x##N, &go.ACT_##N);
+
+ FOR_EACH_ACT(SAVE_ACT_STATE);
+ }
+ return TRUE;
+}
+/* 7.8.3.6 ActIsImplemented() */
+/* This function determines if an ACT is implemented in both the TPM and the platform code. */
+BOOL
+ActIsImplemented(
+ UINT32 act
+ )
+{
+#define CASE_ACT_
+ // This switch accounts for the TPM implemented values.
+ switch(act)
+ {
+#ifndef __ACT_DISABLED // libtpms added
+ FOR_EACH_ACT(CASE_ACT_NUMBER)
+ // This ensures that the platorm implemented the values implemented by
+ // the TPM
+ return _plat__ACT_GetImplemented(act);
+#endif // libtpms added
+ default:
+ break;
+ }
+ return FALSE;
+}
+/* 7.8.3.7 ActCounterUpdate() */
+/* This function updates the ACT counter. If the counter already has a pending update, it returns
+ TPM_RC_RETRY so that the update can be tried again later. */
+#if CC_ACT_SetTimeout // libtpms added
+TPM_RC
+ActCounterUpdate(
+ TPM_RH handle, //IN: the handle of the act
+ UINT32 newValue //IN: the value to set in the ACT
+ )
+{
+ UINT32 act;
+ TPM_RC result;
+ //
+ act = handle - TPM_RH_ACT_0;
+ // This should never fail, but...
+ if(!_plat__ACT_GetImplemented(act))
+ result = TPM_RC_VALUE;
+ else
+ {
+ // Will need to clear orderly so fail if we are orderly and NV is not available
+ if(NV_IS_ORDERLY)
+ RETURN_IF_NV_IS_NOT_AVAILABLE;
+ // if the attempt to update the counter fails, it means that there is an
+ // update pending so wait until it has occurred and then do an update.
+ if(!_plat__ACT_UpdateCounter(act, newValue))
+ result = TPM_RC_RETRY;
+ else
+ {
+ // Indicate that the ACT has been updated since last TPM2_Startup().
+ s_ActUpdated |= (UINT16)(1 << act);
+
+ // Clear the preservedSignaled attribute.
+ go.preservedSignaled &= ~((UINT16)(1 << act));
+
+ // Need to clear the orderly flag
+ g_clearOrderly = TRUE;
+
+ result = TPM_RC_SUCCESS;
+ }
+ }
+ return result;
+}
+#endif // libtpms added
+/* 7.8.3.8 ActGetCapabilityData() */
+/* This function returns the list of ACT data */
+/* Return Value Meaning */
+/* YES if more ACT data is available */
+/* NO if no more ACT data to */
+TPMI_YES_NO
+ActGetCapabilityData(
+ TPM_HANDLE actHandle, // IN: the handle for the starting ACT
+ UINT32 maxCount, // IN: maximum allowed return values
+ TPML_ACT_DATA *actList // OUT: ACT data list
+ )
+{
+ // Initialize output property list
+ actList->count = 0;
+
+ // Make sure that the starting handle value is in range (again)
+ if((actHandle < TPM_RH_ACT_0) || (actHandle > TPM_RH_ACT_F))
+ return FALSE;
+ // The maximum count of curves we may return is MAX_ECC_CURVES
+ if(maxCount > MAX_ACT_DATA)
+ maxCount = MAX_ACT_DATA;
+ // Scan the ACT data from the starting ACT
+ for(; actHandle <= TPM_RH_ACT_F; actHandle++)
+ {
+ UINT32 act = actHandle - TPM_RH_ACT_0;
+ if(actList->count < maxCount)
+ {
+ if(ActIsImplemented(act))
+ {
+ TPMS_ACT_DATA *actData = &actList->actData[actList->count];
+ //
+ memset(&actData->attributes, 0, sizeof(actData->attributes));
+ actData->handle = actHandle;
+ actData->timeout = _plat__ACT_GetRemaining(act);
+ if (_plat__ACT_GetSignaled(act))
+ SET_ATTRIBUTE(actData->attributes, TPMA_ACT, signaled);
+ else
+ CLEAR_ATTRIBUTE(actData->attributes, TPMA_ACT, signaled);
+ actList->count++;
+ }
+ }
+ else
+ {
+ if(_plat__ACT_GetImplemented(act))
+ return YES;
+ }
+ }
+ // If we get here, either all of the ACT values were put in the list, or the list
+ // was filled and there are no more ACT values to return
+ return NO;
+}
diff --git a/src/tpm2/ACT_spt_fp.h b/src/tpm2/ACT_spt_fp.h
new file mode 100644
index 0000000..380e9fb
--- /dev/null
+++ b/src/tpm2/ACT_spt_fp.h
@@ -0,0 +1,95 @@
+/********************************************************************************/
+/* */
+/* ACT Command Support */
+/* Written by Ken Goldman */
+/* IBM Thomas J. Watson Research Center */
+/* $Id$ */
+/* */
+/* Licenses and Notices */
+/* */
+/* 1. Copyright Licenses: */
+/* */
+/* - Trusted Computing Group (TCG) grants to the user of the source code in */
+/* this specification (the "Source Code") a worldwide, irrevocable, */
+/* nonexclusive, royalty free, copyright license to reproduce, create */
+/* derivative works, distribute, display and perform the Source Code and */
+/* derivative works thereof, and to grant others the rights granted herein. */
+/* */
+/* - The TCG grants to the user of the other parts of the specification */
+/* (other than the Source Code) the rights to reproduce, distribute, */
+/* display, and perform the specification solely for the purpose of */
+/* developing products based on such documents. */
+/* */
+/* 2. Source Code Distribution Conditions: */
+/* */
+/* - Redistributions of Source Code must retain the above copyright licenses, */
+/* this list of conditions and the following disclaimers. */
+/* */
+/* - Redistributions in binary form must reproduce the above copyright */
+/* licenses, this list of conditions and the following disclaimers in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* 3. Disclaimers: */
+/* */
+/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
+/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
+/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
+/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
+/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
+/* information on specification licensing rights available through TCG */
+/* membership agreements. */
+/* */
+/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
+/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
+/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
+/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
+/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
+/* */
+/* - Without limitation, TCG and its members and licensors disclaim all */
+/* liability, including liability for infringement of any proprietary */
+/* rights, relating to use of information in this specification and to the */
+/* implementation of this specification, and TCG disclaims all liability for */
+/* cost of procurement of substitute goods or services, lost profits, loss */
+/* of use, loss of data or any incidental, consequential, direct, indirect, */
+/* or special damages, whether under contract, tort, warranty or otherwise, */
+/* arising in any way out of use or reliance upon this specification or any */
+/* information herein. */
+/* */
+/* (c) Copyright IBM Corp. and others, 2019 */
+/* */
+/********************************************************************************/
+
+#ifndef ACT_SPT_FP_H
+#define ACT_SPT_FP_H
+
+BOOL
+ActStartup(
+ STARTUP_TYPE type
+ );
+BOOL
+ActGetSignaled(
+ TPM_RH actHandle
+ );
+BOOL
+ActShutdown(
+ TPM_SU state //IN: the type of the shutdown.
+ );
+BOOL
+ActIsImplemented(
+ UINT32 act
+ );
+TPM_RC
+ActCounterUpdate(
+ TPM_RH handle, //IN: the handle of the act
+ UINT32 newValue //IN: the value to set in the ACT
+ );
+TPMI_YES_NO
+ActGetCapabilityData(
+ TPM_HANDLE actHandle, // IN: the handle for the starting ACT
+ UINT32 maxCount, // IN: maximum allowed return values
+ TPML_ACT_DATA *actList // OUT: ACT data list
+ );
+
+
+
+#endif
diff --git a/src/tpm2/ActivateCredential_fp.h b/src/tpm2/ActivateCredential_fp.h
new file mode 100644
index 0000000..841d117
--- /dev/null
+++ b/src/tpm2/ActivateCredential_fp.h
@@ -0,0 +1,88 @@
+/********************************************************************************/
+/* */
+/* */
+/* Written by Ken Goldman */
+/* IBM Thomas J. Watson Research Center */
+/* $Id: ActivateCredential_fp.h 809 2016-11-16 18:31:54Z kgoldman $ */
+/* */
+/* Licenses and Notices */
+/* */
+/* 1. Copyright Licenses: */
+/* */
+/* - Trusted Computing Group (TCG) grants to the user of the source code in */
+/* this specification (the "Source Code") a worldwide, irrevocable, */
+/* nonexclusive, royalty free, copyright license to reproduce, create */
+/* derivative works, distribute, display and perform the Source Code and */
+/* derivative works thereof, and to grant others the rights granted herein. */
+/* */
+/* - The TCG grants to the user of the other parts of the specification */
+/* (other than the Source Code) the rights to reproduce, distribute, */
+/* display, and perform the specification solely for the purpose of */
+/* developing products based on such documents. */
+/* */
+/* 2. Source Code Distribution Conditions: */
+/* */
+/* - Redistributions of Source Code must retain the above copyright licenses, */
+/* this list of conditions and the following disclaimers. */
+/* */
+/* - Redistributions in binary form must reproduce the above copyright */
+/* licenses, this list of conditions and the following disclaimers in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* 3. Disclaimers: */
+/* */
+/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
+/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
+/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
+/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
+/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
+/* information on specification licensing rights available through TCG */
+/* membership agreements. */
+/* */
+/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
+/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
+/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
+/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
+/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
+/* */
+/* - Without limitation, TCG and its members and licensors disclaim all */
+/* liability, including liability for infringement of any proprietary */
+/* rights, relating to use of information in this specification and to the */
+/* implementation of this specification, and TCG disclaims all liability for */
+/* cost of procurement of substitute goods or services, lost profits, loss */
+/* of use, loss of data or any incidental, consequential, direct, indirect, */
+/* or special damages, whether under contract, tort, warranty or otherwise, */
+/* arising in any way out of use or reliance upon this specification or any */
+/* information herein. */
+/* */
+/* (c) Copyright IBM Corp. and others, 2012-2015 */
+/* */
+/********************************************************************************/
+
+/* rev 119 */
+
+#ifndef ACTIVATECREDENTIAL_FP_H
+#define ACTIVATECREDENTIAL_FP_H
+
+typedef struct {
+ TPMI_DH_OBJECT activateHandle;
+ TPMI_DH_OBJECT keyHandle;
+ TPM2B_ID_OBJECT credentialBlob;
+ TPM2B_ENCRYPTED_SECRET secret;
+} ActivateCredential_In;
+
+#define RC_ActivateCredential_activateHandle (TPM_RC_H + TPM_RC_1)
+#define RC_ActivateCredential_keyHandle (TPM_RC_H + TPM_RC_2)
+#define RC_ActivateCredential_credentialBlob (TPM_RC_P + TPM_RC_1)
+#define RC_ActivateCredential_secret (TPM_RC_P + TPM_RC_2)
+
+typedef struct {
+ TPM2B_DIGEST certInfo;
+} ActivateCredential_Out;
+
+TPM_RC
+TPM2_ActivateCredential(
+ ActivateCredential_In *in, // IN: input parameter list
+ ActivateCredential_Out *out // OUT: output parameter list
+ );
+#endif
diff --git a/src/tpm2/AlgorithmCap.c b/src/tpm2/AlgorithmCap.c
new file mode 100644
index 0000000..a186280
--- /dev/null
+++ b/src/tpm2/AlgorithmCap.c
@@ -0,0 +1,244 @@
+/********************************************************************************/
+/* */
+/* Algorithm Property Definitions */
+/* Written by Ken Goldman */
+/* IBM Thomas J. Watson Research Center */
+/* $Id: AlgorithmCap.c 1594 2020-03-26 22:15:48Z kgoldman $ */
+/* */
+/* Licenses and Notices */
+/* */
+/* 1. Copyright Licenses: */
+/* */
+/* - Trusted Computing Group (TCG) grants to the user of the source code in */
+/* this specification (the "Source Code") a worldwide, irrevocable, */
+/* nonexclusive, royalty free, copyright license to reproduce, create */
+/* derivative works, distribute, display and perform the Source Code and */
+/* derivative works thereof, and to grant others the rights granted herein. */
+/* */
+/* - The TCG grants to the user of the other parts of the specification */
+/* (other than the Source Code) the rights to reproduce, distribute, */
+/* display, and perform the specification solely for the purpose of */
+/* developing products based on such documents. */
+/* */
+/* 2. Source Code Distribution Conditions: */
+/* */
+/* - Redistributions of Source Code must retain the above copyright licenses, */
+/* this list of conditions and the following disclaimers. */
+/* */
+/* - Redistributions in binary form must reproduce the above copyright */
+/* licenses, this list of conditions and the following disclaimers in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* 3. Disclaimers: */
+/* */
+/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
+/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
+/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
+/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
+/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
+/* information on specification licensing rights available through TCG */
+/* membership agreements. */
+/* */
+/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
+/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
+/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
+/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
+/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
+/* */
+/* - Without limitation, TCG and its members and licensors disclaim all */
+/* liability, including liability for infringement of any proprietary */
+/* rights, relating to use of information in this specification and to the */
+/* implementation of this specification, and TCG disclaims all liability for */
+/* cost of procurement of substitute goods or services, lost profits, loss */
+/* of use, loss of data or any incidental, consequential, direct, indirect, */
+/* or special damages, whether under contract, tort, warranty or otherwise, */
+/* arising in any way out of use or reliance upon this specification or any */
+/* information herein. */
+/* */
+/* (c) Copyright IBM Corp. and others, 2016 - 2020 */
+/* */
+/********************************************************************************/
+
+/* 9.1 AlgorithmCap.c */
+/* 9.1.1 Description */
+/* This file contains the algorithm property definitions for the algorithms and the code for the
+ TPM2_GetCapability() to return the algorithm properties. */
+/* 9.1.2 Includes and Defines */
+#include "Tpm.h"
+typedef struct
+{
+ TPM_ALG_ID algID;
+ TPMA_ALGORITHM attributes;
+} ALGORITHM;
+static const ALGORITHM s_algorithms[] =
+ {
+ // The entries in this table need to be in ascending order but the table doesn't
+ // need to be full (gaps are allowed). One day, a tool might exist to fill in the
+ // table from the TPM_ALG description
+#if ALG_RSA
+ {TPM_ALG_RSA, TPMA_ALGORITHM_INITIALIZER(1, 0, 0, 1, 0, 0, 0, 0, 0)},
+#endif
+#if ALG_TDES
+ {TPM_ALG_TDES, TPMA_ALGORITHM_INITIALIZER(0, 1, 0, 0, 0, 0, 0, 0, 0)},
+#endif
+#if ALG_SHA1
+ {TPM_ALG_SHA1, TPMA_ALGORITHM_INITIALIZER(0, 0, 1, 0, 0, 0, 0, 0, 0)},
+#endif
+ {TPM_ALG_HMAC, TPMA_ALGORITHM_INITIALIZER(0, 0, 1, 0, 0, 1, 0, 0, 0)},
+#if ALG_AES
+ {TPM_ALG_AES, TPMA_ALGORITHM_INITIALIZER(0, 1, 0, 0, 0, 0, 0, 0, 0)},
+#endif
+#if ALG_MGF1
+ {TPM_ALG_MGF1, TPMA_ALGORITHM_INITIALIZER(0, 0, 1, 0, 0, 0, 0, 1, 0)},
+#endif
+ {TPM_ALG_KEYEDHASH, TPMA_ALGORITHM_INITIALIZER(0, 0, 1, 1, 0, 1, 1, 0, 0)},
+#if ALG_XOR
+ {TPM_ALG_XOR, TPMA_ALGORITHM_INITIALIZER(0, 1, 1, 0, 0, 0, 0, 0, 0)},
+#endif
+#if ALG_SHA256
+ {TPM_ALG_SHA256, TPMA_ALGORITHM_INITIALIZER(0, 0, 1, 0, 0, 0, 0, 0, 0)},
+#endif
+#if ALG_SHA384
+ {TPM_ALG_SHA384, TPMA_ALGORITHM_INITIALIZER(0, 0, 1, 0, 0, 0, 0, 0, 0)},
+#endif
+#if ALG_SHA512
+ {TPM_ALG_SHA512, TPMA_ALGORITHM_INITIALIZER(0, 0, 1, 0, 0, 0, 0, 0, 0)},
+#endif
+#if ALG_SM3_256
+ {TPM_ALG_SM3_256, TPMA_ALGORITHM_INITIALIZER(0, 0, 1, 0, 0, 0, 0, 0, 0)},
+#endif
+#if ALG_SM4
+ {TPM_ALG_SM4, TPMA_ALGORITHM_INITIALIZER(0, 1, 0, 0, 0, 0, 0, 0, 0)},
+#endif
+#if ALG_RSASSA
+ {TPM_ALG_RSASSA, TPMA_ALGORITHM_INITIALIZER(1, 0, 0, 0, 0, 1, 0, 0, 0)},
+#endif
+#if ALG_RSAES
+ {TPM_ALG_RSAES, TPMA_ALGORITHM_INITIALIZER(1, 0, 0, 0, 0, 0, 1, 0, 0)},
+#endif
+#if ALG_RSAPSS
+ {TPM_ALG_RSAPSS, TPMA_ALGORITHM_INITIALIZER(1, 0, 0, 0, 0, 1, 0, 0, 0)},
+#endif
+#if ALG_OAEP
+ {TPM_ALG_OAEP, TPMA_ALGORITHM_INITIALIZER(1, 0, 0, 0, 0, 0, 1, 0, 0)},
+#endif
+#if ALG_ECDSA
+ {TPM_ALG_ECDSA, TPMA_ALGORITHM_INITIALIZER(1, 0, 0, 0, 0, 1, 0, 0, 0)},
+#endif
+#if ALG_ECDH
+ {TPM_ALG_ECDH, TPMA_ALGORITHM_INITIALIZER(1, 0, 0, 0, 0, 0, 0, 1, 0)},
+#endif
+#if ALG_ECDAA
+ {TPM_ALG_ECDAA, TPMA_ALGORITHM_INITIALIZER(1, 0, 0, 0, 0, 1, 0, 0, 0)},
+#endif
+#if ALG_SM2
+ {TPM_ALG_SM2, TPMA_ALGORITHM_INITIALIZER(1, 0, 0, 0, 0, 1, 0, 1, 0)},
+#endif
+#if ALG_ECSCHNORR
+ {TPM_ALG_ECSCHNORR, TPMA_ALGORITHM_INITIALIZER(1, 0, 0, 0, 0, 1, 0, 0, 0)},
+#endif
+#if ALG_ECMQV
+ {TPM_ALG_ECMQV, TPMA_ALGORITHM_INITIALIZER(1, 0, 0, 0, 0, 0, 0, 1, 0)},
+#endif
+#if ALG_KDF1_SP800_56A
+ {TPM_ALG_KDF1_SP800_56A, TPMA_ALGORITHM_INITIALIZER(0, 0, 1, 0, 0, 0, 0, 1, 0)},
+#endif
+#if ALG_KDF2
+ {TPM_ALG_KDF2, TPMA_ALGORITHM_INITIALIZER(0, 0, 1, 0, 0, 0, 0, 1, 0)},
+#endif
+#if ALG_KDF1_SP800_108
+ {TPM_ALG_KDF1_SP800_108, TPMA_ALGORITHM_INITIALIZER(0, 0, 1, 0, 0, 0, 0, 1, 0)},
+#endif
+#if ALG_ECC
+ {TPM_ALG_ECC, TPMA_ALGORITHM_INITIALIZER(1, 0, 0, 1, 0, 0, 0, 0, 0)},
+#endif
+ {TPM_ALG_SYMCIPHER, TPMA_ALGORITHM_INITIALIZER(0, 0, 0, 1, 0, 0, 0, 0, 0)},
+#if ALG_CAMELLIA
+ {TPM_ALG_CAMELLIA, TPMA_ALGORITHM_INITIALIZER(0, 1, 0, 0, 0, 0, 0, 0, 0)},
+#endif
+#if ALG_CMAC
+ {TPM_ALG_CMAC, TPMA_ALGORITHM_INITIALIZER(0, 1, 0, 0, 0, 1, 0, 0, 0)},
+#endif
+#if ALG_CTR
+ {TPM_ALG_CTR, TPMA_ALGORITHM_INITIALIZER(0, 1, 0, 0, 0, 0, 1, 0, 0)},
+#endif
+#if ALG_OFB
+ {TPM_ALG_OFB, TPMA_ALGORITHM_INITIALIZER(0, 1, 0, 0, 0, 0, 1, 0, 0)},
+#endif
+#if ALG_CBC
+ {TPM_ALG_CBC, TPMA_ALGORITHM_INITIALIZER(0, 1, 0, 0, 0, 0, 1, 0, 0)},
+#endif
+#if ALG_CFB
+ {TPM_ALG_CFB, TPMA_ALGORITHM_INITIALIZER(0, 1, 0, 0, 0, 0, 1, 0, 0)},
+#endif
+#if ALG_ECB
+ {TPM_ALG_ECB, TPMA_ALGORITHM_INITIALIZER(0, 1, 0, 0, 0, 0, 1, 0, 0)},
+#endif
+ };
+/* 9.1.3 AlgorithmCapGetImplemented() */
+/* This function is used by TPM2_GetCapability() to return a list of the implemented algorithms. */
+/* Return Values Meaning */
+/* YES more algorithms to report */
+/* NO no more algorithms to report */
+TPMI_YES_NO
+AlgorithmCapGetImplemented(
+ TPM_ALG_ID algID, // IN: the starting algorithm ID
+ UINT32 count, // IN: count of returned algorithms
+ TPML_ALG_PROPERTY *algList // OUT: algorithm list
+ )
+{
+ TPMI_YES_NO more = NO;
+ UINT32 i;
+ UINT32 algNum;
+ // initialize output algorithm list
+ algList->count = 0;
+ // The maximum count of algorithms we may return is MAX_CAP_ALGS.
+ if(count > MAX_CAP_ALGS)
+ count = MAX_CAP_ALGS;
+ // Compute how many algorithms are defined in s_algorithms array.
+ algNum = sizeof(s_algorithms) / sizeof(s_algorithms[0]);
+ // Scan the implemented algorithm list to see if there is a match to 'algID'.
+ for(i = 0; i < algNum; i++)
+ {
+ // If algID is less than the starting algorithm ID, skip it
+ if(s_algorithms[i].algID < algID)
+ continue;
+ if(algList->count < count)
+ {
+ // If we have not filled up the return list, add more algorithms
+ // to it
+ algList->algProperties[algList->count].alg = s_algorithms[i].algID;
+ algList->algProperties[algList->count].algProperties =
+ s_algorithms[i].attributes;
+ algList->count++;
+ }
+ else
+ {
+ // If the return list is full but we still have algorithms
+ // available, report this and stop scanning.
+ more = YES;
+ break;
+ }
+ }
+ return more;
+}
+/* 9.1.4 AlgorithmGetImplementedVector()
+
+ This function returns the bit vector of the implemented algorithms.
+*/
+LIB_EXPORT
+void
+AlgorithmGetImplementedVector(
+ ALGORITHM_VECTOR *implemented // OUT: the implemented bits are SET
+ )
+{
+ int index;
+ // Nothing implemented until we say it is
+ MemorySet(implemented, 0, sizeof(ALGORITHM_VECTOR));
+ // Go through the list of implemented algorithms and SET the corresponding bit in
+ // in the implemented vector
+ for(index = (sizeof(s_algorithms) / sizeof(s_algorithms[0])) - 1;
+ index >= 0; index--)
+ SET_BIT(s_algorithms[index].algID, *implemented);
+ return;
+}
diff --git a/src/tpm2/AlgorithmCap_fp.h b/src/tpm2/AlgorithmCap_fp.h
new file mode 100644
index 0000000..31e505c
--- /dev/null
+++ b/src/tpm2/AlgorithmCap_fp.h
@@ -0,0 +1,78 @@
+/********************************************************************************/
+/* */
+/* */
+/* Written by Ken Goldman */
+/* IBM Thomas J. Watson Research Center */
+/* $Id: AlgorithmCap_fp.h 1490 2019-07-26 21:13:22Z kgoldman $ */
+/* */
+/* Licenses and Notices */
+/* */
+/* 1. Copyright Licenses: */
+/* */
+/* - Trusted Computing Group (TCG) grants to the user of the source code in */
+/* this specification (the "Source Code") a worldwide, irrevocable, */
+/* nonexclusive, royalty free, copyright license to reproduce, create */
+/* derivative works, distribute, display and perform the Source Code and */
+/* derivative works thereof, and to grant others the rights granted herein. */
+/* */
+/* - The TCG grants to the user of the other parts of the specification */
+/* (other than the Source Code) the rights to reproduce, distribute, */
+/* display, and perform the specification solely for the purpose of */
+/* developing products based on such documents. */
+/* */
+/* 2. Source Code Distribution Conditions: */
+/* */
+/* - Redistributions of Source Code must retain the above copyright licenses, */
+/* this list of conditions and the following disclaimers. */
+/* */
+/* - Redistributions in binary form must reproduce the above copyright */
+/* licenses, this list of conditions and the following disclaimers in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* 3. Disclaimers: */
+/* */
+/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
+/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
+/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
+/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
+/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
+/* information on specification licensing rights available through TCG */
+/* membership agreements. */
+/* */
+/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
+/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
+/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
+/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
+/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
+/* */
+/* - Without limitation, TCG and its members and licensors disclaim all */
+/* liability, including liability for infringement of any proprietary */
+/* rights, relating to use of information in this specification and to the */
+/* implementation of this specification, and TCG disclaims all liability for */
+/* cost of procurement of substitute goods or services, lost profits, loss */
+/* of use, loss of data or any incidental, consequential, direct, indirect, */
+/* or special damages, whether under contract, tort, warranty or otherwise, */
+/* arising in any way out of use or reliance upon this specification or any */
+/* information herein. */
+/* */
+/* (c) Copyright IBM Corp. and others, 2016 */
+/* */
+/********************************************************************************/
+
+#ifndef ALGORITHMCAP_FP_H
+#define ALGORITHMCAP_FP_H
+
+TPMI_YES_NO
+AlgorithmCapGetImplemented(
+ TPM_ALG_ID algID, // IN: the starting algorithm ID
+ UINT32 count, // IN: count of returned algorithms
+ TPML_ALG_PROPERTY *algList // OUT: algorithm list
+ );
+LIB_EXPORT
+void
+AlgorithmGetImplementedVector(
+ ALGORITHM_VECTOR *implemented // OUT: the implemented bits are SET
+ );
+
+
+#endif
diff --git a/src/tpm2/AlgorithmTests.c b/src/tpm2/AlgorithmTests.c
new file mode 100644
index 0000000..08ee6b0
--- /dev/null
+++ b/src/tpm2/AlgorithmTests.c
@@ -0,0 +1,964 @@
+/********************************************************************************/
+/* */
+/* Code to perform the various self-test functions. */
+/* Written by Ken Goldman */
+/* IBM Thomas J. Watson Research Center */
+/* $Id: AlgorithmTests.c 1658 2021-01-22 23:14:01Z kgoldman $ */
+/* */
+/* Licenses and Notices */
+/* */
+/* 1. Copyright Licenses: */
+/* */
+/* - Trusted Computing Group (TCG) grants to the user of the source code in */
+/* this specification (the "Source Code") a worldwide, irrevocable, */
+/* nonexclusive, royalty free, copyright license to reproduce, create */
+/* derivative works, distribute, display and perform the Source Code and */
+/* derivative works thereof, and to grant others the rights granted herein. */
+/* */
+/* - The TCG grants to the user of the other parts of the specification */
+/* (other than the Source Code) the rights to reproduce, distribute, */
+/* display, and perform the specification solely for the purpose of */
+/* developing products based on such documents. */
+/* */
+/* 2. Source Code Distribution Conditions: */
+/* */
+/* - Redistributions of Source Code must retain the above copyright licenses, */
+/* this list of conditions and the following disclaimers. */
+/* */
+/* - Redistributions in binary form must reproduce the above copyright */
+/* licenses, this list of conditions and the following disclaimers in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* 3. Disclaimers: */
+/* */
+/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
+/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
+/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
+/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
+/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
+/* information on specification licensing rights available through TCG */
+/* membership agreements. */
+/* */
+/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
+/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
+/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
+/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
+/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
+/* */
+/* - Without limitation, TCG and its members and licensors disclaim all */
+/* liability, including liability for infringement of any proprietary */
+/* rights, relating to use of information in this specification and to the */
+/* implementation of this specification, and TCG disclaims all liability for */
+/* cost of procurement of substitute goods or services, lost profits, loss */
+/* of use, loss of data or any incidental, consequential, direct, indirect, */
+/* or special damages, whether under contract, tort, warranty or otherwise, */
+/* arising in any way out of use or reliance upon this specification or any */
+/* information herein. */
+/* */
+/* (c) Copyright IBM Corp. and others, 2016 - 2021 */
+/* */
+/********************************************************************************/
+
+/* 10.2.1 AlgorithmTests.c */
+/* 10.2.1.1 Introduction */
+/* This file contains the code to perform the various self-test functions. */
+/* 10.2.1.2 Includes and Defines */
+#include "Tpm.h"
+#define SELF_TEST_DATA
+#if SELF_TEST
+/* These includes pull in the data structures. They contain data definitions for the various
+ tests. */
+#include "SelfTest.h"
+#include "SymmetricTest.h"
+#include "RsaTestData.h"
+#include "EccTestData.h"
+#include "HashTestData.h"
+#include "KdfTestData.h"
+#define TEST_DEFAULT_TEST_HASH(vector) \
+ if(TEST_BIT(DEFAULT_TEST_HASH, g_toTest)) \
+ TestHash(DEFAULT_TEST_HASH, vector);
+/* Make sure that the algorithm has been tested */
+#define CLEAR_BOTH(alg) { CLEAR_BIT(alg, *toTest); \
+ if(toTest != &g_toTest) \
+ CLEAR_BIT(alg, g_toTest); }
+#define SET_BOTH(alg) { SET_BIT(alg, *toTest); \
+ if(toTest != &g_toTest) \
+ SET_BIT(alg, g_toTest); }
+#define TEST_BOTH(alg) ((toTest != &g_toTest) \
+ ? TEST_BIT(alg, *toTest) || TEST_BIT(alg, g_toTest) \
+ : TEST_BIT(alg, *toTest))
+/* Can only cancel if doing a list. */
+#define CHECK_CANCELED \
+ if(_plat__IsCanceled() && toTest != &g_toTest) \
+ return TPM_RC_CANCELED;
+/* 10.2.1.3 Hash Tests */
+/* 10.2.1.3.1 Description */
+/* The hash test does a known-value HMAC using the specified hash algorithm. */
+/* 10.2.1.3.2 TestHash() */
+/* The hash test function. */
+static TPM_RC
+TestHash(
+ TPM_ALG_ID hashAlg,
+ ALGORITHM_VECTOR *toTest
+ )
+{
+ TPM2B_DIGEST computed; // value computed
+ HMAC_STATE state;
+ UINT16 digestSize;
+ const TPM2B *testDigest = NULL;
+ // TPM2B_TYPE(HMAC_BLOCK, DEFAULT_TEST_HASH_BLOCK_SIZE);
+ pAssert(hashAlg != TPM_ALG_NULL);
+#define HASH_CASE_FOR_TEST(HASH, hash) case ALG_##HASH##_VALUE: \
+ testDigest = &c_##HASH##_digest.b; \
+ break;
+ switch(hashAlg)
+ {
+ FOR_EACH_HASH(HASH_CASE_FOR_TEST)
+
+ default:
+ FAIL(FATAL_ERROR_INTERNAL);
+ }
+ // Clear the to-test bits
+ CLEAR_BOTH(hashAlg);
+
+ // If there is an algorithm without test vectors, then assume that things are OK.
+ if(testDigest == NULL || testDigest->size == 0)
+ return TPM_RC_SUCCESS;
+
+ // Set the HMAC key to twice the digest size
+ digestSize = CryptHashGetDigestSize(hashAlg);
+ CryptHmacStart(&state, hashAlg, digestSize * 2,
+ (BYTE *)c_hashTestKey.t.buffer);
+ CryptDigestUpdate(&state.hashState, 2 * CryptHashGetBlockSize(hashAlg),
+ (BYTE *)c_hashTestData.t.buffer);
+ computed.t.size = digestSize;
+ CryptHmacEnd(&state, digestSize, computed.t.buffer);
+ if((testDigest->size != computed.t.size)
+ || (memcmp(testDigest->buffer, computed.t.buffer, computed.b.size) != 0)) {
+ SELF_TEST_FAILURE;
+ }
+ return TPM_RC_SUCCESS;
+}
+// libtpms added begin
+#if SMAC_IMPLEMENTED && ALG_CMAC
+static TPM_RC
+TestSMAC(
+ ALGORITHM_VECTOR *toTest
+ )
+{
+ HMAC_STATE state;
+ UINT16 copied;
+ BYTE out[MAX_SYM_BLOCK_SIZE];
+ UINT32 outSize = sizeof(out);
+ UINT16 blocksize;
+ int i;
+ TPMU_PUBLIC_PARMS cmac_keyParms;
+
+ // initializing this statically seems impossible with gcc...
+ cmac_keyParms.symDetail.sym.algorithm = TPM_ALG_AES;
+ cmac_keyParms.symDetail.sym.keyBits.sym = 128;
+
+ for (i = 0; CMACTests[i].key; i++ )
+ {
+ blocksize = CryptMacStart(&state, &cmac_keyParms,
+ TPM_ALG_CMAC, CMACTests[i].key);
+ pAssert(blocksize <= outSize);
+ CryptDigestUpdate(&state.hashState, CMACTests[i].datalen,
+ CMACTests[i].data);
+ copied = CryptMacEnd(&state, outSize, out);
+ if((CMACTests[i].outlen != copied)
+ || (memcmp(out, CMACTests[i].out, CMACTests[i].outlen) != 0)) {
+ SELF_TEST_FAILURE;
+ }
+ }
+ return TPM_RC_SUCCESS;
+}
+#endif
+// libtpms added end
+/* 10.2.1.4 Symmetric Test Functions */
+/* 10.2.1.4.1 MakeIv() */
+/* Internal function to make the appropriate IV depending on the mode. */
+static UINT32
+MakeIv(
+ TPM_ALG_ID mode, // IN: symmetric mode
+ UINT32 size, // IN: block size of the algorithm
+ BYTE *iv // OUT: IV to fill in
+ )
+{
+ BYTE i;
+ if(mode == TPM_ALG_ECB)
+ return 0;
+ if(mode == TPM_ALG_CTR)
+ {
+ // The test uses an IV that has 0xff in the last byte
+ for(i = 1; i <= size; i++)
+ *iv++ = 0xff - (BYTE)(size - i);
+ }
+ else
+ {
+ for(i = 0; i < size; i++)
+ *iv++ = i;
+ }
+ return size;
+}
+/* 10.2.1.4.2 TestSymmetricAlgorithm() */
+/* Function to test a specific algorithm, key size, and mode. */
+static void
+TestSymmetricAlgorithm(
+ const SYMMETRIC_TEST_VECTOR *test, //
+ TPM_ALG_ID mode //
+ )
+{
+ BYTE encrypted[MAX_SYM_BLOCK_SIZE * 2];
+ BYTE decrypted[MAX_SYM_BLOCK_SIZE * 2];
+ TPM2B_IV iv;
+
+ // libtpms added beging
+ if (test->dataOut[mode - TPM_ALG_CTR] == NULL)
+ return;
+ // libtpms added end
+
+ //
+ // Get the appropriate IV
+ iv.t.size = (UINT16)MakeIv(mode, test->ivSize, iv.t.buffer);
+ // Encrypt known data
+ CryptSymmetricEncrypt(encrypted, test->alg, test->keyBits, test->key, &iv,
+ mode, test->dataInOutSize, test->dataIn);
+ // Check that it matches the expected value
+ if(!MemoryEqual(encrypted, test->dataOut[mode - TPM_ALG_CTR],
+ test->dataInOutSize)) {
+ SELF_TEST_FAILURE;
+ }
+ // Reinitialize the iv for decryption
+ MakeIv(mode, test->ivSize, iv.t.buffer);
+ CryptSymmetricDecrypt(decrypted, test->alg, test->keyBits, test->key, &iv,
+ mode, test->dataInOutSize,
+ test->dataOut[mode - TPM_ALG_CTR]);
+ // Make sure that it matches what we started with
+ if(!MemoryEqual(decrypted, test->dataIn, test->dataInOutSize)) {
+ SELF_TEST_FAILURE;
+ }
+}
+/* 10.2.1.4.3 AllSymsAreDone() */
+/* Checks if both symmetric algorithms have been tested. This is put here so that addition of a
+ symmetric algorithm will be relatively easy to handle */
+/* Return Value Meaning */
+/* TRUE(1) all symmetric algorithms tested */
+/* FALSE(0) not all symmetric algorithms tested */
+static BOOL
+AllSymsAreDone(
+ ALGORITHM_VECTOR *toTest
+ )
+{
+ return (!TEST_BOTH(TPM_ALG_AES) && !TEST_BOTH(TPM_ALG_SM4));
+}
+/* 10.2.1.4.4 AllModesAreDone() */
+/* Checks if all the modes have been tested */
+/* Return Value Meaning */
+/* TRUE(1) all modes tested */
+/* FALSE(0) all modes not tested */
+static BOOL
+AllModesAreDone(
+ ALGORITHM_VECTOR *toTest
+ )
+{
+ TPM_ALG_ID alg;
+ for(alg = SYM_MODE_FIRST; alg <= SYM_MODE_LAST; alg++)
+ if(TEST_BOTH(alg))
+ return FALSE;
+ return TRUE;
+}
+/* 10.2.1.4.5 TestSymmetric() */
+/* If alg is a symmetric block cipher, then all of the modes that are selected are tested. If alg is
+ a mode, then all algorithms of that mode are tested. */
+static TPM_RC
+TestSymmetric(
+ TPM_ALG_ID alg,
+ ALGORITHM_VECTOR *toTest
+ )
+{
+ SYM_INDEX index;
+ TPM_ALG_ID mode;
+ //
+ if(!TEST_BIT(alg, *toTest))
+ return TPM_RC_SUCCESS;
+ if(alg == TPM_ALG_AES || alg == TPM_ALG_SM4 || alg == TPM_ALG_CAMELLIA || alg == TPM_ALG_TDES)
+ {
+ // Will test the algorithm for all modes and key sizes
+ CLEAR_BOTH(alg);
+ // A test this algorithm for all modes
+ for(index = 0; index < NUM_SYMS; index++)
+ {
+ if(c_symTestValues[index].alg == alg)
+ {
+ for(mode = SYM_MODE_FIRST;
+ mode <= SYM_MODE_LAST;
+ mode++)
+ {
+ if(TEST_BIT(mode, g_implementedAlgorithms)) // libtpms always test implemented modes
+ TestSymmetricAlgorithm(&c_symTestValues[index], mode);
+ }
+ }
+ }
+ // if all the symmetric tests are done
+ if(AllSymsAreDone(toTest))
+ {
+ // all symmetric algorithms tested so no modes should be set
+ for(alg = SYM_MODE_FIRST; alg <= SYM_MODE_LAST; alg++)
+ CLEAR_BOTH(alg);
+ }
+ }
+ else if(SYM_MODE_FIRST <= alg && alg <= SYM_MODE_LAST)
+ {
+ // Test this mode for all key sizes and algorithms
+ for(index = 0; index < NUM_SYMS; index++)
+ {
+ // The mode testing only comes into play when doing self tests
+ // by command. When doing self tests by command, the block ciphers are
+ // tested first. That means that all of their modes would have been
+ // tested for all key sizes. If there is no block cipher left to
+ // test, then clear this mode bit.
+ if(!TEST_BIT(TPM_ALG_AES, *toTest)
+ && !TEST_BIT(TPM_ALG_SM4, *toTest))
+ {
+ CLEAR_BOTH(alg);
+ }
+ else
+ {
+ for(index = 0; index < NUM_SYMS; index++)
+ {
+ if(TEST_BIT(c_symTestValues[index].alg, *toTest))
+ TestSymmetricAlgorithm(&c_symTestValues[index], alg);
+ }
+ // have tested this mode for all algorithms
+ CLEAR_BOTH(alg);
+ }
+ }
+ if(AllModesAreDone(toTest))
+ {
+ CLEAR_BOTH(TPM_ALG_AES);
+ CLEAR_BOTH(TPM_ALG_SM4);
+ }
+ }
+ else
+ pAssert(alg == 0 && alg != 0);
+ return TPM_RC_SUCCESS;
+}
+/* 10.2.1.5 RSA Tests */
+#if ALG_RSA
+/* 10.2.1.5.1 Introduction */
+/* The tests are for public key only operations and for private key operations. Signature
+ verification and encryption are public key operations. They are tested by using a KVT. For
+ signature verification, this means that a known good signature is checked by
+ CryptRsaValidateSignature(). If it fails, then the TPM enters failure mode. For encryption, the
+ TPM encrypts known values using the selected scheme and checks that the returned value matches
+ the expected value. */
+/* For private key operations, a full scheme check is used. For a signing key, a known key is used
+ to sign a known message. Then that signature is verified. since the signature may involve use of
+ random values, the signature will be different each time and we can't always check that the
+ signature matches a known value. The same technique is used for decryption (RSADP/RSAEP). */
+/* When an operation uses the public key and the verification has not been tested, the TPM will do a
+ KVT. */
+/* The test for the signing algorithm is built into the call for the algorithm */
+/* 10.2.1.5.2 RsaKeyInitialize() */
+/* The test key is defined by a public modulus and a private prime. The TPM's RSA code computes the
+ second prime and the private exponent. */
+static void
+RsaKeyInitialize(
+ OBJECT *testObject
+ )
+{
+ MemoryCopy2B(&testObject->publicArea.unique.rsa.b, (P2B)&c_rsaPublicModulus,
+ sizeof(c_rsaPublicModulus));
+ MemoryCopy2B(&testObject->sensitive.sensitive.rsa.b, (P2B)&c_rsaPrivatePrime,
+ sizeof(testObject->sensitive.sensitive.rsa.t.buffer));
+ testObject->publicArea.parameters.rsaDetail.keyBits = RSA_TEST_KEY_SIZE * 8;
+ // Use the default exponent
+ testObject->publicArea.parameters.rsaDetail.exponent = 0;
+ testObject->attributes.privateExp = 0;
+}
+/* 10.2.1.5.3 TestRsaEncryptDecrypt() */
+/* These tests are for a public key encryption that uses a random value. */
+static TPM_RC
+TestRsaEncryptDecrypt(
+ TPM_ALG_ID scheme, // IN: the scheme
+ ALGORITHM_VECTOR *toTest //
+ )
+{
+ TPM2B_PUBLIC_KEY_RSA testInput;
+ TPM2B_PUBLIC_KEY_RSA testOutput;
+ OBJECT testObject;
+ const TPM2B_RSA_TEST_KEY *kvtValue = NULL;
+ TPM_RC result = TPM_RC_SUCCESS;
+ const TPM2B *testLabel = NULL;
+ TPMT_RSA_DECRYPT rsaScheme;
+ //
+ // Don't need to initialize much of the test object but do need to initialize
+ // the flag indicating that the private exponent has been computed.
+ testObject.attributes.privateExp = CLEAR;
+ RsaKeyInitialize(&testObject);
+ rsaScheme.scheme = scheme;
+ rsaScheme.details.anySig.hashAlg = DEFAULT_TEST_HASH;
+ CLEAR_BOTH(scheme);
+ CLEAR_BOTH(TPM_ALG_NULL);
+ if(scheme == TPM_ALG_NULL)
+ {
+ // This is an encryption scheme using the private key without any encoding.
+ memcpy(testInput.t.buffer, c_RsaTestValue, sizeof(c_RsaTestValue));
+ testInput.t.size = sizeof(c_RsaTestValue);
+ if(TPM_RC_SUCCESS != CryptRsaEncrypt(&testOutput, &testInput.b,
+ &testObject, &rsaScheme, NULL, NULL)) {
+ SELF_TEST_FAILURE;
+ }
+ if(!MemoryEqual(testOutput.t.buffer, c_RsaepKvt.buffer, c_RsaepKvt.size)) {
+ SELF_TEST_FAILURE;
+ }
+ MemoryCopy2B(&testInput.b, &testOutput.b, sizeof(testInput.t.buffer));
+ if(TPM_RC_SUCCESS != CryptRsaDecrypt(&testOutput.b, &testInput.b,
+ &testObject, &rsaScheme, NULL)) {
+ SELF_TEST_FAILURE;
+ }
+ if(!MemoryEqual(testOutput.t.buffer, c_RsaTestValue,
+ sizeof(c_RsaTestValue))) {
+ SELF_TEST_FAILURE;
+ }
+ }
+ else
+ {
+ // TPM_ALG_RSAES:
+ // This is an decryption scheme using padding according to
+ // PKCS#1v2.1, 7.2. This padding uses random bits. To test a public
+ // key encryption that uses random data, encrypt a value and then
+ // decrypt the value and see that we get the encrypted data back.
+ // The hash is not used by this encryption so it can be TMP_ALG_NULL
+ // TPM_ALG_OAEP_:
+ // This is also an decryption scheme and it also uses a
+ // pseudo-random
+ // value. However, this also uses a hash algorithm. So, we may need
+ // to test that algorithm before use.
+ if(scheme == TPM_ALG_OAEP)
+ {
+ TEST_DEFAULT_TEST_HASH(toTest);
+ kvtValue = &c_OaepKvt;
+ testLabel = OAEP_TEST_STRING;
+ }
+ else if(scheme == TPM_ALG_RSAES)
+ {
+ kvtValue = &c_RsaesKvt;
+ testLabel = NULL;
+ }
+ else {
+ SELF_TEST_FAILURE;
+ }
+ // Only use a digest-size portion of the test value
+ memcpy(testInput.t.buffer, c_RsaTestValue, DEFAULT_TEST_DIGEST_SIZE);
+ testInput.t.size = DEFAULT_TEST_DIGEST_SIZE;
+ // See if the encryption works
+ if(TPM_RC_SUCCESS != CryptRsaEncrypt(&testOutput, &testInput.b,
+ &testObject, &rsaScheme, testLabel,
+ NULL)) {
+ SELF_TEST_FAILURE;
+ }
+ MemoryCopy2B(&testInput.b, &testOutput.b, sizeof(testInput.t.buffer));
+ // see if we can decrypt this value and get the original data back
+ if(TPM_RC_SUCCESS != CryptRsaDecrypt(&testOutput.b, &testInput.b,
+ &testObject, &rsaScheme, testLabel)) {
+ SELF_TEST_FAILURE;
+ }
+ // See if the results compare
+ if(testOutput.t.size != DEFAULT_TEST_DIGEST_SIZE
+ || !MemoryEqual(testOutput.t.buffer, c_RsaTestValue,
+ DEFAULT_TEST_DIGEST_SIZE)) {
+ SELF_TEST_FAILURE;
+ }
+ // Now check that the decryption works on a known value
+ MemoryCopy2B(&testInput.b, (P2B)kvtValue,
+ sizeof(testInput.t.buffer));
+ if(TPM_RC_SUCCESS != CryptRsaDecrypt(&testOutput.b, &testInput.b,
+ &testObject, &rsaScheme, testLabel)) {
+ SELF_TEST_FAILURE;
+ }
+ if(testOutput.t.size != DEFAULT_TEST_DIGEST_SIZE
+ || !MemoryEqual(testOutput.t.buffer, c_RsaTestValue,
+ DEFAULT_TEST_DIGEST_SIZE)) {
+ SELF_TEST_FAILURE;
+ }
+ }
+ return result;
+}
+/* 10.2.1.5.4 TestRsaSignAndVerify() */
+/* This function does the testing of the RSA sign and verification functions. This test does a
+ KVT. */
+static TPM_RC
+TestRsaSignAndVerify(
+ TPM_ALG_ID scheme,
+ ALGORITHM_VECTOR *toTest
+ )
+{
+ TPM_RC result = TPM_RC_SUCCESS;
+ OBJECT testObject;
+ TPM2B_DIGEST testDigest;
+ TPMT_SIGNATURE testSig;
+ // Do a sign and signature verification.
+ // RSASSA:
+ // This is a signing scheme according to PKCS#1-v2.1 8.2. It does not
+ // use random data so there is a KVT for the signing operation. On
+ // first use of the scheme for signing, use the TPM's RSA key to
+ // sign a portion of c_RsaTestData and compare the results to c_RsassaKvt. Then
+ // decrypt the data to see that it matches the starting value. This verifies
+ // the signature with a KVT
+ // Clear the bits indicating that the function has not been checked. This is to
+ // prevent looping
+ CLEAR_BOTH(scheme);
+ CLEAR_BOTH(TPM_ALG_NULL);
+ CLEAR_BOTH(TPM_ALG_RSA);
+ RsaKeyInitialize(&testObject);
+ memcpy(testDigest.t.buffer, (BYTE *)c_RsaTestValue, DEFAULT_TEST_DIGEST_SIZE);
+ testDigest.t.size = DEFAULT_TEST_DIGEST_SIZE;
+ testSig.sigAlg = scheme;
+ testSig.signature.rsapss.hash = DEFAULT_TEST_HASH;
+ // RSAPSS:
+ // This is a signing scheme a according to PKCS#1-v2.2 8.1 it uses
+ // random data in the signature so there is no KVT for the signing
+ // operation. To test signing, the TPM will use the TPM's RSA key
+ // to sign a portion of c_RsaTestValue and then it will verify the
+ // signature. For verification, c_RsapssKvt is verified before the
+ // user signature blob is verified. The worst case for testing of this
+ // algorithm is two private and one public key operation.
+ // The process is to sign known data. If RSASSA is being done, verify that the
+ // signature matches the precomputed value. For both, use the signed value and
+ // see that the verification says that it is a good signature. Then
+ // if testing RSAPSS, do a verify of a known good signature. This ensures that
+ // the validation function works.
+ if(TPM_RC_SUCCESS != CryptRsaSign(&testSig, &testObject, &testDigest, NULL)) {
+ SELF_TEST_FAILURE;
+ }
+ // For RSASSA, make sure the results is what we are looking for
+ if(testSig.sigAlg == TPM_ALG_RSASSA)
+ {
+ if(testSig.signature.rsassa.sig.t.size != RSA_TEST_KEY_SIZE
+ || !MemoryEqual(c_RsassaKvt.buffer,
+ testSig.signature.rsassa.sig.t.buffer,
+ RSA_TEST_KEY_SIZE)) {
+ SELF_TEST_FAILURE;
+ }
+ }
+ // See if the TPM will validate its own signatures
+ if(TPM_RC_SUCCESS != CryptRsaValidateSignature(&testSig, &testObject,
+ &testDigest)) {
+ SELF_TEST_FAILURE;
+ }
+ // If this is RSAPSS, check the verification with known signature
+ // Have to copy because CrytpRsaValidateSignature() eats the signature
+ if(TPM_ALG_RSAPSS == scheme)
+ {
+ MemoryCopy2B(&testSig.signature.rsapss.sig.b, (P2B)&c_RsapssKvt,
+ sizeof(testSig.signature.rsapss.sig.t.buffer));
+ if(TPM_RC_SUCCESS != CryptRsaValidateSignature(&testSig, &testObject,
+ &testDigest)) {
+ SELF_TEST_FAILURE;
+ }
+ }
+ return result;
+}
+/* 10.2.1.5.5 TestRSA() */
+/* Function uses the provided vector to indicate which tests to run. It will clear the vector after
+ each test is run and also clear g_toTest */
+static TPM_RC
+TestRsa(
+ TPM_ALG_ID alg,
+ ALGORITHM_VECTOR *toTest
+ )
+{
+ TPM_RC result = TPM_RC_SUCCESS;
+ //
+ switch(alg)
+ {
+ case TPM_ALG_NULL:
+ // This is the RSAEP/RSADP function. If we are processing a list, don't
+ // need to test these now because any other test will validate
+ // RSAEP/RSADP. Can tell this is list of test by checking to see if
+ // 'toTest' is pointing at g_toTest. If so, this is an isolated test
+ // an need to go ahead and do the test;
+ if((toTest == &g_toTest)
+ || (!TEST_BIT(TPM_ALG_RSASSA, *toTest)
+ && !TEST_BIT(TPM_ALG_RSAES, *toTest)
+ && !TEST_BIT(TPM_ALG_RSAPSS, *toTest)
+ && !TEST_BIT(TPM_ALG_OAEP, *toTest)))
+ // Not running a list of tests or no other tests on the list
+ // so run the test now
+ result = TestRsaEncryptDecrypt(alg, toTest);
+ // if not running the test now, leave the bit on, just in case things
+ // get interrupted
+ break;
+ case TPM_ALG_OAEP:
+ case TPM_ALG_RSAES:
+ result = TestRsaEncryptDecrypt(alg, toTest);
+ break;
+ case TPM_ALG_RSAPSS:
+ case TPM_ALG_RSASSA:
+ result = TestRsaSignAndVerify(alg, toTest);
+ break;
+ default:
+ SELF_TEST_FAILURE;
+ }
+ return result;
+}
+#endif // TPM_ALG_RSA
+/* 10.2.1.6 ECC Tests */
+#if ALG_ECC
+/* 10.2.1.6.1 LoadEccParameter() */
+/* This function is mostly for readability and type checking */
+static void
+LoadEccParameter(
+ TPM2B_ECC_PARAMETER *to, // target
+ const TPM2B_EC_TEST *from // source
+ )
+{
+ MemoryCopy2B(&to->b, &from->b, sizeof(to->t.buffer));
+}
+/* 10.2.1.6.2 LoadEccPoint() */
+static void
+LoadEccPoint(
+ TPMS_ECC_POINT *point, // target
+ const TPM2B_EC_TEST *x, // source
+ const TPM2B_EC_TEST *y
+ )
+{
+ MemoryCopy2B(&point->x.b, (TPM2B *)x, sizeof(point->x.t.buffer));
+ MemoryCopy2B(&point->y.b, (TPM2B *)y, sizeof(point->y.t.buffer));
+}
+/* 10.2.1.6.3 TestECDH() */
+/* This test does a KVT on a point multiply. */
+static TPM_RC
+TestECDH(
+ TPM_ALG_ID scheme, // IN: for consistency
+ ALGORITHM_VECTOR *toTest // IN/OUT: modified after test is run
+ )
+{
+ TPMS_ECC_POINT Z;
+ TPMS_ECC_POINT Qe;
+ TPM2B_ECC_PARAMETER ds;
+ TPM_RC result = TPM_RC_SUCCESS;
+ //
+ NOT_REFERENCED(scheme);
+ CLEAR_BOTH(TPM_ALG_ECDH);
+ LoadEccParameter(&ds, &c_ecTestKey_ds);
+ LoadEccPoint(&Qe, &c_ecTestKey_QeX, &c_ecTestKey_QeY);
+ if(TPM_RC_SUCCESS != CryptEccPointMultiply(&Z, c_testCurve, &Qe, &ds,
+ NULL, NULL)) {
+ SELF_TEST_FAILURE;
+ }
+ if(!MemoryEqual2B(&c_ecTestEcdh_X.b, &Z.x.b)
+ || !MemoryEqual2B(&c_ecTestEcdh_Y.b, &Z.y.b)) {
+ SELF_TEST_FAILURE;
+ }
+ return result;
+}
+/* 10.2.1.6.4 TestEccSignAndVerify() */
+static TPM_RC
+TestEccSignAndVerify(
+ TPM_ALG_ID scheme,
+ ALGORITHM_VECTOR *toTest
+ )
+{
+ OBJECT testObject;
+ TPMT_SIGNATURE testSig;
+ TPMT_ECC_SCHEME eccScheme;
+ testSig.sigAlg = scheme;
+ testSig.signature.ecdsa.hash = DEFAULT_TEST_HASH;
+ eccScheme.scheme = scheme;
+ eccScheme.details.anySig.hashAlg = DEFAULT_TEST_HASH;
+ CLEAR_BOTH(scheme);
+ CLEAR_BOTH(TPM_ALG_ECDH);
+ // ECC signature verification testing uses a KVT.
+ switch(scheme)
+ {
+ case TPM_ALG_ECDSA:
+ LoadEccParameter(&testSig.signature.ecdsa.signatureR, &c_TestEcDsa_r);
+ LoadEccParameter(&testSig.signature.ecdsa.signatureS, &c_TestEcDsa_s);
+ break;
+ case TPM_ALG_ECSCHNORR:
+ LoadEccParameter(&testSig.signature.ecschnorr.signatureR,
+ &c_TestEcSchnorr_r);
+ LoadEccParameter(&testSig.signature.ecschnorr.signatureS,
+ &c_TestEcSchnorr_s);
+ break;
+ case TPM_ALG_SM2:
+ // don't have a test for SM2
+ return TPM_RC_SUCCESS;
+ default:
+ SELF_TEST_FAILURE;
+ break;
+ }
+ TEST_DEFAULT_TEST_HASH(toTest);
+ // Have to copy the key. This is because the size used in the test vectors
+ // is the size of the ECC parameter for the test key while the size of a point
+ // is TPM dependent
+ MemoryCopy2B(&testObject.sensitive.sensitive.ecc.b, &c_ecTestKey_ds.b,
+ sizeof(testObject.sensitive.sensitive.ecc.t.buffer));
+ LoadEccPoint(&testObject.publicArea.unique.ecc, &c_ecTestKey_QsX,
+ &c_ecTestKey_QsY);
+ testObject.publicArea.parameters.eccDetail.curveID = c_testCurve;
+ if(TPM_RC_SUCCESS != CryptEccValidateSignature(&testSig, &testObject,
+ (TPM2B_DIGEST *)&c_ecTestValue.b))
+ {
+ SELF_TEST_FAILURE;
+ }
+ CHECK_CANCELED;
+ // Now sign and verify some data
+ if(TPM_RC_SUCCESS != CryptEccSign(&testSig, &testObject,
+ (TPM2B_DIGEST *)&c_ecTestValue,
+ &eccScheme, NULL)) {
+ SELF_TEST_FAILURE;
+ }
+ CHECK_CANCELED;
+ if(TPM_RC_SUCCESS != CryptEccValidateSignature(&testSig, &testObject,
+ (TPM2B_DIGEST *)&c_ecTestValue)) {
+ SELF_TEST_FAILURE;
+ }
+ CHECK_CANCELED;
+ return TPM_RC_SUCCESS;
+}
+/* 10.2.1.6.5 TestKDFa() */
+
+static TPM_RC
+TestKDFa(
+ ALGORITHM_VECTOR *toTest
+ )
+{
+ static TPM2B_KDF_TEST_KEY keyOut;
+ UINT32 counter = 0;
+ //
+ CLEAR_BOTH(TPM_ALG_KDF1_SP800_108);
+ keyOut.t.size = CryptKDFa(KDF_TEST_ALG, &c_kdfTestKeyIn.b, &c_kdfTestLabel.b,
+ &c_kdfTestContextU.b, &c_kdfTestContextV.b,
+ TEST_KDF_KEY_SIZE * 8, keyOut.t.buffer,
+ &counter, FALSE);
+ if ( keyOut.t.size != TEST_KDF_KEY_SIZE
+ || !MemoryEqual(keyOut.t.buffer, c_kdfTestKeyOut.t.buffer,
+ TEST_KDF_KEY_SIZE))
+ SELF_TEST_FAILURE;
+ return TPM_RC_SUCCESS;
+}
+/* 10.2.1.6.6 TestEcc() */
+static TPM_RC
+TestEcc(
+ TPM_ALG_ID alg,
+ ALGORITHM_VECTOR *toTest
+ )
+{
+ TPM_RC result = TPM_RC_SUCCESS;
+ NOT_REFERENCED(toTest);
+ switch(alg)
+ {
+ case TPM_ALG_ECC:
+ case TPM_ALG_ECDH:
+ // If this is in a loop then see if another test is going to deal with
+ // this.
+ // If toTest is not a self-test list
+ if((toTest == &g_toTest)
+ // or this is the only ECC test in the list
+ || !(TEST_BIT(TPM_ALG_ECDSA, *toTest)
+ || TEST_BIT(TPM_ALG_ECSCHNORR, *toTest)
+ || TEST_BIT(TPM_ALG_SM2, *toTest)))
+ {
+ result = TestECDH(alg, toTest);
+ }
+ break;
+ case TPM_ALG_ECDSA:
+ case TPM_ALG_ECSCHNORR:
+ case TPM_ALG_SM2:
+ result = TestEccSignAndVerify(alg, toTest);
+ break;
+ default:
+ SELF_TEST_FAILURE;
+ break;
+ }
+ return result;
+}
+#endif // TPM_ALG_ECC
+/* 10.2.1.6.4 TestAlgorithm() */
+/* Dispatches to the correct test function for the algorithm or gets a list of testable
+ algorithms. */
+/* If toTest is not NULL, then the test decisions are based on the algorithm selections in
+ toTest. Otherwise, g_toTest is used. When bits are clear in g_toTest they will also be cleared
+ toTest. */
+/* If there doesn't happen to be a test for the algorithm, its associated bit is quietly cleared. */
+/* If alg is zero (TPM_ALG_ERROR), then the toTest vector is cleared of any bits for which there is
+ no test (i.e. no tests are actually run but the vector is cleared). */
+/* NOTE: toTest will only ever have bits set for implemented algorithms but alg can be anything. */
+/* Error Returns Meaning */
+/* TPM_RC_CANCELED test was canceled */
+LIB_EXPORT
+TPM_RC
+TestAlgorithm(
+ TPM_ALG_ID alg,
+ ALGORITHM_VECTOR *toTest
+ )
+{
+ TPM_ALG_ID first = (alg == TPM_ALG_ERROR) ? TPM_ALG_FIRST : alg;
+ TPM_ALG_ID last = (alg == TPM_ALG_ERROR) ? TPM_ALG_LAST : alg;
+ BOOL doTest = (alg != TPM_ALG_ERROR);
+ TPM_RC result = TPM_RC_SUCCESS;
+ if(toTest == NULL)
+ toTest = &g_toTest;
+ // This is kind of strange. This function will either run a test of the selected
+ // algorithm or just clear a bit if there is no test for the algorithm. So,
+ // either this loop will be executed once for the selected algorithm or once for
+ // each of the possible algorithms. If it is executed more than once ('alg' ==
+ // TPM_ALG_ERROR), then no test will be run but bits will be cleared for
+ // unimplemented algorithms. This was done this way so that there is only one
+ // case statement with all of the algorithms. It was easier to have one case
+ // statement than to have multiple ones to manage whenever an algorithm ID is
+ // added.
+ for(alg = first; (alg <= last); alg++)
+ {
+ // if 'alg' was TPM_ALG_ERROR, then we will be cycling through
+ // values, some of which may not be implemented. If the bit in toTest
+ // happens to be set, then we could either generated an assert, or just
+ // silently CLEAR it. Decided to just clear.
+ if(!TEST_BIT(alg, g_implementedAlgorithms))
+ {
+ CLEAR_BIT(alg, *toTest);
+ continue;
+ }
+ // Process whatever is left.
+ // NOTE: since this switch will only be called if the algorithm is
+ // implemented, it is not necessary to modify this list except to comment
+ // out the algorithms for which there is no test
+ switch(alg)
+ {
+ // Symmetric block ciphers
+#if ALG_AES
+ case TPM_ALG_AES:
+// libtpms added begin
+#if SMAC_IMPLEMENTED && ALG_CMAC
+ if (doTest) {
+ result = TestSMAC(toTest);
+ if (result != TPM_RC_SUCCESS)
+ break;
+ }
+#endif
+// libtpms added end
+#endif
+#if ALG_SM4
+ // if SM4 is implemented, its test is like other block ciphers but there
+ // aren't any test vectors for it yet
+ // case TPM_ALG_SM4:
+#endif
+#if ALG_CAMELLIA
+ case TPM_ALG_CAMELLIA: // libtpms activated
+#endif
+#if ALG_TDES
+ case TPM_ALG_TDES: // libtpms added
+#endif
+ // Symmetric modes
+#if !ALG_CFB
+# error CFB is required in all TPM implementations
+#endif // !TPM_ALG_CFB
+ case TPM_ALG_CFB:
+ if(doTest)
+ result = TestSymmetric(alg, toTest);
+ break;
+#if ALG_CTR
+ case TPM_ALG_CTR:
+#endif // TPM_ALG_CRT
+#if ALG_OFB
+ case TPM_ALG_OFB:
+#endif // TPM_ALG_OFB
+#if ALG_CBC
+ case TPM_ALG_CBC:
+#endif // TPM_ALG_CBC
+#if ALG_ECB
+ case TPM_ALG_ECB:
+#endif
+ if(doTest)
+ result = TestSymmetric(alg, toTest);
+ else
+ // If doing the initialization of g_toTest vector, only need
+ // to test one of the modes for the symmetric algorithms. If
+ // initializing for a SelfTest(FULL_TEST), allow all the modes.
+ if(toTest == &g_toTest)
+ CLEAR_BIT(alg, *toTest);
+ break;
+#if !ALG_HMAC
+# error HMAC is required in all TPM implementations
+#endif
+ case TPM_ALG_HMAC:
+ // Clear the bit that indicates that HMAC is required because
+ // HMAC is used as the basic test for all hash algorithms.
+ CLEAR_BOTH(alg);
+ // Testing HMAC means test the default hash
+ if(doTest)
+ TestHash(DEFAULT_TEST_HASH, toTest);
+ else
+ // If not testing, then indicate that the hash needs to be
+ // tested because this uses HMAC
+ SET_BOTH(DEFAULT_TEST_HASH);
+ break;
+ // Have to use two arguments for the macro even though only the first is used in the
+ // expansion.
+#define HASH_CASE_TEST(HASH, hash) \
+ case ALG_##HASH##_VALUE:
+ FOR_EACH_HASH(HASH_CASE_TEST)
+#undef HASH_CASE_TEST
+ if(doTest)
+ result = TestHash(alg, toTest);
+ break;
+ // RSA-dependent
+#if ALG_RSA
+ case TPM_ALG_RSA:
+ CLEAR_BOTH(alg);
+ if(doTest)
+ result = TestRsa(TPM_ALG_NULL, toTest);
+ else
+ SET_BOTH(TPM_ALG_NULL);
+ break;
+ case TPM_ALG_RSASSA:
+ case TPM_ALG_RSAES:
+ case TPM_ALG_RSAPSS:
+ case TPM_ALG_OAEP:
+ case TPM_ALG_NULL: // used or RSADP
+ if(doTest)
+ result = TestRsa(alg, toTest);
+ break;
+#endif // ALG_RSA
+#if ALG_KDF1_SP800_108
+ case TPM_ALG_KDF1_SP800_108:
+ if(doTest)
+ result = TestKDFa(toTest);
+ break;
+#endif // ALG_KDF1_SP800_108
+#if ALG_ECC
+ // ECC dependent but no tests
+ // case TPM_ALG_ECDAA:
+ // case TPM_ALG_ECMQV:
+ // case TPM_ALG_KDF1_SP800_56a:
+ // case TPM_ALG_KDF2:
+ // case TPM_ALG_MGF1:
+ case TPM_ALG_ECC:
+ CLEAR_BOTH(alg);
+ if(doTest)
+ result = TestEcc(TPM_ALG_ECDH, toTest);
+ else
+ SET_BOTH(TPM_ALG_ECDH);
+ break;
+ case TPM_ALG_ECDSA:
+ case TPM_ALG_ECDH:
+ case TPM_ALG_ECSCHNORR:
+ // case TPM_ALG_SM2:
+ if(doTest)
+ result = TestEcc(alg, toTest);
+ break;
+#endif // ALG_ECC
+ default:
+ CLEAR_BIT(alg, *toTest);
+ break;
+ }
+ if(result != TPM_RC_SUCCESS)
+ break;
+ }
+ return result;
+}
+#endif // SELF_TESTS
diff --git a/src/tpm2/AlgorithmTests_fp.h b/src/tpm2/AlgorithmTests_fp.h
new file mode 100644
index 0000000..c180b7b
--- /dev/null
+++ b/src/tpm2/AlgorithmTests_fp.h
@@ -0,0 +1,73 @@
+/********************************************************************************/
+/* */
+/* */
+/* Written by Ken Goldman */
+/* IBM Thomas J. Watson Research Center */
+/* $Id: AlgorithmTests_fp.h 809 2016-11-16 18:31:54Z kgoldman $ */
+/* */
+/* Licenses and Notices */
+/* */
+/* 1. Copyright Licenses: */
+/* */
+/* - Trusted Computing Group (TCG) grants to the user of the source code in */
+/* this specification (the "Source Code") a worldwide, irrevocable, */
+/* nonexclusive, royalty free, copyright license to reproduce, create */
+/* derivative works, distribute, display and perform the Source Code and */
+/* derivative works thereof, and to grant others the rights granted herein. */
+/* */
+/* - The TCG grants to the user of the other parts of the specification */
+/* (other than the Source Code) the rights to reproduce, distribute, */
+/* display, and perform the specification solely for the purpose of */
+/* developing products based on such documents. */
+/* */
+/* 2. Source Code Distribution Conditions: */
+/* */
+/* - Redistributions of Source Code must retain the above copyright licenses, */
+/* this list of conditions and the following disclaimers. */
+/* */
+/* - Redistributions in binary form must reproduce the above copyright */
+/* licenses, this list of conditions and the following disclaimers in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* 3. Disclaimers: */
+/* */
+/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
+/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
+/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
+/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
+/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
+/* information on specification licensing rights available through TCG */
+/* membership agreements. */
+/* */
+/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
+/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
+/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
+/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
+/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
+/* */
+/* - Without limitation, TCG and its members and licensors disclaim all */
+/* liability, including liability for infringement of any proprietary */
+/* rights, relating to use of information in this specification and to the */
+/* implementation of this specification, and TCG disclaims all liability for */
+/* cost of procurement of substitute goods or services, lost profits, loss */
+/* of use, loss of data or any incidental, consequential, direct, indirect, */
+/* or special damages, whether under contract, tort, warranty or otherwise, */
+/* arising in any way out of use or reliance upon this specification or any */
+/* information herein. */
+/* */
+/* (c) Copyright IBM Corp. and others, 2016 */
+/* */
+/********************************************************************************/
+
+#ifndef ALGORITHMTESTS_FP_H
+#define ALGORITHMTESTS_FP_H
+
+LIB_EXPORT
+TPM_RC
+TestAlgorithm(
+ TPM_ALG_ID alg,
+ ALGORITHM_VECTOR *toTest
+ );
+
+
+#endif
diff --git a/src/tpm2/AsymmetricCommands.c b/src/tpm2/AsymmetricCommands.c
new file mode 100644
index 0000000..885087b
--- /dev/null
+++ b/src/tpm2/AsymmetricCommands.c
@@ -0,0 +1,299 @@
+/********************************************************************************/
+/* */
+/* Asymmetric Commands */
+/* Written by Ken Goldman */
+/* IBM Thomas J. Watson Research Center */
+/* $Id: AsymmetricCommands.c 1490 2019-07-26 21:13:22Z kgoldman $ */
+/* */
+/* Licenses and Notices */
+/* */
+/* 1. Copyright Licenses: */
+/* */
+/* - Trusted Computing Group (TCG) grants to the user of the source code in */
+/* this specification (the "Source Code") a worldwide, irrevocable, */
+/* nonexclusive, royalty free, copyright license to reproduce, create */
+/* derivative works, distribute, display and perform the Source Code and */
+/* derivative works thereof, and to grant others the rights granted herein. */
+/* */
+/* - The TCG grants to the user of the other parts of the specification */
+/* (other than the Source Code) the rights to reproduce, distribute, */
+/* display, and perform the specification solely for the purpose of */
+/* developing products based on such documents. */
+/* */
+/* 2. Source Code Distribution Conditions: */
+/* */
+/* - Redistributions of Source Code must retain the above copyright licenses, */
+/* this list of conditions and the following disclaimers. */
+/* */
+/* - Redistributions in binary form must reproduce the above copyright */
+/* licenses, this list of conditions and the following disclaimers in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* 3. Disclaimers: */
+/* */
+/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
+/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
+/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
+/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
+/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
+/* information on specification licensing rights available through TCG */
+/* membership agreements. */
+/* */
+/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
+/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
+/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
+/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
+/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
+/* */
+/* - Without limitation, TCG and its members and licensors disclaim all */
+/* liability, including liability for infringement of any proprietary */
+/* rights, relating to use of information in this specification and to the */
+/* implementation of this specification, and TCG disclaims all liability for */
+/* cost of procurement of substitute goods or services, lost profits, loss */
+/* of use, loss of data or any incidental, consequential, direct, indirect, */
+/* or special damages, whether under contract, tort, warranty or otherwise, */
+/* arising in any way out of use or reliance upon this specification or any */
+/* information herein. */
+/* */
+/* (c) Copyright IBM Corp. and others, 2016 - 2019 */
+/* */
+/********************************************************************************/
+
+#include "Tpm.h"
+#include "RSA_Encrypt_fp.h"
+#if CC_RSA_Encrypt // Conditional expansion of this file
+TPM_RC
+TPM2_RSA_Encrypt(
+ RSA_Encrypt_In *in, // IN: input parameter list
+ RSA_Encrypt_Out *out // OUT: output parameter list
+ )
+{
+ TPM_RC result;
+ OBJECT *rsaKey;
+ TPMT_RSA_DECRYPT *scheme;
+ // Input Validation
+ rsaKey = HandleToObject(in->keyHandle);
+ // selected key must be an RSA key
+ if(rsaKey->publicArea.type != TPM_ALG_RSA)
+ return TPM_RCS_KEY + RC_RSA_Encrypt_keyHandle;
+ // selected key must have the decryption attribute
+ if(!IS_ATTRIBUTE(rsaKey->publicArea.objectAttributes, TPMA_OBJECT, decrypt))
+ return TPM_RCS_ATTRIBUTES + RC_RSA_Encrypt_keyHandle;
+ // Is there a label?
+ if(!IsLabelProperlyFormatted(&in->label.b))
+ return TPM_RCS_VALUE + RC_RSA_Encrypt_label;
+ // Command Output
+ // Select a scheme for encryption
+ scheme = CryptRsaSelectScheme(in->keyHandle, &in->inScheme);
+ if(scheme == NULL)
+ return TPM_RCS_SCHEME + RC_RSA_Encrypt_inScheme;
+ // Encryption. TPM_RC_VALUE, or TPM_RC_SCHEME errors my be returned buy
+ // CryptEncyptRSA.
+ out->outData.t.size = sizeof(out->outData.t.buffer);
+ result = CryptRsaEncrypt(&out->outData, &in->message.b, rsaKey, scheme,
+ &in->label.b, NULL);
+ return result;
+}
+#endif // CC_RSA_Encrypt
+#include "Tpm.h"
+#include "RSA_Decrypt_fp.h"
+#if CC_RSA_Decrypt // Conditional expansion of this file
+TPM_RC
+TPM2_RSA_Decrypt(
+ RSA_Decrypt_In *in, // IN: input parameter list
+ RSA_Decrypt_Out *out // OUT: output parameter list
+ )
+{
+ TPM_RC result;
+ OBJECT *rsaKey;
+ TPMT_RSA_DECRYPT *scheme;
+ // Input Validation
+ rsaKey = HandleToObject(in->keyHandle);
+ // The selected key must be an RSA key
+ if(rsaKey->publicArea.type != TPM_ALG_RSA)
+ return TPM_RCS_KEY + RC_RSA_Decrypt_keyHandle;
+ // The selected key must be an unrestricted decryption key
+ if(IS_ATTRIBUTE(rsaKey->publicArea.objectAttributes, TPMA_OBJECT, restricted)
+ || !IS_ATTRIBUTE(rsaKey->publicArea.objectAttributes, TPMA_OBJECT, decrypt))
+ return TPM_RCS_ATTRIBUTES + RC_RSA_Decrypt_keyHandle;
+ // NOTE: Proper operation of this command requires that the sensitive area
+ // of the key is loaded. This is assured because authorization is required
+ // to use the sensitive area of the key. In order to check the authorization,
+ // the sensitive area has to be loaded, even if authorization is with policy.
+ // If label is present, make sure that it is a NULL-terminated string
+ if(!IsLabelProperlyFormatted(&in->label.b))
+ return TPM_RCS_VALUE + RC_RSA_Decrypt_label;
+ // Command Output
+ // Select a scheme for decrypt.
+ scheme = CryptRsaSelectScheme(in->keyHandle, &in->inScheme);
+ if(scheme == NULL)
+ return TPM_RCS_SCHEME + RC_RSA_Decrypt_inScheme;
+ // Decryption. TPM_RC_VALUE, TPM_RC_SIZE, and TPM_RC_KEY error may be
+ // returned by CryptRsaDecrypt.
+ // NOTE: CryptRsaDecrypt can also return TPM_RC_ATTRIBUTES or TPM_RC_BINDING
+ // when the key is not a decryption key but that was checked above.
+ out->message.t.size = sizeof(out->message.t.buffer);
+ result = CryptRsaDecrypt(&out->message.b, &in->cipherText.b, rsaKey,
+ scheme, &in->label.b);
+ return result;
+}
+#endif // CC_RSA_Decrypt
+#include "Tpm.h"
+#include "ECDH_KeyGen_fp.h"
+#if CC_ECDH_KeyGen // Conditional expansion of this file
+TPM_RC
+TPM2_ECDH_KeyGen(
+ ECDH_KeyGen_In *in, // IN: input parameter list
+ ECDH_KeyGen_Out *out // OUT: output parameter list
+ )
+{
+ OBJECT *eccKey;
+ TPM2B_ECC_PARAMETER sensitive;
+ TPM_RC result;
+ // Input Validation
+ eccKey = HandleToObject(in->keyHandle);
+ // Referenced key must be an ECC key
+ if(eccKey->publicArea.type != TPM_ALG_ECC)
+ return TPM_RCS_KEY + RC_ECDH_KeyGen_keyHandle;
+ // Command Output
+ do
+ {
+ TPMT_PUBLIC *keyPublic = &eccKey->publicArea;
+ // Create ephemeral ECC key
+ result = CryptEccNewKeyPair(&out->pubPoint.point, &sensitive,
+ keyPublic->parameters.eccDetail.curveID);
+ if(result == TPM_RC_SUCCESS)
+ {
+ // Compute Z
+ result = CryptEccPointMultiply(&out->zPoint.point,
+ keyPublic->parameters.eccDetail.curveID,
+ &keyPublic->unique.ecc,
+ &sensitive,
+ NULL, NULL);
+ // The point in the key is not on the curve. Indicate
+ // that the key is bad.
+ if(result == TPM_RC_ECC_POINT)
+ return TPM_RCS_KEY + RC_ECDH_KeyGen_keyHandle;
+ // The other possible error from CryptEccPointMultiply is
+ // TPM_RC_NO_RESULT indicating that the multiplication resulted in
+ // the point at infinity, so get a new random key and start over
+ // BTW, this never happens.
+ }
+ } while(result == TPM_RC_NO_RESULT);
+ return result;
+}
+#endif // CC_ECDH_KeyGen
+#include "Tpm.h"
+#include "ECDH_ZGen_fp.h"
+#if CC_ECDH_ZGen // Conditional expansion of this file
+TPM_RC
+TPM2_ECDH_ZGen(
+ ECDH_ZGen_In *in, // IN: input parameter list
+ ECDH_ZGen_Out *out // OUT: output parameter list
+ )
+{
+ TPM_RC result;
+ OBJECT *eccKey;
+ // Input Validation
+ eccKey = HandleToObject(in->keyHandle);
+ // Selected key must be a non-restricted, decrypt ECC key
+ if(eccKey->publicArea.type != TPM_ALG_ECC)
+ return TPM_RCS_KEY + RC_ECDH_ZGen_keyHandle;
+ // Selected key needs to be unrestricted with the 'decrypt' attribute
+ if(IS_ATTRIBUTE(eccKey->publicArea.objectAttributes, TPMA_OBJECT, restricted)
+ || !IS_ATTRIBUTE(eccKey->publicArea.objectAttributes, TPMA_OBJECT, decrypt))
+ return TPM_RCS_ATTRIBUTES + RC_ECDH_ZGen_keyHandle;
+ // Make sure the scheme allows this use
+ if(eccKey->publicArea.parameters.eccDetail.scheme.scheme != TPM_ALG_ECDH
+ && eccKey->publicArea.parameters.eccDetail.scheme.scheme != TPM_ALG_NULL)
+ return TPM_RCS_SCHEME + RC_ECDH_ZGen_keyHandle;
+ // Command Output
+ // Compute Z. TPM_RC_ECC_POINT or TPM_RC_NO_RESULT may be returned here.
+ result = CryptEccPointMultiply(&out->outPoint.point,
+ eccKey->publicArea.parameters.eccDetail.curveID,
+ &in->inPoint.point,
+ &eccKey->sensitive.sensitive.ecc,
+ NULL, NULL);
+ if(result != TPM_RC_SUCCESS)
+ return RcSafeAddToResult(result, RC_ECDH_ZGen_inPoint);
+ return result;
+}
+#endif // CC_ECDH_ZGen
+#include "Tpm.h"
+#include "ECC_Parameters_fp.h"
+#if CC_ECC_Parameters // Conditional expansion of this file
+TPM_RC
+TPM2_ECC_Parameters(
+ ECC_Parameters_In *in, // IN: input parameter list
+ ECC_Parameters_Out *out // OUT: output parameter list
+ )
+{
+ // Command Output
+ // Get ECC curve parameters
+ if(CryptEccGetParameters(in->curveID, &out->parameters))
+ return TPM_RC_SUCCESS;
+ else
+ return TPM_RCS_VALUE + RC_ECC_Parameters_curveID;
+}
+#endif // CC_ECC_Parameters
+#include "Tpm.h"
+#include "ZGen_2Phase_fp.h"
+#if CC_ZGen_2Phase // Conditional expansion of this file
+TPM_RC
+TPM2_ZGen_2Phase(
+ ZGen_2Phase_In *in, // IN: input parameter list
+ ZGen_2Phase_Out *out // OUT: output parameter list
+ )
+{
+ TPM_RC result;
+ OBJECT *eccKey;
+ TPM2B_ECC_PARAMETER r;
+ TPM_ALG_ID scheme;
+ // Input Validation
+ eccKey = HandleToObject(in->keyA);
+ // keyA must be an ECC key
+ if(eccKey->publicArea.type != TPM_ALG_ECC)
+ return TPM_RCS_KEY + RC_ZGen_2Phase_keyA;
+ // keyA must not be restricted and must be a decrypt key
+ if(IS_ATTRIBUTE(eccKey->publicArea.objectAttributes, TPMA_OBJECT, restricted)
+ || !IS_ATTRIBUTE(eccKey->publicArea.objectAttributes, TPMA_OBJECT, decrypt))
+ return TPM_RCS_ATTRIBUTES + RC_ZGen_2Phase_keyA;
+ // if the scheme of keyA is TPM_ALG_NULL, then use the input scheme; otherwise
+ // the input scheme must be the same as the scheme of keyA
+ scheme = eccKey->publicArea.parameters.asymDetail.scheme.scheme;
+ if(scheme != TPM_ALG_NULL)
+ {
+ if(scheme != in->inScheme)
+ return TPM_RCS_SCHEME + RC_ZGen_2Phase_inScheme;
+ }
+ else
+ scheme = in->inScheme;
+ if(scheme == TPM_ALG_NULL)
+ return TPM_RCS_SCHEME + RC_ZGen_2Phase_inScheme;
+ // Input points must be on the curve of keyA
+ if(!CryptEccIsPointOnCurve(eccKey->publicArea.parameters.eccDetail.curveID,
+ &in->inQsB.point))
+ return TPM_RCS_ECC_POINT + RC_ZGen_2Phase_inQsB;
+ if(!CryptEccIsPointOnCurve(eccKey->publicArea.parameters.eccDetail.curveID,
+ &in->inQeB.point))
+ return TPM_RCS_ECC_POINT + RC_ZGen_2Phase_inQeB;
+ if(!CryptGenerateR(&r, &in->counter,
+ eccKey->publicArea.parameters.eccDetail.curveID,
+ NULL))
+ return TPM_RCS_VALUE + RC_ZGen_2Phase_counter;
+ // Command Output
+ result = CryptEcc2PhaseKeyExchange(&out->outZ1.point,
+ &out->outZ2.point,
+ eccKey->publicArea.parameters.eccDetail.curveID,
+ scheme,
+ &eccKey->sensitive.sensitive.ecc,
+ &r,
+ &in->inQsB.point,
+ &in->inQeB.point);
+ if(result == TPM_RC_SCHEME)
+ return TPM_RCS_SCHEME + RC_ZGen_2Phase_inScheme;
+ if(result == TPM_RC_SUCCESS)
+ CryptEndCommit(in->counter);
+ return result;
+}
+#endif // CC_ZGen_2Phase
diff --git a/src/tpm2/Attest_spt.c b/src/tpm2/Attest_spt.c
new file mode 100644
index 0000000..0b8d29c
--- /dev/null
+++ b/src/tpm2/Attest_spt.c
@@ -0,0 +1,209 @@
+/********************************************************************************/
+/* */
+/* */
+/* Written by Ken Goldman */
+/* IBM Thomas J. Watson Research Center */
+/* $Id: Attest_spt.c 1490 2019-07-26 21:13:22Z kgoldman $ */
+/* */
+/* Licenses and Notices */
+/* */
+/* 1. Copyright Licenses: */
+/* */
+/* - Trusted Computing Group (TCG) grants to the user of the source code in */
+/* this specification (the "Source Code") a worldwide, irrevocable, */
+/* nonexclusive, royalty free, copyright license to reproduce, create */
+/* derivative works, distribute, display and perform the Source Code and */
+/* derivative works thereof, and to grant others the rights granted herein. */
+/* */
+/* - The TCG grants to the user of the other parts of the specification */
+/* (other than the Source Code) the rights to reproduce, distribute, */
+/* display, and perform the specification solely for the purpose of */
+/* developing products based on such documents. */
+/* */
+/* 2. Source Code Distribution Conditions: */
+/* */
+/* - Redistributions of Source Code must retain the above copyright licenses, */
+/* this list of conditions and the following disclaimers. */
+/* */
+/* - Redistributions in binary form must reproduce the above copyright */
+/* licenses, this list of conditions and the following disclaimers in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* 3. Disclaimers: */
+/* */
+/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
+/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
+/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
+/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
+/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
+/* information on specification licensing rights available through TCG */
+/* membership agreements. */
+/* */
+/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
+/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
+/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
+/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
+/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
+/* */
+/* - Without limitation, TCG and its members and licensors disclaim all */
+/* liability, including liability for infringement of any proprietary */
+/* rights, relating to use of information in this specification and to the */
+/* implementation of this specification, and TCG disclaims all liability for */
+/* cost of procurement of substitute goods or services, lost profits, loss */
+/* of use, loss of data or any incidental, consequential, direct, indirect, */
+/* or special damages, whether under contract, tort, warranty or otherwise, */
+/* arising in any way out of use or reliance upon this specification or any */
+/* information herein. */
+/* */
+/* (c) Copyright IBM Corp. and others, 2016 - 2018 */
+/* */
+/********************************************************************************/
+
+#include "Tpm.h"
+#include "Attest_spt_fp.h"
+/* 7.2.2 Functions */
+/* 7.2.2.1 FillInAttestInfo() */
+/* Fill in common fields of TPMS_ATTEST structure. */
+void
+FillInAttestInfo(
+ TPMI_DH_OBJECT signHandle, // IN: handle of signing object
+ TPMT_SIG_SCHEME *scheme, // IN/OUT: scheme to be used for signing
+ TPM2B_DATA *data, // IN: qualifying data
+ TPMS_ATTEST *attest // OUT: attest structure
+ )
+{
+ OBJECT *signObject = HandleToObject(signHandle);
+ // Magic number
+ attest->magic = TPM_GENERATED_VALUE;
+ if(signObject == NULL)
+ {
+ // The name for a null handle is TPM_RH_NULL
+ // This is defined because UINT32_TO_BYTE_ARRAY does a cast. If the
+ // size of the cast is smaller than a constant, the compiler warns
+ // about the truncation of a constant value.
+ TPM_HANDLE nullHandle = TPM_RH_NULL;
+ attest->qualifiedSigner.t.size = sizeof(TPM_HANDLE);
+ UINT32_TO_BYTE_ARRAY(nullHandle, attest->qualifiedSigner.t.name);
+ }
+ else
+ {
+ // Certifying object qualified name
+ // if the scheme is anonymous, this is an empty buffer
+ if(CryptIsSchemeAnonymous(scheme->scheme))
+ attest->qualifiedSigner.t.size = 0;
+ else
+ attest->qualifiedSigner = signObject->qualifiedName;
+ }
+ // current clock in plain text
+ TimeFillInfo(&attest->clockInfo);
+ // Firmware version in plain text
+ attest->firmwareVersion = ((UINT64)gp.firmwareV1 << (sizeof(UINT32) * 8));
+ attest->firmwareVersion += gp.firmwareV2;
+ // Check the hierarchy of sign object. For NULL sign handle, the hierarchy
+ // will be TPM_RH_NULL
+ if((signObject == NULL)
+ || (!signObject->attributes.epsHierarchy
+ && !signObject->attributes.ppsHierarchy))
+ {
+ // For signing key that is not in platform or endorsement hierarchy,
+ // obfuscate the reset, restart and firmware version information
+ UINT64 obfuscation[2];
+ CryptKDFa(CONTEXT_INTEGRITY_HASH_ALG, &gp.shProof.b, OBFUSCATE_STRING,
+ &attest->qualifiedSigner.b, NULL, 128,
+ (BYTE *)&obfuscation[0], NULL, FALSE);
+ // Obfuscate data
+ attest->firmwareVersion += obfuscation[0];
+ attest->clockInfo.resetCount += (UINT32)(obfuscation[1] >> 32);
+ attest->clockInfo.restartCount += (UINT32)obfuscation[1];
+ }
+ // External data
+ if(CryptIsSchemeAnonymous(scheme->scheme))
+ attest->extraData.t.size = 0;
+ else
+ {
+ // If we move the data to the attestation structure, then it is not
+ // used in the signing operation except as part of the signed data
+ attest->extraData = *data;
+ data->t.size = 0;
+ }
+}
+/* 7.2.2.2 SignAttestInfo() */
+/* Sign a TPMS_ATTEST structure. If signHandle is TPM_RH_NULL, a null signature is returned. */
+/* Error Returns Meaning */
+/* TPM_RC_ATTRIBUTES signHandle references not a signing key */
+/* TPM_RC_SCHEME scheme is not compatible with signHandle type */
+/* TPM_RC_VALUE digest generated for the given scheme is greater than the modulus of signHandle (for
+ an RSA key); invalid commit status or failed to generate r value (for an ECC key) */
+TPM_RC
+SignAttestInfo(
+ OBJECT *signKey, // IN: sign object
+ TPMT_SIG_SCHEME *scheme, // IN: sign scheme
+ TPMS_ATTEST *certifyInfo, // IN: the data to be signed
+ TPM2B_DATA *qualifyingData, // IN: extra data for the signing
+ // process
+ TPM2B_ATTEST *attest, // OUT: marshaled attest blob to be
+ // signed
+ TPMT_SIGNATURE *signature // OUT: signature
+ )
+{
+ BYTE *buffer;
+ HASH_STATE hashState;
+ TPM2B_DIGEST digest;
+ TPM_RC result;
+ // Marshal TPMS_ATTEST structure for hash
+ buffer = attest->t.attestationData;
+ attest->t.size = TPMS_ATTEST_Marshal(certifyInfo, &buffer, NULL);
+ if(signKey == NULL)
+ {
+ signature->sigAlg = TPM_ALG_NULL;
+ result = TPM_RC_SUCCESS;
+ }
+ else
+ {
+ TPMI_ALG_HASH hashAlg;
+ // Compute hash
+ hashAlg = scheme->details.any.hashAlg;
+ // need to set the receive buffer to get something put in it
+ digest.t.size = sizeof(digest.t.buffer);
+ digest.t.size = CryptHashBlock(hashAlg, attest->t.size,
+ attest->t.attestationData,
+ digest.t.size, digest.t.buffer);
+ // If there is qualifying data, need to rehash the data
+ // hash(qualifyingData || hash(attestationData))
+ if(qualifyingData->t.size != 0)
+ {
+ CryptHashStart(&hashState, hashAlg);
+ CryptDigestUpdate2B(&hashState, &qualifyingData->b);
+ CryptDigestUpdate2B(&hashState, &digest.b);
+ CryptHashEnd2B(&hashState, &digest.b);
+ }
+ // Sign the hash. A TPM_RC_VALUE, TPM_RC_SCHEME, or
+ // TPM_RC_ATTRIBUTES error may be returned at this point
+ result = CryptSign(signKey, scheme, &digest, signature);
+ // Since the clock is used in an attestation, the state in NV is no longer
+ // "orderly" with respect to the data in RAM if the signature is valid
+ if(result == TPM_RC_SUCCESS)
+ {
+ // Command uses the clock so need to clear the orderly state if it is
+ // set.
+ result = NvClearOrderly();
+ }
+ }
+ return result;
+}
+/* 7.2.2.3 IsSigningObject() */
+/* Checks to see if the object is OK for signing. This is here rather than in Object_spt.c because
+ all the attestation commands use this file but not Object_spt.c. */
+/* Return Values Meaning */
+/* TRUE object may sign */
+/* FALSE object may not sign */
+BOOL
+IsSigningObject(
+ OBJECT *object // IN:
+ )
+{
+ return ((object == NULL)
+ || ((IS_ATTRIBUTE(object->publicArea.objectAttributes, TPMA_OBJECT, sign)
+ && object->publicArea.type != TPM_ALG_SYMCIPHER)));
+}
+
diff --git a/src/tpm2/Attest_spt_fp.h b/src/tpm2/Attest_spt_fp.h
new file mode 100644
index 0000000..25add17
--- /dev/null
+++ b/src/tpm2/Attest_spt_fp.h
@@ -0,0 +1,92 @@
+/********************************************************************************/
+/* */
+/* */
+/* Written by Ken Goldman */
+/* IBM Thomas J. Watson Research Center */
+/* $Id: Attest_spt_fp.h 1490 2019-07-26 21:13:22Z kgoldman $ */
+/* */
+/* Licenses and Notices */
+/* */
+/* 1. Copyright Licenses: */
+/* */
+/* - Trusted Computing Group (TCG) grants to the user of the source code in */
+/* this specification (the "Source Code") a worldwide, irrevocable, */
+/* nonexclusive, royalty free, copyright license to reproduce, create */
+/* derivative works, distribute, display and perform the Source Code and */
+/* derivative works thereof, and to grant others the rights granted herein. */
+/* */
+/* - The TCG grants to the user of the other parts of the specification */
+/* (other than the Source Code) the rights to reproduce, distribute, */
+/* display, and perform the specification solely for the purpose of */
+/* developing products based on such documents. */
+/* */
+/* 2. Source Code Distribution Conditions: */
+/* */
+/* - Redistributions of Source Code must retain the above copyright licenses, */
+/* this list of conditions and the following disclaimers. */
+/* */
+/* - Redistributions in binary form must reproduce the above copyright */
+/* licenses, this list of conditions and the following disclaimers in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* 3. Disclaimers: */
+/* */
+/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
+/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
+/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
+/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
+/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
+/* information on specification licensing rights available through TCG */
+/* membership agreements. */
+/* */
+/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
+/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
+/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
+/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
+/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
+/* */
+/* - Without limitation, TCG and its members and licensors disclaim all */
+/* liability, including liability for infringement of any proprietary */
+/* rights, relating to use of information in this specification and to the */
+/* implementation of this specification, and TCG disclaims all liability for */
+/* cost of procurement of substitute goods or services, lost profits, loss */
+/* of use, loss of data or any incidental, consequential, direct, indirect, */
+/* or special damages, whether under contract, tort, warranty or otherwise, */
+/* arising in any way out of use or reliance upon this specification or any */
+/* information herein. */
+/* */
+/* (c) Copyright IBM Corp. and others, 2016 */
+/* */
+/********************************************************************************/
+
+#ifndef ATTEST_SPT_FP_H
+#define ATTEST_SPT_FP_H
+
+void
+FillInAttestInfo(
+ TPMI_DH_OBJECT signHandle, // IN: handle of signing object
+ TPMT_SIG_SCHEME *scheme, // IN/OUT: scheme to be used for signing
+ TPM2B_DATA *data, // IN: qualifying data
+ TPMS_ATTEST *attest // OUT: attest structure
+ );
+TPM_RC
+SignAttestInfo(
+ OBJECT *signKey, // IN: sign object
+ TPMT_SIG_SCHEME *scheme, // IN: sign scheme
+ TPMS_ATTEST *certifyInfo, // IN: the data to be signed
+ TPM2B_DATA *qualifyingData, // IN: extra data for the signing
+ // process
+ TPM2B_ATTEST *attest, // OUT: marshaled attest blob to be
+ // signed
+ TPMT_SIGNATURE *signature // OUT: signature
+ );
+BOOL
+IsSigningObject(
+ OBJECT *object // IN:
+ );
+
+
+
+
+
+#endif
diff --git a/src/tpm2/AttestationCommands.c b/src/tpm2/AttestationCommands.c
new file mode 100644
index 0000000..9df4315
--- /dev/null
+++ b/src/tpm2/AttestationCommands.c
@@ -0,0 +1,544 @@
+/********************************************************************************/
+/* */
+/* Attestation Commands */
+/* Written by Ken Goldman */
+/* IBM Thomas J. Watson Research Center */
+/* $Id: AttestationCommands.c 1658 2021-01-22 23:14:01Z kgoldman $ */
+/* */
+/* Licenses and Notices */
+/* */
+/* 1. Copyright Licenses: */
+/* */
+/* - Trusted Computing Group (TCG) grants to the user of the source code in */
+/* this specification (the "Source Code") a worldwide, irrevocable, */
+/* nonexclusive, royalty free, copyright license to reproduce, create */
+/* derivative works, distribute, display and perform the Source Code and */
+/* derivative works thereof, and to grant others the rights granted herein. */
+/* */
+/* - The TCG grants to the user of the other parts of the specification */
+/* (other than the Source Code) the rights to reproduce, distribute, */
+/* display, and perform the specification solely for the purpose of */
+/* developing products based on such documents. */
+/* */
+/* 2. Source Code Distribution Conditions: */
+/* */
+/* - Redistributions of Source Code must retain the above copyright licenses, */
+/* this list of conditions and the following disclaimers. */
+/* */
+/* - Redistributions in binary form must reproduce the above copyright */
+/* licenses, this list of conditions and the following disclaimers in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* 3. Disclaimers: */
+/* */
+/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
+/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
+/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
+/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
+/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
+/* information on specification licensing rights available through TCG */
+/* membership agreements. */
+/* */
+/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
+/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
+/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
+/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
+/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
+/* */
+/* - Without limitation, TCG and its members and licensors disclaim all */
+/* liability, including liability for infringement of any proprietary */
+/* rights, relating to use of information in this specification and to the */
+/* implementation of this specification, and TCG disclaims all liability for */
+/* cost of procurement of substitute goods or services, lost profits, loss */
+/* of use, loss of data or any incidental, consequential, direct, indirect, */
+/* or special damages, whether under contract, tort, warranty or otherwise, */
+/* arising in any way out of use or reliance upon this specification or any */
+/* information herein. */
+/* */
+/* (c) Copyright IBM Corp. and others, 2016 - 2021 */
+/* */
+/********************************************************************************/
+
+#include "Tpm.h"
+#include "Attest_spt_fp.h"
+#include "Certify_fp.h"
+#if CC_Certify // Conditional expansion of this file
+TPM_RC
+TPM2_Certify(
+ Certify_In *in, // IN: input parameter list
+ Certify_Out *out // OUT: output parameter list
+ )
+{
+ TPMS_ATTEST certifyInfo;
+ OBJECT *signObject = HandleToObject(in->signHandle);
+ OBJECT *certifiedObject = HandleToObject(in->objectHandle);
+ // Input validation
+ if(!IsSigningObject(signObject))
+ return TPM_RCS_KEY + RC_Certify_signHandle;
+ if(!CryptSelectSignScheme(signObject, &in->inScheme))
+ return TPM_RCS_SCHEME + RC_Certify_inScheme;
+ // Command Output
+ // Filling in attest information
+ // Common fields
+ FillInAttestInfo(in->signHandle, &in->inScheme, &in->qualifyingData,
+ &certifyInfo);
+ // Certify specific fields
+ certifyInfo.type = TPM_ST_ATTEST_CERTIFY;
+ // NOTE: the certified object is not allowed to be TPM_ALG_NULL so
+ // 'certifiedObject' will never be NULL
+ certifyInfo.attested.certify.name = certifiedObject->name;
+
+ // When using an anonymous signing scheme, need to set the qualified Name to the
+ // empty buffer to avoid correlation between keys
+ if(CryptIsSchemeAnonymous(in->inScheme.scheme))
+ certifyInfo.attested.certify.qualifiedName.t.size = 0;
+ else
+ certifyInfo.attested.certify.qualifiedName = certifiedObject->qualifiedName;
+
+ // Sign attestation structure. A NULL signature will be returned if
+ // signHandle is TPM_RH_NULL. A TPM_RC_NV_UNAVAILABLE, TPM_RC_NV_RATE,
+ // TPM_RC_VALUE, TPM_RC_SCHEME or TPM_RC_ATTRIBUTES error may be returned
+ // by SignAttestInfo()
+ return SignAttestInfo(signObject, &in->inScheme, &certifyInfo,
+ &in->qualifyingData, &out->certifyInfo, &out->signature);
+}
+#endif // CC_Certify
+#include "Tpm.h"
+#include "Attest_spt_fp.h"
+#include "CertifyCreation_fp.h"
+#if CC_CertifyCreation // Conditional expansion of this file
+TPM_RC
+TPM2_CertifyCreation(
+ CertifyCreation_In *in, // IN: input parameter list
+ CertifyCreation_Out *out // OUT: output parameter list
+ )
+{
+ TPMT_TK_CREATION ticket;
+ TPMS_ATTEST certifyInfo;
+ OBJECT *certified = HandleToObject(in->objectHandle);
+ OBJECT *signObject = HandleToObject(in->signHandle);
+ // Input Validation
+ if(!IsSigningObject(signObject))
+ return TPM_RCS_KEY + RC_CertifyCreation_signHandle;
+ if(!CryptSelectSignScheme(signObject, &in->inScheme))
+ return TPM_RCS_SCHEME + RC_CertifyCreation_inScheme;
+ // CertifyCreation specific input validation
+ // Re-compute ticket
+ TicketComputeCreation(in->creationTicket.hierarchy, &certified->name,
+ &in->creationHash, &ticket);
+ // Compare ticket
+ if(!MemoryEqual2B(&ticket.digest.b, &in->creationTicket.digest.b))
+ return TPM_RCS_TICKET + RC_CertifyCreation_creationTicket;
+ // Command Output
+ // Common fields
+ FillInAttestInfo(in->signHandle, &in->inScheme, &in->qualifyingData,
+ &certifyInfo);
+ // CertifyCreation specific fields
+ // Attestation type
+ certifyInfo.type = TPM_ST_ATTEST_CREATION;
+ certifyInfo.attested.creation.objectName = certified->name;
+ // Copy the creationHash
+ certifyInfo.attested.creation.creationHash = in->creationHash;
+ // Sign attestation structure. A NULL signature will be returned if
+ // signObject is TPM_RH_NULL. A TPM_RC_NV_UNAVAILABLE, TPM_RC_NV_RATE,
+ // TPM_RC_VALUE, TPM_RC_SCHEME or TPM_RC_ATTRIBUTES error may be returned at
+ // this point
+ return SignAttestInfo(signObject, &in->inScheme, &certifyInfo,
+ &in->qualifyingData, &out->certifyInfo,
+ &out->signature);
+}
+#endif // CC_CertifyCreation
+#include "Tpm.h"
+#include "Attest_spt_fp.h"
+#include "Quote_fp.h"
+#if CC_Quote // Conditional expansion of this file
+TPM_RC
+TPM2_Quote(
+ Quote_In *in, // IN: input parameter list
+ Quote_Out *out // OUT: output parameter list
+ )
+{
+ TPMI_ALG_HASH hashAlg;
+ TPMS_ATTEST quoted;
+ OBJECT *signObject = HandleToObject(in->signHandle);
+ // Input Validation
+ if(!IsSigningObject(signObject))
+ return TPM_RCS_KEY + RC_Quote_signHandle;
+ if(!CryptSelectSignScheme(signObject, &in->inScheme))
+ return TPM_RCS_SCHEME + RC_Quote_inScheme;
+ // Command Output
+ // Filling in attest information
+ // Common fields
+ // FillInAttestInfo may return TPM_RC_SCHEME or TPM_RC_KEY
+ FillInAttestInfo(in->signHandle, &in->inScheme, &in->qualifyingData, &quoted);
+ // Quote specific fields
+ // Attestation type
+ quoted.type = TPM_ST_ATTEST_QUOTE;
+ // Get hash algorithm in sign scheme. This hash algorithm is used to
+ // compute PCR digest. If there is no algorithm, then the PCR cannot
+ // be digested and this command returns TPM_RC_SCHEME
+ hashAlg = in->inScheme.details.any.hashAlg;
+ if(hashAlg == TPM_ALG_NULL)
+ return TPM_RCS_SCHEME + RC_Quote_inScheme;
+ // Compute PCR digest
+ PCRComputeCurrentDigest(hashAlg, &in->PCRselect,
+ &quoted.attested.quote.pcrDigest);
+ // Copy PCR select. "PCRselect" is modified in PCRComputeCurrentDigest
+ // function
+ quoted.attested.quote.pcrSelect = in->PCRselect;
+ // Sign attestation structure. A NULL signature will be returned if
+ // signObject is NULL.
+ return SignAttestInfo(signObject, &in->inScheme, &quoted, &in->qualifyingData,
+ &out->quoted, &out->signature);
+}
+#endif // CC_Quote
+#include "Tpm.h"
+#include "Attest_spt_fp.h"
+#include "GetSessionAuditDigest_fp.h"
+#if CC_GetSessionAuditDigest // Conditional expansion of this file
+TPM_RC
+TPM2_GetSessionAuditDigest(
+ GetSessionAuditDigest_In *in, // IN: input parameter list
+ GetSessionAuditDigest_Out *out // OUT: output parameter list
+ )
+{
+ SESSION *session = SessionGet(in->sessionHandle);
+ TPMS_ATTEST auditInfo;
+ OBJECT *signObject = HandleToObject(in->signHandle);
+ // Input Validation
+ if(!IsSigningObject(signObject))
+ return TPM_RCS_KEY + RC_GetSessionAuditDigest_signHandle;
+ if(!CryptSelectSignScheme(signObject, &in->inScheme))
+ return TPM_RCS_SCHEME + RC_GetSessionAuditDigest_inScheme;
+ // session must be an audit session
+ if(session->attributes.isAudit == CLEAR)
+ return TPM_RCS_TYPE + RC_GetSessionAuditDigest_sessionHandle;
+ // Command Output
+ // Fill in attest information common fields
+ FillInAttestInfo(in->signHandle, &in->inScheme, &in->qualifyingData,
+ &auditInfo);
+ // SessionAuditDigest specific fields
+ auditInfo.type = TPM_ST_ATTEST_SESSION_AUDIT;
+ auditInfo.attested.sessionAudit.sessionDigest = session->u2.auditDigest;
+ // Exclusive audit session
+ auditInfo.attested.sessionAudit.exclusiveSession
+ = (g_exclusiveAuditSession == in->sessionHandle);
+ // Sign attestation structure. A NULL signature will be returned if
+ // signObject is NULL.
+ return SignAttestInfo(signObject, &in->inScheme, &auditInfo,
+ &in->qualifyingData, &out->auditInfo,
+ &out->signature);
+}
+#endif // CC_GetSessionAuditDigest
+#include "Tpm.h"
+#include "Attest_spt_fp.h"
+#include "GetCommandAuditDigest_fp.h"
+#if CC_GetCommandAuditDigest // Conditional expansion of this file
+TPM_RC
+TPM2_GetCommandAuditDigest(
+ GetCommandAuditDigest_In *in, // IN: input parameter list
+ GetCommandAuditDigest_Out *out // OUT: output parameter list
+ )
+{
+ TPM_RC result;
+ TPMS_ATTEST auditInfo;
+ OBJECT *signObject = HandleToObject(in->signHandle);
+ // Input validation
+ if(!IsSigningObject(signObject))
+ return TPM_RCS_KEY + RC_GetCommandAuditDigest_signHandle;
+ if(!CryptSelectSignScheme(signObject, &in->inScheme))
+ return TPM_RCS_SCHEME + RC_GetCommandAuditDigest_inScheme;
+ // Command Output
+ // Fill in attest information common fields
+ FillInAttestInfo(in->signHandle, &in->inScheme, &in->qualifyingData,
+ &auditInfo);
+ // CommandAuditDigest specific fields
+ auditInfo.type = TPM_ST_ATTEST_COMMAND_AUDIT;
+ auditInfo.attested.commandAudit.digestAlg = gp.auditHashAlg;
+ auditInfo.attested.commandAudit.auditCounter = gp.auditCounter;
+ // Copy command audit log
+ auditInfo.attested.commandAudit.auditDigest = gr.commandAuditDigest;
+ CommandAuditGetDigest(&auditInfo.attested.commandAudit.commandDigest);
+ // Sign attestation structure. A NULL signature will be returned if
+ // signHandle is TPM_RH_NULL. A TPM_RC_NV_UNAVAILABLE, TPM_RC_NV_RATE,
+ // TPM_RC_VALUE, TPM_RC_SCHEME or TPM_RC_ATTRIBUTES error may be returned at
+ // this point
+ result = SignAttestInfo(signObject, &in->inScheme, &auditInfo,
+ &in->qualifyingData, &out->auditInfo,
+ &out->signature);
+ // Internal Data Update
+ if(result == TPM_RC_SUCCESS && in->signHandle != TPM_RH_NULL)
+ // Reset log
+ gr.commandAuditDigest.t.size = 0;
+ return result;
+}
+#endif // CC_GetCommandAuditDigest
+#include "Tpm.h"
+#include "Attest_spt_fp.h"
+#include "GetTime_fp.h"
+#if CC_GetTime // Conditional expansion of this file
+TPM_RC
+TPM2_GetTime(
+ GetTime_In *in, // IN: input parameter list
+ GetTime_Out *out // OUT: output parameter list
+ )
+{
+ TPMS_ATTEST timeInfo;
+ OBJECT *signObject = HandleToObject(in->signHandle);
+ // Input Validation
+ if(!IsSigningObject(signObject))
+ return TPM_RCS_KEY + RC_GetTime_signHandle;
+ if(!CryptSelectSignScheme(signObject, &in->inScheme))
+ return TPM_RCS_SCHEME + RC_GetTime_inScheme;
+ // Command Output
+ // Fill in attest common fields
+ FillInAttestInfo(in->signHandle, &in->inScheme, &in->qualifyingData, &timeInfo);
+ // GetClock specific fields
+ timeInfo.type = TPM_ST_ATTEST_TIME;
+ timeInfo.attested.time.time.time = g_time;
+ TimeFillInfo(&timeInfo.attested.time.time.clockInfo);
+ // Firmware version in plain text
+ timeInfo.attested.time.firmwareVersion
+ = (((UINT64)gp.firmwareV1) << 32) + gp.firmwareV2;
+ // Sign attestation structure. A NULL signature will be returned if
+ // signObject is NULL.
+ return SignAttestInfo(signObject, &in->inScheme, &timeInfo, &in->qualifyingData,
+ &out->timeInfo, &out->signature);
+}
+#endif // CC_GetTime
+#include "Tpm.h"
+#include "CertifyX509_fp.h"
+#include "X509.h"
+#include "TpmAsn1_fp.h"
+#include "X509_spt_fp.h"
+#include "Attest_spt_fp.h"
+#include "Platform_fp.h"
+#if CC_CertifyX509 // Conditional expansion of this file
+#if CERTIFYX509_DEBUG
+#include "DebugHelpers_fp.h"
+#endif
+
+/* Error Returns Meaning*/
+/* TPM_RC_ATTRIBUTES the attributes of objectHandle are not compatible with the KeyUsage() or TPMA_OBJECT values in the extensions fields */
+/* TPM_RC_BINDING the public and private portions of the key are not properly bound. */
+/* TPM_RC_HASH the hash algorithm in the scheme is not supported */
+/* TPM_RC_KEY signHandle does not reference a signing key; */
+/* TPM_RC_SCHEME the scheme is not compatible with sign key type, or input scheme is not compatible with default scheme, or the chosen scheme is not a valid sign scheme */
+ /* TPM_RC_VALUE most likely a problem with the format of partialCertificate */
+TPM_RC
+TPM2_CertifyX509(
+ CertifyX509_In *in, // IN: input parameter list
+ CertifyX509_Out *out // OUT: output parameter list
+ )
+{
+ TPM_RC result;
+ OBJECT *signKey = HandleToObject(in->signHandle);
+ OBJECT *object = HandleToObject(in->objectHandle);
+ HASH_STATE hash;
+ INT16 length; // length for a tagged element
+ ASN1UnmarshalContext ctx;
+ ASN1MarshalContext ctxOut;
+ // certTBS holds an array of pointers and lengths. Each entry references the
+ // corresponding value in a TBSCertificate structure. For example, the 1th
+ // element references the version number
+ stringRef certTBS[REF_COUNT] = {{0}};
+#define ALLOWED_SEQUENCES (SUBJECT_PUBLIC_KEY_REF - SIGNATURE_REF)
+ stringRef partial[ALLOWED_SEQUENCES] = {{0}};
+ INT16 countOfSequences = 0;
+ INT16 i;
+ //
+#if CERTIFYX509_DEBUG
+ DebugFileInit();
+ DebugDumpBuffer(in->partialCertificate.t.size, in->partialCertificate.t.buffer,
+ "partialCertificate");
+#endif
+
+ // Input Validation
+ if(in->reserved.b.size != 0)
+ return TPM_RC_SIZE + RC_CertifyX509_reserved;
+ // signing key must be able to sign
+ if(!IsSigningObject(signKey))
+ return TPM_RCS_KEY + RC_CertifyX509_signHandle;
+ // Pick a scheme for sign. If the input sign scheme is not compatible with
+ // the default scheme, return an error.
+ if(!CryptSelectSignScheme(signKey, &in->inScheme))
+ return TPM_RCS_SCHEME + RC_CertifyX509_inScheme;
+ // Make sure that the public Key encoding is known
+ if(X509AddPublicKey(NULL, object) == 0)
+ return TPM_RCS_ASYMMETRIC + RC_CertifyX509_objectHandle;
+ // Unbundle 'partialCertificate'.
+ // Initialize the unmarshaling context
+ if(!ASN1UnmarshalContextInitialize(&ctx, in->partialCertificate.t.size,
+ in->partialCertificate.t.buffer))
+ return TPM_RCS_VALUE + RC_CertifyX509_partialCertificate;
+ // Make sure that this is a constructed SEQUENCE
+ length = ASN1NextTag(&ctx);
+ // Must be a constructed SEQUENCE that uses all of the input parameter
+ if((ctx.tag != (ASN1_CONSTRUCTED_SEQUENCE))
+ || ((ctx.offset + length) != in->partialCertificate.t.size))
+ return TPM_RCS_SIZE + RC_CertifyX509_partialCertificate;
+
+ // This scans through the contents of the outermost SEQUENCE. This would be the
+ // 'issuer', 'validity', 'subject', 'issuerUniqueID' (optional),
+ // 'subjectUniqueID' (optional), and 'extensions.'
+ while(ctx.offset < ctx.size)
+ {
+ INT16 startOfElement = ctx.offset;
+ //
+ // Read the next tag and length field.
+ length = ASN1NextTag(&ctx);
+ if(length < 0)
+ break;
+ if(ctx.tag == ASN1_CONSTRUCTED_SEQUENCE)
+ {
+ partial[countOfSequences].buf = &ctx.buffer[startOfElement];
+ ctx.offset += length;
+ partial[countOfSequences].len = (INT16)ctx.offset - startOfElement;
+ if(++countOfSequences > ALLOWED_SEQUENCES)
+ break;
+ }
+ else if(ctx.tag == X509_EXTENSIONS)
+ {
+ if(certTBS[EXTENSIONS_REF].len != 0)
+ return TPM_RCS_VALUE + RC_CertifyX509_partialCertificate;
+ certTBS[EXTENSIONS_REF].buf = &ctx.buffer[startOfElement];
+ ctx.offset += length;
+ certTBS[EXTENSIONS_REF].len =
+ (INT16)ctx.offset - startOfElement;
+ }
+ else
+ return TPM_RCS_VALUE + RC_CertifyX509_partialCertificate;
+ }
+ // Make sure that we used all of the data and found at least the required
+ // number of elements.
+ if((ctx.offset != ctx.size) || (countOfSequences < 3)
+ || (countOfSequences > 4)
+ || (certTBS[EXTENSIONS_REF].buf == NULL))
+ return TPM_RCS_VALUE + RC_CertifyX509_partialCertificate;
+ // Now that we know how many sequences there were, we can put them where they
+ // belong
+ for(i = 0; i < countOfSequences; i++)
+ certTBS[SUBJECT_KEY_REF - i] = partial[countOfSequences - 1 - i];
+
+ // If only three SEQUENCES, then the TPM needs to produce the signature algorithm.
+ // See if it can
+ if((countOfSequences == 3) &&
+ (X509AddSigningAlgorithm(NULL, signKey, &in->inScheme) == 0))
+ return TPM_RCS_SCHEME + RC_CertifyX509_signHandle;
+
+ // Process the extensions
+ result = X509ProcessExtensions(object, &certTBS[EXTENSIONS_REF]);
+ if(result != TPM_RC_SUCCESS)
+ // If the extension has the TPMA_OBJECT extension and the attributes don't
+ // match, then the error code will be TPM_RCS_ATTRIBUTES. Otherwise, the error
+ // indicates a malformed partialCertificate.
+ return result + ((result == TPM_RCS_ATTRIBUTES)
+ ? RC_CertifyX509_objectHandle
+ : RC_CertifyX509_partialCertificate);
+ // Command Output
+ // Create the addedToCertificate values
+
+ // Build the addedToCertificate from the bottom up.
+ // Initialize the context structure
+ ASN1InitialializeMarshalContext(&ctxOut, sizeof(out->addedToCertificate.t.buffer),
+ out->addedToCertificate.t.buffer);
+ // Place a marker for the overall context
+ ASN1StartMarshalContext(&ctxOut); // SEQUENCE for addedToCertificate
+
+ // Add the subject public key descriptor
+ certTBS[SUBJECT_PUBLIC_KEY_REF].len = X509AddPublicKey(&ctxOut, object);
+ certTBS[SUBJECT_PUBLIC_KEY_REF].buf = ctxOut.buffer + ctxOut.offset;
+ // If the caller didn't provide the algorithm identifier, create it
+ if(certTBS[SIGNATURE_REF].len == 0)
+ {
+ certTBS[SIGNATURE_REF].len = X509AddSigningAlgorithm(&ctxOut, signKey,
+ &in->inScheme);
+ certTBS[SIGNATURE_REF].buf = ctxOut.buffer + ctxOut.offset;
+ }
+ // Create the serial number value. Use the out->tbsDigest as scratch.
+ {
+ TPM2B *digest = &out->tbsDigest.b;
+ //
+ digest->size = (INT16)CryptHashStart(&hash, signKey->publicArea.nameAlg);
+ pAssert(digest->size != 0);
+
+ // The serial number size is the smaller of the digest and the vendor-defined
+ // value
+ digest->size = MIN(digest->size, SIZE_OF_X509_SERIAL_NUMBER);
+ // Add all the parts of the certificate other than the serial number
+ // and version number
+ for(i = SIGNATURE_REF; i < REF_COUNT; i++)
+ CryptDigestUpdate(&hash, certTBS[i].len, certTBS[i].buf);
+ // throw in the Name of the signing key...
+ CryptDigestUpdate2B(&hash, &signKey->name.b);
+ // ...and the Name of the signed key.
+ CryptDigestUpdate2B(&hash, &object->name.b);
+ // Done
+ CryptHashEnd2B(&hash, digest);
+ }
+
+ // Add the serial number
+ certTBS[SERIAL_NUMBER_REF].len =
+ ASN1PushInteger(&ctxOut, out->tbsDigest.t.size, out->tbsDigest.t.buffer);
+ certTBS[SERIAL_NUMBER_REF].buf = ctxOut.buffer + ctxOut.offset;
+
+ // Add the static version number
+ ASN1StartMarshalContext(&ctxOut);
+ ASN1PushUINT(&ctxOut, 2);
+ certTBS[VERSION_REF].len =
+ ASN1EndEncapsulation(&ctxOut, ASN1_APPLICAIION_SPECIFIC);
+ certTBS[VERSION_REF].buf = ctxOut.buffer + ctxOut.offset;
+
+ // Create a fake tag and length for the TBS in the space used for
+ // 'addedToCertificate'
+ {
+ for(length = 0, i = 0; i < REF_COUNT; i++)
+ length += certTBS[i].len;
+ // Put a fake tag and length into the buffer for use in the tbsDigest
+ certTBS[ENCODED_SIZE_REF].len =
+ ASN1PushTagAndLength(&ctxOut, ASN1_CONSTRUCTED_SEQUENCE, length);
+ certTBS[ENCODED_SIZE_REF].buf = ctxOut.buffer + ctxOut.offset;
+ // Restore the buffer pointer to add back the number of octets used for the
+ // tag and length
+ ctxOut.offset += certTBS[ENCODED_SIZE_REF].len;
+ }
+ // sanity check
+ if(ctxOut.offset < 0)
+ return TPM_RC_FAILURE;
+ // Create the tbsDigest to sign
+ out->tbsDigest.t.size = CryptHashStart(&hash, in->inScheme.details.any.hashAlg);
+ for(i = 0; i < REF_COUNT; i++)
+ CryptDigestUpdate(&hash, certTBS[i].len, certTBS[i].buf);
+ CryptHashEnd2B(&hash, &out->tbsDigest.b);
+
+#if CERTIFYX509_DEBUG
+ {
+ BYTE fullTBS[4096];
+ BYTE *fill = fullTBS;
+ int j;
+ for (j = 0; j < REF_COUNT; j++)
+ {
+ MemoryCopy(fill, certTBS[j].buf, certTBS[j].len);
+ fill += certTBS[j].len;
+ }
+ DebugDumpBuffer((int)(fill - &fullTBS[0]), fullTBS, "\nfull TBS");
+ }
+#endif
+
+ // Finish up the processing of addedToCertificate
+ // Create the actual tag and length for the addedToCertificate structure
+ out->addedToCertificate.t.size =
+ ASN1EndEncapsulation(&ctxOut, ASN1_CONSTRUCTED_SEQUENCE);
+ // Now move all the addedToContext to the start of the buffer
+ MemoryCopy(out->addedToCertificate.t.buffer, ctxOut.buffer + ctxOut.offset,
+ out->addedToCertificate.t.size);
+#if CERTIFYX509_DEBUG
+ DebugDumpBuffer(out->addedToCertificate.t.size, out->addedToCertificate.t.buffer,
+ "\naddedToCertificate");
+#endif
+ // only thing missing is the signature
+ result = CryptSign(signKey, &in->inScheme, &out->tbsDigest, &out->signature);
+
+ return result;
+}
+#endif // CC_CertifyX509
diff --git a/src/tpm2/AuditCommands.c b/src/tpm2/AuditCommands.c
new file mode 100644
index 0000000..60960bb
--- /dev/null
+++ b/src/tpm2/AuditCommands.c
@@ -0,0 +1,112 @@
+/********************************************************************************/
+/* */
+/* Command Audit */
+/* Written by Ken Goldman */
+/* IBM Thomas J. Watson Research Center */
+/* $Id: AuditCommands.c 1490 2019-07-26 21:13:22Z kgoldman $ */
+/* */
+/* Licenses and Notices */
+/* */
+/* 1. Copyright Licenses: */
+/* */
+/* - Trusted Computing Group (TCG) grants to the user of the source code in */
+/* this specification (the "Source Code") a worldwide, irrevocable, */
+/* nonexclusive, royalty free, copyright license to reproduce, create */
+/* derivative works, distribute, display and perform the Source Code and */
+/* derivative works thereof, and to grant others the rights granted herein. */
+/* */
+/* - The TCG grants to the user of the other parts of the specification */
+/* (other than the Source Code) the rights to reproduce, distribute, */
+/* display, and perform the specification solely for the purpose of */
+/* developing products based on such documents. */
+/* */
+/* 2. Source Code Distribution Conditions: */
+/* */
+/* - Redistributions of Source Code must retain the above copyright licenses, */
+/* this list of conditions and the following disclaimers. */
+/* */
+/* - Redistributions in binary form must reproduce the above copyright */
+/* licenses, this list of conditions and the following disclaimers in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* 3. Disclaimers: */
+/* */
+/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
+/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
+/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
+/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
+/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
+/* information on specification licensing rights available through TCG */
+/* membership agreements. */
+/* */
+/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
+/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
+/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
+/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
+/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
+/* */
+/* - Without limitation, TCG and its members and licensors disclaim all */
+/* liability, including liability for infringement of any proprietary */
+/* rights, relating to use of information in this specification and to the */
+/* implementation of this specification, and TCG disclaims all liability for */
+/* cost of procurement of substitute goods or services, lost profits, loss */
+/* of use, loss of data or any incidental, consequential, direct, indirect, */
+/* or special damages, whether under contract, tort, warranty or otherwise, */
+/* arising in any way out of use or reliance upon this specification or any */
+/* information herein. */
+/* */
+/* (c) Copyright IBM Corp. and others, 2016 - 2018 */
+/* */
+/********************************************************************************/
+
+#include "Tpm.h"
+#include "SetCommandCodeAuditStatus_fp.h"
+#if CC_SetCommandCodeAuditStatus // Conditional expansion of this file
+TPM_RC
+TPM2_SetCommandCodeAuditStatus(
+ SetCommandCodeAuditStatus_In *in // IN: input parameter list
+ )
+{
+ // The command needs NV update. Check if NV is available.
+ // A TPM_RC_NV_UNAVAILABLE or TPM_RC_NV_RATE error may be returned at
+ // this point
+ RETURN_IF_NV_IS_NOT_AVAILABLE;
+ // Internal Data Update
+ // Update hash algorithm
+ if(in->auditAlg != TPM_ALG_NULL && in->auditAlg != gp.auditHashAlg)
+ {
+ // Can't change the algorithm and command list at the same time
+ if(in->setList.count != 0 || in->clearList.count != 0)
+ return TPM_RCS_VALUE + RC_SetCommandCodeAuditStatus_auditAlg;
+ // Change the hash algorithm for audit
+ gp.auditHashAlg = in->auditAlg;
+ // Set the digest size to a unique value that indicates that the digest
+ // algorithm has been changed. The size will be cleared to zero in the
+ // command audit processing on exit.
+ gr.commandAuditDigest.t.size = 1;
+ // Save the change of command audit data (this sets g_updateNV so that NV
+ // will be updated on exit.)
+ NV_SYNC_PERSISTENT(auditHashAlg);
+ }
+ else
+ {
+ UINT32 i;
+ BOOL changed = FALSE;
+ // Process set list
+ for(i = 0; i < in->setList.count; i++)
+ // If change is made in CommandAuditSet, set changed flag
+ if(CommandAuditSet(in->setList.commandCodes[i]))
+ changed = TRUE;
+ // Process clear list
+ for(i = 0; i < in->clearList.count; i++)
+ // If change is made in CommandAuditClear, set changed flag
+ if(CommandAuditClear(in->clearList.commandCodes[i]))
+ changed = TRUE;
+ // if change was made to command list, update NV
+ if(changed)
+ // this sets g_updateNV so that NV will be updated on exit.
+ NV_SYNC_PERSISTENT(auditCommands);
+ }
+ return TPM_RC_SUCCESS;
+}
+#endif // CC_SetCommandCodeAuditStatus
diff --git a/src/tpm2/BackwardsCompatibility.h b/src/tpm2/BackwardsCompatibility.h
new file mode 100644
index 0000000..6d33b60
--- /dev/null
+++ b/src/tpm2/BackwardsCompatibility.h
@@ -0,0 +1,49 @@
+/********************************************************************************/
+/* */
+/* Backwards compatibility related stuff */
+/* Written by Stefan Berger */
+/* IBM Thomas J. Watson Research Center */
+/* */
+/* (c) Copyright IBM Corporation 2017,2018. */
+/* */
+/* All rights reserved. */
+/* */
+/* Redistribution and use in source and binary forms, with or without */
+/* modification, are permitted provided that the following conditions are */
+/* met: */
+/* */
+/* Redistributions of source code must retain the above copyright notice, */
+/* this list of conditions and the following disclaimer. */
+/* */
+/* Redistributions in binary form must reproduce the above copyright */
+/* notice, this list of conditions and the following disclaimer in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* Neither the names of the IBM Corporation nor the names of its */
+/* contributors may be used to endorse or promote products derived from */
+/* this software without specific prior written permission. */
+/* */
+/* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS */
+/* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT */
+/* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR */
+/* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT */
+/* HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, */
+/* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT */
+/* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, */
+/* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY */
+/* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT */
+/* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE */
+/* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */
+/********************************************************************************/
+
+#ifndef BACKWARDS_COMPATIBILITY_H
+#define BACKWARDS_COMPATIBILITY_H
+
+typedef UINT8 SEED_COMPAT_LEVEL;
+enum {
+ SEED_COMPAT_LEVEL_ORIGINAL = 0, /* original TPM 2 code up to rev155 */
+ SEED_COMPAT_LEVEL_RSA_PRIME_ADJUST_FIX = 1, /* RsaAdjustPrimeCandidate was fixed */
+ SEED_COMPAT_LEVEL_LAST = SEED_COMPAT_LEVEL_RSA_PRIME_ADJUST_FIX
+};
+
+#endif /* BACKWARDS_COMPATIBILITY_H */
diff --git a/src/tpm2/BackwardsCompatibilityObject.c b/src/tpm2/BackwardsCompatibilityObject.c
new file mode 100644
index 0000000..93e5710
--- /dev/null
+++ b/src/tpm2/BackwardsCompatibilityObject.c
@@ -0,0 +1,238 @@
+/********************************************************************************/
+/* */
+/* Backwards compatibility stuff related to OBJECT */
+/* Written by Stefan Berger */
+/* IBM Thomas J. Watson Research Center */
+/* */
+/* (c) Copyright IBM Corporation 2017,2018. */
+/* */
+/* All rights reserved. */
+/* */
+/* Redistribution and use in source and binary forms, with or without */
+/* modification, are permitted provided that the following conditions are */
+/* met: */
+/* */
+/* Redistributions of source code must retain the above copyright notice, */
+/* this list of conditions and the following disclaimer. */
+/* */
+/* Redistributions in binary form must reproduce the above copyright */
+/* notice, this list of conditions and the following disclaimer in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* Neither the names of the IBM Corporation nor the names of its */
+/* contributors may be used to endorse or promote products derived from */
+/* this software without specific prior written permission. */
+/* */
+/* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS */
+/* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT */
+/* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR */
+/* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT */
+/* HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, */
+/* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT */
+/* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, */
+/* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY */
+/* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT */
+/* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE */
+/* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */
+/********************************************************************************/
+
+#include <assert.h>
+
+#include "BackwardsCompatibilityObject.h"
+
+#ifndef static_assert
+#define static_assert(test, msg)
+#endif
+
+/* The following are data structure from libtpms 0.7.x with RSA 2048 support
+ * that help to resume key and hash contexts (TPM2_ContextSave/Load) from this
+ * earlier version. All structures that have different sizes in 0.8 are found
+ * here.
+ */
+typedef union {
+ struct {
+ UINT16 size;
+ BYTE buffer[2048/8];
+ } t;
+ TPM2B b;
+} OLD_TPM2B_PUBLIC_KEY_RSA;
+
+typedef union {
+ TPM2B_DIGEST keyedHash;
+ TPM2B_DIGEST sym;
+ OLD_TPM2B_PUBLIC_KEY_RSA rsa;
+ TPMS_ECC_POINT ecc;
+// TPMS_DERIVE derive;
+} OLD_TPMU_PUBLIC_ID;
+
+typedef struct {
+ TPMI_ALG_PUBLIC type;
+ TPMI_ALG_HASH nameAlg;
+ TPMA_OBJECT objectAttributes;
+ TPM2B_DIGEST authPolicy;
+ TPMU_PUBLIC_PARMS parameters;
+ OLD_TPMU_PUBLIC_ID unique;
+} OLD_TPMT_PUBLIC;
+
+static_assert(sizeof(OLD_TPMT_PUBLIC) == 356,
+ "OLD_TPMT_PUBLIC has wrong size");
+
+typedef union {
+ struct {
+ UINT16 size;
+ BYTE buffer[((2048/8)/2)*5];
+ } t;
+ TPM2B b;
+} OLD_TPM2B_PRIVATE_KEY_RSA;
+
+static_assert(sizeof(OLD_TPM2B_PRIVATE_KEY_RSA) == 642,
+ "OLD_TPM2B_PRIVATE_KEY_RSA has wrong size");
+
+typedef union {
+ struct {
+ UINT16 size;
+ BYTE buffer[((2048/8)/2)*5];
+ } t;
+ TPM2B b;
+} OLD_TPM2B_PRIVATE_VENDOR_SPECIFIC;
+
+typedef union {
+ OLD_TPM2B_PRIVATE_KEY_RSA rsa;
+ TPM2B_ECC_PARAMETER ecc;
+ TPM2B_SENSITIVE_DATA bits;
+ TPM2B_SYM_KEY sym;
+ OLD_TPM2B_PRIVATE_VENDOR_SPECIFIC any;
+} OLD_TPMU_SENSITIVE_COMPOSITE;
+
+typedef struct {
+ TPMI_ALG_PUBLIC sensitiveType;
+ TPM2B_AUTH authValue;
+ TPM2B_DIGEST seedValue;
+ OLD_TPMU_SENSITIVE_COMPOSITE sensitive;
+} OLD_TPMT_SENSITIVE;
+
+static_assert(sizeof(OLD_TPMT_SENSITIVE) == 776,
+ "OLD_TPMT_SENSITIVE has wrong size");
+
+BN_TYPE(old_prime, (2048 / 2));
+
+typedef struct OLD_privateExponent
+{
+ bn_old_prime_t Q;
+ bn_old_prime_t dP;
+ bn_old_prime_t dQ;
+ bn_old_prime_t qInv;
+} OLD_privateExponent_t;
+
+static inline void CopyFromOldPrimeT(bn_prime_t *dst,
+ const bn_old_prime_t *src)
+{
+ dst->allocated = src->allocated;
+ dst->size = src->size;
+ memcpy(dst->d, src->d, sizeof(src->d));
+}
+
+static_assert(sizeof(OLD_privateExponent_t) == 608,
+ "OLD_privateExponent_t has wrong size");
+
+typedef struct OLD_OBJECT
+{
+ // The attributes field is required to be first followed by the publicArea.
+ // This allows the overlay of the object structure and a sequence structure
+ OBJECT_ATTRIBUTES attributes; // object attributes
+ OLD_TPMT_PUBLIC publicArea; // public area of an object
+ OLD_TPMT_SENSITIVE sensitive; // sensitive area of an object
+ OLD_privateExponent_t privateExponent; // Additional field for the private
+ TPM2B_NAME qualifiedName; // object qualified name
+ TPMI_DH_OBJECT evictHandle; // if the object is an evict object,
+ // the original handle is kept here.
+ // The 'working' handle will be the
+ // handle of an object slot.
+ TPM2B_NAME name; // Name of the object name. Kept here
+ // to avoid repeatedly computing it.
+
+ // libtpms added: OBJECT lies in NVRAM; to avoid that it needs different number
+ // of bytes on 32 bit and 64 bit architectures, we need to make sure it's the
+ // same size; simple padding at the end works here
+ UINT32 _pad;
+} OLD_OBJECT;
+
+static_assert(sizeof(OLD_OBJECT) == 1896,
+ "OLD_OBJECT has wrong size");
+
+// Convert an OLD_OBJECT that was copied into buffer using MemoryCopy
+TPM_RC
+OLD_OBJECTToOBJECT(OBJECT *newObject, BYTE *buffer, INT32 size)
+{
+ OLD_OBJECT oldObject;
+ TPM_RC rc = 0;
+
+ // get the attributes
+ MemoryCopy(newObject, buffer, sizeof(newObject->attributes));
+ if (ObjectIsSequence(newObject))
+ {
+ /* resuming old hash contexts is not supported */
+ rc = TPM_RC_DISABLED;
+ }
+ else
+ {
+ if (size != sizeof(OLD_OBJECT))
+ return TPM_RC_SIZE;
+ MemoryCopy(&oldObject, buffer, sizeof(OLD_OBJECT));
+
+ /* fill the newObject with the contents of the oldObject */
+ newObject->attributes = oldObject.attributes;
+
+ newObject->publicArea.type = oldObject.publicArea.type;
+ newObject->publicArea.nameAlg = oldObject.publicArea.nameAlg;
+ newObject->publicArea.objectAttributes = oldObject.publicArea.objectAttributes;
+ newObject->publicArea.authPolicy = oldObject.publicArea.authPolicy;
+ newObject->publicArea.parameters = oldObject.publicArea.parameters;
+ /* the unique part can be one or two TPM2B's */
+ switch (newObject->publicArea.type) {
+ case TPM_ALG_KEYEDHASH:
+ MemoryCopy2B(&newObject->publicArea.unique.keyedHash.b,
+ &oldObject.publicArea.unique.keyedHash.b,
+ sizeof(oldObject.publicArea.unique.keyedHash.t.buffer));
+ break;
+ case TPM_ALG_SYMCIPHER:
+ MemoryCopy2B(&newObject->publicArea.unique.sym.b,
+ &oldObject.publicArea.unique.sym.b,
+ sizeof(oldObject.publicArea.unique.sym.t.buffer));
+ break;
+ case TPM_ALG_RSA:
+ MemoryCopy2B(&newObject->publicArea.unique.rsa.b,
+ &oldObject.publicArea.unique.rsa.b,
+ sizeof(oldObject.publicArea.unique.rsa.t.buffer));
+ break;
+ case TPM_ALG_ECC:
+ MemoryCopy2B(&newObject->publicArea.unique.ecc.x.b,
+ &oldObject.publicArea.unique.ecc.x.b,
+ sizeof(oldObject.publicArea.unique.ecc.x.t.buffer));
+ MemoryCopy2B(&newObject->publicArea.unique.ecc.y.b,
+ &oldObject.publicArea.unique.ecc.y.b,
+ sizeof(oldObject.publicArea.unique.ecc.y.t.buffer));
+ break;
+ }
+
+ newObject->sensitive.sensitiveType = oldObject.sensitive.sensitiveType;
+ newObject->sensitive.authValue = oldObject.sensitive.authValue;
+ newObject->sensitive.seedValue = oldObject.sensitive.seedValue;
+ /* The OLD_TPMU_SENSITIVE_COMPOSITE is always a TPM2B */
+ MemoryCopy2B(&newObject->sensitive.sensitive.any.b,
+ &oldObject.sensitive.sensitive.any.b,
+ sizeof(oldObject.sensitive.sensitive.any.t.buffer));
+
+ CopyFromOldPrimeT(&newObject->privateExponent.Q, &oldObject.privateExponent.Q);
+ CopyFromOldPrimeT(&newObject->privateExponent.dP, &oldObject.privateExponent.dP);
+ CopyFromOldPrimeT(&newObject->privateExponent.dQ, &oldObject.privateExponent.dQ);
+ CopyFromOldPrimeT(&newObject->privateExponent.qInv, &oldObject.privateExponent.qInv);
+
+ newObject->qualifiedName = oldObject.qualifiedName;
+ newObject->evictHandle = oldObject.evictHandle;
+ newObject->name = oldObject.name;
+ }
+
+ return rc;
+}
+
diff --git a/src/tpm2/BackwardsCompatibilityObject.h b/src/tpm2/BackwardsCompatibilityObject.h
new file mode 100644
index 0000000..7a2b1ab
--- /dev/null
+++ b/src/tpm2/BackwardsCompatibilityObject.h
@@ -0,0 +1,47 @@
+/********************************************************************************/
+/* */
+/* Backwards compatibility stuff related to OBJECT */
+/* Written by Stefan Berger */
+/* IBM Thomas J. Watson Research Center */
+/* */
+/* (c) Copyright IBM Corporation 2017,2018. */
+/* */
+/* All rights reserved. */
+/* */
+/* Redistribution and use in source and binary forms, with or without */
+/* modification, are permitted provided that the following conditions are */
+/* met: */
+/* */
+/* Redistributions of source code must retain the above copyright notice, */
+/* this list of conditions and the following disclaimer. */
+/* */
+/* Redistributions in binary form must reproduce the above copyright */
+/* notice, this list of conditions and the following disclaimer in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* Neither the names of the IBM Corporation nor the names of its */
+/* contributors may be used to endorse or promote products derived from */
+/* this software without specific prior written permission. */
+/* */
+/* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS */
+/* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT */
+/* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR */
+/* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT */
+/* HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, */
+/* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT */
+/* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, */
+/* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY */
+/* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT */
+/* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE */
+/* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */
+/********************************************************************************/
+
+#ifndef BACKWARDS_COMPATIBILITY_OBJECT_H
+#define BACKWARDS_COMPATIBILITY_OBJECT_H
+
+#include "Tpm.h"
+
+TPM_RC OLD_OBJECTToOBJECT(OBJECT *object, BYTE *buffer, INT32 size);
+
+#endif /* BACKWARDS_COMPATIBILITY_OBJECT_H */
+
diff --git a/src/tpm2/BaseTypes.h b/src/tpm2/BaseTypes.h
new file mode 100644
index 0000000..b134b22
--- /dev/null
+++ b/src/tpm2/BaseTypes.h
@@ -0,0 +1,85 @@
+/********************************************************************************/
+/* */
+/* Basic Typedefs */
+/* Written by Ken Goldman */
+/* IBM Thomas J. Watson Research Center */
+/* $Id: BaseTypes.h 1531 2019-11-21 23:54:38Z kgoldman $ */
+/* */
+/* Licenses and Notices */
+/* */
+/* 1. Copyright Licenses: */
+/* */
+/* - Trusted Computing Group (TCG) grants to the user of the source code in */
+/* this specification (the "Source Code") a worldwide, irrevocable, */
+/* nonexclusive, royalty free, copyright license to reproduce, create */
+/* derivative works, distribute, display and perform the Source Code and */
+/* derivative works thereof, and to grant others the rights granted herein. */
+/* */
+/* - The TCG grants to the user of the other parts of the specification */
+/* (other than the Source Code) the rights to reproduce, distribute, */
+/* display, and perform the specification solely for the purpose of */
+/* developing products based on such documents. */
+/* */
+/* 2. Source Code Distribution Conditions: */
+/* */
+/* - Redistributions of Source Code must retain the above copyright licenses, */
+/* this list of conditions and the following disclaimers. */
+/* */
+/* - Redistributions in binary form must reproduce the above copyright */
+/* licenses, this list of conditions and the following disclaimers in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* 3. Disclaimers: */
+/* */
+/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
+/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
+/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
+/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
+/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
+/* information on specification licensing rights available through TCG */
+/* membership agreements. */
+/* */
+/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
+/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
+/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
+/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
+/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
+/* */
+/* - Without limitation, TCG and its members and licensors disclaim all */
+/* liability, including liability for infringement of any proprietary */
+/* rights, relating to use of information in this specification and to the */
+/* implementation of this specification, and TCG disclaims all liability for */
+/* cost of procurement of substitute goods or services, lost profits, loss */
+/* of use, loss of data or any incidental, consequential, direct, indirect, */
+/* or special damages, whether under contract, tort, warranty or otherwise, */
+/* arising in any way out of use or reliance upon this specification or any */
+/* information herein. */
+/* */
+/* (c) Copyright IBM Corp. and others, 2016 - 2019 */
+/* */
+/********************************************************************************/
+
+/* 5.2 BaseTypes.h */
+
+#ifndef BASETYPES_H
+#define BASETYPES_H
+
+#include <stdint.h>
+
+/* NULL definition */
+
+#ifndef NULL
+#define NULL (0)
+#endif
+typedef uint8_t UINT8;
+typedef uint8_t BYTE;
+typedef int8_t INT8;
+typedef int BOOL;
+typedef uint16_t UINT16;
+typedef int16_t INT16;
+typedef uint32_t UINT32;
+typedef int32_t INT32;
+typedef uint64_t UINT64;
+typedef int64_t INT64;
+
+#endif
diff --git a/src/tpm2/Bits.c b/src/tpm2/Bits.c
new file mode 100644
index 0000000..5fb4785
--- /dev/null
+++ b/src/tpm2/Bits.c
@@ -0,0 +1,114 @@
+/********************************************************************************/
+/* */
+/* Bit Manipulation Routines */
+/* Written by Ken Goldman */
+/* IBM Thomas J. Watson Research Center */
+/* $Id: Bits.c 1490 2019-07-26 21:13:22Z kgoldman $ */
+/* */
+/* Licenses and Notices */
+/* */
+/* 1. Copyright Licenses: */
+/* */
+/* - Trusted Computing Group (TCG) grants to the user of the source code in */
+/* this specification (the "Source Code") a worldwide, irrevocable, */
+/* nonexclusive, royalty free, copyright license to reproduce, create */
+/* derivative works, distribute, display and perform the Source Code and */
+/* derivative works thereof, and to grant others the rights granted herein. */
+/* */
+/* - The TCG grants to the user of the other parts of the specification */
+/* (other than the Source Code) the rights to reproduce, distribute, */
+/* display, and perform the specification solely for the purpose of */
+/* developing products based on such documents. */
+/* */
+/* 2. Source Code Distribution Conditions: */
+/* */
+/* - Redistributions of Source Code must retain the above copyright licenses, */
+/* this list of conditions and the following disclaimers. */
+/* */
+/* - Redistributions in binary form must reproduce the above copyright */
+/* licenses, this list of conditions and the following disclaimers in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* 3. Disclaimers: */
+/* */
+/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
+/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
+/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
+/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
+/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
+/* information on specification licensing rights available through TCG */
+/* membership agreements. */
+/* */
+/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
+/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
+/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
+/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
+/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
+/* */
+/* - Without limitation, TCG and its members and licensors disclaim all */
+/* liability, including liability for infringement of any proprietary */
+/* rights, relating to use of information in this specification and to the */
+/* implementation of this specification, and TCG disclaims all liability for */
+/* cost of procurement of substitute goods or services, lost profits, loss */
+/* of use, loss of data or any incidental, consequential, direct, indirect, */
+/* or special damages, whether under contract, tort, warranty or otherwise, */
+/* arising in any way out of use or reliance upon this specification or any */
+/* information herein. */
+/* */
+/* (c) Copyright IBM Corp. and others, 2016 - 2018 */
+/* */
+/********************************************************************************/
+
+/* 9.2 Bits.c */
+/* 9.2.1 Introduction */
+/* This file contains bit manipulation routines. They operate on bit arrays. */
+/* The 0th bit in the array is the right-most bit in the 0th octet in the array. */
+/* NOTE: If pAssert() is defined, the functions will assert if the indicated bit number is outside
+ of the range of bArray. How the assert is handled is implementation dependent. */
+/* 9.2.2 Includes */
+#include "Tpm.h"
+/* 9.2.3 Functions */
+/* 9.2.3.1 TestBit() */
+/* This function is used to check the setting of a bit in an array of bits. */
+/* Return Values Meaning */
+/* TRUE bit is set */
+/* FALSE bit is not set */
+
+BOOL
+TestBit(
+ unsigned int bitNum, // IN: number of the bit in 'bArray'
+ BYTE *bArray, // IN: array containing the bits
+ unsigned int bytesInArray // IN: size in bytes of 'bArray'
+ )
+{
+ pAssert(bytesInArray > (bitNum >> 3));
+ return((bArray[bitNum >> 3] & (1 << (bitNum & 7))) != 0);
+}
+
+/* 9.2.3.2 SetBit() */
+/* This function will set the indicated bit in bArray. */
+
+void
+SetBit(
+ unsigned int bitNum, // IN: number of the bit in 'bArray'
+ BYTE *bArray, // IN: array containing the bits
+ unsigned int bytesInArray // IN: size in bytes of 'bArray'
+ )
+{
+ pAssert(bytesInArray > (bitNum >> 3));
+ bArray[bitNum >> 3] |= (1 << (bitNum & 7));
+}
+
+/* 9.2.3.3 ClearBit() */
+/* This function will clear the indicated bit in bArray. */
+
+void
+ClearBit(
+ unsigned int bitNum, // IN: number of the bit in 'bArray'.
+ BYTE *bArray, // IN: array containing the bits
+ unsigned int bytesInArray // IN: size in bytes of 'bArray'
+ )
+{
+ pAssert(bytesInArray > (bitNum >> 3));
+ bArray[bitNum >> 3] &= ~(1 << (bitNum & 7));
+}
diff --git a/src/tpm2/Bits_fp.h b/src/tpm2/Bits_fp.h
new file mode 100644
index 0000000..c4775cd
--- /dev/null
+++ b/src/tpm2/Bits_fp.h
@@ -0,0 +1,98 @@
+/********************************************************************************/
+/* */
+/* Bit Handling */
+/* Written by Ken Goldman */
+/* IBM Thomas J. Watson Research Center */
+/* $Id: Bits_fp.h 803 2016-11-15 20:19:26Z kgoldman */
+/* */
+/* Licenses and Notices */
+/* */
+/* 1. Copyright Licenses: */
+/* */
+/* - Trusted Computing Group (TCG) grants to the user of the source code in */
+/* this specification (the "Source Code") a worldwide, irrevocable, */
+/* nonexclusive, royalty free, copyright license to reproduce, create */
+/* derivative works, distribute, display and perform the Source Code and */
+/* derivative works thereof, and to grant others the rights granted herein. */
+/* */
+/* - The TCG grants to the user of the other parts of the specification */
+/* (other than the Source Code) the rights to reproduce, distribute, */
+/* display, and perform the specification solely for the purpose of */
+/* developing products based on such documents. */
+/* */
+/* 2. Source Code Distribution Conditions: */
+/* */
+/* - Redistributions of Source Code must retain the above copyright licenses, */
+/* this list of conditions and the following disclaimers. */
+/* */
+/* - Redistributions in binary form must reproduce the above copyright */
+/* licenses, this list of conditions and the following disclaimers in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* 3. Disclaimers: */
+/* */
+/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
+/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
+/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
+/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
+/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
+/* information on specification licensing rights available through TCG */
+/* membership agreements. */
+/* */
+/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
+/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
+/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
+/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
+/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
+/* */
+/* - Without limitation, TCG and its members and licensors disclaim all */
+/* liability, including liability for infringement of any proprietary */
+/* rights, relating to use of information in this specification and to the */
+/* implementation of this specification, and TCG disclaims all liability for */
+/* cost of procurement of substitute goods or services, lost profits, loss */
+/* of use, loss of data or any incidental, consequential, direct, indirect, */
+/* or special damages, whether under contract, tort, warranty or otherwise, */
+/* arising in any way out of use or reliance upon this specification or any */
+/* information herein. */
+/* */
+/* (c) Copyright IBM Corp. and others, 2016 - 2018 */
+/* */
+/********************************************************************************/
+
+#ifndef BITS_FP_H
+#define BITS_FP_H
+
+/* 5.3.1 TestBit() */
+/* This function is used to check the setting of a bit in an array of bits. */
+/* Return Value Meaning */
+/* TRUE bit is set */
+/* FALSE bit is not set */
+
+BOOL
+TestBit(
+ unsigned int bitNum, // IN: number of the bit in 'bArray'
+ BYTE *bArray, // IN: array containing the bits
+ unsigned int bytesInArray // IN: size in bytes of 'bArray'
+ );
+
+/* 5.3.2 SetBit() */
+/* This function will set the indicated bit in bArray. */
+
+void
+SetBit(
+ unsigned int bitNum, // IN: number of the bit in 'bArray'
+ BYTE *bArray, // IN: array containing the bits
+ unsigned int bytesInArray // IN: size in bytes of 'bArray'
+ );
+
+/* 5.3.3 ClearBit() */
+/* This function will clear the indicated bit in bArray. */
+
+void
+ClearBit(
+ unsigned int bitNum, // IN: number of the bit in 'bArray'.
+ BYTE *bArray, // IN: array containing the bits
+ unsigned int bytesInArray // IN: size in bytes of 'bArray'
+ );
+
+#endif
diff --git a/src/tpm2/BnConvert.c b/src/tpm2/BnConvert.c
new file mode 100644
index 0000000..49cd6d5
--- /dev/null
+++ b/src/tpm2/BnConvert.c
@@ -0,0 +1,299 @@
+/********************************************************************************/
+/* */
+/* conversion functions that will convert TPM2B to/from internal format */
+/* Written by Ken Goldman */
+/* IBM Thomas J. Watson Research Center */
+/* $Id: BnConvert.c 1519 2019-11-15 20:43:51Z kgoldman $ */
+/* */
+/* Licenses and Notices */
+/* */
+/* 1. Copyright Licenses: */
+/* */
+/* - Trusted Computing Group (TCG) grants to the user of the source code in */
+/* this specification (the "Source Code") a worldwide, irrevocable, */
+/* nonexclusive, royalty free, copyright license to reproduce, create */
+/* derivative works, distribute, display and perform the Source Code and */
+/* derivative works thereof, and to grant others the rights granted herein. */
+/* */
+/* - The TCG grants to the user of the other parts of the specification */
+/* (other than the Source Code) the rights to reproduce, distribute, */
+/* display, and perform the specification solely for the purpose of */
+/* developing products based on such documents. */
+/* */
+/* 2. Source Code Distribution Conditions: */
+/* */
+/* - Redistributions of Source Code must retain the above copyright licenses, */
+/* this list of conditions and the following disclaimers. */
+/* */
+/* - Redistributions in binary form must reproduce the above copyright */
+/* licenses, this list of conditions and the following disclaimers in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* 3. Disclaimers: */
+/* */
+/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
+/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
+/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
+/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
+/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
+/* information on specification licensing rights available through TCG */
+/* membership agreements. */
+/* */
+/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
+/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
+/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
+/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
+/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
+/* */
+/* - Without limitation, TCG and its members and licensors disclaim all */
+/* liability, including liability for infringement of any proprietary */
+/* rights, relating to use of information in this specification and to the */
+/* implementation of this specification, and TCG disclaims all liability for */
+/* cost of procurement of substitute goods or services, lost profits, loss */
+/* of use, loss of data or any incidental, consequential, direct, indirect, */
+/* or special damages, whether under contract, tort, warranty or otherwise, */
+/* arising in any way out of use or reliance upon this specification or any */
+/* information herein. */
+/* */
+/* (c) Copyright IBM Corp. and others, 2016 - 2019 */
+/* */
+/********************************************************************************/
+
+/* 10.2.2 BnConvert.c */
+/* 10.2.2.1 Introduction */
+/* This file contains the basic conversion functions that will convert TPM2B to/from the internal
+ format. The internal format is a bigNum, */
+/* 10.2.2.2 Includes */
+#include "Tpm.h"
+/* 10.2.2.3 Functions */
+/* 10.2.2.3.1 BnFromBytes() */
+/* This function will convert a big-endian byte array to the internal number format. If bn is NULL,
+ then the output is NULL. If bytes is null or the required size is 0, then the output is set to
+ zero */
+LIB_EXPORT bigNum
+BnFromBytes(
+ bigNum bn,
+ const BYTE *bytes,
+ NUMBYTES nBytes
+ )
+{
+ const BYTE *pFrom; // 'p' points to the least significant bytes of source
+ BYTE *pTo; // points to least significant bytes of destination
+ crypt_uword_t size;
+ //
+ size = (bytes != NULL) ? BYTES_TO_CRYPT_WORDS(nBytes) : 0;
+ // If nothing in, nothing out
+ if(bn == NULL)
+ return NULL;
+ // make sure things fit
+ pAssert(BnGetAllocated(bn) >= size);
+ if(size > 0)
+ {
+ // Clear the topmost word in case it is not filled with data
+ bn->d[size - 1] = 0;
+ // Moving the input bytes from the end of the list (LSB) end
+ pFrom = bytes + nBytes - 1;
+ // To the LS0 of the LSW of the bigNum.
+ pTo = (BYTE *)bn->d;
+ for(; nBytes != 0; nBytes--)
+ *pTo++ = *pFrom--;
+ // For a little-endian machine, the conversion is a straight byte
+ // reversal. For a big-endian machine, we have to put the words in
+ // big-endian byte order
+#if BIG_ENDIAN_TPM
+ {
+ crypt_word_t t;
+ for(t = (crypt_word_t)size - 1; t >= 0; t--)
+ bn->d[t] = SWAP_CRYPT_WORD(bn->d[t]);
+ }
+#endif
+ }
+ BnSetTop(bn, size);
+ return bn;
+}
+/* 10.2.2.3.2 BnFrom2B() */
+/* Convert an TPM2B to a BIG_NUM. If the input value does not exist, or the output does not exist,
+ or the input will not fit into the output the function returns NULL */
+LIB_EXPORT bigNum
+BnFrom2B(
+ bigNum bn, // OUT:
+ const TPM2B *a2B // IN: number to convert
+ )
+{
+ if(a2B != NULL)
+ return BnFromBytes(bn, a2B->buffer, a2B->size);
+ // Make sure that the number has an initialized value rather than whatever
+ // was there before
+ BnSetTop(bn, 0); // Function accepts NULL
+ return NULL;
+}
+/* 10.2.2.3.3 BnFromHex() */
+/* Convert a hex string into a bigNum. This is primarily used in debugging. */
+#ifdef _SM2_SIGN_DEBUG // libtpms added
+LIB_EXPORT bigNum
+BnFromHex(
+ bigNum bn, // OUT:
+ const char *hex // IN:
+ )
+{
+#define FromHex(a) ((a) - (((a) > 'a') ? ('a' + 10) \
+ : ((a) > 'A') ? ('A' - 10) : '0'))
+ unsigned i;
+ unsigned wordCount;
+ const char *p;
+ BYTE *d = (BYTE *)&(bn->d[0]);
+ //
+ pAssert(bn && hex);
+ i = (unsigned)strlen(hex);
+ wordCount = BYTES_TO_CRYPT_WORDS((i + 1) / 2);
+ if((i == 0) || (wordCount >= BnGetAllocated(bn)))
+ BnSetWord(bn, 0);
+ else
+ {
+ bn->d[wordCount - 1] = 0;
+ p = hex + i - 1;
+ for(;i > 1; i -= 2)
+ {
+ BYTE a;
+ a = FromHex(*p);
+ p--;
+ *d++ = a + (FromHex(*p) << 4);
+ p--;
+ }
+ if(i == 1)
+ *d = FromHex(*p);
+ }
+#if !BIG_ENDIAN_TPM
+ for(i = 0; i < wordCount; i++)
+ bn->d[i] = SWAP_CRYPT_WORD(bn->d[i]);
+#endif // BIG_ENDIAN_TPM
+ BnSetTop(bn, wordCount);
+ return bn;
+}
+#endif // libtpms added
+/* 10.2.2.3.4 BnToBytes() */
+/* This function converts a BIG_NUM to a byte array. It converts the bigNum to a big-endian byte
+ string and sets size to the normalized value. If size is an input 0, then the receiving buffer is
+ guaranteed to be large enough for the result and the size will be set to the size required for
+ bigNum (leading zeros suppressed). */
+/* The conversion for a little-endian machine simply requires that all significant bytes of the
+ bigNum be reversed. For a big-endian machine, rather than unpack each word individually,
+ the bigNum is converted to little-endian words, copied, and then converted back to big-endian. */
+LIB_EXPORT BOOL
+BnToBytes(
+ bigConst bn,
+ BYTE *buffer,
+ NUMBYTES *size // This the number of bytes that are
+ // available in the buffer. The result
+ // should be this big.
+ )
+{
+ crypt_uword_t requiredSize;
+ BYTE *pFrom;
+ BYTE *pTo;
+ crypt_uword_t count;
+ //
+ // validate inputs
+ pAssert(bn && buffer && size);
+ requiredSize = (BnSizeInBits(bn) + 7) / 8;
+ if(requiredSize == 0)
+ {
+ // If the input value is 0, return a byte of zero
+ *size = 1;
+ *buffer = 0;
+ }
+ else
+ {
+#if BIG_ENDIAN_TPM
+ // Copy the constant input value into a modifiable value
+ BN_VAR(bnL, LARGEST_NUMBER_BITS * 2);
+ BnCopy(bnL, bn);
+ // byte swap the words in the local value to make them little-endian
+ for(count = 0; count < bnL->size; count++)
+ bnL->d[count] = SWAP_CRYPT_WORD(bnL->d[count]);
+ bn = (bigConst)bnL;
+#endif
+ if(*size == 0)
+ *size = (NUMBYTES)requiredSize;
+ pAssert(requiredSize <= *size);
+ // Byte swap the number (not words but the whole value)
+ count = *size;
+ // Start from the least significant word and offset to the most significant
+ // byte which is in some high word
+ pFrom = (BYTE *)(&bn->d[0]) + requiredSize - 1;
+ pTo = buffer;
+ // If the number of output bytes is larger than the number bytes required
+ // for the input number, pad with zeros
+ for(count = *size; count > requiredSize; count--)
+ *pTo++ = 0;
+ // Move the most significant byte at the end of the BigNum to the next most
+ // significant byte position of the 2B and repeat for all significant bytes.
+ for(; requiredSize > 0; requiredSize--)
+ *pTo++ = *pFrom--;
+ }
+ return TRUE;
+}
+/* 10.2.2.3.5 BnTo2B() */
+/* Function to convert a BIG_NUM to TPM2B. The TPM2B size is set to the requested size which may
+ require padding. If size is non-zero and less than required by the value in bn then an error is
+ returned. If size is zero, then the TPM2B is assumed to be large enough for the data and
+ a2b->size will be adjusted accordingly. */
+LIB_EXPORT BOOL
+BnTo2B(
+ bigConst bn, // IN:
+ TPM2B *a2B, // OUT:
+ NUMBYTES size // IN: the desired size
+ )
+{
+ // Set the output size
+ if(bn && a2B)
+ {
+ a2B->size = size;
+ return BnToBytes(bn, a2B->buffer, &a2B->size);
+ }
+ return FALSE;
+}
+#if ALG_ECC
+/* 10.2.2.3.6 BnPointFrom2B() */
+/* Function to create a BIG_POINT structure from a 2B point. A point is going to be two ECC values
+ in the same buffer. The values are going to be the size of the modulus. They are in modular
+ form. */
+LIB_EXPORT bn_point_t *
+BnPointFrom2B(
+ bigPoint ecP, // OUT: the preallocated point structure
+ TPMS_ECC_POINT *p // IN: the number to convert
+ )
+{
+ if(p == NULL)
+ return NULL;
+ if(NULL != ecP)
+ {
+ BnFrom2B(ecP->x, &p->x.b);
+ BnFrom2B(ecP->y, &p->y.b);
+ BnSetWord(ecP->z, 1);
+ }
+ return ecP;
+}
+/* 10.2.2.3.7 BnPointTo2B() */
+/* This function converts a BIG_POINT into a TPMS_ECC_POINT. A TPMS_ECC_POINT contains two
+ TPM2B_ECC_PARAMETER values. The maximum size of the parameters is dependent on the maximum EC key
+ size used in an implementation. The presumption is that the TPMS_ECC_POINT is large enough to
+ hold 2 TPM2B values, each as large as a MAX_ECC_PARAMETER_BYTES */
+LIB_EXPORT BOOL
+BnPointTo2B(
+ TPMS_ECC_POINT *p, // OUT: the converted 2B structure
+ bigPoint ecP, // IN: the values to be converted
+ bigCurve E // IN: curve descriptor for the point
+ )
+{
+ UINT16 size;
+ //
+ pAssert(p && ecP && E);
+ pAssert(BnEqualWord(ecP->z, 1));
+ // BnMsb is the bit number of the MSB. This is one less than the number of bits
+ size = (UINT16)BITS_TO_BYTES(BnSizeInBits(CurveGetOrder(AccessCurveData(E))));
+ BnTo2B(ecP->x, &p->x.b, size);
+ BnTo2B(ecP->y, &p->y.b, size);
+ return TRUE;
+}
+#endif // TPM_ALG_ECC
diff --git a/src/tpm2/BnMath.c b/src/tpm2/BnMath.c
new file mode 100644
index 0000000..0154fb5
--- /dev/null
+++ b/src/tpm2/BnMath.c
@@ -0,0 +1,651 @@
+/********************************************************************************/
+/* */
+/* Simple Operations on Big Numbers */
+/* Written by Ken Goldman */
+/* IBM Thomas J. Watson Research Center */
+/* $Id: BnMath.c 1529 2019-11-21 23:29:01Z kgoldman $ */
+/* */
+/* Licenses and Notices */
+/* */
+/* 1. Copyright Licenses: */
+/* */
+/* - Trusted Computing Group (TCG) grants to the user of the source code in */
+/* this specification (the "Source Code") a worldwide, irrevocable, */
+/* nonexclusive, royalty free, copyright license to reproduce, create */
+/* derivative works, distribute, display and perform the Source Code and */
+/* derivative works thereof, and to grant others the rights granted herein. */
+/* */
+/* - The TCG grants to the user of the other parts of the specification */
+/* (other than the Source Code) the rights to reproduce, distribute, */
+/* display, and perform the specification solely for the purpose of */
+/* developing products based on such documents. */
+/* */
+/* 2. Source Code Distribution Conditions: */
+/* */
+/* - Redistributions of Source Code must retain the above copyright licenses, */
+/* this list of conditions and the following disclaimers. */
+/* */
+/* - Redistributions in binary form must reproduce the above copyright */
+/* licenses, this list of conditions and the following disclaimers in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* 3. Disclaimers: */
+/* */
+/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
+/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
+/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
+/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
+/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
+/* information on specification licensing rights available through TCG */
+/* membership agreements. */
+/* */
+/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
+/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
+/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
+/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
+/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
+/* */
+/* - Without limitation, TCG and its members and licensors disclaim all */
+/* liability, including liability for infringement of any proprietary */
+/* rights, relating to use of information in this specification and to the */
+/* implementation of this specification, and TCG disclaims all liability for */
+/* cost of procurement of substitute goods or services, lost profits, loss */
+/* of use, loss of data or any incidental, consequential, direct, indirect, */
+/* or special damages, whether under contract, tort, warranty or otherwise, */
+/* arising in any way out of use or reliance upon this specification or any */
+/* information herein. */
+/* */
+/* (c) Copyright IBM Corp. and others, 2016 - 2019 */
+/* */
+/********************************************************************************/
+
+/* 10.2.3 BnMath.c */
+
+/* 10.2.3.1 Introduction */
+/* The simulator code uses the canonical form whenever possible in order to make the code in Part 3
+ more accessible. The canonical data formats are simple and not well suited for complex big number
+ computations. When operating on big numbers, the data format is changed for easier
+ manipulation. The format is native words in little-endian format. As the magnitude of the number
+ decreases, the length of the array containing the number decreases but the starting address
+ doesn't change. */
+/* The functions in this file perform simple operations on these big numbers. Only the more complex
+ operations are passed to the underlying support library. Although the support library would have
+ most of these functions, the interface code to convert the format for the values is greater than
+ the size of the code to implement the functions here. So, rather than incur the overhead of
+ conversion, they are done here. */
+/* If an implementer would prefer, the underlying library can be used simply by making code
+ substitutions here. */
+/* NOTE: There is an intention to continue to augment these functions so that there would be no need
+ to use an external big number library. */
+/* Many of these functions have no error returns and will always return TRUE. This is to allow them
+ to be used in guarded sequences. That is: OK = OK || BnSomething(s); where the BnSomething()
+ function should not be called if OK isn't true. */
+
+/* 10.2.3.2 Includes */
+#include "Tpm.h"
+/* A constant value of zero as a stand in for NULL bigNum values */
+const bignum_t BnConstZero = {1, 0, {0}};
+/* 10.2.3.3 Functions */
+/* 10.2.3.3.1 AddSame() */
+/* Adds two values that are the same size. This function allows result to be the same as either of
+ the addends. This is a nice function to put into assembly because handling the carry for
+ multi-precision stuff is not as easy in C (unless there is a REALLY smart compiler). It would be
+ nice if there were idioms in a language that a compiler could recognize what is going on and
+ optimize loops like this. */
+/* Return Values Meaning */
+/* 0 no carry out */
+/* 1 carry out */
+static BOOL
+AddSame(
+ crypt_uword_t *result,
+ const crypt_uword_t *op1,
+ const crypt_uword_t *op2,
+ int count
+ )
+{
+ int carry = 0;
+ int i;
+ for(i = 0; i < count; i++)
+ {
+ crypt_uword_t a = op1[i];
+ crypt_uword_t sum = a + op2[i];
+ result[i] = sum + carry;
+ // generate a carry if the sum is less than either of the inputs
+ // propagate a carry if there was a carry and the sum + carry is zero
+ // do this using bit operations rather than logical operations so that
+ // the time is about the same.
+ // propagate term | generate term
+ carry = ((result[i] == 0) & carry) | (sum < a);
+ }
+ return carry;
+}
+/* 10.2.3.3.2 CarryProp() */
+/* Propagate a carry */
+static int
+CarryProp(
+ crypt_uword_t *result,
+ const crypt_uword_t *op,
+ int count,
+ int carry
+ )
+{
+ for(; count; count--)
+ carry = ((*result++ = *op++ + carry) == 0) & carry;
+ return carry;
+}
+static void
+CarryResolve(
+ bigNum result,
+ int stop,
+ int carry
+ )
+{
+ if(carry)
+ {
+ pAssert((unsigned)stop < result->allocated);
+ result->d[stop++] = 1;
+ }
+ BnSetTop(result, stop);
+}
+/* 10.2.3.3.3 BnAdd() */
+/* This function adds two bigNum values. Always returns TRUE */
+LIB_EXPORT BOOL
+BnAdd(
+ bigNum result,
+ bigConst op1,
+ bigConst op2
+ )
+{
+ crypt_uword_t stop;
+ int carry;
+ const bignum_t *n1 = op1;
+ const bignum_t *n2 = op2;
+ //
+ if(n2->size > n1->size)
+ {
+ n1 = op2;
+ n2 = op1;
+ }
+ pAssert(result->allocated >= n1->size);
+ stop = MIN(n1->size, n2->allocated);
+ carry = (int)AddSame(result->d, n1->d, n2->d, (int)stop);
+ if(n1->size > stop)
+ carry = CarryProp(&result->d[stop], &n1->d[stop], (int)(n1->size - stop), carry);
+ CarryResolve(result, (int)n1->size, carry);
+ return TRUE;
+}
+/* 10.2.3.3.4 BnAddWord() */
+/* Adds a word value to a bigNum. */
+LIB_EXPORT BOOL
+BnAddWord(
+ bigNum result,
+ bigConst op,
+ crypt_uword_t word
+ )
+{
+ int carry;
+ //
+ carry = (result->d[0] = op->d[0] + word) < word;
+ carry = CarryProp(&result->d[1], &op->d[1], (int)(op->size - 1), carry);
+ CarryResolve(result, (int)op->size, carry);
+ return TRUE;
+}
+/* 10.2.3.3.5 SubSame() */
+/* Subtract two values that have the same size. */
+static int
+SubSame(
+ crypt_uword_t *result,
+ const crypt_uword_t *op1,
+ const crypt_uword_t *op2,
+ int count
+ )
+{
+ int borrow = 0;
+ int i;
+ for(i = 0; i < count; i++)
+ {
+ crypt_uword_t a = op1[i];
+ crypt_uword_t diff = a - op2[i];
+ result[i] = diff - borrow;
+ // generate | propagate
+ borrow = (diff > a) | ((diff == 0) & borrow);
+ }
+ return borrow;
+}
+/* 10.2.3.3.6 BorrowProp() */
+/* This propagates a borrow. If borrow is true when the end of the array is reached, then it means
+ that op2 was larger than op1 and we don't handle that case so an assert is generated. This design
+ choice was made because our only bigNum computations are on large positive numbers (primes) or on
+ fields. Propagate a borrow. */
+static int
+BorrowProp(
+ crypt_uword_t *result,
+ const crypt_uword_t *op,
+ int size,
+ int borrow
+ )
+{
+ for(; size > 0; size--)
+ borrow = ((*result++ = *op++ - borrow) == MAX_CRYPT_UWORD) && borrow;
+ return borrow;
+}
+/* 10.2.3.3.7 BnSub() */
+/* This function does subtraction of two bigNum values and returns result = op1 - op2 when op1 is
+ greater than op2. If op2 is greater than op1, then a fault is generated. This function always
+ returns TRUE. */
+
+LIB_EXPORT BOOL
+BnSub(
+ bigNum result,
+ bigConst op1,
+ bigConst op2
+ )
+{
+ int borrow;
+ int stop = (int)MIN(op1->size, op2->allocated);
+ //
+ // Make sure that op2 is not obviously larger than op1
+ pAssert(op1->size >= op2->size);
+ borrow = SubSame(result->d, op1->d, op2->d, stop);
+ if(op1->size > (crypt_uword_t)stop)
+ borrow = BorrowProp(&result->d[stop], &op1->d[stop], (int)(op1->size - stop),
+ borrow);
+ pAssert(!borrow);
+ BnSetTop(result, op1->size);
+ return TRUE;
+}
+/* 10.2.3.3.8 BnSubWord() */
+/* This function subtracts a word value from a bigNum. This function always returns TRUE. */
+LIB_EXPORT BOOL
+BnSubWord(
+ bigNum result,
+ bigConst op,
+ crypt_uword_t word
+ )
+{
+ int borrow;
+ //
+ pAssert(op->size > 1 || word <= op->d[0]);
+ borrow = word > op->d[0];
+ result->d[0] = op->d[0] - word;
+ borrow = BorrowProp(&result->d[1], &op->d[1], (int)(op->size - 1), borrow);
+ pAssert(!borrow);
+ BnSetTop(result, op->size);
+ return TRUE;
+}
+/* 10.2.3.3.9 BnUnsignedCmp() */
+/* This function performs a comparison of op1 to op2. The compare is approximately constant time if
+ the size of the values used in the compare is consistent across calls (from the same line in the
+ calling code). */
+/* Return Values Meaning */
+/* < 0 op1 is less than op2 */
+/* 0 op1 is equal to op2 */
+/* > 0 op1 is greater than op2 */
+LIB_EXPORT int
+BnUnsignedCmp(
+ bigConst op1,
+ bigConst op2
+ )
+{
+ int retVal;
+ int diff;
+ int i;
+ //
+ pAssert((op1 != NULL) && (op2 != NULL));
+ retVal = (int)(op1->size - op2->size);
+ if(retVal == 0)
+ {
+ for(i = (int)(op1->size - 1); i >= 0; i--)
+ {
+ diff = (op1->d[i] < op2->d[i]) ? -1 : (op1->d[i] != op2->d[i]);
+ retVal = retVal == 0 ? diff : retVal;
+ }
+ }
+ else
+ retVal = (retVal < 0) ? -1 : 1;
+ return retVal;
+}
+/* 10.2.3.3.10 BnUnsignedCmpWord() */
+/* Compare a bigNum to a crypt_uword_t. */
+/* Return Value Meaning */
+/* -1 op1 is less that word */
+/* 0 op1 is equal to word */
+/* 1 op1 is greater than word */
+LIB_EXPORT int
+BnUnsignedCmpWord(
+ bigConst op1,
+ crypt_uword_t word
+ )
+{
+ if(op1->size > 1)
+ return 1;
+ else if(op1->size == 1)
+ return (op1->d[0] < word) ? -1 : (op1->d[0] > word);
+ else // op1 is zero
+ // equal if word is zero
+ return (word == 0) ? 0 : -1;
+}
+/* 10.2.3.3.11 BnModWord() */
+/* This function does modular division of a big number when the modulus is a word value. */
+LIB_EXPORT crypt_word_t
+BnModWord(
+ bigConst numerator,
+ crypt_word_t modulus
+ )
+{
+ BN_MAX(remainder);
+ BN_VAR(mod, RADIX_BITS);
+ //
+ mod->d[0] = modulus;
+ mod->size = (modulus != 0);
+ BnDiv(NULL, remainder, numerator, mod);
+ return remainder->d[0];
+}
+/* 10.2.3.3.12 Msb() */
+/* Returns the bit number of the most significant bit of a crypt_uword_t. The number for the least
+ significant bit of any bigNum value is 0. The maximum return value is RADIX_BITS - 1, */
+/* Return Values Meaning */
+/* -1 the word was zero */
+/* n the bit number of the most significant bit in the word */
+LIB_EXPORT int
+Msb(
+ crypt_uword_t word
+ )
+{
+ int retVal = -1;
+ //
+#if RADIX_BITS == 64
+ if(word & 0xffffffff00000000) { retVal += 32; word >>= 32; }
+#endif
+ if(word & 0xffff0000) { retVal += 16; word >>= 16; }
+ if(word & 0x0000ff00) { retVal += 8; word >>= 8; }
+ if(word & 0x000000f0) { retVal += 4; word >>= 4; }
+ if(word & 0x0000000c) { retVal += 2; word >>= 2; }
+ if(word & 0x00000002) { retVal += 1; word >>= 1; }
+ return retVal + (int)word;
+}
+/* 10.2.3.3.13 BnMsb() */
+/* This function returns the number of the MSb() of a bigNum value. */
+/* Return Value Meaning */
+/* -1 the word was zero or bn was NULL */
+/* n the bit number of the most significant bit in the word */
+
+LIB_EXPORT int
+BnMsb(
+ bigConst bn
+ )
+{
+ // If the value is NULL, or the size is zero then treat as zero and return -1
+ if(bn != NULL && bn->size > 0)
+ {
+ int retVal = Msb(bn->d[bn->size - 1]);
+ retVal += (int)(bn->size - 1) * RADIX_BITS;
+ return retVal;
+ }
+ else
+ return -1;
+}
+/* 10.2.3.3.14 BnSizeInBits() */
+/* Returns the number of bits required to hold a number. It is one greater than the Msb. */
+LIB_EXPORT unsigned
+BnSizeInBits(
+ bigConst n
+ )
+{
+ int bits = BnMsb(n) + 1;
+ //
+ return bits < 0 ? 0 : (unsigned)bits;
+}
+/* 10.2.3.3.15 BnSetWord() */
+/* Change the value of a bignum_t to a word value. */
+LIB_EXPORT bigNum
+BnSetWord(
+ bigNum n,
+ crypt_uword_t w
+ )
+{
+ if(n != NULL)
+ {
+ pAssert(n->allocated > 1);
+ n->d[0] = w;
+ BnSetTop(n, (w != 0) ? 1 : 0);
+ }
+ return n;
+}
+/* 10.2.3.3.16 BnSetBit() */
+/* SET a bit in a bigNum. Bit 0 is the least-significant bit in the 0th digit_t. The function always
+ return TRUE */
+LIB_EXPORT BOOL
+BnSetBit(
+ bigNum bn, // IN/OUT: big number to modify
+ unsigned int bitNum // IN: Bit number to SET
+ )
+{
+ crypt_uword_t offset = bitNum / RADIX_BITS;
+ pAssert(bn->allocated * RADIX_BITS >= bitNum);
+ // Grow the number if necessary to set the bit.
+ while(bn->size <= offset)
+ bn->d[bn->size++] = 0;
+ bn->d[offset] |= (crypt_uword_t)(1 << RADIX_MOD(bitNum));
+ return TRUE;
+}
+/* 10.2.3.3.17 BnTestBit() */
+/* Check to see if a bit is SET in a bignum_t. The 0th bit is the LSb() of d[0]. */
+/* Return Values Meaning */
+/* TRUE the bit is set */
+/* FALSE the bit is not set or the number is out of range */
+LIB_EXPORT BOOL
+BnTestBit(
+ bigNum bn, // IN: number to check
+ unsigned int bitNum // IN: bit to test
+ )
+{
+ crypt_uword_t offset = RADIX_DIV(bitNum);
+ //
+ if(bn->size > offset)
+ return ((bn->d[offset] & (((crypt_uword_t)1) << RADIX_MOD(bitNum))) != 0);
+ else
+ return FALSE;
+}
+/* 10.2.3.3.18 BnMaskBits() */
+/* Function to mask off high order bits of a big number. The returned value will have no more than
+ maskBit bits set. */
+/* NOTE: There is a requirement that unused words of a bignum_t are set to zero. */
+/* Return Values Meaning */
+/* TRUE result masked */
+/* FALSE the input was not as large as the mask */
+LIB_EXPORT BOOL
+BnMaskBits(
+ bigNum bn, // IN/OUT: number to mask
+ crypt_uword_t maskBit // IN: the bit number for the mask.
+ )
+{
+ crypt_uword_t finalSize;
+ BOOL retVal;
+ finalSize = BITS_TO_CRYPT_WORDS(maskBit);
+ retVal = (finalSize <= bn->allocated);
+ if(retVal && (finalSize > 0))
+ {
+ crypt_uword_t mask;
+ mask = ~((crypt_uword_t)0) >> RADIX_MOD(maskBit);
+ bn->d[finalSize - 1] &= mask;
+ }
+ BnSetTop(bn, finalSize);
+ return retVal;
+}
+/* 10.2.3.3.19 BnShiftRight() */
+/* Function will shift a bigNum to the right by the shiftAmount. This function always returns
+ TRUE. */
+LIB_EXPORT BOOL
+BnShiftRight(
+ bigNum result,
+ bigConst toShift,
+ uint32_t shiftAmount
+ )
+{
+ uint32_t offset = (shiftAmount >> RADIX_LOG2);
+ uint32_t i;
+ uint32_t shiftIn;
+ crypt_uword_t finalSize;
+ //
+ shiftAmount = shiftAmount & RADIX_MASK;
+ shiftIn = RADIX_BITS - shiftAmount;
+ // The end size is toShift->size - offset less one additional
+ // word if the shiftAmount would make the upper word == 0
+ if(toShift->size > offset)
+ {
+ finalSize = toShift->size - offset;
+ finalSize -= (toShift->d[toShift->size - 1] >> shiftAmount) == 0 ? 1 : 0;
+ }
+ else
+ finalSize = 0;
+ pAssert(finalSize <= result->allocated);
+ if(finalSize != 0)
+ {
+ for(i = 0; i < finalSize; i++)
+ {
+ result->d[i] = (toShift->d[i + offset] >> shiftAmount)
+ | (toShift->d[i + offset + 1] << shiftIn);
+ }
+ if(offset == 0)
+ result->d[i] = toShift->d[i] >> shiftAmount;
+ }
+ BnSetTop(result, finalSize);
+ return TRUE;
+}
+/* 10.2.3.3.20 BnGetRandomBits() */
+/* Return Value Meaning */
+/* TRUE(1) success */
+/* FALSE(0) failure */
+LIB_EXPORT BOOL
+BnGetRandomBits(
+ bigNum n,
+ size_t bits,
+ RAND_STATE *rand
+ )
+{
+ // Since this could be used for ECC key generation using the extra bits method,
+ // make sure that the value is large enough
+ TPM2B_TYPE(LARGEST, LARGEST_NUMBER + 8);
+ TPM2B_LARGEST large;
+ //
+ large.b.size = (UINT16)BITS_TO_BYTES(bits);
+ if(DRBG_Generate(rand, large.t.buffer, large.t.size) == large.t.size)
+ {
+ if(BnFrom2B(n, &large.b) != NULL)
+ {
+ if(BnMaskBits(n, (crypt_uword_t)bits))
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+/* 10.2.3.3.21 BnGenerateRandomInRange() */
+/* Function to generate a random number r in the range 1 <= r < limit. The function gets a random
+ number of bits that is the size of limit. There is some some probability that the returned number
+ is going to be greater than or equal to the limit. If it is, try again. There is no more than 50%
+ chance that the next number is also greater, so try again. We keep trying until we get a value
+ that meets the criteria. Since limit is very often a number with a LOT of high order ones, this
+ rarely would need a second try. */
+/* Return Value Meaning */
+/* TRUE(1) success */
+/* FALSE(0) failure */
+LIB_EXPORT BOOL
+BnGenerateRandomInRange(
+ bigNum dest,
+ bigConst limit,
+ RAND_STATE *rand
+ )
+{
+ size_t bits = BnSizeInBits(limit);
+ //
+ if(bits < 2)
+ {
+ BnSetWord(dest, 0);
+ return FALSE;
+ }
+ else
+ {
+ while(BnGetRandomBits(dest, bits, rand)
+ && (BnEqualZero(dest) || (BnUnsignedCmp(dest, limit) >= 0)));
+ }
+ return !g_inFailureMode;
+}
+
+// libtpms added begin
+
+// This version of BnSizeInBits skips any leading zero bytes in bigConst
+// and thus calculates the bits that OpenSSL will work with after truncating
+// the leading zeros
+static LIB_EXPORT unsigned
+BnSizeInBitsSkipLeadingZeros(
+ bigConst n
+ )
+{
+ int firstByte;
+ unsigned bitSize = BnSizeInBits(n);
+ crypt_uword_t i;
+
+ if (bitSize <= 8)
+ return bitSize;
+
+ // search for the first limb that is non-zero
+ for (i = 0; i < n->size; i++) {
+ if (n->d[i] != 0)
+ break;
+ }
+ if (i >= n->size)
+ return 0; // should never happen
+
+ // get the first byte in this limb that is non-zero
+ firstByte = (RADIX_BITS - 1 - Msb(n->d[i])) >> 3;
+
+ return bitSize - i * sizeof(n->d[0]) - (firstByte << 3);
+}
+
+
+/* This is a version of BnGenerateRandomInRange that ensures that the upper most
+ byte is non-zero, so that the number will not be shortened and subsequent operations
+ will not have a timing-sidechannel
+ */
+LIB_EXPORT BOOL
+BnGenerateRandomInRangeAllBytes(
+ bigNum dest,
+ bigConst limit,
+ RAND_STATE *rand
+ )
+{
+ BOOL OK;
+ int repeats = 0;
+ int maxRepeats;
+ unsigned requestedBits;
+ unsigned requestedBytes;
+ unsigned numBytes;
+
+ if (rand)
+ return BnGenerateRandomInRange(dest, limit, rand);
+
+ // a 'limit' like 'BN_P638_n' has leading zeros and we only need 73 bytes not 80
+ requestedBits = BnSizeInBitsSkipLeadingZeros(limit);
+ requestedBytes = BITS_TO_BYTES(requestedBits);
+ maxRepeats = 8;
+ if (requestedBits & 7)
+ maxRepeats += (9 - (requestedBits & 7));
+
+ while (true) {
+ OK = BnGenerateRandomInRange(dest, limit, rand);
+ if (!OK)
+ break;
+ if (repeats < maxRepeats) {
+ numBytes = BITS_TO_BYTES(BnSizeInBitsSkipLeadingZeros(dest));
+ if (numBytes < requestedBytes) {
+ repeats++;
+ continue;
+ }
+ }
+ break;
+ }
+
+ return OK;
+}
+// libtpms added end
diff --git a/src/tpm2/BnMemory.c b/src/tpm2/BnMemory.c
new file mode 100644
index 0000000..620ca99
--- /dev/null
+++ b/src/tpm2/BnMemory.c
@@ -0,0 +1,205 @@
+/********************************************************************************/
+/* */
+/* */
+/* Written by Ken Goldman */
+/* IBM Thomas J. Watson Research Center */
+/* $Id: BnMemory.c 1262 2018-07-11 21:03:43Z kgoldman $ */
+/* */
+/* Licenses and Notices */
+/* */
+/* 1. Copyright Licenses: */
+/* */
+/* - Trusted Computing Group (TCG) grants to the user of the source code in */
+/* this specification (the "Source Code") a worldwide, irrevocable, */
+/* nonexclusive, royalty free, copyright license to reproduce, create */
+/* derivative works, distribute, display and perform the Source Code and */
+/* derivative works thereof, and to grant others the rights granted herein. */
+/* */
+/* - The TCG grants to the user of the other parts of the specification */
+/* (other than the Source Code) the rights to reproduce, distribute, */
+/* display, and perform the specification solely for the purpose of */
+/* developing products based on such documents. */
+/* */
+/* 2. Source Code Distribution Conditions: */
+/* */
+/* - Redistributions of Source Code must retain the above copyright licenses, */
+/* this list of conditions and the following disclaimers. */
+/* */
+/* - Redistributions in binary form must reproduce the above copyright */
+/* licenses, this list of conditions and the following disclaimers in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* 3. Disclaimers: */
+/* */
+/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
+/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
+/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
+/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
+/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
+/* information on specification licensing rights available through TCG */
+/* membership agreements. */
+/* */
+/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
+/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
+/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
+/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
+/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
+/* */
+/* - Without limitation, TCG and its members and licensors disclaim all */
+/* liability, including liability for infringement of any proprietary */
+/* rights, relating to use of information in this specification and to the */
+/* implementation of this specification, and TCG disclaims all liability for */
+/* cost of procurement of substitute goods or services, lost profits, loss */
+/* of use, loss of data or any incidental, consequential, direct, indirect, */
+/* or special damages, whether under contract, tort, warranty or otherwise, */
+/* arising in any way out of use or reliance upon this specification or any */
+/* information herein. */
+/* */
+/* (c) Copyright IBM Corp. and others, 2016 */
+/* */
+/********************************************************************************/
+
+/* 10.2.5 BnMemory.c */
+/* 10.2.5.1 Introduction */
+/* This file contains the memory setup functions used by the bigNum functions in CryptoEngine() */
+/* 10.2.5.2 Includes */
+#include "Tpm.h"
+/* 10.2.5.3 Functions */
+/* 10.2.5.3.1 BnSetTop() */
+/* This function is used when the size of a bignum_t is changed. It makes sure that the unused words
+ are set to zero and that any significant words of zeros are eliminated from the used size
+ indicator. */
+LIB_EXPORT bigNum
+BnSetTop(
+ bigNum bn, // IN/OUT: number to clean
+ crypt_uword_t top // IN: the new top
+ )
+{
+ if(bn != NULL)
+ {
+ pAssert(top <= bn->allocated);
+ // If forcing the size to be decreased, make sure that the words being
+ // discarded are being set to 0
+ while(bn->size > top)
+ bn->d[--bn->size] = 0;
+ bn->size = top;
+ // Now make sure that the words that are left are 'normalized' (no high-order
+ // words of zero.
+ while((bn->size > 0) && (bn->d[bn->size - 1] == 0))
+ bn->size -= 1;
+ }
+ return bn;
+}
+#if 0 /* libtpms added */
+/* 10.2.5.3.2 BnClearTop() */
+/* This function will make sure that all unused words are zero. */
+LIB_EXPORT bigNum
+BnClearTop(
+ bigNum bn
+ )
+{
+ crypt_uword_t i;
+ //
+ if(bn != NULL)
+ {
+ for(i = bn->size; i < bn->allocated; i++)
+ bn->d[i] = 0;
+ while((bn->size > 0) && (bn->d[bn->size] == 0))
+ bn->size -= 1;
+ }
+ return bn;
+}
+#endif /* libtpms added */
+/* 10.2.5.3.3 BnInitializeWord() */
+/* This function is used to initialize an allocated bigNum with a word value. The bigNum does not
+ have to be allocated with a single word. */
+LIB_EXPORT bigNum
+BnInitializeWord(
+ bigNum bn, // IN:
+ crypt_uword_t allocated, // IN:
+ crypt_uword_t word // IN:
+ )
+{
+ bn->allocated = allocated;
+ bn->size = (word != 0);
+ bn->d[0] = word;
+ while(allocated > 1)
+ bn->d[--allocated] = 0;
+ return bn;
+}
+/* 10.2.5.3.4 BnInit() */
+/* This function initializes a stack allocated bignum_t. It initializes allocated and size and zeros
+ the words of d. */
+LIB_EXPORT bigNum
+BnInit(
+ bigNum bn,
+ crypt_uword_t allocated
+ )
+{
+ if(bn != NULL)
+ {
+ bn->allocated = allocated;
+ bn->size = 0;
+ while(allocated != 0)
+ bn->d[--allocated] = 0;
+ }
+ return bn;
+}
+/* 10.2.5.3.5 BnCopy() */
+/* Function to copy a bignum_t. If the output is NULL, then nothing happens. If the input is NULL,
+ the output is set to zero. */
+LIB_EXPORT BOOL
+BnCopy(
+ bigNum out,
+ bigConst in
+ )
+{
+ if(in == out)
+ BnSetTop(out, BnGetSize(out));
+ else if(out != NULL)
+ {
+ if(in != NULL)
+ {
+ unsigned int i;
+ pAssert(BnGetAllocated(out) >= BnGetSize(in));
+ for(i = 0; i < BnGetSize(in); i++)
+ out->d[i] = in->d[i];
+ BnSetTop(out, BnGetSize(in));
+ }
+ else
+ BnSetTop(out, 0);
+ }
+ return TRUE;
+}
+#if ALG_ECC
+#if 0 /* libtpms added */
+/* 10.2.5.3.6 BnPointCopy() */
+/* Function to copy a bn point. */
+LIB_EXPORT BOOL
+BnPointCopy(
+ bigPoint pOut,
+ pointConst pIn
+ )
+{
+ return BnCopy(pOut->x, pIn->x)
+ && BnCopy(pOut->y, pIn->y)
+ && BnCopy(pOut->z, pIn->z);
+}
+#endif /* libtpms added */
+/* 10.2.5.3.7 BnInitializePoint() */
+/* This function is used to initialize a point structure with the addresses of the coordinates. */
+LIB_EXPORT bn_point_t *
+BnInitializePoint(
+ bigPoint p, // OUT: structure to receive pointers
+ bigNum x, // IN: x coordinate
+ bigNum y, // IN: y coordinate
+ bigNum z // IN: x coordinate
+ )
+{
+ p->x = x;
+ p->y = y;
+ p->z = z;
+ BnSetWord(z, 1);
+ return p;
+}
+#endif // TPM_ALG_ECC
diff --git a/src/tpm2/Cancel.c b/src/tpm2/Cancel.c
new file mode 100644
index 0000000..2026ec0
--- /dev/null
+++ b/src/tpm2/Cancel.c
@@ -0,0 +1,100 @@
+/********************************************************************************/
+/* */
+/* Simulates the cancel pins on the TPM. */
+/* Written by Ken Goldman */
+/* IBM Thomas J. Watson Research Center */
+/* $Id: Cancel.c 1490 2019-07-26 21:13:22Z kgoldman $ */
+/* */
+/* Licenses and Notices */
+/* */
+/* 1. Copyright Licenses: */
+/* */
+/* - Trusted Computing Group (TCG) grants to the user of the source code in */
+/* this specification (the "Source Code") a worldwide, irrevocable, */
+/* nonexclusive, royalty free, copyright license to reproduce, create */
+/* derivative works, distribute, display and perform the Source Code and */
+/* derivative works thereof, and to grant others the rights granted herein. */
+/* */
+/* - The TCG grants to the user of the other parts of the specification */
+/* (other than the Source Code) the rights to reproduce, distribute, */
+/* display, and perform the specification solely for the purpose of */
+/* developing products based on such documents. */
+/* */
+/* 2. Source Code Distribution Conditions: */
+/* */
+/* - Redistributions of Source Code must retain the above copyright licenses, */
+/* this list of conditions and the following disclaimers. */
+/* */
+/* - Redistributions in binary form must reproduce the above copyright */
+/* licenses, this list of conditions and the following disclaimers in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* 3. Disclaimers: */
+/* */
+/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
+/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
+/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
+/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
+/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
+/* information on specification licensing rights available through TCG */
+/* membership agreements. */
+/* */
+/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
+/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
+/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
+/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
+/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
+/* */
+/* - Without limitation, TCG and its members and licensors disclaim all */
+/* liability, including liability for infringement of any proprietary */
+/* rights, relating to use of information in this specification and to the */
+/* implementation of this specification, and TCG disclaims all liability for */
+/* cost of procurement of substitute goods or services, lost profits, loss */
+/* of use, loss of data or any incidental, consequential, direct, indirect, */
+/* or special damages, whether under contract, tort, warranty or otherwise, */
+/* arising in any way out of use or reliance upon this specification or any */
+/* information herein. */
+/* */
+/* (c) Copyright IBM Corp. and others, 2016 - 2019 */
+/* */
+/********************************************************************************/
+
+/* C.2 Cancel.c */
+/* C.2.1. Description */
+/* This module simulates the cancel pins on the TPM. */
+/* C.2.2. Includes, Typedefs, Structures, and Defines */
+#include "Platform.h"
+/* C.2.3. Functions */
+/* C.2.3.1. _plat__IsCanceled() */
+/* Check if the cancel flag is set */
+/* Return Values Meaning */
+/* TRUE(1) if cancel flag is set */
+/* FALSE(0) if cancel flag is not set */
+LIB_EXPORT int
+_plat__IsCanceled(
+ void
+ )
+{
+ // return cancel flag
+ return s_isCanceled;
+}
+/* C.2.3.2. _plat__SetCancel() */
+/* Set cancel flag. */
+LIB_EXPORT void
+_plat__SetCancel(
+ void
+ )
+{
+ s_isCanceled = TRUE;
+ return;
+}
+/* C.2.3.3. _plat__ClearCancel() */
+/* Clear cancel flag */
+LIB_EXPORT void
+_plat__ClearCancel(
+ void
+ )
+{
+ s_isCanceled = FALSE;
+ return;
+}
diff --git a/src/tpm2/Capabilities.h b/src/tpm2/Capabilities.h
new file mode 100644
index 0000000..832187f
--- /dev/null
+++ b/src/tpm2/Capabilities.h
@@ -0,0 +1,76 @@
+/********************************************************************************/
+/* */
+/* Number of capability values that will fit into the largest data buffer */
+/* Written by Ken Goldman */
+/* IBM Thomas J. Watson Research Center */
+/* $Id: Capabilities.h 1519 2019-11-15 20:43:51Z kgoldman $ */
+/* */
+/* Licenses and Notices */
+/* */
+/* 1. Copyright Licenses: */
+/* */
+/* - Trusted Computing Group (TCG) grants to the user of the source code in */
+/* this specification (the "Source Code") a worldwide, irrevocable, */
+/* nonexclusive, royalty free, copyright license to reproduce, create */
+/* derivative works, distribute, display and perform the Source Code and */
+/* derivative works thereof, and to grant others the rights granted herein. */
+/* */
+/* - The TCG grants to the user of the other parts of the specification */
+/* (other than the Source Code) the rights to reproduce, distribute, */
+/* display, and perform the specification solely for the purpose of */
+/* developing products based on such documents. */
+/* */
+/* 2. Source Code Distribution Conditions: */
+/* */
+/* - Redistributions of Source Code must retain the above copyright licenses, */
+/* this list of conditions and the following disclaimers. */
+/* */
+/* - Redistributions in binary form must reproduce the above copyright */
+/* licenses, this list of conditions and the following disclaimers in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* 3. Disclaimers: */
+/* */
+/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
+/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
+/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
+/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
+/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
+/* information on specification licensing rights available through TCG */
+/* membership agreements. */
+/* */
+/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
+/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
+/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
+/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
+/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
+/* */
+/* - Without limitation, TCG and its members and licensors disclaim all */
+/* liability, including liability for infringement of any proprietary */
+/* rights, relating to use of information in this specification and to the */
+/* implementation of this specification, and TCG disclaims all liability for */
+/* cost of procurement of substitute goods or services, lost profits, loss */
+/* of use, loss of data or any incidental, consequential, direct, indirect, */
+/* or special damages, whether under contract, tort, warranty or otherwise, */
+/* arising in any way out of use or reliance upon this specification or any */
+/* information herein. */
+/* */
+/* (c) Copyright IBM Corp. and others, 2016 - 2019 */
+/* */
+/********************************************************************************/
+
+#ifndef _CAPABILITIES_H
+#define _CAPABILITIES_H
+
+#define MAX_CAP_DATA (MAX_CAP_BUFFER - sizeof(TPM_CAP)-sizeof(UINT32))
+#define MAX_CAP_ALGS (MAX_CAP_DATA / sizeof(TPMS_ALG_PROPERTY))
+#define MAX_CAP_HANDLES (MAX_CAP_DATA / sizeof(TPM_HANDLE))
+#define MAX_CAP_CC (MAX_CAP_DATA / sizeof(TPM_CC))
+#define MAX_TPM_PROPERTIES (MAX_CAP_DATA / sizeof(TPMS_TAGGED_PROPERTY))
+#define MAX_PCR_PROPERTIES (MAX_CAP_DATA / sizeof(TPMS_TAGGED_PCR_SELECT))
+#define MAX_ECC_CURVES (MAX_CAP_DATA / sizeof(TPM_ECC_CURVE))
+#define MAX_TAGGED_POLICIES (MAX_CAP_DATA / sizeof(TPMS_TAGGED_POLICY))
+#define MAX_ACT_DATA (MAX_CAP_DATA / sizeof(TPMS_ACT_DATA))
+#define MAX_AC_CAPABILITIES (MAX_CAP_DATA / sizeof(TPMS_AC_OUTPUT))
+
+#endif
diff --git a/src/tpm2/CapabilityCommands.c b/src/tpm2/CapabilityCommands.c
new file mode 100644
index 0000000..e7d675b
--- /dev/null
+++ b/src/tpm2/CapabilityCommands.c
@@ -0,0 +1,215 @@
+/********************************************************************************/
+/* */
+/* Capability Commands */
+/* Written by Ken Goldman */
+/* IBM Thomas J. Watson Research Center */
+/* $Id: CapabilityCommands.c 1519 2019-11-15 20:43:51Z kgoldman $ */
+/* */
+/* Licenses and Notices */
+/* */
+/* 1. Copyright Licenses: */
+/* */
+/* - Trusted Computing Group (TCG) grants to the user of the source code in */
+/* this specification (the "Source Code") a worldwide, irrevocable, */
+/* nonexclusive, royalty free, copyright license to reproduce, create */
+/* derivative works, distribute, display and perform the Source Code and */
+/* derivative works thereof, and to grant others the rights granted herein. */
+/* */
+/* - The TCG grants to the user of the other parts of the specification */
+/* (other than the Source Code) the rights to reproduce, distribute, */
+/* display, and perform the specification solely for the purpose of */
+/* developing products based on such documents. */
+/* */
+/* 2. Source Code Distribution Conditions: */
+/* */
+/* - Redistributions of Source Code must retain the above copyright licenses, */
+/* this list of conditions and the following disclaimers. */
+/* */
+/* - Redistributions in binary form must reproduce the above copyright */
+/* licenses, this list of conditions and the following disclaimers in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* 3. Disclaimers: */
+/* */
+/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
+/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
+/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
+/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
+/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
+/* information on specification licensing rights available through TCG */
+/* membership agreements. */
+/* */
+/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
+/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
+/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
+/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
+/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
+/* */
+/* - Without limitation, TCG and its members and licensors disclaim all */
+/* liability, including liability for infringement of any proprietary */
+/* rights, relating to use of information in this specification and to the */
+/* implementation of this specification, and TCG disclaims all liability for */
+/* cost of procurement of substitute goods or services, lost profits, loss */
+/* of use, loss of data or any incidental, consequential, direct, indirect, */
+/* or special damages, whether under contract, tort, warranty or otherwise, */
+/* arising in any way out of use or reliance upon this specification or any */
+/* information herein. */
+/* */
+/* (c) Copyright IBM Corp. and others, 2016 - 2019 */
+/* */
+/********************************************************************************/
+
+#include "Tpm.h"
+#include "GetCapability_fp.h"
+#if CC_GetCapability // Conditional expansion of this file
+TPM_RC
+TPM2_GetCapability(
+ GetCapability_In *in, // IN: input parameter list
+ GetCapability_Out *out // OUT: output parameter list
+ )
+{
+ TPMU_CAPABILITIES *data = &out->capabilityData.data;
+ // Command Output
+ // Set output capability type the same as input type
+ out->capabilityData.capability = in->capability;
+ switch(in->capability)
+ {
+ case TPM_CAP_ALGS:
+ out->moreData = AlgorithmCapGetImplemented((TPM_ALG_ID)in->property,
+ in->propertyCount,
+ &data->algorithms);
+ break;
+ case TPM_CAP_HANDLES:
+ switch(HandleGetType((TPM_HANDLE)in->property))
+ {
+ case TPM_HT_TRANSIENT:
+ // Get list of handles of loaded transient objects
+ out->moreData = ObjectCapGetLoaded((TPM_HANDLE)in->property,
+ in->propertyCount,
+ &data->handles);
+ break;
+ case TPM_HT_PERSISTENT:
+ // Get list of handles of persistent objects
+ out->moreData = NvCapGetPersistent((TPM_HANDLE)in->property,
+ in->propertyCount,
+ &data->handles);
+ break;
+ case TPM_HT_NV_INDEX:
+ // Get list of defined NV index
+ out->moreData = NvCapGetIndex((TPM_HANDLE)in->property,
+ in->propertyCount,
+ &data->handles);
+ break;
+ case TPM_HT_LOADED_SESSION:
+ // Get list of handles of loaded sessions
+ out->moreData = SessionCapGetLoaded((TPM_HANDLE)in->property,
+ in->propertyCount,
+ &data->handles);
+ break;
+#ifdef TPM_HT_SAVED_SESSION
+ case TPM_HT_SAVED_SESSION:
+#else
+ case TPM_HT_ACTIVE_SESSION:
+#endif
+ // Get list of handles of
+ out->moreData = SessionCapGetSaved((TPM_HANDLE)in->property,
+ in->propertyCount,
+ &data->handles);
+ break;
+ case TPM_HT_PCR:
+ // Get list of handles of PCR
+ out->moreData = PCRCapGetHandles((TPM_HANDLE)in->property,
+ in->propertyCount,
+ &data->handles);
+ break;
+ case TPM_HT_PERMANENT:
+ // Get list of permanent handles
+ out->moreData = PermanentCapGetHandles((TPM_HANDLE)in->property,
+ in->propertyCount,
+ &data->handles);
+ break;
+ default:
+ // Unsupported input handle type
+ return TPM_RCS_HANDLE + RC_GetCapability_property;
+ break;
+ }
+ break;
+ case TPM_CAP_COMMANDS:
+ out->moreData = CommandCapGetCCList((TPM_CC)in->property,
+ in->propertyCount,
+ &data->command);
+ break;
+ case TPM_CAP_PP_COMMANDS:
+ out->moreData = PhysicalPresenceCapGetCCList((TPM_CC)in->property,
+ in->propertyCount,
+ &data->ppCommands);
+ break;
+ case TPM_CAP_AUDIT_COMMANDS:
+ out->moreData = CommandAuditCapGetCCList((TPM_CC)in->property,
+ in->propertyCount,
+ &data->auditCommands);
+ break;
+ case TPM_CAP_PCRS:
+ // Input property must be 0
+ if(in->property != 0)
+ return TPM_RCS_VALUE + RC_GetCapability_property;
+ out->moreData = PCRCapGetAllocation(in->propertyCount,
+ &data->assignedPCR);
+ break;
+ case TPM_CAP_PCR_PROPERTIES:
+ out->moreData = PCRCapGetProperties((TPM_PT_PCR)in->property,
+ in->propertyCount,
+ &data->pcrProperties);
+ break;
+ case TPM_CAP_TPM_PROPERTIES:
+ out->moreData = TPMCapGetProperties((TPM_PT)in->property,
+ in->propertyCount,
+ &data->tpmProperties);
+ break;
+#if ALG_ECC
+ case TPM_CAP_ECC_CURVES:
+ out->moreData = CryptCapGetECCCurve((TPM_ECC_CURVE)in->property,
+ in->propertyCount,
+ &data->eccCurves);
+ break;
+#endif // TPM_ALG_ECC
+ case TPM_CAP_AUTH_POLICIES:
+ if(HandleGetType((TPM_HANDLE)in->property) != TPM_HT_PERMANENT)
+ return TPM_RCS_VALUE + RC_GetCapability_property;
+ out->moreData = PermanentHandleGetPolicy((TPM_HANDLE)in->property,
+ in->propertyCount,
+ &data->authPolicies);
+ break;
+ case TPM_CAP_ACT:
+ if(((TPM_RH)in->property < TPM_RH_ACT_0)
+ || ((TPM_RH)in->property > TPM_RH_ACT_F))
+ return TPM_RCS_VALUE + RC_GetCapability_property;
+ out->moreData = ActGetCapabilityData((TPM_HANDLE)in->property,
+ in->propertyCount,
+ &data->actData);
+ break;
+ case TPM_CAP_VENDOR_PROPERTY:
+ // vendor property is not implemented
+ default:
+ // Unsupported TPM_CAP value
+ return TPM_RCS_VALUE + RC_GetCapability_capability;
+ break;
+ }
+ return TPM_RC_SUCCESS;
+}
+#endif // CC_GetCapability
+#include "Tpm.h"
+#include "TestParms_fp.h"
+#if CC_TestParms // Conditional expansion of this file
+TPM_RC
+TPM2_TestParms(
+ TestParms_In *in // IN: input parameter list
+ )
+{
+ // Input parameter is not reference in command action
+ NOT_REFERENCED(in);
+ // The parameters are tested at unmarshal process. We do nothing in command
+ // action
+ return TPM_RC_SUCCESS;
+}
+#endif // CC_TestParms
diff --git a/src/tpm2/CertifyCreation_fp.h b/src/tpm2/CertifyCreation_fp.h
new file mode 100644
index 0000000..98be3b9
--- /dev/null
+++ b/src/tpm2/CertifyCreation_fp.h
@@ -0,0 +1,95 @@
+/********************************************************************************/
+/* */
+/* */
+/* Written by Ken Goldman */
+/* IBM Thomas J. Watson Research Center */
+/* $Id: CertifyCreation_fp.h 809 2016-11-16 18:31:54Z kgoldman $ */
+/* */
+/* Licenses and Notices */
+/* */
+/* 1. Copyright Licenses: */
+/* */
+/* - Trusted Computing Group (TCG) grants to the user of the source code in */
+/* this specification (the "Source Code") a worldwide, irrevocable, */
+/* nonexclusive, royalty free, copyright license to reproduce, create */
+/* derivative works, distribute, display and perform the Source Code and */
+/* derivative works thereof, and to grant others the rights granted herein. */
+/* */
+/* - The TCG grants to the user of the other parts of the specification */
+/* (other than the Source Code) the rights to reproduce, distribute, */
+/* display, and perform the specification solely for the purpose of */
+/* developing products based on such documents. */
+/* */
+/* 2. Source Code Distribution Conditions: */
+/* */
+/* - Redistributions of Source Code must retain the above copyright licenses, */
+/* this list of conditions and the following disclaimers. */
+/* */
+/* - Redistributions in binary form must reproduce the above copyright */
+/* licenses, this list of conditions and the following disclaimers in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* 3. Disclaimers: */
+/* */
+/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
+/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
+/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
+/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
+/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
+/* information on specification licensing rights available through TCG */
+/* membership agreements. */
+/* */
+/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
+/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
+/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
+/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
+/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
+/* */
+/* - Without limitation, TCG and its members and licensors disclaim all */
+/* liability, including liability for infringement of any proprietary */
+/* rights, relating to use of information in this specification and to the */
+/* implementation of this specification, and TCG disclaims all liability for */
+/* cost of procurement of substitute goods or services, lost profits, loss */
+/* of use, loss of data or any incidental, consequential, direct, indirect, */
+/* or special damages, whether under contract, tort, warranty or otherwise, */
+/* arising in any way out of use or reliance upon this specification or any */
+/* information herein. */
+/* */
+/* (c) Copyright IBM Corp. and others, 2012-2015 */
+/* */
+/********************************************************************************/
+
+/* rev 119 */
+
+#ifndef CERTIFYCREATION_FP_H
+#define CERTIFYCREATION_FP_H
+
+typedef struct {
+ TPMI_DH_OBJECT signHandle;
+ TPMI_DH_OBJECT objectHandle;
+ TPM2B_DATA qualifyingData;
+ TPM2B_DIGEST creationHash;
+ TPMT_SIG_SCHEME inScheme;
+ TPMT_TK_CREATION creationTicket;
+} CertifyCreation_In;
+
+#define RC_CertifyCreation_signHandle (TPM_RC_H + TPM_RC_1)
+#define RC_CertifyCreation_objectHandle (TPM_RC_H + TPM_RC_2)
+#define RC_CertifyCreation_qualifyingData (TPM_RC_P + TPM_RC_1)
+#define RC_CertifyCreation_creationHash (TPM_RC_P + TPM_RC_2)
+#define RC_CertifyCreation_inScheme (TPM_RC_P + TPM_RC_3)
+#define RC_CertifyCreation_creationTicket (TPM_RC_P + TPM_RC_4)
+
+typedef struct {
+ TPM2B_ATTEST certifyInfo;
+ TPMT_SIGNATURE signature;
+} CertifyCreation_Out;
+
+TPM_RC
+TPM2_CertifyCreation(
+ CertifyCreation_In *in, // IN: input parameter list
+ CertifyCreation_Out *out // OUT: output parameter list
+ );
+
+
+#endif
diff --git a/src/tpm2/CertifyX509_fp.h b/src/tpm2/CertifyX509_fp.h
new file mode 100644
index 0000000..b7a002a
--- /dev/null
+++ b/src/tpm2/CertifyX509_fp.h
@@ -0,0 +1,93 @@
+/********************************************************************************/
+/* */
+/* TPM2_CertifyX509 Command Header */
+/* Written by Ken Goldman */
+/* IBM Thomas J. Watson Research Center */
+/* $Id: CertifyX509_fp.h 1519 2019-11-15 20:43:51Z kgoldman $ */
+/* */
+/* Licenses and Notices */
+/* */
+/* 1. Copyright Licenses: */
+/* */
+/* - Trusted Computing Group (TCG) grants to the user of the source code in */
+/* this specification (the "Source Code") a worldwide, irrevocable, */
+/* nonexclusive, royalty free, copyright license to reproduce, create */
+/* derivative works, distribute, display and perform the Source Code and */
+/* derivative works thereof, and to grant others the rights granted herein. */
+/* */
+/* - The TCG grants to the user of the other parts of the specification */
+/* (other than the Source Code) the rights to reproduce, distribute, */
+/* display, and perform the specification solely for the purpose of */
+/* developing products based on such documents. */
+/* */
+/* 2. Source Code Distribution Conditions: */
+/* */
+/* - Redistributions of Source Code must retain the above copyright licenses, */
+/* this list of conditions and the following disclaimers. */
+/* */
+/* - Redistributions in binary form must reproduce the above copyright */
+/* licenses, this list of conditions and the following disclaimers in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* 3. Disclaimers: */
+/* */
+/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
+/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
+/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
+/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
+/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
+/* information on specification licensing rights available through TCG */
+/* membership agreements. */
+/* */
+/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
+/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
+/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
+/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
+/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
+/* */
+/* - Without limitation, TCG and its members and licensors disclaim all */
+/* liability, including liability for infringement of any proprietary */
+/* rights, relating to use of information in this specification and to the */
+/* implementation of this specification, and TCG disclaims all liability for */
+/* cost of procurement of substitute goods or services, lost profits, loss */
+/* of use, loss of data or any incidental, consequential, direct, indirect, */
+/* or special damages, whether under contract, tort, warranty or otherwise, */
+/* arising in any way out of use or reliance upon this specification or any */
+/* information herein. */
+/* */
+/* (c) Copyright IBM Corp. and others, 2019 */
+/* */
+/********************************************************************************/
+
+/* rev 155 */
+
+#ifndef CERTIFYX509_FP_H
+#define CERTIFYX509_FP_H
+
+typedef struct {
+ TPMI_DH_OBJECT objectHandle;
+ TPMI_DH_OBJECT signHandle;
+ TPM2B_DATA reserved;
+ TPMT_SIG_SCHEME inScheme;
+ TPM2B_MAX_BUFFER partialCertificate;
+} CertifyX509_In;
+
+#define RC_CertifyX509_signHandle (TPM_RC_H + TPM_RC_1)
+#define RC_CertifyX509_objectHandle (TPM_RC_H + TPM_RC_2)
+#define RC_CertifyX509_reserved (TPM_RC_P + TPM_RC_1)
+#define RC_CertifyX509_inScheme (TPM_RC_P + TPM_RC_2)
+#define RC_CertifyX509_partialCertificate (TPM_RC_P + TPM_RC_3)
+
+typedef struct {
+ TPM2B_MAX_BUFFER addedToCertificate;
+ TPM2B_DIGEST tbsDigest;
+ TPMT_SIGNATURE signature;
+} CertifyX509_Out;
+
+TPM_RC
+TPM2_CertifyX509(
+ CertifyX509_In *in, // IN: input parameter list
+ CertifyX509_Out *out // OUT: output parameter list
+ );
+
+#endif
diff --git a/src/tpm2/Certify_fp.h b/src/tpm2/Certify_fp.h
new file mode 100644
index 0000000..2e2ff6d
--- /dev/null
+++ b/src/tpm2/Certify_fp.h
@@ -0,0 +1,93 @@
+/********************************************************************************/
+/* */
+/* */
+/* Written by Ken Goldman */
+/* IBM Thomas J. Watson Research Center */
+/* $Id: Certify_fp.h 809 2016-11-16 18:31:54Z kgoldman $ */
+/* */
+/* Licenses and Notices */
+/* */
+/* 1. Copyright Licenses: */
+/* */
+/* - Trusted Computing Group (TCG) grants to the user of the source code in */
+/* this specification (the "Source Code") a worldwide, irrevocable, */
+/* nonexclusive, royalty free, copyright license to reproduce, create */
+/* derivative works, distribute, display and perform the Source Code and */
+/* derivative works thereof, and to grant others the rights granted herein. */
+/* */
+/* - The TCG grants to the user of the other parts of the specification */
+/* (other than the Source Code) the rights to reproduce, distribute, */
+/* display, and perform the specification solely for the purpose of */
+/* developing products based on such documents. */
+/* */
+/* 2. Source Code Distribution Conditions: */
+/* */
+/* - Redistributions of Source Code must retain the above copyright licenses, */
+/* this list of conditions and the following disclaimers. */
+/* */
+/* - Redistributions in binary form must reproduce the above copyright */
+/* licenses, this list of conditions and the following disclaimers in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* 3. Disclaimers: */
+/* */
+/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
+/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
+/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
+/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
+/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
+/* information on specification licensing rights available through TCG */
+/* membership agreements. */
+/* */
+/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
+/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
+/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
+/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
+/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
+/* */
+/* - Without limitation, TCG and its members and licensors disclaim all */
+/* liability, including liability for infringement of any proprietary */
+/* rights, relating to use of information in this specification and to the */
+/* implementation of this specification, and TCG disclaims all liability for */
+/* cost of procurement of substitute goods or services, lost profits, loss */
+/* of use, loss of data or any incidental, consequential, direct, indirect, */
+/* or special damages, whether under contract, tort, warranty or otherwise, */
+/* arising in any way out of use or reliance upon this specification or any */
+/* information herein. */
+/* */
+/* (c) Copyright IBM Corp. and others, 2012-2015 */
+/* */
+/********************************************************************************/
+
+/* rev 119 */
+
+#ifndef CERTIFY_FP_H
+#define CERTIFY_FP_H
+
+typedef struct {
+ TPMI_DH_OBJECT objectHandle;
+ TPMI_DH_OBJECT signHandle;
+ TPM2B_DATA qualifyingData;
+ TPMT_SIG_SCHEME inScheme;
+} Certify_In;
+
+#define RC_Certify_objectHandle (TPM_RC_H + TPM_RC_1)
+#define RC_Certify_signHandle (TPM_RC_H + TPM_RC_2)
+#define RC_Certify_qualifyingData (TPM_RC_P + TPM_RC_1)
+#define RC_Certify_inScheme (TPM_RC_P + TPM_RC_2)
+
+typedef struct {
+ TPM2B_ATTEST certifyInfo;
+ TPMT_SIGNATURE signature;
+} Certify_Out;
+
+
+
+TPM_RC
+TPM2_Certify(
+ Certify_In *in, // IN: input parameter list
+ Certify_Out *out // OUT: output parameter list
+ );
+
+
+#endif
diff --git a/src/tpm2/ChangeEPS_fp.h b/src/tpm2/ChangeEPS_fp.h
new file mode 100644
index 0000000..33001e9
--- /dev/null
+++ b/src/tpm2/ChangeEPS_fp.h
@@ -0,0 +1,79 @@
+/********************************************************************************/
+/* */
+/* */
+/* Written by Ken Goldman */
+/* IBM Thomas J. Watson Research Center */
+/* $Id: ChangeEPS_fp.h 809 2016-11-16 18:31:54Z kgoldman $ */
+/* */
+/* Licenses and Notices */
+/* */
+/* 1. Copyright Licenses: */
+/* */
+/* - Trusted Computing Group (TCG) grants to the user of the source code in */
+/* this specification (the "Source Code") a worldwide, irrevocable, */
+/* nonexclusive, royalty free, copyright license to reproduce, create */
+/* derivative works, distribute, display and perform the Source Code and */
+/* derivative works thereof, and to grant others the rights granted herein. */
+/* */
+/* - The TCG grants to the user of the other parts of the specification */
+/* (other than the Source Code) the rights to reproduce, distribute, */
+/* display, and perform the specification solely for the purpose of */
+/* developing products based on such documents. */
+/* */
+/* 2. Source Code Distribution Conditions: */
+/* */
+/* - Redistributions of Source Code must retain the above copyright licenses, */
+/* this list of conditions and the following disclaimers. */
+/* */
+/* - Redistributions in binary form must reproduce the above copyright */
+/* licenses, this list of conditions and the following disclaimers in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* 3. Disclaimers: */
+/* */
+/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
+/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
+/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
+/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
+/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
+/* information on specification licensing rights available through TCG */
+/* membership agreements. */
+/* */
+/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
+/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
+/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
+/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
+/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
+/* */
+/* - Without limitation, TCG and its members and licensors disclaim all */
+/* liability, including liability for infringement of any proprietary */
+/* rights, relating to use of information in this specification and to the */
+/* implementation of this specification, and TCG disclaims all liability for */
+/* cost of procurement of substitute goods or services, lost profits, loss */
+/* of use, loss of data or any incidental, consequential, direct, indirect, */
+/* or special damages, whether under contract, tort, warranty or otherwise, */
+/* arising in any way out of use or reliance upon this specification or any */
+/* information herein. */
+/* */
+/* (c) Copyright IBM Corp. and others, 2012-2015 */
+/* */
+/********************************************************************************/
+
+/* rev 119 */
+
+#ifndef CHANGEEPS_FP_H
+#define CHANGEEPS_FP_H
+
+typedef struct {
+ TPMI_RH_PLATFORM authHandle;
+} ChangeEPS_In;
+
+#define RC_ChangeEPS_authHandle (TPM_RC_H + TPM_RC_1)
+
+TPM_RC
+TPM2_ChangeEPS(
+ ChangeEPS_In *in // IN: input parameter list
+ );
+
+
+#endif
diff --git a/src/tpm2/ChangePPS_fp.h b/src/tpm2/ChangePPS_fp.h
new file mode 100644
index 0000000..ec1ba45
--- /dev/null
+++ b/src/tpm2/ChangePPS_fp.h
@@ -0,0 +1,79 @@
+/********************************************************************************/
+/* */
+/* */
+/* Written by Ken Goldman */
+/* IBM Thomas J. Watson Research Center */
+/* $Id: ChangePPS_fp.h 809 2016-11-16 18:31:54Z kgoldman $ */
+/* */
+/* Licenses and Notices */
+/* */
+/* 1. Copyright Licenses: */
+/* */
+/* - Trusted Computing Group (TCG) grants to the user of the source code in */
+/* this specification (the "Source Code") a worldwide, irrevocable, */
+/* nonexclusive, royalty free, copyright license to reproduce, create */
+/* derivative works, distribute, display and perform the Source Code and */
+/* derivative works thereof, and to grant others the rights granted herein. */
+/* */
+/* - The TCG grants to the user of the other parts of the specification */
+/* (other than the Source Code) the rights to reproduce, distribute, */
+/* display, and perform the specification solely for the purpose of */
+/* developing products based on such documents. */
+/* */
+/* 2. Source Code Distribution Conditions: */
+/* */
+/* - Redistributions of Source Code must retain the above copyright licenses, */
+/* this list of conditions and the following disclaimers. */
+/* */
+/* - Redistributions in binary form must reproduce the above copyright */
+/* licenses, this list of conditions and the following disclaimers in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* 3. Disclaimers: */
+/* */
+/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
+/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
+/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
+/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
+/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
+/* information on specification licensing rights available through TCG */
+/* membership agreements. */
+/* */
+/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
+/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
+/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
+/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
+/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
+/* */
+/* - Without limitation, TCG and its members and licensors disclaim all */
+/* liability, including liability for infringement of any proprietary */
+/* rights, relating to use of information in this specification and to the */
+/* implementation of this specification, and TCG disclaims all liability for */
+/* cost of procurement of substitute goods or services, lost profits, loss */
+/* of use, loss of data or any incidental, consequential, direct, indirect, */
+/* or special damages, whether under contract, tort, warranty or otherwise, */
+/* arising in any way out of use or reliance upon this specification or any */
+/* information herein. */
+/* */
+/* (c) Copyright IBM Corp. and others, 2012-2015 */
+/* */
+/********************************************************************************/
+
+/* rev 119 */
+
+#ifndef CHANGEPPS_FP_H
+#define CHANGEPPS_FP_H
+
+typedef struct {
+ TPMI_RH_PLATFORM authHandle;
+} ChangePPS_In;
+
+#define RC_ChangePPS_authHandle (TPM_RC_P + TPM_RC_1)
+
+TPM_RC
+TPM2_ChangePPS(
+ ChangePPS_In *in // IN: input parameter list
+ );
+
+
+#endif
diff --git a/src/tpm2/ClearControl_fp.h b/src/tpm2/ClearControl_fp.h
new file mode 100644
index 0000000..7c6920e
--- /dev/null
+++ b/src/tpm2/ClearControl_fp.h
@@ -0,0 +1,79 @@
+/********************************************************************************/
+/* */
+/* */
+/* Written by Ken Goldman */
+/* IBM Thomas J. Watson Research Center */
+/* $Id: ClearControl_fp.h 1521 2019-11-15 21:00:47Z kgoldman $ */
+/* */
+/* Licenses and Notices */
+/* */
+/* 1. Copyright Licenses: */
+/* */
+/* - Trusted Computing Group (TCG) grants to the user of the source code in */
+/* this specification (the "Source Code") a worldwide, irrevocable, */
+/* nonexclusive, royalty free, copyright license to reproduce, create */
+/* derivative works, distribute, display and perform the Source Code and */
+/* derivative works thereof, and to grant others the rights granted herein. */
+/* */
+/* - The TCG grants to the user of the other parts of the specification */
+/* (other than the Source Code) the rights to reproduce, distribute, */
+/* display, and perform the specification solely for the purpose of */
+/* developing products based on such documents. */
+/* */
+/* 2. Source Code Distribution Conditions: */
+/* */
+/* - Redistributions of Source Code must retain the above copyright licenses, */
+/* this list of conditions and the following disclaimers. */
+/* */
+/* - Redistributions in binary form must reproduce the above copyright */
+/* licenses, this list of conditions and the following disclaimers in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* 3. Disclaimers: */
+/* */
+/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
+/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
+/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
+/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
+/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
+/* information on specification licensing rights available through TCG */
+/* membership agreements. */
+/* */
+/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
+/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
+/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
+/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
+/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
+/* */
+/* - Without limitation, TCG and its members and licensors disclaim all */
+/* liability, including liability for infringement of any proprietary */
+/* rights, relating to use of information in this specification and to the */
+/* implementation of this specification, and TCG disclaims all liability for */
+/* cost of procurement of substitute goods or services, lost profits, loss */
+/* of use, loss of data or any incidental, consequential, direct, indirect, */
+/* or special damages, whether under contract, tort, warranty or otherwise, */
+/* arising in any way out of use or reliance upon this specification or any */
+/* information herein. */
+/* */
+/* (c) Copyright IBM Corp. and others, 2012-2015 */
+/* */
+/********************************************************************************/
+
+/* rev 119 */
+
+#ifndef CLEARCONTROL_FP_H
+#define CLEARCONTROL_FP_H
+
+typedef struct {
+ TPMI_RH_CLEAR auth;
+ TPMI_YES_NO disable;
+} ClearControl_In;
+
+#define RC_ClearControl_auth (TPM_RC_H + TPM_RC_1)
+#define RC_ClearControl_disable (TPM_RC_P + TPM_RC_1)
+
+TPM_RC
+TPM2_ClearControl(
+ ClearControl_In *in // IN: input parameter list
+ );
+#endif
diff --git a/src/tpm2/Clear_fp.h b/src/tpm2/Clear_fp.h
new file mode 100644
index 0000000..4440777
--- /dev/null
+++ b/src/tpm2/Clear_fp.h
@@ -0,0 +1,78 @@
+/********************************************************************************/
+/* */
+/* */
+/* Written by Ken Goldman */
+/* IBM Thomas J. Watson Research Center */
+/* $Id: Clear_fp.h 809 2016-11-16 18:31:54Z kgoldman $ */
+/* */
+/* Licenses and Notices */
+/* */
+/* 1. Copyright Licenses: */
+/* */
+/* - Trusted Computing Group (TCG) grants to the user of the source code in */
+/* this specification (the "Source Code") a worldwide, irrevocable, */
+/* nonexclusive, royalty free, copyright license to reproduce, create */
+/* derivative works, distribute, display and perform the Source Code and */
+/* derivative works thereof, and to grant others the rights granted herein. */
+/* */
+/* - The TCG grants to the user of the other parts of the specification */
+/* (other than the Source Code) the rights to reproduce, distribute, */
+/* display, and perform the specification solely for the purpose of */
+/* developing products based on such documents. */
+/* */
+/* 2. Source Code Distribution Conditions: */
+/* */
+/* - Redistributions of Source Code must retain the above copyright licenses, */
+/* this list of conditions and the following disclaimers. */
+/* */
+/* - Redistributions in binary form must reproduce the above copyright */
+/* licenses, this list of conditions and the following disclaimers in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* 3. Disclaimers: */
+/* */
+/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
+/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
+/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
+/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
+/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
+/* information on specification licensing rights available through TCG */
+/* membership agreements. */
+/* */
+/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
+/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
+/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
+/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
+/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
+/* */
+/* - Without limitation, TCG and its members and licensors disclaim all */
+/* liability, including liability for infringement of any proprietary */
+/* rights, relating to use of information in this specification and to the */
+/* implementation of this specification, and TCG disclaims all liability for */
+/* cost of procurement of substitute goods or services, lost profits, loss */
+/* of use, loss of data or any incidental, consequential, direct, indirect, */
+/* or special damages, whether under contract, tort, warranty or otherwise, */
+/* arising in any way out of use or reliance upon this specification or any */
+/* information herein. */
+/* */
+/* (c) Copyright IBM Corp. and others, 2012-2015 */
+/* */
+/********************************************************************************/
+
+/* rev 119 */
+
+#ifndef CLEAR_FP_H
+#define CLEAR_FP_H
+
+typedef struct {
+ TPMI_RH_CLEAR authHandle;
+} Clear_In;
+
+#define RC_Clear_authHandle (TPM_RC_H + TPM_RC_1)
+
+TPM_RC
+TPM2_Clear(
+ Clear_In *in // IN: input parameter list
+ );
+
+#endif
diff --git a/src/tpm2/Clock.c b/src/tpm2/Clock.c
new file mode 100644
index 0000000..cbbcc41
--- /dev/null
+++ b/src/tpm2/Clock.c
@@ -0,0 +1,346 @@
+/********************************************************************************/
+/* */
+/* Used by the simulator to mimic a hardware clock */
+/* Written by Ken Goldman */
+/* IBM Thomas J. Watson Research Center */
+/* $Id: Clock.c 1529 2019-11-21 23:29:01Z kgoldman $ */
+/* */
+/* Licenses and Notices */
+/* */
+/* 1. Copyright Licenses: */
+/* */
+/* - Trusted Computing Group (TCG) grants to the user of the source code in */
+/* this specification (the "Source Code") a worldwide, irrevocable, */
+/* nonexclusive, royalty free, copyright license to reproduce, create */
+/* derivative works, distribute, display and perform the Source Code and */
+/* derivative works thereof, and to grant others the rights granted herein. */
+/* */
+/* - The TCG grants to the user of the other parts of the specification */
+/* (other than the Source Code) the rights to reproduce, distribute, */
+/* display, and perform the specification solely for the purpose of */
+/* developing products based on such documents. */
+/* */
+/* 2. Source Code Distribution Conditions: */
+/* */
+/* - Redistributions of Source Code must retain the above copyright licenses, */
+/* this list of conditions and the following disclaimers. */
+/* */
+/* - Redistributions in binary form must reproduce the above copyright */
+/* licenses, this list of conditions and the following disclaimers in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* 3. Disclaimers: */
+/* */
+/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
+/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
+/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
+/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
+/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
+/* information on specification licensing rights available through TCG */
+/* membership agreements. */
+/* */
+/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
+/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
+/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
+/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
+/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
+/* */
+/* - Without limitation, TCG and its members and licensors disclaim all */
+/* liability, including liability for infringement of any proprietary */
+/* rights, relating to use of information in this specification and to the */
+/* implementation of this specification, and TCG disclaims all liability for */
+/* cost of procurement of substitute goods or services, lost profits, loss */
+/* of use, loss of data or any incidental, consequential, direct, indirect, */
+/* or special damages, whether under contract, tort, warranty or otherwise, */
+/* arising in any way out of use or reliance upon this specification or any */
+/* information herein. */
+/* */
+/* (c) Copyright IBM Corp. and others, 2016 - 2019 */
+/* */
+/********************************************************************************/
+
+/* added for portability because Linux clock is 32 bits */
+
+#include <stdint.h>
+#include <stdio.h>
+#include <time.h>
+
+/* C.3 Clock.c */
+/* C.3.1. Description */
+/* This file contains the routines that are used by the simulator to mimic a hardware clock on a
+ TPM. In this implementation, all the time values are measured in millisecond. However, the
+ precision of the clock functions may be implementation dependent. */
+/* C.3.2. Includes and Data Definitions */
+#include <assert.h>
+#include "Platform.h"
+#include "TpmFail_fp.h"
+
+/* libtpms added begin */
+/* ClockGetTime -- get time given a specified clock type */
+uint64_t
+ClockGetTime(
+ clockid_t clk_id
+ )
+{
+ uint64_t time;
+#ifdef TPM_WINDOWS
+#error Not supported for TPM_WINDOWS
+#else
+ struct timespec systime;
+
+ clock_gettime(clk_id, &systime);
+ time = (uint64_t)systime.tv_sec * 1000 + (systime.tv_nsec / 1000000);
+#endif
+
+ return time;
+}
+
+/* ClockAdjustPostResume -- adjust time parameters post resume */
+#include "Tpm.h"
+void
+ClockAdjustPostResume(UINT64 backthen, BOOL timesAreRealtime)
+{
+ UINT64 now = ClockGetTime(CLOCK_REALTIME);
+ INT64 timediff = now - backthen;
+
+ if (timesAreRealtime) {
+ /* g_time, s_realTimePrevious, s_tpmTime are all in real time */
+ s_suspendedElapsedTime = now;
+ s_hostMonotonicAdjustTime = -ClockGetTime(CLOCK_MONOTONIC);
+
+ /* s_lastSystemTime & s_lastReportTime need to be set as well */
+ s_lastSystemTime = now;
+ s_lastReportedTime = now;
+ } else if (timediff >= 0) {
+ s_suspendedElapsedTime += timediff;
+ }
+}
+/* libtpms added end */
+
+/* C.3.3. Simulator Functions */
+/* C.3.3.1. Introduction */
+/* This set of functions is intended to be called by the simulator environment in order to simulate
+ hardware events. */
+/* C.3.3.2. _plat__TimerReset() */
+/* This function sets current system clock time as t0 for counting TPM time. This function is called
+ at a power on event to reset the clock. When the clock is reset, the indication that the clock
+ was stopped is also set. */
+LIB_EXPORT void
+_plat__TimerReset(
+ void
+ )
+{
+ s_lastSystemTime = 0;
+ s_tpmTime = 0;
+ s_adjustRate = CLOCK_NOMINAL;
+ s_timerReset = TRUE;
+ s_timerStopped = TRUE;
+ s_hostMonotonicAdjustTime = 0; /* libtpms added */
+ s_suspendedElapsedTime = 0; /* libtpms added */
+ return;
+}
+/* C.3.3.3. _plat__TimerRestart() */
+/* This function should be called in order to simulate the restart of the timer should it be stopped
+ while power is still applied. */
+LIB_EXPORT void
+_plat__TimerRestart(
+ void
+ )
+{
+ s_timerStopped = TRUE;
+ return;
+}
+
+/* C.3.4. Functions Used by TPM */
+/* C.3.4.1. Introduction */
+/* These functions are called by the TPM code. They should be replaced by appropriated hardware
+ functions. */
+
+clock_t debugTime;
+/* C.3.4.2. _plat__Time() */
+/* This is another, probably futile, attempt to define a portable function that will return a 64-bit
+ clock value that has mSec resolution. */
+LIB_EXPORT uint64_t
+_plat__RealTime(
+ void
+ )
+{
+ clock64_t time;
+ //#ifdef _MSC_VER kgold
+#ifdef TPM_WINDOWS
+ #include <sys/timeb.h>
+ struct _timeb sysTime;
+ //
+ _ftime(&sysTime); /* kgold, mingw doesn't have _ftime_s */
+ time = (clock64_t)(sysTime.time) * 1000 + sysTime.millitm;
+ // set the time back by one hour if daylight savings
+ if(sysTime.dstflag)
+ time -= 1000 * 60 * 60; // mSec/sec * sec/min * min/hour = ms/hour
+#else
+ // hopefully, this will work with most UNIX systems
+ struct timespec systime;
+ //
+ clock_gettime(CLOCK_MONOTONIC, &systime);
+ time = (clock64_t)systime.tv_sec * 1000 + (systime.tv_nsec / 1000000);
+#endif
+ /* libtpms added begin */
+ /* We have to make sure that this function returns monotonically increasing time
+ also when a vTPM has been suspended and the host has been rebooted.
+ Example:
+ - The vTPM is suspended at systime '5'
+ - The vTPM is resumed at systime '1' after a host reboot
+ -> we now need to add '4' to the time
+ Besides this we want to account for the time a vTPM was suspended.
+ If it was suspended for 10 time units, we need to add '10' here.
+ */
+ time += s_hostMonotonicAdjustTime + s_suspendedElapsedTime;
+ /* libtpms added end */
+ return time;
+}
+
+
+
+/* C.3.4.3. _plat__TimerRead() */
+/* This function provides access to the tick timer of the platform. The TPM code uses this value to
+ drive the TPM Clock. */
+/* The tick timer is supposed to run when power is applied to the device. This timer should not be
+ reset by time events including _TPM_Init(). It should only be reset when TPM power is
+ re-applied. */
+/* If the TPM is run in a protected environment, that environment may provide the tick time to the
+ TPM as long as the time provided by the environment is not allowed to go backwards. If the time
+ provided by the system can go backwards during a power discontinuity, then the
+ _plat__Signal_PowerOn() should call _plat__TimerReset(). */
+LIB_EXPORT uint64_t
+_plat__TimerRead(
+ void
+ )
+{
+#ifdef HARDWARE_CLOCK
+#error "need a definition for reading the hardware clock"
+ return HARDWARE_CLOCK
+#else
+ clock64_t timeDiff;
+ clock64_t adjustedTimeDiff;
+ clock64_t timeNow;
+ clock64_t readjustedTimeDiff;
+ // This produces a timeNow that is basically locked to the system clock.
+ timeNow = _plat__RealTime();
+ // if this hasn't been initialized, initialize it
+ if(s_lastSystemTime == 0)
+ {
+ s_lastSystemTime = timeNow;
+ debugTime = clock();
+ s_lastReportedTime = 0;
+ s_realTimePrevious = 0;
+ }
+ // The system time can bounce around and that's OK as long as we don't allow
+ // time to go backwards. When the time does appear to go backwards, set
+ // lastSystemTime to be the new value and then update the reported time.
+ if(timeNow < s_lastReportedTime)
+ s_lastSystemTime = timeNow;
+ s_lastReportedTime = s_lastReportedTime + timeNow - s_lastSystemTime;
+ s_lastSystemTime = timeNow;
+ timeNow = s_lastReportedTime;
+ // The code above produces a timeNow that is similar to the value returned
+ // by Clock(). The difference is that timeNow does not max out, and it is
+ // at a ms. rate rather than at a CLOCKS_PER_SEC rate. The code below
+ // uses that value and does the rate adjustment on the time value.
+ // If there is no difference in time, then skip all the computations
+ if(s_realTimePrevious >= timeNow)
+ return s_tpmTime;
+ // Compute the amount of time since the last update of the system clock
+ timeDiff = timeNow - s_realTimePrevious;
+ // Do the time rate adjustment and conversion from CLOCKS_PER_SEC to mSec
+ adjustedTimeDiff = (timeDiff * CLOCK_NOMINAL) / ((uint64_t)s_adjustRate);
+ // update the TPM time with the adjusted timeDiff
+ s_tpmTime += (clock64_t)adjustedTimeDiff;
+ // Might have some rounding error that would loose CLOCKS. See what is not
+ // being used. As mentioned above, this could result in putting back more than
+ // is taken out. Here, we are trying to recreate timeDiff.
+ readjustedTimeDiff = (adjustedTimeDiff * (uint64_t)s_adjustRate )
+ / CLOCK_NOMINAL;
+ // adjusted is now converted back to being the amount we should advance the
+ // previous sampled time. It should always be less than or equal to timeDiff.
+ // That is, we could not have use more time than we started with.
+ s_realTimePrevious = s_realTimePrevious + readjustedTimeDiff;
+#ifdef DEBUGGING_TIME
+ // Put this in so that TPM time will pass much faster than real time when
+ // doing debug.
+ // A value of 1000 for DEBUG_TIME_MULTIPLER will make each ms into a second
+ // A good value might be 100
+ return (s_tpmTime * DEBUG_TIME_MULTIPLIER);
+#endif
+ return s_tpmTime;
+#endif
+}
+
+
+/* C.3.4.3. _plat__TimerWasReset() */
+/* This function is used to interrogate the flag indicating if the tick timer has been reset. */
+/* If the resetFlag parameter is SET, then the flag will be CLEAR before the function returns. */
+LIB_EXPORT int
+_plat__TimerWasReset(
+ void
+ )
+{
+ int retVal = s_timerReset;
+ s_timerReset = FALSE;
+ return retVal;
+}
+/* C.3.4.4. _plat__TimerWasStopped() */
+/* This function is used to interrogate the flag indicating if the tick timer has been stopped. If
+ so, this is typically a reason to roll the nonce. */
+/* This function will CLEAR the s_timerStopped flag before returning. This provides functionality
+ that is similar to status register that is cleared when read. This is the model used here because
+ it is the one that has the most impact on the TPM code as the flag can only be accessed by one
+ entity in the TPM. Any other implementation of the hardware can be made to look like a read-once
+ register. */
+LIB_EXPORT int
+_plat__TimerWasStopped(
+ void
+ )
+{
+ BOOL retVal = s_timerStopped;
+ s_timerStopped = FALSE;
+ return retVal;
+}
+/* C.3.4.5. _plat__ClockAdjustRate() */
+/* Adjust the clock rate */
+LIB_EXPORT void
+_plat__ClockAdjustRate(
+ int adjust // IN: the adjust number. It could be positive
+ // or negative
+ )
+{
+ // We expect the caller should only use a fixed set of constant values to
+ // adjust the rate
+ switch(adjust)
+ {
+ case CLOCK_ADJUST_COARSE:
+ s_adjustRate += CLOCK_ADJUST_COARSE;
+ break;
+ case -CLOCK_ADJUST_COARSE:
+ s_adjustRate -= CLOCK_ADJUST_COARSE;
+ break;
+ case CLOCK_ADJUST_MEDIUM:
+ s_adjustRate += CLOCK_ADJUST_MEDIUM;
+ break;
+ case -CLOCK_ADJUST_MEDIUM:
+ s_adjustRate -= CLOCK_ADJUST_MEDIUM;
+ break;
+ case CLOCK_ADJUST_FINE:
+ s_adjustRate += CLOCK_ADJUST_FINE;
+ break;
+ case -CLOCK_ADJUST_FINE:
+ s_adjustRate -= CLOCK_ADJUST_FINE;
+ break;
+ default:
+ // ignore any other values;
+ break;
+ }
+ if(s_adjustRate > (CLOCK_NOMINAL + CLOCK_ADJUST_LIMIT))
+ s_adjustRate = CLOCK_NOMINAL + CLOCK_ADJUST_LIMIT;
+ if(s_adjustRate < (CLOCK_NOMINAL - CLOCK_ADJUST_LIMIT))
+ s_adjustRate = CLOCK_NOMINAL - CLOCK_ADJUST_LIMIT;
+ return;
+}
diff --git a/src/tpm2/ClockCommands.c b/src/tpm2/ClockCommands.c
new file mode 100644
index 0000000..fa0837c
--- /dev/null
+++ b/src/tpm2/ClockCommands.c
@@ -0,0 +1,109 @@
+/********************************************************************************/
+/* */
+/* Clocks and Timers */
+/* Written by Ken Goldman */
+/* IBM Thomas J. Watson Research Center */
+/* $Id: ClockCommands.c 1519 2019-11-15 20:43:51Z kgoldman $ */
+/* */
+/* Licenses and Notices */
+/* */
+/* 1. Copyright Licenses: */
+/* */
+/* - Trusted Computing Group (TCG) grants to the user of the source code in */
+/* this specification (the "Source Code") a worldwide, irrevocable, */
+/* nonexclusive, royalty free, copyright license to reproduce, create */
+/* derivative works, distribute, display and perform the Source Code and */
+/* derivative works thereof, and to grant others the rights granted herein. */
+/* */
+/* - The TCG grants to the user of the other parts of the specification */
+/* (other than the Source Code) the rights to reproduce, distribute, */
+/* display, and perform the specification solely for the purpose of */
+/* developing products based on such documents. */
+/* */
+/* 2. Source Code Distribution Conditions: */
+/* */
+/* - Redistributions of Source Code must retain the above copyright licenses, */
+/* this list of conditions and the following disclaimers. */
+/* */
+/* - Redistributions in binary form must reproduce the above copyright */
+/* licenses, this list of conditions and the following disclaimers in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* 3. Disclaimers: */
+/* */
+/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
+/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
+/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
+/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
+/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
+/* information on specification licensing rights available through TCG */
+/* membership agreements. */
+/* */
+/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
+/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
+/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
+/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
+/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
+/* */
+/* - Without limitation, TCG and its members and licensors disclaim all */
+/* liability, including liability for infringement of any proprietary */
+/* rights, relating to use of information in this specification and to the */
+/* implementation of this specification, and TCG disclaims all liability for */
+/* cost of procurement of substitute goods or services, lost profits, loss */
+/* of use, loss of data or any incidental, consequential, direct, indirect, */
+/* or special damages, whether under contract, tort, warranty or otherwise, */
+/* arising in any way out of use or reliance upon this specification or any */
+/* information herein. */
+/* */
+/* (c) Copyright IBM Corp. and others, 2016 - 2018 */
+/* */
+/********************************************************************************/
+
+#include "Tpm.h"
+#include "ReadClock_fp.h"
+#if CC_ReadClock // Conditional expansion of this file
+TPM_RC
+TPM2_ReadClock(
+ ReadClock_Out *out // OUT: output parameter list
+ )
+{
+ // Command Output
+ out->currentTime.time = g_time;
+ TimeFillInfo(&out->currentTime.clockInfo);
+ return TPM_RC_SUCCESS;
+}
+#endif // CC_ReadClock
+#include "Tpm.h"
+#include "ClockSet_fp.h"
+#if CC_ClockSet // Conditional expansion of this file
+TPM_RC
+TPM2_ClockSet(
+ ClockSet_In *in // IN: input parameter list
+ )
+{
+ // Input Validation
+ // new time can not be bigger than 0xFFFF000000000000 or smaller than
+ // current clock
+ if(in->newTime > 0xFFFF000000000000ULL
+ || in->newTime < go.clock)
+ return TPM_RCS_VALUE + RC_ClockSet_newTime;
+ // Internal Data Update
+ // Can't modify the clock if NV is not available.
+ RETURN_IF_NV_IS_NOT_AVAILABLE;
+ TimeClockUpdate(in->newTime);
+ return TPM_RC_SUCCESS;
+}
+#endif // CC_ClockSet
+#include "Tpm.h"
+#include "ClockRateAdjust_fp.h"
+#if CC_ClockRateAdjust // Conditional expansion of this file
+TPM_RC
+TPM2_ClockRateAdjust(
+ ClockRateAdjust_In *in // IN: input parameter list
+ )
+{
+ // Internal Data Update
+ TimeSetAdjustRate(in->rateAdjust);
+ return TPM_RC_SUCCESS;
+}
+#endif // CC_ClockRateAdjust
diff --git a/src/tpm2/ClockRateAdjust_fp.h b/src/tpm2/ClockRateAdjust_fp.h
new file mode 100644
index 0000000..0c02067
--- /dev/null
+++ b/src/tpm2/ClockRateAdjust_fp.h
@@ -0,0 +1,81 @@
+/********************************************************************************/
+/* */
+/* */
+/* Written by Ken Goldman */
+/* IBM Thomas J. Watson Research Center */
+/* $Id: ClockRateAdjust_fp.h 809 2016-11-16 18:31:54Z kgoldman $ */
+/* */
+/* Licenses and Notices */
+/* */
+/* 1. Copyright Licenses: */
+/* */
+/* - Trusted Computing Group (TCG) grants to the user of the source code in */
+/* this specification (the "Source Code") a worldwide, irrevocable, */
+/* nonexclusive, royalty free, copyright license to reproduce, create */
+/* derivative works, distribute, display and perform the Source Code and */
+/* derivative works thereof, and to grant others the rights granted herein. */
+/* */
+/* - The TCG grants to the user of the other parts of the specification */
+/* (other than the Source Code) the rights to reproduce, distribute, */
+/* display, and perform the specification solely for the purpose of */
+/* developing products based on such documents. */
+/* */
+/* 2. Source Code Distribution Conditions: */
+/* */
+/* - Redistributions of Source Code must retain the above copyright licenses, */
+/* this list of conditions and the following disclaimers. */
+/* */
+/* - Redistributions in binary form must reproduce the above copyright */
+/* licenses, this list of conditions and the following disclaimers in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* 3. Disclaimers: */
+/* */
+/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
+/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
+/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
+/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
+/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
+/* information on specification licensing rights available through TCG */
+/* membership agreements. */
+/* */
+/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
+/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
+/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
+/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
+/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
+/* */
+/* - Without limitation, TCG and its members and licensors disclaim all */
+/* liability, including liability for infringement of any proprietary */
+/* rights, relating to use of information in this specification and to the */
+/* implementation of this specification, and TCG disclaims all liability for */
+/* cost of procurement of substitute goods or services, lost profits, loss */
+/* of use, loss of data or any incidental, consequential, direct, indirect, */
+/* or special damages, whether under contract, tort, warranty or otherwise, */
+/* arising in any way out of use or reliance upon this specification or any */
+/* information herein. */
+/* */
+/* (c) Copyright IBM Corp. and others, 2012-2015 */
+/* */
+/********************************************************************************/
+
+/* rev 119 */
+
+#ifndef CLOCKRATEADJUST_FP_H
+#define CLOCKRATEADJUST_FP_H
+
+typedef struct {
+ TPMI_RH_PROVISION auth;
+ TPM_CLOCK_ADJUST rateAdjust;
+} ClockRateAdjust_In;
+
+#define RC_ClockRateAdjust_auth (TPM_RC_H + TPM_RC_1)
+#define RC_ClockRateAdjust_rateAdjust (TPM_RC_P + TPM_RC_1)
+
+
+TPM_RC
+TPM2_ClockRateAdjust(
+ ClockRateAdjust_In *in // IN: input parameter list
+ );
+
+#endif
diff --git a/src/tpm2/ClockSet_fp.h b/src/tpm2/ClockSet_fp.h
new file mode 100644
index 0000000..8f76b73
--- /dev/null
+++ b/src/tpm2/ClockSet_fp.h
@@ -0,0 +1,81 @@
+/********************************************************************************/
+/* */
+/* */
+/* Written by Ken Goldman */
+/* IBM Thomas J. Watson Research Center */
+/* $Id: ClockSet_fp.h 809 2016-11-16 18:31:54Z kgoldman $ */
+/* */
+/* Licenses and Notices */
+/* */
+/* 1. Copyright Licenses: */
+/* */
+/* - Trusted Computing Group (TCG) grants to the user of the source code in */
+/* this specification (the "Source Code") a worldwide, irrevocable, */
+/* nonexclusive, royalty free, copyright license to reproduce, create */
+/* derivative works, distribute, display and perform the Source Code and */
+/* derivative works thereof, and to grant others the rights granted herein. */
+/* */
+/* - The TCG grants to the user of the other parts of the specification */
+/* (other than the Source Code) the rights to reproduce, distribute, */
+/* display, and perform the specification solely for the purpose of */
+/* developing products based on such documents. */
+/* */
+/* 2. Source Code Distribution Conditions: */
+/* */
+/* - Redistributions of Source Code must retain the above copyright licenses, */
+/* this list of conditions and the following disclaimers. */
+/* */
+/* - Redistributions in binary form must reproduce the above copyright */
+/* licenses, this list of conditions and the following disclaimers in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* 3. Disclaimers: */
+/* */
+/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
+/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
+/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
+/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
+/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
+/* information on specification licensing rights available through TCG */
+/* membership agreements. */
+/* */
+/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
+/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
+/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
+/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
+/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
+/* */
+/* - Without limitation, TCG and its members and licensors disclaim all */
+/* liability, including liability for infringement of any proprietary */
+/* rights, relating to use of information in this specification and to the */
+/* implementation of this specification, and TCG disclaims all liability for */
+/* cost of procurement of substitute goods or services, lost profits, loss */
+/* of use, loss of data or any incidental, consequential, direct, indirect, */
+/* or special damages, whether under contract, tort, warranty or otherwise, */
+/* arising in any way out of use or reliance upon this specification or any */
+/* information herein. */
+/* */
+/* (c) Copyright IBM Corp. and others, 2012-2015 */
+/* */
+/********************************************************************************/
+
+/* rev 119 */
+
+#ifndef CLOCKSET_FP_H
+#define CLOCKSET_FP_H
+
+typedef struct {
+ TPMI_RH_PROVISION auth;
+ UINT64 newTime;
+} ClockSet_In;
+
+#define RC_ClockSet_auth (TPM_RC_H + TPM_RC_1)
+#define RC_ClockSet_newTime (TPM_RC_P + TPM_RC_1)
+
+TPM_RC
+TPM2_ClockSet(
+ ClockSet_In *in // IN: input parameter list
+ );
+
+
+#endif
diff --git a/src/tpm2/CommandAttributeData.h b/src/tpm2/CommandAttributeData.h
new file mode 100644
index 0000000..6facd32
--- /dev/null
+++ b/src/tpm2/CommandAttributeData.h
@@ -0,0 +1,958 @@
+/********************************************************************************/
+/* */
+/* Command code attribute array for GetCapability */
+/* Written by Ken Goldman */
+/* IBM Thomas J. Watson Research Center */
+/* $Id: CommandAttributeData.h 1594 2020-03-26 22:15:48Z kgoldman $ */
+/* */
+/* Licenses and Notices */
+/* */
+/* 1. Copyright Licenses: */
+/* */
+/* - Trusted Computing Group (TCG) grants to the user of the source code in */
+/* this specification (the "Source Code") a worldwide, irrevocable, */
+/* nonexclusive, royalty free, copyright license to reproduce, create */
+/* derivative works, distribute, display and perform the Source Code and */
+/* derivative works thereof, and to grant others the rights granted herein. */
+/* */
+/* - The TCG grants to the user of the other parts of the specification */
+/* (other than the Source Code) the rights to reproduce, distribute, */
+/* display, and perform the specification solely for the purpose of */
+/* developing products based on such documents. */
+/* */
+/* 2. Source Code Distribution Conditions: */
+/* */
+/* - Redistributions of Source Code must retain the above copyright licenses, */
+/* this list of conditions and the following disclaimers. */
+/* */
+/* - Redistributions in binary form must reproduce the above copyright */
+/* licenses, this list of conditions and the following disclaimers in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* 3. Disclaimers: */
+/* */
+/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
+/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
+/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
+/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
+/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
+/* information on specification licensing rights available through TCG */
+/* membership agreements. */
+/* */
+/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
+/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
+/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
+/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
+/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
+/* */
+/* - Without limitation, TCG and its members and licensors disclaim all */
+/* liability, including liability for infringement of any proprietary */
+/* rights, relating to use of information in this specification and to the */
+/* implementation of this specification, and TCG disclaims all liability for */
+/* cost of procurement of substitute goods or services, lost profits, loss */
+/* of use, loss of data or any incidental, consequential, direct, indirect, */
+/* or special damages, whether under contract, tort, warranty or otherwise, */
+/* arising in any way out of use or reliance upon this specification or any */
+/* information herein. */
+/* */
+/* (c) Copyright IBM Corp. and others, 2016 - 2020 */
+/* */
+/********************************************************************************/
+
+/* 5.6 CommandAttributeData.h */
+/* This file should only be included by CommandCodeAttibutes.c */
+
+#ifdef _COMMAND_CODE_ATTRIBUTES_
+#include "CommandAttributes.h"
+#if COMPRESSED_LISTS
+# define PAD_LIST 0
+#else
+# define PAD_LIST 1
+#endif
+
+/* This is the command code attribute array for GetCapability(). Both this array and
+ s_commandAttributes provides command code attributes, but tuned for different purpose */
+
+const TPMA_CC s_ccAttr [] = {
+#if (PAD_LIST || CC_NV_UndefineSpaceSpecial)
+ TPMA_CC_INITIALIZER(0x011f, 0, 1, 0, 0, 2, 0, 0, 0),
+#endif
+#if (PAD_LIST || CC_EvictControl)
+ TPMA_CC_INITIALIZER(0x0120, 0, 1, 0, 0, 2, 0, 0, 0),
+#endif
+#if (PAD_LIST || CC_HierarchyControl)
+ TPMA_CC_INITIALIZER(0x0121, 0, 1, 1, 0, 1, 0, 0, 0),
+#endif
+#if (PAD_LIST || CC_NV_UndefineSpace)
+ TPMA_CC_INITIALIZER(0x0122, 0, 1, 0, 0, 2, 0, 0, 0),
+#endif
+#if (PAD_LIST )
+ TPMA_CC_INITIALIZER(0x0123, 0, 0, 0, 0, 0, 0, 0, 0),
+#endif
+#if (PAD_LIST || CC_ChangeEPS)
+ TPMA_CC_INITIALIZER(0x0124, 0, 1, 1, 0, 1, 0, 0, 0),
+#endif
+#if (PAD_LIST || CC_ChangePPS)
+ TPMA_CC_INITIALIZER(0x0125, 0, 1, 1, 0, 1, 0, 0, 0),
+#endif
+#if (PAD_LIST || CC_Clear)
+ TPMA_CC_INITIALIZER(0x0126, 0, 1, 1, 0, 1, 0, 0, 0),
+#endif
+#if (PAD_LIST || CC_ClearControl)
+ TPMA_CC_INITIALIZER(0x0127, 0, 1, 0, 0, 1, 0, 0, 0),
+#endif
+#if (PAD_LIST || CC_ClockSet)
+ TPMA_CC_INITIALIZER(0x0128, 0, 1, 0, 0, 1, 0, 0, 0),
+#endif
+#if (PAD_LIST || CC_HierarchyChangeAuth)
+ TPMA_CC_INITIALIZER(0x0129, 0, 1, 0, 0, 1, 0, 0, 0),
+#endif
+#if (PAD_LIST || CC_NV_DefineSpace)
+ TPMA_CC_INITIALIZER(0x012a, 0, 1, 0, 0, 1, 0, 0, 0),
+#endif
+#if (PAD_LIST || CC_PCR_Allocate)
+ TPMA_CC_INITIALIZER(0x012b, 0, 1, 0, 0, 1, 0, 0, 0),
+#endif
+#if (PAD_LIST || CC_PCR_SetAuthPolicy)
+ TPMA_CC_INITIALIZER(0x012c, 0, 1, 0, 0, 1, 0, 0, 0),
+#endif
+#if (PAD_LIST || CC_PP_Commands)
+ TPMA_CC_INITIALIZER(0x012d, 0, 1, 0, 0, 1, 0, 0, 0),
+#endif
+#if (PAD_LIST || CC_SetPrimaryPolicy)
+ TPMA_CC_INITIALIZER(0x012e, 0, 1, 0, 0, 1, 0, 0, 0),
+#endif
+#if (PAD_LIST || CC_FieldUpgradeStart)
+ TPMA_CC_INITIALIZER(0x012f, 0, 0, 0, 0, 2, 0, 0, 0),
+#endif
+#if (PAD_LIST || CC_ClockRateAdjust)
+ TPMA_CC_INITIALIZER(0x0130, 0, 0, 0, 0, 1, 0, 0, 0),
+#endif
+#if (PAD_LIST || CC_CreatePrimary)
+ TPMA_CC_INITIALIZER(0x0131, 0, 0, 0, 0, 1, 1, 0, 0),
+#endif
+#if (PAD_LIST || CC_NV_GlobalWriteLock)
+ TPMA_CC_INITIALIZER(0x0132, 0, 1, 0, 0, 1, 0, 0, 0),
+#endif
+#if (PAD_LIST || CC_GetCommandAuditDigest)
+ TPMA_CC_INITIALIZER(0x0133, 0, 1, 0, 0, 2, 0, 0, 0),
+#endif
+#if (PAD_LIST || CC_NV_Increment)
+ TPMA_CC_INITIALIZER(0x0134, 0, 1, 0, 0, 2, 0, 0, 0),
+#endif
+#if (PAD_LIST || CC_NV_SetBits)
+ TPMA_CC_INITIALIZER(0x0135, 0, 1, 0, 0, 2, 0, 0, 0),
+#endif
+#if (PAD_LIST || CC_NV_Extend)
+ TPMA_CC_INITIALIZER(0x0136, 0, 1, 0, 0, 2, 0, 0, 0),
+#endif
+#if (PAD_LIST || CC_NV_Write)
+ TPMA_CC_INITIALIZER(0x0137, 0, 1, 0, 0, 2, 0, 0, 0),
+#endif
+#if (PAD_LIST || CC_NV_WriteLock)
+ TPMA_CC_INITIALIZER(0x0138, 0, 1, 0, 0, 2, 0, 0, 0),
+#endif
+#if (PAD_LIST || CC_DictionaryAttackLockReset)
+ TPMA_CC_INITIALIZER(0x0139, 0, 1, 0, 0, 1, 0, 0, 0),
+#endif
+#if (PAD_LIST || CC_DictionaryAttackParameters)
+ TPMA_CC_INITIALIZER(0x013a, 0, 1, 0, 0, 1, 0, 0, 0),
+#endif
+#if (PAD_LIST || CC_NV_ChangeAuth)
+ TPMA_CC_INITIALIZER(0x013b, 0, 1, 0, 0, 1, 0, 0, 0),
+#endif
+#if (PAD_LIST || CC_PCR_Event)
+ TPMA_CC_INITIALIZER(0x013c, 0, 1, 0, 0, 1, 0, 0, 0),
+#endif
+#if (PAD_LIST || CC_PCR_Reset)
+ TPMA_CC_INITIALIZER(0x013d, 0, 1, 0, 0, 1, 0, 0, 0),
+#endif
+#if (PAD_LIST || CC_SequenceComplete)
+ TPMA_CC_INITIALIZER(0x013e, 0, 0, 0, 1, 1, 0, 0, 0),
+#endif
+#if (PAD_LIST || CC_SetAlgorithmSet)
+ TPMA_CC_INITIALIZER(0x013f, 0, 1, 0, 0, 1, 0, 0, 0),
+#endif
+#if (PAD_LIST || CC_SetCommandCodeAuditStatus)
+ TPMA_CC_INITIALIZER(0x0140, 0, 1, 0, 0, 1, 0, 0, 0),
+#endif
+#if (PAD_LIST || CC_FieldUpgradeData)
+ TPMA_CC_INITIALIZER(0x0141, 0, 1, 0, 0, 0, 0, 0, 0),
+#endif
+#if (PAD_LIST || CC_IncrementalSelfTest)
+ TPMA_CC_INITIALIZER(0x0142, 0, 1, 0, 0, 0, 0, 0, 0),
+#endif
+#if (PAD_LIST || CC_SelfTest)
+ TPMA_CC_INITIALIZER(0x0143, 0, 1, 0, 0, 0, 0, 0, 0),
+#endif
+#if (PAD_LIST || CC_Startup)
+ TPMA_CC_INITIALIZER(0x0144, 0, 1, 0, 0, 0, 0, 0, 0),
+#endif
+#if (PAD_LIST || CC_Shutdown)
+ TPMA_CC_INITIALIZER(0x0145, 0, 1, 0, 0, 0, 0, 0, 0),
+#endif
+#if (PAD_LIST || CC_StirRandom)
+ TPMA_CC_INITIALIZER(0x0146, 0, 1, 0, 0, 0, 0, 0, 0),
+#endif
+#if (PAD_LIST || CC_ActivateCredential)
+ TPMA_CC_INITIALIZER(0x0147, 0, 0, 0, 0, 2, 0, 0, 0),
+#endif
+#if (PAD_LIST || CC_Certify)
+ TPMA_CC_INITIALIZER(0x0148, 0, 0, 0, 0, 2, 0, 0, 0),
+#endif
+#if (PAD_LIST || CC_PolicyNV)
+ TPMA_CC_INITIALIZER(0x0149, 0, 0, 0, 0, 3, 0, 0, 0),
+#endif
+#if (PAD_LIST || CC_CertifyCreation)
+ TPMA_CC_INITIALIZER(0x014a, 0, 0, 0, 0, 2, 0, 0, 0),
+#endif
+#if (PAD_LIST || CC_Duplicate)
+ TPMA_CC_INITIALIZER(0x014b, 0, 0, 0, 0, 2, 0, 0, 0),
+#endif
+#if (PAD_LIST || CC_GetTime)
+ TPMA_CC_INITIALIZER(0x014c, 0, 0, 0, 0, 2, 0, 0, 0),
+#endif
+#if (PAD_LIST || CC_GetSessionAuditDigest)
+ TPMA_CC_INITIALIZER(0x014d, 0, 0, 0, 0, 3, 0, 0, 0),
+#endif
+#if (PAD_LIST || CC_NV_Read)
+ TPMA_CC_INITIALIZER(0x014e, 0, 0, 0, 0, 2, 0, 0, 0),
+#endif
+#if (PAD_LIST || CC_NV_ReadLock)
+ TPMA_CC_INITIALIZER(0x014f, 0, 1, 0, 0, 2, 0, 0, 0),
+#endif
+#if (PAD_LIST || CC_ObjectChangeAuth)
+ TPMA_CC_INITIALIZER(0x0150, 0, 0, 0, 0, 2, 0, 0, 0),
+#endif
+#if (PAD_LIST || CC_PolicySecret)
+ TPMA_CC_INITIALIZER(0x0151, 0, 0, 0, 0, 2, 0, 0, 0),
+#endif
+#if (PAD_LIST || CC_Rewrap)
+ TPMA_CC_INITIALIZER(0x0152, 0, 0, 0, 0, 2, 0, 0, 0),
+#endif
+#if (PAD_LIST || CC_Create)
+ TPMA_CC_INITIALIZER(0x0153, 0, 0, 0, 0, 1, 0, 0, 0),
+#endif
+#if (PAD_LIST || CC_ECDH_ZGen)
+ TPMA_CC_INITIALIZER(0x0154, 0, 0, 0, 0, 1, 0, 0, 0),
+#endif
+#if (PAD_LIST || (CC_HMAC || CC_MAC))
+ TPMA_CC_INITIALIZER(0x0155, 0, 0, 0, 0, 1, 0, 0, 0),
+#endif
+#if (PAD_LIST || CC_Import)
+ TPMA_CC_INITIALIZER(0x0156, 0, 0, 0, 0, 1, 0, 0, 0),
+#endif
+#if (PAD_LIST || CC_Load)
+ TPMA_CC_INITIALIZER(0x0157, 0, 0, 0, 0, 1, 1, 0, 0),
+#endif
+#if (PAD_LIST || CC_Quote)
+ TPMA_CC_INITIALIZER(0x0158, 0, 0, 0, 0, 1, 0, 0, 0),
+#endif
+#if (PAD_LIST || CC_RSA_Decrypt)
+ TPMA_CC_INITIALIZER(0x0159, 0, 0, 0, 0, 1, 0, 0, 0),
+#endif
+#if (PAD_LIST )
+ TPMA_CC_INITIALIZER(0x015a, 0, 0, 0, 0, 0, 0, 0, 0),
+#endif
+#if (PAD_LIST || (CC_HMAC_Start || CC_MAC_Start))
+ TPMA_CC_INITIALIZER(0x015b, 0, 0, 0, 0, 1, 1, 0, 0),
+#endif
+#if (PAD_LIST || CC_SequenceUpdate)
+ TPMA_CC_INITIALIZER(0x015c, 0, 0, 0, 0, 1, 0, 0, 0),
+#endif
+#if (PAD_LIST || CC_Sign)
+ TPMA_CC_INITIALIZER(0x015d, 0, 0, 0, 0, 1, 0, 0, 0),
+#endif
+#if (PAD_LIST || CC_Unseal)
+ TPMA_CC_INITIALIZER(0x015e, 0, 0, 0, 0, 1, 0, 0, 0),
+#endif
+#if (PAD_LIST )
+ TPMA_CC_INITIALIZER(0x015f, 0, 0, 0, 0, 0, 0, 0, 0),
+#endif
+#if (PAD_LIST || CC_PolicySigned)
+ TPMA_CC_INITIALIZER(0x0160, 0, 0, 0, 0, 2, 0, 0, 0),
+#endif
+#if (PAD_LIST || CC_ContextLoad)
+ TPMA_CC_INITIALIZER(0x0161, 0, 0, 0, 0, 0, 1, 0, 0),
+#endif
+#if (PAD_LIST || CC_ContextSave)
+ TPMA_CC_INITIALIZER(0x0162, 0, 0, 0, 0, 1, 0, 0, 0),
+#endif
+#if (PAD_LIST || CC_ECDH_KeyGen)
+ TPMA_CC_INITIALIZER(0x0163, 0, 0, 0, 0, 1, 0, 0, 0),
+#endif
+#if (PAD_LIST || CC_EncryptDecrypt)
+ TPMA_CC_INITIALIZER(0x0164, 0, 0, 0, 0, 1, 0, 0, 0),
+#endif
+#if (PAD_LIST || CC_FlushContext)
+ TPMA_CC_INITIALIZER(0x0165, 0, 0, 0, 0, 0, 0, 0, 0),
+#endif
+#if (PAD_LIST )
+ TPMA_CC_INITIALIZER(0x0166, 0, 0, 0, 0, 0, 0, 0, 0),
+#endif
+#if (PAD_LIST || CC_LoadExternal)
+ TPMA_CC_INITIALIZER(0x0167, 0, 0, 0, 0, 0, 1, 0, 0),
+#endif
+#if (PAD_LIST || CC_MakeCredential)
+ TPMA_CC_INITIALIZER(0x0168, 0, 0, 0, 0, 1, 0, 0, 0),
+#endif
+#if (PAD_LIST || CC_NV_ReadPublic)
+ TPMA_CC_INITIALIZER(0x0169, 0, 0, 0, 0, 1, 0, 0, 0),
+#endif
+#if (PAD_LIST || CC_PolicyAuthorize)
+ TPMA_CC_INITIALIZER(0x016a, 0, 0, 0, 0, 1, 0, 0, 0),
+#endif
+#if (PAD_LIST || CC_PolicyAuthValue)
+ TPMA_CC_INITIALIZER(0x016b, 0, 0, 0, 0, 1, 0, 0, 0),
+#endif
+#if (PAD_LIST || CC_PolicyCommandCode)
+ TPMA_CC_INITIALIZER(0x016c, 0, 0, 0, 0, 1, 0, 0, 0),
+#endif
+#if (PAD_LIST || CC_PolicyCounterTimer)
+ TPMA_CC_INITIALIZER(0x016d, 0, 0, 0, 0, 1, 0, 0, 0),
+#endif
+#if (PAD_LIST || CC_PolicyCpHash)
+ TPMA_CC_INITIALIZER(0x016e, 0, 0, 0, 0, 1, 0, 0, 0),
+#endif
+#if (PAD_LIST || CC_PolicyLocality)
+ TPMA_CC_INITIALIZER(0x016f, 0, 0, 0, 0, 1, 0, 0, 0),
+#endif
+#if (PAD_LIST || CC_PolicyNameHash)
+ TPMA_CC_INITIALIZER(0x0170, 0, 0, 0, 0, 1, 0, 0, 0),
+#endif
+#if (PAD_LIST || CC_PolicyOR)
+ TPMA_CC_INITIALIZER(0x0171, 0, 0, 0, 0, 1, 0, 0, 0),
+#endif
+#if (PAD_LIST || CC_PolicyTicket)
+ TPMA_CC_INITIALIZER(0x0172, 0, 0, 0, 0, 1, 0, 0, 0),
+#endif
+#if (PAD_LIST || CC_ReadPublic)
+ TPMA_CC_INITIALIZER(0x0173, 0, 0, 0, 0, 1, 0, 0, 0),
+#endif
+#if (PAD_LIST || CC_RSA_Encrypt)
+ TPMA_CC_INITIALIZER(0x0174, 0, 0, 0, 0, 1, 0, 0, 0),
+#endif
+#if (PAD_LIST )
+ TPMA_CC_INITIALIZER(0x0175, 0, 0, 0, 0, 0, 0, 0, 0),
+#endif
+#if (PAD_LIST || CC_StartAuthSession)
+ TPMA_CC_INITIALIZER(0x0176, 0, 0, 0, 0, 2, 1, 0, 0),
+#endif
+#if (PAD_LIST || CC_VerifySignature)
+ TPMA_CC_INITIALIZER(0x0177, 0, 0, 0, 0, 1, 0, 0, 0),
+#endif
+#if (PAD_LIST || CC_ECC_Parameters)
+ TPMA_CC_INITIALIZER(0x0178, 0, 0, 0, 0, 0, 0, 0, 0),
+#endif
+#if (PAD_LIST || CC_FirmwareRead)
+ TPMA_CC_INITIALIZER(0x0179, 0, 0, 0, 0, 0, 0, 0, 0),
+#endif
+#if (PAD_LIST || CC_GetCapability)
+ TPMA_CC_INITIALIZER(0x017a, 0, 0, 0, 0, 0, 0, 0, 0),
+#endif
+#if (PAD_LIST || CC_GetRandom)
+ TPMA_CC_INITIALIZER(0x017b, 0, 0, 0, 0, 0, 0, 0, 0),
+#endif
+#if (PAD_LIST || CC_GetTestResult)
+ TPMA_CC_INITIALIZER(0x017c, 0, 0, 0, 0, 0, 0, 0, 0),
+#endif
+#if (PAD_LIST || CC_Hash)
+ TPMA_CC_INITIALIZER(0x017d, 0, 0, 0, 0, 0, 0, 0, 0),
+#endif
+#if (PAD_LIST || CC_PCR_Read)
+ TPMA_CC_INITIALIZER(0x017e, 0, 0, 0, 0, 0, 0, 0, 0),
+#endif
+#if (PAD_LIST || CC_PolicyPCR)
+ TPMA_CC_INITIALIZER(0x017f, 0, 0, 0, 0, 1, 0, 0, 0),
+#endif
+#if (PAD_LIST || CC_PolicyRestart)
+ TPMA_CC_INITIALIZER(0x0180, 0, 0, 0, 0, 1, 0, 0, 0),
+#endif
+#if (PAD_LIST || CC_ReadClock)
+ TPMA_CC_INITIALIZER(0x0181, 0, 0, 0, 0, 0, 0, 0, 0),
+#endif
+#if (PAD_LIST || CC_PCR_Extend)
+ TPMA_CC_INITIALIZER(0x0182, 0, 1, 0, 0, 1, 0, 0, 0),
+#endif
+#if (PAD_LIST || CC_PCR_SetAuthValue)
+ TPMA_CC_INITIALIZER(0x0183, 0, 0, 0, 0, 1, 0, 0, 0),
+#endif
+#if (PAD_LIST || CC_NV_Certify)
+ TPMA_CC_INITIALIZER(0x0184, 0, 0, 0, 0, 3, 0, 0, 0),
+#endif
+#if (PAD_LIST || CC_EventSequenceComplete)
+ TPMA_CC_INITIALIZER(0x0185, 0, 1, 0, 1, 2, 0, 0, 0),
+#endif
+#if (PAD_LIST || CC_HashSequenceStart)
+ TPMA_CC_INITIALIZER(0x0186, 0, 0, 0, 0, 0, 1, 0, 0),
+#endif
+#if (PAD_LIST || CC_PolicyPhysicalPresence)
+ TPMA_CC_INITIALIZER(0x0187, 0, 0, 0, 0, 1, 0, 0, 0),
+#endif
+#if (PAD_LIST || CC_PolicyDuplicationSelect)
+ TPMA_CC_INITIALIZER(0x0188, 0, 0, 0, 0, 1, 0, 0, 0),
+#endif
+#if (PAD_LIST || CC_PolicyGetDigest)
+ TPMA_CC_INITIALIZER(0x0189, 0, 0, 0, 0, 1, 0, 0, 0),
+#endif
+#if (PAD_LIST || CC_TestParms)
+ TPMA_CC_INITIALIZER(0x018a, 0, 0, 0, 0, 0, 0, 0, 0),
+#endif
+#if (PAD_LIST || CC_Commit)
+ TPMA_CC_INITIALIZER(0x018b, 0, 0, 0, 0, 1, 0, 0, 0),
+#endif
+#if (PAD_LIST || CC_PolicyPassword)
+ TPMA_CC_INITIALIZER(0x018c, 0, 0, 0, 0, 1, 0, 0, 0),
+#endif
+#if (PAD_LIST || CC_ZGen_2Phase)
+ TPMA_CC_INITIALIZER(0x018d, 0, 0, 0, 0, 1, 0, 0, 0),
+#endif
+#if (PAD_LIST || CC_EC_Ephemeral)
+ TPMA_CC_INITIALIZER(0x018e, 0, 0, 0, 0, 0, 0, 0, 0),
+#endif
+#if (PAD_LIST || CC_PolicyNvWritten)
+ TPMA_CC_INITIALIZER(0x018f, 0, 0, 0, 0, 1, 0, 0, 0),
+#endif
+#if (PAD_LIST || CC_PolicyTemplate)
+ TPMA_CC_INITIALIZER(0x0190, 0, 0, 0, 0, 1, 0, 0, 0),
+#endif
+#if (PAD_LIST || CC_CreateLoaded)
+ TPMA_CC_INITIALIZER(0x0191, 0, 0, 0, 0, 1, 1, 0, 0),
+#endif
+#if (PAD_LIST || CC_PolicyAuthorizeNV)
+ TPMA_CC_INITIALIZER(0x0192, 0, 0, 0, 0, 3, 0, 0, 0),
+#endif
+#if (PAD_LIST || CC_EncryptDecrypt2)
+ TPMA_CC_INITIALIZER(0x0193, 0, 0, 0, 0, 1, 0, 0, 0),
+#endif
+#if (PAD_LIST || CC_AC_GetCapability)
+ TPMA_CC_INITIALIZER(0x0194, 0, 0, 0, 0, 1, 0, 0, 0),
+#endif
+#if (PAD_LIST || CC_AC_Send)
+ TPMA_CC_INITIALIZER(0x0195, 0, 0, 0, 0, 3, 0, 0, 0),
+#endif
+#if (PAD_LIST || CC_Policy_AC_SendSelect)
+ TPMA_CC_INITIALIZER(0x0196, 0, 0, 0, 0, 1, 0, 0, 0),
+#endif
+#if (PAD_LIST || CC_CertifyX509)
+ TPMA_CC_INITIALIZER(0x0197, 0, 0, 0, 0, 2, 0, 0, 0),
+#endif
+#if (PAD_LIST || CC_ACT_SetTimeout)
+ TPMA_CC_INITIALIZER(0x0198, 0, 0, 0, 0, 1, 0, 0, 0),
+#endif
+#if (PAD_LIST || CC_ECC_Encrypt)
+ TPMA_CC_INITIALIZER(0x0199, 0, 0, 0, 0, 1, 0, 0, 0),
+#endif
+#if (PAD_LIST || CC_ECC_Decrypt)
+ TPMA_CC_INITIALIZER(0x019A, 0, 0, 0, 0, 1, 0, 0, 0),
+#endif
+#if (PAD_LIST || CC_Vendor_TCG_Test)
+ TPMA_CC_INITIALIZER(0x0000, 0, 0, 0, 0, 0, 0, 1, 0),
+#endif
+
+ TPMA_ZERO_INITIALIZER()
+};
+
+/* This is the command code attribute structure. */
+
+const COMMAND_ATTRIBUTES s_commandAttributes [] = {
+#if (PAD_LIST || CC_NV_UndefineSpaceSpecial)
+ (COMMAND_ATTRIBUTES)(CC_NV_UndefineSpaceSpecial * // 0x011f
+ (IS_IMPLEMENTED+HANDLE_1_ADMIN+HANDLE_2_USER+PP_COMMAND)),
+#endif
+#if (PAD_LIST || CC_EvictControl)
+ (COMMAND_ATTRIBUTES)(CC_EvictControl * // 0x0120
+ (IS_IMPLEMENTED+HANDLE_1_USER+PP_COMMAND)),
+#endif
+#if (PAD_LIST || CC_HierarchyControl)
+ (COMMAND_ATTRIBUTES)(CC_HierarchyControl * // 0x0121
+ (IS_IMPLEMENTED+HANDLE_1_USER+PP_COMMAND)),
+#endif
+#if (PAD_LIST || CC_NV_UndefineSpace)
+ (COMMAND_ATTRIBUTES)(CC_NV_UndefineSpace * // 0x0122
+ (IS_IMPLEMENTED+HANDLE_1_USER+PP_COMMAND)),
+#endif
+#if (PAD_LIST )
+ (COMMAND_ATTRIBUTES)(0), // 0x0123
+#endif
+#if (PAD_LIST || CC_ChangeEPS)
+ (COMMAND_ATTRIBUTES)(CC_ChangeEPS * // 0x0124
+ (IS_IMPLEMENTED+HANDLE_1_USER+PP_COMMAND)),
+#endif
+#if (PAD_LIST || CC_ChangePPS)
+ (COMMAND_ATTRIBUTES)(CC_ChangePPS * // 0x0125
+ (IS_IMPLEMENTED+HANDLE_1_USER+PP_COMMAND)),
+#endif
+#if (PAD_LIST || CC_Clear)
+ (COMMAND_ATTRIBUTES)(CC_Clear * // 0x0126
+ (IS_IMPLEMENTED+HANDLE_1_USER+PP_COMMAND)),
+#endif
+#if (PAD_LIST || CC_ClearControl)
+ (COMMAND_ATTRIBUTES)(CC_ClearControl * // 0x0127
+ (IS_IMPLEMENTED+HANDLE_1_USER+PP_COMMAND)),
+#endif
+#if (PAD_LIST || CC_ClockSet)
+ (COMMAND_ATTRIBUTES)(CC_ClockSet * // 0x0128
+ (IS_IMPLEMENTED+HANDLE_1_USER+PP_COMMAND)),
+#endif
+#if (PAD_LIST || CC_HierarchyChangeAuth)
+ (COMMAND_ATTRIBUTES)(CC_HierarchyChangeAuth * // 0x0129
+ (IS_IMPLEMENTED+DECRYPT_2+HANDLE_1_USER+PP_COMMAND)),
+#endif
+#if (PAD_LIST || CC_NV_DefineSpace)
+ (COMMAND_ATTRIBUTES)(CC_NV_DefineSpace * // 0x012a
+ (IS_IMPLEMENTED+DECRYPT_2+HANDLE_1_USER+PP_COMMAND)),
+#endif
+#if (PAD_LIST || CC_PCR_Allocate)
+ (COMMAND_ATTRIBUTES)(CC_PCR_Allocate * // 0x012b
+ (IS_IMPLEMENTED+HANDLE_1_USER+PP_COMMAND)),
+#endif
+#if (PAD_LIST || CC_PCR_SetAuthPolicy)
+ (COMMAND_ATTRIBUTES)(CC_PCR_SetAuthPolicy * // 0x012c
+ (IS_IMPLEMENTED+DECRYPT_2+HANDLE_1_USER+PP_COMMAND)),
+#endif
+#if (PAD_LIST || CC_PP_Commands)
+ (COMMAND_ATTRIBUTES)(CC_PP_Commands * // 0x012d
+ (IS_IMPLEMENTED+HANDLE_1_USER+PP_REQUIRED)),
+#endif
+#if (PAD_LIST || CC_SetPrimaryPolicy)
+ (COMMAND_ATTRIBUTES)(CC_SetPrimaryPolicy * // 0x012e
+ (IS_IMPLEMENTED+DECRYPT_2+HANDLE_1_USER+PP_COMMAND)),
+#endif
+#if (PAD_LIST || CC_FieldUpgradeStart)
+ (COMMAND_ATTRIBUTES)(CC_FieldUpgradeStart * // 0x012f
+ (IS_IMPLEMENTED+DECRYPT_2+HANDLE_1_ADMIN+PP_COMMAND)),
+#endif
+#if (PAD_LIST || CC_ClockRateAdjust)
+ (COMMAND_ATTRIBUTES)(CC_ClockRateAdjust * // 0x0130
+ (IS_IMPLEMENTED+HANDLE_1_USER+PP_COMMAND)),
+#endif
+#if (PAD_LIST || CC_CreatePrimary)
+ (COMMAND_ATTRIBUTES)(CC_CreatePrimary * // 0x0131
+ (IS_IMPLEMENTED+DECRYPT_2+HANDLE_1_USER+PP_COMMAND+ENCRYPT_2+R_HANDLE)),
+#endif
+#if (PAD_LIST || CC_NV_GlobalWriteLock)
+ (COMMAND_ATTRIBUTES)(CC_NV_GlobalWriteLock * // 0x0132
+ (IS_IMPLEMENTED+HANDLE_1_USER+PP_COMMAND)),
+#endif
+#if (PAD_LIST || CC_GetCommandAuditDigest)
+ (COMMAND_ATTRIBUTES)(CC_GetCommandAuditDigest * // 0x0133
+ (IS_IMPLEMENTED+DECRYPT_2+HANDLE_1_USER+HANDLE_2_USER+ENCRYPT_2)),
+#endif
+#if (PAD_LIST || CC_NV_Increment)
+ (COMMAND_ATTRIBUTES)(CC_NV_Increment * // 0x0134
+ (IS_IMPLEMENTED+HANDLE_1_USER)),
+#endif
+#if (PAD_LIST || CC_NV_SetBits)
+ (COMMAND_ATTRIBUTES)(CC_NV_SetBits * // 0x0135
+ (IS_IMPLEMENTED+HANDLE_1_USER)),
+#endif
+#if (PAD_LIST || CC_NV_Extend)
+ (COMMAND_ATTRIBUTES)(CC_NV_Extend * // 0x0136
+ (IS_IMPLEMENTED+DECRYPT_2+HANDLE_1_USER)),
+#endif
+#if (PAD_LIST || CC_NV_Write)
+ (COMMAND_ATTRIBUTES)(CC_NV_Write * // 0x0137
+ (IS_IMPLEMENTED+DECRYPT_2+HANDLE_1_USER)),
+#endif
+#if (PAD_LIST || CC_NV_WriteLock)
+ (COMMAND_ATTRIBUTES)(CC_NV_WriteLock * // 0x0138
+ (IS_IMPLEMENTED+HANDLE_1_USER)),
+#endif
+#if (PAD_LIST || CC_DictionaryAttackLockReset)
+ (COMMAND_ATTRIBUTES)(CC_DictionaryAttackLockReset * // 0x0139
+ (IS_IMPLEMENTED+HANDLE_1_USER)),
+#endif
+#if (PAD_LIST || CC_DictionaryAttackParameters)
+ (COMMAND_ATTRIBUTES)(CC_DictionaryAttackParameters * // 0x013a
+ (IS_IMPLEMENTED+HANDLE_1_USER)),
+#endif
+#if (PAD_LIST || CC_NV_ChangeAuth)
+ (COMMAND_ATTRIBUTES)(CC_NV_ChangeAuth * // 0x013b
+ (IS_IMPLEMENTED+DECRYPT_2+HANDLE_1_ADMIN)),
+#endif
+#if (PAD_LIST || CC_PCR_Event)
+ (COMMAND_ATTRIBUTES)(CC_PCR_Event * // 0x013c
+ (IS_IMPLEMENTED+DECRYPT_2+HANDLE_1_USER)),
+#endif
+#if (PAD_LIST || CC_PCR_Reset)
+ (COMMAND_ATTRIBUTES)(CC_PCR_Reset * // 0x013d
+ (IS_IMPLEMENTED+HANDLE_1_USER)),
+#endif
+#if (PAD_LIST || CC_SequenceComplete)
+ (COMMAND_ATTRIBUTES)(CC_SequenceComplete * // 0x013e
+ (IS_IMPLEMENTED+DECRYPT_2+HANDLE_1_USER+ENCRYPT_2)),
+#endif
+#if (PAD_LIST || CC_SetAlgorithmSet)
+ (COMMAND_ATTRIBUTES)(CC_SetAlgorithmSet * // 0x013f
+ (IS_IMPLEMENTED+HANDLE_1_USER)),
+#endif
+#if (PAD_LIST || CC_SetCommandCodeAuditStatus)
+ (COMMAND_ATTRIBUTES)(CC_SetCommandCodeAuditStatus * // 0x0140
+ (IS_IMPLEMENTED+HANDLE_1_USER+PP_COMMAND)),
+#endif
+#if (PAD_LIST || CC_FieldUpgradeData)
+ (COMMAND_ATTRIBUTES)(CC_FieldUpgradeData * // 0x0141
+ (IS_IMPLEMENTED+DECRYPT_2)),
+#endif
+#if (PAD_LIST || CC_IncrementalSelfTest)
+ (COMMAND_ATTRIBUTES)(CC_IncrementalSelfTest * // 0x0142
+ (IS_IMPLEMENTED)),
+#endif
+#if (PAD_LIST || CC_SelfTest)
+ (COMMAND_ATTRIBUTES)(CC_SelfTest * // 0x0143
+ (IS_IMPLEMENTED)),
+#endif
+#if (PAD_LIST || CC_Startup)
+ (COMMAND_ATTRIBUTES)(CC_Startup * // 0x0144
+ (IS_IMPLEMENTED+NO_SESSIONS)),
+#endif
+#if (PAD_LIST || CC_Shutdown)
+ (COMMAND_ATTRIBUTES)(CC_Shutdown * // 0x0145
+ (IS_IMPLEMENTED)),
+#endif
+#if (PAD_LIST || CC_StirRandom)
+ (COMMAND_ATTRIBUTES)(CC_StirRandom * // 0x0146
+ (IS_IMPLEMENTED+DECRYPT_2)),
+#endif
+#if (PAD_LIST || CC_ActivateCredential)
+ (COMMAND_ATTRIBUTES)(CC_ActivateCredential * // 0x0147
+ (IS_IMPLEMENTED+DECRYPT_2+HANDLE_1_ADMIN+HANDLE_2_USER+ENCRYPT_2)),
+#endif
+#if (PAD_LIST || CC_Certify)
+ (COMMAND_ATTRIBUTES)(CC_Certify * // 0x0148
+ (IS_IMPLEMENTED+DECRYPT_2+HANDLE_1_ADMIN+HANDLE_2_USER+ENCRYPT_2)),
+#endif
+#if (PAD_LIST || CC_PolicyNV)
+ (COMMAND_ATTRIBUTES)(CC_PolicyNV * // 0x0149
+ (IS_IMPLEMENTED+DECRYPT_2+HANDLE_1_USER+ALLOW_TRIAL)),
+#endif
+#if (PAD_LIST || CC_CertifyCreation)
+ (COMMAND_ATTRIBUTES)(CC_CertifyCreation * // 0x014a
+ (IS_IMPLEMENTED+DECRYPT_2+HANDLE_1_USER+ENCRYPT_2)),
+#endif
+#if (PAD_LIST || CC_Duplicate)
+ (COMMAND_ATTRIBUTES)(CC_Duplicate * // 0x014b
+ (IS_IMPLEMENTED+DECRYPT_2+HANDLE_1_DUP+ENCRYPT_2)),
+#endif
+#if (PAD_LIST || CC_GetTime)
+ (COMMAND_ATTRIBUTES)(CC_GetTime * // 0x014c
+ (IS_IMPLEMENTED+DECRYPT_2+HANDLE_1_USER+HANDLE_2_USER+ENCRYPT_2)),
+#endif
+#if (PAD_LIST || CC_GetSessionAuditDigest)
+ (COMMAND_ATTRIBUTES)(CC_GetSessionAuditDigest * // 0x014d
+ (IS_IMPLEMENTED+DECRYPT_2+HANDLE_1_USER+HANDLE_2_USER+ENCRYPT_2)),
+#endif
+#if (PAD_LIST || CC_NV_Read)
+ (COMMAND_ATTRIBUTES)(CC_NV_Read * // 0x014e
+ (IS_IMPLEMENTED+HANDLE_1_USER+ENCRYPT_2)),
+#endif
+#if (PAD_LIST || CC_NV_ReadLock)
+ (COMMAND_ATTRIBUTES)(CC_NV_ReadLock * // 0x014f
+ (IS_IMPLEMENTED+HANDLE_1_USER)),
+#endif
+#if (PAD_LIST || CC_ObjectChangeAuth)
+ (COMMAND_ATTRIBUTES)(CC_ObjectChangeAuth * // 0x0150
+ (IS_IMPLEMENTED+DECRYPT_2+HANDLE_1_ADMIN+ENCRYPT_2)),
+#endif
+#if (PAD_LIST || CC_PolicySecret)
+ (COMMAND_ATTRIBUTES)(CC_PolicySecret * // 0x0151
+ (IS_IMPLEMENTED+DECRYPT_2+HANDLE_1_USER+ALLOW_TRIAL+ENCRYPT_2)),
+#endif
+#if (PAD_LIST || CC_Rewrap)
+ (COMMAND_ATTRIBUTES)(CC_Rewrap * // 0x0152
+ (IS_IMPLEMENTED+DECRYPT_2+HANDLE_1_USER+ENCRYPT_2)),
+#endif
+#if (PAD_LIST || CC_Create)
+ (COMMAND_ATTRIBUTES)(CC_Create * // 0x0153
+ (IS_IMPLEMENTED+DECRYPT_2+HANDLE_1_USER+ENCRYPT_2)),
+#endif
+#if (PAD_LIST || CC_ECDH_ZGen)
+ (COMMAND_ATTRIBUTES)(CC_ECDH_ZGen * // 0x0154
+ (IS_IMPLEMENTED+DECRYPT_2+HANDLE_1_USER+ENCRYPT_2)),
+#endif
+#if (PAD_LIST || (CC_HMAC || CC_MAC))
+ (COMMAND_ATTRIBUTES)((CC_HMAC || CC_MAC) * // 0x0155
+ (IS_IMPLEMENTED+DECRYPT_2+HANDLE_1_USER+ENCRYPT_2)),
+#endif
+#if (PAD_LIST || CC_Import)
+ (COMMAND_ATTRIBUTES)(CC_Import * // 0x0156
+ (IS_IMPLEMENTED+DECRYPT_2+HANDLE_1_USER+ENCRYPT_2)),
+#endif
+#if (PAD_LIST || CC_Load)
+ (COMMAND_ATTRIBUTES)(CC_Load * // 0x0157
+ (IS_IMPLEMENTED+DECRYPT_2+HANDLE_1_USER+ENCRYPT_2+R_HANDLE)),
+#endif
+#if (PAD_LIST || CC_Quote)
+ (COMMAND_ATTRIBUTES)(CC_Quote * // 0x0158
+ (IS_IMPLEMENTED+DECRYPT_2+HANDLE_1_USER+ENCRYPT_2)),
+#endif
+#if (PAD_LIST || CC_RSA_Decrypt)
+ (COMMAND_ATTRIBUTES)(CC_RSA_Decrypt * // 0x0159
+ (IS_IMPLEMENTED+DECRYPT_2+HANDLE_1_USER+ENCRYPT_2)),
+#endif
+#if (PAD_LIST )
+ (COMMAND_ATTRIBUTES)(0), // 0x015a
+#endif
+#if (PAD_LIST || (CC_HMAC_Start || CC_MAC_Start))
+ (COMMAND_ATTRIBUTES)((CC_HMAC_Start || CC_MAC_Start) * // 0x015b
+ (IS_IMPLEMENTED+DECRYPT_2+HANDLE_1_USER+R_HANDLE)),
+#endif
+#if (PAD_LIST || CC_SequenceUpdate)
+ (COMMAND_ATTRIBUTES)(CC_SequenceUpdate * // 0x015c
+ (IS_IMPLEMENTED+DECRYPT_2+HANDLE_1_USER)),
+#endif
+#if (PAD_LIST || CC_Sign)
+ (COMMAND_ATTRIBUTES)(CC_Sign * // 0x015d
+ (IS_IMPLEMENTED+DECRYPT_2+HANDLE_1_USER)),
+#endif
+#if (PAD_LIST || CC_Unseal)
+ (COMMAND_ATTRIBUTES)(CC_Unseal * // 0x015e
+ (IS_IMPLEMENTED+HANDLE_1_USER+ENCRYPT_2)),
+#endif
+#if (PAD_LIST )
+ (COMMAND_ATTRIBUTES)(0), // 0x015f
+#endif
+#if (PAD_LIST || CC_PolicySigned)
+ (COMMAND_ATTRIBUTES)(CC_PolicySigned * // 0x0160
+ (IS_IMPLEMENTED+DECRYPT_2+ALLOW_TRIAL+ENCRYPT_2)),
+#endif
+#if (PAD_LIST || CC_ContextLoad)
+ (COMMAND_ATTRIBUTES)(CC_ContextLoad * // 0x0161
+ (IS_IMPLEMENTED+NO_SESSIONS+R_HANDLE)),
+#endif
+#if (PAD_LIST || CC_ContextSave)
+ (COMMAND_ATTRIBUTES)(CC_ContextSave * // 0x0162
+ (IS_IMPLEMENTED+NO_SESSIONS)),
+#endif
+#if (PAD_LIST || CC_ECDH_KeyGen)
+ (COMMAND_ATTRIBUTES)(CC_ECDH_KeyGen * // 0x0163
+ (IS_IMPLEMENTED+ENCRYPT_2)),
+#endif
+#if (PAD_LIST || CC_EncryptDecrypt)
+ (COMMAND_ATTRIBUTES)(CC_EncryptDecrypt * // 0x0164
+ (IS_IMPLEMENTED+HANDLE_1_USER+ENCRYPT_2)),
+#endif
+#if (PAD_LIST || CC_FlushContext)
+ (COMMAND_ATTRIBUTES)(CC_FlushContext * // 0x0165
+ (IS_IMPLEMENTED+NO_SESSIONS)),
+#endif
+#if (PAD_LIST )
+ (COMMAND_ATTRIBUTES)(0), // 0x0166
+#endif
+#if (PAD_LIST || CC_LoadExternal)
+ (COMMAND_ATTRIBUTES)(CC_LoadExternal * // 0x0167
+ (IS_IMPLEMENTED+DECRYPT_2+ENCRYPT_2+R_HANDLE)),
+#endif
+#if (PAD_LIST || CC_MakeCredential)
+ (COMMAND_ATTRIBUTES)(CC_MakeCredential * // 0x0168
+ (IS_IMPLEMENTED+DECRYPT_2+ENCRYPT_2)),
+#endif
+#if (PAD_LIST || CC_NV_ReadPublic)
+ (COMMAND_ATTRIBUTES)(CC_NV_ReadPublic * // 0x0169
+ (IS_IMPLEMENTED+ENCRYPT_2)),
+#endif
+#if (PAD_LIST || CC_PolicyAuthorize)
+ (COMMAND_ATTRIBUTES)(CC_PolicyAuthorize * // 0x016a
+ (IS_IMPLEMENTED+DECRYPT_2+ALLOW_TRIAL)),
+#endif
+#if (PAD_LIST || CC_PolicyAuthValue)
+ (COMMAND_ATTRIBUTES)(CC_PolicyAuthValue * // 0x016b
+ (IS_IMPLEMENTED+ALLOW_TRIAL)),
+#endif
+#if (PAD_LIST || CC_PolicyCommandCode)
+ (COMMAND_ATTRIBUTES)(CC_PolicyCommandCode * // 0x016c
+ (IS_IMPLEMENTED+ALLOW_TRIAL)),
+#endif
+#if (PAD_LIST || CC_PolicyCounterTimer)
+ (COMMAND_ATTRIBUTES)(CC_PolicyCounterTimer * // 0x016d
+ (IS_IMPLEMENTED+DECRYPT_2+ALLOW_TRIAL)),
+#endif
+#if (PAD_LIST || CC_PolicyCpHash)
+ (COMMAND_ATTRIBUTES)(CC_PolicyCpHash * // 0x016e
+ (IS_IMPLEMENTED+DECRYPT_2+ALLOW_TRIAL)),
+#endif
+#if (PAD_LIST || CC_PolicyLocality)
+ (COMMAND_ATTRIBUTES)(CC_PolicyLocality * // 0x016f
+ (IS_IMPLEMENTED+ALLOW_TRIAL)),
+#endif
+#if (PAD_LIST || CC_PolicyNameHash)
+ (COMMAND_ATTRIBUTES)(CC_PolicyNameHash * // 0x0170
+ (IS_IMPLEMENTED+DECRYPT_2+ALLOW_TRIAL)),
+#endif
+#if (PAD_LIST || CC_PolicyOR)
+ (COMMAND_ATTRIBUTES)(CC_PolicyOR * // 0x0171
+ (IS_IMPLEMENTED+ALLOW_TRIAL)),
+#endif
+#if (PAD_LIST || CC_PolicyTicket)
+ (COMMAND_ATTRIBUTES)(CC_PolicyTicket * // 0x0172
+ (IS_IMPLEMENTED+DECRYPT_2+ALLOW_TRIAL)),
+#endif
+#if (PAD_LIST || CC_ReadPublic)
+ (COMMAND_ATTRIBUTES)(CC_ReadPublic * // 0x0173
+ (IS_IMPLEMENTED+ENCRYPT_2)),
+#endif
+#if (PAD_LIST || CC_RSA_Encrypt)
+ (COMMAND_ATTRIBUTES)(CC_RSA_Encrypt * // 0x0174
+ (IS_IMPLEMENTED+DECRYPT_2+ENCRYPT_2)),
+#endif
+#if (PAD_LIST )
+ (COMMAND_ATTRIBUTES)(0), // 0x0175
+#endif
+#if (PAD_LIST || CC_StartAuthSession)
+ (COMMAND_ATTRIBUTES)(CC_StartAuthSession * // 0x0176
+ (IS_IMPLEMENTED+DECRYPT_2+ENCRYPT_2+R_HANDLE)),
+#endif
+#if (PAD_LIST || CC_VerifySignature)
+ (COMMAND_ATTRIBUTES)(CC_VerifySignature * // 0x0177
+ (IS_IMPLEMENTED+DECRYPT_2)),
+#endif
+#if (PAD_LIST || CC_ECC_Parameters)
+ (COMMAND_ATTRIBUTES)(CC_ECC_Parameters * // 0x0178
+ (IS_IMPLEMENTED)),
+#endif
+#if (PAD_LIST || CC_FirmwareRead)
+ (COMMAND_ATTRIBUTES)(CC_FirmwareRead * // 0x0179
+ (IS_IMPLEMENTED+ENCRYPT_2)),
+#endif
+#if (PAD_LIST || CC_GetCapability)
+ (COMMAND_ATTRIBUTES)(CC_GetCapability * // 0x017a
+ (IS_IMPLEMENTED)),
+#endif
+#if (PAD_LIST || CC_GetRandom)
+ (COMMAND_ATTRIBUTES)(CC_GetRandom * // 0x017b
+ (IS_IMPLEMENTED+ENCRYPT_2)),
+#endif
+#if (PAD_LIST || CC_GetTestResult)
+ (COMMAND_ATTRIBUTES)(CC_GetTestResult * // 0x017c
+ (IS_IMPLEMENTED+ENCRYPT_2)),
+#endif
+#if (PAD_LIST || CC_Hash)
+ (COMMAND_ATTRIBUTES)(CC_Hash * // 0x017d
+ (IS_IMPLEMENTED+DECRYPT_2+ENCRYPT_2)),
+#endif
+#if (PAD_LIST || CC_PCR_Read)
+ (COMMAND_ATTRIBUTES)(CC_PCR_Read * // 0x017e
+ (IS_IMPLEMENTED)),
+#endif
+#if (PAD_LIST || CC_PolicyPCR)
+ (COMMAND_ATTRIBUTES)(CC_PolicyPCR * // 0x017f
+ (IS_IMPLEMENTED+DECRYPT_2+ALLOW_TRIAL)),
+#endif
+#if (PAD_LIST || CC_PolicyRestart)
+ (COMMAND_ATTRIBUTES)(CC_PolicyRestart * // 0x0180
+ (IS_IMPLEMENTED+ALLOW_TRIAL)),
+#endif
+#if (PAD_LIST || CC_ReadClock)
+ (COMMAND_ATTRIBUTES)(CC_ReadClock * // 0x0181
+ (IS_IMPLEMENTED)),
+#endif
+#if (PAD_LIST || CC_PCR_Extend)
+ (COMMAND_ATTRIBUTES)(CC_PCR_Extend * // 0x0182
+ (IS_IMPLEMENTED+HANDLE_1_USER)),
+#endif
+#if (PAD_LIST || CC_PCR_SetAuthValue)
+ (COMMAND_ATTRIBUTES)(CC_PCR_SetAuthValue * // 0x0183
+ (IS_IMPLEMENTED+DECRYPT_2+HANDLE_1_USER)),
+#endif
+#if (PAD_LIST || CC_NV_Certify)
+ (COMMAND_ATTRIBUTES)(CC_NV_Certify * // 0x0184
+ (IS_IMPLEMENTED+DECRYPT_2+HANDLE_1_USER+HANDLE_2_USER+ENCRYPT_2)),
+#endif
+#if (PAD_LIST || CC_EventSequenceComplete)
+ (COMMAND_ATTRIBUTES)(CC_EventSequenceComplete * // 0x0185
+ (IS_IMPLEMENTED+DECRYPT_2+HANDLE_1_USER+HANDLE_2_USER)),
+#endif
+#if (PAD_LIST || CC_HashSequenceStart)
+ (COMMAND_ATTRIBUTES)(CC_HashSequenceStart * // 0x0186
+ (IS_IMPLEMENTED+DECRYPT_2+R_HANDLE)),
+#endif
+#if (PAD_LIST || CC_PolicyPhysicalPresence)
+ (COMMAND_ATTRIBUTES)(CC_PolicyPhysicalPresence * // 0x0187
+ (IS_IMPLEMENTED+ALLOW_TRIAL)),
+#endif
+#if (PAD_LIST || CC_PolicyDuplicationSelect)
+ (COMMAND_ATTRIBUTES)(CC_PolicyDuplicationSelect * // 0x0188
+ (IS_IMPLEMENTED+DECRYPT_2+ALLOW_TRIAL)),
+#endif
+#if (PAD_LIST || CC_PolicyGetDigest)
+ (COMMAND_ATTRIBUTES)(CC_PolicyGetDigest * // 0x0189
+ (IS_IMPLEMENTED+ALLOW_TRIAL+ENCRYPT_2)),
+#endif
+#if (PAD_LIST || CC_TestParms)
+ (COMMAND_ATTRIBUTES)(CC_TestParms * // 0x018a
+ (IS_IMPLEMENTED)),
+#endif
+#if (PAD_LIST || CC_Commit)
+ (COMMAND_ATTRIBUTES)(CC_Commit * // 0x018b
+ (IS_IMPLEMENTED+DECRYPT_2+HANDLE_1_USER+ENCRYPT_2)),
+#endif
+#if (PAD_LIST || CC_PolicyPassword)
+ (COMMAND_ATTRIBUTES)(CC_PolicyPassword * // 0x018c
+ (IS_IMPLEMENTED+ALLOW_TRIAL)),
+#endif
+#if (PAD_LIST || CC_ZGen_2Phase)
+ (COMMAND_ATTRIBUTES)(CC_ZGen_2Phase * // 0x018d
+ (IS_IMPLEMENTED+DECRYPT_2+HANDLE_1_USER+ENCRYPT_2)),
+#endif
+#if (PAD_LIST || CC_EC_Ephemeral)
+ (COMMAND_ATTRIBUTES)(CC_EC_Ephemeral * // 0x018e
+ (IS_IMPLEMENTED+ENCRYPT_2)),
+#endif
+#if (PAD_LIST || CC_PolicyNvWritten)
+ (COMMAND_ATTRIBUTES)(CC_PolicyNvWritten * // 0x018f
+ (IS_IMPLEMENTED+ALLOW_TRIAL)),
+#endif
+#if (PAD_LIST || CC_PolicyTemplate)
+ (COMMAND_ATTRIBUTES)(CC_PolicyTemplate * // 0x0190
+ (IS_IMPLEMENTED+DECRYPT_2+ALLOW_TRIAL)),
+#endif
+#if (PAD_LIST || CC_CreateLoaded)
+ (COMMAND_ATTRIBUTES)(CC_CreateLoaded * // 0x0191
+ (IS_IMPLEMENTED+DECRYPT_2+HANDLE_1_USER+PP_COMMAND+ENCRYPT_2+R_HANDLE)),
+#endif
+#if (PAD_LIST || CC_PolicyAuthorizeNV)
+ (COMMAND_ATTRIBUTES)(CC_PolicyAuthorizeNV * // 0x0192
+ (IS_IMPLEMENTED+HANDLE_1_USER+ALLOW_TRIAL)),
+#endif
+#if (PAD_LIST || CC_EncryptDecrypt2)
+ (COMMAND_ATTRIBUTES)(CC_EncryptDecrypt2 * // 0x0193
+ (IS_IMPLEMENTED+DECRYPT_2+HANDLE_1_USER+ENCRYPT_2)),
+#endif
+#if (PAD_LIST || CC_AC_GetCapability)
+ (COMMAND_ATTRIBUTES)(CC_AC_GetCapability * // 0x0194
+ (IS_IMPLEMENTED)),
+#endif
+#if (PAD_LIST || CC_AC_Send)
+ (COMMAND_ATTRIBUTES)(CC_AC_Send * // 0x0195
+ (IS_IMPLEMENTED+DECRYPT_2+HANDLE_1_DUP+HANDLE_2_USER)),
+#endif
+#if (PAD_LIST || CC_Policy_AC_SendSelect)
+ (COMMAND_ATTRIBUTES)(CC_Policy_AC_SendSelect * // 0x0196
+ (IS_IMPLEMENTED+DECRYPT_2+ALLOW_TRIAL)),
+#endif
+#if (PAD_LIST || CC_CertifyX509)
+ (COMMAND_ATTRIBUTES)(CC_CertifyX509 * // 0x0197
+ (IS_IMPLEMENTED+DECRYPT_2+HANDLE_1_ADMIN+HANDLE_2_USER+ENCRYPT_2)),
+#endif
+#if (PAD_LIST || CC_ACT_SetTimeout)
+ (COMMAND_ATTRIBUTES)(CC_ACT_SetTimeout * // 0x0198
+ (IS_IMPLEMENTED+HANDLE_1_USER)),
+#endif
+#if (PAD_LIST || CC_ECC_Encrypt)
+ (COMMAND_ATTRIBUTES)(CC_ECC_Encrypt * // 0x0199
+ (IS_IMPLEMENTED+DECRYPT_2+ENCRYPT_2)),
+#endif
+#if (PAD_LIST || CC_ECC_Decrypt)
+ (COMMAND_ATTRIBUTES)(CC_ECC_Decrypt * // 0x019A
+ (IS_IMPLEMENTED+DECRYPT_2+HANDLE_1_USER+ENCRYPT_2)),
+#endif
+#if (PAD_LIST || CC_Vendor_TCG_Test)
+ (COMMAND_ATTRIBUTES)(CC_Vendor_TCG_Test * // 0x0000
+ (IS_IMPLEMENTED+DECRYPT_2+ENCRYPT_2)),
+#endif
+
+ 0
+};
+
+#endif // _COMMAND_CODE_ATTRIBUTES_
diff --git a/src/tpm2/CommandAttributes.h b/src/tpm2/CommandAttributes.h
new file mode 100644
index 0000000..d7b6d67
--- /dev/null
+++ b/src/tpm2/CommandAttributes.h
@@ -0,0 +1,88 @@
+/********************************************************************************/
+/* */
+/* Command Attributes */
+/* Written by Ken Goldman */
+/* IBM Thomas J. Watson Research Center */
+/* $Id: CommandAttributes.h 1594 2020-03-26 22:15:48Z kgoldman $ */
+/* */
+/* Licenses and Notices */
+/* */
+/* 1. Copyright Licenses: */
+/* */
+/* - Trusted Computing Group (TCG) grants to the user of the source code in */
+/* this specification (the "Source Code") a worldwide, irrevocable, */
+/* nonexclusive, royalty free, copyright license to reproduce, create */
+/* derivative works, distribute, display and perform the Source Code and */
+/* derivative works thereof, and to grant others the rights granted herein. */
+/* */
+/* - The TCG grants to the user of the other parts of the specification */
+/* (other than the Source Code) the rights to reproduce, distribute, */
+/* display, and perform the specification solely for the purpose of */
+/* developing products based on such documents. */
+/* */
+/* 2. Source Code Distribution Conditions: */
+/* */
+/* - Redistributions of Source Code must retain the above copyright licenses, */
+/* this list of conditions and the following disclaimers. */
+/* */
+/* - Redistributions in binary form must reproduce the above copyright */
+/* licenses, this list of conditions and the following disclaimers in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* 3. Disclaimers: */
+/* */
+/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
+/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
+/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
+/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
+/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
+/* information on specification licensing rights available through TCG */
+/* membership agreements. */
+/* */
+/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
+/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
+/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
+/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
+/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
+/* */
+/* - Without limitation, TCG and its members and licensors disclaim all */
+/* liability, including liability for infringement of any proprietary */
+/* rights, relating to use of information in this specification and to the */
+/* implementation of this specification, and TCG disclaims all liability for */
+/* cost of procurement of substitute goods or services, lost profits, loss */
+/* of use, loss of data or any incidental, consequential, direct, indirect, */
+/* or special damages, whether under contract, tort, warranty or otherwise, */
+/* arising in any way out of use or reliance upon this specification or any */
+/* information herein. */
+/* */
+/* (c) Copyright IBM Corp. and others, 2016 - 2020 */
+/* */
+/********************************************************************************/
+
+#ifndef COMMANDATTRIBUTES_H
+#define COMMANDATTRIBUTES_H
+
+/* 5.7 CommandAttributes.h */
+/* The attributes defined in this file are produced by the parser that creates the structure
+ definitions from Part 3. The attributes are defined in that parser and should track the
+ attributes being tested in CommandCodeAttributes.c. Generally, when an attribute is added to this
+ list, new code will be needed in CommandCodeAttributes.c to test it. */
+
+typedef UINT16 COMMAND_ATTRIBUTES;
+#define NOT_IMPLEMENTED (COMMAND_ATTRIBUTES)(0)
+#define ENCRYPT_2 ((COMMAND_ATTRIBUTES)1 << 0)
+#define ENCRYPT_4 ((COMMAND_ATTRIBUTES)1 << 1)
+#define DECRYPT_2 ((COMMAND_ATTRIBUTES)1 << 2)
+#define DECRYPT_4 ((COMMAND_ATTRIBUTES)1 << 3)
+#define HANDLE_1_USER ((COMMAND_ATTRIBUTES)1 << 4)
+#define HANDLE_1_ADMIN ((COMMAND_ATTRIBUTES)1 << 5)
+#define HANDLE_1_DUP ((COMMAND_ATTRIBUTES)1 << 6)
+#define HANDLE_2_USER ((COMMAND_ATTRIBUTES)1 << 7)
+#define PP_COMMAND ((COMMAND_ATTRIBUTES)1 << 8)
+#define IS_IMPLEMENTED ((COMMAND_ATTRIBUTES)1 << 9)
+#define NO_SESSIONS ((COMMAND_ATTRIBUTES)1 << 10)
+#define NV_COMMAND ((COMMAND_ATTRIBUTES)1 << 11)
+#define PP_REQUIRED ((COMMAND_ATTRIBUTES)1 << 12)
+#define R_HANDLE ((COMMAND_ATTRIBUTES)1 << 13)
+#define ALLOW_TRIAL ((COMMAND_ATTRIBUTES)1 << 14)
+#endif // COMMAND_ATTRIBUTES_H
diff --git a/src/tpm2/CommandAudit.c b/src/tpm2/CommandAudit.c
new file mode 100644
index 0000000..1358c98
--- /dev/null
+++ b/src/tpm2/CommandAudit.c
@@ -0,0 +1,262 @@
+/********************************************************************************/
+/* */
+/* Functions That Support Command Audit */
+/* Written by Ken Goldman */
+/* IBM Thomas J. Watson Research Center */
+/* $Id: CommandAudit.c 1519 2019-11-15 20:43:51Z kgoldman $ */
+/* */
+/* Licenses and Notices */
+/* */
+/* 1. Copyright Licenses: */
+/* */
+/* - Trusted Computing Group (TCG) grants to the user of the source code in */
+/* this specification (the "Source Code") a worldwide, irrevocable, */
+/* nonexclusive, royalty free, copyright license to reproduce, create */
+/* derivative works, distribute, display and perform the Source Code and */
+/* derivative works thereof, and to grant others the rights granted herein. */
+/* */
+/* - The TCG grants to the user of the other parts of the specification */
+/* (other than the Source Code) the rights to reproduce, distribute, */
+/* display, and perform the specification solely for the purpose of */
+/* developing products based on such documents. */
+/* */
+/* 2. Source Code Distribution Conditions: */
+/* */
+/* - Redistributions of Source Code must retain the above copyright licenses, */
+/* this list of conditions and the following disclaimers. */
+/* */
+/* - Redistributions in binary form must reproduce the above copyright */
+/* licenses, this list of conditions and the following disclaimers in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* 3. Disclaimers: */
+/* */
+/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
+/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
+/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
+/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
+/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
+/* information on specification licensing rights available through TCG */
+/* membership agreements. */
+/* */
+/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
+/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
+/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
+/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
+/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
+/* */
+/* - Without limitation, TCG and its members and licensors disclaim all */
+/* liability, including liability for infringement of any proprietary */
+/* rights, relating to use of information in this specification and to the */
+/* implementation of this specification, and TCG disclaims all liability for */
+/* cost of procurement of substitute goods or services, lost profits, loss */
+/* of use, loss of data or any incidental, consequential, direct, indirect, */
+/* or special damages, whether under contract, tort, warranty or otherwise, */
+/* arising in any way out of use or reliance upon this specification or any */
+/* information herein. */
+/* */
+/* (c) Copyright IBM Corp. and others, 2016 - 2019 */
+/* */
+/********************************************************************************/
+
+/* 8.1 CommandAudit.c */
+/* 8.1.1 Introduction */
+/* This file contains the functions that support command audit. */
+/* 8.1.2 Includes */
+#include "Tpm.h"
+/* 8.1.3 Functions */
+/* 8.1.3.1 CommandAuditPreInstall_Init() */
+/* This function initializes the command audit list. This function simulates the behavior of
+ manufacturing. A function is used instead of a structure definition because this is easier than
+ figuring out the initialization value for a bit array. */
+/* This function would not be implemented outside of a manufacturing or simulation environment. */
+void
+CommandAuditPreInstall_Init(
+ void
+ )
+{
+ // Clear all the audit commands
+ MemorySet(gp.auditCommands, 0x00, sizeof(gp.auditCommands));
+ // TPM_CC_SetCommandCodeAuditStatus always being audited
+ CommandAuditSet(TPM_CC_SetCommandCodeAuditStatus);
+ // Set initial command audit hash algorithm to be context integrity hash
+ // algorithm
+ gp.auditHashAlg = CONTEXT_INTEGRITY_HASH_ALG;
+ // Set up audit counter to be 0
+ gp.auditCounter = 0;
+ // Write command audit persistent data to NV
+ NV_SYNC_PERSISTENT(auditCommands);
+ NV_SYNC_PERSISTENT(auditHashAlg);
+ NV_SYNC_PERSISTENT(auditCounter);
+ return;
+}
+/* 8.1.3.2 CommandAuditStartup() */
+/* This function clears the command audit digest on a TPM Reset. */
+BOOL
+CommandAuditStartup(
+ STARTUP_TYPE type // IN: start up type
+ )
+{
+ if((type != SU_RESTART) && (type != SU_RESUME))
+ {
+ // Reset the digest size to initialize the digest
+ gr.commandAuditDigest.t.size = 0;
+ }
+ return TRUE;
+}
+/* 8.1.3.3 CommandAuditSet() */
+/* This function will SET the audit flag for a command. This function will not SET the audit flag
+ for a command that is not implemented. This ensures that the audit status is not SET when
+ TPM2_GetCapability() is used to read the list of audited commands. */
+/* This function is only used by TPM2_SetCommandCodeAuditStatus(). */
+/* The actions in TPM2_SetCommandCodeAuditStatus() are expected to cause the changes to be saved to
+ NV after it is setting and clearing bits. */
+/* Return Values Meaning */
+/* TRUE the command code audit status was changed */
+/* FALSE the command code audit status was not changed */
+BOOL
+CommandAuditSet(
+ TPM_CC commandCode // IN: command code
+ )
+{
+ COMMAND_INDEX commandIndex = CommandCodeToCommandIndex(commandCode);
+ // Only SET a bit if the corresponding command is implemented
+ if(commandIndex != UNIMPLEMENTED_COMMAND_INDEX)
+ {
+ // Can't audit shutdown
+ if(commandCode != TPM_CC_Shutdown)
+ {
+ if(!TEST_BIT(commandIndex, gp.auditCommands))
+ {
+ // Set bit
+ SET_BIT(commandIndex, gp.auditCommands);
+ return TRUE;
+ }
+ }
+ }
+ // No change
+ return FALSE;
+}
+/* 8.1.3.4 CommandAuditClear() */
+/* This function will CLEAR the audit flag for a command. It will not CLEAR the audit flag for
+ TPM_CC_SetCommandCodeAuditStatus(). */
+/* This function is only used by TPM2_SetCommandCodeAuditStatus(). */
+/* The actions in TPM2_SetCommandCodeAuditStatus() are expected to cause the changes to be saved to
+ NV after it is setting and clearing bits. */
+/* Return Values Meaning */
+/* TRUE the command code audit status was changed */
+/* FALSE the command code audit status was not changed */
+BOOL
+CommandAuditClear(
+ TPM_CC commandCode // IN: command code
+ )
+{
+ COMMAND_INDEX commandIndex = CommandCodeToCommandIndex(commandCode);
+ // Do nothing if the command is not implemented
+ if(commandIndex != UNIMPLEMENTED_COMMAND_INDEX)
+ {
+ // The bit associated with TPM_CC_SetCommandCodeAuditStatus() cannot be
+ // cleared
+ if(commandCode != TPM_CC_SetCommandCodeAuditStatus)
+ {
+ if(TEST_BIT(commandIndex, gp.auditCommands))
+ {
+ // Clear bit
+ CLEAR_BIT(commandIndex, gp.auditCommands);
+ return TRUE;
+ }
+ }
+ }
+ // No change
+ return FALSE;
+}
+/* 8.1.3.5 CommandAuditIsRequired() */
+/* This function indicates if the audit flag is SET for a command. */
+/* Return Values Meaning */
+/* TRUE if command is audited */
+/* FALSE if command is not audited */
+BOOL
+CommandAuditIsRequired(
+ COMMAND_INDEX commandIndex // IN: command index
+ )
+{
+ // Check the bit map. If the bit is SET, command audit is required
+ return(TEST_BIT(commandIndex, gp.auditCommands));
+}
+/* 8.1.3.6 CommandAuditCapGetCCList() */
+/* This function returns a list of commands that have their audit bit SET. */
+/* The list starts at the input commandCode. */
+/* Return Values Meaning */
+/* YES if there are more command code available */
+/* NO all the available command code has been returned */
+TPMI_YES_NO
+CommandAuditCapGetCCList(
+ TPM_CC commandCode, // IN: start command code
+ UINT32 count, // IN: count of returned TPM_CC
+ TPML_CC *commandList // OUT: list of TPM_CC
+ )
+{
+ TPMI_YES_NO more = NO;
+ COMMAND_INDEX commandIndex;
+ // Initialize output handle list
+ commandList->count = 0;
+ // The maximum count of command we may return is MAX_CAP_CC
+ if(count > MAX_CAP_CC) count = MAX_CAP_CC;
+ // Find the implemented command that has a command code that is the same or
+ // higher than the input
+ // Collect audit commands
+ for(commandIndex = GetClosestCommandIndex(commandCode);
+ commandIndex != UNIMPLEMENTED_COMMAND_INDEX;
+ commandIndex = GetNextCommandIndex(commandIndex))
+ {
+ if(CommandAuditIsRequired(commandIndex))
+ {
+ if(commandList->count < count)
+ {
+ // If we have not filled up the return list, add this command
+ // code to its
+ TPM_CC cc = GET_ATTRIBUTE(s_ccAttr[commandIndex],
+ TPMA_CC, commandIndex);
+ if(IS_ATTRIBUTE(s_ccAttr[commandIndex], TPMA_CC, V))
+ cc += (1 << 29);
+ commandList->commandCodes[commandList->count] = cc;
+ commandList->count++;
+ }
+ else
+ {
+ // If the return list is full but we still have command
+ // available, report this and stop iterating
+ more = YES;
+ break;
+ }
+ }
+ }
+ return more;
+}
+/* 8.1.3.7 CommandAuditGetDigest */
+/* This command is used to create a digest of the commands being audited. The commands are processed
+ in ascending numeric order with a list of TPM_CC being added to a hash. This operates as if all
+ the audited command codes were concatenated and then hashed. */
+void
+CommandAuditGetDigest(
+ TPM2B_DIGEST *digest // OUT: command digest
+ )
+{
+ TPM_CC commandCode;
+ COMMAND_INDEX commandIndex;
+ HASH_STATE hashState;
+ // Start hash
+ digest->t.size = CryptHashStart(&hashState, gp.auditHashAlg);
+ // Add command code
+ for(commandIndex = 0; commandIndex < COMMAND_COUNT; commandIndex++)
+ {
+ if(CommandAuditIsRequired(commandIndex))
+ {
+ commandCode = GetCommandCode(commandIndex);
+ CryptDigestUpdateInt(&hashState, sizeof(commandCode), commandCode);
+ }
+ }
+ // Complete hash
+ CryptHashEnd2B(&hashState, &digest->b);
+ return;
+}
diff --git a/src/tpm2/CommandAudit_fp.h b/src/tpm2/CommandAudit_fp.h
new file mode 100644
index 0000000..aa43331
--- /dev/null
+++ b/src/tpm2/CommandAudit_fp.h
@@ -0,0 +1,97 @@
+/********************************************************************************/
+/* */
+/* */
+/* Written by Ken Goldman */
+/* IBM Thomas J. Watson Research Center */
+/* $Id: CommandAudit_fp.h 1490 2019-07-26 21:13:22Z kgoldman $ */
+/* */
+/* Licenses and Notices */
+/* */
+/* 1. Copyright Licenses: */
+/* */
+/* - Trusted Computing Group (TCG) grants to the user of the source code in */
+/* this specification (the "Source Code") a worldwide, irrevocable, */
+/* nonexclusive, royalty free, copyright license to reproduce, create */
+/* derivative works, distribute, display and perform the Source Code and */
+/* derivative works thereof, and to grant others the rights granted herein. */
+/* */
+/* - The TCG grants to the user of the other parts of the specification */
+/* (other than the Source Code) the rights to reproduce, distribute, */
+/* display, and perform the specification solely for the purpose of */
+/* developing products based on such documents. */
+/* */
+/* 2. Source Code Distribution Conditions: */
+/* */
+/* - Redistributions of Source Code must retain the above copyright licenses, */
+/* this list of conditions and the following disclaimers. */
+/* */
+/* - Redistributions in binary form must reproduce the above copyright */
+/* licenses, this list of conditions and the following disclaimers in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* 3. Disclaimers: */
+/* */
+/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
+/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
+/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
+/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
+/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
+/* information on specification licensing rights available through TCG */
+/* membership agreements. */
+/* */
+/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
+/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
+/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
+/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
+/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
+/* */
+/* - Without limitation, TCG and its members and licensors disclaim all */
+/* liability, including liability for infringement of any proprietary */
+/* rights, relating to use of information in this specification and to the */
+/* implementation of this specification, and TCG disclaims all liability for */
+/* cost of procurement of substitute goods or services, lost profits, loss */
+/* of use, loss of data or any incidental, consequential, direct, indirect, */
+/* or special damages, whether under contract, tort, warranty or otherwise, */
+/* arising in any way out of use or reliance upon this specification or any */
+/* information herein. */
+/* */
+/* (c) Copyright IBM Corp. and others, 2016 - 2019 */
+/* */
+/********************************************************************************/
+
+#ifndef COMMANDAUDIT_FP_H
+#define COMMANDAUDIT_FP_H
+
+void
+CommandAuditPreInstall_Init(
+ void
+ );
+BOOL
+CommandAuditStartup(
+ STARTUP_TYPE type // IN: start up type
+ );
+BOOL
+CommandAuditSet(
+ TPM_CC commandCode // IN: command code
+ );
+BOOL
+CommandAuditClear(
+ TPM_CC commandCode // IN: command code
+ );
+BOOL
+CommandAuditIsRequired(
+ COMMAND_INDEX commandIndex // IN: command index
+ );
+TPMI_YES_NO
+CommandAuditCapGetCCList(
+ TPM_CC commandCode, // IN: start command code
+ UINT32 count, // IN: count of returned TPM_CC
+ TPML_CC *commandList // OUT: list of TPM_CC
+ );
+void
+CommandAuditGetDigest(
+ TPM2B_DIGEST *digest // OUT: command digest
+ );
+
+
+#endif
diff --git a/src/tpm2/CommandCodeAttributes.c b/src/tpm2/CommandCodeAttributes.c
new file mode 100644
index 0000000..f6d0f8d
--- /dev/null
+++ b/src/tpm2/CommandCodeAttributes.c
@@ -0,0 +1,559 @@
+/********************************************************************************/
+/* */
+/* Functions for testing various command properties */
+/* Written by Ken Goldman */
+/* IBM Thomas J. Watson Research Center */
+/* $Id: CommandCodeAttributes.c 1594 2020-03-26 22:15:48Z kgoldman $ */
+/* */
+/* Licenses and Notices */
+/* */
+/* 1. Copyright Licenses: */
+/* */
+/* - Trusted Computing Group (TCG) grants to the user of the source code in */
+/* this specification (the "Source Code") a worldwide, irrevocable, */
+/* nonexclusive, royalty free, copyright license to reproduce, create */
+/* derivative works, distribute, display and perform the Source Code and */
+/* derivative works thereof, and to grant others the rights granted herein. */
+/* */
+/* - The TCG grants to the user of the other parts of the specification */
+/* (other than the Source Code) the rights to reproduce, distribute, */
+/* display, and perform the specification solely for the purpose of */
+/* developing products based on such documents. */
+/* */
+/* 2. Source Code Distribution Conditions: */
+/* */
+/* - Redistributions of Source Code must retain the above copyright licenses, */
+/* this list of conditions and the following disclaimers. */
+/* */
+/* - Redistributions in binary form must reproduce the above copyright */
+/* licenses, this list of conditions and the following disclaimers in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* 3. Disclaimers: */
+/* */
+/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
+/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
+/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
+/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
+/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
+/* information on specification licensing rights available through TCG */
+/* membership agreements. */
+/* */
+/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
+/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
+/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
+/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
+/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
+/* */
+/* - Without limitation, TCG and its members and licensors disclaim all */
+/* liability, including liability for infringement of any proprietary */
+/* rights, relating to use of information in this specification and to the */
+/* implementation of this specification, and TCG disclaims all liability for */
+/* cost of procurement of substitute goods or services, lost profits, loss */
+/* of use, loss of data or any incidental, consequential, direct, indirect, */
+/* or special damages, whether under contract, tort, warranty or otherwise, */
+/* arising in any way out of use or reliance upon this specification or any */
+/* information herein. */
+/* */
+/* (c) Copyright IBM Corp. and others, 2016 - 2020 */
+/* */
+/********************************************************************************/
+
+/* 9.3 CommandCodeAttributes.c */
+/* 9.3.1 Introduction */
+/* This file contains the functions for testing various command properties. */
+/* 9.3.2 Includes and Defines */
+#include "Tpm.h"
+#include "CommandCodeAttributes_fp.h"
+/* Set the default value for CC_VEND if not already set */
+#ifndef CC_VEND
+#define CC_VEND (TPM_CC)(0x20000000)
+#endif
+typedef UINT16 ATTRIBUTE_TYPE;
+/* The following file is produced from the command tables in part 3 of the specification. It defines
+ the attributes for each of the commands. */
+/* NOTE: This file is currently produced by an automated process. Files produced from Part 2 or Part
+ 3 tables through automated processes are not included in the specification so that there is no
+ ambiguity about the table containing the information being the normative definition. */
+#define _COMMAND_CODE_ATTRIBUTES_
+#include "CommandAttributeData.h"
+/* 9.3.3 Command Attribute Functions */
+/* 9.3.3.1 NextImplementedIndex() */
+/* This function is used when the lists are not compressed. In a compressed list, only the
+ implemented commands are present. So, a search might find a value but that value may not be
+ implemented. This function checks to see if the input commandIndex points to an implemented
+ command and, if not, it searches upwards until it finds one. When the list is compressed, this
+ function gets defined as a no-op. */
+/* Return Value Meaning */
+/* UNIMPLEMENTED_COMMAND_INDEX command is not implemented */
+/* other index of the command */
+
+#if !COMPRESSED_LISTS
+static COMMAND_INDEX
+NextImplementedIndex(
+ COMMAND_INDEX commandIndex
+ )
+{
+ for(;commandIndex < COMMAND_COUNT; commandIndex++)
+ {
+ if(s_commandAttributes[commandIndex] & IS_IMPLEMENTED)
+ return commandIndex;
+ }
+ return UNIMPLEMENTED_COMMAND_INDEX;
+}
+#else
+#define NextImplementedIndex(x) (x)
+#endif
+/* 9.3.3.2 GetClosestCommandIndex() */
+/* This function returns the command index for the command with a value that is equal to or greater
+ than the input value */
+/* Return Value Meaning */
+/* UNIMPLEMENTED_COMMAND_INDEX command is not implemented */
+/* other index of the command */
+
+COMMAND_INDEX
+GetClosestCommandIndex(
+ TPM_CC commandCode // IN: the command code to start at
+ )
+{
+ BOOL vendor = (commandCode & CC_VEND) != 0;
+ COMMAND_INDEX searchIndex = (COMMAND_INDEX)commandCode;
+ // The commandCode is a UINT32 and the search index is UINT16. We are going to
+ // search for a match but need to make sure that the commandCode value is not
+ // out of range. To do this, need to clear the vendor bit of the commandCode
+ // (if set) and compare the result to the 16-bit searchIndex value. If it is
+ // out of range, indicate that the command is not implemented
+ if((commandCode & ~CC_VEND) != searchIndex)
+ return UNIMPLEMENTED_COMMAND_INDEX;
+ // if there is at least one vendor command, the last entry in the array will
+ // have the v bit set. If the input commandCode is larger than the last
+ // vendor-command, then it is out of range.
+ if(vendor)
+ {
+#if VENDOR_COMMAND_ARRAY_SIZE > 0
+ COMMAND_INDEX commandIndex;
+ COMMAND_INDEX min;
+ COMMAND_INDEX max;
+ int diff;
+#if LIBRARY_COMMAND_ARRAY_SIZE == COMMAND_COUNT
+#error "Constants are not consistent."
+#endif
+ // Check to see if the value is equal to or below the minimum
+ // entry.
+ // Note: Put this check first so that the typical case of only one vendor-
+ // specific command doesn't waste any more time.
+ if(GET_ATTRIBUTE(s_ccAttr[LIBRARY_COMMAND_ARRAY_SIZE], TPMA_CC,
+ commandIndex) >= searchIndex)
+ {
+ // the vendor array is always assumed to be packed so there is
+ // no need to check to see if the command is implemented
+ return LIBRARY_COMMAND_ARRAY_SIZE;
+ }
+ // See if this is out of range on the top
+ if(GET_ATTRIBUTE(s_ccAttr[COMMAND_COUNT - 1], TPMA_CC, commandIndex)
+ < searchIndex)
+ {
+ return UNIMPLEMENTED_COMMAND_INDEX;
+ }
+ commandIndex = UNIMPLEMENTED_COMMAND_INDEX; // Needs initialization to keep
+ // compiler happy
+ min = LIBRARY_COMMAND_ARRAY_SIZE; // first vendor command
+ max = COMMAND_COUNT - 1; // last vendor command
+ diff = 1; // needs initialization to keep
+ // compiler happy
+ while(min <= max)
+ {
+ commandIndex = (min + max + 1) / 2;
+ diff = GET_ATTRIBUTE(s_ccAttr[commandIndex], TPMA_CC, commandIndex)
+ - searchIndex;
+ if(diff == 0)
+ return commandIndex;
+ if(diff > 0)
+ max = commandIndex - 1;
+ else
+ min = commandIndex + 1;
+ }
+ // didn't find and exact match. commandIndex will be pointing at the last
+ // item tested. If 'diff' is positive, then the last item tested was
+ // larger index of the command code so it is the smallest value
+ // larger than the requested value.
+ if(diff > 0)
+ return commandIndex;
+ // if 'diff' is negative, then the value tested was smaller than
+ // the commandCode index and the next higher value is the correct one.
+ // Note: this will necessarily be in range because of the earlier check
+ // that the index was within range.
+ return commandIndex + 1;
+#else
+ // If there are no vendor commands so anything with the vendor bit set is out
+ // of range
+ return UNIMPLEMENTED_COMMAND_INDEX;
+#endif
+ }
+ // Get here if the V-Bit was not set in 'commandCode'
+ if(GET_ATTRIBUTE(s_ccAttr[LIBRARY_COMMAND_ARRAY_SIZE - 1], TPMA_CC,
+ commandIndex) < searchIndex)
+ {
+ // requested index is out of the range to the top
+#if VENDOR_COMMAND_ARRAY_SIZE > 0
+ // If there are vendor commands, then the first vendor command
+ // is the next value greater than the commandCode.
+ // NOTE: we got here if the starting index did not have the V bit but we
+ // reached the end of the array of library commands (non-vendor). Since
+ // there is at least one vendor command, and vendor commands are always
+ // in a compressed list that starts after the library list, the next
+ // index value contains a valid vendor command.
+ return LIBRARY_COMMAND_ARRAY_SIZE;
+#else
+ // if there are no vendor commands, then this is out of range
+ return UNIMPLEMENTED_COMMAND_INDEX;
+#endif
+ }
+ // If the request is lower than any value in the array, then return
+ // the lowest value (needs to be an index for an implemented command
+ if(GET_ATTRIBUTE(s_ccAttr[0], TPMA_CC, commandIndex) >= searchIndex)
+ {
+ return NextImplementedIndex(0);
+ }
+ else
+ {
+#if COMPRESSED_LISTS
+ COMMAND_INDEX commandIndex = UNIMPLEMENTED_COMMAND_INDEX;
+ COMMAND_INDEX min = 0;
+ COMMAND_INDEX max = LIBRARY_COMMAND_ARRAY_SIZE - 1;
+ int diff = 1;
+#if LIBRARY_COMMAND_ARRAY_SIZE == 0
+#error "Something is terribly wrong"
+#endif
+ // The s_ccAttr array contains an extra entry at the end (a zero value).
+ // Don't count this as an array entry. This means that max should start
+ // out pointing to the last valid entry in the array which is - 2
+ pAssert(max == (sizeof(s_ccAttr) / sizeof(TPMA_CC)
+ - VENDOR_COMMAND_ARRAY_SIZE - 2));
+ while(min <= max)
+ {
+ commandIndex = (min + max + 1) / 2;
+ diff = GET_ATTRIBUTE(s_ccAttr[commandIndex], TPMA_CC,
+ commandIndex) - searchIndex;
+ if(diff == 0)
+ return commandIndex;
+ if(diff > 0)
+ max = commandIndex - 1;
+ else
+ min = commandIndex + 1;
+ }
+ // didn't find and exact match. commandIndex will be pointing at the
+ // last item tested. If diff is positive, then the last item tested was
+ // larger index of the command code so it is the smallest value
+ // larger than the requested value.
+ if(diff > 0)
+ return commandIndex;
+ // if diff is negative, then the value tested was smaller than
+ // the commandCode index and the next higher value is the correct one.
+ // Note: this will necessarily be in range because of the earlier check
+ // that the index was within range.
+ return commandIndex + 1;
+#else
+ // The list is not compressed so offset into the array by the command
+ // code value of the first entry in the list. Then go find the first
+ // implemented command.
+ return NextImplementedIndex(searchIndex
+ - (COMMAND_INDEX)s_ccAttr[0].commandIndex);
+#endif
+ }
+}
+/* 9.3.3.3 CommandCodeToComandIndex() */
+/* This function returns the index in the various attributes arrays of the command. */
+/* Return Values Meaning */
+/* UNIMPLEMENTED_COMMAND_INDEX command is not implemented */
+/* other index of the command */
+COMMAND_INDEX
+CommandCodeToCommandIndex(
+ TPM_CC commandCode // IN: the command code to look up
+ )
+{
+ // Extract the low 16-bits of the command code to get the starting search index
+ COMMAND_INDEX searchIndex = (COMMAND_INDEX)commandCode;
+ BOOL vendor = (commandCode & CC_VEND) != 0;
+ COMMAND_INDEX commandIndex;
+#if !COMPRESSED_LISTS
+ if(!vendor)
+ {
+ commandIndex = searchIndex - (COMMAND_INDEX)s_ccAttr[0].commandIndex;
+ // Check for out of range or unimplemented.
+ // Note, since a COMMAND_INDEX is unsigned, if searchIndex is smaller than
+ // the lowest value of command, it will become a 'negative' number making
+ // it look like a large unsigned number, this will cause it to fail
+ // the unsigned check below.
+ if(commandIndex >= LIBRARY_COMMAND_ARRAY_SIZE
+ || (s_commandAttributes[commandIndex] & IS_IMPLEMENTED) == 0)
+ return UNIMPLEMENTED_COMMAND_INDEX;
+ return commandIndex;
+ }
+#endif
+ // Need this code for any vendor code lookup or for compressed lists
+ commandIndex = GetClosestCommandIndex(commandCode);
+ // Look at the returned value from get closest. If it isn't the one that was
+ // requested, then the command is not implemented.
+ if(commandIndex != UNIMPLEMENTED_COMMAND_INDEX)
+ {
+ if((GET_ATTRIBUTE(s_ccAttr[commandIndex], TPMA_CC, commandIndex)
+ != searchIndex)
+ || (IS_ATTRIBUTE(s_ccAttr[commandIndex], TPMA_CC, V)) != vendor)
+ commandIndex = UNIMPLEMENTED_COMMAND_INDEX;
+ }
+ return commandIndex;
+}
+/* 9.3.3.4 GetNextCommandIndex() */
+/* This function returns the index of the next implemented command. */
+/* Return Values Meaning */
+/* UNIMPLEMENTED_COMMAND_INDEX no more implemented commands */
+/* other the index of the next implemented command */
+COMMAND_INDEX
+GetNextCommandIndex(
+ COMMAND_INDEX commandIndex // IN: the starting index
+ )
+{
+ while(++commandIndex < COMMAND_COUNT)
+ {
+#if !COMPRESSED_LISTS
+ if(s_commandAttributes[commandIndex] & IS_IMPLEMENTED)
+#endif
+ return commandIndex;
+ }
+ return UNIMPLEMENTED_COMMAND_INDEX;
+}
+/* 9.3.3.5 GetCommandCode() */
+/* This function returns the commandCode associated with the command index */
+TPM_CC
+GetCommandCode(
+ COMMAND_INDEX commandIndex // IN: the command index
+ )
+{
+ TPM_CC commandCode = GET_ATTRIBUTE(s_ccAttr[commandIndex],
+ TPMA_CC, commandIndex);
+ if(IS_ATTRIBUTE(s_ccAttr[commandIndex], TPMA_CC, V))
+ commandCode += CC_VEND;
+ return commandCode;
+}
+/* 9.3.3.6 CommandAuthRole() */
+/* This function returns the authorization role required of a handle. */
+/* Return Values Meaning */
+/* AUTH_NONE no authorization is required */
+/* AUTH_USER user role authorization is required */
+/* AUTH_ADMIN admin role authorization is required */
+/* AUTH_DUP duplication role authorization is required */
+AUTH_ROLE
+CommandAuthRole(
+ COMMAND_INDEX commandIndex, // IN: command index
+ UINT32 handleIndex // IN: handle index (zero based)
+ )
+{
+ if(0 == handleIndex)
+ {
+ // Any authorization role set?
+ COMMAND_ATTRIBUTES properties = s_commandAttributes[commandIndex];
+ if(properties & HANDLE_1_USER)
+ return AUTH_USER;
+ if(properties & HANDLE_1_ADMIN)
+ return AUTH_ADMIN;
+ if(properties & HANDLE_1_DUP)
+ return AUTH_DUP;
+ }
+ else if(1 == handleIndex)
+ {
+ if(s_commandAttributes[commandIndex] & HANDLE_2_USER)
+ return AUTH_USER;
+ }
+ return AUTH_NONE;
+}
+/* 9.3.3.7 EncryptSize() */
+/* This function returns the size of the decrypt size field. This function returns 0 if encryption
+ is not allowed */
+/* Return Values Meaning */
+/* 0 encryption not allowed */
+/* 2 size field is two bytes */
+/* 4 size field is four bytes */
+
+int
+EncryptSize(
+ COMMAND_INDEX commandIndex // IN: command index
+ )
+{
+ return ((s_commandAttributes[commandIndex] & ENCRYPT_2) ? 2 :
+ (s_commandAttributes[commandIndex] & ENCRYPT_4) ? 4 : 0);
+}
+
+/* 9.3.3.8 DecryptSize() */
+/* This function returns the size of the decrypt size field. This function returns 0 if decryption
+ is not allowed */
+/* Return Values Meaning */
+/* 0 encryption not allowed */
+/* 2 size field is two bytes */
+/* 4 size field is four bytes */
+
+int
+DecryptSize(
+ COMMAND_INDEX commandIndex // IN: command index
+ )
+{
+ return ((s_commandAttributes[commandIndex] & DECRYPT_2) ? 2 :
+ (s_commandAttributes[commandIndex] & DECRYPT_4) ? 4 : 0);
+}
+
+/* 9.3.3.9 IsSessionAllowed() */
+/* This function indicates if the command is allowed to have sessions. */
+/* This function must not be called if the command is not known to be implemented. */
+/* Return Values Meaning */
+/* TRUE session is allowed with this command */
+/* FALSE session is not allowed with this command */
+
+BOOL
+IsSessionAllowed(
+ COMMAND_INDEX commandIndex // IN: the command to be checked
+ )
+{
+ return ((s_commandAttributes[commandIndex] & NO_SESSIONS) == 0);
+}
+
+/* 9.3.3.10 IsHandleInResponse() */
+/* This function determines if a command has a handle in the response */
+
+BOOL
+IsHandleInResponse(
+ COMMAND_INDEX commandIndex
+ )
+{
+ return ((s_commandAttributes[commandIndex] & R_HANDLE) != 0);
+}
+
+/* 9.3.3.11 IsWriteOperation() */
+/* Checks to see if an operation will write to an NV Index and is subject to being blocked by
+ read-lock */
+BOOL
+IsWriteOperation(
+ COMMAND_INDEX commandIndex // IN: Command to check
+ )
+{
+#ifdef WRITE_LOCK
+ return ((s_commandAttributes[commandIndex] & WRITE_LOCK) != 0);
+#else
+ if(!IS_ATTRIBUTE(s_ccAttr[commandIndex], TPMA_CC, V))
+ {
+ switch(GET_ATTRIBUTE(s_ccAttr[commandIndex], TPMA_CC, commandIndex))
+ {
+ case TPM_CC_NV_Write:
+#if CC_NV_Increment
+ case TPM_CC_NV_Increment:
+#endif
+#if CC_NV_SetBits
+ case TPM_CC_NV_SetBits:
+#endif
+#if CC_NV_Extend
+ case TPM_CC_NV_Extend:
+#endif
+#if CC_AC_Send
+ case TPM_CC_AC_Send:
+#endif
+ // NV write lock counts as a write operation for authorization purposes.
+ // We check to see if the NV is write locked before we do the
+ // authorization. If it is locked, we fail the command early.
+ case TPM_CC_NV_WriteLock:
+ return TRUE;
+ default:
+ break;
+ }
+ }
+ return FALSE;
+#endif
+}
+/* 9.3.3.12 IsReadOperation() */
+/* Checks to see if an operation will write to an NV Index and is subject to being blocked by
+ write-lock. */
+BOOL
+IsReadOperation(
+ COMMAND_INDEX commandIndex // IN: Command to check
+ )
+{
+#ifdef READ_LOCK
+ return ((s_commandAttributes[commandIndex] & READ_LOCK) != 0);
+#else
+ if(!IS_ATTRIBUTE(s_ccAttr[commandIndex], TPMA_CC, V))
+ {
+ switch(GET_ATTRIBUTE(s_ccAttr[commandIndex], TPMA_CC, commandIndex))
+ {
+ case TPM_CC_NV_Read:
+ case TPM_CC_PolicyNV:
+ case TPM_CC_NV_Certify:
+ // NV read lock counts as a read operation for authorization purposes.
+ // We check to see if the NV is read locked before we do the
+ // authorization. If it is locked, we fail the command early.
+ case TPM_CC_NV_ReadLock:
+ return TRUE;
+ default:
+ break;
+ }
+ }
+ return FALSE;
+#endif
+}
+/* 9.3.3.13 CommandCapGetCCList() */
+/* This function returns a list of implemented commands and command attributes starting from the
+ command in commandCode. */
+/* Return Values Meaning */
+/* YES more command attributes are available */
+/* NO no more command attributes are available */
+TPMI_YES_NO
+CommandCapGetCCList(
+ TPM_CC commandCode, // IN: start command code
+ UINT32 count, // IN: maximum count for number of entries in
+ // 'commandList'
+ TPML_CCA *commandList // OUT: list of TPMA_CC
+ )
+{
+ TPMI_YES_NO more = NO;
+ COMMAND_INDEX commandIndex;
+ // initialize output handle list count
+ commandList->count = 0;
+ for(commandIndex = GetClosestCommandIndex(commandCode);
+ commandIndex != UNIMPLEMENTED_COMMAND_INDEX;
+ commandIndex = GetNextCommandIndex(commandIndex))
+ {
+#if !COMPRESSED_LISTS
+ // this check isn't needed for compressed lists.
+ if(!(s_commandAttributes[commandIndex] & IS_IMPLEMENTED))
+ continue;
+#endif
+ if(commandList->count < count)
+ {
+ // If the list is not full, add the attributes for this command.
+ commandList->commandAttributes[commandList->count]
+ = s_ccAttr[commandIndex];
+ commandList->count++;
+ }
+ else
+ {
+ // If the list is full but there are more commands to report,
+ // indicate this and return.
+ more = YES;
+ break;
+ }
+ }
+ return more;
+}
+#if 0 /* libtpms added */
+/* 9.3.3.14 IsVendorCommand() */
+/* Function indicates if a command index references a vendor command. */
+/* Return Values Meaning */
+/* TRUE command is a vendor command */
+/* FALSE command is not a vendor command */
+
+BOOL
+IsVendorCommand(
+ COMMAND_INDEX commandIndex // IN: command index to check
+ )
+{
+ return (IS_ATTRIBUTE(s_ccAttr[commandIndex], TPMA_CC, V));
+}
+#endif /* libtpms added */
+
diff --git a/src/tpm2/CommandCodeAttributes_fp.h b/src/tpm2/CommandCodeAttributes_fp.h
new file mode 100644
index 0000000..18755b1
--- /dev/null
+++ b/src/tpm2/CommandCodeAttributes_fp.h
@@ -0,0 +1,125 @@
+/********************************************************************************/
+/* */
+/* */
+/* Written by Ken Goldman */
+/* IBM Thomas J. Watson Research Center */
+/* $Id: CommandCodeAttributes_fp.h 1490 2019-07-26 21:13:22Z kgoldman $ */
+/* */
+/* Licenses and Notices */
+/* */
+/* 1. Copyright Licenses: */
+/* */
+/* - Trusted Computing Group (TCG) grants to the user of the source code in */
+/* this specification (the "Source Code") a worldwide, irrevocable, */
+/* nonexclusive, royalty free, copyright license to reproduce, create */
+/* derivative works, distribute, display and perform the Source Code and */
+/* derivative works thereof, and to grant others the rights granted herein. */
+/* */
+/* - The TCG grants to the user of the other parts of the specification */
+/* (other than the Source Code) the rights to reproduce, distribute, */
+/* display, and perform the specification solely for the purpose of */
+/* developing products based on such documents. */
+/* */
+/* 2. Source Code Distribution Conditions: */
+/* */
+/* - Redistributions of Source Code must retain the above copyright licenses, */
+/* this list of conditions and the following disclaimers. */
+/* */
+/* - Redistributions in binary form must reproduce the above copyright */
+/* licenses, this list of conditions and the following disclaimers in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* 3. Disclaimers: */
+/* */
+/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
+/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
+/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
+/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
+/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
+/* information on specification licensing rights available through TCG */
+/* membership agreements. */
+/* */
+/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
+/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
+/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
+/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
+/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
+/* */
+/* - Without limitation, TCG and its members and licensors disclaim all */
+/* liability, including liability for infringement of any proprietary */
+/* rights, relating to use of information in this specification and to the */
+/* implementation of this specification, and TCG disclaims all liability for */
+/* cost of procurement of substitute goods or services, lost profits, loss */
+/* of use, loss of data or any incidental, consequential, direct, indirect, */
+/* or special damages, whether under contract, tort, warranty or otherwise, */
+/* arising in any way out of use or reliance upon this specification or any */
+/* information herein. */
+/* */
+/* (c) Copyright IBM Corp. and others, 2016 */
+/* */
+/********************************************************************************/
+
+#ifndef COMMANDCODEATTRIBUTES_FP_H
+#define COMMANDCODEATTRIBUTES_FP_H
+
+COMMAND_INDEX
+GetClosestCommandIndex(
+ TPM_CC commandCode // IN: the command code to start at
+ );
+COMMAND_INDEX
+CommandCodeToCommandIndex(
+ TPM_CC commandCode // IN: the command code to look up
+ );
+COMMAND_INDEX
+GetNextCommandIndex(
+ COMMAND_INDEX commandIndex // IN: the starting index
+ );
+TPM_CC
+GetCommandCode(
+ COMMAND_INDEX commandIndex // IN: the command index
+ );
+AUTH_ROLE
+CommandAuthRole(
+ COMMAND_INDEX commandIndex, // IN: command index
+ UINT32 handleIndex // IN: handle index (zero based)
+ );
+int
+EncryptSize(
+ COMMAND_INDEX commandIndex // IN: command index
+ );
+int
+DecryptSize(
+ COMMAND_INDEX commandIndex // IN: command index
+ );
+BOOL
+IsSessionAllowed(
+ COMMAND_INDEX commandIndex // IN: the command to be checked
+ );
+BOOL
+IsHandleInResponse(
+ COMMAND_INDEX commandIndex
+ );
+BOOL
+IsWriteOperation(
+ COMMAND_INDEX commandIndex // IN: Command to check
+ );
+BOOL
+IsReadOperation(
+ COMMAND_INDEX commandIndex // IN: Command to check
+ );
+TPMI_YES_NO
+CommandCapGetCCList(
+ TPM_CC commandCode, // IN: start command code
+ UINT32 count, // IN: maximum count for number of entries in
+ // 'commandList'
+ TPML_CCA *commandList // OUT: list of TPMA_CC
+ );
+#if 0 /* libtpms added */
+BOOL
+IsVendorCommand(
+ COMMAND_INDEX commandIndex // IN: command index to check
+ );
+#endif /* libtpms added */
+
+
+#endif
diff --git a/src/tpm2/CommandDispatchData.h b/src/tpm2/CommandDispatchData.h
new file mode 100644
index 0000000..b11096c
--- /dev/null
+++ b/src/tpm2/CommandDispatchData.h
@@ -0,0 +1,4623 @@
+/********************************************************************************/
+/* */
+/* Command DIspatch Data */
+/* Written by Ken Goldman */
+/* IBM Thomas J. Watson Research Center */
+/* $Id: CommandDispatchData.h 1658 2021-01-22 23:14:01Z kgoldman $ */
+/* */
+/* Licenses and Notices */
+/* */
+/* 1. Copyright Licenses: */
+/* */
+/* - Trusted Computing Group (TCG) grants to the user of the source code in */
+/* this specification (the "Source Code") a worldwide, irrevocable, */
+/* nonexclusive, royalty free, copyright license to reproduce, create */
+/* derivative works, distribute, display and perform the Source Code and */
+/* derivative works thereof, and to grant others the rights granted herein. */
+/* */
+/* - The TCG grants to the user of the other parts of the specification */
+/* (other than the Source Code) the rights to reproduce, distribute, */
+/* display, and perform the specification solely for the purpose of */
+/* developing products based on such documents. */
+/* */
+/* 2. Source Code Distribution Conditions: */
+/* */
+/* - Redistributions of Source Code must retain the above copyright licenses, */
+/* this list of conditions and the following disclaimers. */
+/* */
+/* - Redistributions in binary form must reproduce the above copyright */
+/* licenses, this list of conditions and the following disclaimers in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* 3. Disclaimers: */
+/* */
+/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
+/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
+/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
+/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
+/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
+/* information on specification licensing rights available through TCG */
+/* membership agreements. */
+/* */
+/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
+/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
+/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
+/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
+/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
+/* */
+/* - Without limitation, TCG and its members and licensors disclaim all */
+/* liability, including liability for infringement of any proprietary */
+/* rights, relating to use of information in this specification and to the */
+/* implementation of this specification, and TCG disclaims all liability for */
+/* cost of procurement of substitute goods or services, lost profits, loss */
+/* of use, loss of data or any incidental, consequential, direct, indirect, */
+/* or special damages, whether under contract, tort, warranty or otherwise, */
+/* arising in any way out of use or reliance upon this specification or any */
+/* information herein. */
+/* */
+/* (c) Copyright IBM Corp. and others, 2016 - 2021 */
+/* */
+/********************************************************************************/
+
+/* This file should only be included by CommandCodeAttibutes.c */
+#ifdef _COMMAND_TABLE_DISPATCH_
+
+#define END_OF_LIST 0xff
+#define ADD_FLAG 0x80
+
+/* These macros provide some variability in how the data is encoded. They also make the lines a
+ little shorter. ;-) */
+
+#if TABLE_DRIVEN_MARSHAL
+# define UNMARSHAL_DISPATCH(name) (marshalIndex_t)name##_MARSHAL_REF
+# define MARSHAL_DISPATCH(name) (marshalIndex_t)name##_MARSHAL_REF
+# define _UNMARSHAL_T_ marshalIndex_t
+# define _MARSHAL_T_ marshalIndex_t
+#
+#else
+# define UNMARSHAL_DISPATCH(name) (UNMARSHAL_t)name##_Unmarshal
+# define MARSHAL_DISPATCH(name) (MARSHAL_t)name##_Marshal
+# define _UNMARSHAL_T_ UNMARSHAL_t
+# define _MARSHAL_T_ MARSHAL_t
+#endif
+
+const _UNMARSHAL_T_ unmarshalArray[] = {
+#define TPMI_DH_CONTEXT_H_UNMARSHAL 0
+ UNMARSHAL_DISPATCH(TPMI_DH_CONTEXT),
+#define TPMI_RH_AC_H_UNMARSHAL (TPMI_DH_CONTEXT_H_UNMARSHAL + 1)
+ UNMARSHAL_DISPATCH(TPMI_RH_AC),
+#define TPMI_RH_ACT_H_UNMARSHAL (TPMI_RH_AC_H_UNMARSHAL + 1)
+ UNMARSHAL_DISPATCH(TPMI_RH_ACT),
+#define TPMI_RH_CLEAR_H_UNMARSHAL (TPMI_RH_ACT_H_UNMARSHAL + 1)
+ UNMARSHAL_DISPATCH(TPMI_RH_CLEAR),
+#define TPMI_RH_HIERARCHY_AUTH_H_UNMARSHAL (TPMI_RH_CLEAR_H_UNMARSHAL + 1)
+ UNMARSHAL_DISPATCH(TPMI_RH_HIERARCHY_AUTH),
+#define TPMI_RH_HIERARCHY_POLICY_H_UNMARSHAL \
+ (TPMI_RH_HIERARCHY_AUTH_H_UNMARSHAL + 1)
+ UNMARSHAL_DISPATCH(TPMI_RH_HIERARCHY_POLICY),
+#define TPMI_RH_LOCKOUT_H_UNMARSHAL \
+ (TPMI_RH_HIERARCHY_POLICY_H_UNMARSHAL + 1)
+ UNMARSHAL_DISPATCH(TPMI_RH_LOCKOUT),
+#define TPMI_RH_NV_AUTH_H_UNMARSHAL (TPMI_RH_LOCKOUT_H_UNMARSHAL + 1)
+ UNMARSHAL_DISPATCH(TPMI_RH_NV_AUTH),
+#define TPMI_RH_NV_INDEX_H_UNMARSHAL (TPMI_RH_NV_AUTH_H_UNMARSHAL + 1)
+ UNMARSHAL_DISPATCH(TPMI_RH_NV_INDEX),
+#define TPMI_RH_PLATFORM_H_UNMARSHAL (TPMI_RH_NV_INDEX_H_UNMARSHAL + 1)
+ UNMARSHAL_DISPATCH(TPMI_RH_PLATFORM),
+#define TPMI_RH_PROVISION_H_UNMARSHAL (TPMI_RH_PLATFORM_H_UNMARSHAL + 1)
+ UNMARSHAL_DISPATCH(TPMI_RH_PROVISION),
+#define TPMI_SH_HMAC_H_UNMARSHAL (TPMI_RH_PROVISION_H_UNMARSHAL + 1)
+ UNMARSHAL_DISPATCH(TPMI_SH_HMAC),
+#define TPMI_SH_POLICY_H_UNMARSHAL (TPMI_SH_HMAC_H_UNMARSHAL + 1)
+ UNMARSHAL_DISPATCH(TPMI_SH_POLICY),
+ // HANDLE_FIRST_FLAG_TYPE is the first handle that needs a flag when called.
+#define HANDLE_FIRST_FLAG_TYPE (TPMI_SH_POLICY_H_UNMARSHAL + 1)
+#define TPMI_DH_ENTITY_H_UNMARSHAL (TPMI_SH_POLICY_H_UNMARSHAL + 1)
+ UNMARSHAL_DISPATCH(TPMI_DH_ENTITY),
+#define TPMI_DH_OBJECT_H_UNMARSHAL (TPMI_DH_ENTITY_H_UNMARSHAL + 1)
+ UNMARSHAL_DISPATCH(TPMI_DH_OBJECT),
+#define TPMI_DH_PARENT_H_UNMARSHAL (TPMI_DH_OBJECT_H_UNMARSHAL + 1)
+ UNMARSHAL_DISPATCH(TPMI_DH_PARENT),
+#define TPMI_DH_PCR_H_UNMARSHAL (TPMI_DH_PARENT_H_UNMARSHAL + 1)
+ UNMARSHAL_DISPATCH(TPMI_DH_PCR),
+#define TPMI_RH_ENDORSEMENT_H_UNMARSHAL (TPMI_DH_PCR_H_UNMARSHAL + 1)
+ UNMARSHAL_DISPATCH(TPMI_RH_ENDORSEMENT),
+#define TPMI_RH_HIERARCHY_H_UNMARSHAL \
+ (TPMI_RH_ENDORSEMENT_H_UNMARSHAL + 1)
+ UNMARSHAL_DISPATCH(TPMI_RH_HIERARCHY),
+ // PARAMETER_FIRST_TYPE marks the end of the handle list.
+#define PARAMETER_FIRST_TYPE (TPMI_RH_HIERARCHY_H_UNMARSHAL + 1)
+#define TPM2B_DATA_P_UNMARSHAL (TPMI_RH_HIERARCHY_H_UNMARSHAL + 1)
+ UNMARSHAL_DISPATCH(TPM2B_DATA),
+#define TPM2B_DIGEST_P_UNMARSHAL (TPM2B_DATA_P_UNMARSHAL + 1)
+ UNMARSHAL_DISPATCH(TPM2B_DIGEST),
+#define TPM2B_ECC_PARAMETER_P_UNMARSHAL (TPM2B_DIGEST_P_UNMARSHAL + 1)
+ UNMARSHAL_DISPATCH(TPM2B_ECC_PARAMETER),
+#define TPM2B_ECC_POINT_P_UNMARSHAL \
+ (TPM2B_ECC_PARAMETER_P_UNMARSHAL + 1)
+ UNMARSHAL_DISPATCH(TPM2B_ECC_POINT),
+#define TPM2B_ENCRYPTED_SECRET_P_UNMARSHAL (TPM2B_ECC_POINT_P_UNMARSHAL + 1)
+ UNMARSHAL_DISPATCH(TPM2B_ENCRYPTED_SECRET),
+#define TPM2B_EVENT_P_UNMARSHAL \
+ (TPM2B_ENCRYPTED_SECRET_P_UNMARSHAL + 1)
+ UNMARSHAL_DISPATCH(TPM2B_EVENT),
+#define TPM2B_ID_OBJECT_P_UNMARSHAL (TPM2B_EVENT_P_UNMARSHAL + 1)
+ UNMARSHAL_DISPATCH(TPM2B_ID_OBJECT),
+#define TPM2B_IV_P_UNMARSHAL (TPM2B_ID_OBJECT_P_UNMARSHAL + 1)
+ UNMARSHAL_DISPATCH(TPM2B_IV),
+#define TPM2B_MAX_BUFFER_P_UNMARSHAL (TPM2B_IV_P_UNMARSHAL + 1)
+ UNMARSHAL_DISPATCH(TPM2B_MAX_BUFFER),
+#define TPM2B_MAX_NV_BUFFER_P_UNMARSHAL (TPM2B_MAX_BUFFER_P_UNMARSHAL + 1)
+ UNMARSHAL_DISPATCH(TPM2B_MAX_NV_BUFFER),
+#define TPM2B_NAME_P_UNMARSHAL \
+ (TPM2B_MAX_NV_BUFFER_P_UNMARSHAL + 1)
+ UNMARSHAL_DISPATCH(TPM2B_NAME),
+#define TPM2B_NV_PUBLIC_P_UNMARSHAL (TPM2B_NAME_P_UNMARSHAL + 1)
+ UNMARSHAL_DISPATCH(TPM2B_NV_PUBLIC),
+#define TPM2B_PRIVATE_P_UNMARSHAL (TPM2B_NV_PUBLIC_P_UNMARSHAL + 1)
+ UNMARSHAL_DISPATCH(TPM2B_PRIVATE),
+#define TPM2B_PUBLIC_KEY_RSA_P_UNMARSHAL (TPM2B_PRIVATE_P_UNMARSHAL + 1)
+ UNMARSHAL_DISPATCH(TPM2B_PUBLIC_KEY_RSA),
+#define TPM2B_SENSITIVE_P_UNMARSHAL \
+ (TPM2B_PUBLIC_KEY_RSA_P_UNMARSHAL + 1)
+ UNMARSHAL_DISPATCH(TPM2B_SENSITIVE),
+#define TPM2B_SENSITIVE_CREATE_P_UNMARSHAL (TPM2B_SENSITIVE_P_UNMARSHAL + 1)
+ UNMARSHAL_DISPATCH(TPM2B_SENSITIVE_CREATE),
+#define TPM2B_SENSITIVE_DATA_P_UNMARSHAL \
+ (TPM2B_SENSITIVE_CREATE_P_UNMARSHAL + 1)
+ UNMARSHAL_DISPATCH(TPM2B_SENSITIVE_DATA),
+#define TPM2B_TEMPLATE_P_UNMARSHAL \
+ (TPM2B_SENSITIVE_DATA_P_UNMARSHAL + 1)
+ UNMARSHAL_DISPATCH(TPM2B_TEMPLATE),
+#define TPM2B_TIMEOUT_P_UNMARSHAL (TPM2B_TEMPLATE_P_UNMARSHAL + 1)
+ UNMARSHAL_DISPATCH(TPM2B_TIMEOUT),
+#define TPMI_DH_CONTEXT_P_UNMARSHAL (TPM2B_TIMEOUT_P_UNMARSHAL + 1)
+ UNMARSHAL_DISPATCH(TPMI_DH_CONTEXT),
+#define TPMI_DH_PERSISTENT_P_UNMARSHAL (TPMI_DH_CONTEXT_P_UNMARSHAL + 1)
+ UNMARSHAL_DISPATCH(TPMI_DH_PERSISTENT),
+#define TPMI_ECC_CURVE_P_UNMARSHAL (TPMI_DH_PERSISTENT_P_UNMARSHAL + 1)
+ UNMARSHAL_DISPATCH(TPMI_ECC_CURVE),
+#define TPMI_YES_NO_P_UNMARSHAL (TPMI_ECC_CURVE_P_UNMARSHAL + 1)
+ UNMARSHAL_DISPATCH(TPMI_YES_NO),
+#define TPML_ALG_P_UNMARSHAL (TPMI_YES_NO_P_UNMARSHAL + 1)
+ UNMARSHAL_DISPATCH(TPML_ALG),
+#define TPML_CC_P_UNMARSHAL (TPML_ALG_P_UNMARSHAL + 1)
+ UNMARSHAL_DISPATCH(TPML_CC),
+#define TPML_DIGEST_P_UNMARSHAL (TPML_CC_P_UNMARSHAL + 1)
+ UNMARSHAL_DISPATCH(TPML_DIGEST),
+#define TPML_DIGEST_VALUES_P_UNMARSHAL (TPML_DIGEST_P_UNMARSHAL + 1)
+ UNMARSHAL_DISPATCH(TPML_DIGEST_VALUES),
+#define TPML_PCR_SELECTION_P_UNMARSHAL (TPML_DIGEST_VALUES_P_UNMARSHAL + 1)
+ UNMARSHAL_DISPATCH(TPML_PCR_SELECTION),
+#define TPMS_CONTEXT_P_UNMARSHAL (TPML_PCR_SELECTION_P_UNMARSHAL + 1)
+ UNMARSHAL_DISPATCH(TPMS_CONTEXT),
+#define TPMT_PUBLIC_PARMS_P_UNMARSHAL (TPMS_CONTEXT_P_UNMARSHAL + 1)
+ UNMARSHAL_DISPATCH(TPMT_PUBLIC_PARMS),
+#define TPMT_TK_AUTH_P_UNMARSHAL (TPMT_PUBLIC_PARMS_P_UNMARSHAL + 1)
+ UNMARSHAL_DISPATCH(TPMT_TK_AUTH),
+#define TPMT_TK_CREATION_P_UNMARSHAL (TPMT_TK_AUTH_P_UNMARSHAL + 1)
+ UNMARSHAL_DISPATCH(TPMT_TK_CREATION),
+#define TPMT_TK_HASHCHECK_P_UNMARSHAL (TPMT_TK_CREATION_P_UNMARSHAL + 1)
+ UNMARSHAL_DISPATCH(TPMT_TK_HASHCHECK),
+#define TPMT_TK_VERIFIED_P_UNMARSHAL (TPMT_TK_HASHCHECK_P_UNMARSHAL + 1)
+ UNMARSHAL_DISPATCH(TPMT_TK_VERIFIED),
+#define TPM_AT_P_UNMARSHAL (TPMT_TK_VERIFIED_P_UNMARSHAL + 1)
+ UNMARSHAL_DISPATCH(TPM_AT),
+#define TPM_CAP_P_UNMARSHAL (TPM_AT_P_UNMARSHAL + 1)
+ UNMARSHAL_DISPATCH(TPM_CAP),
+#define TPM_CLOCK_ADJUST_P_UNMARSHAL (TPM_CAP_P_UNMARSHAL + 1)
+ UNMARSHAL_DISPATCH(TPM_CLOCK_ADJUST),
+#define TPM_EO_P_UNMARSHAL (TPM_CLOCK_ADJUST_P_UNMARSHAL + 1)
+ UNMARSHAL_DISPATCH(TPM_EO),
+#define TPM_SE_P_UNMARSHAL (TPM_EO_P_UNMARSHAL + 1)
+ UNMARSHAL_DISPATCH(TPM_SE),
+#define TPM_SU_P_UNMARSHAL (TPM_SE_P_UNMARSHAL + 1)
+ UNMARSHAL_DISPATCH(TPM_SU),
+#define UINT16_P_UNMARSHAL (TPM_SU_P_UNMARSHAL + 1)
+ UNMARSHAL_DISPATCH(UINT16),
+#define UINT32_P_UNMARSHAL (UINT16_P_UNMARSHAL + 1)
+ UNMARSHAL_DISPATCH(UINT32),
+#define UINT64_P_UNMARSHAL (UINT32_P_UNMARSHAL + 1)
+ UNMARSHAL_DISPATCH(UINT64),
+#define UINT8_P_UNMARSHAL (UINT64_P_UNMARSHAL + 1)
+ UNMARSHAL_DISPATCH(UINT8),
+ // PARAMETER_FIRST_FLAG_TYPE is the first parameter to need a flag.
+#define PARAMETER_FIRST_FLAG_TYPE (UINT8_P_UNMARSHAL + 1)
+#define TPM2B_PUBLIC_P_UNMARSHAL (UINT8_P_UNMARSHAL + 1)
+ UNMARSHAL_DISPATCH(TPM2B_PUBLIC),
+#define TPMI_ALG_CIPHER_MODE_P_UNMARSHAL (TPM2B_PUBLIC_P_UNMARSHAL + 1)
+ UNMARSHAL_DISPATCH(TPMI_ALG_CIPHER_MODE),
+#define TPMI_ALG_HASH_P_UNMARSHAL \
+ (TPMI_ALG_CIPHER_MODE_P_UNMARSHAL + 1)
+ UNMARSHAL_DISPATCH(TPMI_ALG_HASH),
+#define TPMI_ALG_MAC_SCHEME_P_UNMARSHAL (TPMI_ALG_HASH_P_UNMARSHAL + 1)
+ UNMARSHAL_DISPATCH(TPMI_ALG_MAC_SCHEME),
+#define TPMI_DH_PCR_P_UNMARSHAL \
+ (TPMI_ALG_MAC_SCHEME_P_UNMARSHAL + 1)
+ UNMARSHAL_DISPATCH(TPMI_DH_PCR),
+#define TPMI_ECC_KEY_EXCHANGE_P_UNMARSHAL (TPMI_DH_PCR_P_UNMARSHAL + 1)
+ UNMARSHAL_DISPATCH(TPMI_ECC_KEY_EXCHANGE),
+#define TPMI_RH_ENABLES_P_UNMARSHAL \
+ (TPMI_ECC_KEY_EXCHANGE_P_UNMARSHAL + 1)
+ UNMARSHAL_DISPATCH(TPMI_RH_ENABLES),
+#define TPMI_RH_HIERARCHY_P_UNMARSHAL (TPMI_RH_ENABLES_P_UNMARSHAL + 1)
+ UNMARSHAL_DISPATCH(TPMI_RH_HIERARCHY),
+#define TPMT_KDF_SCHEME_P_UNMARSHAL (TPMI_RH_HIERARCHY_P_UNMARSHAL + 1)
+ UNMARSHAL_DISPATCH(TPMT_KDF_SCHEME),
+#define TPMT_RSA_DECRYPT_P_UNMARSHAL (TPMT_KDF_SCHEME_P_UNMARSHAL + 1)
+ UNMARSHAL_DISPATCH(TPMT_RSA_DECRYPT),
+#define TPMT_SIGNATURE_P_UNMARSHAL (TPMT_RSA_DECRYPT_P_UNMARSHAL + 1)
+ UNMARSHAL_DISPATCH(TPMT_SIGNATURE),
+#define TPMT_SIG_SCHEME_P_UNMARSHAL (TPMT_SIGNATURE_P_UNMARSHAL + 1)
+ UNMARSHAL_DISPATCH(TPMT_SIG_SCHEME),
+#define TPMT_SYM_DEF_P_UNMARSHAL (TPMT_SIG_SCHEME_P_UNMARSHAL + 1)
+ UNMARSHAL_DISPATCH(TPMT_SYM_DEF),
+#define TPMT_SYM_DEF_OBJECT_P_UNMARSHAL (TPMT_SYM_DEF_P_UNMARSHAL + 1)
+ UNMARSHAL_DISPATCH(TPMT_SYM_DEF_OBJECT)
+ // PARAMETER_LAST_TYPE is the end of the command parameter list.
+
+ // PARAMETER_LAST_TYPE is the end of the command parameter list.
+#define PARAMETER_LAST_TYPE (TPMT_SYM_DEF_OBJECT_P_UNMARSHAL)
+
+};
+
+
+const _MARSHAL_T_ marshalArray[] = {
+
+#define UINT32_H_MARSHAL 0
+ MARSHAL_DISPATCH(UINT32),
+ // RESPONSE_PARAMETER_FIRST_TYPE marks the end of the response handles.
+#define RESPONSE_PARAMETER_FIRST_TYPE (UINT32_H_MARSHAL + 1)
+#define TPM2B_ATTEST_P_MARSHAL (UINT32_H_MARSHAL + 1)
+ MARSHAL_DISPATCH(TPM2B_ATTEST),
+#define TPM2B_CREATION_DATA_P_MARSHAL (TPM2B_ATTEST_P_MARSHAL + 1)
+ MARSHAL_DISPATCH(TPM2B_CREATION_DATA),
+#define TPM2B_DATA_P_MARSHAL (TPM2B_CREATION_DATA_P_MARSHAL + 1)
+ MARSHAL_DISPATCH(TPM2B_DATA),
+#define TPM2B_DIGEST_P_MARSHAL (TPM2B_DATA_P_MARSHAL + 1)
+ MARSHAL_DISPATCH(TPM2B_DIGEST),
+#define TPM2B_ECC_POINT_P_MARSHAL (TPM2B_DIGEST_P_MARSHAL + 1)
+ MARSHAL_DISPATCH(TPM2B_ECC_POINT),
+#define TPM2B_ENCRYPTED_SECRET_P_MARSHAL (TPM2B_ECC_POINT_P_MARSHAL + 1)
+ MARSHAL_DISPATCH(TPM2B_ENCRYPTED_SECRET),
+#define TPM2B_ID_OBJECT_P_MARSHAL \
+ (TPM2B_ENCRYPTED_SECRET_P_MARSHAL + 1)
+ MARSHAL_DISPATCH(TPM2B_ID_OBJECT),
+#define TPM2B_IV_P_MARSHAL (TPM2B_ID_OBJECT_P_MARSHAL + 1)
+ MARSHAL_DISPATCH(TPM2B_IV),
+#define TPM2B_MAX_BUFFER_P_MARSHAL (TPM2B_IV_P_MARSHAL + 1)
+ MARSHAL_DISPATCH(TPM2B_MAX_BUFFER),
+#define TPM2B_MAX_NV_BUFFER_P_MARSHAL (TPM2B_MAX_BUFFER_P_MARSHAL + 1)
+ MARSHAL_DISPATCH(TPM2B_MAX_NV_BUFFER),
+#define TPM2B_NAME_P_MARSHAL (TPM2B_MAX_NV_BUFFER_P_MARSHAL + 1)
+ MARSHAL_DISPATCH(TPM2B_NAME),
+#define TPM2B_NV_PUBLIC_P_MARSHAL (TPM2B_NAME_P_MARSHAL + 1)
+ MARSHAL_DISPATCH(TPM2B_NV_PUBLIC),
+#define TPM2B_PRIVATE_P_MARSHAL (TPM2B_NV_PUBLIC_P_MARSHAL + 1)
+ MARSHAL_DISPATCH(TPM2B_PRIVATE),
+#define TPM2B_PUBLIC_P_MARSHAL (TPM2B_PRIVATE_P_MARSHAL + 1)
+ MARSHAL_DISPATCH(TPM2B_PUBLIC),
+#define TPM2B_PUBLIC_KEY_RSA_P_MARSHAL (TPM2B_PUBLIC_P_MARSHAL + 1)
+ MARSHAL_DISPATCH(TPM2B_PUBLIC_KEY_RSA),
+#define TPM2B_SENSITIVE_DATA_P_MARSHAL (TPM2B_PUBLIC_KEY_RSA_P_MARSHAL + 1)
+ MARSHAL_DISPATCH(TPM2B_SENSITIVE_DATA),
+#define TPM2B_TIMEOUT_P_MARSHAL (TPM2B_SENSITIVE_DATA_P_MARSHAL + 1)
+ MARSHAL_DISPATCH(TPM2B_TIMEOUT),
+#define UINT8_P_MARSHAL (TPM2B_TIMEOUT_P_MARSHAL + 1)
+ MARSHAL_DISPATCH(UINT8),
+#define TPML_AC_CAPABILITIES_P_MARSHAL (UINT8_P_MARSHAL + 1)
+ MARSHAL_DISPATCH(TPML_AC_CAPABILITIES),
+#define TPML_ALG_P_MARSHAL (TPML_AC_CAPABILITIES_P_MARSHAL + 1)
+ MARSHAL_DISPATCH(TPML_ALG),
+#define TPML_DIGEST_P_MARSHAL (TPML_ALG_P_MARSHAL + 1)
+ MARSHAL_DISPATCH(TPML_DIGEST),
+#define TPML_DIGEST_VALUES_P_MARSHAL (TPML_DIGEST_P_MARSHAL + 1)
+ MARSHAL_DISPATCH(TPML_DIGEST_VALUES),
+#define TPML_PCR_SELECTION_P_MARSHAL (TPML_DIGEST_VALUES_P_MARSHAL + 1)
+ MARSHAL_DISPATCH(TPML_PCR_SELECTION),
+#define TPMS_AC_OUTPUT_P_MARSHAL (TPML_PCR_SELECTION_P_MARSHAL + 1)
+ MARSHAL_DISPATCH(TPMS_AC_OUTPUT),
+#define TPMS_ALGORITHM_DETAIL_ECC_P_MARSHAL (TPMS_AC_OUTPUT_P_MARSHAL + 1)
+ MARSHAL_DISPATCH(TPMS_ALGORITHM_DETAIL_ECC),
+#define TPMS_CAPABILITY_DATA_P_MARSHAL \
+ (TPMS_ALGORITHM_DETAIL_ECC_P_MARSHAL + 1)
+ MARSHAL_DISPATCH(TPMS_CAPABILITY_DATA),
+#define TPMS_CONTEXT_P_MARSHAL (TPMS_CAPABILITY_DATA_P_MARSHAL + 1)
+ MARSHAL_DISPATCH(TPMS_CONTEXT),
+#define TPMS_TIME_INFO_P_MARSHAL (TPMS_CONTEXT_P_MARSHAL + 1)
+ MARSHAL_DISPATCH(TPMS_TIME_INFO),
+#define TPMT_HA_P_MARSHAL (TPMS_TIME_INFO_P_MARSHAL + 1)
+ MARSHAL_DISPATCH(TPMT_HA),
+#define TPMT_SIGNATURE_P_MARSHAL (TPMT_HA_P_MARSHAL + 1)
+ MARSHAL_DISPATCH(TPMT_SIGNATURE),
+#define TPMT_TK_AUTH_P_MARSHAL (TPMT_SIGNATURE_P_MARSHAL + 1)
+ MARSHAL_DISPATCH(TPMT_TK_AUTH),
+#define TPMT_TK_CREATION_P_MARSHAL (TPMT_TK_AUTH_P_MARSHAL + 1)
+ MARSHAL_DISPATCH(TPMT_TK_CREATION),
+#define TPMT_TK_HASHCHECK_P_MARSHAL (TPMT_TK_CREATION_P_MARSHAL + 1)
+ MARSHAL_DISPATCH(TPMT_TK_HASHCHECK),
+#define TPMT_TK_VERIFIED_P_MARSHAL (TPMT_TK_HASHCHECK_P_MARSHAL + 1)
+ MARSHAL_DISPATCH(TPMT_TK_VERIFIED),
+#define UINT32_P_MARSHAL (TPMT_TK_VERIFIED_P_MARSHAL + 1)
+ MARSHAL_DISPATCH(UINT32),
+#define UINT16_P_MARSHAL (UINT32_P_MARSHAL + 1)
+ MARSHAL_DISPATCH(UINT16)
+
+#define RESPONSE_PARAMETER_LAST_TYPE (UINT16_P_MARSHAL)
+};
+
+/* This list of aliases allows the types in the _COMMAND_DESCRIPTOR_T to match the types in the
+ command/response templates of part 3. */
+#define INT32_P_UNMARSHAL UINT32_P_UNMARSHAL
+#define TPM2B_AUTH_P_UNMARSHAL TPM2B_DIGEST_P_UNMARSHAL
+#define TPM2B_NONCE_P_UNMARSHAL TPM2B_DIGEST_P_UNMARSHAL
+#define TPM2B_OPERAND_P_UNMARSHAL TPM2B_DIGEST_P_UNMARSHAL
+#define TPMA_LOCALITY_P_UNMARSHAL UINT8_P_UNMARSHAL
+#define TPM_CC_P_UNMARSHAL UINT32_P_UNMARSHAL
+#define TPMI_DH_CONTEXT_H_MARSHAL UINT32_H_MARSHAL
+#define TPMI_DH_OBJECT_H_MARSHAL UINT32_H_MARSHAL
+#define TPMI_SH_AUTH_SESSION_H_MARSHAL UINT32_H_MARSHAL
+#define TPM_HANDLE_H_MARSHAL UINT32_H_MARSHAL
+#define TPM2B_NONCE_P_MARSHAL TPM2B_DIGEST_P_MARSHAL
+#define TPMI_YES_NO_P_MARSHAL UINT8_P_MARSHAL
+#define TPM_RC_P_MARSHAL UINT32_P_MARSHAL
+
+#if CC_Startup
+#include "Startup_fp.h"
+typedef TPM_RC (Startup_Entry)(
+ Startup_In *in
+ );
+typedef const struct {
+ Startup_Entry *entry;
+ UINT16 inSize;
+ UINT16 outSize;
+ UINT16 offsetOfTypes;
+ BYTE types[3];
+} Startup_COMMAND_DESCRIPTOR_t;
+Startup_COMMAND_DESCRIPTOR_t _StartupData = {
+ /* entry */ &TPM2_Startup,
+ /* inSize */ (UINT16)(sizeof(Startup_In)),
+ /* outSize */ 0,
+ /* offsetOfTypes */ offsetof(Startup_COMMAND_DESCRIPTOR_t, types),
+ /* offsets */ // No parameter offsets
+ /* types */ {TPM_SU_P_UNMARSHAL,
+ END_OF_LIST,
+ END_OF_LIST}
+};
+#define _StartupDataAddress (&_StartupData)
+#else
+#define _StartupDataAddress 0
+#endif
+#if CC_Shutdown
+#include "Shutdown_fp.h"
+typedef TPM_RC (Shutdown_Entry)(
+ Shutdown_In *in
+ );
+typedef const struct {
+ Shutdown_Entry *entry;
+ UINT16 inSize;
+ UINT16 outSize;
+ UINT16 offsetOfTypes;
+ BYTE types[3];
+} Shutdown_COMMAND_DESCRIPTOR_t;
+Shutdown_COMMAND_DESCRIPTOR_t _ShutdownData = {
+ /* entry */ &TPM2_Shutdown,
+ /* inSize */ (UINT16)(sizeof(Shutdown_In)),
+ /* outSize */ 0,
+ /* offsetOfTypes */ offsetof(Shutdown_COMMAND_DESCRIPTOR_t, types),
+ /* offsets */ // No parameter offsets
+ /* types */ {TPM_SU_P_UNMARSHAL,
+ END_OF_LIST,
+ END_OF_LIST}
+};
+#define _ShutdownDataAddress (&_ShutdownData)
+#else
+#define _ShutdownDataAddress 0
+#endif
+#if CC_SelfTest
+#include "SelfTest_fp.h"
+typedef TPM_RC (SelfTest_Entry)(
+ SelfTest_In *in
+ );
+typedef const struct {
+ SelfTest_Entry *entry;
+ UINT16 inSize;
+ UINT16 outSize;
+ UINT16 offsetOfTypes;
+ BYTE types[3];
+} SelfTest_COMMAND_DESCRIPTOR_t;
+SelfTest_COMMAND_DESCRIPTOR_t _SelfTestData = {
+ /* entry */ &TPM2_SelfTest,
+ /* inSize */ (UINT16)(sizeof(SelfTest_In)),
+ /* outSize */ 0,
+ /* offsetOfTypes */ offsetof(SelfTest_COMMAND_DESCRIPTOR_t, types),
+ /* offsets */ // No parameter offsets
+ /* types */ {TPMI_YES_NO_P_UNMARSHAL,
+ END_OF_LIST,
+ END_OF_LIST}
+};
+#define _SelfTestDataAddress (&_SelfTestData)
+#else
+#define _SelfTestDataAddress 0
+#endif
+#if CC_IncrementalSelfTest
+#include "IncrementalSelfTest_fp.h"
+typedef TPM_RC (IncrementalSelfTest_Entry)(
+ IncrementalSelfTest_In *in,
+ IncrementalSelfTest_Out *out
+ );
+typedef const struct {
+ IncrementalSelfTest_Entry *entry;
+ UINT16 inSize;
+ UINT16 outSize;
+ UINT16 offsetOfTypes;
+ BYTE types[4];
+} IncrementalSelfTest_COMMAND_DESCRIPTOR_t;
+IncrementalSelfTest_COMMAND_DESCRIPTOR_t _IncrementalSelfTestData = {
+ /* entry */ &TPM2_IncrementalSelfTest,
+ /* inSize */ (UINT16)(sizeof(IncrementalSelfTest_In)),
+ /* outSize */ (UINT16)(sizeof(IncrementalSelfTest_Out)),
+ /* offsetOfTypes */ offsetof(IncrementalSelfTest_COMMAND_DESCRIPTOR_t, types),
+ /* offsets */ // No parameter offsets
+ /* types */ {TPML_ALG_P_UNMARSHAL,
+ END_OF_LIST,
+ TPML_ALG_P_MARSHAL,
+ END_OF_LIST}
+};
+#define _IncrementalSelfTestDataAddress (&_IncrementalSelfTestData)
+#else
+#define _IncrementalSelfTestDataAddress 0
+#endif
+#if CC_GetTestResult
+#include "GetTestResult_fp.h"
+typedef TPM_RC (GetTestResult_Entry)(
+ GetTestResult_Out *out
+ );
+typedef const struct {
+ GetTestResult_Entry *entry;
+ UINT16 inSize;
+ UINT16 outSize;
+ UINT16 offsetOfTypes;
+ UINT16 paramOffsets[1];
+ BYTE types[4];
+} GetTestResult_COMMAND_DESCRIPTOR_t;
+GetTestResult_COMMAND_DESCRIPTOR_t _GetTestResultData = {
+ /* entry */ &TPM2_GetTestResult,
+ /* inSize */ 0,
+ /* outSize */ (UINT16)(sizeof(GetTestResult_Out)),
+ /* offsetOfTypes */ offsetof(GetTestResult_COMMAND_DESCRIPTOR_t, types),
+ /* offsets */ {(UINT16)(offsetof(GetTestResult_Out, testResult))},
+ /* types */ {END_OF_LIST,
+ TPM2B_MAX_BUFFER_P_MARSHAL,
+ TPM_RC_P_MARSHAL,
+ END_OF_LIST}
+};
+#define _GetTestResultDataAddress (&_GetTestResultData)
+#else
+#define _GetTestResultDataAddress 0
+#endif
+#if CC_StartAuthSession
+#include "StartAuthSession_fp.h"
+typedef TPM_RC (StartAuthSession_Entry)(
+ StartAuthSession_In *in,
+ StartAuthSession_Out *out
+ );
+typedef const struct {
+ StartAuthSession_Entry *entry;
+ UINT16 inSize;
+ UINT16 outSize;
+ UINT16 offsetOfTypes;
+ UINT16 paramOffsets[7];
+ BYTE types[11];
+} StartAuthSession_COMMAND_DESCRIPTOR_t;
+StartAuthSession_COMMAND_DESCRIPTOR_t _StartAuthSessionData = {
+ /* entry */ &TPM2_StartAuthSession,
+ /* inSize */ (UINT16)(sizeof(StartAuthSession_In)),
+ /* outSize */ (UINT16)(sizeof(StartAuthSession_Out)),
+ /* offsetOfTypes */ offsetof(StartAuthSession_COMMAND_DESCRIPTOR_t, types),
+ /* offsets */ {(UINT16)(offsetof(StartAuthSession_In, bind)),
+ (UINT16)(offsetof(StartAuthSession_In, nonceCaller)),
+ (UINT16)(offsetof(StartAuthSession_In, encryptedSalt)),
+ (UINT16)(offsetof(StartAuthSession_In, sessionType)),
+ (UINT16)(offsetof(StartAuthSession_In, symmetric)),
+ (UINT16)(offsetof(StartAuthSession_In, authHash)),
+ (UINT16)(offsetof(StartAuthSession_Out, nonceTPM))},
+ /* types */ {TPMI_DH_OBJECT_H_UNMARSHAL + ADD_FLAG,
+ TPMI_DH_ENTITY_H_UNMARSHAL + ADD_FLAG,
+ TPM2B_NONCE_P_UNMARSHAL,
+ TPM2B_ENCRYPTED_SECRET_P_UNMARSHAL,
+ TPM_SE_P_UNMARSHAL,
+ TPMT_SYM_DEF_P_UNMARSHAL + ADD_FLAG,
+ TPMI_ALG_HASH_P_UNMARSHAL,
+ END_OF_LIST,
+ TPMI_SH_AUTH_SESSION_H_MARSHAL,
+ TPM2B_NONCE_P_MARSHAL,
+ END_OF_LIST}
+};
+#define _StartAuthSessionDataAddress (&_StartAuthSessionData)
+#else
+#define _StartAuthSessionDataAddress 0
+#endif
+#if CC_PolicyRestart
+#include "PolicyRestart_fp.h"
+typedef TPM_RC (PolicyRestart_Entry)(
+ PolicyRestart_In *in
+ );
+typedef const struct {
+ PolicyRestart_Entry *entry;
+ UINT16 inSize;
+ UINT16 outSize;
+ UINT16 offsetOfTypes;
+ BYTE types[3];
+} PolicyRestart_COMMAND_DESCRIPTOR_t;
+PolicyRestart_COMMAND_DESCRIPTOR_t _PolicyRestartData = {
+ /* entry */ &TPM2_PolicyRestart,
+ /* inSize */ (UINT16)(sizeof(PolicyRestart_In)),
+ /* outSize */ 0,
+ /* offsetOfTypes */ offsetof(PolicyRestart_COMMAND_DESCRIPTOR_t, types),
+ /* offsets */ // No parameter offsets
+ /* types */ {TPMI_SH_POLICY_H_UNMARSHAL,
+ END_OF_LIST,
+ END_OF_LIST}
+};
+#define _PolicyRestartDataAddress (&_PolicyRestartData)
+#else
+#define _PolicyRestartDataAddress 0
+#endif
+#if CC_Create
+#include "Create_fp.h"
+typedef TPM_RC (Create_Entry)(
+ Create_In *in,
+ Create_Out *out
+ );
+typedef const struct {
+ Create_Entry *entry;
+ UINT16 inSize;
+ UINT16 outSize;
+ UINT16 offsetOfTypes;
+ UINT16 paramOffsets[8];
+ BYTE types[12];
+} Create_COMMAND_DESCRIPTOR_t;
+Create_COMMAND_DESCRIPTOR_t _CreateData = {
+ /* entry */ &TPM2_Create,
+ /* inSize */ (UINT16)(sizeof(Create_In)),
+ /* outSize */ (UINT16)(sizeof(Create_Out)),
+ /* offsetOfTypes */ offsetof(Create_COMMAND_DESCRIPTOR_t, types),
+ /* offsets */ {(UINT16)(offsetof(Create_In, inSensitive)),
+ (UINT16)(offsetof(Create_In, inPublic)),
+ (UINT16)(offsetof(Create_In, outsideInfo)),
+ (UINT16)(offsetof(Create_In, creationPCR)),
+ (UINT16)(offsetof(Create_Out, outPublic)),
+ (UINT16)(offsetof(Create_Out, creationData)),
+ (UINT16)(offsetof(Create_Out, creationHash)),
+ (UINT16)(offsetof(Create_Out, creationTicket))},
+ /* types */ {TPMI_DH_OBJECT_H_UNMARSHAL,
+ TPM2B_SENSITIVE_CREATE_P_UNMARSHAL,
+ TPM2B_PUBLIC_P_UNMARSHAL,
+ TPM2B_DATA_P_UNMARSHAL,
+ TPML_PCR_SELECTION_P_UNMARSHAL,
+ END_OF_LIST,
+ TPM2B_PRIVATE_P_MARSHAL,
+ TPM2B_PUBLIC_P_MARSHAL,
+ TPM2B_CREATION_DATA_P_MARSHAL,
+ TPM2B_DIGEST_P_MARSHAL,
+ TPMT_TK_CREATION_P_MARSHAL,
+ END_OF_LIST}
+};
+#define _CreateDataAddress (&_CreateData)
+#else
+#define _CreateDataAddress 0
+#endif
+#if CC_Load
+#include "Load_fp.h"
+typedef TPM_RC (Load_Entry)(
+ Load_In *in,
+ Load_Out *out
+ );
+typedef const struct {
+ Load_Entry *entry;
+ UINT16 inSize;
+ UINT16 outSize;
+ UINT16 offsetOfTypes;
+ UINT16 paramOffsets[3];
+ BYTE types[7];
+} Load_COMMAND_DESCRIPTOR_t;
+Load_COMMAND_DESCRIPTOR_t _LoadData = {
+ /* entry */ &TPM2_Load,
+ /* inSize */ (UINT16)(sizeof(Load_In)),
+ /* outSize */ (UINT16)(sizeof(Load_Out)),
+ /* offsetOfTypes */ offsetof(Load_COMMAND_DESCRIPTOR_t, types),
+ /* offsets */ {(UINT16)(offsetof(Load_In, inPrivate)),
+ (UINT16)(offsetof(Load_In, inPublic)),
+ (UINT16)(offsetof(Load_Out, name))},
+ /* types */ {TPMI_DH_OBJECT_H_UNMARSHAL,
+ TPM2B_PRIVATE_P_UNMARSHAL,
+ TPM2B_PUBLIC_P_UNMARSHAL,
+ END_OF_LIST,
+ TPM_HANDLE_H_MARSHAL,
+ TPM2B_NAME_P_MARSHAL,
+ END_OF_LIST}
+};
+#define _LoadDataAddress (&_LoadData)
+#else
+#define _LoadDataAddress 0
+#endif
+#if CC_LoadExternal
+#include "LoadExternal_fp.h"
+typedef TPM_RC (LoadExternal_Entry)(
+ LoadExternal_In *in,
+ LoadExternal_Out *out
+ );
+typedef const struct {
+ LoadExternal_Entry *entry;
+ UINT16 inSize;
+ UINT16 outSize;
+ UINT16 offsetOfTypes;
+ UINT16 paramOffsets[3];
+ BYTE types[7];
+} LoadExternal_COMMAND_DESCRIPTOR_t;
+LoadExternal_COMMAND_DESCRIPTOR_t _LoadExternalData = {
+ /* entry */ &TPM2_LoadExternal,
+ /* inSize */ (UINT16)(sizeof(LoadExternal_In)),
+ /* outSize */ (UINT16)(sizeof(LoadExternal_Out)),
+ /* offsetOfTypes */ offsetof(LoadExternal_COMMAND_DESCRIPTOR_t, types),
+ /* offsets */ {(UINT16)(offsetof(LoadExternal_In, inPublic)),
+ (UINT16)(offsetof(LoadExternal_In, hierarchy)),
+ (UINT16)(offsetof(LoadExternal_Out, name))},
+ /* types */ {TPM2B_SENSITIVE_P_UNMARSHAL,
+ TPM2B_PUBLIC_P_UNMARSHAL + ADD_FLAG,
+ TPMI_RH_HIERARCHY_P_UNMARSHAL + ADD_FLAG,
+ END_OF_LIST,
+ TPM_HANDLE_H_MARSHAL,
+ TPM2B_NAME_P_MARSHAL,
+ END_OF_LIST}
+};
+#define _LoadExternalDataAddress (&_LoadExternalData)
+#else
+#define _LoadExternalDataAddress 0
+#endif
+#if CC_ReadPublic
+#include "ReadPublic_fp.h"
+typedef TPM_RC (ReadPublic_Entry)(
+ ReadPublic_In *in,
+ ReadPublic_Out *out
+ );
+typedef const struct {
+ ReadPublic_Entry *entry;
+ UINT16 inSize;
+ UINT16 outSize;
+ UINT16 offsetOfTypes;
+ UINT16 paramOffsets[2];
+ BYTE types[6];
+} ReadPublic_COMMAND_DESCRIPTOR_t;
+ReadPublic_COMMAND_DESCRIPTOR_t _ReadPublicData = {
+ /* entry */ &TPM2_ReadPublic,
+ /* inSize */ (UINT16)(sizeof(ReadPublic_In)),
+ /* outSize */ (UINT16)(sizeof(ReadPublic_Out)),
+ /* offsetOfTypes */ offsetof(ReadPublic_COMMAND_DESCRIPTOR_t, types),
+ /* offsets */ {(UINT16)(offsetof(ReadPublic_Out, name)),
+ (UINT16)(offsetof(ReadPublic_Out, qualifiedName))},
+ /* types */ {TPMI_DH_OBJECT_H_UNMARSHAL,
+ END_OF_LIST,
+ TPM2B_PUBLIC_P_MARSHAL,
+ TPM2B_NAME_P_MARSHAL,
+ TPM2B_NAME_P_MARSHAL,
+ END_OF_LIST}
+};
+#define _ReadPublicDataAddress (&_ReadPublicData)
+#else
+#define _ReadPublicDataAddress 0
+#endif
+#if CC_ActivateCredential
+#include "ActivateCredential_fp.h"
+typedef TPM_RC (ActivateCredential_Entry)(
+ ActivateCredential_In *in,
+ ActivateCredential_Out *out
+ );
+typedef const struct {
+ ActivateCredential_Entry *entry;
+ UINT16 inSize;
+ UINT16 outSize;
+ UINT16 offsetOfTypes;
+ UINT16 paramOffsets[3];
+ BYTE types[7];
+} ActivateCredential_COMMAND_DESCRIPTOR_t;
+ActivateCredential_COMMAND_DESCRIPTOR_t _ActivateCredentialData = {
+ /* entry */ &TPM2_ActivateCredential,
+ /* inSize */ (UINT16)(sizeof(ActivateCredential_In)),
+ /* outSize */ (UINT16)(sizeof(ActivateCredential_Out)),
+ /* offsetOfTypes */ offsetof(ActivateCredential_COMMAND_DESCRIPTOR_t, types),
+ /* offsets */ {(UINT16)(offsetof(ActivateCredential_In, keyHandle)),
+ (UINT16)(offsetof(ActivateCredential_In, credentialBlob)),
+ (UINT16)(offsetof(ActivateCredential_In, secret))},
+ /* types */ {TPMI_DH_OBJECT_H_UNMARSHAL,
+ TPMI_DH_OBJECT_H_UNMARSHAL,
+ TPM2B_ID_OBJECT_P_UNMARSHAL,
+ TPM2B_ENCRYPTED_SECRET_P_UNMARSHAL,
+ END_OF_LIST,
+ TPM2B_DIGEST_P_MARSHAL,
+ END_OF_LIST}
+};
+#define _ActivateCredentialDataAddress (&_ActivateCredentialData)
+#else
+#define _ActivateCredentialDataAddress 0
+#endif
+#if CC_MakeCredential
+#include "MakeCredential_fp.h"
+typedef TPM_RC (MakeCredential_Entry)(
+ MakeCredential_In *in,
+ MakeCredential_Out *out
+ );
+typedef const struct {
+ MakeCredential_Entry *entry;
+ UINT16 inSize;
+ UINT16 outSize;
+ UINT16 offsetOfTypes;
+ UINT16 paramOffsets[3];
+ BYTE types[7];
+} MakeCredential_COMMAND_DESCRIPTOR_t;
+MakeCredential_COMMAND_DESCRIPTOR_t _MakeCredentialData = {
+ /* entry */ &TPM2_MakeCredential,
+ /* inSize */ (UINT16)(sizeof(MakeCredential_In)),
+ /* outSize */ (UINT16)(sizeof(MakeCredential_Out)),
+ /* offsetOfTypes */ offsetof(MakeCredential_COMMAND_DESCRIPTOR_t, types),
+ /* offsets */ {(UINT16)(offsetof(MakeCredential_In, credential)),
+ (UINT16)(offsetof(MakeCredential_In, objectName)),
+ (UINT16)(offsetof(MakeCredential_Out, secret))},
+ /* types */ {TPMI_DH_OBJECT_H_UNMARSHAL,
+ TPM2B_DIGEST_P_UNMARSHAL,
+ TPM2B_NAME_P_UNMARSHAL,
+ END_OF_LIST,
+ TPM2B_ID_OBJECT_P_MARSHAL,
+ TPM2B_ENCRYPTED_SECRET_P_MARSHAL,
+ END_OF_LIST}
+};
+#define _MakeCredentialDataAddress (&_MakeCredentialData)
+#else
+#define _MakeCredentialDataAddress 0
+#endif
+#if CC_Unseal
+#include "Unseal_fp.h"
+typedef TPM_RC (Unseal_Entry)(
+ Unseal_In *in,
+ Unseal_Out *out
+ );
+typedef const struct {
+ Unseal_Entry *entry;
+ UINT16 inSize;
+ UINT16 outSize;
+ UINT16 offsetOfTypes;
+ BYTE types[4];
+} Unseal_COMMAND_DESCRIPTOR_t;
+Unseal_COMMAND_DESCRIPTOR_t _UnsealData = {
+ /* entry */ &TPM2_Unseal,
+ /* inSize */ (UINT16)(sizeof(Unseal_In)),
+ /* outSize */ (UINT16)(sizeof(Unseal_Out)),
+ /* offsetOfTypes */ offsetof(Unseal_COMMAND_DESCRIPTOR_t, types),
+ /* offsets */ // No parameter offsets
+ /* types */ {TPMI_DH_OBJECT_H_UNMARSHAL,
+ END_OF_LIST,
+ TPM2B_SENSITIVE_DATA_P_MARSHAL,
+ END_OF_LIST}
+};
+#define _UnsealDataAddress (&_UnsealData)
+#else
+#define _UnsealDataAddress 0
+#endif
+#if CC_ObjectChangeAuth
+#include "ObjectChangeAuth_fp.h"
+typedef TPM_RC (ObjectChangeAuth_Entry)(
+ ObjectChangeAuth_In *in,
+ ObjectChangeAuth_Out *out
+ );
+typedef const struct {
+ ObjectChangeAuth_Entry *entry;
+ UINT16 inSize;
+ UINT16 outSize;
+ UINT16 offsetOfTypes;
+ UINT16 paramOffsets[2];
+ BYTE types[6];
+} ObjectChangeAuth_COMMAND_DESCRIPTOR_t;
+ObjectChangeAuth_COMMAND_DESCRIPTOR_t _ObjectChangeAuthData = {
+ /* entry */ &TPM2_ObjectChangeAuth,
+ /* inSize */ (UINT16)(sizeof(ObjectChangeAuth_In)),
+ /* outSize */ (UINT16)(sizeof(ObjectChangeAuth_Out)),
+ /* offsetOfTypes */ offsetof(ObjectChangeAuth_COMMAND_DESCRIPTOR_t, types),
+ /* offsets */ {(UINT16)(offsetof(ObjectChangeAuth_In, parentHandle)),
+ (UINT16)(offsetof(ObjectChangeAuth_In, newAuth))},
+ /* types */ {TPMI_DH_OBJECT_H_UNMARSHAL,
+ TPMI_DH_OBJECT_H_UNMARSHAL,
+ TPM2B_AUTH_P_UNMARSHAL,
+ END_OF_LIST,
+ TPM2B_PRIVATE_P_MARSHAL,
+ END_OF_LIST}
+};
+#define _ObjectChangeAuthDataAddress (&_ObjectChangeAuthData)
+#else
+#define _ObjectChangeAuthDataAddress 0
+#endif
+#if CC_CreateLoaded
+#include "CreateLoaded_fp.h"
+typedef TPM_RC (CreateLoaded_Entry)(
+ CreateLoaded_In *in,
+ CreateLoaded_Out *out
+ );
+typedef const struct {
+ CreateLoaded_Entry *entry;
+ UINT16 inSize;
+ UINT16 outSize;
+ UINT16 offsetOfTypes;
+ UINT16 paramOffsets[5];
+ BYTE types[9];
+} CreateLoaded_COMMAND_DESCRIPTOR_t;
+CreateLoaded_COMMAND_DESCRIPTOR_t _CreateLoadedData = {
+ /* entry */ &TPM2_CreateLoaded,
+ /* inSize */ (UINT16)(sizeof(CreateLoaded_In)),
+ /* outSize */ (UINT16)(sizeof(CreateLoaded_Out)),
+ /* offsetOfTypes */ offsetof(CreateLoaded_COMMAND_DESCRIPTOR_t, types),
+ /* offsets */ {(UINT16)(offsetof(CreateLoaded_In, inSensitive)),
+ (UINT16)(offsetof(CreateLoaded_In, inPublic)),
+ (UINT16)(offsetof(CreateLoaded_Out, outPrivate)),
+ (UINT16)(offsetof(CreateLoaded_Out, outPublic)),
+ (UINT16)(offsetof(CreateLoaded_Out, name))},
+ /* types */ {TPMI_DH_PARENT_H_UNMARSHAL + ADD_FLAG,
+ TPM2B_SENSITIVE_CREATE_P_UNMARSHAL,
+ TPM2B_TEMPLATE_P_UNMARSHAL,
+ END_OF_LIST,
+ TPM_HANDLE_H_MARSHAL,
+ TPM2B_PRIVATE_P_MARSHAL,
+ TPM2B_PUBLIC_P_MARSHAL,
+ TPM2B_NAME_P_MARSHAL,
+ END_OF_LIST}
+};
+#define _CreateLoadedDataAddress (&_CreateLoadedData)
+#else
+#define _CreateLoadedDataAddress 0
+#endif
+#if CC_Duplicate
+#include "Duplicate_fp.h"
+typedef TPM_RC (Duplicate_Entry)(
+ Duplicate_In *in,
+ Duplicate_Out *out
+ );
+typedef const struct {
+ Duplicate_Entry *entry;
+ UINT16 inSize;
+ UINT16 outSize;
+ UINT16 offsetOfTypes;
+ UINT16 paramOffsets[5];
+ BYTE types[9];
+} Duplicate_COMMAND_DESCRIPTOR_t;
+Duplicate_COMMAND_DESCRIPTOR_t _DuplicateData = {
+ /* entry */ &TPM2_Duplicate,
+ /* inSize */ (UINT16)(sizeof(Duplicate_In)),
+ /* outSize */ (UINT16)(sizeof(Duplicate_Out)),
+ /* offsetOfTypes */ offsetof(Duplicate_COMMAND_DESCRIPTOR_t, types),
+ /* offsets */ {(UINT16)(offsetof(Duplicate_In, newParentHandle)),
+ (UINT16)(offsetof(Duplicate_In, encryptionKeyIn)),
+ (UINT16)(offsetof(Duplicate_In, symmetricAlg)),
+ (UINT16)(offsetof(Duplicate_Out, duplicate)),
+ (UINT16)(offsetof(Duplicate_Out, outSymSeed))},
+ /* types */ {TPMI_DH_OBJECT_H_UNMARSHAL,
+ TPMI_DH_OBJECT_H_UNMARSHAL + ADD_FLAG,
+ TPM2B_DATA_P_UNMARSHAL,
+ TPMT_SYM_DEF_OBJECT_P_UNMARSHAL + ADD_FLAG,
+ END_OF_LIST,
+ TPM2B_DATA_P_MARSHAL,
+ TPM2B_PRIVATE_P_MARSHAL,
+ TPM2B_ENCRYPTED_SECRET_P_MARSHAL,
+ END_OF_LIST}
+};
+#define _DuplicateDataAddress (&_DuplicateData)
+#else
+#define _DuplicateDataAddress 0
+#endif
+#if CC_Rewrap
+#include "Rewrap_fp.h"
+typedef TPM_RC (Rewrap_Entry)(
+ Rewrap_In *in,
+ Rewrap_Out *out
+ );
+typedef const struct {
+ Rewrap_Entry *entry;
+ UINT16 inSize;
+ UINT16 outSize;
+ UINT16 offsetOfTypes;
+ UINT16 paramOffsets[5];
+ BYTE types[9];
+} Rewrap_COMMAND_DESCRIPTOR_t;
+Rewrap_COMMAND_DESCRIPTOR_t _RewrapData = {
+ /* entry */ &TPM2_Rewrap,
+ /* inSize */ (UINT16)(sizeof(Rewrap_In)),
+ /* outSize */ (UINT16)(sizeof(Rewrap_Out)),
+ /* offsetOfTypes */ offsetof(Rewrap_COMMAND_DESCRIPTOR_t, types),
+ /* offsets */ {(UINT16)(offsetof(Rewrap_In, newParent)),
+ (UINT16)(offsetof(Rewrap_In, inDuplicate)),
+ (UINT16)(offsetof(Rewrap_In, name)),
+ (UINT16)(offsetof(Rewrap_In, inSymSeed)),
+ (UINT16)(offsetof(Rewrap_Out, outSymSeed))},
+ /* types */ {TPMI_DH_OBJECT_H_UNMARSHAL + ADD_FLAG,
+ TPMI_DH_OBJECT_H_UNMARSHAL + ADD_FLAG,
+ TPM2B_PRIVATE_P_UNMARSHAL,
+ TPM2B_NAME_P_UNMARSHAL,
+ TPM2B_ENCRYPTED_SECRET_P_UNMARSHAL,
+ END_OF_LIST,
+ TPM2B_PRIVATE_P_MARSHAL,
+ TPM2B_ENCRYPTED_SECRET_P_MARSHAL,
+ END_OF_LIST}
+};
+#define _RewrapDataAddress (&_RewrapData)
+#else
+#define _RewrapDataAddress 0
+#endif
+#if CC_Import
+#include "Import_fp.h"
+typedef TPM_RC (Import_Entry)(
+ Import_In *in,
+ Import_Out *out
+ );
+typedef const struct {
+ Import_Entry *entry;
+ UINT16 inSize;
+ UINT16 outSize;
+ UINT16 offsetOfTypes;
+ UINT16 paramOffsets[5];
+ BYTE types[9];
+} Import_COMMAND_DESCRIPTOR_t;
+Import_COMMAND_DESCRIPTOR_t _ImportData = {
+ /* entry */ &TPM2_Import,
+ /* inSize */ (UINT16)(sizeof(Import_In)),
+ /* outSize */ (UINT16)(sizeof(Import_Out)),
+ /* offsetOfTypes */ offsetof(Import_COMMAND_DESCRIPTOR_t, types),
+ /* offsets */ {(UINT16)(offsetof(Import_In, encryptionKey)),
+ (UINT16)(offsetof(Import_In, objectPublic)),
+ (UINT16)(offsetof(Import_In, duplicate)),
+ (UINT16)(offsetof(Import_In, inSymSeed)),
+ (UINT16)(offsetof(Import_In, symmetricAlg))},
+ /* types */ {TPMI_DH_OBJECT_H_UNMARSHAL,
+ TPM2B_DATA_P_UNMARSHAL,
+ TPM2B_PUBLIC_P_UNMARSHAL,
+ TPM2B_PRIVATE_P_UNMARSHAL,
+ TPM2B_ENCRYPTED_SECRET_P_UNMARSHAL,
+ TPMT_SYM_DEF_OBJECT_P_UNMARSHAL + ADD_FLAG,
+ END_OF_LIST,
+ TPM2B_PRIVATE_P_MARSHAL,
+ END_OF_LIST}
+};
+#define _ImportDataAddress (&_ImportData)
+#else
+#define _ImportDataAddress 0
+#endif
+#if CC_RSA_Encrypt
+#include "RSA_Encrypt_fp.h"
+typedef TPM_RC (RSA_Encrypt_Entry)(
+ RSA_Encrypt_In *in,
+ RSA_Encrypt_Out *out
+ );
+typedef const struct {
+ RSA_Encrypt_Entry *entry;
+ UINT16 inSize;
+ UINT16 outSize;
+ UINT16 offsetOfTypes;
+ UINT16 paramOffsets[3];
+ BYTE types[7];
+} RSA_Encrypt_COMMAND_DESCRIPTOR_t;
+RSA_Encrypt_COMMAND_DESCRIPTOR_t _RSA_EncryptData = {
+ /* entry */ &TPM2_RSA_Encrypt,
+ /* inSize */ (UINT16)(sizeof(RSA_Encrypt_In)),
+ /* outSize */ (UINT16)(sizeof(RSA_Encrypt_Out)),
+ /* offsetOfTypes */ offsetof(RSA_Encrypt_COMMAND_DESCRIPTOR_t, types),
+ /* offsets */ {(UINT16)(offsetof(RSA_Encrypt_In, message)),
+ (UINT16)(offsetof(RSA_Encrypt_In, inScheme)),
+ (UINT16)(offsetof(RSA_Encrypt_In, label))},
+ /* types */ {TPMI_DH_OBJECT_H_UNMARSHAL,
+ TPM2B_PUBLIC_KEY_RSA_P_UNMARSHAL,
+ TPMT_RSA_DECRYPT_P_UNMARSHAL + ADD_FLAG,
+ TPM2B_DATA_P_UNMARSHAL,
+ END_OF_LIST,
+ TPM2B_PUBLIC_KEY_RSA_P_MARSHAL,
+ END_OF_LIST}
+};
+#define _RSA_EncryptDataAddress (&_RSA_EncryptData)
+#else
+#define _RSA_EncryptDataAddress 0
+#endif
+#if CC_RSA_Decrypt
+#include "RSA_Decrypt_fp.h"
+typedef TPM_RC (RSA_Decrypt_Entry)(
+ RSA_Decrypt_In *in,
+ RSA_Decrypt_Out *out
+ );
+typedef const struct {
+ RSA_Decrypt_Entry *entry;
+ UINT16 inSize;
+ UINT16 outSize;
+ UINT16 offsetOfTypes;
+ UINT16 paramOffsets[3];
+ BYTE types[7];
+} RSA_Decrypt_COMMAND_DESCRIPTOR_t;
+RSA_Decrypt_COMMAND_DESCRIPTOR_t _RSA_DecryptData = {
+ /* entry */ &TPM2_RSA_Decrypt,
+ /* inSize */ (UINT16)(sizeof(RSA_Decrypt_In)),
+ /* outSize */ (UINT16)(sizeof(RSA_Decrypt_Out)),
+ /* offsetOfTypes */ offsetof(RSA_Decrypt_COMMAND_DESCRIPTOR_t, types),
+ /* offsets */ {(UINT16)(offsetof(RSA_Decrypt_In, cipherText)),
+ (UINT16)(offsetof(RSA_Decrypt_In, inScheme)),
+ (UINT16)(offsetof(RSA_Decrypt_In, label))},
+ /* types */ {TPMI_DH_OBJECT_H_UNMARSHAL,
+ TPM2B_PUBLIC_KEY_RSA_P_UNMARSHAL,
+ TPMT_RSA_DECRYPT_P_UNMARSHAL + ADD_FLAG,
+ TPM2B_DATA_P_UNMARSHAL,
+ END_OF_LIST,
+ TPM2B_PUBLIC_KEY_RSA_P_MARSHAL,
+ END_OF_LIST}
+};
+#define _RSA_DecryptDataAddress (&_RSA_DecryptData)
+#else
+#define _RSA_DecryptDataAddress 0
+#endif
+#if CC_ECDH_KeyGen
+#include "ECDH_KeyGen_fp.h"
+typedef TPM_RC (ECDH_KeyGen_Entry)(
+ ECDH_KeyGen_In *in,
+ ECDH_KeyGen_Out *out
+ );
+typedef const struct {
+ ECDH_KeyGen_Entry *entry;
+ UINT16 inSize;
+ UINT16 outSize;
+ UINT16 offsetOfTypes;
+ UINT16 paramOffsets[1];
+ BYTE types[5];
+} ECDH_KeyGen_COMMAND_DESCRIPTOR_t;
+ECDH_KeyGen_COMMAND_DESCRIPTOR_t _ECDH_KeyGenData = {
+ /* entry */ &TPM2_ECDH_KeyGen,
+ /* inSize */ (UINT16)(sizeof(ECDH_KeyGen_In)),
+ /* outSize */ (UINT16)(sizeof(ECDH_KeyGen_Out)),
+ /* offsetOfTypes */ offsetof(ECDH_KeyGen_COMMAND_DESCRIPTOR_t, types),
+ /* offsets */ {(UINT16)(offsetof(ECDH_KeyGen_Out, pubPoint))},
+ /* types */ {TPMI_DH_OBJECT_H_UNMARSHAL,
+ END_OF_LIST,
+ TPM2B_ECC_POINT_P_MARSHAL,
+ TPM2B_ECC_POINT_P_MARSHAL,
+ END_OF_LIST}
+};
+#define _ECDH_KeyGenDataAddress (&_ECDH_KeyGenData)
+#else
+#define _ECDH_KeyGenDataAddress 0
+#endif
+#if CC_ECDH_ZGen
+#include "ECDH_ZGen_fp.h"
+typedef TPM_RC (ECDH_ZGen_Entry)(
+ ECDH_ZGen_In *in,
+ ECDH_ZGen_Out *out
+ );
+typedef const struct {
+ ECDH_ZGen_Entry *entry;
+ UINT16 inSize;
+ UINT16 outSize;
+ UINT16 offsetOfTypes;
+ UINT16 paramOffsets[1];
+ BYTE types[5];
+} ECDH_ZGen_COMMAND_DESCRIPTOR_t;
+ECDH_ZGen_COMMAND_DESCRIPTOR_t _ECDH_ZGenData = {
+ /* entry */ &TPM2_ECDH_ZGen,
+ /* inSize */ (UINT16)(sizeof(ECDH_ZGen_In)),
+ /* outSize */ (UINT16)(sizeof(ECDH_ZGen_Out)),
+ /* offsetOfTypes */ offsetof(ECDH_ZGen_COMMAND_DESCRIPTOR_t, types),
+ /* offsets */ {(UINT16)(offsetof(ECDH_ZGen_In, inPoint))},
+ /* types */ {TPMI_DH_OBJECT_H_UNMARSHAL,
+ TPM2B_ECC_POINT_P_UNMARSHAL,
+ END_OF_LIST,
+ TPM2B_ECC_POINT_P_MARSHAL,
+ END_OF_LIST}
+};
+#define _ECDH_ZGenDataAddress (&_ECDH_ZGenData)
+#else
+#define _ECDH_ZGenDataAddress 0
+#endif
+
+#if CC_ECC_Encrypt
+
+#include "ECC_Encrypt_fp.h"
+
+typedef TPM_RC (ECC_Encrypt_Entry)(
+ ECC_Encrypt_In *in,
+ ECC_Encrypt_Out *out
+ );
+
+typedef const struct {
+ ECC_Encrypt_Entry *entry;
+ UINT16 inSize;
+ UINT16 outSize;
+ UINT16 offsetOfTypes;
+ UINT16 paramOffsets[4];
+ BYTE types[8];
+} ECC_Encrypt_COMMAND_DESCRIPTOR_t;
+
+ECC_Encrypt_COMMAND_DESCRIPTOR_t _ECC_EncryptData = {
+ /* entry */ &TPM2_ECC_Encrypt,
+ /* inSize */ (UINT16)(sizeof(ECC_Encrypt_In)),
+ /* outSize */ (UINT16)(sizeof(ECC_Encrypt_Out)),
+ /* offsetOfTypes */ offsetof(ECC_Encrypt_COMMAND_DESCRIPTOR_t, types),
+ /* offsets */ {(UINT16)(offsetof(ECC_Encrypt_In, plainText)),
+ (UINT16)(offsetof(ECC_Encrypt_In, inScheme)),
+ (UINT16)(offsetof(ECC_Encrypt_Out, C2)),
+ (UINT16)(offsetof(ECC_Encrypt_Out, C3))},
+ /* types */ {TPMI_DH_OBJECT_H_UNMARSHAL,
+ TPM2B_MAX_BUFFER_P_UNMARSHAL,
+ TPMT_KDF_SCHEME_P_UNMARSHAL + ADD_FLAG,
+ END_OF_LIST,
+ TPM2B_ECC_POINT_P_MARSHAL,
+ TPM2B_MAX_BUFFER_P_MARSHAL,
+ TPM2B_DIGEST_P_MARSHAL,
+ END_OF_LIST}
+};
+
+#define _ECC_EncryptDataAddress (&_ECC_EncryptData)
+#else
+#define _ECC_EncryptDataAddress 0
+#endif // CC_ECC_Encrypt
+
+#if CC_ECC_Decrypt
+
+#include "ECC_Decrypt_fp.h"
+
+typedef TPM_RC (ECC_Decrypt_Entry)(
+ ECC_Decrypt_In *in,
+ ECC_Decrypt_Out *out
+ );
+
+typedef const struct {
+ ECC_Decrypt_Entry *entry;
+ UINT16 inSize;
+ UINT16 outSize;
+ UINT16 offsetOfTypes;
+ UINT16 paramOffsets[4];
+ BYTE types[8];
+} ECC_Decrypt_COMMAND_DESCRIPTOR_t;
+
+ECC_Decrypt_COMMAND_DESCRIPTOR_t _ECC_DecryptData = {
+ /* entry */ &TPM2_ECC_Decrypt,
+ /* inSize */ (UINT16)(sizeof(ECC_Decrypt_In)),
+ /* outSize */ (UINT16)(sizeof(ECC_Decrypt_Out)),
+ /* offsetOfTypes */ offsetof(ECC_Decrypt_COMMAND_DESCRIPTOR_t, types),
+ /* offsets */ {(UINT16)(offsetof(ECC_Decrypt_In, C1)),
+ (UINT16)(offsetof(ECC_Decrypt_In, C2)),
+ (UINT16)(offsetof(ECC_Decrypt_In, C3)),
+ (UINT16)(offsetof(ECC_Decrypt_In, inScheme))},
+ /* types */ {TPMI_DH_OBJECT_H_UNMARSHAL,
+ TPM2B_ECC_POINT_P_UNMARSHAL,
+ TPM2B_MAX_BUFFER_P_UNMARSHAL,
+ TPM2B_DIGEST_P_UNMARSHAL,
+ TPMT_KDF_SCHEME_P_UNMARSHAL + ADD_FLAG,
+ END_OF_LIST,
+ TPM2B_MAX_BUFFER_P_MARSHAL,
+ END_OF_LIST}
+};
+
+#define _ECC_DecryptDataAddress (&_ECC_DecryptData)
+#else
+#define _ECC_DecryptDataAddress 0
+#endif // CC_ECC_Decrypt
+
+#if CC_ECC_Parameters
+#include "ECC_Parameters_fp.h"
+typedef TPM_RC (ECC_Parameters_Entry)(
+ ECC_Parameters_In *in,
+ ECC_Parameters_Out *out
+ );
+typedef const struct {
+ ECC_Parameters_Entry *entry;
+ UINT16 inSize;
+ UINT16 outSize;
+ UINT16 offsetOfTypes;
+ BYTE types[4];
+} ECC_Parameters_COMMAND_DESCRIPTOR_t;
+ECC_Parameters_COMMAND_DESCRIPTOR_t _ECC_ParametersData = {
+ /* entry */ &TPM2_ECC_Parameters,
+ /* inSize */ (UINT16)(sizeof(ECC_Parameters_In)),
+ /* outSize */ (UINT16)(sizeof(ECC_Parameters_Out)),
+ /* offsetOfTypes */ offsetof(ECC_Parameters_COMMAND_DESCRIPTOR_t, types),
+ /* offsets */ // No parameter offsets
+ /* types */ {TPMI_ECC_CURVE_P_UNMARSHAL,
+ END_OF_LIST,
+ TPMS_ALGORITHM_DETAIL_ECC_P_MARSHAL,
+ END_OF_LIST}
+};
+#define _ECC_ParametersDataAddress (&_ECC_ParametersData)
+#else
+#define _ECC_ParametersDataAddress 0
+#endif
+#if CC_ZGen_2Phase
+#include "ZGen_2Phase_fp.h"
+typedef TPM_RC (ZGen_2Phase_Entry)(
+ ZGen_2Phase_In *in,
+ ZGen_2Phase_Out *out
+ );
+typedef const struct {
+ ZGen_2Phase_Entry *entry;
+ UINT16 inSize;
+ UINT16 outSize;
+ UINT16 offsetOfTypes;
+ UINT16 paramOffsets[5];
+ BYTE types[9];
+} ZGen_2Phase_COMMAND_DESCRIPTOR_t;
+ZGen_2Phase_COMMAND_DESCRIPTOR_t _ZGen_2PhaseData = {
+ /* entry */ &TPM2_ZGen_2Phase,
+ /* inSize */ (UINT16)(sizeof(ZGen_2Phase_In)),
+ /* outSize */ (UINT16)(sizeof(ZGen_2Phase_Out)),
+ /* offsetOfTypes */ offsetof(ZGen_2Phase_COMMAND_DESCRIPTOR_t, types),
+ /* offsets */ {(UINT16)(offsetof(ZGen_2Phase_In, inQsB)),
+ (UINT16)(offsetof(ZGen_2Phase_In, inQeB)),
+ (UINT16)(offsetof(ZGen_2Phase_In, inScheme)),
+ (UINT16)(offsetof(ZGen_2Phase_In, counter)),
+ (UINT16)(offsetof(ZGen_2Phase_Out, outZ2))},
+ /* types */ {TPMI_DH_OBJECT_H_UNMARSHAL,
+ TPM2B_ECC_POINT_P_UNMARSHAL,
+ TPM2B_ECC_POINT_P_UNMARSHAL,
+ TPMI_ECC_KEY_EXCHANGE_P_UNMARSHAL,
+ UINT16_P_UNMARSHAL,
+ END_OF_LIST,
+ TPM2B_ECC_POINT_P_MARSHAL,
+ TPM2B_ECC_POINT_P_MARSHAL,
+ END_OF_LIST}
+};
+#define _ZGen_2PhaseDataAddress (&_ZGen_2PhaseData)
+#else
+#define _ZGen_2PhaseDataAddress 0
+#endif
+#if CC_EncryptDecrypt
+#include "EncryptDecrypt_fp.h"
+typedef TPM_RC (EncryptDecrypt_Entry)(
+ EncryptDecrypt_In *in,
+ EncryptDecrypt_Out *out
+ );
+typedef const struct {
+ EncryptDecrypt_Entry *entry;
+ UINT16 inSize;
+ UINT16 outSize;
+ UINT16 offsetOfTypes;
+ UINT16 paramOffsets[5];
+ BYTE types[9];
+} EncryptDecrypt_COMMAND_DESCRIPTOR_t;
+EncryptDecrypt_COMMAND_DESCRIPTOR_t _EncryptDecryptData = {
+ /* entry */ &TPM2_EncryptDecrypt,
+ /* inSize */ (UINT16)(sizeof(EncryptDecrypt_In)),
+ /* outSize */ (UINT16)(sizeof(EncryptDecrypt_Out)),
+ /* offsetOfTypes */ offsetof(EncryptDecrypt_COMMAND_DESCRIPTOR_t, types),
+ /* offsets */ {(UINT16)(offsetof(EncryptDecrypt_In, decrypt)),
+ (UINT16)(offsetof(EncryptDecrypt_In, mode)),
+ (UINT16)(offsetof(EncryptDecrypt_In, ivIn)),
+ (UINT16)(offsetof(EncryptDecrypt_In, inData)),
+ (UINT16)(offsetof(EncryptDecrypt_Out, ivOut))},
+ /* types */ {TPMI_DH_OBJECT_H_UNMARSHAL,
+ TPMI_YES_NO_P_UNMARSHAL,
+ TPMI_ALG_CIPHER_MODE_P_UNMARSHAL + ADD_FLAG,
+ TPM2B_IV_P_UNMARSHAL,
+ TPM2B_MAX_BUFFER_P_UNMARSHAL,
+ END_OF_LIST,
+ TPM2B_MAX_BUFFER_P_MARSHAL,
+ TPM2B_IV_P_MARSHAL,
+ END_OF_LIST}
+};
+#define _EncryptDecryptDataAddress (&_EncryptDecryptData)
+#else
+#define _EncryptDecryptDataAddress 0
+#endif
+#if CC_EncryptDecrypt2
+#include "EncryptDecrypt2_fp.h"
+typedef TPM_RC (EncryptDecrypt2_Entry)(
+ EncryptDecrypt2_In *in,
+ EncryptDecrypt2_Out *out
+ );
+typedef const struct {
+ EncryptDecrypt2_Entry *entry;
+ UINT16 inSize;
+ UINT16 outSize;
+ UINT16 offsetOfTypes;
+ UINT16 paramOffsets[5];
+ BYTE types[9];
+} EncryptDecrypt2_COMMAND_DESCRIPTOR_t;
+EncryptDecrypt2_COMMAND_DESCRIPTOR_t _EncryptDecrypt2Data = {
+ /* entry */ &TPM2_EncryptDecrypt2,
+ /* inSize */ (UINT16)(sizeof(EncryptDecrypt2_In)),
+ /* outSize */ (UINT16)(sizeof(EncryptDecrypt2_Out)),
+ /* offsetOfTypes */ offsetof(EncryptDecrypt2_COMMAND_DESCRIPTOR_t, types),
+ /* offsets */ {(UINT16)(offsetof(EncryptDecrypt2_In, inData)),
+ (UINT16)(offsetof(EncryptDecrypt2_In, decrypt)),
+ (UINT16)(offsetof(EncryptDecrypt2_In, mode)),
+ (UINT16)(offsetof(EncryptDecrypt2_In, ivIn)),
+ (UINT16)(offsetof(EncryptDecrypt2_Out, ivOut))},
+ /* types */ {TPMI_DH_OBJECT_H_UNMARSHAL,
+ TPM2B_MAX_BUFFER_P_UNMARSHAL,
+ TPMI_YES_NO_P_UNMARSHAL,
+ TPMI_ALG_CIPHER_MODE_P_UNMARSHAL + ADD_FLAG,
+ TPM2B_IV_P_UNMARSHAL,
+ END_OF_LIST,
+ TPM2B_MAX_BUFFER_P_MARSHAL,
+ TPM2B_IV_P_MARSHAL,
+ END_OF_LIST}
+};
+#define _EncryptDecrypt2DataAddress (&_EncryptDecrypt2Data)
+#else
+#define _EncryptDecrypt2DataAddress 0
+#endif
+#if CC_Hash
+#include "Hash_fp.h"
+typedef TPM_RC (Hash_Entry)(
+ Hash_In *in,
+ Hash_Out *out
+ );
+typedef const struct {
+ Hash_Entry *entry;
+ UINT16 inSize;
+ UINT16 outSize;
+ UINT16 offsetOfTypes;
+ UINT16 paramOffsets[3];
+ BYTE types[7];
+} Hash_COMMAND_DESCRIPTOR_t;
+Hash_COMMAND_DESCRIPTOR_t _HashData = {
+ /* entry */ &TPM2_Hash,
+ /* inSize */ (UINT16)(sizeof(Hash_In)),
+ /* outSize */ (UINT16)(sizeof(Hash_Out)),
+ /* offsetOfTypes */ offsetof(Hash_COMMAND_DESCRIPTOR_t, types),
+ /* offsets */ {(UINT16)(offsetof(Hash_In, hashAlg)),
+ (UINT16)(offsetof(Hash_In, hierarchy)),
+ (UINT16)(offsetof(Hash_Out, validation))},
+ /* types */ {TPM2B_MAX_BUFFER_P_UNMARSHAL,
+ TPMI_ALG_HASH_P_UNMARSHAL,
+ TPMI_RH_HIERARCHY_P_UNMARSHAL + ADD_FLAG,
+ END_OF_LIST,
+ TPM2B_DIGEST_P_MARSHAL,
+ TPMT_TK_HASHCHECK_P_MARSHAL,
+ END_OF_LIST}
+};
+#define _HashDataAddress (&_HashData)
+#else
+#define _HashDataAddress 0
+#endif
+#if CC_HMAC
+#include "HMAC_fp.h"
+typedef TPM_RC (HMAC_Entry)(
+ HMAC_In *in,
+ HMAC_Out *out
+ );
+typedef const struct {
+ HMAC_Entry *entry;
+ UINT16 inSize;
+ UINT16 outSize;
+ UINT16 offsetOfTypes;
+ UINT16 paramOffsets[2];
+ BYTE types[6];
+} HMAC_COMMAND_DESCRIPTOR_t;
+HMAC_COMMAND_DESCRIPTOR_t _HMACData = {
+ /* entry */ &TPM2_HMAC,
+ /* inSize */ (UINT16)(sizeof(HMAC_In)),
+ /* outSize */ (UINT16)(sizeof(HMAC_Out)),
+ /* offsetOfTypes */ offsetof(HMAC_COMMAND_DESCRIPTOR_t, types),
+ /* offsets */ {(UINT16)(offsetof(HMAC_In, buffer)),
+ (UINT16)(offsetof(HMAC_In, hashAlg))},
+ /* types */ {TPMI_DH_OBJECT_H_UNMARSHAL,
+ TPM2B_MAX_BUFFER_P_UNMARSHAL,
+ TPMI_ALG_HASH_P_UNMARSHAL + ADD_FLAG,
+ END_OF_LIST,
+ TPM2B_DIGEST_P_MARSHAL,
+ END_OF_LIST}
+};
+#define _HMACDataAddress (&_HMACData)
+#else
+#define _HMACDataAddress 0
+#endif
+#if CC_MAC
+#include "MAC_fp.h"
+typedef TPM_RC (MAC_Entry)(
+ MAC_In *in,
+ MAC_Out *out
+ );
+typedef const struct {
+ MAC_Entry *entry;
+ UINT16 inSize;
+ UINT16 outSize;
+ UINT16 offsetOfTypes;
+ UINT16 paramOffsets[2];
+ BYTE types[6];
+} MAC_COMMAND_DESCRIPTOR_t;
+MAC_COMMAND_DESCRIPTOR_t _MACData = {
+ /* entry */ &TPM2_MAC,
+ /* inSize */ (UINT16)(sizeof(MAC_In)),
+ /* outSize */ (UINT16)(sizeof(MAC_Out)),
+ /* offsetOfTypes */ offsetof(MAC_COMMAND_DESCRIPTOR_t, types),
+ /* offsets */ {(UINT16)(offsetof(MAC_In, buffer)),
+ (UINT16)(offsetof(MAC_In, inScheme))},
+ /* types */ {TPMI_DH_OBJECT_H_UNMARSHAL,
+ TPM2B_MAX_BUFFER_P_UNMARSHAL,
+ TPMI_ALG_MAC_SCHEME_P_UNMARSHAL + ADD_FLAG,
+ END_OF_LIST,
+ TPM2B_DIGEST_P_MARSHAL,
+ END_OF_LIST}
+};
+#define _MACDataAddress (&_MACData)
+#else
+#define _MACDataAddress 0
+#endif
+#if CC_GetRandom
+#include "GetRandom_fp.h"
+typedef TPM_RC (GetRandom_Entry)(
+ GetRandom_In *in,
+ GetRandom_Out *out
+ );
+typedef const struct {
+ GetRandom_Entry *entry;
+ UINT16 inSize;
+ UINT16 outSize;
+ UINT16 offsetOfTypes;
+ BYTE types[4];
+} GetRandom_COMMAND_DESCRIPTOR_t;
+GetRandom_COMMAND_DESCRIPTOR_t _GetRandomData = {
+ /* entry */ &TPM2_GetRandom,
+ /* inSize */ (UINT16)(sizeof(GetRandom_In)),
+ /* outSize */ (UINT16)(sizeof(GetRandom_Out)),
+ /* offsetOfTypes */ offsetof(GetRandom_COMMAND_DESCRIPTOR_t, types),
+ /* offsets */ // No parameter offsets
+ /* types */ {UINT16_P_UNMARSHAL,
+ END_OF_LIST,
+ TPM2B_DIGEST_P_MARSHAL,
+ END_OF_LIST}
+};
+#define _GetRandomDataAddress (&_GetRandomData)
+#else
+#define _GetRandomDataAddress 0
+#endif
+#if CC_StirRandom
+#include "StirRandom_fp.h"
+typedef TPM_RC (StirRandom_Entry)(
+ StirRandom_In *in
+ );
+typedef const struct {
+ StirRandom_Entry *entry;
+ UINT16 inSize;
+ UINT16 outSize;
+ UINT16 offsetOfTypes;
+ BYTE types[3];
+} StirRandom_COMMAND_DESCRIPTOR_t;
+StirRandom_COMMAND_DESCRIPTOR_t _StirRandomData = {
+ /* entry */ &TPM2_StirRandom,
+ /* inSize */ (UINT16)(sizeof(StirRandom_In)),
+ /* outSize */ 0,
+ /* offsetOfTypes */ offsetof(StirRandom_COMMAND_DESCRIPTOR_t, types),
+ /* offsets */ // No parameter offsets
+ /* types */ {TPM2B_SENSITIVE_DATA_P_UNMARSHAL,
+ END_OF_LIST,
+ END_OF_LIST}
+};
+#define _StirRandomDataAddress (&_StirRandomData)
+#else
+#define _StirRandomDataAddress 0
+#endif
+#if CC_HMAC_Start
+#include "HMAC_Start_fp.h"
+typedef TPM_RC (HMAC_Start_Entry)(
+ HMAC_Start_In *in,
+ HMAC_Start_Out *out
+ );
+typedef const struct {
+ HMAC_Start_Entry *entry;
+ UINT16 inSize;
+ UINT16 outSize;
+ UINT16 offsetOfTypes;
+ UINT16 paramOffsets[2];
+ BYTE types[6];
+} HMAC_Start_COMMAND_DESCRIPTOR_t;
+HMAC_Start_COMMAND_DESCRIPTOR_t _HMAC_StartData = {
+ /* entry */ &TPM2_HMAC_Start,
+ /* inSize */ (UINT16)(sizeof(HMAC_Start_In)),
+ /* outSize */ (UINT16)(sizeof(HMAC_Start_Out)),
+ /* offsetOfTypes */ offsetof(HMAC_Start_COMMAND_DESCRIPTOR_t, types),
+ /* offsets */ {(UINT16)(offsetof(HMAC_Start_In, auth)),
+ (UINT16)(offsetof(HMAC_Start_In, hashAlg))},
+ /* types */ {TPMI_DH_OBJECT_H_UNMARSHAL,
+ TPM2B_AUTH_P_UNMARSHAL,
+ TPMI_ALG_HASH_P_UNMARSHAL + ADD_FLAG,
+ END_OF_LIST,
+ TPMI_DH_OBJECT_H_MARSHAL,
+ END_OF_LIST}
+};
+#define _HMAC_StartDataAddress (&_HMAC_StartData)
+#else
+#define _HMAC_StartDataAddress 0
+#endif
+#if CC_MAC_Start
+#include "MAC_Start_fp.h"
+typedef TPM_RC (MAC_Start_Entry)(
+ MAC_Start_In *in,
+ MAC_Start_Out *out
+ );
+typedef const struct {
+ MAC_Start_Entry *entry;
+ UINT16 inSize;
+ UINT16 outSize;
+ UINT16 offsetOfTypes;
+ UINT16 paramOffsets[2];
+ BYTE types[6];
+} MAC_Start_COMMAND_DESCRIPTOR_t;
+MAC_Start_COMMAND_DESCRIPTOR_t _MAC_StartData = {
+ /* entry */ &TPM2_MAC_Start,
+ /* inSize */ (UINT16)(sizeof(MAC_Start_In)),
+ /* outSize */ (UINT16)(sizeof(MAC_Start_Out)),
+ /* offsetOfTypes */ offsetof(MAC_Start_COMMAND_DESCRIPTOR_t, types),
+ /* offsets */ {(UINT16)(offsetof(MAC_Start_In, auth)),
+ (UINT16)(offsetof(MAC_Start_In, inScheme))},
+ /* types */ {TPMI_DH_OBJECT_H_UNMARSHAL,
+ TPM2B_AUTH_P_UNMARSHAL,
+ TPMI_ALG_MAC_SCHEME_P_UNMARSHAL + ADD_FLAG,
+ END_OF_LIST,
+ TPMI_DH_OBJECT_H_MARSHAL,
+ END_OF_LIST}
+};
+#define _MAC_StartDataAddress (&_MAC_StartData)
+#else
+#define _MAC_StartDataAddress 0
+#endif
+#if CC_HashSequenceStart
+#include "HashSequenceStart_fp.h"
+typedef TPM_RC (HashSequenceStart_Entry)(
+ HashSequenceStart_In *in,
+ HashSequenceStart_Out *out
+ );
+typedef const struct {
+ HashSequenceStart_Entry *entry;
+ UINT16 inSize;
+ UINT16 outSize;
+ UINT16 offsetOfTypes;
+ UINT16 paramOffsets[1];
+ BYTE types[5];
+} HashSequenceStart_COMMAND_DESCRIPTOR_t;
+HashSequenceStart_COMMAND_DESCRIPTOR_t _HashSequenceStartData = {
+ /* entry */ &TPM2_HashSequenceStart,
+ /* inSize */ (UINT16)(sizeof(HashSequenceStart_In)),
+ /* outSize */ (UINT16)(sizeof(HashSequenceStart_Out)),
+ /* offsetOfTypes */ offsetof(HashSequenceStart_COMMAND_DESCRIPTOR_t, types),
+ /* offsets */ {(UINT16)(offsetof(HashSequenceStart_In, hashAlg))},
+ /* types */ {TPM2B_AUTH_P_UNMARSHAL,
+ TPMI_ALG_HASH_P_UNMARSHAL + ADD_FLAG,
+ END_OF_LIST,
+ TPMI_DH_OBJECT_H_MARSHAL,
+ END_OF_LIST}
+};
+#define _HashSequenceStartDataAddress (&_HashSequenceStartData)
+#else
+#define _HashSequenceStartDataAddress 0
+#endif
+#if CC_SequenceUpdate
+#include "SequenceUpdate_fp.h"
+typedef TPM_RC (SequenceUpdate_Entry)(
+ SequenceUpdate_In *in
+ );
+typedef const struct {
+ SequenceUpdate_Entry *entry;
+ UINT16 inSize;
+ UINT16 outSize;
+ UINT16 offsetOfTypes;
+ UINT16 paramOffsets[1];
+ BYTE types[4];
+} SequenceUpdate_COMMAND_DESCRIPTOR_t;
+SequenceUpdate_COMMAND_DESCRIPTOR_t _SequenceUpdateData = {
+ /* entry */ &TPM2_SequenceUpdate,
+ /* inSize */ (UINT16)(sizeof(SequenceUpdate_In)),
+ /* outSize */ 0,
+ /* offsetOfTypes */ offsetof(SequenceUpdate_COMMAND_DESCRIPTOR_t, types),
+ /* offsets */ {(UINT16)(offsetof(SequenceUpdate_In, buffer))},
+ /* types */ {TPMI_DH_OBJECT_H_UNMARSHAL,
+ TPM2B_MAX_BUFFER_P_UNMARSHAL,
+ END_OF_LIST,
+ END_OF_LIST}
+};
+#define _SequenceUpdateDataAddress (&_SequenceUpdateData)
+#else
+#define _SequenceUpdateDataAddress 0
+#endif
+#if CC_SequenceComplete
+#include "SequenceComplete_fp.h"
+typedef TPM_RC (SequenceComplete_Entry)(
+ SequenceComplete_In *in,
+ SequenceComplete_Out *out
+ );
+typedef const struct {
+ SequenceComplete_Entry *entry;
+ UINT16 inSize;
+ UINT16 outSize;
+ UINT16 offsetOfTypes;
+ UINT16 paramOffsets[3];
+ BYTE types[7];
+} SequenceComplete_COMMAND_DESCRIPTOR_t;
+SequenceComplete_COMMAND_DESCRIPTOR_t _SequenceCompleteData = {
+ /* entry */ &TPM2_SequenceComplete,
+ /* inSize */ (UINT16)(sizeof(SequenceComplete_In)),
+ /* outSize */ (UINT16)(sizeof(SequenceComplete_Out)),
+ /* offsetOfTypes */ offsetof(SequenceComplete_COMMAND_DESCRIPTOR_t, types),
+ /* offsets */ {(UINT16)(offsetof(SequenceComplete_In, buffer)),
+ (UINT16)(offsetof(SequenceComplete_In, hierarchy)),
+ (UINT16)(offsetof(SequenceComplete_Out, validation))},
+ /* types */ {TPMI_DH_OBJECT_H_UNMARSHAL,
+ TPM2B_MAX_BUFFER_P_UNMARSHAL,
+ TPMI_RH_HIERARCHY_P_UNMARSHAL + ADD_FLAG,
+ END_OF_LIST,
+ TPM2B_DIGEST_P_MARSHAL,
+ TPMT_TK_HASHCHECK_P_MARSHAL,
+ END_OF_LIST}
+};
+#define _SequenceCompleteDataAddress (&_SequenceCompleteData)
+#else
+#define _SequenceCompleteDataAddress 0
+#endif
+#if CC_EventSequenceComplete
+#include "EventSequenceComplete_fp.h"
+typedef TPM_RC (EventSequenceComplete_Entry)(
+ EventSequenceComplete_In *in,
+ EventSequenceComplete_Out *out
+ );
+typedef const struct {
+ EventSequenceComplete_Entry *entry;
+ UINT16 inSize;
+ UINT16 outSize;
+ UINT16 offsetOfTypes;
+ UINT16 paramOffsets[2];
+ BYTE types[6];
+} EventSequenceComplete_COMMAND_DESCRIPTOR_t;
+EventSequenceComplete_COMMAND_DESCRIPTOR_t _EventSequenceCompleteData = {
+ /* entry */ &TPM2_EventSequenceComplete,
+ /* inSize */ (UINT16)(sizeof(EventSequenceComplete_In)),
+ /* outSize */ (UINT16)(sizeof(EventSequenceComplete_Out)),
+ /* offsetOfTypes */ offsetof(EventSequenceComplete_COMMAND_DESCRIPTOR_t, types),
+ /* offsets */ {(UINT16)(offsetof(EventSequenceComplete_In, sequenceHandle)),
+ (UINT16)(offsetof(EventSequenceComplete_In, buffer))},
+ /* types */ {TPMI_DH_PCR_H_UNMARSHAL + ADD_FLAG,
+ TPMI_DH_OBJECT_H_UNMARSHAL,
+ TPM2B_MAX_BUFFER_P_UNMARSHAL,
+ END_OF_LIST,
+ TPML_DIGEST_VALUES_P_MARSHAL,
+ END_OF_LIST}
+};
+#define _EventSequenceCompleteDataAddress (&_EventSequenceCompleteData)
+#else
+#define _EventSequenceCompleteDataAddress 0
+#endif
+#if CC_Certify
+#include "Certify_fp.h"
+typedef TPM_RC (Certify_Entry)(
+ Certify_In *in,
+ Certify_Out *out
+ );
+typedef const struct {
+ Certify_Entry *entry;
+ UINT16 inSize;
+ UINT16 outSize;
+ UINT16 offsetOfTypes;
+ UINT16 paramOffsets[4];
+ BYTE types[8];
+} Certify_COMMAND_DESCRIPTOR_t;
+Certify_COMMAND_DESCRIPTOR_t _CertifyData = {
+ /* entry */ &TPM2_Certify,
+ /* inSize */ (UINT16)(sizeof(Certify_In)),
+ /* outSize */ (UINT16)(sizeof(Certify_Out)),
+ /* offsetOfTypes */ offsetof(Certify_COMMAND_DESCRIPTOR_t, types),
+ /* offsets */ {(UINT16)(offsetof(Certify_In, signHandle)),
+ (UINT16)(offsetof(Certify_In, qualifyingData)),
+ (UINT16)(offsetof(Certify_In, inScheme)),
+ (UINT16)(offsetof(Certify_Out, signature))},
+ /* types */ {TPMI_DH_OBJECT_H_UNMARSHAL,
+ TPMI_DH_OBJECT_H_UNMARSHAL + ADD_FLAG,
+ TPM2B_DATA_P_UNMARSHAL,
+ TPMT_SIG_SCHEME_P_UNMARSHAL + ADD_FLAG,
+ END_OF_LIST,
+ TPM2B_ATTEST_P_MARSHAL,
+ TPMT_SIGNATURE_P_MARSHAL,
+ END_OF_LIST}
+};
+#define _CertifyDataAddress (&_CertifyData)
+#else
+#define _CertifyDataAddress 0
+#endif
+#if CC_CertifyCreation
+#include "CertifyCreation_fp.h"
+typedef TPM_RC (CertifyCreation_Entry)(
+ CertifyCreation_In *in,
+ CertifyCreation_Out *out
+ );
+typedef const struct {
+ CertifyCreation_Entry *entry;
+ UINT16 inSize;
+ UINT16 outSize;
+ UINT16 offsetOfTypes;
+ UINT16 paramOffsets[6];
+ BYTE types[10];
+} CertifyCreation_COMMAND_DESCRIPTOR_t;
+CertifyCreation_COMMAND_DESCRIPTOR_t _CertifyCreationData = {
+ /* entry */ &TPM2_CertifyCreation,
+ /* inSize */ (UINT16)(sizeof(CertifyCreation_In)),
+ /* outSize */ (UINT16)(sizeof(CertifyCreation_Out)),
+ /* offsetOfTypes */ offsetof(CertifyCreation_COMMAND_DESCRIPTOR_t, types),
+ /* offsets */ {(UINT16)(offsetof(CertifyCreation_In, objectHandle)),
+ (UINT16)(offsetof(CertifyCreation_In, qualifyingData)),
+ (UINT16)(offsetof(CertifyCreation_In, creationHash)),
+ (UINT16)(offsetof(CertifyCreation_In, inScheme)),
+ (UINT16)(offsetof(CertifyCreation_In, creationTicket)),
+ (UINT16)(offsetof(CertifyCreation_Out, signature))},
+ /* types */ {TPMI_DH_OBJECT_H_UNMARSHAL + ADD_FLAG,
+ TPMI_DH_OBJECT_H_UNMARSHAL,
+ TPM2B_DATA_P_UNMARSHAL,
+ TPM2B_DIGEST_P_UNMARSHAL,
+ TPMT_SIG_SCHEME_P_UNMARSHAL + ADD_FLAG,
+ TPMT_TK_CREATION_P_UNMARSHAL,
+ END_OF_LIST,
+ TPM2B_ATTEST_P_MARSHAL,
+ TPMT_SIGNATURE_P_MARSHAL,
+ END_OF_LIST}
+};
+#define _CertifyCreationDataAddress (&_CertifyCreationData)
+#else
+#define _CertifyCreationDataAddress 0
+#endif
+#if CC_Quote
+#include "Quote_fp.h"
+typedef TPM_RC (Quote_Entry)(
+ Quote_In *in,
+ Quote_Out *out
+ );
+typedef const struct {
+ Quote_Entry *entry;
+ UINT16 inSize;
+ UINT16 outSize;
+ UINT16 offsetOfTypes;
+ UINT16 paramOffsets[4];
+ BYTE types[8];
+} Quote_COMMAND_DESCRIPTOR_t;
+Quote_COMMAND_DESCRIPTOR_t _QuoteData = {
+ /* entry */ &TPM2_Quote,
+ /* inSize */ (UINT16)(sizeof(Quote_In)),
+ /* outSize */ (UINT16)(sizeof(Quote_Out)),
+ /* offsetOfTypes */ offsetof(Quote_COMMAND_DESCRIPTOR_t, types),
+ /* offsets */ {(UINT16)(offsetof(Quote_In, qualifyingData)),
+ (UINT16)(offsetof(Quote_In, inScheme)),
+ (UINT16)(offsetof(Quote_In, PCRselect)),
+ (UINT16)(offsetof(Quote_Out, signature))},
+ /* types */ {TPMI_DH_OBJECT_H_UNMARSHAL + ADD_FLAG,
+ TPM2B_DATA_P_UNMARSHAL,
+ TPMT_SIG_SCHEME_P_UNMARSHAL + ADD_FLAG,
+ TPML_PCR_SELECTION_P_UNMARSHAL,
+ END_OF_LIST,
+ TPM2B_ATTEST_P_MARSHAL,
+ TPMT_SIGNATURE_P_MARSHAL,
+ END_OF_LIST}
+};
+#define _QuoteDataAddress (&_QuoteData)
+#else
+#define _QuoteDataAddress 0
+#endif
+#if CC_GetSessionAuditDigest
+#include "GetSessionAuditDigest_fp.h"
+typedef TPM_RC (GetSessionAuditDigest_Entry)(
+ GetSessionAuditDigest_In *in,
+ GetSessionAuditDigest_Out *out
+ );
+typedef const struct {
+ GetSessionAuditDigest_Entry *entry;
+ UINT16 inSize;
+ UINT16 outSize;
+ UINT16 offsetOfTypes;
+ UINT16 paramOffsets[5];
+ BYTE types[9];
+} GetSessionAuditDigest_COMMAND_DESCRIPTOR_t;
+GetSessionAuditDigest_COMMAND_DESCRIPTOR_t _GetSessionAuditDigestData = {
+ /* entry */ &TPM2_GetSessionAuditDigest,
+ /* inSize */ (UINT16)(sizeof(GetSessionAuditDigest_In)),
+ /* outSize */ (UINT16)(sizeof(GetSessionAuditDigest_Out)),
+ /* offsetOfTypes */ offsetof(GetSessionAuditDigest_COMMAND_DESCRIPTOR_t, types),
+ /* offsets */ {(UINT16)(offsetof(GetSessionAuditDigest_In, signHandle)),
+ (UINT16)(offsetof(GetSessionAuditDigest_In, sessionHandle)),
+ (UINT16)(offsetof(GetSessionAuditDigest_In, qualifyingData)),
+ (UINT16)(offsetof(GetSessionAuditDigest_In, inScheme)),
+ (UINT16)(offsetof(GetSessionAuditDigest_Out, signature))},
+ /* types */ {TPMI_RH_ENDORSEMENT_H_UNMARSHAL,
+ TPMI_DH_OBJECT_H_UNMARSHAL + ADD_FLAG,
+ TPMI_SH_HMAC_H_UNMARSHAL,
+ TPM2B_DATA_P_UNMARSHAL,
+ TPMT_SIG_SCHEME_P_UNMARSHAL + ADD_FLAG,
+ END_OF_LIST,
+ TPM2B_ATTEST_P_MARSHAL,
+ TPMT_SIGNATURE_P_MARSHAL,
+ END_OF_LIST}
+};
+#define _GetSessionAuditDigestDataAddress (&_GetSessionAuditDigestData)
+#else
+#define _GetSessionAuditDigestDataAddress 0
+#endif
+#if CC_GetCommandAuditDigest
+#include "GetCommandAuditDigest_fp.h"
+typedef TPM_RC (GetCommandAuditDigest_Entry)(
+ GetCommandAuditDigest_In *in,
+ GetCommandAuditDigest_Out *out
+ );
+typedef const struct {
+ GetCommandAuditDigest_Entry *entry;
+ UINT16 inSize;
+ UINT16 outSize;
+ UINT16 offsetOfTypes;
+ UINT16 paramOffsets[4];
+ BYTE types[8];
+} GetCommandAuditDigest_COMMAND_DESCRIPTOR_t;
+GetCommandAuditDigest_COMMAND_DESCRIPTOR_t _GetCommandAuditDigestData = {
+ /* entry */ &TPM2_GetCommandAuditDigest,
+ /* inSize */ (UINT16)(sizeof(GetCommandAuditDigest_In)),
+ /* outSize */ (UINT16)(sizeof(GetCommandAuditDigest_Out)),
+ /* offsetOfTypes */ offsetof(GetCommandAuditDigest_COMMAND_DESCRIPTOR_t, types),
+ /* offsets */ {(UINT16)(offsetof(GetCommandAuditDigest_In, signHandle)),
+ (UINT16)(offsetof(GetCommandAuditDigest_In, qualifyingData)),
+ (UINT16)(offsetof(GetCommandAuditDigest_In, inScheme)),
+ (UINT16)(offsetof(GetCommandAuditDigest_Out, signature))},
+ /* types */ {TPMI_RH_ENDORSEMENT_H_UNMARSHAL,
+ TPMI_DH_OBJECT_H_UNMARSHAL + ADD_FLAG,
+ TPM2B_DATA_P_UNMARSHAL,
+ TPMT_SIG_SCHEME_P_UNMARSHAL + ADD_FLAG,
+ END_OF_LIST,
+ TPM2B_ATTEST_P_MARSHAL,
+ TPMT_SIGNATURE_P_MARSHAL,
+ END_OF_LIST}
+};
+#define _GetCommandAuditDigestDataAddress (&_GetCommandAuditDigestData)
+#else
+#define _GetCommandAuditDigestDataAddress 0
+#endif
+#if CC_GetTime
+#include "GetTime_fp.h"
+typedef TPM_RC (GetTime_Entry)(
+ GetTime_In *in,
+ GetTime_Out *out
+ );
+typedef const struct {
+ GetTime_Entry *entry;
+ UINT16 inSize;
+ UINT16 outSize;
+ UINT16 offsetOfTypes;
+ UINT16 paramOffsets[4];
+ BYTE types[8];
+} GetTime_COMMAND_DESCRIPTOR_t;
+GetTime_COMMAND_DESCRIPTOR_t _GetTimeData = {
+ /* entry */ &TPM2_GetTime,
+ /* inSize */ (UINT16)(sizeof(GetTime_In)),
+ /* outSize */ (UINT16)(sizeof(GetTime_Out)),
+ /* offsetOfTypes */ offsetof(GetTime_COMMAND_DESCRIPTOR_t, types),
+ /* offsets */ {(UINT16)(offsetof(GetTime_In, signHandle)),
+ (UINT16)(offsetof(GetTime_In, qualifyingData)),
+ (UINT16)(offsetof(GetTime_In, inScheme)),
+ (UINT16)(offsetof(GetTime_Out, signature))},
+ /* types */ {TPMI_RH_ENDORSEMENT_H_UNMARSHAL,
+ TPMI_DH_OBJECT_H_UNMARSHAL + ADD_FLAG,
+ TPM2B_DATA_P_UNMARSHAL,
+ TPMT_SIG_SCHEME_P_UNMARSHAL + ADD_FLAG,
+ END_OF_LIST,
+ TPM2B_ATTEST_P_MARSHAL,
+ TPMT_SIGNATURE_P_MARSHAL,
+ END_OF_LIST}
+};
+#define _GetTimeDataAddress (&_GetTimeData)
+#else
+#define _GetTimeDataAddress 0
+#endif
+#if CC_CertifyX509
+#include "CertifyX509_fp.h"
+typedef TPM_RC (CertifyX509_Entry)(
+ CertifyX509_In *in,
+ CertifyX509_Out *out
+ );
+typedef const struct {
+ CertifyX509_Entry *entry;
+ UINT16 inSize;
+ UINT16 outSize;
+ UINT16 offsetOfTypes;
+ UINT16 paramOffsets[6];
+ BYTE types[10];
+} CertifyX509_COMMAND_DESCRIPTOR_t;
+CertifyX509_COMMAND_DESCRIPTOR_t _CertifyX509Data = {
+ /* entry */ &TPM2_CertifyX509,
+ /* inSize */ (UINT16)(sizeof(CertifyX509_In)),
+ /* outSize */ (UINT16)(sizeof(CertifyX509_Out)),
+ /* offsetOfTypes */ offsetof(CertifyX509_COMMAND_DESCRIPTOR_t, types),
+ /* offsets */ {(UINT16)(offsetof(CertifyX509_In, signHandle)),
+ (UINT16)(offsetof(CertifyX509_In, reserved)),
+ (UINT16)(offsetof(CertifyX509_In, inScheme)),
+ (UINT16)(offsetof(CertifyX509_In, partialCertificate)),
+ (UINT16)(offsetof(CertifyX509_Out, tbsDigest)),
+ (UINT16)(offsetof(CertifyX509_Out, signature))},
+ /* types */ {TPMI_DH_OBJECT_H_UNMARSHAL,
+ TPMI_DH_OBJECT_H_UNMARSHAL + ADD_FLAG,
+ TPM2B_DATA_P_UNMARSHAL,
+ TPMT_SIG_SCHEME_P_UNMARSHAL + ADD_FLAG,
+ TPM2B_MAX_BUFFER_P_UNMARSHAL,
+ END_OF_LIST,
+ TPM2B_MAX_BUFFER_P_MARSHAL,
+ TPM2B_DIGEST_P_MARSHAL,
+ TPMT_SIGNATURE_P_MARSHAL,
+ END_OF_LIST}
+};
+#define _CertifyX509DataAddress (&_CertifyX509Data)
+#else
+#define _CertifyX509DataAddress 0
+#endif // CC_CertifyX509
+#if CC_Commit
+#include "Commit_fp.h"
+typedef TPM_RC (Commit_Entry)(
+ Commit_In *in,
+ Commit_Out *out
+ );
+typedef const struct {
+ Commit_Entry *entry;
+ UINT16 inSize;
+ UINT16 outSize;
+ UINT16 offsetOfTypes;
+ UINT16 paramOffsets[6];
+ BYTE types[10];
+} Commit_COMMAND_DESCRIPTOR_t;
+Commit_COMMAND_DESCRIPTOR_t _CommitData = {
+ /* entry */ &TPM2_Commit,
+ /* inSize */ (UINT16)(sizeof(Commit_In)),
+ /* outSize */ (UINT16)(sizeof(Commit_Out)),
+ /* offsetOfTypes */ offsetof(Commit_COMMAND_DESCRIPTOR_t, types),
+ /* offsets */ {(UINT16)(offsetof(Commit_In, P1)),
+ (UINT16)(offsetof(Commit_In, s2)),
+ (UINT16)(offsetof(Commit_In, y2)),
+ (UINT16)(offsetof(Commit_Out, L)),
+ (UINT16)(offsetof(Commit_Out, E)),
+ (UINT16)(offsetof(Commit_Out, counter))},
+ /* types */ {TPMI_DH_OBJECT_H_UNMARSHAL,
+ TPM2B_ECC_POINT_P_UNMARSHAL,
+ TPM2B_SENSITIVE_DATA_P_UNMARSHAL,
+ TPM2B_ECC_PARAMETER_P_UNMARSHAL,
+ END_OF_LIST,
+ TPM2B_ECC_POINT_P_MARSHAL,
+ TPM2B_ECC_POINT_P_MARSHAL,
+ TPM2B_ECC_POINT_P_MARSHAL,
+ UINT16_P_MARSHAL,
+ END_OF_LIST}
+};
+#define _CommitDataAddress (&_CommitData)
+#else
+#define _CommitDataAddress 0
+#endif
+#if CC_EC_Ephemeral
+#include "EC_Ephemeral_fp.h"
+typedef TPM_RC (EC_Ephemeral_Entry)(
+ EC_Ephemeral_In *in,
+ EC_Ephemeral_Out *out
+ );
+typedef const struct {
+ EC_Ephemeral_Entry *entry;
+ UINT16 inSize;
+ UINT16 outSize;
+ UINT16 offsetOfTypes;
+ UINT16 paramOffsets[1];
+ BYTE types[5];
+} EC_Ephemeral_COMMAND_DESCRIPTOR_t;
+EC_Ephemeral_COMMAND_DESCRIPTOR_t _EC_EphemeralData = {
+ /* entry */ &TPM2_EC_Ephemeral,
+ /* inSize */ (UINT16)(sizeof(EC_Ephemeral_In)),
+ /* outSize */ (UINT16)(sizeof(EC_Ephemeral_Out)),
+ /* offsetOfTypes */ offsetof(EC_Ephemeral_COMMAND_DESCRIPTOR_t, types),
+ /* offsets */ {(UINT16)(offsetof(EC_Ephemeral_Out, counter))},
+ /* types */ {TPMI_ECC_CURVE_P_UNMARSHAL,
+ END_OF_LIST,
+ TPM2B_ECC_POINT_P_MARSHAL,
+ UINT16_P_MARSHAL,
+ END_OF_LIST}
+};
+#define _EC_EphemeralDataAddress (&_EC_EphemeralData)
+#else
+#define _EC_EphemeralDataAddress 0
+#endif
+#if CC_VerifySignature
+#include "VerifySignature_fp.h"
+typedef TPM_RC (VerifySignature_Entry)(
+ VerifySignature_In *in,
+ VerifySignature_Out *out
+ );
+typedef const struct {
+ VerifySignature_Entry *entry;
+ UINT16 inSize;
+ UINT16 outSize;
+ UINT16 offsetOfTypes;
+ UINT16 paramOffsets[2];
+ BYTE types[6];
+} VerifySignature_COMMAND_DESCRIPTOR_t;
+VerifySignature_COMMAND_DESCRIPTOR_t _VerifySignatureData = {
+ /* entry */ &TPM2_VerifySignature,
+ /* inSize */ (UINT16)(sizeof(VerifySignature_In)),
+ /* outSize */ (UINT16)(sizeof(VerifySignature_Out)),
+ /* offsetOfTypes */ offsetof(VerifySignature_COMMAND_DESCRIPTOR_t, types),
+ /* offsets */ {(UINT16)(offsetof(VerifySignature_In, digest)),
+ (UINT16)(offsetof(VerifySignature_In, signature))},
+ /* types */ {TPMI_DH_OBJECT_H_UNMARSHAL,
+ TPM2B_DIGEST_P_UNMARSHAL,
+ TPMT_SIGNATURE_P_UNMARSHAL,
+ END_OF_LIST,
+ TPMT_TK_VERIFIED_P_MARSHAL,
+ END_OF_LIST}
+};
+#define _VerifySignatureDataAddress (&_VerifySignatureData)
+#else
+#define _VerifySignatureDataAddress 0
+#endif
+#if CC_Sign
+#include "Sign_fp.h"
+typedef TPM_RC (Sign_Entry)(
+ Sign_In *in,
+ Sign_Out *out
+ );
+typedef const struct {
+ Sign_Entry *entry;
+ UINT16 inSize;
+ UINT16 outSize;
+ UINT16 offsetOfTypes;
+ UINT16 paramOffsets[3];
+ BYTE types[7];
+} Sign_COMMAND_DESCRIPTOR_t;
+Sign_COMMAND_DESCRIPTOR_t _SignData = {
+ /* entry */ &TPM2_Sign,
+ /* inSize */ (UINT16)(sizeof(Sign_In)),
+ /* outSize */ (UINT16)(sizeof(Sign_Out)),
+ /* offsetOfTypes */ offsetof(Sign_COMMAND_DESCRIPTOR_t, types),
+ /* offsets */ {(UINT16)(offsetof(Sign_In, digest)),
+ (UINT16)(offsetof(Sign_In, inScheme)),
+ (UINT16)(offsetof(Sign_In, validation))},
+ /* types */ {TPMI_DH_OBJECT_H_UNMARSHAL,
+ TPM2B_DIGEST_P_UNMARSHAL,
+ TPMT_SIG_SCHEME_P_UNMARSHAL + ADD_FLAG,
+ TPMT_TK_HASHCHECK_P_UNMARSHAL,
+ END_OF_LIST,
+ TPMT_SIGNATURE_P_MARSHAL,
+ END_OF_LIST}
+};
+#define _SignDataAddress (&_SignData)
+#else
+#define _SignDataAddress 0
+#endif
+#if CC_SetCommandCodeAuditStatus
+#include "SetCommandCodeAuditStatus_fp.h"
+typedef TPM_RC (SetCommandCodeAuditStatus_Entry)(
+ SetCommandCodeAuditStatus_In *in
+ );
+typedef const struct {
+ SetCommandCodeAuditStatus_Entry *entry;
+ UINT16 inSize;
+ UINT16 outSize;
+ UINT16 offsetOfTypes;
+ UINT16 paramOffsets[3];
+ BYTE types[6];
+} SetCommandCodeAuditStatus_COMMAND_DESCRIPTOR_t;
+SetCommandCodeAuditStatus_COMMAND_DESCRIPTOR_t _SetCommandCodeAuditStatusData = {
+ /* entry */ &TPM2_SetCommandCodeAuditStatus,
+ /* inSize */ (UINT16)(sizeof(SetCommandCodeAuditStatus_In)),
+ /* outSize */ 0,
+ /* offsetOfTypes */ offsetof(SetCommandCodeAuditStatus_COMMAND_DESCRIPTOR_t, types),
+ /* offsets */ {(UINT16)(offsetof(SetCommandCodeAuditStatus_In, auditAlg)),
+ (UINT16)(offsetof(SetCommandCodeAuditStatus_In, setList)),
+ (UINT16)(offsetof(SetCommandCodeAuditStatus_In, clearList))},
+ /* types */ {TPMI_RH_PROVISION_H_UNMARSHAL,
+ TPMI_ALG_HASH_P_UNMARSHAL + ADD_FLAG,
+ TPML_CC_P_UNMARSHAL,
+ TPML_CC_P_UNMARSHAL,
+ END_OF_LIST,
+ END_OF_LIST}
+};
+#define _SetCommandCodeAuditStatusDataAddress (&_SetCommandCodeAuditStatusData)
+#else
+#define _SetCommandCodeAuditStatusDataAddress 0
+#endif
+#if CC_PCR_Extend
+#include "PCR_Extend_fp.h"
+typedef TPM_RC (PCR_Extend_Entry)(
+ PCR_Extend_In *in
+ );
+typedef const struct {
+ PCR_Extend_Entry *entry;
+ UINT16 inSize;
+ UINT16 outSize;
+ UINT16 offsetOfTypes;
+ UINT16 paramOffsets[1];
+ BYTE types[4];
+} PCR_Extend_COMMAND_DESCRIPTOR_t;
+PCR_Extend_COMMAND_DESCRIPTOR_t _PCR_ExtendData = {
+ /* entry */ &TPM2_PCR_Extend,
+ /* inSize */ (UINT16)(sizeof(PCR_Extend_In)),
+ /* outSize */ 0,
+ /* offsetOfTypes */ offsetof(PCR_Extend_COMMAND_DESCRIPTOR_t, types),
+ /* offsets */ {(UINT16)(offsetof(PCR_Extend_In, digests))},
+ /* types */ {TPMI_DH_PCR_H_UNMARSHAL + ADD_FLAG,
+ TPML_DIGEST_VALUES_P_UNMARSHAL,
+ END_OF_LIST,
+ END_OF_LIST}
+};
+#define _PCR_ExtendDataAddress (&_PCR_ExtendData)
+#else
+#define _PCR_ExtendDataAddress 0
+#endif
+#if CC_PCR_Event
+#include "PCR_Event_fp.h"
+typedef TPM_RC (PCR_Event_Entry)(
+ PCR_Event_In *in,
+ PCR_Event_Out *out
+ );
+typedef const struct {
+ PCR_Event_Entry *entry;
+ UINT16 inSize;
+ UINT16 outSize;
+ UINT16 offsetOfTypes;
+ UINT16 paramOffsets[1];
+ BYTE types[5];
+} PCR_Event_COMMAND_DESCRIPTOR_t;
+PCR_Event_COMMAND_DESCRIPTOR_t _PCR_EventData = {
+ /* entry */ &TPM2_PCR_Event,
+ /* inSize */ (UINT16)(sizeof(PCR_Event_In)),
+ /* outSize */ (UINT16)(sizeof(PCR_Event_Out)),
+ /* offsetOfTypes */ offsetof(PCR_Event_COMMAND_DESCRIPTOR_t, types),
+ /* offsets */ {(UINT16)(offsetof(PCR_Event_In, eventData))},
+ /* types */ {TPMI_DH_PCR_H_UNMARSHAL + ADD_FLAG,
+ TPM2B_EVENT_P_UNMARSHAL,
+ END_OF_LIST,
+ TPML_DIGEST_VALUES_P_MARSHAL,
+ END_OF_LIST}
+};
+#define _PCR_EventDataAddress (&_PCR_EventData)
+#else
+#define _PCR_EventDataAddress 0
+#endif
+#if CC_PCR_Read
+#include "PCR_Read_fp.h"
+typedef TPM_RC (PCR_Read_Entry)(
+ PCR_Read_In *in,
+ PCR_Read_Out *out
+ );
+typedef const struct {
+ PCR_Read_Entry *entry;
+ UINT16 inSize;
+ UINT16 outSize;
+ UINT16 offsetOfTypes;
+ UINT16 paramOffsets[2];
+ BYTE types[6];
+} PCR_Read_COMMAND_DESCRIPTOR_t;
+PCR_Read_COMMAND_DESCRIPTOR_t _PCR_ReadData = {
+ /* entry */ &TPM2_PCR_Read,
+ /* inSize */ (UINT16)(sizeof(PCR_Read_In)),
+ /* outSize */ (UINT16)(sizeof(PCR_Read_Out)),
+ /* offsetOfTypes */ offsetof(PCR_Read_COMMAND_DESCRIPTOR_t, types),
+ /* offsets */ {(UINT16)(offsetof(PCR_Read_Out, pcrSelectionOut)),
+ (UINT16)(offsetof(PCR_Read_Out, pcrValues))},
+ /* types */ {TPML_PCR_SELECTION_P_UNMARSHAL,
+ END_OF_LIST,
+ UINT32_P_MARSHAL,
+ TPML_PCR_SELECTION_P_MARSHAL,
+ TPML_DIGEST_P_MARSHAL,
+ END_OF_LIST}
+};
+#define _PCR_ReadDataAddress (&_PCR_ReadData)
+#else
+#define _PCR_ReadDataAddress 0
+#endif
+#if CC_PCR_Allocate
+#include "PCR_Allocate_fp.h"
+typedef TPM_RC (PCR_Allocate_Entry)(
+ PCR_Allocate_In *in,
+ PCR_Allocate_Out *out
+ );
+typedef const struct {
+ PCR_Allocate_Entry *entry;
+ UINT16 inSize;
+ UINT16 outSize;
+ UINT16 offsetOfTypes;
+ UINT16 paramOffsets[4];
+ BYTE types[8];
+} PCR_Allocate_COMMAND_DESCRIPTOR_t;
+PCR_Allocate_COMMAND_DESCRIPTOR_t _PCR_AllocateData = {
+ /* entry */ &TPM2_PCR_Allocate,
+ /* inSize */ (UINT16)(sizeof(PCR_Allocate_In)),
+ /* outSize */ (UINT16)(sizeof(PCR_Allocate_Out)),
+ /* offsetOfTypes */ offsetof(PCR_Allocate_COMMAND_DESCRIPTOR_t, types),
+ /* offsets */ {(UINT16)(offsetof(PCR_Allocate_In, pcrAllocation)),
+ (UINT16)(offsetof(PCR_Allocate_Out, maxPCR)),
+ (UINT16)(offsetof(PCR_Allocate_Out, sizeNeeded)),
+ (UINT16)(offsetof(PCR_Allocate_Out, sizeAvailable))},
+ /* types */ {TPMI_RH_PLATFORM_H_UNMARSHAL,
+ TPML_PCR_SELECTION_P_UNMARSHAL,
+ END_OF_LIST,
+ TPMI_YES_NO_P_MARSHAL,
+ UINT32_P_MARSHAL,
+ UINT32_P_MARSHAL,
+ UINT32_P_MARSHAL,
+ END_OF_LIST}
+};
+#define _PCR_AllocateDataAddress (&_PCR_AllocateData)
+#else
+#define _PCR_AllocateDataAddress 0
+#endif
+#if CC_PCR_SetAuthPolicy
+#include "PCR_SetAuthPolicy_fp.h"
+typedef TPM_RC (PCR_SetAuthPolicy_Entry)(
+ PCR_SetAuthPolicy_In *in
+ );
+typedef const struct {
+ PCR_SetAuthPolicy_Entry *entry;
+ UINT16 inSize;
+ UINT16 outSize;
+ UINT16 offsetOfTypes;
+ UINT16 paramOffsets[3];
+ BYTE types[6];
+} PCR_SetAuthPolicy_COMMAND_DESCRIPTOR_t;
+PCR_SetAuthPolicy_COMMAND_DESCRIPTOR_t _PCR_SetAuthPolicyData = {
+ /* entry */ &TPM2_PCR_SetAuthPolicy,
+ /* inSize */ (UINT16)(sizeof(PCR_SetAuthPolicy_In)),
+ /* outSize */ 0,
+ /* offsetOfTypes */ offsetof(PCR_SetAuthPolicy_COMMAND_DESCRIPTOR_t, types),
+ /* offsets */ {(UINT16)(offsetof(PCR_SetAuthPolicy_In, authPolicy)),
+ (UINT16)(offsetof(PCR_SetAuthPolicy_In, hashAlg)),
+ (UINT16)(offsetof(PCR_SetAuthPolicy_In, pcrNum))},
+ /* types */ {TPMI_RH_PLATFORM_H_UNMARSHAL,
+ TPM2B_DIGEST_P_UNMARSHAL,
+ TPMI_ALG_HASH_P_UNMARSHAL + ADD_FLAG,
+ TPMI_DH_PCR_P_UNMARSHAL,
+ END_OF_LIST,
+ END_OF_LIST}
+};
+#define _PCR_SetAuthPolicyDataAddress (&_PCR_SetAuthPolicyData)
+#else
+#define _PCR_SetAuthPolicyDataAddress 0
+#endif
+#if CC_PCR_SetAuthValue
+#include "PCR_SetAuthValue_fp.h"
+typedef TPM_RC (PCR_SetAuthValue_Entry)(
+ PCR_SetAuthValue_In *in
+ );
+typedef const struct {
+ PCR_SetAuthValue_Entry *entry;
+ UINT16 inSize;
+ UINT16 outSize;
+ UINT16 offsetOfTypes;
+ UINT16 paramOffsets[1];
+ BYTE types[4];
+} PCR_SetAuthValue_COMMAND_DESCRIPTOR_t;
+PCR_SetAuthValue_COMMAND_DESCRIPTOR_t _PCR_SetAuthValueData = {
+ /* entry */ &TPM2_PCR_SetAuthValue,
+ /* inSize */ (UINT16)(sizeof(PCR_SetAuthValue_In)),
+ /* outSize */ 0,
+ /* offsetOfTypes */ offsetof(PCR_SetAuthValue_COMMAND_DESCRIPTOR_t, types),
+ /* offsets */ {(UINT16)(offsetof(PCR_SetAuthValue_In, auth))},
+ /* types */ {TPMI_DH_PCR_H_UNMARSHAL,
+ TPM2B_DIGEST_P_UNMARSHAL,
+ END_OF_LIST,
+ END_OF_LIST}
+};
+#define _PCR_SetAuthValueDataAddress (&_PCR_SetAuthValueData)
+#else
+#define _PCR_SetAuthValueDataAddress 0
+#endif
+#if CC_PCR_Reset
+#include "PCR_Reset_fp.h"
+typedef TPM_RC (PCR_Reset_Entry)(
+ PCR_Reset_In *in
+ );
+typedef const struct {
+ PCR_Reset_Entry *entry;
+ UINT16 inSize;
+ UINT16 outSize;
+ UINT16 offsetOfTypes;
+ BYTE types[3];
+} PCR_Reset_COMMAND_DESCRIPTOR_t;
+PCR_Reset_COMMAND_DESCRIPTOR_t _PCR_ResetData = {
+ /* entry */ &TPM2_PCR_Reset,
+ /* inSize */ (UINT16)(sizeof(PCR_Reset_In)),
+ /* outSize */ 0,
+ /* offsetOfTypes */ offsetof(PCR_Reset_COMMAND_DESCRIPTOR_t, types),
+ /* offsets */ // No parameter offsets
+ /* types */ {TPMI_DH_PCR_H_UNMARSHAL,
+ END_OF_LIST,
+ END_OF_LIST}
+};
+#define _PCR_ResetDataAddress (&_PCR_ResetData)
+#else
+#define _PCR_ResetDataAddress 0
+#endif
+#if CC_PolicySigned
+#include "PolicySigned_fp.h"
+typedef TPM_RC (PolicySigned_Entry)(
+ PolicySigned_In *in,
+ PolicySigned_Out *out
+ );
+typedef const struct {
+ PolicySigned_Entry *entry;
+ UINT16 inSize;
+ UINT16 outSize;
+ UINT16 offsetOfTypes;
+ UINT16 paramOffsets[7];
+ BYTE types[11];
+} PolicySigned_COMMAND_DESCRIPTOR_t;
+PolicySigned_COMMAND_DESCRIPTOR_t _PolicySignedData = {
+ /* entry */ &TPM2_PolicySigned,
+ /* inSize */ (UINT16)(sizeof(PolicySigned_In)),
+ /* outSize */ (UINT16)(sizeof(PolicySigned_Out)),
+ /* offsetOfTypes */ offsetof(PolicySigned_COMMAND_DESCRIPTOR_t, types),
+ /* offsets */ {(UINT16)(offsetof(PolicySigned_In, policySession)),
+ (UINT16)(offsetof(PolicySigned_In, nonceTPM)),
+ (UINT16)(offsetof(PolicySigned_In, cpHashA)),
+ (UINT16)(offsetof(PolicySigned_In, policyRef)),
+ (UINT16)(offsetof(PolicySigned_In, expiration)),
+ (UINT16)(offsetof(PolicySigned_In, auth)),
+ (UINT16)(offsetof(PolicySigned_Out, policyTicket))},
+ /* types */ {TPMI_DH_OBJECT_H_UNMARSHAL,
+ TPMI_SH_POLICY_H_UNMARSHAL,
+ TPM2B_NONCE_P_UNMARSHAL,
+ TPM2B_DIGEST_P_UNMARSHAL,
+ TPM2B_NONCE_P_UNMARSHAL,
+ INT32_P_UNMARSHAL,
+ TPMT_SIGNATURE_P_UNMARSHAL,
+ END_OF_LIST,
+ TPM2B_TIMEOUT_P_MARSHAL,
+ TPMT_TK_AUTH_P_MARSHAL,
+ END_OF_LIST}
+};
+#define _PolicySignedDataAddress (&_PolicySignedData)
+#else
+#define _PolicySignedDataAddress 0
+#endif
+#if CC_PolicySecret
+#include "PolicySecret_fp.h"
+typedef TPM_RC (PolicySecret_Entry)(
+ PolicySecret_In *in,
+ PolicySecret_Out *out
+ );
+typedef const struct {
+ PolicySecret_Entry *entry;
+ UINT16 inSize;
+ UINT16 outSize;
+ UINT16 offsetOfTypes;
+ UINT16 paramOffsets[6];
+ BYTE types[10];
+} PolicySecret_COMMAND_DESCRIPTOR_t;
+PolicySecret_COMMAND_DESCRIPTOR_t _PolicySecretData = {
+ /* entry */ &TPM2_PolicySecret,
+ /* inSize */ (UINT16)(sizeof(PolicySecret_In)),
+ /* outSize */ (UINT16)(sizeof(PolicySecret_Out)),
+ /* offsetOfTypes */ offsetof(PolicySecret_COMMAND_DESCRIPTOR_t, types),
+ /* offsets */ {(UINT16)(offsetof(PolicySecret_In, policySession)),
+ (UINT16)(offsetof(PolicySecret_In, nonceTPM)),
+ (UINT16)(offsetof(PolicySecret_In, cpHashA)),
+ (UINT16)(offsetof(PolicySecret_In, policyRef)),
+ (UINT16)(offsetof(PolicySecret_In, expiration)),
+ (UINT16)(offsetof(PolicySecret_Out, policyTicket))},
+ /* types */ {TPMI_DH_ENTITY_H_UNMARSHAL,
+ TPMI_SH_POLICY_H_UNMARSHAL,
+ TPM2B_NONCE_P_UNMARSHAL,
+ TPM2B_DIGEST_P_UNMARSHAL,
+ TPM2B_NONCE_P_UNMARSHAL,
+ INT32_P_UNMARSHAL,
+ END_OF_LIST,
+ TPM2B_TIMEOUT_P_MARSHAL,
+ TPMT_TK_AUTH_P_MARSHAL,
+ END_OF_LIST}
+};
+#define _PolicySecretDataAddress (&_PolicySecretData)
+#else
+#define _PolicySecretDataAddress 0
+#endif
+#if CC_PolicyTicket
+#include "PolicyTicket_fp.h"
+typedef TPM_RC (PolicyTicket_Entry)(
+ PolicyTicket_In *in
+ );
+typedef const struct {
+ PolicyTicket_Entry *entry;
+ UINT16 inSize;
+ UINT16 outSize;
+ UINT16 offsetOfTypes;
+ UINT16 paramOffsets[5];
+ BYTE types[8];
+} PolicyTicket_COMMAND_DESCRIPTOR_t;
+PolicyTicket_COMMAND_DESCRIPTOR_t _PolicyTicketData = {
+ /* entry */ &TPM2_PolicyTicket,
+ /* inSize */ (UINT16)(sizeof(PolicyTicket_In)),
+ /* outSize */ 0,
+ /* offsetOfTypes */ offsetof(PolicyTicket_COMMAND_DESCRIPTOR_t, types),
+ /* offsets */ {(UINT16)(offsetof(PolicyTicket_In, timeout)),
+ (UINT16)(offsetof(PolicyTicket_In, cpHashA)),
+ (UINT16)(offsetof(PolicyTicket_In, policyRef)),
+ (UINT16)(offsetof(PolicyTicket_In, authName)),
+ (UINT16)(offsetof(PolicyTicket_In, ticket))},
+ /* types */ {TPMI_SH_POLICY_H_UNMARSHAL,
+ TPM2B_TIMEOUT_P_UNMARSHAL,
+ TPM2B_DIGEST_P_UNMARSHAL,
+ TPM2B_NONCE_P_UNMARSHAL,
+ TPM2B_NAME_P_UNMARSHAL,
+ TPMT_TK_AUTH_P_UNMARSHAL,
+ END_OF_LIST,
+ END_OF_LIST}
+};
+#define _PolicyTicketDataAddress (&_PolicyTicketData)
+#else
+#define _PolicyTicketDataAddress 0
+#endif
+#if CC_PolicyOR
+#include "PolicyOR_fp.h"
+typedef TPM_RC (PolicyOR_Entry)(
+ PolicyOR_In *in
+ );
+typedef const struct {
+ PolicyOR_Entry *entry;
+ UINT16 inSize;
+ UINT16 outSize;
+ UINT16 offsetOfTypes;
+ UINT16 paramOffsets[1];
+ BYTE types[4];
+} PolicyOR_COMMAND_DESCRIPTOR_t;
+PolicyOR_COMMAND_DESCRIPTOR_t _PolicyORData = {
+ /* entry */ &TPM2_PolicyOR,
+ /* inSize */ (UINT16)(sizeof(PolicyOR_In)),
+ /* outSize */ 0,
+ /* offsetOfTypes */ offsetof(PolicyOR_COMMAND_DESCRIPTOR_t, types),
+ /* offsets */ {(UINT16)(offsetof(PolicyOR_In, pHashList))},
+ /* types */ {TPMI_SH_POLICY_H_UNMARSHAL,
+ TPML_DIGEST_P_UNMARSHAL,
+ END_OF_LIST,
+ END_OF_LIST}
+};
+#define _PolicyORDataAddress (&_PolicyORData)
+#else
+#define _PolicyORDataAddress 0
+#endif
+#if CC_PolicyPCR
+#include "PolicyPCR_fp.h"
+typedef TPM_RC (PolicyPCR_Entry)(
+ PolicyPCR_In *in
+ );
+typedef const struct {
+ PolicyPCR_Entry *entry;
+ UINT16 inSize;
+ UINT16 outSize;
+ UINT16 offsetOfTypes;
+ UINT16 paramOffsets[2];
+ BYTE types[5];
+} PolicyPCR_COMMAND_DESCRIPTOR_t;
+PolicyPCR_COMMAND_DESCRIPTOR_t _PolicyPCRData = {
+ /* entry */ &TPM2_PolicyPCR,
+ /* inSize */ (UINT16)(sizeof(PolicyPCR_In)),
+ /* outSize */ 0,
+ /* offsetOfTypes */ offsetof(PolicyPCR_COMMAND_DESCRIPTOR_t, types),
+ /* offsets */ {(UINT16)(offsetof(PolicyPCR_In, pcrDigest)),
+ (UINT16)(offsetof(PolicyPCR_In, pcrs))},
+ /* types */ {TPMI_SH_POLICY_H_UNMARSHAL,
+ TPM2B_DIGEST_P_UNMARSHAL,
+ TPML_PCR_SELECTION_P_UNMARSHAL,
+ END_OF_LIST,
+ END_OF_LIST}
+};
+#define _PolicyPCRDataAddress (&_PolicyPCRData)
+#else
+#define _PolicyPCRDataAddress 0
+#endif
+#if CC_PolicyLocality
+#include "PolicyLocality_fp.h"
+typedef TPM_RC (PolicyLocality_Entry)(
+ PolicyLocality_In *in
+ );
+typedef const struct {
+ PolicyLocality_Entry *entry;
+ UINT16 inSize;
+ UINT16 outSize;
+ UINT16 offsetOfTypes;
+ UINT16 paramOffsets[1];
+ BYTE types[4];
+} PolicyLocality_COMMAND_DESCRIPTOR_t;
+PolicyLocality_COMMAND_DESCRIPTOR_t _PolicyLocalityData = {
+ /* entry */ &TPM2_PolicyLocality,
+ /* inSize */ (UINT16)(sizeof(PolicyLocality_In)),
+ /* outSize */ 0,
+ /* offsetOfTypes */ offsetof(PolicyLocality_COMMAND_DESCRIPTOR_t, types),
+ /* offsets */ {(UINT16)(offsetof(PolicyLocality_In, locality))},
+ /* types */ {TPMI_SH_POLICY_H_UNMARSHAL,
+ TPMA_LOCALITY_P_UNMARSHAL,
+ END_OF_LIST,
+ END_OF_LIST}
+};
+#define _PolicyLocalityDataAddress (&_PolicyLocalityData)
+#else
+#define _PolicyLocalityDataAddress 0
+#endif
+#if CC_PolicyNV
+#include "PolicyNV_fp.h"
+typedef TPM_RC (PolicyNV_Entry)(
+ PolicyNV_In *in
+ );
+typedef const struct {
+ PolicyNV_Entry *entry;
+ UINT16 inSize;
+ UINT16 outSize;
+ UINT16 offsetOfTypes;
+ UINT16 paramOffsets[5];
+ BYTE types[8];
+} PolicyNV_COMMAND_DESCRIPTOR_t;
+PolicyNV_COMMAND_DESCRIPTOR_t _PolicyNVData = {
+ /* entry */ &TPM2_PolicyNV,
+ /* inSize */ (UINT16)(sizeof(PolicyNV_In)),
+ /* outSize */ 0,
+ /* offsetOfTypes */ offsetof(PolicyNV_COMMAND_DESCRIPTOR_t, types),
+ /* offsets */ {(UINT16)(offsetof(PolicyNV_In, nvIndex)),
+ (UINT16)(offsetof(PolicyNV_In, policySession)),
+ (UINT16)(offsetof(PolicyNV_In, operandB)),
+ (UINT16)(offsetof(PolicyNV_In, offset)),
+ (UINT16)(offsetof(PolicyNV_In, operation))},
+ /* types */ {TPMI_RH_NV_AUTH_H_UNMARSHAL,
+ TPMI_RH_NV_INDEX_H_UNMARSHAL,
+ TPMI_SH_POLICY_H_UNMARSHAL,
+ TPM2B_OPERAND_P_UNMARSHAL,
+ UINT16_P_UNMARSHAL,
+ TPM_EO_P_UNMARSHAL,
+ END_OF_LIST,
+ END_OF_LIST}
+};
+#define _PolicyNVDataAddress (&_PolicyNVData)
+#else
+#define _PolicyNVDataAddress 0
+#endif
+#if CC_PolicyCounterTimer
+#include "PolicyCounterTimer_fp.h"
+typedef TPM_RC (PolicyCounterTimer_Entry)(
+ PolicyCounterTimer_In *in
+ );
+typedef const struct {
+ PolicyCounterTimer_Entry *entry;
+ UINT16 inSize;
+ UINT16 outSize;
+ UINT16 offsetOfTypes;
+ UINT16 paramOffsets[3];
+ BYTE types[6];
+} PolicyCounterTimer_COMMAND_DESCRIPTOR_t;
+PolicyCounterTimer_COMMAND_DESCRIPTOR_t _PolicyCounterTimerData = {
+ /* entry */ &TPM2_PolicyCounterTimer,
+ /* inSize */ (UINT16)(sizeof(PolicyCounterTimer_In)),
+ /* outSize */ 0,
+ /* offsetOfTypes */ offsetof(PolicyCounterTimer_COMMAND_DESCRIPTOR_t, types),
+ /* offsets */ {(UINT16)(offsetof(PolicyCounterTimer_In, operandB)),
+ (UINT16)(offsetof(PolicyCounterTimer_In, offset)),
+ (UINT16)(offsetof(PolicyCounterTimer_In, operation))},
+ /* types */ {TPMI_SH_POLICY_H_UNMARSHAL,
+ TPM2B_OPERAND_P_UNMARSHAL,
+ UINT16_P_UNMARSHAL,
+ TPM_EO_P_UNMARSHAL,
+ END_OF_LIST,
+ END_OF_LIST}
+};
+#define _PolicyCounterTimerDataAddress (&_PolicyCounterTimerData)
+#else
+#define _PolicyCounterTimerDataAddress 0
+#endif
+#if CC_PolicyCommandCode
+#include "PolicyCommandCode_fp.h"
+typedef TPM_RC (PolicyCommandCode_Entry)(
+ PolicyCommandCode_In *in
+ );
+typedef const struct {
+ PolicyCommandCode_Entry *entry;
+ UINT16 inSize;
+ UINT16 outSize;
+ UINT16 offsetOfTypes;
+ UINT16 paramOffsets[1];
+ BYTE types[4];
+} PolicyCommandCode_COMMAND_DESCRIPTOR_t;
+PolicyCommandCode_COMMAND_DESCRIPTOR_t _PolicyCommandCodeData = {
+ /* entry */ &TPM2_PolicyCommandCode,
+ /* inSize */ (UINT16)(sizeof(PolicyCommandCode_In)),
+ /* outSize */ 0,
+ /* offsetOfTypes */ offsetof(PolicyCommandCode_COMMAND_DESCRIPTOR_t, types),
+ /* offsets */ {(UINT16)(offsetof(PolicyCommandCode_In, code))},
+ /* types */ {TPMI_SH_POLICY_H_UNMARSHAL,
+ TPM_CC_P_UNMARSHAL,
+ END_OF_LIST,
+ END_OF_LIST}
+};
+#define _PolicyCommandCodeDataAddress (&_PolicyCommandCodeData)
+#else
+#define _PolicyCommandCodeDataAddress 0
+#endif
+#if CC_PolicyPhysicalPresence
+#include "PolicyPhysicalPresence_fp.h"
+typedef TPM_RC (PolicyPhysicalPresence_Entry)(
+ PolicyPhysicalPresence_In *in
+ );
+typedef const struct {
+ PolicyPhysicalPresence_Entry *entry;
+ UINT16 inSize;
+ UINT16 outSize;
+ UINT16 offsetOfTypes;
+ BYTE types[3];
+} PolicyPhysicalPresence_COMMAND_DESCRIPTOR_t;
+PolicyPhysicalPresence_COMMAND_DESCRIPTOR_t _PolicyPhysicalPresenceData = {
+ /* entry */ &TPM2_PolicyPhysicalPresence,
+ /* inSize */ (UINT16)(sizeof(PolicyPhysicalPresence_In)),
+ /* outSize */ 0,
+ /* offsetOfTypes */ offsetof(PolicyPhysicalPresence_COMMAND_DESCRIPTOR_t, types),
+ /* offsets */ // No parameter offsets
+ /* types */ {TPMI_SH_POLICY_H_UNMARSHAL,
+ END_OF_LIST,
+ END_OF_LIST}
+};
+#define _PolicyPhysicalPresenceDataAddress (&_PolicyPhysicalPresenceData)
+#else
+#define _PolicyPhysicalPresenceDataAddress 0
+#endif
+#if CC_PolicyCpHash
+#include "PolicyCpHash_fp.h"
+typedef TPM_RC (PolicyCpHash_Entry)(
+ PolicyCpHash_In *in
+ );
+typedef const struct {
+ PolicyCpHash_Entry *entry;
+ UINT16 inSize;
+ UINT16 outSize;
+ UINT16 offsetOfTypes;
+ UINT16 paramOffsets[1];
+ BYTE types[4];
+} PolicyCpHash_COMMAND_DESCRIPTOR_t;
+PolicyCpHash_COMMAND_DESCRIPTOR_t _PolicyCpHashData = {
+ /* entry */ &TPM2_PolicyCpHash,
+ /* inSize */ (UINT16)(sizeof(PolicyCpHash_In)),
+ /* outSize */ 0,
+ /* offsetOfTypes */ offsetof(PolicyCpHash_COMMAND_DESCRIPTOR_t, types),
+ /* offsets */ {(UINT16)(offsetof(PolicyCpHash_In, cpHashA))},
+ /* types */ {TPMI_SH_POLICY_H_UNMARSHAL,
+ TPM2B_DIGEST_P_UNMARSHAL,
+ END_OF_LIST,
+ END_OF_LIST}
+};
+#define _PolicyCpHashDataAddress (&_PolicyCpHashData)
+#else
+#define _PolicyCpHashDataAddress 0
+#endif
+#if CC_PolicyNameHash
+#include "PolicyNameHash_fp.h"
+typedef TPM_RC (PolicyNameHash_Entry)(
+ PolicyNameHash_In *in
+ );
+typedef const struct {
+ PolicyNameHash_Entry *entry;
+ UINT16 inSize;
+ UINT16 outSize;
+ UINT16 offsetOfTypes;
+ UINT16 paramOffsets[1];
+ BYTE types[4];
+} PolicyNameHash_COMMAND_DESCRIPTOR_t;
+PolicyNameHash_COMMAND_DESCRIPTOR_t _PolicyNameHashData = {
+ /* entry */ &TPM2_PolicyNameHash,
+ /* inSize */ (UINT16)(sizeof(PolicyNameHash_In)),
+ /* outSize */ 0,
+ /* offsetOfTypes */ offsetof(PolicyNameHash_COMMAND_DESCRIPTOR_t, types),
+ /* offsets */ {(UINT16)(offsetof(PolicyNameHash_In, nameHash))},
+ /* types */ {TPMI_SH_POLICY_H_UNMARSHAL,
+ TPM2B_DIGEST_P_UNMARSHAL,
+ END_OF_LIST,
+ END_OF_LIST}
+};
+#define _PolicyNameHashDataAddress (&_PolicyNameHashData)
+#else
+#define _PolicyNameHashDataAddress 0
+#endif
+#if CC_PolicyDuplicationSelect
+#include "PolicyDuplicationSelect_fp.h"
+typedef TPM_RC (PolicyDuplicationSelect_Entry)(
+ PolicyDuplicationSelect_In *in
+ );
+typedef const struct {
+ PolicyDuplicationSelect_Entry *entry;
+ UINT16 inSize;
+ UINT16 outSize;
+ UINT16 offsetOfTypes;
+ UINT16 paramOffsets[3];
+ BYTE types[6];
+} PolicyDuplicationSelect_COMMAND_DESCRIPTOR_t;
+PolicyDuplicationSelect_COMMAND_DESCRIPTOR_t _PolicyDuplicationSelectData = {
+ /* entry */ &TPM2_PolicyDuplicationSelect,
+ /* inSize */ (UINT16)(sizeof(PolicyDuplicationSelect_In)),
+ /* outSize */ 0,
+ /* offsetOfTypes */ offsetof(PolicyDuplicationSelect_COMMAND_DESCRIPTOR_t, types),
+ /* offsets */ {(UINT16)(offsetof(PolicyDuplicationSelect_In, objectName)),
+ (UINT16)(offsetof(PolicyDuplicationSelect_In, newParentName)),
+ (UINT16)(offsetof(PolicyDuplicationSelect_In, includeObject))},
+ /* types */ {TPMI_SH_POLICY_H_UNMARSHAL,
+ TPM2B_NAME_P_UNMARSHAL,
+ TPM2B_NAME_P_UNMARSHAL,
+ TPMI_YES_NO_P_UNMARSHAL,
+ END_OF_LIST,
+ END_OF_LIST}
+};
+#define _PolicyDuplicationSelectDataAddress (&_PolicyDuplicationSelectData)
+#else
+#define _PolicyDuplicationSelectDataAddress 0
+#endif
+#if CC_PolicyAuthorize
+#include "PolicyAuthorize_fp.h"
+typedef TPM_RC (PolicyAuthorize_Entry)(
+ PolicyAuthorize_In *in
+ );
+typedef const struct {
+ PolicyAuthorize_Entry *entry;
+ UINT16 inSize;
+ UINT16 outSize;
+ UINT16 offsetOfTypes;
+ UINT16 paramOffsets[4];
+ BYTE types[7];
+} PolicyAuthorize_COMMAND_DESCRIPTOR_t;
+PolicyAuthorize_COMMAND_DESCRIPTOR_t _PolicyAuthorizeData = {
+ /* entry */ &TPM2_PolicyAuthorize,
+ /* inSize */ (UINT16)(sizeof(PolicyAuthorize_In)),
+ /* outSize */ 0,
+ /* offsetOfTypes */ offsetof(PolicyAuthorize_COMMAND_DESCRIPTOR_t, types),
+ /* offsets */ {(UINT16)(offsetof(PolicyAuthorize_In, approvedPolicy)),
+ (UINT16)(offsetof(PolicyAuthorize_In, policyRef)),
+ (UINT16)(offsetof(PolicyAuthorize_In, keySign)),
+ (UINT16)(offsetof(PolicyAuthorize_In, checkTicket))},
+ /* types */ {TPMI_SH_POLICY_H_UNMARSHAL,
+ TPM2B_DIGEST_P_UNMARSHAL,
+ TPM2B_NONCE_P_UNMARSHAL,
+ TPM2B_NAME_P_UNMARSHAL,
+ TPMT_TK_VERIFIED_P_UNMARSHAL,
+ END_OF_LIST,
+ END_OF_LIST}
+};
+#define _PolicyAuthorizeDataAddress (&_PolicyAuthorizeData)
+#else
+#define _PolicyAuthorizeDataAddress 0
+#endif
+#if CC_PolicyAuthValue
+#include "PolicyAuthValue_fp.h"
+typedef TPM_RC (PolicyAuthValue_Entry)(
+ PolicyAuthValue_In *in
+ );
+typedef const struct {
+ PolicyAuthValue_Entry *entry;
+ UINT16 inSize;
+ UINT16 outSize;
+ UINT16 offsetOfTypes;
+ BYTE types[3];
+} PolicyAuthValue_COMMAND_DESCRIPTOR_t;
+PolicyAuthValue_COMMAND_DESCRIPTOR_t _PolicyAuthValueData = {
+ /* entry */ &TPM2_PolicyAuthValue,
+ /* inSize */ (UINT16)(sizeof(PolicyAuthValue_In)),
+ /* outSize */ 0,
+ /* offsetOfTypes */ offsetof(PolicyAuthValue_COMMAND_DESCRIPTOR_t, types),
+ /* offsets */ // No parameter offsets
+ /* types */ {TPMI_SH_POLICY_H_UNMARSHAL,
+ END_OF_LIST,
+ END_OF_LIST}
+};
+#define _PolicyAuthValueDataAddress (&_PolicyAuthValueData)
+#else
+#define _PolicyAuthValueDataAddress 0
+#endif
+#if CC_PolicyPassword
+#include "PolicyPassword_fp.h"
+typedef TPM_RC (PolicyPassword_Entry)(
+ PolicyPassword_In *in
+ );
+typedef const struct {
+ PolicyPassword_Entry *entry;
+ UINT16 inSize;
+ UINT16 outSize;
+ UINT16 offsetOfTypes;
+ BYTE types[3];
+} PolicyPassword_COMMAND_DESCRIPTOR_t;
+PolicyPassword_COMMAND_DESCRIPTOR_t _PolicyPasswordData = {
+ /* entry */ &TPM2_PolicyPassword,
+ /* inSize */ (UINT16)(sizeof(PolicyPassword_In)),
+ /* outSize */ 0,
+ /* offsetOfTypes */ offsetof(PolicyPassword_COMMAND_DESCRIPTOR_t, types),
+ /* offsets */ // No parameter offsets
+ /* types */ {TPMI_SH_POLICY_H_UNMARSHAL,
+ END_OF_LIST,
+ END_OF_LIST}
+};
+#define _PolicyPasswordDataAddress (&_PolicyPasswordData)
+#else
+#define _PolicyPasswordDataAddress 0
+#endif
+#if CC_PolicyGetDigest
+#include "PolicyGetDigest_fp.h"
+typedef TPM_RC (PolicyGetDigest_Entry)(
+ PolicyGetDigest_In *in,
+ PolicyGetDigest_Out *out
+ );
+typedef const struct {
+ PolicyGetDigest_Entry *entry;
+ UINT16 inSize;
+ UINT16 outSize;
+ UINT16 offsetOfTypes;
+ BYTE types[4];
+} PolicyGetDigest_COMMAND_DESCRIPTOR_t;
+PolicyGetDigest_COMMAND_DESCRIPTOR_t _PolicyGetDigestData = {
+ /* entry */ &TPM2_PolicyGetDigest,
+ /* inSize */ (UINT16)(sizeof(PolicyGetDigest_In)),
+ /* outSize */ (UINT16)(sizeof(PolicyGetDigest_Out)),
+ /* offsetOfTypes */ offsetof(PolicyGetDigest_COMMAND_DESCRIPTOR_t, types),
+ /* offsets */ // No parameter offsets
+ /* types */ {TPMI_SH_POLICY_H_UNMARSHAL,
+ END_OF_LIST,
+ TPM2B_DIGEST_P_MARSHAL,
+ END_OF_LIST}
+};
+#define _PolicyGetDigestDataAddress (&_PolicyGetDigestData)
+#else
+#define _PolicyGetDigestDataAddress 0
+#endif
+#if CC_PolicyNvWritten
+#include "PolicyNvWritten_fp.h"
+typedef TPM_RC (PolicyNvWritten_Entry)(
+ PolicyNvWritten_In *in
+ );
+typedef const struct {
+ PolicyNvWritten_Entry *entry;
+ UINT16 inSize;
+ UINT16 outSize;
+ UINT16 offsetOfTypes;
+ UINT16 paramOffsets[1];
+ BYTE types[4];
+} PolicyNvWritten_COMMAND_DESCRIPTOR_t;
+PolicyNvWritten_COMMAND_DESCRIPTOR_t _PolicyNvWrittenData = {
+ /* entry */ &TPM2_PolicyNvWritten,
+ /* inSize */ (UINT16)(sizeof(PolicyNvWritten_In)),
+ /* outSize */ 0,
+ /* offsetOfTypes */ offsetof(PolicyNvWritten_COMMAND_DESCRIPTOR_t, types),
+ /* offsets */ {(UINT16)(offsetof(PolicyNvWritten_In, writtenSet))},
+ /* types */ {TPMI_SH_POLICY_H_UNMARSHAL,
+ TPMI_YES_NO_P_UNMARSHAL,
+ END_OF_LIST,
+ END_OF_LIST}
+};
+#define _PolicyNvWrittenDataAddress (&_PolicyNvWrittenData)
+#else
+#define _PolicyNvWrittenDataAddress 0
+#endif
+#if CC_PolicyTemplate
+#include "PolicyTemplate_fp.h"
+typedef TPM_RC (PolicyTemplate_Entry)(
+ PolicyTemplate_In *in
+ );
+typedef const struct {
+ PolicyTemplate_Entry *entry;
+ UINT16 inSize;
+ UINT16 outSize;
+ UINT16 offsetOfTypes;
+ UINT16 paramOffsets[1];
+ BYTE types[4];
+} PolicyTemplate_COMMAND_DESCRIPTOR_t;
+PolicyTemplate_COMMAND_DESCRIPTOR_t _PolicyTemplateData = {
+ /* entry */ &TPM2_PolicyTemplate,
+ /* inSize */ (UINT16)(sizeof(PolicyTemplate_In)),
+ /* outSize */ 0,
+ /* offsetOfTypes */ offsetof(PolicyTemplate_COMMAND_DESCRIPTOR_t, types),
+ /* offsets */ {(UINT16)(offsetof(PolicyTemplate_In, templateHash))},
+ /* types */ {TPMI_SH_POLICY_H_UNMARSHAL,
+ TPM2B_DIGEST_P_UNMARSHAL,
+ END_OF_LIST,
+ END_OF_LIST}
+};
+#define _PolicyTemplateDataAddress (&_PolicyTemplateData)
+#else
+#define _PolicyTemplateDataAddress 0
+#endif
+#if CC_PolicyAuthorizeNV
+#include "PolicyAuthorizeNV_fp.h"
+typedef TPM_RC (PolicyAuthorizeNV_Entry)(
+ PolicyAuthorizeNV_In *in
+ );
+typedef const struct {
+ PolicyAuthorizeNV_Entry *entry;
+ UINT16 inSize;
+ UINT16 outSize;
+ UINT16 offsetOfTypes;
+ UINT16 paramOffsets[2];
+ BYTE types[5];
+} PolicyAuthorizeNV_COMMAND_DESCRIPTOR_t;
+PolicyAuthorizeNV_COMMAND_DESCRIPTOR_t _PolicyAuthorizeNVData = {
+ /* entry */ &TPM2_PolicyAuthorizeNV,
+ /* inSize */ (UINT16)(sizeof(PolicyAuthorizeNV_In)),
+ /* outSize */ 0,
+ /* offsetOfTypes */ offsetof(PolicyAuthorizeNV_COMMAND_DESCRIPTOR_t, types),
+ /* offsets */ {(UINT16)(offsetof(PolicyAuthorizeNV_In, nvIndex)),
+ (UINT16)(offsetof(PolicyAuthorizeNV_In, policySession))},
+ /* types */ {TPMI_RH_NV_AUTH_H_UNMARSHAL,
+ TPMI_RH_NV_INDEX_H_UNMARSHAL,
+ TPMI_SH_POLICY_H_UNMARSHAL,
+ END_OF_LIST,
+ END_OF_LIST}
+};
+#define _PolicyAuthorizeNVDataAddress (&_PolicyAuthorizeNVData)
+#else
+#define _PolicyAuthorizeNVDataAddress 0
+#endif
+#if CC_CreatePrimary
+#include "CreatePrimary_fp.h"
+typedef TPM_RC (CreatePrimary_Entry)(
+ CreatePrimary_In *in,
+ CreatePrimary_Out *out
+ );
+typedef const struct {
+ CreatePrimary_Entry *entry;
+ UINT16 inSize;
+ UINT16 outSize;
+ UINT16 offsetOfTypes;
+ UINT16 paramOffsets[9];
+ BYTE types[13];
+} CreatePrimary_COMMAND_DESCRIPTOR_t;
+CreatePrimary_COMMAND_DESCRIPTOR_t _CreatePrimaryData = {
+ /* entry */ &TPM2_CreatePrimary,
+ /* inSize */ (UINT16)(sizeof(CreatePrimary_In)),
+ /* outSize */ (UINT16)(sizeof(CreatePrimary_Out)),
+ /* offsetOfTypes */ offsetof(CreatePrimary_COMMAND_DESCRIPTOR_t, types),
+ /* offsets */ {(UINT16)(offsetof(CreatePrimary_In, inSensitive)),
+ (UINT16)(offsetof(CreatePrimary_In, inPublic)),
+ (UINT16)(offsetof(CreatePrimary_In, outsideInfo)),
+ (UINT16)(offsetof(CreatePrimary_In, creationPCR)),
+ (UINT16)(offsetof(CreatePrimary_Out, outPublic)),
+ (UINT16)(offsetof(CreatePrimary_Out, creationData)),
+ (UINT16)(offsetof(CreatePrimary_Out, creationHash)),
+ (UINT16)(offsetof(CreatePrimary_Out, creationTicket)),
+ (UINT16)(offsetof(CreatePrimary_Out, name))},
+ /* types */ {TPMI_RH_HIERARCHY_H_UNMARSHAL + ADD_FLAG,
+ TPM2B_SENSITIVE_CREATE_P_UNMARSHAL,
+ TPM2B_PUBLIC_P_UNMARSHAL,
+ TPM2B_DATA_P_UNMARSHAL,
+ TPML_PCR_SELECTION_P_UNMARSHAL,
+ END_OF_LIST,
+ TPM_HANDLE_H_MARSHAL,
+ TPM2B_PUBLIC_P_MARSHAL,
+ TPM2B_CREATION_DATA_P_MARSHAL,
+ TPM2B_DIGEST_P_MARSHAL,
+ TPMT_TK_CREATION_P_MARSHAL,
+ TPM2B_NAME_P_MARSHAL,
+ END_OF_LIST}
+};
+#define _CreatePrimaryDataAddress (&_CreatePrimaryData)
+#else
+#define _CreatePrimaryDataAddress 0
+#endif
+#if CC_HierarchyControl
+#include "HierarchyControl_fp.h"
+typedef TPM_RC (HierarchyControl_Entry)(
+ HierarchyControl_In *in
+ );
+typedef const struct {
+ HierarchyControl_Entry *entry;
+ UINT16 inSize;
+ UINT16 outSize;
+ UINT16 offsetOfTypes;
+ UINT16 paramOffsets[2];
+ BYTE types[5];
+} HierarchyControl_COMMAND_DESCRIPTOR_t;
+HierarchyControl_COMMAND_DESCRIPTOR_t _HierarchyControlData = {
+ /* entry */ &TPM2_HierarchyControl,
+ /* inSize */ (UINT16)(sizeof(HierarchyControl_In)),
+ /* outSize */ 0,
+ /* offsetOfTypes */ offsetof(HierarchyControl_COMMAND_DESCRIPTOR_t, types),
+ /* offsets */ {(UINT16)(offsetof(HierarchyControl_In, enable)),
+ (UINT16)(offsetof(HierarchyControl_In, state))},
+ /* types */ {TPMI_RH_HIERARCHY_H_UNMARSHAL,
+ TPMI_RH_ENABLES_P_UNMARSHAL,
+ TPMI_YES_NO_P_UNMARSHAL,
+ END_OF_LIST,
+ END_OF_LIST}
+};
+#define _HierarchyControlDataAddress (&_HierarchyControlData)
+#else
+#define _HierarchyControlDataAddress 0
+#endif
+#if CC_SetPrimaryPolicy
+#include "SetPrimaryPolicy_fp.h"
+typedef TPM_RC (SetPrimaryPolicy_Entry)(
+ SetPrimaryPolicy_In *in
+ );
+typedef const struct {
+ SetPrimaryPolicy_Entry *entry;
+ UINT16 inSize;
+ UINT16 outSize;
+ UINT16 offsetOfTypes;
+ UINT16 paramOffsets[2];
+ BYTE types[5];
+} SetPrimaryPolicy_COMMAND_DESCRIPTOR_t;
+SetPrimaryPolicy_COMMAND_DESCRIPTOR_t _SetPrimaryPolicyData = {
+ /* entry */ &TPM2_SetPrimaryPolicy,
+ /* inSize */ (UINT16)(sizeof(SetPrimaryPolicy_In)),
+ /* outSize */ 0,
+ /* offsetOfTypes */ offsetof(SetPrimaryPolicy_COMMAND_DESCRIPTOR_t, types),
+ /* offsets */ {(UINT16)(offsetof(SetPrimaryPolicy_In, authPolicy)),
+ (UINT16)(offsetof(SetPrimaryPolicy_In, hashAlg))},
+ /* types */ {TPMI_RH_HIERARCHY_POLICY_H_UNMARSHAL,
+ TPM2B_DIGEST_P_UNMARSHAL,
+ TPMI_ALG_HASH_P_UNMARSHAL + ADD_FLAG,
+ END_OF_LIST,
+ END_OF_LIST}
+};
+#define _SetPrimaryPolicyDataAddress (&_SetPrimaryPolicyData)
+#else
+#define _SetPrimaryPolicyDataAddress 0
+#endif
+#if CC_ChangePPS
+#include "ChangePPS_fp.h"
+typedef TPM_RC (ChangePPS_Entry)(
+ ChangePPS_In *in
+ );
+typedef const struct {
+ ChangePPS_Entry *entry;
+ UINT16 inSize;
+ UINT16 outSize;
+ UINT16 offsetOfTypes;
+ BYTE types[3];
+} ChangePPS_COMMAND_DESCRIPTOR_t;
+ChangePPS_COMMAND_DESCRIPTOR_t _ChangePPSData = {
+ /* entry */ &TPM2_ChangePPS,
+ /* inSize */ (UINT16)(sizeof(ChangePPS_In)),
+ /* outSize */ 0,
+ /* offsetOfTypes */ offsetof(ChangePPS_COMMAND_DESCRIPTOR_t, types),
+ /* offsets */ // No parameter offsets
+ /* types */ {TPMI_RH_PLATFORM_H_UNMARSHAL,
+ END_OF_LIST,
+ END_OF_LIST}
+};
+#define _ChangePPSDataAddress (&_ChangePPSData)
+#else
+#define _ChangePPSDataAddress 0
+#endif
+#if CC_ChangeEPS
+#include "ChangeEPS_fp.h"
+typedef TPM_RC (ChangeEPS_Entry)(
+ ChangeEPS_In *in
+ );
+typedef const struct {
+ ChangeEPS_Entry *entry;
+ UINT16 inSize;
+ UINT16 outSize;
+ UINT16 offsetOfTypes;
+ BYTE types[3];
+} ChangeEPS_COMMAND_DESCRIPTOR_t;
+ChangeEPS_COMMAND_DESCRIPTOR_t _ChangeEPSData = {
+ /* entry */ &TPM2_ChangeEPS,
+ /* inSize */ (UINT16)(sizeof(ChangeEPS_In)),
+ /* outSize */ 0,
+ /* offsetOfTypes */ offsetof(ChangeEPS_COMMAND_DESCRIPTOR_t, types),
+ /* offsets */ // No parameter offsets
+ /* types */ {TPMI_RH_PLATFORM_H_UNMARSHAL,
+ END_OF_LIST,
+ END_OF_LIST}
+};
+#define _ChangeEPSDataAddress (&_ChangeEPSData)
+#else
+#define _ChangeEPSDataAddress 0
+#endif
+#if CC_Clear
+#include "Clear_fp.h"
+typedef TPM_RC (Clear_Entry)(
+ Clear_In *in
+ );
+typedef const struct {
+ Clear_Entry *entry;
+ UINT16 inSize;
+ UINT16 outSize;
+ UINT16 offsetOfTypes;
+ BYTE types[3];
+} Clear_COMMAND_DESCRIPTOR_t;
+Clear_COMMAND_DESCRIPTOR_t _ClearData = {
+ /* entry */ &TPM2_Clear,
+ /* inSize */ (UINT16)(sizeof(Clear_In)),
+ /* outSize */ 0,
+ /* offsetOfTypes */ offsetof(Clear_COMMAND_DESCRIPTOR_t, types),
+ /* offsets */ // No parameter offsets
+ /* types */ {TPMI_RH_CLEAR_H_UNMARSHAL,
+ END_OF_LIST,
+ END_OF_LIST}
+};
+#define _ClearDataAddress (&_ClearData)
+#else
+#define _ClearDataAddress 0
+#endif
+#if CC_ClearControl
+#include "ClearControl_fp.h"
+typedef TPM_RC (ClearControl_Entry)(
+ ClearControl_In *in
+ );
+typedef const struct {
+ ClearControl_Entry *entry;
+ UINT16 inSize;
+ UINT16 outSize;
+ UINT16 offsetOfTypes;
+ UINT16 paramOffsets[1];
+ BYTE types[4];
+} ClearControl_COMMAND_DESCRIPTOR_t;
+ClearControl_COMMAND_DESCRIPTOR_t _ClearControlData = {
+ /* entry */ &TPM2_ClearControl,
+ /* inSize */ (UINT16)(sizeof(ClearControl_In)),
+ /* outSize */ 0,
+ /* offsetOfTypes */ offsetof(ClearControl_COMMAND_DESCRIPTOR_t, types),
+ /* offsets */ {(UINT16)(offsetof(ClearControl_In, disable))},
+ /* types */ {TPMI_RH_CLEAR_H_UNMARSHAL,
+ TPMI_YES_NO_P_UNMARSHAL,
+ END_OF_LIST,
+ END_OF_LIST}
+};
+#define _ClearControlDataAddress (&_ClearControlData)
+#else
+#define _ClearControlDataAddress 0
+#endif
+#if CC_HierarchyChangeAuth
+#include "HierarchyChangeAuth_fp.h"
+typedef TPM_RC (HierarchyChangeAuth_Entry)(
+ HierarchyChangeAuth_In *in
+ );
+typedef const struct {
+ HierarchyChangeAuth_Entry *entry;
+ UINT16 inSize;
+ UINT16 outSize;
+ UINT16 offsetOfTypes;
+ UINT16 paramOffsets[1];
+ BYTE types[4];
+} HierarchyChangeAuth_COMMAND_DESCRIPTOR_t;
+HierarchyChangeAuth_COMMAND_DESCRIPTOR_t _HierarchyChangeAuthData = {
+ /* entry */ &TPM2_HierarchyChangeAuth,
+ /* inSize */ (UINT16)(sizeof(HierarchyChangeAuth_In)),
+ /* outSize */ 0,
+ /* offsetOfTypes */ offsetof(HierarchyChangeAuth_COMMAND_DESCRIPTOR_t, types),
+ /* offsets */ {(UINT16)(offsetof(HierarchyChangeAuth_In, newAuth))},
+ /* types */ {TPMI_RH_HIERARCHY_AUTH_H_UNMARSHAL,
+ TPM2B_AUTH_P_UNMARSHAL,
+ END_OF_LIST,
+ END_OF_LIST}
+};
+#define _HierarchyChangeAuthDataAddress (&_HierarchyChangeAuthData)
+#else
+#define _HierarchyChangeAuthDataAddress 0
+#endif
+#if CC_DictionaryAttackLockReset
+#include "DictionaryAttackLockReset_fp.h"
+typedef TPM_RC (DictionaryAttackLockReset_Entry)(
+ DictionaryAttackLockReset_In *in
+ );
+typedef const struct {
+ DictionaryAttackLockReset_Entry *entry;
+ UINT16 inSize;
+ UINT16 outSize;
+ UINT16 offsetOfTypes;
+ BYTE types[3];
+} DictionaryAttackLockReset_COMMAND_DESCRIPTOR_t;
+DictionaryAttackLockReset_COMMAND_DESCRIPTOR_t _DictionaryAttackLockResetData = {
+ /* entry */ &TPM2_DictionaryAttackLockReset,
+ /* inSize */ (UINT16)(sizeof(DictionaryAttackLockReset_In)),
+ /* outSize */ 0,
+ /* offsetOfTypes */ offsetof(DictionaryAttackLockReset_COMMAND_DESCRIPTOR_t, types),
+ /* offsets */ // No parameter offsets
+ /* types */ {TPMI_RH_LOCKOUT_H_UNMARSHAL,
+ END_OF_LIST,
+ END_OF_LIST}
+};
+#define _DictionaryAttackLockResetDataAddress (&_DictionaryAttackLockResetData)
+#else
+#define _DictionaryAttackLockResetDataAddress 0
+#endif
+#if CC_DictionaryAttackParameters
+#include "DictionaryAttackParameters_fp.h"
+typedef TPM_RC (DictionaryAttackParameters_Entry)(
+ DictionaryAttackParameters_In *in
+ );
+typedef const struct {
+ DictionaryAttackParameters_Entry *entry;
+ UINT16 inSize;
+ UINT16 outSize;
+ UINT16 offsetOfTypes;
+ UINT16 paramOffsets[3];
+ BYTE types[6];
+} DictionaryAttackParameters_COMMAND_DESCRIPTOR_t;
+DictionaryAttackParameters_COMMAND_DESCRIPTOR_t _DictionaryAttackParametersData = {
+ /* entry */ &TPM2_DictionaryAttackParameters,
+ /* inSize */ (UINT16)(sizeof(DictionaryAttackParameters_In)),
+ /* outSize */ 0,
+ /* offsetOfTypes */ offsetof(DictionaryAttackParameters_COMMAND_DESCRIPTOR_t, types),
+ /* offsets */ {(UINT16)(offsetof(DictionaryAttackParameters_In, newMaxTries)),
+ (UINT16)(offsetof(DictionaryAttackParameters_In, newRecoveryTime)),
+ (UINT16)(offsetof(DictionaryAttackParameters_In, lockoutRecovery))},
+ /* types */ {TPMI_RH_LOCKOUT_H_UNMARSHAL,
+ UINT32_P_UNMARSHAL,
+ UINT32_P_UNMARSHAL,
+ UINT32_P_UNMARSHAL,
+ END_OF_LIST,
+ END_OF_LIST}
+};
+#define _DictionaryAttackParametersDataAddress (&_DictionaryAttackParametersData)
+#else
+#define _DictionaryAttackParametersDataAddress 0
+#endif
+#if CC_PP_Commands
+#include "PP_Commands_fp.h"
+typedef TPM_RC (PP_Commands_Entry)(
+ PP_Commands_In *in
+ );
+typedef const struct {
+ PP_Commands_Entry *entry;
+ UINT16 inSize;
+ UINT16 outSize;
+ UINT16 offsetOfTypes;
+ UINT16 paramOffsets[2];
+ BYTE types[5];
+} PP_Commands_COMMAND_DESCRIPTOR_t;
+PP_Commands_COMMAND_DESCRIPTOR_t _PP_CommandsData = {
+ /* entry */ &TPM2_PP_Commands,
+ /* inSize */ (UINT16)(sizeof(PP_Commands_In)),
+ /* outSize */ 0,
+ /* offsetOfTypes */ offsetof(PP_Commands_COMMAND_DESCRIPTOR_t, types),
+ /* offsets */ {(UINT16)(offsetof(PP_Commands_In, setList)),
+ (UINT16)(offsetof(PP_Commands_In, clearList))},
+ /* types */ {TPMI_RH_PLATFORM_H_UNMARSHAL,
+ TPML_CC_P_UNMARSHAL,
+ TPML_CC_P_UNMARSHAL,
+ END_OF_LIST,
+ END_OF_LIST}
+};
+#define _PP_CommandsDataAddress (&_PP_CommandsData)
+#else
+#define _PP_CommandsDataAddress 0
+#endif
+#if CC_SetAlgorithmSet
+#include "SetAlgorithmSet_fp.h"
+typedef TPM_RC (SetAlgorithmSet_Entry)(
+ SetAlgorithmSet_In *in
+ );
+typedef const struct {
+ SetAlgorithmSet_Entry *entry;
+ UINT16 inSize;
+ UINT16 outSize;
+ UINT16 offsetOfTypes;
+ UINT16 paramOffsets[1];
+ BYTE types[4];
+} SetAlgorithmSet_COMMAND_DESCRIPTOR_t;
+SetAlgorithmSet_COMMAND_DESCRIPTOR_t _SetAlgorithmSetData = {
+ /* entry */ &TPM2_SetAlgorithmSet,
+ /* inSize */ (UINT16)(sizeof(SetAlgorithmSet_In)),
+ /* outSize */ 0,
+ /* offsetOfTypes */ offsetof(SetAlgorithmSet_COMMAND_DESCRIPTOR_t, types),
+ /* offsets */ {(UINT16)(offsetof(SetAlgorithmSet_In, algorithmSet))},
+ /* types */ {TPMI_RH_PLATFORM_H_UNMARSHAL,
+ UINT32_P_UNMARSHAL,
+ END_OF_LIST,
+ END_OF_LIST}
+};
+#define _SetAlgorithmSetDataAddress (&_SetAlgorithmSetData)
+#else
+#define _SetAlgorithmSetDataAddress 0
+#endif
+#if CC_FieldUpgradeStart
+#include "FieldUpgradeStart_fp.h"
+typedef TPM_RC (FieldUpgradeStart_Entry)(
+ FieldUpgradeStart_In *in
+ );
+typedef const struct {
+ FieldUpgradeStart_Entry *entry;
+ UINT16 inSize;
+ UINT16 outSize;
+ UINT16 offsetOfTypes;
+ UINT16 paramOffsets[3];
+ BYTE types[6];
+} FieldUpgradeStart_COMMAND_DESCRIPTOR_t;
+FieldUpgradeStart_COMMAND_DESCRIPTOR_t _FieldUpgradeStartData = {
+ /* entry */ &TPM2_FieldUpgradeStart,
+ /* inSize */ (UINT16)(sizeof(FieldUpgradeStart_In)),
+ /* outSize */ 0,
+ /* offsetOfTypes */ offsetof(FieldUpgradeStart_COMMAND_DESCRIPTOR_t, types),
+ /* offsets */ {(UINT16)(offsetof(FieldUpgradeStart_In, keyHandle)),
+ (UINT16)(offsetof(FieldUpgradeStart_In, fuDigest)),
+ (UINT16)(offsetof(FieldUpgradeStart_In, manifestSignature))},
+ /* types */ {TPMI_RH_PLATFORM_H_UNMARSHAL,
+ TPMI_DH_OBJECT_H_UNMARSHAL,
+ TPM2B_DIGEST_P_UNMARSHAL,
+ TPMT_SIGNATURE_P_UNMARSHAL,
+ END_OF_LIST,
+ END_OF_LIST}
+};
+#define _FieldUpgradeStartDataAddress (&_FieldUpgradeStartData)
+#else
+#define _FieldUpgradeStartDataAddress 0
+#endif
+#if CC_FieldUpgradeData
+#include "FieldUpgradeData_fp.h"
+typedef TPM_RC (FieldUpgradeData_Entry)(
+ FieldUpgradeData_In *in,
+ FieldUpgradeData_Out *out
+ );
+typedef const struct {
+ FieldUpgradeData_Entry *entry;
+ UINT16 inSize;
+ UINT16 outSize;
+ UINT16 offsetOfTypes;
+ UINT16 paramOffsets[1];
+ BYTE types[5];
+} FieldUpgradeData_COMMAND_DESCRIPTOR_t;
+FieldUpgradeData_COMMAND_DESCRIPTOR_t _FieldUpgradeDataData = {
+ /* entry */ &TPM2_FieldUpgradeData,
+ /* inSize */ (UINT16)(sizeof(FieldUpgradeData_In)),
+ /* outSize */ (UINT16)(sizeof(FieldUpgradeData_Out)),
+ /* offsetOfTypes */ offsetof(FieldUpgradeData_COMMAND_DESCRIPTOR_t, types),
+ /* offsets */ {(UINT16)(offsetof(FieldUpgradeData_Out, firstDigest))},
+ /* types */ {TPM2B_MAX_BUFFER_P_UNMARSHAL,
+ END_OF_LIST,
+ TPMT_HA_P_MARSHAL,
+ TPMT_HA_P_MARSHAL,
+ END_OF_LIST}
+};
+#define _FieldUpgradeDataDataAddress (&_FieldUpgradeDataData)
+#else
+#define _FieldUpgradeDataDataAddress 0
+#endif
+#if CC_FirmwareRead
+#include "FirmwareRead_fp.h"
+typedef TPM_RC (FirmwareRead_Entry)(
+ FirmwareRead_In *in,
+ FirmwareRead_Out *out
+ );
+typedef const struct {
+ FirmwareRead_Entry *entry;
+ UINT16 inSize;
+ UINT16 outSize;
+ UINT16 offsetOfTypes;
+ BYTE types[4];
+} FirmwareRead_COMMAND_DESCRIPTOR_t;
+FirmwareRead_COMMAND_DESCRIPTOR_t _FirmwareReadData = {
+ /* entry */ &TPM2_FirmwareRead,
+ /* inSize */ (UINT16)(sizeof(FirmwareRead_In)),
+ /* outSize */ (UINT16)(sizeof(FirmwareRead_Out)),
+ /* offsetOfTypes */ offsetof(FirmwareRead_COMMAND_DESCRIPTOR_t, types),
+ /* offsets */ // No parameter offsets
+ /* types */ {UINT32_P_UNMARSHAL,
+ END_OF_LIST,
+ TPM2B_MAX_BUFFER_P_MARSHAL,
+ END_OF_LIST}
+};
+#define _FirmwareReadDataAddress (&_FirmwareReadData)
+#else
+#define _FirmwareReadDataAddress 0
+#endif
+#if CC_ContextSave
+#include "ContextSave_fp.h"
+typedef TPM_RC (ContextSave_Entry)(
+ ContextSave_In *in,
+ ContextSave_Out *out
+ );
+typedef const struct {
+ ContextSave_Entry *entry;
+ UINT16 inSize;
+ UINT16 outSize;
+ UINT16 offsetOfTypes;
+ BYTE types[4];
+} ContextSave_COMMAND_DESCRIPTOR_t;
+ContextSave_COMMAND_DESCRIPTOR_t _ContextSaveData = {
+ /* entry */ &TPM2_ContextSave,
+ /* inSize */ (UINT16)(sizeof(ContextSave_In)),
+ /* outSize */ (UINT16)(sizeof(ContextSave_Out)),
+ /* offsetOfTypes */ offsetof(ContextSave_COMMAND_DESCRIPTOR_t, types),
+ /* offsets */ // No parameter offsets
+ /* types */ {TPMI_DH_CONTEXT_H_UNMARSHAL,
+ END_OF_LIST,
+ TPMS_CONTEXT_P_MARSHAL,
+ END_OF_LIST}
+};
+#define _ContextSaveDataAddress (&_ContextSaveData)
+#else
+#define _ContextSaveDataAddress 0
+#endif
+#if CC_ContextLoad
+#include "ContextLoad_fp.h"
+typedef TPM_RC (ContextLoad_Entry)(
+ ContextLoad_In *in,
+ ContextLoad_Out *out
+ );
+typedef const struct {
+ ContextLoad_Entry *entry;
+ UINT16 inSize;
+ UINT16 outSize;
+ UINT16 offsetOfTypes;
+ BYTE types[4];
+} ContextLoad_COMMAND_DESCRIPTOR_t;
+ContextLoad_COMMAND_DESCRIPTOR_t _ContextLoadData = {
+ /* entry */ &TPM2_ContextLoad,
+ /* inSize */ (UINT16)(sizeof(ContextLoad_In)),
+ /* outSize */ (UINT16)(sizeof(ContextLoad_Out)),
+ /* offsetOfTypes */ offsetof(ContextLoad_COMMAND_DESCRIPTOR_t, types),
+ /* offsets */ // No parameter offsets
+ /* types */ {TPMS_CONTEXT_P_UNMARSHAL,
+ END_OF_LIST,
+ TPMI_DH_CONTEXT_H_MARSHAL,
+ END_OF_LIST}
+};
+#define _ContextLoadDataAddress (&_ContextLoadData)
+#else
+#define _ContextLoadDataAddress 0
+#endif
+#if CC_FlushContext
+#include "FlushContext_fp.h"
+typedef TPM_RC (FlushContext_Entry)(
+ FlushContext_In *in
+ );
+typedef const struct {
+ FlushContext_Entry *entry;
+ UINT16 inSize;
+ UINT16 outSize;
+ UINT16 offsetOfTypes;
+ BYTE types[3];
+} FlushContext_COMMAND_DESCRIPTOR_t;
+FlushContext_COMMAND_DESCRIPTOR_t _FlushContextData = {
+ /* entry */ &TPM2_FlushContext,
+ /* inSize */ (UINT16)(sizeof(FlushContext_In)),
+ /* outSize */ 0,
+ /* offsetOfTypes */ offsetof(FlushContext_COMMAND_DESCRIPTOR_t, types),
+ /* offsets */ // No parameter offsets
+ /* types */ {TPMI_DH_CONTEXT_P_UNMARSHAL,
+ END_OF_LIST,
+ END_OF_LIST}
+};
+#define _FlushContextDataAddress (&_FlushContextData)
+#else
+#define _FlushContextDataAddress 0
+#endif
+#if CC_EvictControl
+#include "EvictControl_fp.h"
+typedef TPM_RC (EvictControl_Entry)(
+ EvictControl_In *in
+ );
+typedef const struct {
+ EvictControl_Entry *entry;
+ UINT16 inSize;
+ UINT16 outSize;
+ UINT16 offsetOfTypes;
+ UINT16 paramOffsets[2];
+ BYTE types[5];
+} EvictControl_COMMAND_DESCRIPTOR_t;
+EvictControl_COMMAND_DESCRIPTOR_t _EvictControlData = {
+ /* entry */ &TPM2_EvictControl,
+ /* inSize */ (UINT16)(sizeof(EvictControl_In)),
+ /* outSize */ 0,
+ /* offsetOfTypes */ offsetof(EvictControl_COMMAND_DESCRIPTOR_t, types),
+ /* offsets */ {(UINT16)(offsetof(EvictControl_In, objectHandle)),
+ (UINT16)(offsetof(EvictControl_In, persistentHandle))},
+ /* types */ {TPMI_RH_PROVISION_H_UNMARSHAL,
+ TPMI_DH_OBJECT_H_UNMARSHAL,
+ TPMI_DH_PERSISTENT_P_UNMARSHAL,
+ END_OF_LIST,
+ END_OF_LIST}
+};
+#define _EvictControlDataAddress (&_EvictControlData)
+#else
+#define _EvictControlDataAddress 0
+#endif
+#if CC_ReadClock
+#include "ReadClock_fp.h"
+typedef TPM_RC (ReadClock_Entry)(
+ ReadClock_Out *out
+ );
+typedef const struct {
+ ReadClock_Entry *entry;
+ UINT16 inSize;
+ UINT16 outSize;
+ UINT16 offsetOfTypes;
+ BYTE types[3];
+} ReadClock_COMMAND_DESCRIPTOR_t;
+ReadClock_COMMAND_DESCRIPTOR_t _ReadClockData = {
+ /* entry */ &TPM2_ReadClock,
+ /* inSize */ 0,
+ /* outSize */ (UINT16)(sizeof(ReadClock_Out)),
+ /* offsetOfTypes */ offsetof(ReadClock_COMMAND_DESCRIPTOR_t, types),
+ /* offsets */ // No parameter offsets
+ /* types */ {END_OF_LIST,
+ TPMS_TIME_INFO_P_MARSHAL,
+ END_OF_LIST}
+};
+#define _ReadClockDataAddress (&_ReadClockData)
+#else
+#define _ReadClockDataAddress 0
+#endif
+#if CC_ClockSet
+#include "ClockSet_fp.h"
+typedef TPM_RC (ClockSet_Entry)(
+ ClockSet_In *in
+ );
+typedef const struct {
+ ClockSet_Entry *entry;
+ UINT16 inSize;
+ UINT16 outSize;
+ UINT16 offsetOfTypes;
+ UINT16 paramOffsets[1];
+ BYTE types[4];
+} ClockSet_COMMAND_DESCRIPTOR_t;
+ClockSet_COMMAND_DESCRIPTOR_t _ClockSetData = {
+ /* entry */ &TPM2_ClockSet,
+ /* inSize */ (UINT16)(sizeof(ClockSet_In)),
+ /* outSize */ 0,
+ /* offsetOfTypes */ offsetof(ClockSet_COMMAND_DESCRIPTOR_t, types),
+ /* offsets */ {(UINT16)(offsetof(ClockSet_In, newTime))},
+ /* types */ {TPMI_RH_PROVISION_H_UNMARSHAL,
+ UINT64_P_UNMARSHAL,
+ END_OF_LIST,
+ END_OF_LIST}
+};
+#define _ClockSetDataAddress (&_ClockSetData)
+#else
+#define _ClockSetDataAddress 0
+#endif
+#if CC_ClockRateAdjust
+#include "ClockRateAdjust_fp.h"
+typedef TPM_RC (ClockRateAdjust_Entry)(
+ ClockRateAdjust_In *in
+ );
+typedef const struct {
+ ClockRateAdjust_Entry *entry;
+ UINT16 inSize;
+ UINT16 outSize;
+ UINT16 offsetOfTypes;
+ UINT16 paramOffsets[1];
+ BYTE types[4];
+} ClockRateAdjust_COMMAND_DESCRIPTOR_t;
+ClockRateAdjust_COMMAND_DESCRIPTOR_t _ClockRateAdjustData = {
+ /* entry */ &TPM2_ClockRateAdjust,
+ /* inSize */ (UINT16)(sizeof(ClockRateAdjust_In)),
+ /* outSize */ 0,
+ /* offsetOfTypes */ offsetof(ClockRateAdjust_COMMAND_DESCRIPTOR_t, types),
+ /* offsets */ {(UINT16)(offsetof(ClockRateAdjust_In, rateAdjust))},
+ /* types */ {TPMI_RH_PROVISION_H_UNMARSHAL,
+ TPM_CLOCK_ADJUST_P_UNMARSHAL,
+ END_OF_LIST,
+ END_OF_LIST}
+};
+#define _ClockRateAdjustDataAddress (&_ClockRateAdjustData)
+#else
+#define _ClockRateAdjustDataAddress 0
+#endif
+#if CC_GetCapability
+#include "GetCapability_fp.h"
+typedef TPM_RC (GetCapability_Entry)(
+ GetCapability_In *in,
+ GetCapability_Out *out
+ );
+typedef const struct {
+ GetCapability_Entry *entry;
+ UINT16 inSize;
+ UINT16 outSize;
+ UINT16 offsetOfTypes;
+ UINT16 paramOffsets[3];
+ BYTE types[7];
+} GetCapability_COMMAND_DESCRIPTOR_t;
+GetCapability_COMMAND_DESCRIPTOR_t _GetCapabilityData = {
+ /* entry */ &TPM2_GetCapability,
+ /* inSize */ (UINT16)(sizeof(GetCapability_In)),
+ /* outSize */ (UINT16)(sizeof(GetCapability_Out)),
+ /* offsetOfTypes */ offsetof(GetCapability_COMMAND_DESCRIPTOR_t, types),
+ /* offsets */ {(UINT16)(offsetof(GetCapability_In, property)),
+ (UINT16)(offsetof(GetCapability_In, propertyCount)),
+ (UINT16)(offsetof(GetCapability_Out, capabilityData))},
+ /* types */ {TPM_CAP_P_UNMARSHAL,
+ UINT32_P_UNMARSHAL,
+ UINT32_P_UNMARSHAL,
+ END_OF_LIST,
+ TPMI_YES_NO_P_MARSHAL,
+ TPMS_CAPABILITY_DATA_P_MARSHAL,
+ END_OF_LIST}
+};
+#define _GetCapabilityDataAddress (&_GetCapabilityData)
+#else
+#define _GetCapabilityDataAddress 0
+#endif
+#if CC_TestParms
+#include "TestParms_fp.h"
+typedef TPM_RC (TestParms_Entry)(
+ TestParms_In *in
+ );
+typedef const struct {
+ TestParms_Entry *entry;
+ UINT16 inSize;
+ UINT16 outSize;
+ UINT16 offsetOfTypes;
+ BYTE types[3];
+} TestParms_COMMAND_DESCRIPTOR_t;
+TestParms_COMMAND_DESCRIPTOR_t _TestParmsData = {
+ /* entry */ &TPM2_TestParms,
+ /* inSize */ (UINT16)(sizeof(TestParms_In)),
+ /* outSize */ 0,
+ /* offsetOfTypes */ offsetof(TestParms_COMMAND_DESCRIPTOR_t, types),
+ /* offsets */ // No parameter offsets
+ /* types */ {TPMT_PUBLIC_PARMS_P_UNMARSHAL,
+ END_OF_LIST,
+ END_OF_LIST}
+};
+#define _TestParmsDataAddress (&_TestParmsData)
+#else
+#define _TestParmsDataAddress 0
+#endif
+#if CC_NV_DefineSpace
+#include "NV_DefineSpace_fp.h"
+typedef TPM_RC (NV_DefineSpace_Entry)(
+ NV_DefineSpace_In *in
+ );
+typedef const struct {
+ NV_DefineSpace_Entry *entry;
+ UINT16 inSize;
+ UINT16 outSize;
+ UINT16 offsetOfTypes;
+ UINT16 paramOffsets[2];
+ BYTE types[5];
+} NV_DefineSpace_COMMAND_DESCRIPTOR_t;
+NV_DefineSpace_COMMAND_DESCRIPTOR_t _NV_DefineSpaceData = {
+ /* entry */ &TPM2_NV_DefineSpace,
+ /* inSize */ (UINT16)(sizeof(NV_DefineSpace_In)),
+ /* outSize */ 0,
+ /* offsetOfTypes */ offsetof(NV_DefineSpace_COMMAND_DESCRIPTOR_t, types),
+ /* offsets */ {(UINT16)(offsetof(NV_DefineSpace_In, auth)),
+ (UINT16)(offsetof(NV_DefineSpace_In, publicInfo))},
+ /* types */ {TPMI_RH_PROVISION_H_UNMARSHAL,
+ TPM2B_AUTH_P_UNMARSHAL,
+ TPM2B_NV_PUBLIC_P_UNMARSHAL,
+ END_OF_LIST,
+ END_OF_LIST}
+};
+#define _NV_DefineSpaceDataAddress (&_NV_DefineSpaceData)
+#else
+#define _NV_DefineSpaceDataAddress 0
+#endif
+#if CC_NV_UndefineSpace
+#include "NV_UndefineSpace_fp.h"
+typedef TPM_RC (NV_UndefineSpace_Entry)(
+ NV_UndefineSpace_In *in
+ );
+typedef const struct {
+ NV_UndefineSpace_Entry *entry;
+ UINT16 inSize;
+ UINT16 outSize;
+ UINT16 offsetOfTypes;
+ UINT16 paramOffsets[1];
+ BYTE types[4];
+} NV_UndefineSpace_COMMAND_DESCRIPTOR_t;
+NV_UndefineSpace_COMMAND_DESCRIPTOR_t _NV_UndefineSpaceData = {
+ /* entry */ &TPM2_NV_UndefineSpace,
+ /* inSize */ (UINT16)(sizeof(NV_UndefineSpace_In)),
+ /* outSize */ 0,
+ /* offsetOfTypes */ offsetof(NV_UndefineSpace_COMMAND_DESCRIPTOR_t, types),
+ /* offsets */ {(UINT16)(offsetof(NV_UndefineSpace_In, nvIndex))},
+ /* types */ {TPMI_RH_PROVISION_H_UNMARSHAL,
+ TPMI_RH_NV_INDEX_H_UNMARSHAL,
+ END_OF_LIST,
+ END_OF_LIST}
+};
+#define _NV_UndefineSpaceDataAddress (&_NV_UndefineSpaceData)
+#else
+#define _NV_UndefineSpaceDataAddress 0
+#endif
+#if CC_NV_UndefineSpaceSpecial
+#include "NV_UndefineSpaceSpecial_fp.h"
+typedef TPM_RC (NV_UndefineSpaceSpecial_Entry)(
+ NV_UndefineSpaceSpecial_In *in
+ );
+typedef const struct {
+ NV_UndefineSpaceSpecial_Entry *entry;
+ UINT16 inSize;
+ UINT16 outSize;
+ UINT16 offsetOfTypes;
+ UINT16 paramOffsets[1];
+ BYTE types[4];
+} NV_UndefineSpaceSpecial_COMMAND_DESCRIPTOR_t;
+NV_UndefineSpaceSpecial_COMMAND_DESCRIPTOR_t _NV_UndefineSpaceSpecialData = {
+ /* entry */ &TPM2_NV_UndefineSpaceSpecial,
+ /* inSize */ (UINT16)(sizeof(NV_UndefineSpaceSpecial_In)),
+ /* outSize */ 0,
+ /* offsetOfTypes */ offsetof(NV_UndefineSpaceSpecial_COMMAND_DESCRIPTOR_t, types),
+ /* offsets */ {(UINT16)(offsetof(NV_UndefineSpaceSpecial_In, platform))},
+ /* types */ {TPMI_RH_NV_INDEX_H_UNMARSHAL,
+ TPMI_RH_PLATFORM_H_UNMARSHAL,
+ END_OF_LIST,
+ END_OF_LIST}
+};
+#define _NV_UndefineSpaceSpecialDataAddress (&_NV_UndefineSpaceSpecialData)
+#else
+#define _NV_UndefineSpaceSpecialDataAddress 0
+#endif
+#if CC_NV_ReadPublic
+#include "NV_ReadPublic_fp.h"
+typedef TPM_RC (NV_ReadPublic_Entry)(
+ NV_ReadPublic_In *in,
+ NV_ReadPublic_Out *out
+ );
+typedef const struct {
+ NV_ReadPublic_Entry *entry;
+ UINT16 inSize;
+ UINT16 outSize;
+ UINT16 offsetOfTypes;
+ UINT16 paramOffsets[1];
+ BYTE types[5];
+} NV_ReadPublic_COMMAND_DESCRIPTOR_t;
+NV_ReadPublic_COMMAND_DESCRIPTOR_t _NV_ReadPublicData = {
+ /* entry */ &TPM2_NV_ReadPublic,
+ /* inSize */ (UINT16)(sizeof(NV_ReadPublic_In)),
+ /* outSize */ (UINT16)(sizeof(NV_ReadPublic_Out)),
+ /* offsetOfTypes */ offsetof(NV_ReadPublic_COMMAND_DESCRIPTOR_t, types),
+ /* offsets */ {(UINT16)(offsetof(NV_ReadPublic_Out, nvName))},
+ /* types */ {TPMI_RH_NV_INDEX_H_UNMARSHAL,
+ END_OF_LIST,
+ TPM2B_NV_PUBLIC_P_MARSHAL,
+ TPM2B_NAME_P_MARSHAL,
+ END_OF_LIST}
+};
+#define _NV_ReadPublicDataAddress (&_NV_ReadPublicData)
+#else
+#define _NV_ReadPublicDataAddress 0
+#endif
+#if CC_NV_Write
+#include "NV_Write_fp.h"
+typedef TPM_RC (NV_Write_Entry)(
+ NV_Write_In *in
+ );
+typedef const struct {
+ NV_Write_Entry *entry;
+ UINT16 inSize;
+ UINT16 outSize;
+ UINT16 offsetOfTypes;
+ UINT16 paramOffsets[3];
+ BYTE types[6];
+} NV_Write_COMMAND_DESCRIPTOR_t;
+NV_Write_COMMAND_DESCRIPTOR_t _NV_WriteData = {
+ /* entry */ &TPM2_NV_Write,
+ /* inSize */ (UINT16)(sizeof(NV_Write_In)),
+ /* outSize */ 0,
+ /* offsetOfTypes */ offsetof(NV_Write_COMMAND_DESCRIPTOR_t, types),
+ /* offsets */ {(UINT16)(offsetof(NV_Write_In, nvIndex)),
+ (UINT16)(offsetof(NV_Write_In, data)),
+ (UINT16)(offsetof(NV_Write_In, offset))},
+ /* types */ {TPMI_RH_NV_AUTH_H_UNMARSHAL,
+ TPMI_RH_NV_INDEX_H_UNMARSHAL,
+ TPM2B_MAX_NV_BUFFER_P_UNMARSHAL,
+ UINT16_P_UNMARSHAL,
+ END_OF_LIST,
+ END_OF_LIST}
+};
+#define _NV_WriteDataAddress (&_NV_WriteData)
+#else
+#define _NV_WriteDataAddress 0
+#endif
+#if CC_NV_Increment
+#include "NV_Increment_fp.h"
+typedef TPM_RC (NV_Increment_Entry)(
+ NV_Increment_In *in
+ );
+typedef const struct {
+ NV_Increment_Entry *entry;
+ UINT16 inSize;
+ UINT16 outSize;
+ UINT16 offsetOfTypes;
+ UINT16 paramOffsets[1];
+ BYTE types[4];
+} NV_Increment_COMMAND_DESCRIPTOR_t;
+NV_Increment_COMMAND_DESCRIPTOR_t _NV_IncrementData = {
+ /* entry */ &TPM2_NV_Increment,
+ /* inSize */ (UINT16)(sizeof(NV_Increment_In)),
+ /* outSize */ 0,
+ /* offsetOfTypes */ offsetof(NV_Increment_COMMAND_DESCRIPTOR_t, types),
+ /* offsets */ {(UINT16)(offsetof(NV_Increment_In, nvIndex))},
+ /* types */ {TPMI_RH_NV_AUTH_H_UNMARSHAL,
+ TPMI_RH_NV_INDEX_H_UNMARSHAL,
+ END_OF_LIST,
+ END_OF_LIST}
+};
+#define _NV_IncrementDataAddress (&_NV_IncrementData)
+#else
+#define _NV_IncrementDataAddress 0
+#endif
+#if CC_NV_Extend
+#include "NV_Extend_fp.h"
+typedef TPM_RC (NV_Extend_Entry)(
+ NV_Extend_In *in
+ );
+typedef const struct {
+ NV_Extend_Entry *entry;
+ UINT16 inSize;
+ UINT16 outSize;
+ UINT16 offsetOfTypes;
+ UINT16 paramOffsets[2];
+ BYTE types[5];
+} NV_Extend_COMMAND_DESCRIPTOR_t;
+NV_Extend_COMMAND_DESCRIPTOR_t _NV_ExtendData = {
+ /* entry */ &TPM2_NV_Extend,
+ /* inSize */ (UINT16)(sizeof(NV_Extend_In)),
+ /* outSize */ 0,
+ /* offsetOfTypes */ offsetof(NV_Extend_COMMAND_DESCRIPTOR_t, types),
+ /* offsets */ {(UINT16)(offsetof(NV_Extend_In, nvIndex)),
+ (UINT16)(offsetof(NV_Extend_In, data))},
+ /* types */ {TPMI_RH_NV_AUTH_H_UNMARSHAL,
+ TPMI_RH_NV_INDEX_H_UNMARSHAL,
+ TPM2B_MAX_NV_BUFFER_P_UNMARSHAL,
+ END_OF_LIST,
+ END_OF_LIST}
+};
+#define _NV_ExtendDataAddress (&_NV_ExtendData)
+#else
+#define _NV_ExtendDataAddress 0
+#endif
+#if CC_NV_SetBits
+#include "NV_SetBits_fp.h"
+typedef TPM_RC (NV_SetBits_Entry)(
+ NV_SetBits_In *in
+ );
+typedef const struct {
+ NV_SetBits_Entry *entry;
+ UINT16 inSize;
+ UINT16 outSize;
+ UINT16 offsetOfTypes;
+ UINT16 paramOffsets[2];
+ BYTE types[5];
+} NV_SetBits_COMMAND_DESCRIPTOR_t;
+NV_SetBits_COMMAND_DESCRIPTOR_t _NV_SetBitsData = {
+ /* entry */ &TPM2_NV_SetBits,
+ /* inSize */ (UINT16)(sizeof(NV_SetBits_In)),
+ /* outSize */ 0,
+ /* offsetOfTypes */ offsetof(NV_SetBits_COMMAND_DESCRIPTOR_t, types),
+ /* offsets */ {(UINT16)(offsetof(NV_SetBits_In, nvIndex)),
+ (UINT16)(offsetof(NV_SetBits_In, bits))},
+ /* types */ {TPMI_RH_NV_AUTH_H_UNMARSHAL,
+ TPMI_RH_NV_INDEX_H_UNMARSHAL,
+ UINT64_P_UNMARSHAL,
+ END_OF_LIST,
+ END_OF_LIST}
+};
+#define _NV_SetBitsDataAddress (&_NV_SetBitsData)
+#else
+#define _NV_SetBitsDataAddress 0
+#endif
+#if CC_NV_WriteLock
+#include "NV_WriteLock_fp.h"
+typedef TPM_RC (NV_WriteLock_Entry)(
+ NV_WriteLock_In *in
+ );
+typedef const struct {
+ NV_WriteLock_Entry *entry;
+ UINT16 inSize;
+ UINT16 outSize;
+ UINT16 offsetOfTypes;
+ UINT16 paramOffsets[1];
+ BYTE types[4];
+} NV_WriteLock_COMMAND_DESCRIPTOR_t;
+NV_WriteLock_COMMAND_DESCRIPTOR_t _NV_WriteLockData = {
+ /* entry */ &TPM2_NV_WriteLock,
+ /* inSize */ (UINT16)(sizeof(NV_WriteLock_In)),
+ /* outSize */ 0,
+ /* offsetOfTypes */ offsetof(NV_WriteLock_COMMAND_DESCRIPTOR_t, types),
+ /* offsets */ {(UINT16)(offsetof(NV_WriteLock_In, nvIndex))},
+ /* types */ {TPMI_RH_NV_AUTH_H_UNMARSHAL,
+ TPMI_RH_NV_INDEX_H_UNMARSHAL,
+ END_OF_LIST,
+ END_OF_LIST}
+};
+#define _NV_WriteLockDataAddress (&_NV_WriteLockData)
+#else
+#define _NV_WriteLockDataAddress 0
+#endif
+#if CC_NV_GlobalWriteLock
+#include "NV_GlobalWriteLock_fp.h"
+typedef TPM_RC (NV_GlobalWriteLock_Entry)(
+ NV_GlobalWriteLock_In *in
+ );
+typedef const struct {
+ NV_GlobalWriteLock_Entry *entry;
+ UINT16 inSize;
+ UINT16 outSize;
+ UINT16 offsetOfTypes;
+ BYTE types[3];
+} NV_GlobalWriteLock_COMMAND_DESCRIPTOR_t;
+NV_GlobalWriteLock_COMMAND_DESCRIPTOR_t _NV_GlobalWriteLockData = {
+ /* entry */ &TPM2_NV_GlobalWriteLock,
+ /* inSize */ (UINT16)(sizeof(NV_GlobalWriteLock_In)),
+ /* outSize */ 0,
+ /* offsetOfTypes */ offsetof(NV_GlobalWriteLock_COMMAND_DESCRIPTOR_t, types),
+ /* offsets */ // No parameter offsets
+ /* types */ {TPMI_RH_PROVISION_H_UNMARSHAL,
+ END_OF_LIST,
+ END_OF_LIST}
+};
+#define _NV_GlobalWriteLockDataAddress (&_NV_GlobalWriteLockData)
+#else
+#define _NV_GlobalWriteLockDataAddress 0
+#endif
+#if CC_NV_Read
+#include "NV_Read_fp.h"
+typedef TPM_RC (NV_Read_Entry)(
+ NV_Read_In *in,
+ NV_Read_Out *out
+ );
+typedef const struct {
+ NV_Read_Entry *entry;
+ UINT16 inSize;
+ UINT16 outSize;
+ UINT16 offsetOfTypes;
+ UINT16 paramOffsets[3];
+ BYTE types[7];
+} NV_Read_COMMAND_DESCRIPTOR_t;
+NV_Read_COMMAND_DESCRIPTOR_t _NV_ReadData = {
+ /* entry */ &TPM2_NV_Read,
+ /* inSize */ (UINT16)(sizeof(NV_Read_In)),
+ /* outSize */ (UINT16)(sizeof(NV_Read_Out)),
+ /* offsetOfTypes */ offsetof(NV_Read_COMMAND_DESCRIPTOR_t, types),
+ /* offsets */ {(UINT16)(offsetof(NV_Read_In, nvIndex)),
+ (UINT16)(offsetof(NV_Read_In, size)),
+ (UINT16)(offsetof(NV_Read_In, offset))},
+ /* types */ {TPMI_RH_NV_AUTH_H_UNMARSHAL,
+ TPMI_RH_NV_INDEX_H_UNMARSHAL,
+ UINT16_P_UNMARSHAL,
+ UINT16_P_UNMARSHAL,
+ END_OF_LIST,
+ TPM2B_MAX_NV_BUFFER_P_MARSHAL,
+ END_OF_LIST}
+};
+#define _NV_ReadDataAddress (&_NV_ReadData)
+#else
+#define _NV_ReadDataAddress 0
+#endif
+#if CC_NV_ReadLock
+#include "NV_ReadLock_fp.h"
+typedef TPM_RC (NV_ReadLock_Entry)(
+ NV_ReadLock_In *in
+ );
+typedef const struct {
+ NV_ReadLock_Entry *entry;
+ UINT16 inSize;
+ UINT16 outSize;
+ UINT16 offsetOfTypes;
+ UINT16 paramOffsets[1];
+ BYTE types[4];
+} NV_ReadLock_COMMAND_DESCRIPTOR_t;
+NV_ReadLock_COMMAND_DESCRIPTOR_t _NV_ReadLockData = {
+ /* entry */ &TPM2_NV_ReadLock,
+ /* inSize */ (UINT16)(sizeof(NV_ReadLock_In)),
+ /* outSize */ 0,
+ /* offsetOfTypes */ offsetof(NV_ReadLock_COMMAND_DESCRIPTOR_t, types),
+ /* offsets */ {(UINT16)(offsetof(NV_ReadLock_In, nvIndex))},
+ /* types */ {TPMI_RH_NV_AUTH_H_UNMARSHAL,
+ TPMI_RH_NV_INDEX_H_UNMARSHAL,
+ END_OF_LIST,
+ END_OF_LIST}
+};
+#define _NV_ReadLockDataAddress (&_NV_ReadLockData)
+#else
+#define _NV_ReadLockDataAddress 0
+#endif
+#if CC_NV_ChangeAuth
+#include "NV_ChangeAuth_fp.h"
+typedef TPM_RC (NV_ChangeAuth_Entry)(
+ NV_ChangeAuth_In *in
+ );
+typedef const struct {
+ NV_ChangeAuth_Entry *entry;
+ UINT16 inSize;
+ UINT16 outSize;
+ UINT16 offsetOfTypes;
+ UINT16 paramOffsets[1];
+ BYTE types[4];
+} NV_ChangeAuth_COMMAND_DESCRIPTOR_t;
+NV_ChangeAuth_COMMAND_DESCRIPTOR_t _NV_ChangeAuthData = {
+ /* entry */ &TPM2_NV_ChangeAuth,
+ /* inSize */ (UINT16)(sizeof(NV_ChangeAuth_In)),
+ /* outSize */ 0,
+ /* offsetOfTypes */ offsetof(NV_ChangeAuth_COMMAND_DESCRIPTOR_t, types),
+ /* offsets */ {(UINT16)(offsetof(NV_ChangeAuth_In, newAuth))},
+ /* types */ {TPMI_RH_NV_INDEX_H_UNMARSHAL,
+ TPM2B_AUTH_P_UNMARSHAL,
+ END_OF_LIST,
+ END_OF_LIST}
+};
+#define _NV_ChangeAuthDataAddress (&_NV_ChangeAuthData)
+#else
+#define _NV_ChangeAuthDataAddress 0
+#endif
+#if CC_NV_Certify
+#include "NV_Certify_fp.h"
+typedef TPM_RC (NV_Certify_Entry)(
+ NV_Certify_In *in,
+ NV_Certify_Out *out
+ );
+typedef const struct {
+ NV_Certify_Entry *entry;
+ UINT16 inSize;
+ UINT16 outSize;
+ UINT16 offsetOfTypes;
+ UINT16 paramOffsets[7];
+ BYTE types[11];
+} NV_Certify_COMMAND_DESCRIPTOR_t;
+NV_Certify_COMMAND_DESCRIPTOR_t _NV_CertifyData = {
+ /* entry */ &TPM2_NV_Certify,
+ /* inSize */ (UINT16)(sizeof(NV_Certify_In)),
+ /* outSize */ (UINT16)(sizeof(NV_Certify_Out)),
+ /* offsetOfTypes */ offsetof(NV_Certify_COMMAND_DESCRIPTOR_t, types),
+ /* offsets */ {(UINT16)(offsetof(NV_Certify_In, authHandle)),
+ (UINT16)(offsetof(NV_Certify_In, nvIndex)),
+ (UINT16)(offsetof(NV_Certify_In, qualifyingData)),
+ (UINT16)(offsetof(NV_Certify_In, inScheme)),
+ (UINT16)(offsetof(NV_Certify_In, size)),
+ (UINT16)(offsetof(NV_Certify_In, offset)),
+ (UINT16)(offsetof(NV_Certify_Out, signature))},
+ /* types */ {TPMI_DH_OBJECT_H_UNMARSHAL + ADD_FLAG,
+ TPMI_RH_NV_AUTH_H_UNMARSHAL,
+ TPMI_RH_NV_INDEX_H_UNMARSHAL,
+ TPM2B_DATA_P_UNMARSHAL,
+ TPMT_SIG_SCHEME_P_UNMARSHAL + ADD_FLAG,
+ UINT16_P_UNMARSHAL,
+ UINT16_P_UNMARSHAL,
+ END_OF_LIST,
+ TPM2B_ATTEST_P_MARSHAL,
+ TPMT_SIGNATURE_P_MARSHAL,
+ END_OF_LIST}
+};
+#define _NV_CertifyDataAddress (&_NV_CertifyData)
+#else
+#define _NV_CertifyDataAddress 0
+#endif
+
+#if CC_AC_GetCapability
+#include "AC_GetCapability_fp.h"
+typedef TPM_RC (AC_GetCapability_Entry)(
+ AC_GetCapability_In *in,
+ AC_GetCapability_Out *out
+ );
+typedef const struct {
+ AC_GetCapability_Entry *entry;
+ UINT16 inSize;
+ UINT16 outSize;
+ UINT16 offsetOfTypes;
+ UINT16 paramOffsets[3];
+ BYTE types[7];
+} AC_GetCapability_COMMAND_DESCRIPTOR_t;
+AC_GetCapability_COMMAND_DESCRIPTOR_t _AC_GetCapabilityData = {
+ /* entry */ &TPM2_AC_GetCapability,
+ /* inSize */ (UINT16)(sizeof(AC_GetCapability_In)),
+ /* outSize */ (UINT16)(sizeof(AC_GetCapability_Out)),
+ /* offsetOfTypes */ offsetof(AC_GetCapability_COMMAND_DESCRIPTOR_t, types),
+ /* offsets */ {(UINT16)(offsetof(AC_GetCapability_In, capability)),
+ (UINT16)(offsetof(AC_GetCapability_In, count)),
+ (UINT16)(offsetof(AC_GetCapability_Out, capabilitiesData))},
+ /* types */ {TPMI_RH_AC_H_UNMARSHAL,
+ TPM_AT_P_UNMARSHAL,
+ UINT32_P_UNMARSHAL,
+ END_OF_LIST,
+ TPMI_YES_NO_P_MARSHAL,
+ TPML_AC_CAPABILITIES_P_MARSHAL,
+ END_OF_LIST}
+};
+#define _AC_GetCapabilityDataAddress (&_AC_GetCapabilityData)
+#else
+#define _AC_GetCapabilityDataAddress 0
+#endif
+
+#if CC_AC_Send
+#include "AC_Send_fp.h"
+typedef TPM_RC (AC_Send_Entry)(
+ AC_Send_In *in,
+ AC_Send_Out *out
+ );
+typedef const struct {
+ AC_Send_Entry *entry;
+ UINT16 inSize;
+ UINT16 outSize;
+ UINT16 offsetOfTypes;
+ UINT16 paramOffsets[3];
+ BYTE types[7];
+} AC_Send_COMMAND_DESCRIPTOR_t;
+AC_Send_COMMAND_DESCRIPTOR_t _AC_SendData = {
+ /* entry */ &TPM2_AC_Send,
+ /* inSize */ (UINT16)(sizeof(AC_Send_In)),
+ /* outSize */ (UINT16)(sizeof(AC_Send_Out)),
+ /* offsetOfTypes */ offsetof(AC_Send_COMMAND_DESCRIPTOR_t, types),
+ /* offsets */ {(UINT16)(offsetof(AC_Send_In, authHandle)),
+ (UINT16)(offsetof(AC_Send_In, ac)),
+ (UINT16)(offsetof(AC_Send_In, acDataIn))},
+ /* types */ {TPMI_DH_OBJECT_H_UNMARSHAL,
+ TPMI_RH_NV_AUTH_H_UNMARSHAL,
+ TPMI_RH_AC_H_UNMARSHAL,
+ TPM2B_MAX_BUFFER_P_UNMARSHAL,
+ END_OF_LIST,
+ TPMS_AC_OUTPUT_P_MARSHAL,
+ END_OF_LIST}
+};
+#define _AC_SendDataAddress (&_AC_SendData)
+#else
+#define _AC_SendDataAddress 0
+#endif
+
+#if CC_Policy_AC_SendSelect
+#include "Policy_AC_SendSelect_fp.h"
+typedef TPM_RC (Policy_AC_SendSelect_Entry)(
+ Policy_AC_SendSelect_In *in
+ );
+typedef const struct {
+ Policy_AC_SendSelect_Entry *entry;
+ UINT16 inSize;
+ UINT16 outSize;
+ UINT16 offsetOfTypes;
+ UINT16 paramOffsets[4];
+ BYTE types[7];
+} Policy_AC_SendSelect_COMMAND_DESCRIPTOR_t;
+Policy_AC_SendSelect_COMMAND_DESCRIPTOR_t _Policy_AC_SendSelectData = {
+ /* entry */ &TPM2_Policy_AC_SendSelect,
+ /* inSize */ (UINT16)(sizeof(Policy_AC_SendSelect_In)),
+ /* outSize */ 0,
+ /* offsetOfTypes */ offsetof(Policy_AC_SendSelect_COMMAND_DESCRIPTOR_t, types),
+ /* offsets */ {(UINT16)(offsetof(Policy_AC_SendSelect_In, objectName)),
+ (UINT16)(offsetof(Policy_AC_SendSelect_In, authHandleName)),
+ (UINT16)(offsetof(Policy_AC_SendSelect_In, acName)),
+ (UINT16)(offsetof(Policy_AC_SendSelect_In, includeObject))},
+ /* types */ {TPMI_SH_POLICY_H_UNMARSHAL,
+ TPM2B_NAME_P_UNMARSHAL,
+ TPM2B_NAME_P_UNMARSHAL,
+ TPM2B_NAME_P_UNMARSHAL,
+ TPMI_YES_NO_P_UNMARSHAL,
+ END_OF_LIST,
+ END_OF_LIST}
+};
+#define _Policy_AC_SendSelectDataAddress (&_Policy_AC_SendSelectData)
+#else
+#define _Policy_AC_SendSelectDataAddress 0
+#endif
+
+#if CC_ACT_SetTimeout
+#include "ACT_SetTimeout_fp.h"
+typedef TPM_RC (ACT_SetTimeout_Entry)(
+ ACT_SetTimeout_In *in
+ );
+typedef const struct {
+ ACT_SetTimeout_Entry *entry;
+ UINT16 inSize;
+ UINT16 outSize;
+ UINT16 offsetOfTypes;
+ UINT16 paramOffsets[1];
+ BYTE types[4];
+} ACT_SetTimeout_COMMAND_DESCRIPTOR_t;
+ACT_SetTimeout_COMMAND_DESCRIPTOR_t _ACT_SetTimeoutData = {
+ /* entry */ &TPM2_ACT_SetTimeout,
+ /* inSize */ (UINT16)(sizeof(ACT_SetTimeout_In)),
+ /* outSize */ 0,
+ /* offsetOfTypes */ offsetof(ACT_SetTimeout_COMMAND_DESCRIPTOR_t, types),
+ /* offsets */ {(UINT16)(offsetof(ACT_SetTimeout_In, startTimeout))},
+ /* types */ {TPMI_RH_ACT_H_UNMARSHAL,
+ UINT32_P_UNMARSHAL,
+ END_OF_LIST,
+ END_OF_LIST}
+};
+#define _ACT_SetTimeoutDataAddress (&_ACT_SetTimeoutData)
+#else
+#define _ACT_SetTimeoutDataAddress 0
+#endif // CC_ACT_SetTimeout
+
+#if CC_Vendor_TCG_Test
+#include "Vendor_TCG_Test_fp.h"
+typedef TPM_RC (Vendor_TCG_Test_Entry)(
+ Vendor_TCG_Test_In *in,
+ Vendor_TCG_Test_Out *out
+ );
+typedef const struct {
+ Vendor_TCG_Test_Entry *entry;
+ UINT16 inSize;
+ UINT16 outSize;
+ UINT16 offsetOfTypes;
+ BYTE types[4];
+} Vendor_TCG_Test_COMMAND_DESCRIPTOR_t;
+Vendor_TCG_Test_COMMAND_DESCRIPTOR_t _Vendor_TCG_TestData = {
+ /* entry */ &TPM2_Vendor_TCG_Test,
+ /* inSize */ (UINT16)(sizeof(Vendor_TCG_Test_In)),
+ /* outSize */ (UINT16)(sizeof(Vendor_TCG_Test_Out)),
+ /* offsetOfTypes */ offsetof(Vendor_TCG_Test_COMMAND_DESCRIPTOR_t, types),
+ /* offsets */ // No parameter offsets
+ /* types */ {TPM2B_DATA_P_UNMARSHAL,
+ END_OF_LIST,
+ TPM2B_DATA_P_MARSHAL,
+ END_OF_LIST}
+};
+#define _Vendor_TCG_TestDataAddress (&_Vendor_TCG_TestData)
+#else
+#define _Vendor_TCG_TestDataAddress 0
+#endif
+
+COMMAND_DESCRIPTOR_t *s_CommandDataArray[] = {
+#if (PAD_LIST || CC_NV_UndefineSpaceSpecial)
+ (COMMAND_DESCRIPTOR_t *)_NV_UndefineSpaceSpecialDataAddress,
+#endif
+#if (PAD_LIST || CC_EvictControl)
+ (COMMAND_DESCRIPTOR_t *)_EvictControlDataAddress,
+#endif
+#if (PAD_LIST || CC_HierarchyControl)
+ (COMMAND_DESCRIPTOR_t *)_HierarchyControlDataAddress,
+#endif
+#if (PAD_LIST || CC_NV_UndefineSpace)
+ (COMMAND_DESCRIPTOR_t *)_NV_UndefineSpaceDataAddress,
+#endif
+#if (PAD_LIST)
+ (COMMAND_DESCRIPTOR_t *)0,
+#endif
+#if (PAD_LIST || CC_ChangeEPS)
+ (COMMAND_DESCRIPTOR_t *)_ChangeEPSDataAddress,
+#endif
+#if (PAD_LIST || CC_ChangePPS)
+ (COMMAND_DESCRIPTOR_t *)_ChangePPSDataAddress,
+#endif
+#if (PAD_LIST || CC_Clear)
+ (COMMAND_DESCRIPTOR_t *)_ClearDataAddress,
+#endif
+#if (PAD_LIST || CC_ClearControl)
+ (COMMAND_DESCRIPTOR_t *)_ClearControlDataAddress,
+#endif
+#if (PAD_LIST || CC_ClockSet)
+ (COMMAND_DESCRIPTOR_t *)_ClockSetDataAddress,
+#endif
+#if (PAD_LIST || CC_HierarchyChangeAuth)
+ (COMMAND_DESCRIPTOR_t *)_HierarchyChangeAuthDataAddress,
+#endif
+#if (PAD_LIST || CC_NV_DefineSpace)
+ (COMMAND_DESCRIPTOR_t *)_NV_DefineSpaceDataAddress,
+#endif
+#if (PAD_LIST || CC_PCR_Allocate)
+ (COMMAND_DESCRIPTOR_t *)_PCR_AllocateDataAddress,
+#endif
+#if (PAD_LIST || CC_PCR_SetAuthPolicy)
+ (COMMAND_DESCRIPTOR_t *)_PCR_SetAuthPolicyDataAddress,
+#endif
+#if (PAD_LIST || CC_PP_Commands)
+ (COMMAND_DESCRIPTOR_t *)_PP_CommandsDataAddress,
+#endif
+#if (PAD_LIST || CC_SetPrimaryPolicy)
+ (COMMAND_DESCRIPTOR_t *)_SetPrimaryPolicyDataAddress,
+#endif
+#if (PAD_LIST || CC_FieldUpgradeStart)
+ (COMMAND_DESCRIPTOR_t *)_FieldUpgradeStartDataAddress,
+#endif
+#if (PAD_LIST || CC_ClockRateAdjust)
+ (COMMAND_DESCRIPTOR_t *)_ClockRateAdjustDataAddress,
+#endif
+#if (PAD_LIST || CC_CreatePrimary)
+ (COMMAND_DESCRIPTOR_t *)_CreatePrimaryDataAddress,
+#endif
+#if (PAD_LIST || CC_NV_GlobalWriteLock)
+ (COMMAND_DESCRIPTOR_t *)_NV_GlobalWriteLockDataAddress,
+#endif
+#if (PAD_LIST || CC_GetCommandAuditDigest)
+ (COMMAND_DESCRIPTOR_t *)_GetCommandAuditDigestDataAddress,
+#endif
+#if (PAD_LIST || CC_NV_Increment)
+ (COMMAND_DESCRIPTOR_t *)_NV_IncrementDataAddress,
+#endif
+#if (PAD_LIST || CC_NV_SetBits)
+ (COMMAND_DESCRIPTOR_t *)_NV_SetBitsDataAddress,
+#endif
+#if (PAD_LIST || CC_NV_Extend)
+ (COMMAND_DESCRIPTOR_t *)_NV_ExtendDataAddress,
+#endif
+#if (PAD_LIST || CC_NV_Write)
+ (COMMAND_DESCRIPTOR_t *)_NV_WriteDataAddress,
+#endif
+#if (PAD_LIST || CC_NV_WriteLock)
+ (COMMAND_DESCRIPTOR_t *)_NV_WriteLockDataAddress,
+#endif
+#if (PAD_LIST || CC_DictionaryAttackLockReset)
+ (COMMAND_DESCRIPTOR_t *)_DictionaryAttackLockResetDataAddress,
+#endif
+#if (PAD_LIST || CC_DictionaryAttackParameters)
+ (COMMAND_DESCRIPTOR_t *)_DictionaryAttackParametersDataAddress,
+#endif
+#if (PAD_LIST || CC_NV_ChangeAuth)
+ (COMMAND_DESCRIPTOR_t *)_NV_ChangeAuthDataAddress,
+#endif
+#if (PAD_LIST || CC_PCR_Event)
+ (COMMAND_DESCRIPTOR_t *)_PCR_EventDataAddress,
+#endif
+#if (PAD_LIST || CC_PCR_Reset)
+ (COMMAND_DESCRIPTOR_t *)_PCR_ResetDataAddress,
+#endif
+#if (PAD_LIST || CC_SequenceComplete)
+ (COMMAND_DESCRIPTOR_t *)_SequenceCompleteDataAddress,
+#endif
+#if (PAD_LIST || CC_SetAlgorithmSet)
+ (COMMAND_DESCRIPTOR_t *)_SetAlgorithmSetDataAddress,
+#endif
+#if (PAD_LIST || CC_SetCommandCodeAuditStatus)
+ (COMMAND_DESCRIPTOR_t *)_SetCommandCodeAuditStatusDataAddress,
+#endif
+#if (PAD_LIST || CC_FieldUpgradeData)
+ (COMMAND_DESCRIPTOR_t *)_FieldUpgradeDataDataAddress,
+#endif
+#if (PAD_LIST || CC_IncrementalSelfTest)
+ (COMMAND_DESCRIPTOR_t *)_IncrementalSelfTestDataAddress,
+#endif
+#if (PAD_LIST || CC_SelfTest)
+ (COMMAND_DESCRIPTOR_t *)_SelfTestDataAddress,
+#endif
+#if (PAD_LIST || CC_Startup)
+ (COMMAND_DESCRIPTOR_t *)_StartupDataAddress,
+#endif
+#if (PAD_LIST || CC_Shutdown)
+ (COMMAND_DESCRIPTOR_t *)_ShutdownDataAddress,
+#endif
+#if (PAD_LIST || CC_StirRandom)
+ (COMMAND_DESCRIPTOR_t *)_StirRandomDataAddress,
+#endif
+#if (PAD_LIST || CC_ActivateCredential)
+ (COMMAND_DESCRIPTOR_t *)_ActivateCredentialDataAddress,
+#endif
+#if (PAD_LIST || CC_Certify)
+ (COMMAND_DESCRIPTOR_t *)_CertifyDataAddress,
+#endif
+#if (PAD_LIST || CC_PolicyNV)
+ (COMMAND_DESCRIPTOR_t *)_PolicyNVDataAddress,
+#endif
+#if (PAD_LIST || CC_CertifyCreation)
+ (COMMAND_DESCRIPTOR_t *)_CertifyCreationDataAddress,
+#endif
+#if (PAD_LIST || CC_Duplicate)
+ (COMMAND_DESCRIPTOR_t *)_DuplicateDataAddress,
+#endif
+#if (PAD_LIST || CC_GetTime)
+ (COMMAND_DESCRIPTOR_t *)_GetTimeDataAddress,
+#endif
+#if (PAD_LIST || CC_GetSessionAuditDigest)
+ (COMMAND_DESCRIPTOR_t *)_GetSessionAuditDigestDataAddress,
+#endif
+#if (PAD_LIST || CC_NV_Read)
+ (COMMAND_DESCRIPTOR_t *)_NV_ReadDataAddress,
+#endif
+#if (PAD_LIST || CC_NV_ReadLock)
+ (COMMAND_DESCRIPTOR_t *)_NV_ReadLockDataAddress,
+#endif
+#if (PAD_LIST || CC_ObjectChangeAuth)
+ (COMMAND_DESCRIPTOR_t *)_ObjectChangeAuthDataAddress,
+#endif
+#if (PAD_LIST || CC_PolicySecret)
+ (COMMAND_DESCRIPTOR_t *)_PolicySecretDataAddress,
+#endif
+#if (PAD_LIST || CC_Rewrap)
+ (COMMAND_DESCRIPTOR_t *)_RewrapDataAddress,
+#endif
+#if (PAD_LIST || CC_Create)
+ (COMMAND_DESCRIPTOR_t *)_CreateDataAddress,
+#endif
+#if (PAD_LIST || CC_ECDH_ZGen)
+ (COMMAND_DESCRIPTOR_t *)_ECDH_ZGenDataAddress,
+#endif
+#if (PAD_LIST || (CC_HMAC || CC_MAC))
+# if CC_HMAC
+ (COMMAND_DESCRIPTOR_t *)_HMACDataAddress,
+# endif
+# if CC_MAC
+ (COMMAND_DESCRIPTOR_t *)_MACDataAddress,
+# endif
+# if (CC_HMAC || CC_MAC) > 1
+# error "More than one aliased command defined"
+# endif
+#endif // CC_HMAC CC_MAC
+#if (PAD_LIST || CC_Import)
+ (COMMAND_DESCRIPTOR_t *)_ImportDataAddress,
+#endif
+#if (PAD_LIST || CC_Load)
+ (COMMAND_DESCRIPTOR_t *)_LoadDataAddress,
+#endif
+#if (PAD_LIST || CC_Quote)
+ (COMMAND_DESCRIPTOR_t *)_QuoteDataAddress,
+#endif
+#if (PAD_LIST || CC_RSA_Decrypt)
+ (COMMAND_DESCRIPTOR_t *)_RSA_DecryptDataAddress,
+#endif
+#if (PAD_LIST)
+ (COMMAND_DESCRIPTOR_t *)0,
+#endif
+#if (PAD_LIST || (CC_HMAC_Start || CC_MAC_Start))
+# if CC_HMAC_Start
+ (COMMAND_DESCRIPTOR_t *)_HMAC_StartDataAddress,
+# endif
+# if CC_MAC_Start
+ (COMMAND_DESCRIPTOR_t *)_MAC_StartDataAddress,
+# endif
+# if (CC_HMAC_Start || CC_MAC_Start) > 1
+# error "More than one aliased command defined"
+# endif
+#endif // CC_HMAC_Start CC_MAC_Start
+#if (PAD_LIST || CC_SequenceUpdate)
+ (COMMAND_DESCRIPTOR_t *)_SequenceUpdateDataAddress,
+#endif
+#if (PAD_LIST || CC_Sign)
+ (COMMAND_DESCRIPTOR_t *)_SignDataAddress,
+#endif
+#if (PAD_LIST || CC_Unseal)
+ (COMMAND_DESCRIPTOR_t *)_UnsealDataAddress,
+#endif
+#if (PAD_LIST)
+ (COMMAND_DESCRIPTOR_t *)0,
+#endif
+#if (PAD_LIST || CC_PolicySigned)
+ (COMMAND_DESCRIPTOR_t *)_PolicySignedDataAddress,
+#endif
+#if (PAD_LIST || CC_ContextLoad)
+ (COMMAND_DESCRIPTOR_t *)_ContextLoadDataAddress,
+#endif
+#if (PAD_LIST || CC_ContextSave)
+ (COMMAND_DESCRIPTOR_t *)_ContextSaveDataAddress,
+#endif
+#if (PAD_LIST || CC_ECDH_KeyGen)
+ (COMMAND_DESCRIPTOR_t *)_ECDH_KeyGenDataAddress,
+#endif
+#if (PAD_LIST || CC_EncryptDecrypt)
+ (COMMAND_DESCRIPTOR_t *)_EncryptDecryptDataAddress,
+#endif
+#if (PAD_LIST || CC_FlushContext)
+ (COMMAND_DESCRIPTOR_t *)_FlushContextDataAddress,
+#endif
+#if (PAD_LIST)
+ (COMMAND_DESCRIPTOR_t *)0,
+#endif
+#if (PAD_LIST || CC_LoadExternal)
+ (COMMAND_DESCRIPTOR_t *)_LoadExternalDataAddress,
+#endif
+#if (PAD_LIST || CC_MakeCredential)
+ (COMMAND_DESCRIPTOR_t *)_MakeCredentialDataAddress,
+#endif
+#if (PAD_LIST || CC_NV_ReadPublic)
+ (COMMAND_DESCRIPTOR_t *)_NV_ReadPublicDataAddress,
+#endif
+#if (PAD_LIST || CC_PolicyAuthorize)
+ (COMMAND_DESCRIPTOR_t *)_PolicyAuthorizeDataAddress,
+#endif
+#if (PAD_LIST || CC_PolicyAuthValue)
+ (COMMAND_DESCRIPTOR_t *)_PolicyAuthValueDataAddress,
+#endif
+#if (PAD_LIST || CC_PolicyCommandCode)
+ (COMMAND_DESCRIPTOR_t *)_PolicyCommandCodeDataAddress,
+#endif
+#if (PAD_LIST || CC_PolicyCounterTimer)
+ (COMMAND_DESCRIPTOR_t *)_PolicyCounterTimerDataAddress,
+#endif
+#if (PAD_LIST || CC_PolicyCpHash)
+ (COMMAND_DESCRIPTOR_t *)_PolicyCpHashDataAddress,
+#endif
+#if (PAD_LIST || CC_PolicyLocality)
+ (COMMAND_DESCRIPTOR_t *)_PolicyLocalityDataAddress,
+#endif
+#if (PAD_LIST || CC_PolicyNameHash)
+ (COMMAND_DESCRIPTOR_t *)_PolicyNameHashDataAddress,
+#endif
+#if (PAD_LIST || CC_PolicyOR)
+ (COMMAND_DESCRIPTOR_t *)_PolicyORDataAddress,
+#endif
+#if (PAD_LIST || CC_PolicyTicket)
+ (COMMAND_DESCRIPTOR_t *)_PolicyTicketDataAddress,
+#endif
+#if (PAD_LIST || CC_ReadPublic)
+ (COMMAND_DESCRIPTOR_t *)_ReadPublicDataAddress,
+#endif
+#if (PAD_LIST || CC_RSA_Encrypt)
+ (COMMAND_DESCRIPTOR_t *)_RSA_EncryptDataAddress,
+#endif
+#if (PAD_LIST)
+ (COMMAND_DESCRIPTOR_t *)0,
+#endif
+#if (PAD_LIST || CC_StartAuthSession)
+ (COMMAND_DESCRIPTOR_t *)_StartAuthSessionDataAddress,
+#endif
+#if (PAD_LIST || CC_VerifySignature)
+ (COMMAND_DESCRIPTOR_t *)_VerifySignatureDataAddress,
+#endif
+#if (PAD_LIST || CC_ECC_Parameters)
+ (COMMAND_DESCRIPTOR_t *)_ECC_ParametersDataAddress,
+#endif
+#if (PAD_LIST || CC_FirmwareRead)
+ (COMMAND_DESCRIPTOR_t *)_FirmwareReadDataAddress,
+#endif
+#if (PAD_LIST || CC_GetCapability)
+ (COMMAND_DESCRIPTOR_t *)_GetCapabilityDataAddress,
+#endif
+#if (PAD_LIST || CC_GetRandom)
+ (COMMAND_DESCRIPTOR_t *)_GetRandomDataAddress,
+#endif
+#if (PAD_LIST || CC_GetTestResult)
+ (COMMAND_DESCRIPTOR_t *)_GetTestResultDataAddress,
+#endif
+#if (PAD_LIST || CC_Hash)
+ (COMMAND_DESCRIPTOR_t *)_HashDataAddress,
+#endif
+#if (PAD_LIST || CC_PCR_Read)
+ (COMMAND_DESCRIPTOR_t *)_PCR_ReadDataAddress,
+#endif
+#if (PAD_LIST || CC_PolicyPCR)
+ (COMMAND_DESCRIPTOR_t *)_PolicyPCRDataAddress,
+#endif
+#if (PAD_LIST || CC_PolicyRestart)
+ (COMMAND_DESCRIPTOR_t *)_PolicyRestartDataAddress,
+#endif
+#if (PAD_LIST || CC_ReadClock)
+ (COMMAND_DESCRIPTOR_t *)_ReadClockDataAddress,
+#endif
+#if (PAD_LIST || CC_PCR_Extend)
+ (COMMAND_DESCRIPTOR_t *)_PCR_ExtendDataAddress,
+#endif
+#if (PAD_LIST || CC_PCR_SetAuthValue)
+ (COMMAND_DESCRIPTOR_t *)_PCR_SetAuthValueDataAddress,
+#endif
+#if (PAD_LIST || CC_NV_Certify)
+ (COMMAND_DESCRIPTOR_t *)_NV_CertifyDataAddress,
+#endif
+#if (PAD_LIST || CC_EventSequenceComplete)
+ (COMMAND_DESCRIPTOR_t *)_EventSequenceCompleteDataAddress,
+#endif
+#if (PAD_LIST || CC_HashSequenceStart)
+ (COMMAND_DESCRIPTOR_t *)_HashSequenceStartDataAddress,
+#endif
+#if (PAD_LIST || CC_PolicyPhysicalPresence)
+ (COMMAND_DESCRIPTOR_t *)_PolicyPhysicalPresenceDataAddress,
+#endif
+#if (PAD_LIST || CC_PolicyDuplicationSelect)
+ (COMMAND_DESCRIPTOR_t *)_PolicyDuplicationSelectDataAddress,
+#endif
+#if (PAD_LIST || CC_PolicyGetDigest)
+ (COMMAND_DESCRIPTOR_t *)_PolicyGetDigestDataAddress,
+#endif
+#if (PAD_LIST || CC_TestParms)
+ (COMMAND_DESCRIPTOR_t *)_TestParmsDataAddress,
+#endif
+#if (PAD_LIST || CC_Commit)
+ (COMMAND_DESCRIPTOR_t *)_CommitDataAddress,
+#endif
+#if (PAD_LIST || CC_PolicyPassword)
+ (COMMAND_DESCRIPTOR_t *)_PolicyPasswordDataAddress,
+#endif
+#if (PAD_LIST || CC_ZGen_2Phase)
+ (COMMAND_DESCRIPTOR_t *)_ZGen_2PhaseDataAddress,
+#endif
+#if (PAD_LIST || CC_EC_Ephemeral)
+ (COMMAND_DESCRIPTOR_t *)_EC_EphemeralDataAddress,
+#endif
+#if (PAD_LIST || CC_PolicyNvWritten)
+ (COMMAND_DESCRIPTOR_t *)_PolicyNvWrittenDataAddress,
+#endif
+#if (PAD_LIST || CC_PolicyTemplate)
+ (COMMAND_DESCRIPTOR_t *)_PolicyTemplateDataAddress,
+#endif
+#if (PAD_LIST || CC_CreateLoaded)
+ (COMMAND_DESCRIPTOR_t *)_CreateLoadedDataAddress,
+#endif
+#if (PAD_LIST || CC_PolicyAuthorizeNV)
+ (COMMAND_DESCRIPTOR_t *)_PolicyAuthorizeNVDataAddress,
+#endif
+#if (PAD_LIST || CC_EncryptDecrypt2)
+ (COMMAND_DESCRIPTOR_t *)_EncryptDecrypt2DataAddress,
+#endif
+#if (PAD_LIST || CC_AC_GetCapability)
+ (COMMAND_DESCRIPTOR_t *)_AC_GetCapabilityDataAddress,
+#endif // CC_AC_GetCapability
+#if (PAD_LIST || CC_AC_Send)
+ (COMMAND_DESCRIPTOR_t *)_AC_SendDataAddress,
+#endif // CC_AC_Send
+#if (PAD_LIST || CC_Policy_AC_SendSelect)
+ (COMMAND_DESCRIPTOR_t *)_Policy_AC_SendSelectDataAddress,
+#endif // CC_Policy_AC_SendSelect
+#if (PAD_LIST || CC_CertifyX509)
+ (COMMAND_DESCRIPTOR_t *)_CertifyX509DataAddress,
+#endif // CC_CertifyX509
+#if (PAD_LIST || CC_ACT_SetTimeout)
+ (COMMAND_DESCRIPTOR_t *)_ACT_SetTimeoutDataAddress,
+#endif // CC_ACT_SetTimeout
+#if (PAD_LIST || CC_ECC_Encrypt)
+ (COMMAND_DESCRIPTOR_t *)_ECC_EncryptDataAddress,
+#endif // CC_ECC_Encrypt
+#if (PAD_LIST || CC_ECC_Decrypt)
+ (COMMAND_DESCRIPTOR_t *)_ECC_DecryptDataAddress,
+#endif // CC_ECC_Decrypt
+#if (PAD_LIST || CC_Vendor_TCG_Test)
+ (COMMAND_DESCRIPTOR_t *)_Vendor_TCG_TestDataAddress,
+#endif
+ 0
+};
+
+#endif // _COMMAND_TABLE_DISPATCH_
diff --git a/src/tpm2/CommandDispatcher.c b/src/tpm2/CommandDispatcher.c
new file mode 100644
index 0000000..c0464b9
--- /dev/null
+++ b/src/tpm2/CommandDispatcher.c
@@ -0,0 +1,409 @@
+/********************************************************************************/
+/* */
+/* Command Dispatcher */
+/* Written by Ken Goldman */
+/* IBM Thomas J. Watson Research Center */
+/* $Id: CommandDispatcher.c 1658 2021-01-22 23:14:01Z kgoldman $ */
+/* */
+/* Licenses and Notices */
+/* */
+/* 1. Copyright Licenses: */
+/* */
+/* - Trusted Computing Group (TCG) grants to the user of the source code in */
+/* this specification (the "Source Code") a worldwide, irrevocable, */
+/* nonexclusive, royalty free, copyright license to reproduce, create */
+/* derivative works, distribute, display and perform the Source Code and */
+/* derivative works thereof, and to grant others the rights granted herein. */
+/* */
+/* - The TCG grants to the user of the other parts of the specification */
+/* (other than the Source Code) the rights to reproduce, distribute, */
+/* display, and perform the specification solely for the purpose of */
+/* developing products based on such documents. */
+/* */
+/* 2. Source Code Distribution Conditions: */
+/* */
+/* - Redistributions of Source Code must retain the above copyright licenses, */
+/* this list of conditions and the following disclaimers. */
+/* */
+/* - Redistributions in binary form must reproduce the above copyright */
+/* licenses, this list of conditions and the following disclaimers in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* 3. Disclaimers: */
+/* */
+/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
+/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
+/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
+/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
+/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
+/* information on specification licensing rights available through TCG */
+/* membership agreements. */
+/* */
+/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
+/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
+/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
+/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
+/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
+/* */
+/* - Without limitation, TCG and its members and licensors disclaim all */
+/* liability, including liability for infringement of any proprietary */
+/* rights, relating to use of information in this specification and to the */
+/* implementation of this specification, and TCG disclaims all liability for */
+/* cost of procurement of substitute goods or services, lost profits, loss */
+/* of use, loss of data or any incidental, consequential, direct, indirect, */
+/* or special damages, whether under contract, tort, warranty or otherwise, */
+/* arising in any way out of use or reliance upon this specification or any */
+/* information herein. */
+/* */
+/* (c) Copyright IBM Corp. and others, 2016 - 2021 */
+/* */
+/********************************************************************************/
+
+/* 6.3 CommandDispatcher.c */
+/* CommandDispatcher() performs the following operations: */
+/* * unmarshals command parameters from the input buffer; */
+/* NOTE Unlike other unmarshaling functions, parmBufferStart does not advance. parmBufferSize Is
+ reduced. */
+/* * invokes the function that performs the command actions; */
+/* * marshals the returned handles, if any; and */
+/* * marshals the returned parameters, if any, into the output buffer putting in the
+ * parameterSize field if authorization sessions are present. */
+/* NOTE 1 The output buffer is the return from the MemoryGetResponseBuffer() function. It includes
+ the header, handles, response parameters, and authorization area. respParmSize is the response
+ parameter size, and does not include the header, handles, or authorization area. */
+/* NOTE 2 The reference implementation is permitted to do compare operations over a union as a byte
+ array. Therefore, the command parameter in structure must be initialized (e.g., zeroed) before
+ unmarshaling so that the compare operation is valid in cases where some bytes are unused. */
+/* 6.3.1.1 Includes and Typedefs */
+#include "Tpm.h"
+// #include "Marshal.h" kgold
+
+#if TABLE_DRIVEN_DISPATCH
+typedef TPM_RC(NoFlagFunction)(void *target, BYTE **buffer, INT32 *size);
+typedef TPM_RC(FlagFunction)(void *target, BYTE **buffer, INT32 *size, BOOL flag);
+typedef FlagFunction *UNMARSHAL_t;
+typedef INT16(MarshalFunction)(void *source, BYTE **buffer, INT32 *size);
+typedef MarshalFunction *MARSHAL_t;
+typedef TPM_RC(COMMAND_NO_ARGS)(void);
+typedef TPM_RC(COMMAND_IN_ARG)(void *in);
+typedef TPM_RC(COMMAND_OUT_ARG)(void *out);
+typedef TPM_RC(COMMAND_INOUT_ARG)(void *in, void *out);
+typedef union
+{
+ COMMAND_NO_ARGS *noArgs;
+ COMMAND_IN_ARG *inArg;
+ COMMAND_OUT_ARG *outArg;
+ COMMAND_INOUT_ARG *inOutArg;
+} COMMAND_t;
+typedef struct
+{
+ COMMAND_t command; // Address of the command
+ UINT16 inSize; // Maximum size of the input structure
+ UINT16 outSize; // Maximum size of the output structure
+ UINT16 typesOffset; // address of the types field
+ UINT16 offsets[1];
+} COMMAND_DESCRIPTOR_t;
+#if COMPRESSED_LISTS
+# define PAD_LIST 0
+#else
+# define PAD_LIST 1
+#endif
+#define _COMMAND_TABLE_DISPATCH_
+#include "CommandDispatchData.h"
+#define TEST_COMMAND TPM_CC_Startup
+#define NEW_CC
+#else
+#include "Commands.h"
+#endif
+
+/* 6.3.1.2 Marshal/Unmarshal Functions */
+/* 6.3.1.2.1 ParseHandleBuffer() */
+/* This is the table-driven version of the handle buffer unmarshaling code */
+
+TPM_RC
+ParseHandleBuffer(
+ COMMAND *command
+ )
+{
+ TPM_RC result;
+#if TABLE_DRIVEN_DISPATCH
+ COMMAND_DESCRIPTOR_t *desc;
+ BYTE *types;
+ BYTE type;
+ BYTE dType;
+ // Make sure that nothing strange has happened
+ pAssert(command->index
+ < sizeof(s_CommandDataArray) / sizeof(COMMAND_DESCRIPTOR_t *));
+ // Get the address of the descriptor for this command
+ desc = s_CommandDataArray[command->index];
+ pAssert(desc != NULL);
+ // Get the associated list of unmarshaling data types.
+ types = &((BYTE *)desc)[desc->typesOffset];
+ // if(s_ccAttr[commandIndex].commandIndex == TEST_COMMAND)
+ // commandIndex = commandIndex;
+ // No handles yet
+ command->handleNum = 0;
+ // Get the first type value
+ for(type = *types++;
+ // check each byte to make sure that we have not hit the start
+ // of the parameters
+ (dType = (type & 0x7F)) < PARAMETER_FIRST_TYPE;
+ // get the next type
+ type = *types++)
+ {
+#if TABLE_DRIVEN_MARSHAL
+ marshalIndex_t index;
+ index = unmarshalArray[dType] | ((type & 0x80) ? NULL_FLAG : 0);
+ result = Unmarshal(index, &(command->handles[command->handleNum]),
+ &command->parameterBuffer, &command->parameterSize);
+
+#else
+
+ // See if unmarshaling of this handle type requires a flag
+ if(dType < HANDLE_FIRST_FLAG_TYPE)
+ {
+ // Look up the function to do the unmarshaling
+ NoFlagFunction *f = (NoFlagFunction *)unmarshalArray[dType];
+ // call it
+ result = f(&(command->handles[command->handleNum]),
+ &command->parameterBuffer,
+ &command->parameterSize);
+ }
+ else
+ {
+ // Look up the function
+ FlagFunction *f = unmarshalArray[dType];
+ // Call it setting the flag to the appropriate value
+ result = f(&(command->handles[command->handleNum]),
+ &command->parameterBuffer,
+ &command->parameterSize, (type & 0x80) != 0);
+ }
+#endif
+ // Got a handle
+ // We do this first so that the match for the handle offset of the
+ // response code works correctly.
+ command->handleNum += 1;
+ if(result != TPM_RC_SUCCESS)
+ // if the unmarshaling failed, return the response code with the
+ // handle indication set
+ return result + TPM_RC_H + (command->handleNum * TPM_RC_1);
+ }
+#else
+ BYTE **handleBufferStart = &command->parameterBuffer;
+ INT32 *bufferRemainingSize = &command->parameterSize;
+ TPM_HANDLE *handles = &command->handles[0];
+ UINT32 *handleCount = &command->handleNum;
+ *handleCount = 0;
+ switch(command->code)
+ {
+#include "HandleProcess.h"
+#undef handles
+ default:
+ FAIL(FATAL_ERROR_INTERNAL);
+ break;
+ }
+#endif
+ return TPM_RC_SUCCESS;
+}
+
+/* 6.3.1.2.2 CommandDispatcher() */
+/* Function to unmarshal the command parameters, call the selected action code, and marshal the
+ response parameters. */
+
+TPM_RC
+CommandDispatcher(
+ COMMAND *command
+ )
+{
+#if !TABLE_DRIVEN_DISPATCH
+ TPM_RC result;
+ BYTE **paramBuffer = &command->parameterBuffer;
+ INT32 *paramBufferSize = &command->parameterSize;
+ BYTE **responseBuffer = &command->responseBuffer;
+ INT32 *respParmSize = &command->parameterSize;
+ INT32 rSize;
+ TPM_HANDLE *handles = &command->handles[0];
+
+ command->handleNum = 0; /* The command-specific code knows how many handles there are. This
+ is for cataloging the number of response handles */
+ MemoryIoBufferAllocationReset(); /* Initialize so that allocation will work properly */
+ switch(GetCommandCode(command->index))
+ {
+#include "CommandDispatcher.h"
+ default:
+ FAIL(FATAL_ERROR_INTERNAL);
+ break;
+ }
+ Exit:
+ MemoryIoBufferZero();
+ return result;
+#else
+ COMMAND_DESCRIPTOR_t *desc;
+ BYTE *types;
+ BYTE type;
+ UINT16 *offsets;
+ UINT16 offset = 0;
+ UINT32 maxInSize;
+ BYTE *commandIn;
+ INT32 maxOutSize;
+ BYTE *commandOut;
+ COMMAND_t cmd;
+ TPM_HANDLE *handles;
+ UINT32 hasInParameters = 0;
+ BOOL hasOutParameters = FALSE;
+ UINT32 pNum = 0;
+ BYTE dType; // dispatch type
+ TPM_RC result;
+ //
+ // Get the address of the descriptor for this command
+ pAssert(command->index
+ < sizeof(s_CommandDataArray) / sizeof(COMMAND_DESCRIPTOR_t *));
+ desc = s_CommandDataArray[command->index];
+ // Get the list of parameter types for this command
+ pAssert(desc != NULL);
+ types = &((BYTE *)desc)[desc->typesOffset];
+ // Get a pointer to the list of parameter offsets
+ offsets = &desc->offsets[0];
+ // pointer to handles
+ handles = command->handles;
+ // Get the size required to hold all the unmarshaled parameters for this command
+ maxInSize = desc->inSize;
+ // and the size of the output parameter structure returned by this command
+ maxOutSize = desc->outSize;
+ MemoryIoBufferAllocationReset();
+ // Get a buffer for the input parameters
+ commandIn = MemoryGetInBuffer(maxInSize);
+ // And the output parameters
+ commandOut = (BYTE *)MemoryGetOutBuffer((UINT32)maxOutSize);
+ // Get the address of the action code dispatch
+ cmd = desc->command;
+ // Copy any handles into the input buffer
+ for(type = *types++; (type & 0x7F) < PARAMETER_FIRST_TYPE; type = *types++)
+ {
+ // 'offset' was initialized to zero so the first unmarshaling will always
+ // be to the start of the data structure
+ *(TPM_HANDLE *)&(commandIn[offset]) = *handles++;
+ // This check is used so that we don't have to add an additional offset
+ // value to the offsets list to correspond to the stop value in the
+ // command parameter list.
+ if(*types != 0xFF)
+ offset = *offsets++;
+ // maxInSize -= sizeof(TPM_HANDLE);
+ hasInParameters++;
+ }
+ // Exit loop with type containing the last value read from types
+ // maxInSize has the amount of space remaining in the command action input
+ // buffer. Make sure that we don't have more data to unmarshal than is going to
+ // fit.
+ // type contains the last value read from types so it is not necessary to
+ // reload it, which is good because *types now points to the next value
+ for(; (dType = (type & 0x7F)) <= PARAMETER_LAST_TYPE; type = *types++)
+ {
+ pNum++;
+#if TABLE_DRIVEN_MARSHAL
+ {
+ marshalIndex_t index = unmarshalArray[dType];
+ index |= (type & 0x80) ? NULL_FLAG : 0;
+ result = Unmarshal(index, &commandIn[offset], &command->parameterBuffer,
+ &command->parameterSize);
+ }
+#else
+ if(dType < PARAMETER_FIRST_FLAG_TYPE)
+ {
+ NoFlagFunction *f = (NoFlagFunction *)unmarshalArray[dType];
+ result = f(&commandIn[offset], &command->parameterBuffer,
+ &command->parameterSize);
+ }
+ else
+ {
+ FlagFunction *f = unmarshalArray[dType];
+ result = f(&commandIn[offset], &command->parameterBuffer,
+ &command->parameterSize,
+ (type & 0x80) != 0);
+ }
+#endif
+ if(result != TPM_RC_SUCCESS)
+ {
+ result += TPM_RC_P + (TPM_RC_1 * pNum);
+ goto Exit;
+ }
+ // This check is used so that we don't have to add an additional offset
+ // value to the offsets list to correspond to the stop value in the
+ // command parameter list.
+ if(*types != 0xFF)
+ offset = *offsets++;
+ hasInParameters++;
+ }
+ // Should have used all the bytes in the input
+ if(command->parameterSize != 0)
+ {
+ result = TPM_RC_SIZE;
+ goto Exit;
+ }
+ // The command parameter unmarshaling stopped when it hit a value that was out
+ // of range for unmarshaling values and left *types pointing to the first
+ // marshaling type. If that type happens to be the STOP value, then there
+ // are no response parameters. So, set the flag to indicate if there are
+ // output parameters.
+ hasOutParameters = *types != 0xFF;
+ // There are four cases for calling, with and without input parameters and with
+ // and without output parameters.
+ if(hasInParameters > 0)
+ {
+ if(hasOutParameters)
+ result = cmd.inOutArg(commandIn, commandOut);
+ else
+ result = cmd.inArg(commandIn);
+ }
+ else
+ {
+ if(hasOutParameters)
+ result = cmd.outArg(commandOut);
+ else
+ result = cmd.noArgs();
+ }
+ if(result != TPM_RC_SUCCESS)
+ goto Exit;
+ // Offset in the marshaled output structure
+ offset = 0;
+ // Process the return handles, if any
+ command->handleNum = 0;
+ // Could make this a loop to process output handles but there is only ever
+ // one handle in the outputs (for now).
+ type = *types++;
+ if((dType = (type & 0x7F)) < RESPONSE_PARAMETER_FIRST_TYPE)
+ {
+ // The out->handle value was referenced as TPM_HANDLE in the
+ // action code so it has to be properly aligned.
+ command->handles[command->handleNum++] =
+ *((TPM_HANDLE *)&(commandOut[offset]));
+ maxOutSize -= sizeof(UINT32);
+ type = *types++;
+ offset = *offsets++;
+ }
+ // Use the size of the command action output buffer as the maximum for the
+ // number of bytes that can get marshaled. Since the marshaling code has
+ // no pointers to data, all of the data being returned has to be in the
+ // command action output buffer. If we try to marshal more bytes than
+ // could fit into the output buffer, we need to fail.
+ for(;(dType = (type & 0x7F)) <= RESPONSE_PARAMETER_LAST_TYPE
+ && !g_inFailureMode; type = *types++)
+ {
+#if TABLE_DRIVEN_MARSHAL
+ marshalIndex_t index = marshalArray[dType];
+ command->parameterSize += Marshal(index, &commandOut[offset],
+ &command->responseBuffer,
+ &maxOutSize);
+#else
+ const MARSHAL_t f = marshalArray[dType];
+ command->parameterSize += f(&commandOut[offset], &command->responseBuffer,
+ &maxOutSize);
+#endif
+ offset = *offsets++;
+ }
+ result = (maxOutSize < 0) ? TPM_RC_FAILURE : TPM_RC_SUCCESS;
+ Exit:
+ MemoryIoBufferZero();
+ return result;
+#endif
+}
diff --git a/src/tpm2/CommandDispatcher_fp.h b/src/tpm2/CommandDispatcher_fp.h
new file mode 100644
index 0000000..6065ace
--- /dev/null
+++ b/src/tpm2/CommandDispatcher_fp.h
@@ -0,0 +1,75 @@
+/********************************************************************************/
+/* */
+/* */
+/* Written by Ken Goldman */
+/* IBM Thomas J. Watson Research Center */
+/* $Id: CommandDispatcher_fp.h 1490 2019-07-26 21:13:22Z kgoldman $ */
+/* */
+/* Licenses and Notices */
+/* */
+/* 1. Copyright Licenses: */
+/* */
+/* - Trusted Computing Group (TCG) grants to the user of the source code in */
+/* this specification (the "Source Code") a worldwide, irrevocable, */
+/* nonexclusive, royalty free, copyright license to reproduce, create */
+/* derivative works, distribute, display and perform the Source Code and */
+/* derivative works thereof, and to grant others the rights granted herein. */
+/* */
+/* - The TCG grants to the user of the other parts of the specification */
+/* (other than the Source Code) the rights to reproduce, distribute, */
+/* display, and perform the specification solely for the purpose of */
+/* developing products based on such documents. */
+/* */
+/* 2. Source Code Distribution Conditions: */
+/* */
+/* - Redistributions of Source Code must retain the above copyright licenses, */
+/* this list of conditions and the following disclaimers. */
+/* */
+/* - Redistributions in binary form must reproduce the above copyright */
+/* licenses, this list of conditions and the following disclaimers in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* 3. Disclaimers: */
+/* */
+/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
+/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
+/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
+/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
+/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
+/* information on specification licensing rights available through TCG */
+/* membership agreements. */
+/* */
+/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
+/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
+/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
+/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
+/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
+/* */
+/* - Without limitation, TCG and its members and licensors disclaim all */
+/* liability, including liability for infringement of any proprietary */
+/* rights, relating to use of information in this specification and to the */
+/* implementation of this specification, and TCG disclaims all liability for */
+/* cost of procurement of substitute goods or services, lost profits, loss */
+/* of use, loss of data or any incidental, consequential, direct, indirect, */
+/* or special damages, whether under contract, tort, warranty or otherwise, */
+/* arising in any way out of use or reliance upon this specification or any */
+/* information herein. */
+/* */
+/* (c) Copyright IBM Corp. and others, 2016 */
+/* */
+/********************************************************************************/
+
+#ifndef COMMANDDISPATCHER_FP_H
+#define COMMANDDISPATCHER_FP_H
+
+TPM_RC
+CommandDispatcher(
+ COMMAND *command
+ );
+TPM_RC
+ParseHandleBuffer(
+ COMMAND *command
+ );
+
+
+#endif
diff --git a/src/tpm2/Commit_fp.h b/src/tpm2/Commit_fp.h
new file mode 100644
index 0000000..6233eaf
--- /dev/null
+++ b/src/tpm2/Commit_fp.h
@@ -0,0 +1,94 @@
+/********************************************************************************/
+/* */
+/* */
+/* Written by Ken Goldman */
+/* IBM Thomas J. Watson Research Center */
+/* $Id: Commit_fp.h 809 2016-11-16 18:31:54Z kgoldman $ */
+/* */
+/* Licenses and Notices */
+/* */
+/* 1. Copyright Licenses: */
+/* */
+/* - Trusted Computing Group (TCG) grants to the user of the source code in */
+/* this specification (the "Source Code") a worldwide, irrevocable, */
+/* nonexclusive, royalty free, copyright license to reproduce, create */
+/* derivative works, distribute, display and perform the Source Code and */
+/* derivative works thereof, and to grant others the rights granted herein. */
+/* */
+/* - The TCG grants to the user of the other parts of the specification */
+/* (other than the Source Code) the rights to reproduce, distribute, */
+/* display, and perform the specification solely for the purpose of */
+/* developing products based on such documents. */
+/* */
+/* 2. Source Code Distribution Conditions: */
+/* */
+/* - Redistributions of Source Code must retain the above copyright licenses, */
+/* this list of conditions and the following disclaimers. */
+/* */
+/* - Redistributions in binary form must reproduce the above copyright */
+/* licenses, this list of conditions and the following disclaimers in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* 3. Disclaimers: */
+/* */
+/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
+/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
+/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
+/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
+/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
+/* information on specification licensing rights available through TCG */
+/* membership agreements. */
+/* */
+/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
+/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
+/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
+/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
+/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
+/* */
+/* - Without limitation, TCG and its members and licensors disclaim all */
+/* liability, including liability for infringement of any proprietary */
+/* rights, relating to use of information in this specification and to the */
+/* implementation of this specification, and TCG disclaims all liability for */
+/* cost of procurement of substitute goods or services, lost profits, loss */
+/* of use, loss of data or any incidental, consequential, direct, indirect, */
+/* or special damages, whether under contract, tort, warranty or otherwise, */
+/* arising in any way out of use or reliance upon this specification or any */
+/* information herein. */
+/* */
+/* (c) Copyright IBM Corp. and others, 2012-2015 */
+/* */
+/********************************************************************************/
+
+/* rev 119 */
+
+#ifndef COMMIT_FP_H
+#define COMMIT_FP_H
+
+typedef struct {
+ TPMI_DH_OBJECT signHandle;
+ TPM2B_ECC_POINT P1;
+ TPM2B_SENSITIVE_DATA s2;
+ TPM2B_ECC_PARAMETER y2;
+} Commit_In;
+
+#define RC_Commit_signHandle (TPM_RC_H + TPM_RC_1)
+#define RC_Commit_P1 (TPM_RC_P + TPM_RC_1)
+#define RC_Commit_s2 (TPM_RC_P + TPM_RC_2)
+#define RC_Commit_y2 (TPM_RC_P + TPM_RC_3)
+
+typedef struct {
+ TPM2B_ECC_POINT K;
+ TPM2B_ECC_POINT L;
+ TPM2B_ECC_POINT E;
+ UINT16 counter;
+} Commit_Out;
+
+TPM_RC
+TPM2_Commit(
+ Commit_In *in, // IN: input parameter list
+ Commit_Out *out // OUT: output parameter list
+ );
+
+
+
+#endif
diff --git a/src/tpm2/CompilerDependencies.h b/src/tpm2/CompilerDependencies.h
new file mode 100644
index 0000000..60ad954
--- /dev/null
+++ b/src/tpm2/CompilerDependencies.h
@@ -0,0 +1,193 @@
+/********************************************************************************/
+/* */
+/* Compiler Dependencies */
+/* Written by Ken Goldman */
+/* IBM Thomas J. Watson Research Center */
+/* $Id: CompilerDependencies.h 1453 2019-04-05 16:43:36Z kgoldman $ */
+/* */
+/* Licenses and Notices */
+/* */
+/* 1. Copyright Licenses: */
+/* */
+/* - Trusted Computing Group (TCG) grants to the user of the source code in */
+/* this specification (the "Source Code") a worldwide, irrevocable, */
+/* nonexclusive, royalty free, copyright license to reproduce, create */
+/* derivative works, distribute, display and perform the Source Code and */
+/* derivative works thereof, and to grant others the rights granted herein. */
+/* */
+/* - The TCG grants to the user of the other parts of the specification */
+/* (other than the Source Code) the rights to reproduce, distribute, */
+/* display, and perform the specification solely for the purpose of */
+/* developing products based on such documents. */
+/* */
+/* 2. Source Code Distribution Conditions: */
+/* */
+/* - Redistributions of Source Code must retain the above copyright licenses, */
+/* this list of conditions and the following disclaimers. */
+/* */
+/* - Redistributions in binary form must reproduce the above copyright */
+/* licenses, this list of conditions and the following disclaimers in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* 3. Disclaimers: */
+/* */
+/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
+/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
+/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
+/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
+/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
+/* information on specification licensing rights available through TCG */
+/* membership agreements. */
+/* */
+/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
+/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
+/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
+/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
+/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
+/* */
+/* - Without limitation, TCG and its members and licensors disclaim all */
+/* liability, including liability for infringement of any proprietary */
+/* rights, relating to use of information in this specification and to the */
+/* implementation of this specification, and TCG disclaims all liability for */
+/* cost of procurement of substitute goods or services, lost profits, loss */
+/* of use, loss of data or any incidental, consequential, direct, indirect, */
+/* or special damages, whether under contract, tort, warranty or otherwise, */
+/* arising in any way out of use or reliance upon this specification or any */
+/* information herein. */
+/* */
+/* (c) Copyright IBM Corp. and others, 2016 - 2019 */
+/* */
+/********************************************************************************/
+
+#ifndef COMPILERDEPEDENCIES_H
+#define COMPILERDEPEDENCIES_H
+
+/* kgold - Not in the original code. A user reported that it was required for a non-Visual Studio
+ environment.
+*/
+
+#ifdef TPM_WINDOWS
+#include <windows.h>
+#include <winsock.h>
+#endif
+
+/* 5.10 CompilerDependencies.h */
+#ifdef GCC
+# undef _MSC_VER
+# undef WIN32
+#endif
+
+#ifdef _MSC_VER
+
+// These definitions are for the Microsoft compiler Endian conversion for aligned structures
+# define REVERSE_ENDIAN_16(_Number) _byteswap_ushort(_Number)
+# define REVERSE_ENDIAN_32(_Number) _byteswap_ulong(_Number)
+# define REVERSE_ENDIAN_64(_Number) _byteswap_uint64(_Number)
+
+// Avoid compiler warning for in line of stdio (or not)
+
+// #define _NO_CRT_STDIO_INLINE
+
+// This macro is used to handle LIB_EXPORT of function and variable names in lieu of a .def
+// file. Visual Studio requires that functions be explicitly exported and imported.
+
+# define LIB_EXPORT __declspec(dllexport) // VS compatible version
+# define LIB_IMPORT __declspec(dllimport)
+
+// This is defined to indicate a function that does not return. Microsoft compilers do not
+// support the _Noretrun() function parameter.
+
+# define NORETURN __declspec(noreturn)
+# if _MSC_VER >= 1400 // SAL processing when needed
+# include <sal.h>
+# endif
+# ifdef _WIN64
+# define _INTPTR 2
+# else
+# define _INTPTR 1
+# endif
+# define NOT_REFERENCED(x) (x)
+
+// Lower the compiler error warning for system include files. They tend not to be that clean and
+// there is no reason to sort through all the spurious errors that they generate when the normal
+// error level is set to /Wall
+
+# define _REDUCE_WARNING_LEVEL_(n) \
+ __pragma(warning(push, n))
+
+// Restore the compiler warning level
+
+# define _NORMAL_WARNING_LEVEL_ \
+ __pragma(warning(pop))
+# include <stdint.h>
+#endif // _MSC_VER
+
+#ifndef _MSC_VER
+#ifndef WINAPI
+# define WINAPI
+#endif
+# define __pragma(x)
+ /* libtpms added begin */
+# if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR >= 2)
+# define REVERSE_ENDIAN_16(_Number) __builtin_bswap16(_Number)
+# define REVERSE_ENDIAN_32(_Number) __builtin_bswap32(_Number)
+# define REVERSE_ENDIAN_64(_Number) __builtin_bswap64(_Number)
+# else
+# if defined __linux__ || defined __CYGWIN__
+# include <byteswap.h>
+# define REVERSE_ENDIAN_16(_Number) bswap_16(_Number)
+# define REVERSE_ENDIAN_32(_Number) bswap_32(_Number)
+# define REVERSE_ENDIAN_64(_Number) bswap_64(_Number)
+# elif defined __OpenBSD__
+# include <endian.h>
+# define REVERSE_ENDIAN_16(_Number) swap16(_Number)
+# define REVERSE_ENDIAN_32(_Number) swap32(_Number)
+# define REVERSE_ENDIAN_64(_Number) swap64(_Number)
+# elif defined __APPLE__
+# include <libkern/OSByteOrder.h>
+# define REVERSE_ENDIAN_16(_Number) _OSSwapInt16(_Number)
+# define REVERSE_ENDIAN_32(_Number) _OSSwapInt32(_Number)
+# define REVERSE_ENDIAN_64(_Number) _OSSwapInt64(_Number)
+# elif defined __FreeBSD__
+# include <sys/endian.h>
+# define REVERSE_ENDIAN_16(_Number) bswap16(_Number)
+# define REVERSE_ENDIAN_32(_Number) bswap32(_Number)
+# define REVERSE_ENDIAN_64(_Number) bswap64(_Number)
+# else
+# error Unsupported OS
+# endif
+# endif
+ /* libtpms added end */
+#endif
+#if defined(__GNUC__)
+# define NORETURN __attribute__((noreturn))
+# include <stdint.h>
+#endif
+
+// Things that are not defined should be defined as NULL
+#ifndef NORETURN
+# define NORETURN
+#endif
+#ifndef LIB_EXPORT
+# define LIB_EXPORT
+#endif
+#ifndef LIB_IMPORT
+# define LIB_IMPORT
+#endif
+#ifndef _REDUCE_WARNING_LEVEL_
+# define _REDUCE_WARNING_LEVEL_(n)
+#endif
+#ifndef _NORMAL_WARNING_LEVEL_
+# define _NORMAL_WARNING_LEVEL_
+#endif
+#ifndef NOT_REFERENCED
+# define NOT_REFERENCED(x) (x = x)
+#endif
+#ifdef _POSIX_
+typedef int SOCKET;
+#endif
+// #ifdef TPM_POSIX
+// typedef int SOCKET;
+// #endif
+#endif // _COMPILER_DEPENDENCIES_H_
+
diff --git a/src/tpm2/ContextCommands.c b/src/tpm2/ContextCommands.c
new file mode 100644
index 0000000..c557c88
--- /dev/null
+++ b/src/tpm2/ContextCommands.c
@@ -0,0 +1,458 @@
+/********************************************************************************/
+/* */
+/* Context Management */
+/* Written by Ken Goldman */
+/* IBM Thomas J. Watson Research Center */
+/* $Id: ContextCommands.c 1658 2021-01-22 23:14:01Z kgoldman $ */
+/* */
+/* Licenses and Notices */
+/* */
+/* 1. Copyright Licenses: */
+/* */
+/* - Trusted Computing Group (TCG) grants to the user of the source code in */
+/* this specification (the "Source Code") a worldwide, irrevocable, */
+/* nonexclusive, royalty free, copyright license to reproduce, create */
+/* derivative works, distribute, display and perform the Source Code and */
+/* derivative works thereof, and to grant others the rights granted herein. */
+/* */
+/* - The TCG grants to the user of the other parts of the specification */
+/* (other than the Source Code) the rights to reproduce, distribute, */
+/* display, and perform the specification solely for the purpose of */
+/* developing products based on such documents. */
+/* */
+/* 2. Source Code Distribution Conditions: */
+/* */
+/* - Redistributions of Source Code must retain the above copyright licenses, */
+/* this list of conditions and the following disclaimers. */
+/* */
+/* - Redistributions in binary form must reproduce the above copyright */
+/* licenses, this list of conditions and the following disclaimers in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* 3. Disclaimers: */
+/* */
+/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
+/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
+/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
+/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
+/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
+/* information on specification licensing rights available through TCG */
+/* membership agreements. */
+/* */
+/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
+/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
+/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
+/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
+/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
+/* */
+/* - Without limitation, TCG and its members and licensors disclaim all */
+/* liability, including liability for infringement of any proprietary */
+/* rights, relating to use of information in this specification and to the */
+/* implementation of this specification, and TCG disclaims all liability for */
+/* cost of procurement of substitute goods or services, lost profits, loss */
+/* of use, loss of data or any incidental, consequential, direct, indirect, */
+/* or special damages, whether under contract, tort, warranty or otherwise, */
+/* arising in any way out of use or reliance upon this specification or any */
+/* information herein. */
+/* */
+/* (c) Copyright IBM Corp. and others, 2016 - 2021 */
+/* */
+/********************************************************************************/
+
+#include "Tpm.h"
+#include "ContextSave_fp.h"
+#include "NVMarshal.h" // libtpms added
+#if CC_ContextSave // Conditional expansion of this file
+#include "Context_spt_fp.h"
+/* Error Returns Meaning */
+/* TPM_RC_CONTEXT_GAP a contextID could not be assigned for a session context save */
+/* TPM_RC_TOO_MANY_CONTEXTS no more contexts can be saved as the counter has maxed out */
+TPM_RC
+TPM2_ContextSave(
+ ContextSave_In *in, // IN: input parameter list
+ ContextSave_Out *out // OUT: output parameter list
+ )
+{
+ TPM_RC result = TPM_RC_SUCCESS;
+ UINT16 fingerprintSize; // The size of fingerprint in context
+ // blob.
+ UINT64 contextID = 0; // session context ID
+ TPM2B_SYM_KEY symKey;
+ TPM2B_IV iv;
+ TPM2B_DIGEST integrity;
+ UINT16 integritySize;
+ BYTE *buffer;
+ // This command may cause the orderlyState to be cleared due to
+ // the update of state reset data. If the state is orderly and
+ // cannot be changed, exit early.
+ RETURN_IF_ORDERLY;
+
+ // Internal Data Update
+
+ // This implementation does not do things in quite the same way as described in
+ // Part 2 of the specification. In Part 2, it indicates that the
+ // TPMS_CONTEXT_DATA contains two TPM2B values. That is not how this is
+ // implemented. Rather, the size field of the TPM2B_CONTEXT_DATA is used to
+ // determine the amount of data in the encrypted data. That part is not
+ // independently sized. This makes the actual size 2 bytes smaller than
+ // calculated using Part 2. Since this is opaque to the caller, it is not
+ // necessary to fix. The actual size is returned by TPM2_GetCapabilties().
+
+ // Initialize output handle. At the end of command action, the output
+ // handle of an object will be replaced, while the output handle
+ // for a session will be the same as input
+ out->context.savedHandle = in->saveHandle;
+ // Get the size of fingerprint in context blob. The sequence value in
+ // TPMS_CONTEXT structure is used as the fingerprint
+ fingerprintSize = sizeof(out->context.sequence);
+ // Compute the integrity size at the beginning of context blob
+ integritySize = sizeof(integrity.t.size)
+ + CryptHashGetDigestSize(CONTEXT_INTEGRITY_HASH_ALG);
+ // Perform object or session specific context save
+ switch(HandleGetType(in->saveHandle))
+ {
+ case TPM_HT_TRANSIENT:
+ {
+ OBJECT *object = HandleToObject(in->saveHandle);
+ ANY_OBJECT_BUFFER *outObject;
+ unsigned char buffer[sizeof(OBJECT) * 2]; // libtpms changed begin
+ BYTE *bufptr = &buffer[0];
+ INT32 size = sizeof(buffer);
+ UINT16 written = ANY_OBJECT_Marshal(object, &bufptr, &size);
+ UINT16 objectSize = written; // libtpms changed end
+ outObject = (ANY_OBJECT_BUFFER *)(out->context.contextBlob.t.buffer
+ + integritySize + fingerprintSize);
+ // Set size of the context data. The contents of context blob is vendor
+ // defined. In this implementation, the size is size of integrity
+ // plus fingerprint plus the whole internal OBJECT structure
+ out->context.contextBlob.t.size = integritySize +
+ fingerprintSize + objectSize;
+ // Make sure things fit
+ pAssert(out->context.contextBlob.t.size
+ <= sizeof(out->context.contextBlob.t.buffer));
+ // Copy the whole internal OBJECT structure to context blob
+ MemoryCopy(outObject, buffer, written); // libtpms changed
+ // Increment object context ID
+ gr.objectContextID++;
+ // If object context ID overflows, TPM should be put in failure mode
+ if(gr.objectContextID == 0)
+ FAIL(FATAL_ERROR_INTERNAL);
+ // Fill in other return values for an object.
+ out->context.sequence = gr.objectContextID;
+ // For regular object, savedHandle is 0x80000000. For sequence object,
+ // savedHandle is 0x80000001. For object with stClear, savedHandle
+ // is 0x80000002
+ if(ObjectIsSequence(object))
+ {
+ out->context.savedHandle = 0x80000001;
+ /* ANY_OBJECT_Marshal already wrote it // libtpms changed begin
+ SequenceDataExport((HASH_OBJECT *)object,
+ (HASH_OBJECT_BUFFER *)outObject);
+ */ // libtpms changed end
+ }
+ else
+ out->context.savedHandle = (object->attributes.stClear == SET)
+ ? 0x80000002 : 0x80000000;
+ // Get object hierarchy
+ out->context.hierarchy = ObjectGetHierarchy(object);
+ break;
+ }
+ case TPM_HT_HMAC_SESSION:
+ case TPM_HT_POLICY_SESSION:
+ {
+ SESSION *session = SessionGet(in->saveHandle);
+ // Set size of the context data. The contents of context blob is vendor
+ // defined. In this implementation, the size of context blob is the
+ // size of a internal session structure plus the size of
+ // fingerprint plus the size of integrity
+ out->context.contextBlob.t.size = integritySize +
+ fingerprintSize + sizeof(*session);
+ // Make sure things fit
+ pAssert(out->context.contextBlob.t.size
+ < sizeof(out->context.contextBlob.t.buffer));
+ // Copy the whole internal SESSION structure to context blob.
+ // Save space for fingerprint at the beginning of the buffer
+ // This is done before anything else so that the actual context
+ // can be reclaimed after this call
+ pAssert(sizeof(*session) <= sizeof(out->context.contextBlob.t.buffer)
+ - integritySize - fingerprintSize);
+ MemoryCopy(out->context.contextBlob.t.buffer + integritySize
+ + fingerprintSize, session, sizeof(*session));
+ // Fill in the other return parameters for a session
+ // Get a context ID and set the session tracking values appropriately
+ // TPM_RC_CONTEXT_GAP is a possible error.
+ // SessionContextSave() will flush the in-memory context
+ // so no additional errors may occur after this call.
+ result = SessionContextSave(out->context.savedHandle, &contextID);
+ if(result != TPM_RC_SUCCESS)
+ return result;
+ // sequence number is the current session contextID
+ out->context.sequence = contextID;
+ // use TPM_RH_NULL as hierarchy for session context
+ out->context.hierarchy = TPM_RH_NULL;
+ break;
+ }
+ default:
+ // SaveContext may only take an object handle or a session handle.
+ // All the other handle type should be filtered out at unmarshal
+ FAIL(FATAL_ERROR_INTERNAL);
+ break;
+ }
+ // Save fingerprint at the beginning of encrypted area of context blob.
+ // Reserve the integrity space
+ pAssert(sizeof(out->context.sequence) <=
+ sizeof(out->context.contextBlob.t.buffer) - integritySize);
+ MemoryCopy(out->context.contextBlob.t.buffer + integritySize,
+ &out->context.sequence, sizeof(out->context.sequence));
+ // Compute context encryption key
+ ComputeContextProtectionKey(&out->context, &symKey, &iv);
+ // Encrypt context blob
+ CryptSymmetricEncrypt(out->context.contextBlob.t.buffer + integritySize,
+ CONTEXT_ENCRYPT_ALG, CONTEXT_ENCRYPT_KEY_BITS,
+ symKey.t.buffer, &iv, TPM_ALG_CFB,
+ out->context.contextBlob.t.size - integritySize,
+ out->context.contextBlob.t.buffer + integritySize);
+ // Compute integrity hash for the object
+ // In this implementation, the same routine is used for both sessions
+ // and objects.
+ ComputeContextIntegrity(&out->context, &integrity);
+ // add integrity at the beginning of context blob
+ buffer = out->context.contextBlob.t.buffer;
+ TPM2B_DIGEST_Marshal(&integrity, &buffer, NULL);
+ // orderly state should be cleared because of the update of state reset and
+ // state clear data
+ g_clearOrderly = TRUE;
+ return result;
+}
+#endif // CC_ContextSave
+#include "Tpm.h"
+#include "ContextLoad_fp.h"
+#if CC_ContextLoad // Conditional expansion of this file
+#include "Context_spt_fp.h"
+TPM_RC
+TPM2_ContextLoad(
+ ContextLoad_In *in, // IN: input parameter list
+ ContextLoad_Out *out // OUT: output parameter list
+ )
+{
+ TPM_RC result;
+ TPM2B_DIGEST integrityToCompare;
+ TPM2B_DIGEST integrity;
+ BYTE *buffer; // defined to save some typing
+ INT32 size; // defined to save some typing
+ TPM_HT handleType;
+ TPM2B_SYM_KEY symKey;
+ TPM2B_IV iv;
+ // Input Validation
+
+ // See discussion about the context format in TPM2_ContextSave Detailed Actions
+
+ // IF this is a session context, make sure that the sequence number is
+ // consistent with the version in the slot
+ // Check context blob size
+ handleType = HandleGetType(in->context.savedHandle);
+ // Get integrity from context blob
+ buffer = in->context.contextBlob.t.buffer;
+ size = (INT32)in->context.contextBlob.t.size;
+ result = TPM2B_DIGEST_Unmarshal(&integrity, &buffer, &size);
+ if(result != TPM_RC_SUCCESS)
+ return result;
+ // the size of the integrity value has to match the size of digest produced
+ // by the integrity hash
+ if(integrity.t.size != CryptHashGetDigestSize(CONTEXT_INTEGRITY_HASH_ALG))
+ return TPM_RCS_SIZE + RC_ContextLoad_context;
+ // Make sure that the context blob has enough space for the fingerprint. This
+ // is elastic pants to go with the belt and suspenders we already have to make
+ // sure that the context is complete and untampered.
+ if((unsigned)size < sizeof(in->context.sequence))
+ return TPM_RCS_SIZE + RC_ContextLoad_context;
+ // After unmarshaling the integrity value, 'buffer' is pointing at the first
+ // byte of the integrity protected and encrypted buffer and 'size' is the number
+ // of integrity protected and encrypted bytes.
+ // Compute context integrity
+ ComputeContextIntegrity(&in->context, &integrityToCompare);
+ // Compare integrity
+ if(!MemoryEqual2B(&integrity.b, &integrityToCompare.b))
+ return TPM_RCS_INTEGRITY + RC_ContextLoad_context;
+ // Compute context encryption key
+ ComputeContextProtectionKey(&in->context, &symKey, &iv);
+ // Decrypt context data in place
+ CryptSymmetricDecrypt(buffer, CONTEXT_ENCRYPT_ALG, CONTEXT_ENCRYPT_KEY_BITS,
+ symKey.t.buffer, &iv, TPM_ALG_CFB, size, buffer);
+ // See if the fingerprint value matches. If not, it is symptomatic of either
+ // a broken TPM or that the TPM is under attack so go into failure mode.
+ if(!MemoryEqual(buffer, &in->context.sequence, sizeof(in->context.sequence)))
+ FAIL(FATAL_ERROR_INTERNAL);
+ // step over fingerprint
+ buffer += sizeof(in->context.sequence);
+ // set the remaining size of the context
+ size -= sizeof(in->context.sequence);
+ // Perform object or session specific input check
+ switch(handleType)
+ {
+ case TPM_HT_TRANSIENT:
+ {
+ OBJECT *outObject;
+ if(size > (INT32)sizeof(OBJECT))
+ FAIL(FATAL_ERROR_INTERNAL);
+ // Discard any changes to the handle that the TRM might have made
+ in->context.savedHandle = TRANSIENT_FIRST;
+ // If hierarchy is disabled, no object context can be loaded in this
+ // hierarchy
+ if(!HierarchyIsEnabled(in->context.hierarchy))
+ return TPM_RCS_HIERARCHY + RC_ContextLoad_context;
+ // Restore object. If there is no empty space, indicate as much
+ outObject = ObjectContextLoadLibtpms(buffer, size, // libtpms changed
+ &out->loadedHandle);
+ if(outObject == NULL)
+ return TPM_RC_OBJECT_MEMORY;
+ break;
+ }
+ case TPM_HT_POLICY_SESSION:
+ case TPM_HT_HMAC_SESSION:
+ {
+ if(size != sizeof(SESSION))
+ FAIL(FATAL_ERROR_INTERNAL);
+ // This command may cause the orderlyState to be cleared due to
+ // the update of state reset data. If this is the case, check if NV is
+ // available first
+ RETURN_IF_ORDERLY;
+ // Check if input handle points to a valid saved session and that the
+ // sequence number makes sense
+ if(!SequenceNumberForSavedContextIsValid(&in->context))
+ return TPM_RCS_HANDLE + RC_ContextLoad_context;
+ // Restore session. A TPM_RC_SESSION_MEMORY, TPM_RC_CONTEXT_GAP error
+ // may be returned at this point
+ result = SessionContextLoad((SESSION_BUF *)buffer,
+ &in->context.savedHandle);
+ if(result != TPM_RC_SUCCESS)
+ return result;
+ out->loadedHandle = in->context.savedHandle;
+ // orderly state should be cleared because of the update of state
+ // reset and state clear data
+ g_clearOrderly = TRUE;
+ break;
+ }
+ default:
+ // Context blob may only have an object handle or a session handle.
+ // All the other handle type should be filtered out at unmarshal
+ FAIL(FATAL_ERROR_INTERNAL);
+ break;
+ }
+ return TPM_RC_SUCCESS;
+}
+#endif // CC_ContextLoad
+#include "Tpm.h"
+#include "FlushContext_fp.h"
+#if CC_FlushContext // Conditional expansion of this file
+TPM_RC
+TPM2_FlushContext(
+ FlushContext_In *in // IN: input parameter list
+ )
+{
+ // Internal Data Update
+ // Call object or session specific routine to flush
+ switch(HandleGetType(in->flushHandle))
+ {
+ case TPM_HT_TRANSIENT:
+ if(!IsObjectPresent(in->flushHandle))
+ return TPM_RCS_HANDLE + RC_FlushContext_flushHandle;
+ // Flush object
+ FlushObject(in->flushHandle);
+ break;
+ case TPM_HT_HMAC_SESSION:
+ case TPM_HT_POLICY_SESSION:
+ if(!SessionIsLoaded(in->flushHandle)
+ && !SessionIsSaved(in->flushHandle)
+ )
+ return TPM_RCS_HANDLE + RC_FlushContext_flushHandle;
+ // If the session to be flushed is the exclusive audit session, then
+ // indicate that there is no exclusive audit session any longer.
+ if(in->flushHandle == g_exclusiveAuditSession)
+ g_exclusiveAuditSession = TPM_RH_UNASSIGNED;
+ // Flush session
+ SessionFlush(in->flushHandle);
+ break;
+ default:
+ // This command only takes object or session handle. Other handles
+ // should be filtered out at handle unmarshal
+ FAIL(FATAL_ERROR_INTERNAL);
+ break;
+ }
+ return TPM_RC_SUCCESS;
+}
+#endif // CC_FlushContext
+#include "Tpm.h"
+#include "EvictControl_fp.h"
+#if CC_EvictControl // Conditional expansion of this file
+TPM_RC
+TPM2_EvictControl(
+ EvictControl_In *in // IN: input parameter list
+ )
+{
+ TPM_RC result;
+ OBJECT *evictObject;
+ // Input Validation
+ // Get internal object pointer
+ evictObject = HandleToObject(in->objectHandle);
+ // Temporary, stClear or public only objects can not be made persistent
+ if(evictObject->attributes.temporary == SET
+ || evictObject->attributes.stClear == SET
+ || evictObject->attributes.publicOnly == SET)
+ return TPM_RCS_ATTRIBUTES + RC_EvictControl_objectHandle;
+ // If objectHandle refers to a persistent object, it should be the same as
+ // input persistentHandle
+ if(evictObject->attributes.evict == SET
+ && evictObject->evictHandle != in->persistentHandle)
+ return TPM_RCS_HANDLE + RC_EvictControl_objectHandle;
+ // Additional authorization validation
+ if(in->auth == TPM_RH_PLATFORM)
+ {
+ // To make persistent
+ if(evictObject->attributes.evict == CLEAR)
+ {
+ // PlatformAuth can not set evict object in storage or endorsement
+ // hierarchy
+ if(evictObject->attributes.ppsHierarchy == CLEAR)
+ return TPM_RCS_HIERARCHY + RC_EvictControl_objectHandle;
+ // Platform cannot use a handle outside of platform persistent range.
+ if(!NvIsPlatformPersistentHandle(in->persistentHandle))
+ return TPM_RCS_RANGE + RC_EvictControl_persistentHandle;
+ }
+ // PlatformAuth can delete any persistent object
+ }
+ else if(in->auth == TPM_RH_OWNER)
+ {
+ // OwnerAuth can not set or clear evict object in platform hierarchy
+ if(evictObject->attributes.ppsHierarchy == SET)
+ return TPM_RCS_HIERARCHY + RC_EvictControl_objectHandle;
+ // Owner cannot use a handle outside of owner persistent range.
+ if(evictObject->attributes.evict == CLEAR
+ && !NvIsOwnerPersistentHandle(in->persistentHandle))
+ return TPM_RCS_RANGE + RC_EvictControl_persistentHandle;
+ }
+ else
+ {
+ // Other authorization is not allowed in this command and should have been
+ // filtered out in unmarshal process
+ FAIL(FATAL_ERROR_INTERNAL);
+ }
+ // Internal Data Update
+ // Change evict state
+ if(evictObject->attributes.evict == CLEAR)
+ {
+ // Make object persistent
+ if(NvFindHandle(in->persistentHandle) != 0)
+ return TPM_RC_NV_DEFINED;
+ // A TPM_RC_NV_HANDLE or TPM_RC_NV_SPACE error may be returned at this
+ // point
+ result = NvAddEvictObject(in->persistentHandle, evictObject);
+ }
+ else
+ {
+ // Delete the persistent object in NV
+ result = NvDeleteEvict(evictObject->evictHandle);
+ }
+ return result;
+}
+#endif // CC_EvictControl
diff --git a/src/tpm2/ContextLoad_fp.h b/src/tpm2/ContextLoad_fp.h
new file mode 100644
index 0000000..79e8800
--- /dev/null
+++ b/src/tpm2/ContextLoad_fp.h
@@ -0,0 +1,84 @@
+/********************************************************************************/
+/* */
+/* */
+/* Written by Ken Goldman */
+/* IBM Thomas J. Watson Research Center */
+/* $Id: ContextLoad_fp.h 809 2016-11-16 18:31:54Z kgoldman $ */
+/* */
+/* Licenses and Notices */
+/* */
+/* 1. Copyright Licenses: */
+/* */
+/* - Trusted Computing Group (TCG) grants to the user of the source code in */
+/* this specification (the "Source Code") a worldwide, irrevocable, */
+/* nonexclusive, royalty free, copyright license to reproduce, create */
+/* derivative works, distribute, display and perform the Source Code and */
+/* derivative works thereof, and to grant others the rights granted herein. */
+/* */
+/* - The TCG grants to the user of the other parts of the specification */
+/* (other than the Source Code) the rights to reproduce, distribute, */
+/* display, and perform the specification solely for the purpose of */
+/* developing products based on such documents. */
+/* */
+/* 2. Source Code Distribution Conditions: */
+/* */
+/* - Redistributions of Source Code must retain the above copyright licenses, */
+/* this list of conditions and the following disclaimers. */
+/* */
+/* - Redistributions in binary form must reproduce the above copyright */
+/* licenses, this list of conditions and the following disclaimers in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* 3. Disclaimers: */
+/* */
+/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
+/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
+/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
+/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
+/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
+/* information on specification licensing rights available through TCG */
+/* membership agreements. */
+/* */
+/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
+/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
+/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
+/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
+/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
+/* */
+/* - Without limitation, TCG and its members and licensors disclaim all */
+/* liability, including liability for infringement of any proprietary */
+/* rights, relating to use of information in this specification and to the */
+/* implementation of this specification, and TCG disclaims all liability for */
+/* cost of procurement of substitute goods or services, lost profits, loss */
+/* of use, loss of data or any incidental, consequential, direct, indirect, */
+/* or special damages, whether under contract, tort, warranty or otherwise, */
+/* arising in any way out of use or reliance upon this specification or any */
+/* information herein. */
+/* */
+/* (c) Copyright IBM Corp. and others, 2012-2015 */
+/* */
+/********************************************************************************/
+
+/* rev 119 */
+
+#ifndef CONTEXTLOAD_FP_H
+#define CONTEXTLOAD_FP_H
+
+typedef struct {
+ TPMS_CONTEXT context;
+} ContextLoad_In;
+
+#define RC_ContextLoad_context (TPM_RC_P + TPM_RC_1)
+
+typedef struct {
+ TPMI_DH_CONTEXT loadedHandle;
+} ContextLoad_Out;
+
+TPM_RC
+TPM2_ContextLoad(
+ ContextLoad_In *in, // IN: input parameter list
+ ContextLoad_Out *out // OUT: output parameter list
+ );
+
+
+#endif
diff --git a/src/tpm2/ContextSave_fp.h b/src/tpm2/ContextSave_fp.h
new file mode 100644
index 0000000..631ee91
--- /dev/null
+++ b/src/tpm2/ContextSave_fp.h
@@ -0,0 +1,84 @@
+/********************************************************************************/
+/* */
+/* */
+/* Written by Ken Goldman */
+/* IBM Thomas J. Watson Research Center */
+/* $Id: ContextSave_fp.h 809 2016-11-16 18:31:54Z kgoldman $ */
+/* */
+/* Licenses and Notices */
+/* */
+/* 1. Copyright Licenses: */
+/* */
+/* - Trusted Computing Group (TCG) grants to the user of the source code in */
+/* this specification (the "Source Code") a worldwide, irrevocable, */
+/* nonexclusive, royalty free, copyright license to reproduce, create */
+/* derivative works, distribute, display and perform the Source Code and */
+/* derivative works thereof, and to grant others the rights granted herein. */
+/* */
+/* - The TCG grants to the user of the other parts of the specification */
+/* (other than the Source Code) the rights to reproduce, distribute, */
+/* display, and perform the specification solely for the purpose of */
+/* developing products based on such documents. */
+/* */
+/* 2. Source Code Distribution Conditions: */
+/* */
+/* - Redistributions of Source Code must retain the above copyright licenses, */
+/* this list of conditions and the following disclaimers. */
+/* */
+/* - Redistributions in binary form must reproduce the above copyright */
+/* licenses, this list of conditions and the following disclaimers in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* 3. Disclaimers: */
+/* */
+/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
+/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
+/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
+/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
+/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
+/* information on specification licensing rights available through TCG */
+/* membership agreements. */
+/* */
+/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
+/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
+/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
+/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
+/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
+/* */
+/* - Without limitation, TCG and its members and licensors disclaim all */
+/* liability, including liability for infringement of any proprietary */
+/* rights, relating to use of information in this specification and to the */
+/* implementation of this specification, and TCG disclaims all liability for */
+/* cost of procurement of substitute goods or services, lost profits, loss */
+/* of use, loss of data or any incidental, consequential, direct, indirect, */
+/* or special damages, whether under contract, tort, warranty or otherwise, */
+/* arising in any way out of use or reliance upon this specification or any */
+/* information herein. */
+/* */
+/* (c) Copyright IBM Corp. and others, 2012-2015 */
+/* */
+/********************************************************************************/
+
+/* rev 119 */
+
+#ifndef CONTEXTSAVE_FP_H
+#define CONTEXTSAVE_FP_H
+
+typedef struct {
+ TPMI_DH_CONTEXT saveHandle;
+} ContextSave_In;
+
+#define RC_ContextSave_saveHandle (TPM_RC_P + TPM_RC_1)
+
+typedef struct {
+ TPMS_CONTEXT context;
+} ContextSave_Out;
+
+TPM_RC
+TPM2_ContextSave(
+ ContextSave_In *in, // IN: input parameter list
+ ContextSave_Out *out // OUT: output parameter list
+ );
+
+
+#endif
diff --git a/src/tpm2/Context_spt.c b/src/tpm2/Context_spt.c
new file mode 100644
index 0000000..a46d730
--- /dev/null
+++ b/src/tpm2/Context_spt.c
@@ -0,0 +1,204 @@
+/********************************************************************************/
+/* */
+/* Context Management Command Support */
+/* Written by Ken Goldman */
+/* IBM Thomas J. Watson Research Center */
+/* $Id: Context_spt.c 1603 2020-04-03 17:48:43Z kgoldman $ */
+/* */
+/* Licenses and Notices */
+/* */
+/* 1. Copyright Licenses: */
+/* */
+/* - Trusted Computing Group (TCG) grants to the user of the source code in */
+/* this specification (the "Source Code") a worldwide, irrevocable, */
+/* nonexclusive, royalty free, copyright license to reproduce, create */
+/* derivative works, distribute, display and perform the Source Code and */
+/* derivative works thereof, and to grant others the rights granted herein. */
+/* */
+/* - The TCG grants to the user of the other parts of the specification */
+/* (other than the Source Code) the rights to reproduce, distribute, */
+/* display, and perform the specification solely for the purpose of */
+/* developing products based on such documents. */
+/* */
+/* 2. Source Code Distribution Conditions: */
+/* */
+/* - Redistributions of Source Code must retain the above copyright licenses, */
+/* this list of conditions and the following disclaimers. */
+/* */
+/* - Redistributions in binary form must reproduce the above copyright */
+/* licenses, this list of conditions and the following disclaimers in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* 3. Disclaimers: */
+/* */
+/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
+/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
+/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
+/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
+/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
+/* information on specification licensing rights available through TCG */
+/* membership agreements. */
+/* */
+/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
+/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
+/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
+/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
+/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
+/* */
+/* - Without limitation, TCG and its members and licensors disclaim all */
+/* liability, including liability for infringement of any proprietary */
+/* rights, relating to use of information in this specification and to the */
+/* implementation of this specification, and TCG disclaims all liability for */
+/* cost of procurement of substitute goods or services, lost profits, loss */
+/* of use, loss of data or any incidental, consequential, direct, indirect, */
+/* or special damages, whether under contract, tort, warranty or otherwise, */
+/* arising in any way out of use or reliance upon this specification or any */
+/* information herein. */
+/* */
+/* (c) Copyright IBM Corp. and others, 2016 - 2020 */
+/* */
+/********************************************************************************/
+
+/* 7.3.1 Includes */
+#include "Tpm.h"
+#include "Context_spt_fp.h"
+/* 7.3.2 Functions */
+/* 7.3.2.1 ComputeContextProtectionKey() */
+/* This function retrieves the symmetric protection key for context encryption It is used by
+ TPM2_ContextSave() and TPM2_ContextLoad() to create the symmetric encryption key and iv */
+void
+ComputeContextProtectionKey(
+ TPMS_CONTEXT *contextBlob, // IN: context blob
+ TPM2B_SYM_KEY *symKey, // OUT: the symmetric key
+ TPM2B_IV *iv // OUT: the IV.
+ )
+{
+ UINT16 symKeyBits; // number of bits in the parent's
+ // symmetric key
+ TPM2B_PROOF *proof = NULL; // the proof value to use. Is null for
+ // everything but a primary object in
+ // the Endorsement Hierarchy
+ BYTE kdfResult[sizeof(TPMU_HA) * 2];// Value produced by the KDF
+ TPM2B_DATA sequence2B, handle2B;
+ // Get proof value
+ proof = HierarchyGetProof(contextBlob->hierarchy);
+
+ // Get sequence value in 2B format
+ sequence2B.t.size = sizeof(contextBlob->sequence);
+ cAssert(sequence2B.t.size <= sizeof(sequence2B.t.buffer));
+ MemoryCopy(sequence2B.t.buffer, &contextBlob->sequence, sequence2B.t.size);
+
+ // Get handle value in 2B format
+ handle2B.t.size = sizeof(contextBlob->savedHandle);
+ cAssert(handle2B.t.size <= sizeof(handle2B.t.buffer));
+ MemoryCopy(handle2B.t.buffer, &contextBlob->savedHandle, handle2B.t.size);
+
+ // Get the symmetric encryption key size
+ symKey->t.size = CONTEXT_ENCRYPT_KEY_BYTES;
+ symKeyBits = CONTEXT_ENCRYPT_KEY_BITS;
+ // Get the size of the IV for the algorithm
+ iv->t.size = CryptGetSymmetricBlockSize(CONTEXT_ENCRYPT_ALG, symKeyBits);
+ // KDFa to generate symmetric key and IV value
+ CryptKDFa(CONTEXT_INTEGRITY_HASH_ALG, &proof->b, CONTEXT_KEY, &sequence2B.b,
+ &handle2B.b, (symKey->t.size + iv->t.size) * 8, kdfResult, NULL,
+ FALSE);
+ // Copy part of the returned value as the key
+ pAssert(symKey->t.size <= sizeof(symKey->t.buffer));
+ MemoryCopy(symKey->t.buffer, kdfResult, symKey->t.size);
+ // Copy the rest as the IV
+ pAssert(iv->t.size <= sizeof(iv->t.buffer));
+ MemoryCopy(iv->t.buffer, &kdfResult[symKey->t.size], iv->t.size);
+ return;
+}
+/* 7.3.2.2 ComputeContextIntegrity() */
+/* Generate the integrity hash for a context It is used by TPM2_ContextSave() to create an integrity
+ hash and by TPM2_ContextLoad() to compare an integrity hash */
+void
+ComputeContextIntegrity(
+ TPMS_CONTEXT *contextBlob, // IN: context blob
+ TPM2B_DIGEST *integrity // OUT: integrity
+ )
+{
+ HMAC_STATE hmacState;
+ TPM2B_PROOF *proof;
+ UINT16 integritySize;
+ // Get proof value
+ proof = HierarchyGetProof(contextBlob->hierarchy);
+ // Start HMAC
+ integrity->t.size = CryptHmacStart2B(&hmacState, CONTEXT_INTEGRITY_HASH_ALG,
+ &proof->b);
+ // Compute integrity size at the beginning of context blob
+ integritySize = sizeof(integrity->t.size) + integrity->t.size;
+ // Adding total reset counter so that the context cannot be
+ // used after a TPM Reset
+ CryptDigestUpdateInt(&hmacState.hashState, sizeof(gp.totalResetCount),
+ gp.totalResetCount);
+ // If this is a ST_CLEAR object, add the clear count
+ // so that this contest cannot be loaded after a TPM Restart
+ if(contextBlob->savedHandle == 0x80000002)
+ CryptDigestUpdateInt(&hmacState.hashState, sizeof(gr.clearCount),
+ gr.clearCount);
+ // Adding sequence number to the HMAC to make sure that it doesn't
+ // get changed
+ CryptDigestUpdateInt(&hmacState.hashState, sizeof(contextBlob->sequence),
+ contextBlob->sequence);
+ // Protect the handle
+ CryptDigestUpdateInt(&hmacState.hashState, sizeof(contextBlob->savedHandle),
+ contextBlob->savedHandle);
+ // Adding sensitive contextData, skip the leading integrity area
+ CryptDigestUpdate(&hmacState.hashState,
+ contextBlob->contextBlob.t.size - integritySize,
+ contextBlob->contextBlob.t.buffer + integritySize);
+ // Complete HMAC
+ CryptHmacEnd2B(&hmacState, &integrity->b);
+ return;
+}
+#if 0
+/* 7.3.2.3 SequenceDataExport() */
+/* This function is used scan through the sequence object and either modify the hash state data for
+ export (contextSave) or to import it into the internal format (contextLoad). This function should
+ only be called after the sequence object has been copied to the context buffer (contextSave) or
+ from the context buffer into the sequence object. The presumption is that the context buffer
+ version of the data is the same size as the internal representation so nothing outsize of the
+ hash context area gets modified. */
+void
+SequenceDataExport(
+ HASH_OBJECT *object, // IN: an internal hash object
+ HASH_OBJECT_BUFFER *exportObject // OUT: a sequence context in a buffer
+ )
+{
+ // If the hash object is not an event, then only one hash context is needed
+ int count = (object->attributes.eventSeq) ? HASH_COUNT : 1;
+ for(count--; count >= 0; count--)
+ {
+ HASH_STATE *hash = &object->state.hashState[count];
+ size_t offset = (BYTE *)hash - (BYTE *)object;
+ BYTE *exportHash = &((BYTE *)exportObject)[offset];
+ CryptHashExportState(hash, (EXPORT_HASH_STATE *)exportHash);
+ }
+}
+/* 7.3.2.4 SequenceDataImport() */
+/* This function is used scan through the sequence object and either modify the hash state data for
+ export (contextSave) or to import it into the internal format (contextLoad). This function should
+ only be called after the sequence object has been copied to the context buffer (contextSave) or
+ from the context buffer into the sequence object. The presumption is that the context buffer
+ version of the data is the same size as the internal representation so nothing outsize of the
+ hash context area gets modified. */
+void
+SequenceDataImport(
+ HASH_OBJECT *object, // IN/OUT: an internal hash object
+ HASH_OBJECT_BUFFER *exportObject // IN/OUT: a sequence context in a buffer
+ )
+{
+ // If the hash object is not an event, then only one hash context is needed
+ int count = (object->attributes.eventSeq) ? HASH_COUNT : 1;
+ for(count--; count >= 0; count--)
+ {
+ HASH_STATE *hash = &object->state.hashState[count];
+ size_t offset = (BYTE *)hash - (BYTE *)object;
+ BYTE *importHash = &((BYTE *)exportObject)[offset];
+ //
+ CryptHashImportState(hash, (EXPORT_HASH_STATE *)importHash);
+ }
+}
+#endif
diff --git a/src/tpm2/Context_spt_fp.h b/src/tpm2/Context_spt_fp.h
new file mode 100644
index 0000000..19b9576
--- /dev/null
+++ b/src/tpm2/Context_spt_fp.h
@@ -0,0 +1,88 @@
+/********************************************************************************/
+/* */
+/* */
+/* Written by Ken Goldman */
+/* IBM Thomas J. Watson Research Center */
+/* $Id: Context_spt_fp.h 1490 2019-07-26 21:13:22Z kgoldman $ */
+/* */
+/* Licenses and Notices */
+/* */
+/* 1. Copyright Licenses: */
+/* */
+/* - Trusted Computing Group (TCG) grants to the user of the source code in */
+/* this specification (the "Source Code") a worldwide, irrevocable, */
+/* nonexclusive, royalty free, copyright license to reproduce, create */
+/* derivative works, distribute, display and perform the Source Code and */
+/* derivative works thereof, and to grant others the rights granted herein. */
+/* */
+/* - The TCG grants to the user of the other parts of the specification */
+/* (other than the Source Code) the rights to reproduce, distribute, */
+/* display, and perform the specification solely for the purpose of */
+/* developing products based on such documents. */
+/* */
+/* 2. Source Code Distribution Conditions: */
+/* */
+/* - Redistributions of Source Code must retain the above copyright licenses, */
+/* this list of conditions and the following disclaimers. */
+/* */
+/* - Redistributions in binary form must reproduce the above copyright */
+/* licenses, this list of conditions and the following disclaimers in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* 3. Disclaimers: */
+/* */
+/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
+/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
+/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
+/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
+/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
+/* information on specification licensing rights available through TCG */
+/* membership agreements. */
+/* */
+/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
+/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
+/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
+/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
+/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
+/* */
+/* - Without limitation, TCG and its members and licensors disclaim all */
+/* liability, including liability for infringement of any proprietary */
+/* rights, relating to use of information in this specification and to the */
+/* implementation of this specification, and TCG disclaims all liability for */
+/* cost of procurement of substitute goods or services, lost profits, loss */
+/* of use, loss of data or any incidental, consequential, direct, indirect, */
+/* or special damages, whether under contract, tort, warranty or otherwise, */
+/* arising in any way out of use or reliance upon this specification or any */
+/* information herein. */
+/* */
+/* (c) Copyright IBM Corp. and others, 2016 */
+/* */
+/********************************************************************************/
+
+#ifndef CONTEXT_SPT_H
+#define CONTEXT_SPT_H
+
+void
+ComputeContextProtectionKey(
+ TPMS_CONTEXT *contextBlob, // IN: context blob
+ TPM2B_SYM_KEY *symKey, // OUT: the symmetric key
+ TPM2B_IV *iv // OUT: the IV.
+ );
+void
+ComputeContextIntegrity(
+ TPMS_CONTEXT *contextBlob, // IN: context blob
+ TPM2B_DIGEST *integrity // OUT: integrity
+ );
+void
+SequenceDataExport(
+ HASH_OBJECT *object, // IN: an internal hash object
+ HASH_OBJECT_BUFFER *exportObject // OUT: a sequence context in a buffer
+ );
+void
+SequenceDataImport(
+ HASH_OBJECT *object, // IN/OUT: an internal hash object
+ HASH_OBJECT_BUFFER *exportObject // IN/OUT: a sequence context in a buffer
+ );
+
+
+#endif
diff --git a/src/tpm2/CreateLoaded_fp.h b/src/tpm2/CreateLoaded_fp.h
new file mode 100644
index 0000000..302e606
--- /dev/null
+++ b/src/tpm2/CreateLoaded_fp.h
@@ -0,0 +1,90 @@
+/********************************************************************************/
+/* */
+/* */
+/* Written by Ken Goldman */
+/* IBM Thomas J. Watson Research Center */
+/* $Id: CreateLoaded_fp.h 1600 2020-03-30 22:08:01Z kgoldman $ */
+/* */
+/* Licenses and Notices */
+/* */
+/* 1. Copyright Licenses: */
+/* */
+/* - Trusted Computing Group (TCG) grants to the user of the source code in */
+/* this specification (the "Source Code") a worldwide, irrevocable, */
+/* nonexclusive, royalty free, copyright license to reproduce, create */
+/* derivative works, distribute, display and perform the Source Code and */
+/* derivative works thereof, and to grant others the rights granted herein. */
+/* */
+/* - The TCG grants to the user of the other parts of the specification */
+/* (other than the Source Code) the rights to reproduce, distribute, */
+/* display, and perform the specification solely for the purpose of */
+/* developing products based on such documents. */
+/* */
+/* 2. Source Code Distribution Conditions: */
+/* */
+/* - Redistributions of Source Code must retain the above copyright licenses, */
+/* this list of conditions and the following disclaimers. */
+/* */
+/* - Redistributions in binary form must reproduce the above copyright */
+/* licenses, this list of conditions and the following disclaimers in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* 3. Disclaimers: */
+/* */
+/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
+/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
+/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
+/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
+/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
+/* information on specification licensing rights available through TCG */
+/* membership agreements. */
+/* */
+/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
+/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
+/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
+/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
+/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
+/* */
+/* - Without limitation, TCG and its members and licensors disclaim all */
+/* liability, including liability for infringement of any proprietary */
+/* rights, relating to use of information in this specification and to the */
+/* implementation of this specification, and TCG disclaims all liability for */
+/* cost of procurement of substitute goods or services, lost profits, loss */
+/* of use, loss of data or any incidental, consequential, direct, indirect, */
+/* or special damages, whether under contract, tort, warranty or otherwise, */
+/* arising in any way out of use or reliance upon this specification or any */
+/* information herein. */
+/* */
+/* (c) Copyright IBM Corp. and others, 2012-2015 */
+/* */
+/********************************************************************************/
+
+#ifndef CREATELOADED_FP_H
+#define CREATELOADED_FP_H
+
+/* rev 136 */
+
+typedef struct {
+ TPMI_DH_PARENT parentHandle;
+ TPM2B_SENSITIVE_CREATE inSensitive;
+ TPM2B_TEMPLATE inPublic;
+} CreateLoaded_In;
+
+#define RC_CreateLoaded_parentHandle (TPM_RC_H + TPM_RC_1)
+#define RC_CreateLoaded_inSensitive (TPM_RC_P + TPM_RC_1)
+#define RC_CreateLoaded_inPublic (TPM_RC_P + TPM_RC_2)
+
+typedef struct {
+ TPM_HANDLE objectHandle;
+ TPM2B_PRIVATE outPrivate;
+ TPM2B_PUBLIC outPublic;
+ TPM2B_NAME name;
+} CreateLoaded_Out;
+
+TPM_RC
+TPM2_CreateLoaded(
+ CreateLoaded_In *in, // IN: input parameter list
+ CreateLoaded_Out *out // OUT: output parameter list
+ );
+
+#endif
diff --git a/src/tpm2/CreatePrimary_fp.h b/src/tpm2/CreatePrimary_fp.h
new file mode 100644
index 0000000..724d1bc
--- /dev/null
+++ b/src/tpm2/CreatePrimary_fp.h
@@ -0,0 +1,96 @@
+/********************************************************************************/
+/* */
+/* */
+/* Written by Ken Goldman */
+/* IBM Thomas J. Watson Research Center */
+/* $Id: CreatePrimary_fp.h 809 2016-11-16 18:31:54Z kgoldman $ */
+/* */
+/* Licenses and Notices */
+/* */
+/* 1. Copyright Licenses: */
+/* */
+/* - Trusted Computing Group (TCG) grants to the user of the source code in */
+/* this specification (the "Source Code") a worldwide, irrevocable, */
+/* nonexclusive, royalty free, copyright license to reproduce, create */
+/* derivative works, distribute, display and perform the Source Code and */
+/* derivative works thereof, and to grant others the rights granted herein. */
+/* */
+/* - The TCG grants to the user of the other parts of the specification */
+/* (other than the Source Code) the rights to reproduce, distribute, */
+/* display, and perform the specification solely for the purpose of */
+/* developing products based on such documents. */
+/* */
+/* 2. Source Code Distribution Conditions: */
+/* */
+/* - Redistributions of Source Code must retain the above copyright licenses, */
+/* this list of conditions and the following disclaimers. */
+/* */
+/* - Redistributions in binary form must reproduce the above copyright */
+/* licenses, this list of conditions and the following disclaimers in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* 3. Disclaimers: */
+/* */
+/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
+/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
+/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
+/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
+/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
+/* information on specification licensing rights available through TCG */
+/* membership agreements. */
+/* */
+/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
+/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
+/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
+/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
+/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
+/* */
+/* - Without limitation, TCG and its members and licensors disclaim all */
+/* liability, including liability for infringement of any proprietary */
+/* rights, relating to use of information in this specification and to the */
+/* implementation of this specification, and TCG disclaims all liability for */
+/* cost of procurement of substitute goods or services, lost profits, loss */
+/* of use, loss of data or any incidental, consequential, direct, indirect, */
+/* or special damages, whether under contract, tort, warranty or otherwise, */
+/* arising in any way out of use or reliance upon this specification or any */
+/* information herein. */
+/* */
+/* (c) Copyright IBM Corp. and others, 2012-2015 */
+/* */
+/********************************************************************************/
+
+/* rev 119 */
+
+#ifndef CREATEPRIMARY_FP_H
+#define CREATEPRIMARY_FP_H
+
+typedef struct {
+ TPMI_RH_HIERARCHY primaryHandle;
+ TPM2B_SENSITIVE_CREATE inSensitive;
+ TPM2B_PUBLIC inPublic;
+ TPM2B_DATA outsideInfo;
+ TPML_PCR_SELECTION creationPCR;
+} CreatePrimary_In;
+
+#define RC_CreatePrimary_primaryHandle (TPM_RC_H + TPM_RC_1)
+#define RC_CreatePrimary_inSensitive (TPM_RC_P + TPM_RC_1)
+#define RC_CreatePrimary_inPublic (TPM_RC_P + TPM_RC_2)
+#define RC_CreatePrimary_outsideInfo (TPM_RC_P + TPM_RC_3)
+#define RC_CreatePrimary_creationPCR (TPM_RC_P + TPM_RC_4)
+
+typedef struct {
+ TPM_HANDLE objectHandle;
+ TPM2B_PUBLIC outPublic;
+ TPM2B_CREATION_DATA creationData;
+ TPM2B_DIGEST creationHash;
+ TPMT_TK_CREATION creationTicket;
+ TPM2B_NAME name;
+} CreatePrimary_Out;
+
+TPM_RC
+TPM2_CreatePrimary(
+ CreatePrimary_In *in, // IN: input parameter list
+ CreatePrimary_Out *out // OUT: output parameter list
+ );
+
+#endif
diff --git a/src/tpm2/Create_fp.h b/src/tpm2/Create_fp.h
new file mode 100644
index 0000000..69752a1
--- /dev/null
+++ b/src/tpm2/Create_fp.h
@@ -0,0 +1,96 @@
+/********************************************************************************/
+/* */
+/* */
+/* Written by Ken Goldman */
+/* IBM Thomas J. Watson Research Center */
+/* $Id: Create_fp.h 1521 2019-11-15 21:00:47Z kgoldman $ */
+/* */
+/* Licenses and Notices */
+/* */
+/* 1. Copyright Licenses: */
+/* */
+/* - Trusted Computing Group (TCG) grants to the user of the source code in */
+/* this specification (the "Source Code") a worldwide, irrevocable, */
+/* nonexclusive, royalty free, copyright license to reproduce, create */
+/* derivative works, distribute, display and perform the Source Code and */
+/* derivative works thereof, and to grant others the rights granted herein. */
+/* */
+/* - The TCG grants to the user of the other parts of the specification */
+/* (other than the Source Code) the rights to reproduce, distribute, */
+/* display, and perform the specification solely for the purpose of */
+/* developing products based on such documents. */
+/* */
+/* 2. Source Code Distribution Conditions: */
+/* */
+/* - Redistributions of Source Code must retain the above copyright licenses, */
+/* this list of conditions and the following disclaimers. */
+/* */
+/* - Redistributions in binary form must reproduce the above copyright */
+/* licenses, this list of conditions and the following disclaimers in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* 3. Disclaimers: */
+/* */
+/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
+/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
+/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
+/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
+/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
+/* information on specification licensing rights available through TCG */
+/* membership agreements. */
+/* */
+/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
+/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
+/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
+/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
+/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
+/* */
+/* - Without limitation, TCG and its members and licensors disclaim all */
+/* liability, including liability for infringement of any proprietary */
+/* rights, relating to use of information in this specification and to the */
+/* implementation of this specification, and TCG disclaims all liability for */
+/* cost of procurement of substitute goods or services, lost profits, loss */
+/* of use, loss of data or any incidental, consequential, direct, indirect, */
+/* or special damages, whether under contract, tort, warranty or otherwise, */
+/* arising in any way out of use or reliance upon this specification or any */
+/* information herein. */
+/* */
+/* (c) Copyright IBM Corp. and others, 2012-2015 */
+/* */
+/********************************************************************************/
+
+/* rev 137 */
+
+#ifndef CREATE_FP_H
+#define CREATE_FP_H
+
+typedef struct {
+ TPMI_DH_OBJECT parentHandle;
+ TPM2B_SENSITIVE_CREATE inSensitive;
+ TPM2B_PUBLIC inPublic;
+ TPM2B_DATA outsideInfo;
+ TPML_PCR_SELECTION creationPCR;
+} Create_In;
+
+#define RC_Create_parentHandle (TPM_RC_H + TPM_RC_1)
+#define RC_Create_inSensitive (TPM_RC_P + TPM_RC_1)
+#define RC_Create_inPublic (TPM_RC_P + TPM_RC_2)
+#define RC_Create_outsideInfo (TPM_RC_P + TPM_RC_3)
+#define RC_Create_creationPCR (TPM_RC_P + TPM_RC_4)
+
+typedef struct {
+ TPM2B_PRIVATE outPrivate;
+ TPM2B_PUBLIC outPublic;
+ TPM2B_CREATION_DATA creationData;
+ TPM2B_DIGEST creationHash;
+ TPMT_TK_CREATION creationTicket;
+} Create_Out;
+
+TPM_RC
+TPM2_Create(
+ Create_In *in, // IN: input parameter list
+ Create_Out *out // OUT: output parameter list
+ );
+
+
+#endif
diff --git a/src/tpm2/CryptEccData.c b/src/tpm2/CryptEccData.c
new file mode 100644
index 0000000..d7bac18
--- /dev/null
+++ b/src/tpm2/CryptEccData.c
@@ -0,0 +1,618 @@
+/********************************************************************************/
+/* */
+/* ECC curve data */
+/* Written by Ken Goldman */
+/* IBM Thomas J. Watson Research Center */
+/* $Id: CryptEccData.c 1658 2021-01-22 23:14:01Z kgoldman $ */
+/* */
+/* Licenses and Notices */
+/* */
+/* 1. Copyright Licenses: */
+/* */
+/* - Trusted Computing Group (TCG) grants to the user of the source code in */
+/* this specification (the "Source Code") a worldwide, irrevocable, */
+/* nonexclusive, royalty free, copyright license to reproduce, create */
+/* derivative works, distribute, display and perform the Source Code and */
+/* derivative works thereof, and to grant others the rights granted herein. */
+/* */
+/* - The TCG grants to the user of the other parts of the specification */
+/* (other than the Source Code) the rights to reproduce, distribute, */
+/* display, and perform the specification solely for the purpose of */
+/* developing products based on such documents. */
+/* */
+/* 2. Source Code Distribution Conditions: */
+/* */
+/* - Redistributions of Source Code must retain the above copyright licenses, */
+/* this list of conditions and the following disclaimers. */
+/* */
+/* - Redistributions in binary form must reproduce the above copyright */
+/* licenses, this list of conditions and the following disclaimers in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* 3. Disclaimers: */
+/* */
+/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
+/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
+/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
+/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
+/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
+/* information on specification licensing rights available through TCG */
+/* membership agreements. */
+/* */
+/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
+/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
+/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
+/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
+/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
+/* */
+/* - Without limitation, TCG and its members and licensors disclaim all */
+/* liability, including liability for infringement of any proprietary */
+/* rights, relating to use of information in this specification and to the */
+/* implementation of this specification, and TCG disclaims all liability for */
+/* cost of procurement of substitute goods or services, lost profits, loss */
+/* of use, loss of data or any incidental, consequential, direct, indirect, */
+/* or special damages, whether under contract, tort, warranty or otherwise, */
+/* arising in any way out of use or reliance upon this specification or any */
+/* information herein. */
+/* */
+/* (c) Copyright IBM Corp. and others, 2018 - 2021 */
+/* */
+/********************************************************************************/
+
+/* 10.2.8 CryptEccData.c */
+#include "Tpm.h"
+#include "OIDs.h"
+/* This file contains the ECC curve data. The format of the data depends on the setting of
+ USE_BN_ECC_DATA. If it is defined, then the TPM's BigNum() format is used. Otherwise, it is kept
+ in TPM2B format. The purpose of having the data in BigNum() format is so that it does not have to
+ be reformatted before being used by the crypto library. */
+#if ALG_ECC
+#if USE_BN_ECC_DATA
+# define TO_ECC_64 TO_CRYPT_WORD_64
+# define TO_ECC_56(a, b, c, d, e, f, g) TO_ECC_64(0, a, b, c, d, e, f, g)
+# define TO_ECC_48(a, b, c, d, e, f) TO_ECC_64(0, 0, a, b, c, d, e, f)
+# define TO_ECC_40(a, b, c, d, e) TO_ECC_64(0, 0, 0, a, b, c, d, e)
+# if RADIX_BITS > 32
+# define TO_ECC_32(a, b, c, d) TO_ECC_64(0, 0, 0, 0, a, b, c, d)
+# define TO_ECC_24(a, b, c) TO_ECC_64(0, 0, 0, 0, 0, a, b, c)
+# define TO_ECC_16(a, b) TO_ECC_64(0, 0, 0, 0, 0, 0, a, b)
+# define TO_ECC_8(a) TO_ECC_64(0, 0, 0, 0, 0, 0, 0, a)
+# else // RADIX_BITS == 32
+# define TO_ECC_32 BIG_ENDIAN_BYTES_TO_UINT32
+# define TO_ECC_24(a, b, c) TO_ECC_32(0, a, b, c)
+# define TO_ECC_16(a, b) TO_ECC_32(0, 0, a, b)
+# define TO_ECC_8(a) TO_ECC_32(0, 0, 0, a)
+# endif
+#else // TPM2B_
+# define TO_ECC_64(a, b, c, d, e, f, g, h) a, b, c, d, e, f, g, h
+# define TO_ECC_56(a, b, c, d, e, f, g) a, b, c, d, e, f, g
+# define TO_ECC_48(a, b, c, d, e, f) a, b, c, d, e, f
+# define TO_ECC_40(a, b, c, d, e) a, b, c, d, e
+# define TO_ECC_32(a, b, c, d) a, b, c, d
+# define TO_ECC_24(a, b, c) a, b, c
+# define TO_ECC_16(a, b) a, b
+# define TO_ECC_8(a) a
+#endif
+#if USE_BN_ECC_DATA
+#define BN_MIN_ALLOC(bytes) \
+ (BYTES_TO_CRYPT_WORDS(bytes) == 0) ? 1 : BYTES_TO_CRYPT_WORDS(bytes)
+# define ECC_CONST(NAME, bytes, initializer) \
+ const struct { \
+ crypt_uword_t allocate, size, d[BN_MIN_ALLOC(bytes)]; \
+ } NAME = {BN_MIN_ALLOC(bytes), BYTES_TO_CRYPT_WORDS(bytes),{initializer}}
+ ECC_CONST(ECC_ZERO, 0, 0);
+#else
+# define ECC_CONST(NAME, bytes, initializer) \
+ const TPM2B_##bytes##_BYTE_VALUE NAME = {bytes, {initializer}}
+/* Have to special case ECC_ZERO */
+TPM2B_BYTE_VALUE(1);
+TPM2B_1_BYTE_VALUE ECC_ZERO = {1, {0}};
+#endif
+ECC_CONST(ECC_ONE, 1, 1);
+#if !USE_BN_ECC_DATA
+TPM2B_BYTE_VALUE(24);
+#define TO_ECC_192(a, b, c) a, b, c
+TPM2B_BYTE_VALUE(28);
+#define TO_ECC_224(a, b, c, d) a, b, c, d
+TPM2B_BYTE_VALUE(32);
+#define TO_ECC_256(a, b, c, d) a, b, c, d
+TPM2B_BYTE_VALUE(48);
+#define TO_ECC_384(a, b, c, d, e, f) a, b, c, d, e, f
+TPM2B_BYTE_VALUE(66);
+#define TO_ECC_528(a, b, c, d, e, f, g, h, i) a, b, c, d, e, f, g, h, i
+TPM2B_BYTE_VALUE(80);
+#define TO_ECC_640(a, b, c, d, e, f, g, h, i, j) a, b, c, d, e, f, g, h, i, j
+#else
+#define TO_ECC_192(a, b, c) c, b, a
+#define TO_ECC_224(a, b, c, d) d, c, b, a
+#define TO_ECC_256(a, b, c, d) d, c, b, a
+#define TO_ECC_384(a, b, c, d, e, f) f, e, d, c, b, a
+#define TO_ECC_528(a, b, c, d, e, f, g, h, i) i, h, g, f, e, d, c, b, a
+#define TO_ECC_640(a, b, c, d, e, f, g, h, i, j) j, i, h, g, f, e, d, c, b, a
+#endif // !USE_BN_ECC_DATA
+#if ECC_NIST_P192
+ECC_CONST(NIST_P192_p, 24, TO_ECC_192(
+ TO_ECC_64(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF),
+ TO_ECC_64(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE),
+ TO_ECC_64(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF)));
+ECC_CONST(NIST_P192_a, 24, TO_ECC_192(
+ TO_ECC_64(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF),
+ TO_ECC_64(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE),
+ TO_ECC_64(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC)));
+ECC_CONST(NIST_P192_b, 24, TO_ECC_192(
+ TO_ECC_64(0x64, 0x21, 0x05, 0x19, 0xE5, 0x9C, 0x80, 0xE7),
+ TO_ECC_64(0x0F, 0xA7, 0xE9, 0xAB, 0x72, 0x24, 0x30, 0x49),
+ TO_ECC_64(0xFE, 0xB8, 0xDE, 0xEC, 0xC1, 0x46, 0xB9, 0xB1)));
+ECC_CONST(NIST_P192_gX, 24, TO_ECC_192(
+ TO_ECC_64(0x18, 0x8D, 0xA8, 0x0E, 0xB0, 0x30, 0x90, 0xF6),
+ TO_ECC_64(0x7C, 0xBF, 0x20, 0xEB, 0x43, 0xA1, 0x88, 0x00),
+ TO_ECC_64(0xF4, 0xFF, 0x0A, 0xFD, 0x82, 0xFF, 0x10, 0x12)));
+ECC_CONST(NIST_P192_gY, 24, TO_ECC_192(
+ TO_ECC_64(0x07, 0x19, 0x2B, 0x95, 0xFF, 0xC8, 0xDA, 0x78),
+ TO_ECC_64(0x63, 0x10, 0x11, 0xED, 0x6B, 0x24, 0xCD, 0xD5),
+ TO_ECC_64(0x73, 0xF9, 0x77, 0xA1, 0x1E, 0x79, 0x48, 0x11)));
+ECC_CONST(NIST_P192_n, 24, TO_ECC_192(
+ TO_ECC_64(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF),
+ TO_ECC_64(0xFF, 0xFF, 0xFF, 0xFF, 0x99, 0xDE, 0xF8, 0x36),
+ TO_ECC_64(0x14, 0x6B, 0xC9, 0xB1, 0xB4, 0xD2, 0x28, 0x31)));
+#define NIST_P192_h ECC_ONE
+#define NIST_P192_gZ ECC_ONE
+#if USE_BN_ECC_DATA
+const ECC_CURVE_DATA NIST_P192 = {
+ (bigNum)&NIST_P192_p, (bigNum)&NIST_P192_n, (bigNum)&NIST_P192_h,
+ (bigNum)&NIST_P192_a, (bigNum)&NIST_P192_b,
+ {(bigNum)&NIST_P192_gX, (bigNum)&NIST_P192_gY, (bigNum)&NIST_P192_gZ}};
+#else
+const ECC_CURVE_DATA NIST_P192 = {
+ &NIST_P192_p.b, &NIST_P192_n.b, &NIST_P192_h.b,
+ &NIST_P192_a.b, &NIST_P192_b.b,
+ {&NIST_P192_gX.b, &NIST_P192_gY.b, &NIST_P192_gZ.b}};
+#endif // USE_BN_ECC_DATA
+#endif // ECC_NIST_P192
+#if ECC_NIST_P224
+ECC_CONST(NIST_P224_p, 28, TO_ECC_224(
+ TO_ECC_32(0xFF, 0xFF, 0xFF, 0xFF),
+ TO_ECC_64(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF),
+ TO_ECC_64(0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00),
+ TO_ECC_64(0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01)));
+ECC_CONST(NIST_P224_a, 28, TO_ECC_224(
+ TO_ECC_32(0xFF, 0xFF, 0xFF, 0xFF),
+ TO_ECC_64(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF),
+ TO_ECC_64(0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF),
+ TO_ECC_64(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE)));
+ECC_CONST(NIST_P224_b, 28, TO_ECC_224(
+ TO_ECC_32(0xB4, 0x05, 0x0A, 0x85),
+ TO_ECC_64(0x0C, 0x04, 0xB3, 0xAB, 0xF5, 0x41, 0x32, 0x56),
+ TO_ECC_64(0x50, 0x44, 0xB0, 0xB7, 0xD7, 0xBF, 0xD8, 0xBA),
+ TO_ECC_64(0x27, 0x0B, 0x39, 0x43, 0x23, 0x55, 0xFF, 0xB4)));
+ECC_CONST(NIST_P224_gX, 28, TO_ECC_224(
+ TO_ECC_32(0xB7, 0x0E, 0x0C, 0xBD),
+ TO_ECC_64(0x6B, 0xB4, 0xBF, 0x7F, 0x32, 0x13, 0x90, 0xB9),
+ TO_ECC_64(0x4A, 0x03, 0xC1, 0xD3, 0x56, 0xC2, 0x11, 0x22),
+ TO_ECC_64(0x34, 0x32, 0x80, 0xD6, 0x11, 0x5C, 0x1D, 0x21)));
+ECC_CONST(NIST_P224_gY, 28, TO_ECC_224(
+ TO_ECC_32(0xBD, 0x37, 0x63, 0x88),
+ TO_ECC_64(0xB5, 0xF7, 0x23, 0xFB, 0x4C, 0x22, 0xDF, 0xE6),
+ TO_ECC_64(0xCD, 0x43, 0x75, 0xA0, 0x5A, 0x07, 0x47, 0x64),
+ TO_ECC_64(0x44, 0xD5, 0x81, 0x99, 0x85, 0x00, 0x7E, 0x34)));
+ECC_CONST(NIST_P224_n, 28, TO_ECC_224(
+ TO_ECC_32(0xFF, 0xFF, 0xFF, 0xFF),
+ TO_ECC_64(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF),
+ TO_ECC_64(0xFF, 0xFF, 0x16, 0xA2, 0xE0, 0xB8, 0xF0, 0x3E),
+ TO_ECC_64(0x13, 0xDD, 0x29, 0x45, 0x5C, 0x5C, 0x2A, 0x3D)));
+#define NIST_P224_h ECC_ONE
+#define NIST_P224_gZ ECC_ONE
+#if USE_BN_ECC_DATA
+const ECC_CURVE_DATA NIST_P224 = {
+ (bigNum)&NIST_P224_p, (bigNum)&NIST_P224_n, (bigNum)&NIST_P224_h,
+ (bigNum)&NIST_P224_a, (bigNum)&NIST_P224_b,
+ {(bigNum)&NIST_P224_gX, (bigNum)&NIST_P224_gY, (bigNum)&NIST_P224_gZ}};
+#else
+const ECC_CURVE_DATA NIST_P224 = {
+ &NIST_P224_p.b, &NIST_P224_n.b, &NIST_P224_h.b,
+ &NIST_P224_a.b, &NIST_P224_b.b,
+ {&NIST_P224_gX.b, &NIST_P224_gY.b, &NIST_P224_gZ.b}};
+#endif // USE_BN_ECC_DATA
+#endif // ECC_NIST_P224
+#if ECC_NIST_P256
+ECC_CONST(NIST_P256_p, 32, TO_ECC_256(
+ TO_ECC_64(0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x01),
+ TO_ECC_64(0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00),
+ TO_ECC_64(0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF),
+ TO_ECC_64(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF)));
+ECC_CONST(NIST_P256_a, 32, TO_ECC_256(
+ TO_ECC_64(0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x01),
+ TO_ECC_64(0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00),
+ TO_ECC_64(0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF),
+ TO_ECC_64(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC)));
+ECC_CONST(NIST_P256_b, 32, TO_ECC_256(
+ TO_ECC_64(0x5A, 0xC6, 0x35, 0xD8, 0xAA, 0x3A, 0x93, 0xE7),
+ TO_ECC_64(0xB3, 0xEB, 0xBD, 0x55, 0x76, 0x98, 0x86, 0xBC),
+ TO_ECC_64(0x65, 0x1D, 0x06, 0xB0, 0xCC, 0x53, 0xB0, 0xF6),
+ TO_ECC_64(0x3B, 0xCE, 0x3C, 0x3E, 0x27, 0xD2, 0x60, 0x4B)));
+ECC_CONST(NIST_P256_gX, 32, TO_ECC_256(
+ TO_ECC_64(0x6B, 0x17, 0xD1, 0xF2, 0xE1, 0x2C, 0x42, 0x47),
+ TO_ECC_64(0xF8, 0xBC, 0xE6, 0xE5, 0x63, 0xA4, 0x40, 0xF2),
+ TO_ECC_64(0x77, 0x03, 0x7D, 0x81, 0x2D, 0xEB, 0x33, 0xA0),
+ TO_ECC_64(0xF4, 0xA1, 0x39, 0x45, 0xD8, 0x98, 0xC2, 0x96)));
+ECC_CONST(NIST_P256_gY, 32, TO_ECC_256(
+ TO_ECC_64(0x4F, 0xE3, 0x42, 0xE2, 0xFE, 0x1A, 0x7F, 0x9B),
+ TO_ECC_64(0x8E, 0xE7, 0xEB, 0x4A, 0x7C, 0x0F, 0x9E, 0x16),
+ TO_ECC_64(0x2B, 0xCE, 0x33, 0x57, 0x6B, 0x31, 0x5E, 0xCE),
+ TO_ECC_64(0xCB, 0xB6, 0x40, 0x68, 0x37, 0xBF, 0x51, 0xF5)));
+ECC_CONST(NIST_P256_n, 32, TO_ECC_256(
+ TO_ECC_64(0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00),
+ TO_ECC_64(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF),
+ TO_ECC_64(0xBC, 0xE6, 0xFA, 0xAD, 0xA7, 0x17, 0x9E, 0x84),
+ TO_ECC_64(0xF3, 0xB9, 0xCA, 0xC2, 0xFC, 0x63, 0x25, 0x51)));
+#define NIST_P256_h ECC_ONE
+#define NIST_P256_gZ ECC_ONE
+#if USE_BN_ECC_DATA
+const ECC_CURVE_DATA NIST_P256 = {
+ (bigNum)&NIST_P256_p, (bigNum)&NIST_P256_n, (bigNum)&NIST_P256_h,
+ (bigNum)&NIST_P256_a, (bigNum)&NIST_P256_b,
+ {(bigNum)&NIST_P256_gX, (bigNum)&NIST_P256_gY, (bigNum)&NIST_P256_gZ}};
+#else
+const ECC_CURVE_DATA NIST_P256 = {
+ &NIST_P256_p.b, &NIST_P256_n.b, &NIST_P256_h.b,
+ &NIST_P256_a.b, &NIST_P256_b.b,
+ {&NIST_P256_gX.b, &NIST_P256_gY.b, &NIST_P256_gZ.b}};
+#endif // USE_BN_ECC_DATA
+#endif // ECC_NIST_P256
+#if ECC_NIST_P384
+ECC_CONST(NIST_P384_p, 48, TO_ECC_384(
+ TO_ECC_64(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF),
+ TO_ECC_64(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF),
+ TO_ECC_64(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF),
+ TO_ECC_64(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE),
+ TO_ECC_64(0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00),
+ TO_ECC_64(0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF)));
+ECC_CONST(NIST_P384_a, 48, TO_ECC_384(
+ TO_ECC_64(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF),
+ TO_ECC_64(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF),
+ TO_ECC_64(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF),
+ TO_ECC_64(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE),
+ TO_ECC_64(0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00),
+ TO_ECC_64(0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFC)));
+ECC_CONST(NIST_P384_b, 48, TO_ECC_384(
+ TO_ECC_64(0xB3, 0x31, 0x2F, 0xA7, 0xE2, 0x3E, 0xE7, 0xE4),
+ TO_ECC_64(0x98, 0x8E, 0x05, 0x6B, 0xE3, 0xF8, 0x2D, 0x19),
+ TO_ECC_64(0x18, 0x1D, 0x9C, 0x6E, 0xFE, 0x81, 0x41, 0x12),
+ TO_ECC_64(0x03, 0x14, 0x08, 0x8F, 0x50, 0x13, 0x87, 0x5A),
+ TO_ECC_64(0xC6, 0x56, 0x39, 0x8D, 0x8A, 0x2E, 0xD1, 0x9D),
+ TO_ECC_64(0x2A, 0x85, 0xC8, 0xED, 0xD3, 0xEC, 0x2A, 0xEF)));
+ECC_CONST(NIST_P384_gX, 48, TO_ECC_384(
+ TO_ECC_64(0xAA, 0x87, 0xCA, 0x22, 0xBE, 0x8B, 0x05, 0x37),
+ TO_ECC_64(0x8E, 0xB1, 0xC7, 0x1E, 0xF3, 0x20, 0xAD, 0x74),
+ TO_ECC_64(0x6E, 0x1D, 0x3B, 0x62, 0x8B, 0xA7, 0x9B, 0x98),
+ TO_ECC_64(0x59, 0xF7, 0x41, 0xE0, 0x82, 0x54, 0x2A, 0x38),
+ TO_ECC_64(0x55, 0x02, 0xF2, 0x5D, 0xBF, 0x55, 0x29, 0x6C),
+ TO_ECC_64(0x3A, 0x54, 0x5E, 0x38, 0x72, 0x76, 0x0A, 0xB7)));
+ECC_CONST(NIST_P384_gY, 48, TO_ECC_384(
+ TO_ECC_64(0x36, 0x17, 0xDE, 0x4A, 0x96, 0x26, 0x2C, 0x6F),
+ TO_ECC_64(0x5D, 0x9E, 0x98, 0xBF, 0x92, 0x92, 0xDC, 0x29),
+ TO_ECC_64(0xF8, 0xF4, 0x1D, 0xBD, 0x28, 0x9A, 0x14, 0x7C),
+ TO_ECC_64(0xE9, 0xDA, 0x31, 0x13, 0xB5, 0xF0, 0xB8, 0xC0),
+ TO_ECC_64(0x0A, 0x60, 0xB1, 0xCE, 0x1D, 0x7E, 0x81, 0x9D),
+ TO_ECC_64(0x7A, 0x43, 0x1D, 0x7C, 0x90, 0xEA, 0x0E, 0x5F)));
+ECC_CONST(NIST_P384_n, 48, TO_ECC_384(
+ TO_ECC_64(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF),
+ TO_ECC_64(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF),
+ TO_ECC_64(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF),
+ TO_ECC_64(0xC7, 0x63, 0x4D, 0x81, 0xF4, 0x37, 0x2D, 0xDF),
+ TO_ECC_64(0x58, 0x1A, 0x0D, 0xB2, 0x48, 0xB0, 0xA7, 0x7A),
+ TO_ECC_64(0xEC, 0xEC, 0x19, 0x6A, 0xCC, 0xC5, 0x29, 0x73)));
+#define NIST_P384_h ECC_ONE
+#define NIST_P384_gZ ECC_ONE
+#if USE_BN_ECC_DATA
+const ECC_CURVE_DATA NIST_P384 = {
+ (bigNum)&NIST_P384_p, (bigNum)&NIST_P384_n, (bigNum)&NIST_P384_h,
+ (bigNum)&NIST_P384_a, (bigNum)&NIST_P384_b,
+ {(bigNum)&NIST_P384_gX, (bigNum)&NIST_P384_gY, (bigNum)&NIST_P384_gZ}};
+#else
+const ECC_CURVE_DATA NIST_P384 = {
+ &NIST_P384_p.b, &NIST_P384_n.b, &NIST_P384_h.b,
+ &NIST_P384_a.b, &NIST_P384_b.b,
+ {&NIST_P384_gX.b, &NIST_P384_gY.b, &NIST_P384_gZ.b}};
+#endif // USE_BN_ECC_DATA
+#endif // ECC_NIST_P384
+#if ECC_NIST_P521
+ECC_CONST(NIST_P521_p, 66, TO_ECC_528(
+ TO_ECC_16(0x01, 0xFF),
+ TO_ECC_64(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF),
+ TO_ECC_64(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF),
+ TO_ECC_64(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF),
+ TO_ECC_64(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF),
+ TO_ECC_64(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF),
+ TO_ECC_64(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF),
+ TO_ECC_64(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF),
+ TO_ECC_64(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF)));
+ECC_CONST(NIST_P521_a, 66, TO_ECC_528(
+ TO_ECC_16(0x01, 0xFF),
+ TO_ECC_64(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF),
+ TO_ECC_64(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF),
+ TO_ECC_64(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF),
+ TO_ECC_64(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF),
+ TO_ECC_64(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF),
+ TO_ECC_64(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF),
+ TO_ECC_64(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF),
+ TO_ECC_64(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC)));
+ECC_CONST(NIST_P521_b, 66, TO_ECC_528(
+ TO_ECC_16(0x00, 0x51),
+ TO_ECC_64(0x95, 0x3E, 0xB9, 0x61, 0x8E, 0x1C, 0x9A, 0x1F),
+ TO_ECC_64(0x92, 0x9A, 0x21, 0xA0, 0xB6, 0x85, 0x40, 0xEE),
+ TO_ECC_64(0xA2, 0xDA, 0x72, 0x5B, 0x99, 0xB3, 0x15, 0xF3),
+ TO_ECC_64(0xB8, 0xB4, 0x89, 0x91, 0x8E, 0xF1, 0x09, 0xE1),
+ TO_ECC_64(0x56, 0x19, 0x39, 0x51, 0xEC, 0x7E, 0x93, 0x7B),
+ TO_ECC_64(0x16, 0x52, 0xC0, 0xBD, 0x3B, 0xB1, 0xBF, 0x07),
+ TO_ECC_64(0x35, 0x73, 0xDF, 0x88, 0x3D, 0x2C, 0x34, 0xF1),
+ TO_ECC_64(0xEF, 0x45, 0x1F, 0xD4, 0x6B, 0x50, 0x3F, 0x00)));
+ECC_CONST(NIST_P521_gX, 66, TO_ECC_528(
+ TO_ECC_16(0x00, 0xC6),
+ TO_ECC_64(0x85, 0x8E, 0x06, 0xB7, 0x04, 0x04, 0xE9, 0xCD),
+ TO_ECC_64(0x9E, 0x3E, 0xCB, 0x66, 0x23, 0x95, 0xB4, 0x42),
+ TO_ECC_64(0x9C, 0x64, 0x81, 0x39, 0x05, 0x3F, 0xB5, 0x21),
+ TO_ECC_64(0xF8, 0x28, 0xAF, 0x60, 0x6B, 0x4D, 0x3D, 0xBA),
+ TO_ECC_64(0xA1, 0x4B, 0x5E, 0x77, 0xEF, 0xE7, 0x59, 0x28),
+ TO_ECC_64(0xFE, 0x1D, 0xC1, 0x27, 0xA2, 0xFF, 0xA8, 0xDE),
+ TO_ECC_64(0x33, 0x48, 0xB3, 0xC1, 0x85, 0x6A, 0x42, 0x9B),
+ TO_ECC_64(0xF9, 0x7E, 0x7E, 0x31, 0xC2, 0xE5, 0xBD, 0x66)));
+ECC_CONST(NIST_P521_gY, 66, TO_ECC_528(
+ TO_ECC_16(0x01, 0x18),
+ TO_ECC_64(0x39, 0x29, 0x6A, 0x78, 0x9A, 0x3B, 0xC0, 0x04),
+ TO_ECC_64(0x5C, 0x8A, 0x5F, 0xB4, 0x2C, 0x7D, 0x1B, 0xD9),
+ TO_ECC_64(0x98, 0xF5, 0x44, 0x49, 0x57, 0x9B, 0x44, 0x68),
+ TO_ECC_64(0x17, 0xAF, 0xBD, 0x17, 0x27, 0x3E, 0x66, 0x2C),
+ TO_ECC_64(0x97, 0xEE, 0x72, 0x99, 0x5E, 0xF4, 0x26, 0x40),
+ TO_ECC_64(0xC5, 0x50, 0xB9, 0x01, 0x3F, 0xAD, 0x07, 0x61),
+ TO_ECC_64(0x35, 0x3C, 0x70, 0x86, 0xA2, 0x72, 0xC2, 0x40),
+ TO_ECC_64(0x88, 0xBE, 0x94, 0x76, 0x9F, 0xD1, 0x66, 0x50)));
+ECC_CONST(NIST_P521_n, 66, TO_ECC_528(
+ TO_ECC_16(0x01, 0xFF),
+ TO_ECC_64(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF),
+ TO_ECC_64(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF),
+ TO_ECC_64(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF),
+ TO_ECC_64(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFA),
+ TO_ECC_64(0x51, 0x86, 0x87, 0x83, 0xBF, 0x2F, 0x96, 0x6B),
+ TO_ECC_64(0x7F, 0xCC, 0x01, 0x48, 0xF7, 0x09, 0xA5, 0xD0),
+ TO_ECC_64(0x3B, 0xB5, 0xC9, 0xB8, 0x89, 0x9C, 0x47, 0xAE),
+ TO_ECC_64(0xBB, 0x6F, 0xB7, 0x1E, 0x91, 0x38, 0x64, 0x09)));
+#define NIST_P521_h ECC_ONE
+#define NIST_P521_gZ ECC_ONE
+#if USE_BN_ECC_DATA
+const ECC_CURVE_DATA NIST_P521 = {
+ (bigNum)&NIST_P521_p, (bigNum)&NIST_P521_n, (bigNum)&NIST_P521_h,
+ (bigNum)&NIST_P521_a, (bigNum)&NIST_P521_b,
+ {(bigNum)&NIST_P521_gX, (bigNum)&NIST_P521_gY, (bigNum)&NIST_P521_gZ}};
+#else
+const ECC_CURVE_DATA NIST_P521 = {
+ &NIST_P521_p.b, &NIST_P521_n.b, &NIST_P521_h.b,
+ &NIST_P521_a.b, &NIST_P521_b.b,
+ {&NIST_P521_gX.b, &NIST_P521_gY.b, &NIST_P521_gZ.b}};
+#endif // USE_BN_ECC_DATA
+#endif // ECC_NIST_P521
+#if ECC_BN_P256
+ECC_CONST(BN_P256_p, 32, TO_ECC_256(
+ TO_ECC_64(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0xF0, 0xCD),
+ TO_ECC_64(0x46, 0xE5, 0xF2, 0x5E, 0xEE, 0x71, 0xA4, 0x9F),
+ TO_ECC_64(0x0C, 0xDC, 0x65, 0xFB, 0x12, 0x98, 0x0A, 0x82),
+ TO_ECC_64(0xD3, 0x29, 0x2D, 0xDB, 0xAE, 0xD3, 0x30, 0x13)));
+#define BN_P256_a ECC_ZERO
+ECC_CONST(BN_P256_b, 1, TO_ECC_8(3));
+#define BN_P256_gX ECC_ONE
+ECC_CONST(BN_P256_gY, 1, TO_ECC_8(2));
+ECC_CONST(BN_P256_n, 32, TO_ECC_256(
+ TO_ECC_64(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0xF0, 0xCD),
+ TO_ECC_64(0x46, 0xE5, 0xF2, 0x5E, 0xEE, 0x71, 0xA4, 0x9E),
+ TO_ECC_64(0x0C, 0xDC, 0x65, 0xFB, 0x12, 0x99, 0x92, 0x1A),
+ TO_ECC_64(0xF6, 0x2D, 0x53, 0x6C, 0xD1, 0x0B, 0x50, 0x0D)));
+#define BN_P256_h ECC_ONE
+#define BN_P256_gZ ECC_ONE
+#if USE_BN_ECC_DATA
+const ECC_CURVE_DATA BN_P256 = {
+ (bigNum)&BN_P256_p, (bigNum)&BN_P256_n, (bigNum)&BN_P256_h,
+ (bigNum)&BN_P256_a, (bigNum)&BN_P256_b,
+ {(bigNum)&BN_P256_gX, (bigNum)&BN_P256_gY, (bigNum)&BN_P256_gZ}};
+#else
+const ECC_CURVE_DATA BN_P256 = {
+ &BN_P256_p.b, &BN_P256_n.b, &BN_P256_h.b,
+ &BN_P256_a.b, &BN_P256_b.b,
+ {&BN_P256_gX.b, &BN_P256_gY.b, &BN_P256_gZ.b}};
+#endif // USE_BN_ECC_DATA
+#endif // ECC_BN_P256
+#if ECC_BN_P638
+ECC_CONST(BN_P638_p, 80, TO_ECC_640(
+ TO_ECC_64(0x23, 0xFF, 0xFF, 0xFD, 0xC0, 0x00, 0x00, 0x0D),
+ TO_ECC_64(0x7F, 0xFF, 0xFF, 0xB8, 0x00, 0x00, 0x01, 0xD3),
+ TO_ECC_64(0xFF, 0xFF, 0xF9, 0x42, 0xD0, 0x00, 0x16, 0x5E),
+ TO_ECC_64(0x3F, 0xFF, 0x94, 0x87, 0x00, 0x00, 0xD5, 0x2F),
+ TO_ECC_64(0xFF, 0xFD, 0xD0, 0xE0, 0x00, 0x08, 0xDE, 0x55),
+ TO_ECC_64(0xC0, 0x00, 0x86, 0x52, 0x00, 0x21, 0xE5, 0x5B),
+ TO_ECC_64(0xFF, 0xFF, 0xF5, 0x1F, 0xFF, 0xF4, 0xEB, 0x80),
+ TO_ECC_64(0x00, 0x00, 0x00, 0x4C, 0x80, 0x01, 0x5A, 0xCD),
+ TO_ECC_64(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xEC, 0xE0),
+ TO_ECC_64(0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x67)));
+#define BN_P638_a ECC_ZERO
+ECC_CONST(BN_P638_b, 2, TO_ECC_16(0x01,0x01));
+ECC_CONST(BN_P638_gX, 80, TO_ECC_640(
+ TO_ECC_64(0x23, 0xFF, 0xFF, 0xFD, 0xC0, 0x00, 0x00, 0x0D),
+ TO_ECC_64(0x7F, 0xFF, 0xFF, 0xB8, 0x00, 0x00, 0x01, 0xD3),
+ TO_ECC_64(0xFF, 0xFF, 0xF9, 0x42, 0xD0, 0x00, 0x16, 0x5E),
+ TO_ECC_64(0x3F, 0xFF, 0x94, 0x87, 0x00, 0x00, 0xD5, 0x2F),
+ TO_ECC_64(0xFF, 0xFD, 0xD0, 0xE0, 0x00, 0x08, 0xDE, 0x55),
+ TO_ECC_64(0xC0, 0x00, 0x86, 0x52, 0x00, 0x21, 0xE5, 0x5B),
+ TO_ECC_64(0xFF, 0xFF, 0xF5, 0x1F, 0xFF, 0xF4, 0xEB, 0x80),
+ TO_ECC_64(0x00, 0x00, 0x00, 0x4C, 0x80, 0x01, 0x5A, 0xCD),
+ TO_ECC_64(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xEC, 0xE0),
+ TO_ECC_64(0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x66)));
+ECC_CONST(BN_P638_gY, 1, TO_ECC_8(0x10));
+ECC_CONST(BN_P638_n, 80, TO_ECC_640(
+ TO_ECC_64(0x23, 0xFF, 0xFF, 0xFD, 0xC0, 0x00, 0x00, 0x0D),
+ TO_ECC_64(0x7F, 0xFF, 0xFF, 0xB8, 0x00, 0x00, 0x01, 0xD3),
+ TO_ECC_64(0xFF, 0xFF, 0xF9, 0x42, 0xD0, 0x00, 0x16, 0x5E),
+ TO_ECC_64(0x3F, 0xFF, 0x94, 0x87, 0x00, 0x00, 0xD5, 0x2F),
+ TO_ECC_64(0xFF, 0xFD, 0xD0, 0xE0, 0x00, 0x08, 0xDE, 0x55),
+ TO_ECC_64(0x60, 0x00, 0x86, 0x55, 0x00, 0x21, 0xE5, 0x55),
+ TO_ECC_64(0xFF, 0xFF, 0xF5, 0x4F, 0xFF, 0xF4, 0xEA, 0xC0),
+ TO_ECC_64(0x00, 0x00, 0x00, 0x49, 0x80, 0x01, 0x54, 0xD9),
+ TO_ECC_64(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xED, 0xA0),
+ TO_ECC_64(0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x61)));
+#define BN_P638_h ECC_ONE
+#define BN_P638_gZ ECC_ONE
+#if USE_BN_ECC_DATA
+const ECC_CURVE_DATA BN_P638 = {
+ (bigNum)&BN_P638_p, (bigNum)&BN_P638_n, (bigNum)&BN_P638_h,
+ (bigNum)&BN_P638_a, (bigNum)&BN_P638_b,
+ {(bigNum)&BN_P638_gX, (bigNum)&BN_P638_gY, (bigNum)&BN_P638_gZ}};
+#else
+const ECC_CURVE_DATA BN_P638 = {
+ &BN_P638_p.b, &BN_P638_n.b, &BN_P638_h.b,
+ &BN_P638_a.b, &BN_P638_b.b,
+ {&BN_P638_gX.b, &BN_P638_gY.b, &BN_P638_gZ.b}};
+#endif // USE_BN_ECC_DATA
+#endif // ECC_BN_P638
+#if ECC_SM2_P256
+ECC_CONST(SM2_P256_p, 32, TO_ECC_256(
+ TO_ECC_64(0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF),
+ TO_ECC_64(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF),
+ TO_ECC_64(0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00),
+ TO_ECC_64(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF)));
+ECC_CONST(SM2_P256_a, 32, TO_ECC_256(
+ TO_ECC_64(0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF),
+ TO_ECC_64(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF),
+ TO_ECC_64(0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00),
+ TO_ECC_64(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC)));
+ECC_CONST(SM2_P256_b, 32, TO_ECC_256(
+ TO_ECC_64(0x28, 0xE9, 0xFA, 0x9E, 0x9D, 0x9F, 0x5E, 0x34),
+ TO_ECC_64(0x4D, 0x5A, 0x9E, 0x4B, 0xCF, 0x65, 0x09, 0xA7),
+ TO_ECC_64(0xF3, 0x97, 0x89, 0xF5, 0x15, 0xAB, 0x8F, 0x92),
+ TO_ECC_64(0xDD, 0xBC, 0xBD, 0x41, 0x4D, 0x94, 0x0E, 0x93)));
+ECC_CONST(SM2_P256_gX, 32, TO_ECC_256(
+ TO_ECC_64(0x32, 0xC4, 0xAE, 0x2C, 0x1F, 0x19, 0x81, 0x19),
+ TO_ECC_64(0x5F, 0x99, 0x04, 0x46, 0x6A, 0x39, 0xC9, 0x94),
+ TO_ECC_64(0x8F, 0xE3, 0x0B, 0xBF, 0xF2, 0x66, 0x0B, 0xE1),
+ TO_ECC_64(0x71, 0x5A, 0x45, 0x89, 0x33, 0x4C, 0x74, 0xC7)));
+ECC_CONST(SM2_P256_gY, 32, TO_ECC_256(
+ TO_ECC_64(0xBC, 0x37, 0x36, 0xA2, 0xF4, 0xF6, 0x77, 0x9C),
+ TO_ECC_64(0x59, 0xBD, 0xCE, 0xE3, 0x6B, 0x69, 0x21, 0x53),
+ TO_ECC_64(0xD0, 0xA9, 0x87, 0x7C, 0xC6, 0x2A, 0x47, 0x40),
+ TO_ECC_64(0x02, 0xDF, 0x32, 0xE5, 0x21, 0x39, 0xF0, 0xA0)));
+ECC_CONST(SM2_P256_n, 32, TO_ECC_256(
+ TO_ECC_64(0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF),
+ TO_ECC_64(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF),
+ TO_ECC_64(0x72, 0x03, 0xDF, 0x6B, 0x21, 0xC6, 0x05, 0x2B),
+ TO_ECC_64(0x53, 0xBB, 0xF4, 0x09, 0x39, 0xD5, 0x41, 0x23)));
+#define SM2_P256_h ECC_ONE
+#define SM2_P256_gZ ECC_ONE
+#if USE_BN_ECC_DATA
+const ECC_CURVE_DATA SM2_P256 = {
+ (bigNum)&SM2_P256_p, (bigNum)&SM2_P256_n, (bigNum)&SM2_P256_h,
+ (bigNum)&SM2_P256_a, (bigNum)&SM2_P256_b,
+ {(bigNum)&SM2_P256_gX, (bigNum)&SM2_P256_gY, (bigNum)&SM2_P256_gZ}};
+#else
+const ECC_CURVE_DATA SM2_P256 = {
+ &SM2_P256_p.b, &SM2_P256_n.b, &SM2_P256_h.b,
+ &SM2_P256_a.b, &SM2_P256_b.b,
+ {&SM2_P256_gX.b, &SM2_P256_gY.b, &SM2_P256_gZ.b}};
+#endif // USE_BN_ECC_DATA
+#endif // ECC_SM2_P256
+#define comma
+const ECC_CURVE eccCurves[] = {
+#if ECC_NIST_P192
+ comma
+ {TPM_ECC_NIST_P192,
+ 192,
+ {TPM_ALG_KDF1_SP800_56A, {{TPM_ALG_SHA256}}},
+ {TPM_ALG_NULL, {{TPM_ALG_NULL}}},
+ &NIST_P192,
+ OID_ECC_NIST_P192
+ CURVE_NAME("NIST_P192")}
+# undef comma
+# define comma ,
+#endif // ECC_NIST_P192
+#if ECC_NIST_P224
+ comma
+ {TPM_ECC_NIST_P224,
+ 224,
+ {TPM_ALG_KDF1_SP800_56A, {{TPM_ALG_SHA256}}},
+ {TPM_ALG_NULL, {{TPM_ALG_NULL}}},
+ &NIST_P224,
+ OID_ECC_NIST_P224
+ CURVE_NAME("NIST_P224")}
+# undef comma
+# define comma ,
+#endif // ECC_NIST_P224
+#if ECC_NIST_P256
+ comma
+ {TPM_ECC_NIST_P256,
+ 256,
+ {TPM_ALG_KDF1_SP800_56A, {{TPM_ALG_SHA256}}},
+ {TPM_ALG_NULL, {{TPM_ALG_NULL}}},
+ &NIST_P256,
+ OID_ECC_NIST_P256
+ CURVE_NAME("NIST_P256")}
+# undef comma
+# define comma ,
+#endif // ECC_NIST_P256
+#if ECC_NIST_P384
+ comma
+ {TPM_ECC_NIST_P384,
+ 384,
+ {TPM_ALG_KDF1_SP800_56A, {{TPM_ALG_SHA384}}},
+ {TPM_ALG_NULL, {{TPM_ALG_NULL}}},
+ &NIST_P384,
+ OID_ECC_NIST_P384
+ CURVE_NAME("NIST_P384")}
+# undef comma
+# define comma ,
+#endif // ECC_NIST_P384
+#if ECC_NIST_P521
+ comma
+ {TPM_ECC_NIST_P521,
+ 521,
+ {TPM_ALG_KDF1_SP800_56A, {{TPM_ALG_SHA512}}},
+ {TPM_ALG_NULL, {{TPM_ALG_NULL}}},
+ &NIST_P521,
+ OID_ECC_NIST_P521
+ CURVE_NAME("NIST_P521")}
+# undef comma
+# define comma ,
+#endif // ECC_NIST_P521
+#if ECC_BN_P256
+ comma
+ {TPM_ECC_BN_P256,
+ 256,
+ {TPM_ALG_NULL, {{TPM_ALG_NULL}}},
+ {TPM_ALG_NULL, {{TPM_ALG_NULL}}},
+ &BN_P256,
+ OID_ECC_BN_P256
+ CURVE_NAME("BN_P256")}
+# undef comma
+# define comma ,
+#endif // ECC_BN_P256
+#if ECC_BN_P638
+ comma
+ {TPM_ECC_BN_P638,
+ 638,
+ {TPM_ALG_NULL, {{TPM_ALG_NULL}}},
+ {TPM_ALG_NULL, {{TPM_ALG_NULL}}},
+ &BN_P638,
+ OID_ECC_BN_P638
+ CURVE_NAME("BN_P638")}
+# undef comma
+# define comma ,
+#endif // ECC_BN_P638
+#if ECC_SM2_P256
+ comma
+ {TPM_ECC_SM2_P256,
+ 256,
+ {TPM_ALG_KDF1_SP800_56A, {{TPM_ALG_SM3_256}}},
+ {TPM_ALG_NULL, {{TPM_ALG_NULL}}},
+ &SM2_P256,
+ OID_ECC_SM2_P256
+ CURVE_NAME("SM2_P256")}
+# undef comma
+# define comma ,
+#endif // ECC_SM2_P256
+};
+#endif // TPM_ALG_ECC
diff --git a/src/tpm2/CryptSelfTest.c b/src/tpm2/CryptSelfTest.c
new file mode 100644
index 0000000..7a25511
--- /dev/null
+++ b/src/tpm2/CryptSelfTest.c
@@ -0,0 +1,225 @@
+/********************************************************************************/
+/* */
+/* Self-Test of Cryptographic Functions */
+/* Written by Ken Goldman */
+/* IBM Thomas J. Watson Research Center */
+/* $Id: CryptSelfTest.c 1594 2020-03-26 22:15:48Z kgoldman $ */
+/* */
+/* Licenses and Notices */
+/* */
+/* 1. Copyright Licenses: */
+/* */
+/* - Trusted Computing Group (TCG) grants to the user of the source code in */
+/* this specification (the "Source Code") a worldwide, irrevocable, */
+/* nonexclusive, royalty free, copyright license to reproduce, create */
+/* derivative works, distribute, display and perform the Source Code and */
+/* derivative works thereof, and to grant others the rights granted herein. */
+/* */
+/* - The TCG grants to the user of the other parts of the specification */
+/* (other than the Source Code) the rights to reproduce, distribute, */
+/* display, and perform the specification solely for the purpose of */
+/* developing products based on such documents. */
+/* */
+/* 2. Source Code Distribution Conditions: */
+/* */
+/* - Redistributions of Source Code must retain the above copyright licenses, */
+/* this list of conditions and the following disclaimers. */
+/* */
+/* - Redistributions in binary form must reproduce the above copyright */
+/* licenses, this list of conditions and the following disclaimers in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* 3. Disclaimers: */
+/* */
+/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
+/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
+/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
+/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
+/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
+/* information on specification licensing rights available through TCG */
+/* membership agreements. */
+/* */
+/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
+/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
+/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
+/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
+/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
+/* */
+/* - Without limitation, TCG and its members and licensors disclaim all */
+/* liability, including liability for infringement of any proprietary */
+/* rights, relating to use of information in this specification and to the */
+/* implementation of this specification, and TCG disclaims all liability for */
+/* cost of procurement of substitute goods or services, lost profits, loss */
+/* of use, loss of data or any incidental, consequential, direct, indirect, */
+/* or special damages, whether under contract, tort, warranty or otherwise, */
+/* arising in any way out of use or reliance upon this specification or any */
+/* information herein. */
+/* */
+/* (c) Copyright IBM Corp. and others, 2016 - 2020 */
+/* */
+/********************************************************************************/
+
+/* 10.2.7 CryptSelfTest.c */
+/* 10.2.7.1 Introduction */
+/* The functions in this file are designed to support self-test of cryptographic functions in the
+ TPM. The TPM allows the user to decide whether to run self-test on a demand basis or to run all
+ the self-tests before proceeding. */
+/* The self-tests are controlled by a set of bit vectors. The g_untestedDecryptionAlgorithms vector
+ has a bit for each decryption algorithm that needs to be tested and
+ g_untestedEncryptionAlgorithms has a bit for each encryption algorithm that needs to be
+ tested. Before an algorithm is used, the appropriate vector is checked (indexed using the
+ algorithm ID). If the bit is 1, then the test function should be called. */
+/* For more information, see TpmSelfTests().txt */
+#include "Tpm.h"
+/* 10.2.7.2 Functions */
+/* 10.2.7.2.1 RunSelfTest() */
+/* Local function to run self-test */
+static TPM_RC
+CryptRunSelfTests(
+ ALGORITHM_VECTOR *toTest // IN: the vector of the algorithms to test
+ )
+{
+ TPM_ALG_ID alg;
+ // For each of the algorithms that are in the toTestVecor, need to run a
+ // test
+ for(alg = TPM_ALG_FIRST; alg <= TPM_ALG_LAST; alg++)
+ {
+ if(TEST_BIT(alg, *toTest))
+ {
+ TPM_RC result = CryptTestAlgorithm(alg, toTest);
+ if(result != TPM_RC_SUCCESS)
+ return result;
+ }
+ }
+ return TPM_RC_SUCCESS;
+}
+/* 10.2.7.2.2 CryptSelfTest() */
+/* This function is called to start/complete a full self-test. If fullTest is NO, then only the
+ untested algorithms will be run. If fullTest is YES, then g_untestedDecryptionAlgorithms is
+ reinitialized and then all tests are run. This implementation of the reference design does not
+ support processing outside the framework of a TPM command. As a consequence, this command does
+ not complete until all tests are done. Since this can take a long time, the TPM will check after
+ each test to see if the command is canceled. If so, then the TPM will returned
+ TPM_RC_CANCELLED. To continue with the self-tests, call TPM2_SelfTest(fullTest == No) and the TPM
+ will complete the testing. */
+/* Error Returns Meaning */
+/* TPM_RC_CANCELED if the command is canceled */
+LIB_EXPORT
+TPM_RC
+CryptSelfTest(
+ TPMI_YES_NO fullTest // IN: if full test is required
+ )
+{
+#if SIMULATION
+ if(g_forceFailureMode)
+ FAIL(FATAL_ERROR_FORCED);
+#endif
+ // If the caller requested a full test, then reset the to test vector so that
+ // all the tests will be run
+ if(fullTest == YES)
+ {
+ MemoryCopy(g_toTest,
+ g_implementedAlgorithms,
+ sizeof(g_toTest));
+ }
+ return CryptRunSelfTests(&g_toTest);
+}
+/* 10.2.7.2.3 CryptIncrementalSelfTest() */
+/* This function is used to perform an incremental self-test. This implementation will perform the
+ toTest values before returning. That is, it assumes that the TPM cannot perform background tasks
+ between commands. */
+/* This command may be canceled. If it is, then there is no return result. However, this command can
+ be run again and the incremental progress will not be lost. */
+/* Error Returns Meaning */
+/* TPM_RC_CANCELED processing of this command was canceled */
+/* TPM_RC_TESTING if toTest list is not empty */
+/* TPM_RC_VALUE an algorithm in the toTest list is not implemented */
+TPM_RC
+CryptIncrementalSelfTest(
+ TPML_ALG *toTest, // IN: list of algorithms to be tested
+ TPML_ALG *toDoList // OUT: list of algorithms needing test
+ )
+{
+ ALGORITHM_VECTOR toTestVector = {0};
+ TPM_ALG_ID alg;
+ UINT32 i;
+ pAssert(toTest != NULL && toDoList != NULL);
+ if(toTest->count > 0)
+ {
+ // Transcribe the toTest list into the toTestVector
+ for(i = 0; i < toTest->count; i++)
+ {
+ alg = toTest->algorithms[i];
+ // make sure that the algorithm value is not out of range
+ if((alg > TPM_ALG_LAST) || !TEST_BIT(alg, g_implementedAlgorithms))
+ return TPM_RC_VALUE;
+ SET_BIT(alg, toTestVector);
+ }
+ // Run the test
+ if(CryptRunSelfTests(&toTestVector) == TPM_RC_CANCELED)
+ return TPM_RC_CANCELED;
+ }
+ // Fill in the toDoList with the algorithms that are still untested
+ toDoList->count = 0;
+ for(alg = TPM_ALG_FIRST;
+ toDoList->count < MAX_ALG_LIST_SIZE && alg <= TPM_ALG_LAST;
+ alg++)
+ {
+ if(TEST_BIT(alg, g_toTest))
+ toDoList->algorithms[toDoList->count++] = alg;
+ }
+ return TPM_RC_SUCCESS;
+}
+/* 10.2.7.2.4 CryptInitializeToTest() */
+/* This function will initialize the data structures for testing all the algorithms. This should not
+ be called unless CryptAlgsSetImplemented() has been called */
+void
+CryptInitializeToTest(
+ void
+ )
+{
+ // Indicate that nothing has been tested
+ memset(&g_cryptoSelfTestState, 0, sizeof(g_cryptoSelfTestState));
+ // Copy the implemented algorithm vector
+ MemoryCopy(g_toTest, g_implementedAlgorithms, sizeof(g_toTest));
+ // Setting the algorithm to null causes the test function to just clear
+ // out any algorithms for which there is no test.
+ CryptTestAlgorithm(TPM_ALG_ERROR, &g_toTest);
+ return;
+}
+/* 10.2.7.2.5 CryptTestAlgorithm() */
+/* Only point of contact with the actual self tests. If a self-test fails, there is no return and
+ the TPM goes into failure mode. The call to TestAlgorithm() uses an algorithm selector and a bit
+ vector. When the test is run, the corresponding bit in toTest and in g_toTest is CLEAR. If toTest
+ is NULL, then only the bit in g_toTest is CLEAR. There is a special case for the call to
+ TestAlgorithm(). When alg is TPM_ALG_ERROR, TestAlgorithm() will CLEAR any bit in toTest for
+ which it has no test. This allows the knowledge about which algorithms have test to be accessed
+ through the interface that provides the test. */
+/* Error Returns Meaning */
+/* TPM_RC_CANCELED test was canceled */
+LIB_EXPORT
+TPM_RC
+CryptTestAlgorithm(
+ TPM_ALG_ID alg,
+ ALGORITHM_VECTOR *toTest
+ )
+{
+ TPM_RC result;
+#if SELF_TEST
+ result = TestAlgorithm(alg, toTest);
+#else
+ // If this is an attempt to determine the algorithms for which there is a
+ // self test, pretend that all of them do. We do that by not clearing any
+ // of the algorithm bits. When/if this function is called to run tests, it
+ // will over report. This can be changed so that any call to check on which
+ // algorithms have tests, 'toTest' can be cleared.
+ if(alg != TPM_ALG_ERROR)
+ {
+ CLEAR_BIT(alg, g_toTest);
+ if(toTest != NULL)
+ CLEAR_BIT(alg, *toTest);
+ }
+ result = TPM_RC_SUCCESS;
+#endif
+ return result;
+}
diff --git a/src/tpm2/CryptSelfTest_fp.h b/src/tpm2/CryptSelfTest_fp.h
new file mode 100644
index 0000000..8dd3822
--- /dev/null
+++ b/src/tpm2/CryptSelfTest_fp.h
@@ -0,0 +1,87 @@
+/********************************************************************************/
+/* */
+/* */
+/* Written by Ken Goldman */
+/* IBM Thomas J. Watson Research Center */
+/* $Id: CryptSelfTest_fp.h 1490 2019-07-26 21:13:22Z kgoldman $ */
+/* */
+/* Licenses and Notices */
+/* */
+/* 1. Copyright Licenses: */
+/* */
+/* - Trusted Computing Group (TCG) grants to the user of the source code in */
+/* this specification (the "Source Code") a worldwide, irrevocable, */
+/* nonexclusive, royalty free, copyright license to reproduce, create */
+/* derivative works, distribute, display and perform the Source Code and */
+/* derivative works thereof, and to grant others the rights granted herein. */
+/* */
+/* - The TCG grants to the user of the other parts of the specification */
+/* (other than the Source Code) the rights to reproduce, distribute, */
+/* display, and perform the specification solely for the purpose of */
+/* developing products based on such documents. */
+/* */
+/* 2. Source Code Distribution Conditions: */
+/* */
+/* - Redistributions of Source Code must retain the above copyright licenses, */
+/* this list of conditions and the following disclaimers. */
+/* */
+/* - Redistributions in binary form must reproduce the above copyright */
+/* licenses, this list of conditions and the following disclaimers in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* 3. Disclaimers: */
+/* */
+/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
+/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
+/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
+/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
+/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
+/* information on specification licensing rights available through TCG */
+/* membership agreements. */
+/* */
+/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
+/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
+/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
+/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
+/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
+/* */
+/* - Without limitation, TCG and its members and licensors disclaim all */
+/* liability, including liability for infringement of any proprietary */
+/* rights, relating to use of information in this specification and to the */
+/* implementation of this specification, and TCG disclaims all liability for */
+/* cost of procurement of substitute goods or services, lost profits, loss */
+/* of use, loss of data or any incidental, consequential, direct, indirect, */
+/* or special damages, whether under contract, tort, warranty or otherwise, */
+/* arising in any way out of use or reliance upon this specification or any */
+/* information herein. */
+/* */
+/* (c) Copyright IBM Corp. and others, 2016 */
+/* */
+/********************************************************************************/
+
+#ifndef CRYPTSELFTEST_FP_H
+#define CRYPTSELFTEST_FP_H
+
+LIB_EXPORT
+TPM_RC
+CryptSelfTest(
+ TPMI_YES_NO fullTest // IN: if full test is required
+ );
+TPM_RC
+CryptIncrementalSelfTest(
+ TPML_ALG *toTest, // IN: list of algorithms to be tested
+ TPML_ALG *toDoList // OUT: list of algorithms needing test
+ );
+void
+CryptInitializeToTest(
+ void
+ );
+LIB_EXPORT
+TPM_RC
+CryptTestAlgorithm(
+ TPM_ALG_ID alg,
+ ALGORITHM_VECTOR *toTest
+ );
+
+
+#endif
diff --git a/src/tpm2/CryptUtil.c b/src/tpm2/CryptUtil.c
new file mode 100644
index 0000000..9879f91
--- /dev/null
+++ b/src/tpm2/CryptUtil.c
@@ -0,0 +1,1739 @@
+/********************************************************************************/
+/* */
+/* Interfaces to the Crypto Engine */
+/* Written by Ken Goldman */
+/* IBM Thomas J. Watson Research Center */
+/* $Id: CryptUtil.c 1658 2021-01-22 23:14:01Z kgoldman $ */
+/* */
+/* Licenses and Notices */
+/* */
+/* 1. Copyright Licenses: */
+/* */
+/* - Trusted Computing Group (TCG) grants to the user of the source code in */
+/* this specification (the "Source Code") a worldwide, irrevocable, */
+/* nonexclusive, royalty free, copyright license to reproduce, create */
+/* derivative works, distribute, display and perform the Source Code and */
+/* derivative works thereof, and to grant others the rights granted herein. */
+/* */
+/* - The TCG grants to the user of the other parts of the specification */
+/* (other than the Source Code) the rights to reproduce, distribute, */
+/* display, and perform the specification solely for the purpose of */
+/* developing products based on such documents. */
+/* */
+/* 2. Source Code Distribution Conditions: */
+/* */
+/* - Redistributions of Source Code must retain the above copyright licenses, */
+/* this list of conditions and the following disclaimers. */
+/* */
+/* - Redistributions in binary form must reproduce the above copyright */
+/* licenses, this list of conditions and the following disclaimers in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* 3. Disclaimers: */
+/* */
+/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
+/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
+/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
+/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
+/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
+/* information on specification licensing rights available through TCG */
+/* membership agreements. */
+/* */
+/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
+/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
+/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
+/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
+/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
+/* */
+/* - Without limitation, TCG and its members and licensors disclaim all */
+/* liability, including liability for infringement of any proprietary */
+/* rights, relating to use of information in this specification and to the */
+/* implementation of this specification, and TCG disclaims all liability for */
+/* cost of procurement of substitute goods or services, lost profits, loss */
+/* of use, loss of data or any incidental, consequential, direct, indirect, */
+/* or special damages, whether under contract, tort, warranty or otherwise, */
+/* arising in any way out of use or reliance upon this specification or any */
+/* information herein. */
+/* */
+/* (c) Copyright IBM Corp. and others, 2016 - 2021 */
+/* */
+/********************************************************************************/
+
+/* 10.2.6 CryptUtil.c */
+/* 10.2.6.1 Introduction */
+/* This module contains the interfaces to the CryptoEngine() and provides miscellaneous
+ cryptographic functions in support of the TPM. */
+/* 10.2.6.2 Includes */
+#include "Tpm.h"
+/* 10.2.6.3 Hash/HMAC Functions */
+/* 10.2.6.3.1 CryptHmacSign() */
+/* Sign a digest using an HMAC key. This an HMAC of a digest, not an HMAC of a message. */
+/* Error Returns Meaning */
+/* TPM_RC_HASH not a valid hash */
+static TPM_RC
+CryptHmacSign(
+ TPMT_SIGNATURE *signature, // OUT: signature
+ OBJECT *signKey, // IN: HMAC key sign the hash
+ TPM2B_DIGEST *hashData // IN: hash to be signed
+ )
+{
+ HMAC_STATE hmacState;
+ UINT32 digestSize;
+ digestSize = CryptHmacStart2B(&hmacState, signature->signature.any.hashAlg,
+ &signKey->sensitive.sensitive.bits.b);
+ CryptDigestUpdate2B(&hmacState.hashState, &hashData->b);
+ CryptHmacEnd(&hmacState, digestSize,
+ (BYTE *)&signature->signature.hmac.digest);
+ return TPM_RC_SUCCESS;
+}
+/* 10.2.6.3.2 CryptHMACVerifySignature() */
+/* This function will verify a signature signed by a HMAC key. Note that a caller needs to prepare
+ signature with the signature algorithm (TPM_ALG_HMAC) and the hash algorithm to use. This
+ function then builds a signature of that type. */
+/* Error Returns Meaning */
+/* TPM_RC_SCHEME not the proper scheme for this key type */
+/* TPM_RC_SIGNATURE if invalid input or signature is not genuine */
+static TPM_RC
+CryptHMACVerifySignature(
+ OBJECT *signKey, // IN: HMAC key signed the hash
+ TPM2B_DIGEST *hashData, // IN: digest being verified
+ TPMT_SIGNATURE *signature // IN: signature to be verified
+ )
+{
+ TPMT_SIGNATURE test;
+ TPMT_KEYEDHASH_SCHEME *keyScheme =
+ &signKey->publicArea.parameters.keyedHashDetail.scheme;
+ //
+ if((signature->sigAlg != TPM_ALG_HMAC)
+ || (signature->signature.hmac.hashAlg == TPM_ALG_NULL))
+ return TPM_RC_SCHEME;
+ // This check is not really needed for verification purposes. However, it does
+ // prevent someone from trying to validate a signature using a weaker hash
+ // algorithm than otherwise allowed by the key. That is, a key with a scheme
+ // other than TMP_ALG_NULL can only be used to validate signatures that have
+ // a matching scheme.
+ if((keyScheme->scheme != TPM_ALG_NULL)
+ && ((keyScheme->scheme != signature->sigAlg)
+ || (keyScheme->details.hmac.hashAlg != signature->signature.any.hashAlg)))
+ return TPM_RC_SIGNATURE;
+ test.sigAlg = signature->sigAlg;
+ test.signature.hmac.hashAlg = signature->signature.hmac.hashAlg;
+ CryptHmacSign(&test, signKey, hashData);
+ // Compare digest
+ if(!MemoryEqual(&test.signature.hmac.digest,
+ &signature->signature.hmac.digest,
+ CryptHashGetDigestSize(signature->signature.any.hashAlg)))
+ return TPM_RC_SIGNATURE;
+ return TPM_RC_SUCCESS;
+}
+/* 10.2.6.3.3 CryptGenerateKeyedHash() */
+/* This function creates a keyedHash object. */
+/* Error Returns Meaning */
+/* TPM_RC_NO_RESULT cannot get values from random number generator */
+/* TPM_RC_SIZE sensitive data size is larger than allowed for the scheme */
+static TPM_RC
+CryptGenerateKeyedHash(
+ TPMT_PUBLIC *publicArea, // IN/OUT: the public area template
+ // for the new key.
+ TPMT_SENSITIVE *sensitive, // OUT: sensitive area
+ TPMS_SENSITIVE_CREATE *sensitiveCreate, // IN: sensitive creation data
+ RAND_STATE *rand // IN: "entropy" source
+ )
+{
+ TPMT_KEYEDHASH_SCHEME *scheme;
+ TPM_ALG_ID hashAlg;
+ UINT16 digestSize;
+
+ scheme = &publicArea->parameters.keyedHashDetail.scheme;
+
+ if(publicArea->type != TPM_ALG_KEYEDHASH)
+ return TPM_RC_FAILURE;
+ // Pick the limiting hash algorithm
+ if(scheme->scheme == TPM_ALG_NULL)
+ hashAlg = publicArea->nameAlg;
+ else if(scheme->scheme == TPM_ALG_XOR)
+ hashAlg = scheme->details.xorr.hashAlg;
+ else
+ hashAlg = scheme->details.hmac.hashAlg;
+ /* hashBlockSize = CryptHashGetBlockSize(hashAlg); */
+ digestSize = CryptHashGetDigestSize(hashAlg);
+
+ // if this is a signing or a decryption key, then the limit
+ // for the data size is the block size of the hash. This limit
+ // is set because larger values have lower entropy because of the
+ // HMAC function. The lower limit is 1/2 the size of the digest
+ //
+ //If the user provided the key, check that it is a proper size
+ if(sensitiveCreate->data.t.size != 0)
+ {
+ if(IS_ATTRIBUTE(publicArea->objectAttributes, TPMA_OBJECT, decrypt)
+ || IS_ATTRIBUTE(publicArea->objectAttributes, TPMA_OBJECT, sign))
+ {
+ if(sensitiveCreate->data.t.size > CryptHashGetBlockSize(hashAlg))
+ return TPM_RC_SIZE;
+#if 0 // May make this a FIPS-mode requirement
+ if(sensitiveCreate->data.t.size < (digestSize / 2))
+ return TPM_RC_SIZE;
+#endif
+ }
+ // If this is a data blob, then anything that will get past the unmarshaling
+ // is OK
+ MemoryCopy2B(&sensitive->sensitive.bits.b, &sensitiveCreate->data.b,
+ sizeof(sensitive->sensitive.bits.t.buffer));
+ }
+ else
+ {
+ // The TPM is going to generate the data so set the size to be the
+ // size of the digest of the algorithm
+ sensitive->sensitive.bits.t.size =
+ DRBG_Generate(rand, sensitive->sensitive.bits.t.buffer, digestSize);
+ if(sensitive->sensitive.bits.t.size == 0)
+ return (g_inFailureMode) ? TPM_RC_FAILURE : TPM_RC_NO_RESULT;
+ }
+ return TPM_RC_SUCCESS;
+}
+/* 10.2.6.3.4 CryptIsSchemeAnonymous() */
+/* This function is used to test a scheme to see if it is an anonymous scheme The only anonymous
+ scheme is ECDAA. ECDAA can be used to do things like U-Prove. */
+BOOL
+CryptIsSchemeAnonymous(
+ TPM_ALG_ID scheme // IN: the scheme algorithm to test
+ )
+{
+ return scheme == TPM_ALG_ECDAA;
+}
+/* 10.2.6.4 Symmetric Functions */
+/* 10.2.6.4.1 ParmDecryptSym() */
+/* This function performs parameter decryption using symmetric block cipher. */
+void
+ParmDecryptSym(
+ TPM_ALG_ID symAlg, // IN: the symmetric algorithm
+ TPM_ALG_ID hash, // IN: hash algorithm for KDFa
+ UINT16 keySizeInBits, // IN: the key size in bits
+ TPM2B *key, // IN: KDF HMAC key
+ TPM2B *nonceCaller, // IN: nonce caller
+ TPM2B *nonceTpm, // IN: nonce TPM
+ UINT32 dataSize, // IN: size of parameter buffer
+ BYTE *data // OUT: buffer to be decrypted
+ )
+{
+ // KDF output buffer
+ // It contains parameters for the CFB encryption
+ // From MSB to LSB, they are the key and iv
+ BYTE symParmString[MAX_SYM_KEY_BYTES + MAX_SYM_BLOCK_SIZE];
+ // Symmetric key size in byte
+ UINT16 keySize = (keySizeInBits + 7) / 8;
+ TPM2B_IV iv;
+ iv.t.size = CryptGetSymmetricBlockSize(symAlg, keySizeInBits);
+ // If there is decryption to do...
+ if(iv.t.size > 0)
+ {
+ // Generate key and iv
+ CryptKDFa(hash, key, CFB_KEY, nonceCaller, nonceTpm,
+ keySizeInBits + (iv.t.size * 8), symParmString, NULL, FALSE);
+ MemoryCopy(iv.t.buffer, &symParmString[keySize], iv.t.size);
+ CryptSymmetricDecrypt(data, symAlg, keySizeInBits, symParmString,
+ &iv, TPM_ALG_CFB, dataSize, data);
+ }
+ return;
+}
+/* 10.2.6.4.2 ParmEncryptSym() */
+/* This function performs parameter encryption using symmetric block cipher. */
+void
+ParmEncryptSym(
+ TPM_ALG_ID symAlg, // IN: symmetric algorithm
+ TPM_ALG_ID hash, // IN: hash algorithm for KDFa
+ UINT16 keySizeInBits, // IN: AES symmetric key size in bits
+ TPM2B *key, // IN: KDF HMAC key
+ TPM2B *nonceCaller, // IN: nonce caller
+ TPM2B *nonceTpm, // IN: nonce TPM
+ UINT32 dataSize, // IN: size of parameter buffer
+ BYTE *data // OUT: buffer to be encrypted
+ )
+{
+ // KDF output buffer
+ // It contains parameters for the CFB encryption
+ BYTE symParmString[MAX_SYM_KEY_BYTES + MAX_SYM_BLOCK_SIZE];
+ // Symmetric key size in bytes
+ UINT16 keySize = (keySizeInBits + 7) / 8;
+ TPM2B_IV iv;
+ iv.t.size = CryptGetSymmetricBlockSize(symAlg, keySizeInBits);
+ // See if there is any encryption to do
+ if(iv.t.size > 0)
+ {
+ // Generate key and iv
+ CryptKDFa(hash, key, CFB_KEY, nonceTpm, nonceCaller,
+ keySizeInBits + (iv.t.size * 8), symParmString, NULL, FALSE);
+ MemoryCopy(iv.t.buffer, &symParmString[keySize], iv.t.size);
+ CryptSymmetricEncrypt(data, symAlg, keySizeInBits, symParmString, &iv,
+ TPM_ALG_CFB, dataSize, data);
+ }
+ return;
+}
+/* 10.2.6.4.3 CryptGenerateKeySymmetric() */
+/* This function generates a symmetric cipher key. The derivation process is determined by the type
+ of the provided rand */
+/* Error Returns Meaning */
+/* TPM_RC_NO_RESULT cannot get a random value */
+/* TPM_RC_KEY_SIZE key size in the public area does not match the size in the sensitive creation
+ area */
+/* TPM_RC_KEY provided key value is not allowed */
+static TPM_RC
+CryptGenerateKeySymmetric(
+ TPMT_PUBLIC *publicArea, // IN/OUT: The public area template
+ // for the new key.
+ TPMT_SENSITIVE *sensitive, // OUT: sensitive area
+ TPMS_SENSITIVE_CREATE *sensitiveCreate, // IN: sensitive creation data
+ RAND_STATE *rand // IN: the "entropy" source for
+ )
+{
+ UINT16 keyBits = publicArea->parameters.symDetail.sym.keyBits.sym;
+ TPM_RC result;
+ //
+ // only do multiples of RADIX_BITS
+ if((keyBits % RADIX_BITS) != 0)
+ return TPM_RC_KEY_SIZE;
+ // If this is not a new key, then the provided key data must be the right size
+ if(sensitiveCreate->data.t.size != 0)
+ {
+ result = CryptSymKeyValidate(&publicArea->parameters.symDetail.sym,
+ (TPM2B_SYM_KEY *)&sensitiveCreate->data);
+ if(result == TPM_RC_SUCCESS)
+ MemoryCopy2B(&sensitive->sensitive.sym.b, &sensitiveCreate->data.b,
+ sizeof(sensitive->sensitive.sym.t.buffer));
+ }
+#if ALG_TDES
+ else if(publicArea->parameters.symDetail.sym.algorithm == TPM_ALG_TDES)
+ {
+ sensitive->sensitive.sym.t.size = keyBits / 8;
+ result = CryptGenerateKeyDes(publicArea, sensitive, rand);
+ }
+#endif
+ else
+ {
+ sensitive->sensitive.sym.t.size =
+ DRBG_Generate(rand, sensitive->sensitive.sym.t.buffer,
+ BITS_TO_BYTES(keyBits));
+ if(g_inFailureMode)
+ result = TPM_RC_FAILURE;
+ else if(sensitive->sensitive.sym.t.size == 0)
+ result = TPM_RC_NO_RESULT;
+ else
+ result = TPM_RC_SUCCESS;
+ }
+ return result;
+}
+/* 10.2.6.4.4 CryptXORObfuscation() */
+/* This function implements XOR obfuscation. It should not be called if the hash algorithm is not
+ implemented. The only return value from this function is TPM_RC_SUCCESS. */
+void
+CryptXORObfuscation(
+ TPM_ALG_ID hash, // IN: hash algorithm for KDF
+ TPM2B *key, // IN: KDF key
+ TPM2B *contextU, // IN: contextU
+ TPM2B *contextV, // IN: contextV
+ UINT32 dataSize, // IN: size of data buffer
+ BYTE *data // IN/OUT: data to be XORed in place
+ )
+{
+ BYTE mask[MAX_DIGEST_SIZE]; // Allocate a digest sized buffer
+ BYTE *pm;
+ UINT32 i;
+ UINT32 counter = 0;
+ UINT16 hLen = CryptHashGetDigestSize(hash);
+ UINT32 requestSize = dataSize * 8;
+ INT32 remainBytes = (INT32)dataSize;
+ pAssert((key != NULL) && (data != NULL) && (hLen != 0));
+ // Call KDFa to generate XOR mask
+ for(; remainBytes > 0; remainBytes -= hLen)
+ {
+ // Make a call to KDFa to get next iteration
+ CryptKDFa(hash, key, XOR_KEY, contextU, contextV,
+ requestSize, mask, &counter, TRUE);
+ // XOR next piece of the data
+ pm = mask;
+ for(i = hLen < remainBytes ? hLen : remainBytes; i > 0; i--)
+ *data++ ^= *pm++;
+ }
+ return;
+}
+/* 10.2.6.5 Initialization and shut down */
+/* 10.2.6.5.1 CryptInit() */
+/* This function is called when the TPM receives a _TPM_Init() indication. */
+/* NOTE: The hash algorithms do not have to be tested, they just need to be available. They have to
+ be tested before the TPM can accept HMAC authorization or return any result that relies on a hash
+ algorithm. */
+/* Return Values Meaning */
+/* TRUE initializations succeeded */
+/* FALSE initialization failed and caller should place the TPM into Failure Mode */
+BOOL
+CryptInit(
+ void
+ )
+{
+ BOOL ok;
+ // Initialize the vector of implemented algorithms
+ AlgorithmGetImplementedVector(&g_implementedAlgorithms);
+ // Indicate that all test are necessary
+ CryptInitializeToTest();
+ // Do any library initializations that are necessary. If any fails,
+ // the caller should go into failure mode;
+ ok = SupportLibInit();
+ ok = ok && CryptSymInit();
+ ok = ok && CryptRandInit();
+ ok = ok && CryptHashInit();
+#if ALG_RSA
+ ok = ok && CryptRsaInit();
+#endif // TPM_ALG_RSA
+#if ALG_ECC
+ ok = ok && CryptEccInit();
+#endif // TPM_ALG_ECC
+ return ok;
+}
+/* 10.2.6.5.2 CryptStartup() */
+/* This function is called by TPM2_Startup() to initialize the functions in this cryptographic
+ library and in the provided CryptoLibrary(). This function and CryptUtilInit() are both provided
+ so that the implementation may move the initialization around to get the best interaction. */
+/* Return Values Meaning */
+/* TRUE startup succeeded */
+/* FALSE startup failed and caller should place the TPM into Failure Mode */
+BOOL
+CryptStartup(
+ STARTUP_TYPE type // IN: the startup type
+ )
+{
+ BOOL OK;
+ NOT_REFERENCED(type);
+ OK = CryptSymStartup();
+ OK = OK && CryptRandStartup();
+ OK = OK && CryptHashStartup();
+#if ALG_RSA
+ OK = OK && CryptRsaStartup();
+#endif // TPM_ALG_RSA
+#if ALG_ECC
+ OK = OK && CryptEccStartup();
+#endif // TPM_ALG_ECC
+ ;
+#if ALG_ECC
+ // Don't directly check for SU_RESET because that is the default
+ if(OK && (type != SU_RESTART) && (type != SU_RESUME))
+ {
+ // If the shutdown was orderly, then the values recovered from NV will
+ // be OK to use.
+ // Get a new random commit nonce
+ gr.commitNonce.t.size = sizeof(gr.commitNonce.t.buffer);
+ CryptRandomGenerate(gr.commitNonce.t.size, gr.commitNonce.t.buffer);
+ // Reset the counter and commit array
+ gr.commitCounter = 0;
+ MemorySet(gr.commitArray, 0, sizeof(gr.commitArray));
+ }
+#endif // TPM_ALG_ECC
+ return OK;
+}
+/* 10.2.6.6 Algorithm-Independent Functions */
+/* 10.2.6.6.1 Introduction */
+/* These functions are used generically when a function of a general type (e.g., symmetric
+ encryption) is required. The functions will modify the parameters as required to interface to
+ the indicated algorithms. */
+/* 10.2.6.6.2 CryptIsAsymAlgorithm() */
+/* This function indicates if an algorithm is an asymmetric algorithm. */
+/* Return Values Meaning */
+/* TRUE if it is an asymmetric algorithm */
+/* FALSE if it is not an asymmetric algorithm */
+BOOL
+CryptIsAsymAlgorithm(
+ TPM_ALG_ID algID // IN: algorithm ID
+ )
+{
+ switch(algID)
+ {
+#if ALG_RSA
+ case TPM_ALG_RSA:
+#endif
+#if ALG_ECC
+ case TPM_ALG_ECC:
+#endif
+ return TRUE;
+ break;
+ default:
+ break;
+ }
+ return FALSE;
+}
+/* 10.2.6.6.3 CryptSecretEncrypt() */
+/* This function creates a secret value and its associated secret structure using an asymmetric
+ algorithm. */
+/* This function is used by TPM2_Rewrap() TPM2_MakeCredential(), and TPM2_Duplicate(). */
+/* Error Returns Meaning */
+/* TPM_RC_ATTRIBUTES keyHandle does not reference a valid decryption key */
+/* TPM_RC_KEY invalid ECC key (public point is not on the curve) */
+/* TPM_RC_SCHEME RSA key with an unsupported padding scheme */
+/* TPM_RC_VALUE numeric value of the data to be decrypted is greater than the RSA key modulus */
+TPM_RC
+CryptSecretEncrypt(
+ OBJECT *encryptKey, // IN: encryption key object
+ const TPM2B *label, // IN: a null-terminated string as L
+ TPM2B_DATA *data, // OUT: secret value
+ TPM2B_ENCRYPTED_SECRET *secret // OUT: secret structure
+ )
+{
+ TPMT_RSA_DECRYPT scheme;
+ TPM_RC result = TPM_RC_SUCCESS;
+ //
+ if(data == NULL || secret == NULL)
+ return TPM_RC_FAILURE;
+ // The output secret value has the size of the digest produced by the nameAlg.
+ data->t.size = CryptHashGetDigestSize(encryptKey->publicArea.nameAlg);
+ // The encryption scheme is OAEP using the nameAlg of the encrypt key.
+ scheme.scheme = TPM_ALG_OAEP;
+ scheme.details.anySig.hashAlg = encryptKey->publicArea.nameAlg;
+ if(!IS_ATTRIBUTE(encryptKey->publicArea.objectAttributes, TPMA_OBJECT, decrypt))
+ return TPM_RC_ATTRIBUTES;
+ switch(encryptKey->publicArea.type)
+ {
+#if ALG_RSA
+ case TPM_ALG_RSA:
+ {
+ // Create secret data from RNG
+ CryptRandomGenerate(data->t.size, data->t.buffer);
+ // Encrypt the data by RSA OAEP into encrypted secret
+ result = CryptRsaEncrypt((TPM2B_PUBLIC_KEY_RSA *)secret, &data->b,
+ encryptKey, &scheme, label, NULL);
+ }
+ break;
+#endif //TPM_ALG_RSA
+#if ALG_ECC
+ case TPM_ALG_ECC:
+ {
+ TPMS_ECC_POINT eccPublic;
+ TPM2B_ECC_PARAMETER eccPrivate;
+ TPMS_ECC_POINT eccSecret;
+ BYTE *buffer = secret->t.secret;
+ // Need to make sure that the public point of the key is on the
+ // curve defined by the key.
+ if(!CryptEccIsPointOnCurve(
+ encryptKey->publicArea.parameters.eccDetail.curveID,
+ &encryptKey->publicArea.unique.ecc))
+ result = TPM_RC_KEY;
+ else
+ {
+ // Call crypto engine to create an auxiliary ECC key
+ // We assume crypt engine initialization should always success.
+ // Otherwise, TPM should go to failure mode.
+ CryptEccNewKeyPair(&eccPublic, &eccPrivate,
+ encryptKey->publicArea.parameters.eccDetail.curveID);
+ // Marshal ECC public to secret structure. This will be used by the
+ // recipient to decrypt the secret with their private key.
+ secret->t.size = TPMS_ECC_POINT_Marshal(&eccPublic, &buffer, NULL);
+ // Compute ECDH shared secret which is R = [d]Q where d is the
+ // private part of the ephemeral key and Q is the public part of a
+ // TPM key. TPM_RC_KEY error return from CryptComputeECDHSecret
+ // because the auxiliary ECC key is just created according to the
+ // parameters of input ECC encrypt key.
+ if(CryptEccPointMultiply(&eccSecret,
+ encryptKey->publicArea.parameters.eccDetail.curveID,
+ &encryptKey->publicArea.unique.ecc, &eccPrivate,
+ NULL, NULL) != TPM_RC_SUCCESS)
+ result = TPM_RC_KEY;
+ else
+ {
+ // The secret value is computed from Z using KDFe as:
+ // secret := KDFe(HashID, Z, Use, PartyUInfo, PartyVInfo, bits)
+ // Where:
+ // HashID the nameAlg of the decrypt key
+ // Z the x coordinate (Px) of the product (P) of the point
+ // (Q) of the secret and the private x coordinate (de,V)
+ // of the decryption key
+ // Use a null-terminated string containing "SECRET"
+ // PartyUInfo the x coordinate of the point in the secret
+ // (Qe,U )
+ // PartyVInfo the x coordinate of the public key (Qs,V )
+ // bits the number of bits in the digest of HashID
+ // Retrieve seed from KDFe
+ CryptKDFe(encryptKey->publicArea.nameAlg, &eccSecret.x.b,
+ label, &eccPublic.x.b,
+ &encryptKey->publicArea.unique.ecc.x.b,
+ data->t.size * 8, data->t.buffer);
+ }
+ }
+ }
+ break;
+#endif //TPM_ALG_ECC
+ default:
+ FAIL(FATAL_ERROR_INTERNAL);
+ break;
+ }
+ return result;
+}
+/* 10.2.6.6.4 CryptSecretDecrypt() */
+/* Decrypt a secret value by asymmetric (or symmetric) algorithm This function is used for
+ ActivateCredential() and Import for asymmetric decryption, and StartAuthSession() for both
+ asymmetric and symmetric decryption process */
+/* Error Returns Meaning */
+/* TPM_RC_ATTRIBUTES RSA key is not a decryption key */
+/* TPM_RC_BINDING Invalid RSA key (public and private parts are not cryptographically bound. */
+/* TPM_RC_ECC_POINT ECC point in the secret is not on the curve */
+/* TPM_RC_INSUFFICIENT failed to retrieve ECC point from the secret */
+/* TPM_RC_NO_RESULT multiplication resulted in ECC point at infinity */
+/* TPM_RC_SIZE data to decrypt is not of the same size as RSA key */
+/* TPM_RC_VALUE For RSA key, numeric value of the encrypted data is greater than the modulus, or the
+ recovered data is larger than the output buffer. For keyedHash or symmetric key, the secret is
+ larger than the size of the digest produced by the name algorithm. */
+/* TPM_RC_FAILURE internal error */
+TPM_RC
+CryptSecretDecrypt(
+ OBJECT *decryptKey, // IN: decrypt key
+ TPM2B_NONCE *nonceCaller, // IN: nonceCaller. It is needed for
+ // symmetric decryption. For
+ // asymmetric decryption, this
+ // parameter is NULL
+ const TPM2B *label, // IN: a value for L
+ TPM2B_ENCRYPTED_SECRET *secret, // IN: input secret
+ TPM2B_DATA *data // OUT: decrypted secret value
+ )
+{
+ TPM_RC result = TPM_RC_SUCCESS;
+ // Decryption for secret
+ switch(decryptKey->publicArea.type)
+ {
+#if ALG_RSA
+ case TPM_ALG_RSA:
+ {
+ TPMT_RSA_DECRYPT scheme;
+ TPMT_RSA_SCHEME *keyScheme
+ = &decryptKey->publicArea.parameters.rsaDetail.scheme;
+ UINT16 digestSize;
+ scheme = *(TPMT_RSA_DECRYPT *)keyScheme;
+ // If the key scheme is TPM_ALG_NULL, set the scheme to OAEP and
+ // set the algorithm to the name algorithm.
+ if(scheme.scheme == TPM_ALG_NULL)
+ {
+ // Use OAEP scheme
+ scheme.scheme = TPM_ALG_OAEP;
+ scheme.details.oaep.hashAlg = decryptKey->publicArea.nameAlg;
+ }
+ // use the digestSize as an indicator of whether or not the scheme
+ // is using a supported hash algorithm.
+ // Note: depending on the scheme used for encryption, a hashAlg might
+ // not be needed. However, the return value has to have some upper
+ // limit on the size. In this case, it is the size of the digest of the
+ // hash algorithm. It is checked after the decryption is done but, there
+ // is no point in doing the decryption if the size is going to be
+ // 'wrong' anyway.
+ digestSize = CryptHashGetDigestSize(scheme.details.oaep.hashAlg);
+ if(scheme.scheme != TPM_ALG_OAEP || digestSize == 0)
+ return TPM_RC_SCHEME;
+ // Set the output buffer capacity
+ data->t.size = sizeof(data->t.buffer);
+ // Decrypt seed by RSA OAEP
+ result = CryptRsaDecrypt(&data->b, &secret->b,
+ decryptKey, &scheme, label);
+ if((result == TPM_RC_SUCCESS) && (data->t.size > digestSize))
+ result = TPM_RC_VALUE;
+ }
+ break;
+#endif //TPM_ALG_RSA
+#if ALG_ECC
+ case TPM_ALG_ECC:
+ {
+ TPMS_ECC_POINT eccPublic;
+ TPMS_ECC_POINT eccSecret;
+ BYTE *buffer = secret->t.secret;
+ INT32 size = secret->t.size;
+ // Retrieve ECC point from secret buffer
+ result = TPMS_ECC_POINT_Unmarshal(&eccPublic, &buffer, &size);
+ if(result == TPM_RC_SUCCESS)
+ {
+ result = CryptEccPointMultiply(&eccSecret,
+ decryptKey->publicArea.parameters.eccDetail.curveID,
+ &eccPublic, &decryptKey->sensitive.sensitive.ecc,
+ NULL, NULL);
+ if(result == TPM_RC_SUCCESS)
+ {
+ // Set the size of the "recovered" secret value to be the size
+ // of the digest produced by the nameAlg.
+ data->t.size =
+ CryptHashGetDigestSize(decryptKey->publicArea.nameAlg);
+ // The secret value is computed from Z using KDFe as:
+ // secret := KDFe(HashID, Z, Use, PartyUInfo, PartyVInfo, bits)
+ // Where:
+ // HashID -- the nameAlg of the decrypt key
+ // Z -- the x coordinate (Px) of the product (P) of the point
+ // (Q) of the secret and the private x coordinate (de,V)
+ // of the decryption key
+ // Use -- a null-terminated string containing "SECRET"
+ // PartyUInfo -- the x coordinate of the point in the secret
+ // (Qe,U )
+ // PartyVInfo -- the x coordinate of the public key (Qs,V )
+ // bits -- the number of bits in the digest of HashID
+ // Retrieve seed from KDFe
+ CryptKDFe(decryptKey->publicArea.nameAlg, &eccSecret.x.b, label,
+ &eccPublic.x.b,
+ &decryptKey->publicArea.unique.ecc.x.b,
+ data->t.size * 8, data->t.buffer);
+ }
+ }
+ }
+ break;
+#endif //TPM_ALG_ECC
+#if !ALG_KEYEDHASH
+# error "KEYEDHASH support is required"
+#endif
+ case TPM_ALG_KEYEDHASH:
+ // The seed size can not be bigger than the digest size of nameAlg
+ if(secret->t.size >
+ CryptHashGetDigestSize(decryptKey->publicArea.nameAlg))
+ result = TPM_RC_VALUE;
+ else
+ {
+ // Retrieve seed by XOR Obfuscation:
+ // seed = XOR(secret, hash, key, nonceCaller, nullNonce)
+ // where:
+ // secret the secret parameter from the TPM2_StartAuthHMAC
+ // command that contains the seed value
+ // hash nameAlg of tpmKey
+ // key the key or data value in the object referenced by
+ // entityHandle in the TPM2_StartAuthHMAC command
+ // nonceCaller the parameter from the TPM2_StartAuthHMAC command
+ // nullNonce a zero-length nonce
+ // XOR Obfuscation in place
+ CryptXORObfuscation(decryptKey->publicArea.nameAlg,
+ &decryptKey->sensitive.sensitive.bits.b,
+ &nonceCaller->b, NULL,
+ secret->t.size, secret->t.secret);
+ // Copy decrypted seed
+ MemoryCopy2B(&data->b, &secret->b, sizeof(data->t.buffer));
+ }
+ break;
+ case TPM_ALG_SYMCIPHER:
+ {
+ TPM2B_IV iv = {{0}};
+ TPMT_SYM_DEF_OBJECT *symDef;
+ // The seed size can not be bigger than the digest size of nameAlg
+ if(secret->t.size >
+ CryptHashGetDigestSize(decryptKey->publicArea.nameAlg))
+ result = TPM_RC_VALUE;
+ else
+ {
+ symDef = &decryptKey->publicArea.parameters.symDetail.sym;
+ iv.t.size = CryptGetSymmetricBlockSize(symDef->algorithm,
+ symDef->keyBits.sym);
+ if(iv.t.size == 0)
+ return TPM_RC_FAILURE;
+ if(nonceCaller->t.size >= iv.t.size)
+ {
+ MemoryCopy(iv.t.buffer, nonceCaller->t.buffer, iv.t.size);
+ }
+ else
+ {
+ if(nonceCaller->t.size > sizeof(iv.t.buffer))
+ return TPM_RC_FAILURE;
+ MemoryCopy(iv.t.buffer, nonceCaller->t.buffer, // libtpms changed: use iv.t.buffer
+ nonceCaller->t.size);
+ }
+ // make sure secret will fit
+ if(secret->t.size > data->t.size)
+ return TPM_RC_FAILURE;
+ data->t.size = secret->t.size;
+ // CFB decrypt, using nonceCaller as iv
+ CryptSymmetricDecrypt(data->t.buffer, symDef->algorithm,
+ symDef->keyBits.sym,
+ decryptKey->sensitive.sensitive.sym.t.buffer,
+ &iv, TPM_ALG_CFB, secret->t.size,
+ secret->t.secret);
+ }
+ }
+ break;
+ default:
+ FAIL(FATAL_ERROR_INTERNAL);
+ break;
+ }
+ return result;
+}
+/* 10.2.6.6.5 CryptParameterEncryption() */
+/* This function does in-place encryption of a response parameter. */
+void
+CryptParameterEncryption(
+ TPM_HANDLE handle, // IN: encrypt session handle
+ TPM2B *nonceCaller, // IN: nonce caller
+ UINT16 leadingSizeInByte, // IN: the size of the leading size field in
+ // bytes
+ TPM2B_AUTH *extraKey, // IN: additional key material other than
+ // sessionAuth
+ BYTE *buffer // IN/OUT: parameter buffer to be encrypted
+ )
+{
+ SESSION *session = SessionGet(handle); // encrypt session
+ TPM2B_TYPE(TEMP_KEY, (sizeof(extraKey->t.buffer)
+ + sizeof(session->sessionKey.t.buffer)));
+ TPM2B_TEMP_KEY key; // encryption key
+ UINT32 cipherSize = 0; // size of cipher text
+ // Retrieve encrypted data size.
+ if(leadingSizeInByte == 2)
+ {
+ // Extract the first two bytes as the size field as the data size
+ // encrypt
+ cipherSize = (UINT32)BYTE_ARRAY_TO_UINT16(buffer);
+ // advance the buffer
+ buffer = &buffer[2];
+ }
+#ifdef TPM4B
+ else if(leadingSizeInByte == 4)
+ {
+ // use the first four bytes to indicate the number of bytes to encrypt
+ cipherSize = BYTE_ARRAY_TO_UINT32(buffer);
+ //advance pointer
+ buffer = &buffer[4];
+ }
+#endif
+ else
+ {
+ FAIL(FATAL_ERROR_INTERNAL);
+ }
+ // Compute encryption key by concatenating sessionKey with extra key
+ MemoryCopy2B(&key.b, &session->sessionKey.b, sizeof(key.t.buffer));
+ MemoryConcat2B(&key.b, &extraKey->b, sizeof(key.t.buffer));
+ if(session->symmetric.algorithm == TPM_ALG_XOR)
+ // XOR parameter encryption formulation:
+ // XOR(parameter, hash, sessionAuth, nonceNewer, nonceOlder)
+ CryptXORObfuscation(session->authHashAlg, &(key.b),
+ &(session->nonceTPM.b),
+ nonceCaller, cipherSize, buffer);
+ else
+ ParmEncryptSym(session->symmetric.algorithm, session->authHashAlg,
+ session->symmetric.keyBits.aes, &(key.b),
+ nonceCaller, &(session->nonceTPM.b),
+ cipherSize, buffer);
+ return;
+}
+/* 10.2.6.6.6 CryptParameterDecryption() */
+/* This function does in-place decryption of a command parameter. */
+/* Error Returns Meaning */
+/* TPM_RC_SIZE The number of bytes in the input buffer is less than the number of bytes to be
+ decrypted. */
+TPM_RC
+CryptParameterDecryption(
+ TPM_HANDLE handle, // IN: encrypted session handle
+ TPM2B *nonceCaller, // IN: nonce caller
+ UINT32 bufferSize, // IN: size of parameter buffer
+ UINT16 leadingSizeInByte, // IN: the size of the leading size field in
+ // byte
+ TPM2B_AUTH *extraKey, // IN: the authValue
+ BYTE *buffer // IN/OUT: parameter buffer to be decrypted
+ )
+{
+ SESSION *session = SessionGet(handle); // encrypt session
+ // The HMAC key is going to be the concatenation of the session key and any
+ // additional key material (like the authValue). The size of both of these
+ // is the size of the buffer which can contain a TPMT_HA.
+ TPM2B_TYPE(HMAC_KEY, (sizeof(extraKey->t.buffer)
+ + sizeof(session->sessionKey.t.buffer)));
+ TPM2B_HMAC_KEY key; // decryption key
+ UINT32 cipherSize = 0; // size of cipher text
+ // Retrieve encrypted data size.
+ if(leadingSizeInByte == 2)
+ {
+ // The first two bytes of the buffer are the size of the
+ // data to be decrypted
+ cipherSize = (UINT32)BYTE_ARRAY_TO_UINT16(buffer);
+ buffer = &buffer[2]; // advance the buffer
+ }
+#ifdef TPM4B
+ else if(leadingSizeInByte == 4)
+ {
+ // the leading size is four bytes so get the four byte size field
+ cipherSize = BYTE_ARRAY_TO_UINT32(buffer);
+ buffer = &buffer[4]; //advance pointer
+ }
+#endif
+ else
+ {
+ FAIL(FATAL_ERROR_INTERNAL);
+ }
+ if(cipherSize > bufferSize)
+ return TPM_RC_SIZE;
+ // Compute decryption key by concatenating sessionAuth with extra input key
+ MemoryCopy2B(&key.b, &session->sessionKey.b, sizeof(key.t.buffer));
+ MemoryConcat2B(&key.b, &extraKey->b, sizeof(key.t.buffer));
+ if(session->symmetric.algorithm == TPM_ALG_XOR)
+ // XOR parameter decryption formulation:
+ // XOR(parameter, hash, sessionAuth, nonceNewer, nonceOlder)
+ // Call XOR obfuscation function
+ CryptXORObfuscation(session->authHashAlg, &key.b, nonceCaller,
+ &(session->nonceTPM.b), cipherSize, buffer);
+ else
+ // Assume that it is one of the symmetric block ciphers.
+ ParmDecryptSym(session->symmetric.algorithm, session->authHashAlg,
+ session->symmetric.keyBits.sym,
+ &key.b, nonceCaller, &session->nonceTPM.b,
+ cipherSize, buffer);
+ return TPM_RC_SUCCESS;
+}
+/* 10.2.6.6.7 CryptComputeSymmetricUnique() */
+/* This function computes the unique field in public area for symmetric objects. */
+void
+CryptComputeSymmetricUnique(
+ TPMT_PUBLIC *publicArea, // IN: the object's public area
+ TPMT_SENSITIVE *sensitive, // IN: the associated sensitive area
+ TPM2B_DIGEST *unique // OUT: unique buffer
+ )
+{
+ // For parents (symmetric and derivation), use an HMAC to compute
+ // the 'unique' field
+ if(IS_ATTRIBUTE(publicArea->objectAttributes, TPMA_OBJECT, restricted)
+ && IS_ATTRIBUTE(publicArea->objectAttributes, TPMA_OBJECT, decrypt))
+ {
+ // Unique field is HMAC(sensitive->seedValue, sensitive->sensitive)
+ HMAC_STATE hmacState;
+ unique->b.size = CryptHmacStart2B(&hmacState, publicArea->nameAlg,
+ &sensitive->seedValue.b);
+ CryptDigestUpdate2B(&hmacState.hashState,
+ &sensitive->sensitive.any.b);
+ CryptHmacEnd2B(&hmacState, &unique->b);
+ }
+ else
+ {
+ HASH_STATE hashState;
+ // Unique := Hash(sensitive->seedValue || sensitive->sensitive)
+ unique->t.size = CryptHashStart(&hashState, publicArea->nameAlg);
+ CryptDigestUpdate2B(&hashState, &sensitive->seedValue.b);
+ CryptDigestUpdate2B(&hashState, &sensitive->sensitive.any.b);
+ CryptHashEnd2B(&hashState, &unique->b);
+ }
+ return;
+}
+/* 10.2.6.6.8 CryptCreateObject() */
+/* This function creates an object. For an asymmetric key, it will create a key pair and, for a
+ parent key, a seed value for child protections. */
+/* For an symmetric object, (TPM_ALG_SYMCIPHER or TPM_ALG_KEYEDHASH), it will create a secret key if
+ the caller did not provide one. It will create a random secret seed value that is hashed with the
+ secret value to create the public unique value. */
+/* publicArea, sensitive, and sensitiveCreate are the only required parameters and are the only ones
+ that are used by TPM2_Create(). The other parameters are optional and are used when the generated
+ Object needs to be deterministic. This is the case for both Primary Objects and Derived
+ Objects. */
+/* When a seed value is provided, a RAND_STATE will be populated and used for all operations in the
+ object generation that require a random number. In the simplest case, TPM2_CreatePrimary() will
+ use seed, label and context with context being the hash of the template. If the Primary Object is
+ in the Endorsement hierarchy, it will also populate proof with ehProof. */
+/* For derived keys, seed will be the secret value from the parent, label and context will be set
+ according to the parameters of TPM2_CreateLoaded() and hashAlg will be set which causes the RAND_STATE
+ to be a KDF generator. */
+/* Error Returns Meaning */
+/* TPM_RC_KEY a provided key is not an allowed value */
+/* TPM_RC_KEY_SIZE key size in the public area does not match the size in the sensitive creation
+ area for a symmetric key */
+/* TPM_RC_NO_RESULT unable to get random values (only in derivation) */
+/* TPM_RC_RANGE for an RSA key, the exponent is not supported */
+/* TPM_RC_SIZE sensitive data size is larger than allowed for the scheme for a keyed hash object */
+/* TPM_RC_VALUE exponent is not prime or could not find a prime using the provided parameters for an
+ RSA key; unsupported name algorithm for an ECC key */
+TPM_RC
+CryptCreateObject(
+ OBJECT *object, // IN: new object structure pointer
+ TPMS_SENSITIVE_CREATE *sensitiveCreate, // IN: sensitive creation
+ RAND_STATE *rand // IN: the random number generator
+ // to use
+ )
+{
+ TPMT_PUBLIC *publicArea = &object->publicArea;
+ TPMT_SENSITIVE *sensitive = &object->sensitive;
+ TPM_RC result = TPM_RC_SUCCESS;
+ //
+ // Set the sensitive type for the object
+ sensitive->sensitiveType = publicArea->type;
+ // For all objects, copy the initial authorization data
+ sensitive->authValue = sensitiveCreate->userAuth;
+ // If the TPM is the source of the data, set the size of the provided data to
+ // zero so that there's no confusion about what to do.
+ if(IS_ATTRIBUTE(publicArea->objectAttributes,
+ TPMA_OBJECT, sensitiveDataOrigin))
+ sensitiveCreate->data.t.size = 0;
+ // Generate the key and unique fields for the asymmetric keys and just the
+ // sensitive value for symmetric object
+ switch(publicArea->type)
+ {
+#if ALG_RSA
+ // Create RSA key
+ case TPM_ALG_RSA:
+ // RSA uses full object so that it has a place to put the private
+ // exponent
+ result = CryptRsaGenerateKey(object, rand);
+ break;
+#endif // TPM_ALG_RSA
+#if ALG_ECC
+ // Create ECC key
+ case TPM_ALG_ECC:
+ result = CryptEccGenerateKey(publicArea, sensitive, rand);
+ break;
+#endif // TPM_ALG_ECC
+ case TPM_ALG_SYMCIPHER:
+ result = CryptGenerateKeySymmetric(publicArea, sensitive,
+ sensitiveCreate, rand);
+ break;
+ case TPM_ALG_KEYEDHASH:
+ result = CryptGenerateKeyedHash(publicArea, sensitive,
+ sensitiveCreate, rand);
+ break;
+ default:
+ FAIL(FATAL_ERROR_INTERNAL);
+ break;
+ }
+ if(result != TPM_RC_SUCCESS)
+ return result;
+ // Create the sensitive seed value
+ // If this is a primary key in the endorsement hierarchy, stir the DRBG state
+ // This implementation uses both shProof and ehProof to make sure that there
+ // is no leakage of either.
+ if(object->attributes.primary && object->attributes.epsHierarchy)
+ {
+ DRBG_AdditionalData((DRBG_STATE *)rand, &gp.shProof.b);
+ DRBG_AdditionalData((DRBG_STATE *)rand, &gp.ehProof.b);
+ }
+ // Generate a seedValue that is the size of the digest produced by nameAlg
+ sensitive->seedValue.t.size =
+ DRBG_Generate(rand, object->sensitive.seedValue.t.buffer,
+ CryptHashGetDigestSize(publicArea->nameAlg));
+ if(g_inFailureMode)
+ return TPM_RC_FAILURE;
+ else if(sensitive->seedValue.t.size == 0)
+ return TPM_RC_NO_RESULT;
+ // For symmetric objects, need to compute the unique value for the public area
+ if(publicArea->type == TPM_ALG_SYMCIPHER
+ || publicArea->type == TPM_ALG_KEYEDHASH)
+ {
+ CryptComputeSymmetricUnique(publicArea, sensitive,
+ &publicArea->unique.sym);
+ }
+ else
+ {
+ // if this is an asymmetric key and it isn't a parent, then
+ // get rid of the seed.
+ if(IS_ATTRIBUTE(publicArea->objectAttributes, TPMA_OBJECT, sign)
+ || !IS_ATTRIBUTE(publicArea->objectAttributes, TPMA_OBJECT, restricted))
+ memset(&sensitive->seedValue, 0,
+ sizeof(sensitive->seedValue));
+ }
+ // Compute the name
+ PublicMarshalAndComputeName(publicArea, &object->name);
+ return result;
+}
+/* 10.2.6.6.9 CryptGetSignHashAlg() */
+/* Get the hash algorithm of signature from a TPMT_SIGNATURE structure. It assumes the signature is
+ not NULL This is a function for easy access */
+TPMI_ALG_HASH
+CryptGetSignHashAlg(
+ TPMT_SIGNATURE *auth // IN: signature
+ )
+{
+ if(auth->sigAlg == TPM_ALG_NULL)
+ FAIL(FATAL_ERROR_INTERNAL);
+ // Get authHash algorithm based on signing scheme
+ switch(auth->sigAlg)
+ {
+#if ALG_RSA
+ // If RSA is supported, both RSASSA and RSAPSS are required
+# if !defined TPM_ALG_RSASSA || !defined TPM_ALG_RSAPSS
+# error "RSASSA and RSAPSS are required for RSA"
+# endif
+ case TPM_ALG_RSASSA:
+ return auth->signature.rsassa.hash;
+ case TPM_ALG_RSAPSS:
+ return auth->signature.rsapss.hash;
+#endif //TPM_ALG_RSA
+#if ALG_ECC
+ // If ECC is defined, ECDSA is mandatory
+# ifndef TPM_ALG_ECDSA
+# error "ECDSA is required for ECC"
+# endif
+ case TPM_ALG_ECDSA:
+ // SM2 and ECSCHNORR are optional
+# if ALG_SM2
+ case TPM_ALG_SM2:
+# endif
+# if ALG_ECSCHNORR
+ case TPM_ALG_ECSCHNORR:
+# endif
+ //all ECC signatures look the same
+ return auth->signature.ecdsa.hash;
+# if ALG_ECDAA
+ // Don't know how to verify an ECDAA signature
+ case TPM_ALG_ECDAA:
+ break;
+# endif
+#endif //TPM_ALG_ECC
+ case TPM_ALG_HMAC:
+ return auth->signature.hmac.hashAlg;
+ default:
+ break;
+ }
+ return TPM_ALG_NULL;
+}
+/* 10.2.6.6.10 CryptIsSplitSign() */
+/* This function us used to determine if the signing operation is a split signing operation that
+ required a TPM2_Commit(). */
+BOOL
+CryptIsSplitSign(
+ TPM_ALG_ID scheme // IN: the algorithm selector
+ )
+{
+ switch(scheme)
+ {
+# if ALG_ECDAA
+ case TPM_ALG_ECDAA:
+ return TRUE;
+ break;
+# endif // TPM_ALG_ECDAA
+ default:
+ return FALSE;
+ break;
+ }
+}
+/* 10.2.6.6.11 CryptIsAsymSignScheme() */
+/* This function indicates if a scheme algorithm is a sign algorithm. */
+BOOL
+CryptIsAsymSignScheme(
+ TPMI_ALG_PUBLIC publicType, // IN: Type of the object
+ TPMI_ALG_ASYM_SCHEME scheme // IN: the scheme
+ )
+{
+ BOOL isSignScheme = TRUE;
+ switch(publicType)
+ {
+#if ALG_RSA
+ case TPM_ALG_RSA:
+ switch(scheme)
+ {
+# if !defined TPM_ALG_RSASSA || !defined TPM_ALG_RSAPSS
+# error "RSASSA and PSAPSS required if RSA used."
+# endif
+ case TPM_ALG_RSASSA:
+ case TPM_ALG_RSAPSS:
+ break;
+ default:
+ isSignScheme = FALSE;
+ break;
+ }
+ break;
+#endif //TPM_ALG_RSA
+#if ALG_ECC
+ // If ECC is implemented ECDSA is required
+ case TPM_ALG_ECC:
+ switch(scheme)
+ {
+ // Support for ECDSA is required for ECC
+ case TPM_ALG_ECDSA:
+#if ALG_ECDAA // ECDAA is optional
+ case TPM_ALG_ECDAA:
+#endif
+#if ALG_ECSCHNORR // Schnorr is also optional
+ case TPM_ALG_ECSCHNORR:
+#endif
+#if ALG_SM2 // SM2 is optional
+ case TPM_ALG_SM2:
+#endif
+ break;
+ default:
+ isSignScheme = FALSE;
+ break;
+ }
+ break;
+#endif //TPM_ALG_ECC
+ default:
+ isSignScheme = FALSE;
+ break;
+ }
+ return isSignScheme;
+}
+/* 10.2.6.6.12 CryptIsAsymDecryptScheme() */
+/* This function indicate if a scheme algorithm is a decrypt algorithm. */
+BOOL
+CryptIsAsymDecryptScheme(
+ TPMI_ALG_PUBLIC publicType, // IN: Type of the object
+ TPMI_ALG_ASYM_SCHEME scheme // IN: the scheme
+ )
+{
+ BOOL isDecryptScheme = TRUE;
+ switch(publicType)
+ {
+#if ALG_RSA
+ case TPM_ALG_RSA:
+ switch(scheme)
+ {
+ case TPM_ALG_RSAES:
+ case TPM_ALG_OAEP:
+ break;
+ default:
+ isDecryptScheme = FALSE;
+ break;
+ }
+ break;
+#endif //TPM_ALG_RSA
+#if ALG_ECC
+ // If ECC is implemented ECDH is required
+ case TPM_ALG_ECC:
+ switch(scheme)
+ {
+#if !ALG_ECDH
+# error "ECDH is required for ECC"
+#endif
+ case TPM_ALG_ECDH:
+#if ALG_SM2
+ case TPM_ALG_SM2:
+#endif
+#if ALG_ECMQV
+ case TPM_ALG_ECMQV:
+#endif
+ break;
+ default:
+ isDecryptScheme = FALSE;
+ break;
+ }
+ break;
+#endif //TPM_ALG_ECC
+ default:
+ isDecryptScheme = FALSE;
+ break;
+ }
+ return isDecryptScheme;
+}
+/* 10.2.6.6.13 CryptSelectSignScheme() */
+/* This function is used by the attestation and signing commands. It implements the rules for
+ selecting the signature scheme to use in signing. This function requires that the signing key
+ either be TPM_RH_NULL or be loaded. */
+/* If a default scheme is defined in object, the default scheme should be chosen, otherwise, the
+ input scheme should be chosen. In the case that both object and input scheme has a non-NULL
+ scheme algorithm, if the schemes are compatible, the input scheme will be chosen. */
+/* This function should not be called if 'signObject->publicArea.type' == TPM_ALG_SYMCIPHER. */
+/* Return Values Meaning */
+/* TRUE scheme selected */
+/* FALSE both scheme and key's default scheme are empty; or scheme is empty while key's default
+ scheme requires explicit input scheme (split signing); or non-empty default key scheme differs
+ from scheme */
+BOOL
+CryptSelectSignScheme(
+ OBJECT *signObject, // IN: signing key
+ TPMT_SIG_SCHEME *scheme // IN/OUT: signing scheme
+ )
+{
+ TPMT_SIG_SCHEME *objectScheme;
+ TPMT_PUBLIC *publicArea;
+ BOOL OK;
+ // If the signHandle is TPM_RH_NULL, then the NULL scheme is used, regardless
+ // of the setting of scheme
+ if(signObject == NULL)
+ {
+ OK = TRUE;
+ scheme->scheme = TPM_ALG_NULL;
+ scheme->details.any.hashAlg = TPM_ALG_NULL;
+ }
+ else
+ {
+ // assignment to save typing.
+ publicArea = &signObject->publicArea;
+ // A symmetric cipher can be used to encrypt and decrypt but it can't
+ // be used for signing
+ if(publicArea->type == TPM_ALG_SYMCIPHER)
+ return FALSE;
+ // Point to the scheme object
+ if(CryptIsAsymAlgorithm(publicArea->type))
+ objectScheme =
+ (TPMT_SIG_SCHEME *)&publicArea->parameters.asymDetail.scheme;
+ else
+ objectScheme =
+ (TPMT_SIG_SCHEME *)&publicArea->parameters.keyedHashDetail.scheme;
+ // If the object doesn't have a default scheme, then use the
+ // input scheme.
+ if(objectScheme->scheme == TPM_ALG_NULL)
+ {
+ // Input and default can't both be NULL
+ OK = (scheme->scheme != TPM_ALG_NULL);
+ // Assume that the scheme is compatible with the key. If not,
+ // an error will be generated in the signing operation.
+ }
+ else if(scheme->scheme == TPM_ALG_NULL)
+ {
+ // input scheme is NULL so use default
+ // First, check to see if the default requires that the caller
+ // provided scheme data
+ OK = !CryptIsSplitSign(objectScheme->scheme);
+ if(OK)
+ {
+ // The object has a scheme and the input is TPM_ALG_NULL so copy
+ // the object scheme as the final scheme. It is better to use a
+ // structure copy than a copy of the individual fields.
+ *scheme = *objectScheme;
+ }
+ }
+ else
+ {
+ // Both input and object have scheme selectors
+ // If the scheme and the hash are not the same then...
+ // NOTE: the reason that there is no copy here is that the input
+ // might contain extra data for a split signing scheme and that
+ // data is not in the object so, it has to be preserved.
+ OK = (objectScheme->scheme == scheme->scheme)
+ && (objectScheme->details.any.hashAlg
+ == scheme->details.any.hashAlg);
+ }
+ }
+ return OK;
+}
+/* 10.2.6.6.14 CryptSign() */
+/* Sign a digest with asymmetric key or HMAC. This function is called by attestation commands and
+ the generic TPM2_Sign() command. This function checks the key scheme and digest size. It does
+ not check if the sign operation is allowed for restricted key. It should be checked before the
+ function is called. The function will assert if the key is not a signing key. */
+/* Error Returns Meaning */
+/* TPM_RC_SCHEME signScheme is not compatible with the signing key type */
+/* TPM_RC_VALUE digest value is greater than the modulus of signHandle or size of hashData does not
+ match hash algorithm insignScheme (for an RSA key); invalid commit status or failed to generate r
+ value (for an ECC key) */
+TPM_RC
+CryptSign(
+ OBJECT *signKey, // IN: signing key
+ TPMT_SIG_SCHEME *signScheme, // IN: sign scheme.
+ TPM2B_DIGEST *digest, // IN: The digest being signed
+ TPMT_SIGNATURE *signature // OUT: signature
+ )
+{
+ TPM_RC result = TPM_RC_SCHEME;
+ // Initialize signature scheme
+ signature->sigAlg = signScheme->scheme;
+ // If the signature algorithm is TPM_ALG_NULL or the signing key is NULL,
+ // then we are done
+ if((signature->sigAlg == TPM_ALG_NULL) || (signKey == NULL))
+ return TPM_RC_SUCCESS;
+ // Initialize signature hash
+ // Note: need to do the check for TPM_ALG_NULL first because the null scheme
+ // doesn't have a hashAlg member.
+ signature->signature.any.hashAlg = signScheme->details.any.hashAlg;
+ // perform sign operation based on different key type
+ switch(signKey->publicArea.type)
+ {
+#if ALG_RSA
+ case TPM_ALG_RSA:
+ result = CryptRsaSign(signature, signKey, digest, NULL);
+ break;
+#endif //TPM_ALG_RSA
+#if ALG_ECC
+ case TPM_ALG_ECC:
+ // The reason that signScheme is passed to CryptEccSign but not to the
+ // other signing methods is that the signing for ECC may be split and
+ // need the 'r' value that is in the scheme but not in the signature.
+ result = CryptEccSign(signature, signKey, digest,
+ (TPMT_ECC_SCHEME *)signScheme, NULL);
+ break;
+#endif //TPM_ALG_ECC
+ case TPM_ALG_KEYEDHASH:
+ result = CryptHmacSign(signature, signKey, digest);
+ break;
+ default:
+ FAIL(FATAL_ERROR_INTERNAL);
+ break;
+ }
+ return result;
+}
+/* 10.2.6.6.15 CryptValidateSignature() */
+/* This function is used to verify a signature. It is called by TPM2_VerifySignature() and
+ TPM2_PolicySigned(). */
+/* Since this operation only requires use of a public key, no consistency checks are necessary for
+ the key to signature type because a caller can load any public key that they like with any scheme
+ that they like. This routine simply makes sure that the signature is correct, whatever the
+ type. */
+/* Error Returns Meaning */
+/* TPM_RC_SIGNATURE the signature is not genuine */
+/* TPM_RC_SCHEME the scheme is not supported */
+/* TPM_RC_HANDLE an HMAC key was selected but the private part of the key is not loaded */
+TPM_RC
+CryptValidateSignature(
+ TPMI_DH_OBJECT keyHandle, // IN: The handle of sign key
+ TPM2B_DIGEST *digest, // IN: The digest being validated
+ TPMT_SIGNATURE *signature // IN: signature
+ )
+{
+ // NOTE: HandleToObject will either return a pointer to a loaded object or
+ // will assert. It will never return a non-valid value. This makes it save
+ // to initialize 'publicArea' with the return value from HandleToObject()
+ // without checking it first.
+ OBJECT *signObject = HandleToObject(keyHandle);
+ TPMT_PUBLIC *publicArea = &signObject->publicArea;
+ TPM_RC result = TPM_RC_SCHEME;
+ // The input unmarshaling should prevent any input signature from being
+ // a NULL signature, but just in case
+ if(signature->sigAlg == TPM_ALG_NULL)
+ return TPM_RC_SIGNATURE;
+ switch(publicArea->type)
+ {
+#if ALG_RSA
+ case TPM_ALG_RSA:
+ {
+ //
+ // Call RSA code to verify signature
+ result = CryptRsaValidateSignature(signature, signObject, digest);
+ break;
+ }
+#endif //TPM_ALG_RSA
+#if ALG_ECC
+ case TPM_ALG_ECC:
+ result = CryptEccValidateSignature(signature, signObject, digest);
+ break;
+#endif // TPM_ALG_ECC
+ case TPM_ALG_KEYEDHASH:
+ if(signObject->attributes.publicOnly)
+ result = TPM_RCS_HANDLE;
+ else
+ result = CryptHMACVerifySignature(signObject, digest, signature);
+ break;
+ default:
+ break;
+ }
+ return result;
+}
+/* 10.2.6.6.16 CryptGetTestResult */
+/* This function returns the results of a self-test function. */
+/* NOTE: the behavior in this function is NOT the correct behavior for a real TPM implementation.
+ An artificial behavior is placed here due to the limitation of a software simulation environment.
+ For the correct behavior, consult the part 3 specification for TPM2_GetTestResult(). */
+TPM_RC
+CryptGetTestResult(
+ TPM2B_MAX_BUFFER *outData // OUT: test result data
+ )
+{
+ outData->t.size = 0;
+ return TPM_RC_SUCCESS;
+}
+/* 10.2.6.6.17 CryptValidateKeys() */
+/* This function is used to verify that the key material of an object is valid. For a publicOnly
+ object, the key is verified for size and, if it is an ECC key, it is verified to be on the
+ specified curve. For a key with a sensitive area, the binding between the public and private
+ parts of the key are verified. If the nameAlg of the key is TPM_ALG_NULL, then the size of the
+ sensitive area is verified but the public portion is not verified, unless the key is an RSA
+ key. For an RSA key, the reason for loading the sensitive area is to use it. The only way to use
+ a private RSA key is to compute the private exponent. To compute the private exponent, the public
+ modulus is used. */
+/* Error Returns Meaning */
+/* TPM_RC_BINDING the public and private parts are not cryptographically bound */
+/* TPM_RC_HASH cannot have a publicOnly key with nameAlg of TPM_ALG_NULL */
+/* TPM_RC_KEY the public unique is not valid */
+/* TPM_RC_KEY_SIZE the private area key is not valid */
+/* TPM_RC_TYPE the types of the sensitive and private parts do not match */
+TPM_RC
+CryptValidateKeys(
+ TPMT_PUBLIC *publicArea,
+ TPMT_SENSITIVE *sensitive,
+ TPM_RC blamePublic,
+ TPM_RC blameSensitive
+ )
+{
+ TPM_RC result;
+ UINT16 keySizeInBytes;
+ UINT16 digestSize = CryptHashGetDigestSize(publicArea->nameAlg);
+ TPMU_PUBLIC_PARMS *params = &publicArea->parameters;
+ TPMU_PUBLIC_ID *unique = &publicArea->unique;
+ if(sensitive != NULL)
+ {
+ // Make sure that the types of the public and sensitive are compatible
+ if(publicArea->type != sensitive->sensitiveType)
+ return TPM_RCS_TYPE + blameSensitive;
+ // Make sure that the authValue is not bigger than allowed
+ // If there is no name algorithm, then the size just needs to be less than
+ // the maximum size of the buffer used for authorization. That size check
+ // was made during unmarshaling of the sensitive area
+ if((sensitive->authValue.t.size) > digestSize && (digestSize > 0))
+ return TPM_RCS_SIZE + blameSensitive;
+ }
+ switch(publicArea->type)
+ {
+#if ALG_RSA
+ case TPM_ALG_RSA:
+ keySizeInBytes = BITS_TO_BYTES(params->rsaDetail.keyBits);
+ // Regardless of whether there is a sensitive area, the public modulus
+ // needs to have the correct size. Otherwise, it can't be used for
+ // any public key operation nor can it be used to compute the private
+ // exponent.
+ // NOTE: This implementation only supports key sizes that are multiples
+ // of 1024 bits which means that the MSb of the 0th byte will always be
+ // SET in either a prime or the public modulus.
+ if((unique->rsa.t.size != keySizeInBytes)
+ || (unique->rsa.t.buffer[0] < 0x80))
+ return TPM_RCS_KEY + blamePublic;
+ if(params->rsaDetail.exponent != 0
+ && params->rsaDetail.exponent < 7)
+ return TPM_RCS_VALUE + blamePublic;
+ if(sensitive != NULL)
+ {
+ // If there is a sensitive area, it has to be the correct size
+ // including having the correct high order bit SET.
+ if(((sensitive->sensitive.rsa.t.size * 2) != keySizeInBytes)
+ || (sensitive->sensitive.rsa.t.buffer[0] < 0x80))
+ return TPM_RCS_KEY_SIZE + blameSensitive;
+ }
+ break;
+#endif
+#if ALG_ECC
+ case TPM_ALG_ECC:
+ {
+ TPMI_ECC_CURVE curveId;
+ curveId = params->eccDetail.curveID;
+ keySizeInBytes = BITS_TO_BYTES(CryptEccGetKeySizeForCurve(curveId));
+ if(sensitive == NULL)
+ {
+ // Validate the public key size
+ if(unique->ecc.x.t.size != keySizeInBytes
+ || unique->ecc.y.t.size != keySizeInBytes)
+ return TPM_RCS_KEY + blamePublic;
+ if(publicArea->nameAlg != TPM_ALG_NULL)
+ {
+ if(!CryptEccIsPointOnCurve(curveId, &unique->ecc))
+ return TPM_RCS_ECC_POINT + blamePublic;
+ }
+ }
+ else
+ {
+ // If the nameAlg is TPM_ALG_NULL, then only verify that the
+ // private part of the key is OK.
+ if(!CryptEccIsValidPrivateKey(&sensitive->sensitive.ecc,
+ curveId))
+ return TPM_RCS_KEY_SIZE;
+ if(publicArea->nameAlg != TPM_ALG_NULL)
+ {
+ // Full key load, verify that the public point belongs to the
+ // private key.
+ TPMS_ECC_POINT toCompare;
+ result = CryptEccPointMultiply(&toCompare, curveId, NULL,
+ &sensitive->sensitive.ecc,
+ NULL, NULL);
+ if(result != TPM_RC_SUCCESS)
+ return TPM_RCS_BINDING;
+ else
+ {
+ // Make sure that the private key generated the public key.
+ // The input values and the values produced by the point
+ // multiply may not be the same size so adjust the computed
+ // value to match the size of the input value by adding or
+ // removing zeros.
+ AdjustNumberB(&toCompare.x.b, unique->ecc.x.t.size);
+ AdjustNumberB(&toCompare.y.b, unique->ecc.y.t.size);
+ if(!MemoryEqual2B(&unique->ecc.x.b, &toCompare.x.b)
+ || !MemoryEqual2B(&unique->ecc.y.b, &toCompare.y.b))
+ return TPM_RCS_BINDING;
+ }
+ }
+ }
+ break;
+ }
+#endif
+ default:
+ // Checks for SYMCIPHER and KEYEDHASH are largely the same
+ // If public area has a nameAlg, then validate the public area size
+ // and if there is also a sensitive area, validate the binding
+ // For consistency, if the object is public-only just make sure that
+ // the unique field is consistent with the name algorithm
+ if(sensitive == NULL)
+ {
+ if(unique->sym.t.size != digestSize)
+ return TPM_RCS_KEY + blamePublic;
+ }
+ else
+ {
+ // Make sure that the key size in the sensitive area is consistent.
+ if(publicArea->type == TPM_ALG_SYMCIPHER)
+ {
+ result = CryptSymKeyValidate(&params->symDetail.sym,
+ &sensitive->sensitive.sym);
+ if(result != TPM_RC_SUCCESS)
+ return result + blameSensitive;
+ }
+ else
+ {
+ // For a keyed hash object, the key has to be less than the
+ // smaller of the block size of the hash used in the scheme or
+ // 128 bytes. The worst case value is limited by the
+ // unmarshaling code so the only thing left to be checked is
+ // that it does not exceed the block size of the hash.
+ // by the hash algorithm of the scheme.
+ TPMT_KEYEDHASH_SCHEME *scheme;
+ UINT16 maxSize;
+ scheme = &params->keyedHashDetail.scheme;
+ if(scheme->scheme == TPM_ALG_XOR)
+ {
+ maxSize = CryptHashGetBlockSize(scheme->details.xorr.hashAlg);
+ }
+ else if(scheme->scheme == TPM_ALG_HMAC)
+ {
+ maxSize = CryptHashGetBlockSize(scheme->details.hmac.hashAlg);
+ }
+ else if(scheme->scheme == TPM_ALG_NULL)
+ {
+ // Not signing or xor so must be a data block
+ maxSize = 128;
+ }
+ else
+ return TPM_RCS_SCHEME + blamePublic;
+ if(sensitive->sensitive.bits.t.size > maxSize)
+ return TPM_RCS_KEY_SIZE + blameSensitive;
+ }
+ // If there is a nameAlg, check the binding
+ if(publicArea->nameAlg != TPM_ALG_NULL)
+ {
+ TPM2B_DIGEST compare;
+ if(sensitive->seedValue.t.size != digestSize)
+ return TPM_RCS_KEY_SIZE + blameSensitive;
+ CryptComputeSymmetricUnique(publicArea, sensitive, &compare);
+ if(!MemoryEqual2B(&unique->sym.b, &compare.b))
+ return TPM_RC_BINDING;
+ }
+ }
+ break;
+ }
+ // For a parent, need to check that the seedValue is the correct size for
+ // protections. It should be at least half the size of the nameAlg
+ if(IS_ATTRIBUTE(publicArea->objectAttributes, TPMA_OBJECT, restricted)
+ && IS_ATTRIBUTE(publicArea->objectAttributes, TPMA_OBJECT, decrypt)
+ && sensitive != NULL
+ && publicArea->nameAlg != TPM_ALG_NULL)
+ {
+ if((sensitive->seedValue.t.size < (digestSize / 2))
+ || (sensitive->seedValue.t.size > digestSize))
+ return TPM_RCS_SIZE + blameSensitive;
+ }
+ return TPM_RC_SUCCESS;
+}
+/* 10.2.6.6.18 CryptSelectMac() */
+/* This function is used to set the MAC scheme based on the key parameters and the input scheme. */
+/* Error Returns Meaning */
+/* TPM_RC_SCHEME the scheme is not a valid mac scheme */
+/* TPM_RC_TYPE the input key is not a type that supports a mac */
+/* TPM_RC_VALUE the input scheme and the key scheme are not compatible */
+TPM_RC
+CryptSelectMac(
+ TPMT_PUBLIC *publicArea,
+ TPMI_ALG_MAC_SCHEME *inMac
+ )
+{
+ TPM_ALG_ID macAlg = TPM_ALG_NULL;
+ switch(publicArea->type)
+ {
+ case TPM_ALG_KEYEDHASH:
+ {
+ // Local value to keep lines from getting too long
+ TPMT_KEYEDHASH_SCHEME *scheme;
+ scheme = &publicArea->parameters.keyedHashDetail.scheme;
+ // Expect that the scheme is either HMAC or NULL
+ if(scheme->scheme != TPM_ALG_NULL)
+ macAlg = scheme->details.hmac.hashAlg;
+ break;
+ }
+ case TPM_ALG_SYMCIPHER:
+ {
+ TPMT_SYM_DEF_OBJECT *scheme;
+ scheme = &publicArea->parameters.symDetail.sym;
+ // Expect that the scheme is either valid symmetric cipher or NULL
+ if(scheme->algorithm != TPM_ALG_NULL)
+ macAlg = scheme->mode.sym;
+ break;
+ }
+ default:
+ return TPM_RCS_TYPE;
+ }
+ // If the input value is not TPM_ALG_NULL ...
+ if(*inMac != TPM_ALG_NULL)
+ {
+ // ... then either the scheme in the key must be TPM_ALG_NULL or the input
+ // value must match
+ if((macAlg != TPM_ALG_NULL) && (*inMac != macAlg))
+ return TPM_RCS_VALUE;
+ }
+ else
+ {
+ // Since the input value is TPM_ALG_NULL, then the key value can't be
+ // TPM_ALG_NULL
+ if(macAlg == TPM_ALG_NULL)
+ return TPM_RCS_VALUE;
+ *inMac = macAlg;
+ }
+ if(!CryptMacIsValidForKey(publicArea->type, *inMac, FALSE))
+ return TPM_RCS_SCHEME;
+ return TPM_RC_SUCCESS;
+}
+/* 10.2.6.6.19 CryptMacIsValidForKey() */
+/* Check to see if the key type is compatible with the mac type */
+BOOL
+CryptMacIsValidForKey(
+ TPM_ALG_ID keyType,
+ TPM_ALG_ID macAlg,
+ BOOL flag
+ )
+{
+ switch(keyType)
+ {
+ case TPM_ALG_KEYEDHASH:
+ return CryptHashIsValidAlg(macAlg, flag);
+ break;
+ case TPM_ALG_SYMCIPHER:
+ return CryptSmacIsValidAlg(macAlg, flag);
+ break;
+ default:
+ break;
+ }
+ return FALSE;
+}
+/* 10.2.6.6.20 CryptSmacIsValidAlg() */
+/* This function is used to test if an algorithm is a supported SMAC algorithm. It needs to be
+ updated as new algorithms are added. */
+BOOL
+CryptSmacIsValidAlg(
+ TPM_ALG_ID alg,
+ BOOL FLAG // IN: Indicates if TPM_ALG_NULL is valid
+ )
+{
+ switch (alg)
+ {
+#if ALG_CMAC
+ case TPM_ALG_CMAC:
+ return TRUE;
+ break;
+#endif
+ case TPM_ALG_NULL:
+ return FLAG;
+ break;
+ default:
+ return FALSE;
+ }
+}
+/* 10.2.6.6.21 CryptSymModeIsValid() */
+/* Function checks to see if an algorithm ID is a valid, symmetric block cipher mode for the TPM. If
+ flag is SET, them TPM_ALG_NULL is a valid mode. not include the modes used for SMAC */
+BOOL
+CryptSymModeIsValid(
+ TPM_ALG_ID mode,
+ BOOL flag
+ )
+{
+ switch(mode)
+ {
+#if ALG_CTR
+ case TPM_ALG_CTR:
+#endif // ALG_CTR
+#if ALG_OFB
+ case TPM_ALG_OFB:
+#endif // ALG_OFB
+#if ALG_CBC
+ case TPM_ALG_CBC:
+#endif // ALG_CBC
+#if ALG_CFB
+ case TPM_ALG_CFB:
+#endif // ALG_CFB
+#if ALG_ECB
+ case TPM_ALG_ECB:
+#endif // ALG_ECB
+ return TRUE;
+ case TPM_ALG_NULL:
+ return flag;
+ break;
+ default:
+ break;
+ }
+ return FALSE;
+}
diff --git a/src/tpm2/DA.c b/src/tpm2/DA.c
new file mode 100644
index 0000000..d61272e
--- /dev/null
+++ b/src/tpm2/DA.c
@@ -0,0 +1,240 @@
+/********************************************************************************/
+/* */
+/* Dictionary Attack Logic. */
+/* Written by Ken Goldman */
+/* IBM Thomas J. Watson Research Center */
+/* $Id: DA.c 1658 2021-01-22 23:14:01Z kgoldman $ */
+/* */
+/* Licenses and Notices */
+/* */
+/* 1. Copyright Licenses: */
+/* */
+/* - Trusted Computing Group (TCG) grants to the user of the source code in */
+/* this specification (the "Source Code") a worldwide, irrevocable, */
+/* nonexclusive, royalty free, copyright license to reproduce, create */
+/* derivative works, distribute, display and perform the Source Code and */
+/* derivative works thereof, and to grant others the rights granted herein. */
+/* */
+/* - The TCG grants to the user of the other parts of the specification */
+/* (other than the Source Code) the rights to reproduce, distribute, */
+/* display, and perform the specification solely for the purpose of */
+/* developing products based on such documents. */
+/* */
+/* 2. Source Code Distribution Conditions: */
+/* */
+/* - Redistributions of Source Code must retain the above copyright licenses, */
+/* this list of conditions and the following disclaimers. */
+/* */
+/* - Redistributions in binary form must reproduce the above copyright */
+/* licenses, this list of conditions and the following disclaimers in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* 3. Disclaimers: */
+/* */
+/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
+/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
+/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
+/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
+/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
+/* information on specification licensing rights available through TCG */
+/* membership agreements. */
+/* */
+/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
+/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
+/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
+/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
+/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
+/* */
+/* - Without limitation, TCG and its members and licensors disclaim all */
+/* liability, including liability for infringement of any proprietary */
+/* rights, relating to use of information in this specification and to the */
+/* implementation of this specification, and TCG disclaims all liability for */
+/* cost of procurement of substitute goods or services, lost profits, loss */
+/* of use, loss of data or any incidental, consequential, direct, indirect, */
+/* or special damages, whether under contract, tort, warranty or otherwise, */
+/* arising in any way out of use or reliance upon this specification or any */
+/* information herein. */
+/* */
+/* (c) Copyright IBM Corp. and others, 2016 - 2019 */
+/* */
+/********************************************************************************/
+
+/* 8.2 DA.c */
+/* 8.2.1 Introduction */
+/* This file contains the functions and data definitions relating to the dictionary attack logic. */
+/* 8.2.2 Includes and Data Definitions */
+#define DA_C
+#include "Tpm.h"
+/* 8.2.3 Functions */
+/* 8.2.3.1 DAPreInstall_Init() */
+/* This function initializes the DA parameters to their manufacturer-default values. The default
+ values are determined by a platform-specific specification. */
+/* This function should not be called outside of a manufacturing or simulation environment. */
+/* The DA parameters will be restored to these initial values by TPM2_Clear(). */
+void
+DAPreInstall_Init(
+ void
+ )
+{
+ gp.failedTries = 0;
+ gp.maxTries = 3;
+ gp.recoveryTime = 1000; // in seconds (~16.67 minutes)
+ gp.lockoutRecovery = 1000; // in seconds
+ gp.lockOutAuthEnabled = TRUE; // Use of lockoutAuth is enabled
+ // Record persistent DA parameter changes to NV
+ NV_SYNC_PERSISTENT(failedTries);
+ NV_SYNC_PERSISTENT(maxTries);
+ NV_SYNC_PERSISTENT(recoveryTime);
+ NV_SYNC_PERSISTENT(lockoutRecovery);
+ NV_SYNC_PERSISTENT(lockOutAuthEnabled);
+ return;
+}
+/* 8.2.3.2 DAStartup() */
+/* This function is called by TPM2_Startup() to initialize the DA parameters. In the case of
+ Startup(CLEAR), use of lockoutAuth will be enabled if the lockout recovery time is 0. Otherwise,
+ lockoutAuth will not be enabled until the TPM has been continuously powered for the
+ lockoutRecovery time. */
+/* This function requires that NV be available and not rate limiting. */
+BOOL
+DAStartup(
+ STARTUP_TYPE type // IN: startup type
+ )
+{
+ NOT_REFERENCED(type);
+#if !ACCUMULATE_SELF_HEAL_TIMER
+ _plat__TimerWasReset();
+ s_selfHealTimer = 0;
+ s_lockoutTimer = 0;
+#else
+ if(_plat__TimerWasReset())
+ {
+ if(!NV_IS_ORDERLY)
+ {
+ // If shutdown was not orderly, then don't really know if go.time has
+ // any useful value so reset the timer to 0. This is what the tick
+ // was reset to
+ s_selfHealTimer = 0;
+ s_lockoutTimer = 0;
+ }
+ else
+ {
+ // If we know how much time was accumulated at the last orderly shutdown
+ // subtract that from the saved timer values so that they effectively
+ // have the accumulated values
+ s_selfHealTimer -= go.time;
+ s_lockoutTimer -= go.time;
+ }
+ }
+#endif
+ // For any Startup(), if lockoutRecovery is 0, enable use of lockoutAuth.
+ if(gp.lockoutRecovery == 0)
+ {
+ gp.lockOutAuthEnabled = TRUE;
+ // Record the changes to NV
+ NV_SYNC_PERSISTENT(lockOutAuthEnabled);
+ }
+ // If DA has not been disabled and the previous shutdown is not orderly
+ // failedTries is not already at its maximum then increment 'failedTries'
+ if(gp.recoveryTime != 0
+ && gp.failedTries < gp.maxTries
+ && !IS_ORDERLY(g_prevOrderlyState))
+ {
+#if USE_DA_USED
+ gp.failedTries += g_daUsed;
+ g_daUsed = FALSE;
+#else
+ gp.failedTries++;
+#endif
+ // Record the change to NV
+ NV_SYNC_PERSISTENT(failedTries);
+ }
+ // Before Startup, the TPM will not do clock updates. At startup, need to
+ // do a time update which will do the DA update.
+ TimeUpdate();
+ return TRUE;
+}
+/* 8.2.3.3 DARegisterFailure() */
+/* This function is called when an authorization failure occurs on an entity that is subject to
+ dictionary-attack protection. When a DA failure is triggered, register the failure by resetting
+ the relevant self-healing timer to the current time. */
+void
+DARegisterFailure(
+ TPM_HANDLE handle // IN: handle for failure
+ )
+{
+ // Reset the timer associated with lockout if the handle is the lockoutAuth.
+ if(handle == TPM_RH_LOCKOUT)
+ s_lockoutTimer = g_time;
+ else
+ s_selfHealTimer = g_time;
+ return;
+}
+/* 8.2.3.4 DASelfHeal() */
+/* This function is called to check if sufficient time has passed to allow decrement of failedTries
+ or to re-enable use of lockoutAuth. */
+/* This function should be called when the time interval is updated. */
+void
+DASelfHeal(
+ void
+ )
+{
+ // Regular authorization self healing logic
+ // If no failed authorization tries, do nothing. Otherwise, try to
+ // decrease failedTries
+ if(gp.failedTries != 0)
+ {
+ // if recovery time is 0, DA logic has been disabled. Clear failed tries
+ // immediately
+ if(gp.recoveryTime == 0)
+ {
+ gp.failedTries = 0;
+ // Update NV record
+ NV_SYNC_PERSISTENT(failedTries);
+ }
+ else
+ {
+ UINT64 decreaseCount;
+#if 0 // Errata eliminates this code
+ // In the unlikely event that failedTries should become larger than
+ // maxTries
+ if(gp.failedTries > gp.maxTries)
+ gp.failedTries = gp.maxTries;
+#endif
+ // How much can failedTries be decreased
+ // Cast s_selfHealTimer to an int in case it became negative at
+ // startup
+ decreaseCount = ((g_time - (INT64)s_selfHealTimer) / 1000)
+ / gp.recoveryTime;
+ if(gp.failedTries <= (UINT32)decreaseCount)
+ // should not set failedTries below zero
+ gp.failedTries = 0;
+ else
+ gp.failedTries -= (UINT32)decreaseCount;
+ // the cast prevents overflow of the product
+ s_selfHealTimer += (decreaseCount * (UINT64)gp.recoveryTime) * 1000;
+ if(decreaseCount != 0)
+ // If there was a change to the failedTries, record the changes
+ // to NV
+ NV_SYNC_PERSISTENT(failedTries);
+ }
+ }
+ // LockoutAuth self healing logic
+ // If lockoutAuth is enabled, do nothing. Otherwise, try to see if we
+ // may enable it
+ if(!gp.lockOutAuthEnabled)
+ {
+ // if lockout authorization recovery time is 0, a reboot is required to
+ // re-enable use of lockout authorization. Self-healing would not
+ // apply in this case.
+ if(gp.lockoutRecovery != 0)
+ {
+ if(((g_time - (INT64)s_lockoutTimer) / 1000) >= gp.lockoutRecovery)
+ {
+ gp.lockOutAuthEnabled = TRUE;
+ // Record the changes to NV
+ NV_SYNC_PERSISTENT(lockOutAuthEnabled);
+ }
+ }
+ }
+ return;
+}
diff --git a/src/tpm2/DA_fp.h b/src/tpm2/DA_fp.h
new file mode 100644
index 0000000..bb5f464
--- /dev/null
+++ b/src/tpm2/DA_fp.h
@@ -0,0 +1,87 @@
+/********************************************************************************/
+/* */
+/* */
+/* Written by Ken Goldman */
+/* IBM Thomas J. Watson Research Center */
+/* $Id: DA_fp.h 1490 2019-07-26 21:13:22Z kgoldman $ */
+/* */
+/* Licenses and Notices */
+/* */
+/* 1. Copyright Licenses: */
+/* */
+/* - Trusted Computing Group (TCG) grants to the user of the source code in */
+/* this specification (the "Source Code") a worldwide, irrevocable, */
+/* nonexclusive, royalty free, copyright license to reproduce, create */
+/* derivative works, distribute, display and perform the Source Code and */
+/* derivative works thereof, and to grant others the rights granted herein. */
+/* */
+/* - The TCG grants to the user of the other parts of the specification */
+/* (other than the Source Code) the rights to reproduce, distribute, */
+/* display, and perform the specification solely for the purpose of */
+/* developing products based on such documents. */
+/* */
+/* 2. Source Code Distribution Conditions: */
+/* */
+/* - Redistributions of Source Code must retain the above copyright licenses, */
+/* this list of conditions and the following disclaimers. */
+/* */
+/* - Redistributions in binary form must reproduce the above copyright */
+/* licenses, this list of conditions and the following disclaimers in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* 3. Disclaimers: */
+/* */
+/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
+/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
+/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
+/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
+/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
+/* information on specification licensing rights available through TCG */
+/* membership agreements. */
+/* */
+/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
+/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
+/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
+/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
+/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
+/* */
+/* - Without limitation, TCG and its members and licensors disclaim all */
+/* liability, including liability for infringement of any proprietary */
+/* rights, relating to use of information in this specification and to the */
+/* implementation of this specification, and TCG disclaims all liability for */
+/* cost of procurement of substitute goods or services, lost profits, loss */
+/* of use, loss of data or any incidental, consequential, direct, indirect, */
+/* or special damages, whether under contract, tort, warranty or otherwise, */
+/* arising in any way out of use or reliance upon this specification or any */
+/* information herein. */
+/* */
+/* (c) Copyright IBM Corp. and others, 2016 - 2019 */
+/* */
+/********************************************************************************/
+
+#ifndef DA_FP_H
+#define DA_FP_H
+
+void
+DAPreInstall_Init(
+ void
+ );
+void
+DAInit(
+ void
+ );
+BOOL
+DAStartup(
+ STARTUP_TYPE type // IN: startup type
+ );
+void
+DARegisterFailure(
+ TPM_HANDLE handle // IN: handle for failure
+ );
+void
+DASelfHeal(
+ void
+ );
+
+
+#endif
diff --git a/src/tpm2/DebugHelpers.c b/src/tpm2/DebugHelpers.c
new file mode 100644
index 0000000..eb58a29
--- /dev/null
+++ b/src/tpm2/DebugHelpers.c
@@ -0,0 +1,160 @@
+/********************************************************************************/
+/* */
+/* Debug Helper */
+/* Written by Ken Goldman */
+/* IBM Thomas J. Watson Research Center */
+/* $Id: DebugHelpers.c 1658 2021-01-22 23:14:01Z kgoldman $ */
+/* */
+/* Licenses and Notices */
+/* */
+/* 1. Copyright Licenses: */
+/* */
+/* - Trusted Computing Group (TCG) grants to the user of the source code in */
+/* this specification (the "Source Code") a worldwide, irrevocable, */
+/* nonexclusive, royalty free, copyright license to reproduce, create */
+/* derivative works, distribute, display and perform the Source Code and */
+/* derivative works thereof, and to grant others the rights granted herein. */
+/* */
+/* - The TCG grants to the user of the other parts of the specification */
+/* (other than the Source Code) the rights to reproduce, distribute, */
+/* display, and perform the specification solely for the purpose of */
+/* developing products based on such documents. */
+/* */
+/* 2. Source Code Distribution Conditions: */
+/* */
+/* - Redistributions of Source Code must retain the above copyright licenses, */
+/* this list of conditions and the following disclaimers. */
+/* */
+/* - Redistributions in binary form must reproduce the above copyright */
+/* licenses, this list of conditions and the following disclaimers in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* 3. Disclaimers: */
+/* */
+/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
+/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
+/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
+/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
+/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
+/* information on specification licensing rights available through TCG */
+/* membership agreements. */
+/* */
+/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
+/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
+/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
+/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
+/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
+/* */
+/* - Without limitation, TCG and its members and licensors disclaim all */
+/* liability, including liability for infringement of any proprietary */
+/* rights, relating to use of information in this specification and to the */
+/* implementation of this specification, and TCG disclaims all liability for */
+/* cost of procurement of substitute goods or services, lost profits, loss */
+/* of use, loss of data or any incidental, consequential, direct, indirect, */
+/* or special damages, whether under contract, tort, warranty or otherwise, */
+/* arising in any way out of use or reliance upon this specification or any */
+/* information herein. */
+/* */
+/* (c) Copyright IBM Corp. and others, 2019 - 2021 */
+/* */
+/********************************************************************************/
+
+/* C.13 DebugHelpers.c */
+/* C.13.1. Description */
+/* This file contains the NV read and write access methods. This implementation uses RAM/file and
+ does not manage the RAM/file as NV blocks. The implementation may become more sophisticated over
+ time. */
+/* C.13.2. Includes and Local */
+#include <stdio.h>
+#include <time.h>
+#include "Platform.h"
+#include "DebugHelpers_fp.h"
+
+#if CERTIFYX509_DEBUG
+const char *debugFileName = "DebugFile.txt";
+
+/* C.13.2.1. fileOpen() */
+
+/* This exists to allow use of the safe version of fopen() with a MS runtime. */
+
+static FILE *
+fileOpen(
+ const char *fn,
+ const char *mode
+ )
+{
+ FILE *f;
+# if defined _MSC_VER
+ if(fopen_s(&f, fn, mode) != 0)
+ f = NULL;
+# else
+ f = fopen(fn, mode);
+# endif
+ return f;
+}
+/* C.13.2.2. DebugFileInit() */
+/* This function initializes the file containing the debug data with the time of the file
+ creation. */
+/* This function opens the file used to hold the debug data. */
+/* Return Value Meaning */
+/* 0 success */
+/* != 0 error */
+int
+DebugFileInit(
+ void
+ )
+{
+ FILE *f = NULL;
+ time_t t = time(NULL);
+ //
+ // Get current date and time.
+# if defined _MSC_VER
+ char timeString[100];
+ ctime_s(timeString, (size_t)sizeof(timeString), &t);
+# else
+ char *timeString;
+ timeString = ctime(&t);
+# endif
+ // Try to open the debug file
+ f = fileOpen(debugFileName, "w");
+ if(f)
+ {
+ /* Initialize the contents with the time. */
+ fprintf(f, "%s\n", timeString);
+ fclose(f);
+ return 0;
+ }
+ return -1;
+}
+
+/* C.13.2.3. DebugDumpBuffer() */
+
+void
+DebugDumpBuffer(
+ int size,
+ unsigned char *buf,
+ const char *identifier
+ )
+{
+ int i;
+ //
+ FILE *f = fileOpen(debugFileName, "a");
+ if(!f)
+ return;
+ if(identifier)
+ fprintf(f, "%s\n", identifier);
+ if(buf)
+ {
+ for(i = 0; i < size; i++)
+ {
+ if(((i % 16) == 0) && (i))
+ fprintf(f, "\n");
+ fprintf(f, " %02X", buf[i]);
+ }
+ if((size % 16) != 0)
+ fprintf(f, "\n");
+ }
+ fclose(f);
+}
+
+#endif // CERTIFYX509_DEBUG
diff --git a/src/tpm2/DebugHelpers_fp.h b/src/tpm2/DebugHelpers_fp.h
new file mode 100644
index 0000000..6e74cd4
--- /dev/null
+++ b/src/tpm2/DebugHelpers_fp.h
@@ -0,0 +1,83 @@
+/********************************************************************************/
+/* */
+/* Debug Helper */
+/* Written by Ken Goldman */
+/* IBM Thomas J. Watson Research Center */
+/* $Id: DebugHelpers_fp.h 1658 2021-01-22 23:14:01Z kgoldman $ */
+/* */
+/* Licenses and Notices */
+/* */
+/* 1. Copyright Licenses: */
+/* */
+/* - Trusted Computing Group (TCG) grants to the user of the source code in */
+/* this specification (the "Source Code") a worldwide, irrevocable, */
+/* nonexclusive, royalty free, copyright license to reproduce, create */
+/* derivative works, distribute, display and perform the Source Code and */
+/* derivative works thereof, and to grant others the rights granted herein. */
+/* */
+/* - The TCG grants to the user of the other parts of the specification */
+/* (other than the Source Code) the rights to reproduce, distribute, */
+/* display, and perform the specification solely for the purpose of */
+/* developing products based on such documents. */
+/* */
+/* 2. Source Code Distribution Conditions: */
+/* */
+/* - Redistributions of Source Code must retain the above copyright licenses, */
+/* this list of conditions and the following disclaimers. */
+/* */
+/* - Redistributions in binary form must reproduce the above copyright */
+/* licenses, this list of conditions and the following disclaimers in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* 3. Disclaimers: */
+/* */
+/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
+/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
+/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
+/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
+/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
+/* information on specification licensing rights available through TCG */
+/* membership agreements. */
+/* */
+/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
+/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
+/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
+/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
+/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
+/* */
+/* - Without limitation, TCG and its members and licensors disclaim all */
+/* liability, including liability for infringement of any proprietary */
+/* rights, relating to use of information in this specification and to the */
+/* implementation of this specification, and TCG disclaims all liability for */
+/* cost of procurement of substitute goods or services, lost profits, loss */
+/* of use, loss of data or any incidental, consequential, direct, indirect, */
+/* or special damages, whether under contract, tort, warranty or otherwise, */
+/* arising in any way out of use or reliance upon this specification or any */
+/* information herein. */
+/* */
+/* (c) Copyright IBM Corp. and others, 2019 - 2021 */
+/* */
+/********************************************************************************/
+#ifndef DEBUGHELPERS_FP_H
+#define DEBUGHELPERS_FP_H
+
+int
+DebugFileInit(
+ void
+ );
+void
+DebugFileClose(
+ void
+ );
+void
+DebugDumpBuffer(
+ int size,
+ unsigned char *buf,
+ const char *identifier
+ );
+
+
+
+
+
+#endif
diff --git a/src/tpm2/DictionaryAttackLockReset_fp.h b/src/tpm2/DictionaryAttackLockReset_fp.h
new file mode 100644
index 0000000..7be9f3a
--- /dev/null
+++ b/src/tpm2/DictionaryAttackLockReset_fp.h
@@ -0,0 +1,79 @@
+/********************************************************************************/
+/* */
+/* */
+/* Written by Ken Goldman */
+/* IBM Thomas J. Watson Research Center */
+/* $Id: DictionaryAttackLockReset_fp.h 809 2016-11-16 18:31:54Z kgoldman $ */
+/* */
+/* Licenses and Notices */
+/* */
+/* 1. Copyright Licenses: */
+/* */
+/* - Trusted Computing Group (TCG) grants to the user of the source code in */
+/* this specification (the "Source Code") a worldwide, irrevocable, */
+/* nonexclusive, royalty free, copyright license to reproduce, create */
+/* derivative works, distribute, display and perform the Source Code and */
+/* derivative works thereof, and to grant others the rights granted herein. */
+/* */
+/* - The TCG grants to the user of the other parts of the specification */
+/* (other than the Source Code) the rights to reproduce, distribute, */
+/* display, and perform the specification solely for the purpose of */
+/* developing products based on such documents. */
+/* */
+/* 2. Source Code Distribution Conditions: */
+/* */
+/* - Redistributions of Source Code must retain the above copyright licenses, */
+/* this list of conditions and the following disclaimers. */
+/* */
+/* - Redistributions in binary form must reproduce the above copyright */
+/* licenses, this list of conditions and the following disclaimers in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* 3. Disclaimers: */
+/* */
+/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
+/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
+/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
+/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
+/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
+/* information on specification licensing rights available through TCG */
+/* membership agreements. */
+/* */
+/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
+/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
+/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
+/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
+/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
+/* */
+/* - Without limitation, TCG and its members and licensors disclaim all */
+/* liability, including liability for infringement of any proprietary */
+/* rights, relating to use of information in this specification and to the */
+/* implementation of this specification, and TCG disclaims all liability for */
+/* cost of procurement of substitute goods or services, lost profits, loss */
+/* of use, loss of data or any incidental, consequential, direct, indirect, */
+/* or special damages, whether under contract, tort, warranty or otherwise, */
+/* arising in any way out of use or reliance upon this specification or any */
+/* information herein. */
+/* */
+/* (c) Copyright IBM Corp. and others, 2012-2015 */
+/* */
+/********************************************************************************/
+
+/* rev 119 */
+
+#ifndef DICTIONARYATTACKLOCKRESET_FP_H
+#define DICTIONARYATTACKLOCKRESET_FP_H
+
+typedef struct {
+ TPMI_RH_LOCKOUT lockHandle;
+} DictionaryAttackLockReset_In;
+
+#define RC_DictionaryAttackLockReset_lockHandle (TPM_RC_H + TPM_RC_1)
+
+TPM_RC
+TPM2_DictionaryAttackLockReset(
+ DictionaryAttackLockReset_In *in // IN: input parameter list
+ );
+
+
+#endif
diff --git a/src/tpm2/DictionaryAttackParameters_fp.h b/src/tpm2/DictionaryAttackParameters_fp.h
new file mode 100644
index 0000000..cfc6124
--- /dev/null
+++ b/src/tpm2/DictionaryAttackParameters_fp.h
@@ -0,0 +1,86 @@
+/********************************************************************************/
+/* */
+/* */
+/* Written by Ken Goldman */
+/* IBM Thomas J. Watson Research Center */
+/* $Id: DictionaryAttackParameters_fp.h 1521 2019-11-15 21:00:47Z kgoldman $ */
+/* */
+/* Licenses and Notices */
+/* */
+/* 1. Copyright Licenses: */
+/* */
+/* - Trusted Computing Group (TCG) grants to the user of the source code in */
+/* this specification (the "Source Code") a worldwide, irrevocable, */
+/* nonexclusive, royalty free, copyright license to reproduce, create */
+/* derivative works, distribute, display and perform the Source Code and */
+/* derivative works thereof, and to grant others the rights granted herein. */
+/* */
+/* - The TCG grants to the user of the other parts of the specification */
+/* (other than the Source Code) the rights to reproduce, distribute, */
+/* display, and perform the specification solely for the purpose of */
+/* developing products based on such documents. */
+/* */
+/* 2. Source Code Distribution Conditions: */
+/* */
+/* - Redistributions of Source Code must retain the above copyright licenses, */
+/* this list of conditions and the following disclaimers. */
+/* */
+/* - Redistributions in binary form must reproduce the above copyright */
+/* licenses, this list of conditions and the following disclaimers in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* 3. Disclaimers: */
+/* */
+/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
+/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
+/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
+/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
+/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
+/* information on specification licensing rights available through TCG */
+/* membership agreements. */
+/* */
+/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
+/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
+/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
+/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
+/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
+/* */
+/* - Without limitation, TCG and its members and licensors disclaim all */
+/* liability, including liability for infringement of any proprietary */
+/* rights, relating to use of information in this specification and to the */
+/* implementation of this specification, and TCG disclaims all liability for */
+/* cost of procurement of substitute goods or services, lost profits, loss */
+/* of use, loss of data or any incidental, consequential, direct, indirect, */
+/* or special damages, whether under contract, tort, warranty or otherwise, */
+/* arising in any way out of use or reliance upon this specification or any */
+/* information herein. */
+/* */
+/* (c) Copyright IBM Corp. and others, 2012-2015 */
+/* */
+/********************************************************************************/
+
+/* rev 119 */
+
+#ifndef DICTIONARYATTACKPARAMETERS_FP_H
+#define DICTIONARYATTACKPARAMETERS_FP_H
+
+
+typedef struct {
+ TPMI_RH_LOCKOUT lockHandle;
+ UINT32 newMaxTries;
+ UINT32 newRecoveryTime;
+ UINT32 lockoutRecovery;
+} DictionaryAttackParameters_In;
+
+#define RC_DictionaryAttackParameters_lockHandle (TPM_RC_H + TPM_RC_1)
+#define RC_DictionaryAttackParameters_newMaxTries (TPM_RC_P + TPM_RC_1)
+#define RC_DictionaryAttackParameters_newRecoveryTime (TPM_RC_P + TPM_RC_2)
+#define RC_DictionaryAttackParameters_lockoutRecovery (TPM_RC_P + TPM_RC_3)
+
+TPM_RC
+TPM2_DictionaryAttackParameters(
+ DictionaryAttackParameters_In *in // IN: input parameter list
+ );
+
+
+#endif
diff --git a/src/tpm2/DictionaryCommands.c b/src/tpm2/DictionaryCommands.c
new file mode 100644
index 0000000..cc21868
--- /dev/null
+++ b/src/tpm2/DictionaryCommands.c
@@ -0,0 +1,104 @@
+/********************************************************************************/
+/* */
+/* Dictionary Attack Functions */
+/* Written by Ken Goldman */
+/* IBM Thomas J. Watson Research Center */
+/* $Id: DictionaryCommands.c 1490 2019-07-26 21:13:22Z kgoldman $ */
+/* */
+/* Licenses and Notices */
+/* */
+/* 1. Copyright Licenses: */
+/* */
+/* - Trusted Computing Group (TCG) grants to the user of the source code in */
+/* this specification (the "Source Code") a worldwide, irrevocable, */
+/* nonexclusive, royalty free, copyright license to reproduce, create */
+/* derivative works, distribute, display and perform the Source Code and */
+/* derivative works thereof, and to grant others the rights granted herein. */
+/* */
+/* - The TCG grants to the user of the other parts of the specification */
+/* (other than the Source Code) the rights to reproduce, distribute, */
+/* display, and perform the specification solely for the purpose of */
+/* developing products based on such documents. */
+/* */
+/* 2. Source Code Distribution Conditions: */
+/* */
+/* - Redistributions of Source Code must retain the above copyright licenses, */
+/* this list of conditions and the following disclaimers. */
+/* */
+/* - Redistributions in binary form must reproduce the above copyright */
+/* licenses, this list of conditions and the following disclaimers in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* 3. Disclaimers: */
+/* */
+/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
+/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
+/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
+/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
+/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
+/* information on specification licensing rights available through TCG */
+/* membership agreements. */
+/* */
+/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
+/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
+/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
+/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
+/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
+/* */
+/* - Without limitation, TCG and its members and licensors disclaim all */
+/* liability, including liability for infringement of any proprietary */
+/* rights, relating to use of information in this specification and to the */
+/* implementation of this specification, and TCG disclaims all liability for */
+/* cost of procurement of substitute goods or services, lost profits, loss */
+/* of use, loss of data or any incidental, consequential, direct, indirect, */
+/* or special damages, whether under contract, tort, warranty or otherwise, */
+/* arising in any way out of use or reliance upon this specification or any */
+/* information herein. */
+/* */
+/* (c) Copyright IBM Corp. and others, 2016 - 2018 */
+/* */
+/********************************************************************************/
+
+#include "Tpm.h"
+#include "DictionaryAttackLockReset_fp.h"
+#if CC_DictionaryAttackLockReset // Conditional expansion of this file
+TPM_RC
+TPM2_DictionaryAttackLockReset(
+ DictionaryAttackLockReset_In *in // IN: input parameter list
+ )
+{
+ // Input parameter is not reference in command action
+ NOT_REFERENCED(in);
+ // The command needs NV update.
+ RETURN_IF_NV_IS_NOT_AVAILABLE;
+ // Internal Data Update
+ // Set failed tries to 0
+ gp.failedTries = 0;
+ // Record the changes to NV
+ NV_SYNC_PERSISTENT(failedTries);
+ return TPM_RC_SUCCESS;
+}
+#endif // CC_DictionaryAttackLockReset
+#include "Tpm.h"
+#include "DictionaryAttackParameters_fp.h"
+#if CC_DictionaryAttackParameters // Conditional expansion of this file
+TPM_RC
+TPM2_DictionaryAttackParameters(
+ DictionaryAttackParameters_In *in // IN: input parameter list
+ )
+{
+ // The command needs NV update.
+ RETURN_IF_NV_IS_NOT_AVAILABLE;
+ // Internal Data Update
+ // Set dictionary attack parameters
+ gp.maxTries = in->newMaxTries;
+ gp.recoveryTime = in->newRecoveryTime;
+ gp.lockoutRecovery = in->lockoutRecovery;
+ // Record the changes to NV
+ NV_SYNC_PERSISTENT(failedTries);
+ NV_SYNC_PERSISTENT(maxTries);
+ NV_SYNC_PERSISTENT(recoveryTime);
+ NV_SYNC_PERSISTENT(lockoutRecovery);
+ return TPM_RC_SUCCESS;
+}
+#endif // CC_DictionaryAttackParameters
diff --git a/src/tpm2/Duplicate_fp.h b/src/tpm2/Duplicate_fp.h
new file mode 100644
index 0000000..5deffa1
--- /dev/null
+++ b/src/tpm2/Duplicate_fp.h
@@ -0,0 +1,91 @@
+/********************************************************************************/
+/* */
+/* */
+/* Written by Ken Goldman */
+/* IBM Thomas J. Watson Research Center */
+/* $Id: Duplicate_fp.h 809 2016-11-16 18:31:54Z kgoldman $ */
+/* */
+/* Licenses and Notices */
+/* */
+/* 1. Copyright Licenses: */
+/* */
+/* - Trusted Computing Group (TCG) grants to the user of the source code in */
+/* this specification (the "Source Code") a worldwide, irrevocable, */
+/* nonexclusive, royalty free, copyright license to reproduce, create */
+/* derivative works, distribute, display and perform the Source Code and */
+/* derivative works thereof, and to grant others the rights granted herein. */
+/* */
+/* - The TCG grants to the user of the other parts of the specification */
+/* (other than the Source Code) the rights to reproduce, distribute, */
+/* display, and perform the specification solely for the purpose of */
+/* developing products based on such documents. */
+/* */
+/* 2. Source Code Distribution Conditions: */
+/* */
+/* - Redistributions of Source Code must retain the above copyright licenses, */
+/* this list of conditions and the following disclaimers. */
+/* */
+/* - Redistributions in binary form must reproduce the above copyright */
+/* licenses, this list of conditions and the following disclaimers in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* 3. Disclaimers: */
+/* */
+/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
+/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
+/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
+/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
+/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
+/* information on specification licensing rights available through TCG */
+/* membership agreements. */
+/* */
+/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
+/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
+/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
+/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
+/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
+/* */
+/* - Without limitation, TCG and its members and licensors disclaim all */
+/* liability, including liability for infringement of any proprietary */
+/* rights, relating to use of information in this specification and to the */
+/* implementation of this specification, and TCG disclaims all liability for */
+/* cost of procurement of substitute goods or services, lost profits, loss */
+/* of use, loss of data or any incidental, consequential, direct, indirect, */
+/* or special damages, whether under contract, tort, warranty or otherwise, */
+/* arising in any way out of use or reliance upon this specification or any */
+/* information herein. */
+/* */
+/* (c) Copyright IBM Corp. and others, 2012-2015 */
+/* */
+/********************************************************************************/
+
+/* rev 119 */
+
+#ifndef DUPLICATE_FP_H
+#define DUPLICATE_FP_H
+
+typedef struct {
+ TPMI_DH_OBJECT objectHandle;
+ TPMI_DH_OBJECT newParentHandle;
+ TPM2B_DATA encryptionKeyIn;
+ TPMT_SYM_DEF_OBJECT symmetricAlg;
+} Duplicate_In;
+
+typedef struct {
+ TPM2B_DATA encryptionKeyOut;
+ TPM2B_PRIVATE duplicate;
+ TPM2B_ENCRYPTED_SECRET outSymSeed;
+} Duplicate_Out;
+
+#define RC_Duplicate_objectHandle (TPM_RC_H + TPM_RC_1)
+#define RC_Duplicate_newParentHandle (TPM_RC_H + TPM_RC_2)
+#define RC_Duplicate_encryptionKeyIn (TPM_RC_P + TPM_RC_1)
+#define RC_Duplicate_symmetricAlg (TPM_RC_P + TPM_RC_2)
+
+TPM_RC
+TPM2_Duplicate(
+ Duplicate_In *in, // IN: input parameter list
+ Duplicate_Out *out // OUT: output parameter list
+ );
+
+#endif
diff --git a/src/tpm2/DuplicationCommands.c b/src/tpm2/DuplicationCommands.c
new file mode 100644
index 0000000..525ecf7
--- /dev/null
+++ b/src/tpm2/DuplicationCommands.c
@@ -0,0 +1,352 @@
+/********************************************************************************/
+/* */
+/* Duplication Commands */
+/* Written by Ken Goldman */
+/* IBM Thomas J. Watson Research Center */
+/* $Id: DuplicationCommands.c 1490 2019-07-26 21:13:22Z kgoldman $ */
+/* */
+/* Licenses and Notices */
+/* */
+/* 1. Copyright Licenses: */
+/* */
+/* - Trusted Computing Group (TCG) grants to the user of the source code in */
+/* this specification (the "Source Code") a worldwide, irrevocable, */
+/* nonexclusive, royalty free, copyright license to reproduce, create */
+/* derivative works, distribute, display and perform the Source Code and */
+/* derivative works thereof, and to grant others the rights granted herein. */
+/* */
+/* - The TCG grants to the user of the other parts of the specification */
+/* (other than the Source Code) the rights to reproduce, distribute, */
+/* display, and perform the specification solely for the purpose of */
+/* developing products based on such documents. */
+/* */
+/* 2. Source Code Distribution Conditions: */
+/* */
+/* - Redistributions of Source Code must retain the above copyright licenses, */
+/* this list of conditions and the following disclaimers. */
+/* */
+/* - Redistributions in binary form must reproduce the above copyright */
+/* licenses, this list of conditions and the following disclaimers in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* 3. Disclaimers: */
+/* */
+/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
+/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
+/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
+/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
+/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
+/* information on specification licensing rights available through TCG */
+/* membership agreements. */
+/* */
+/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
+/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
+/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
+/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
+/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
+/* */
+/* - Without limitation, TCG and its members and licensors disclaim all */
+/* liability, including liability for infringement of any proprietary */
+/* rights, relating to use of information in this specification and to the */
+/* implementation of this specification, and TCG disclaims all liability for */
+/* cost of procurement of substitute goods or services, lost profits, loss */
+/* of use, loss of data or any incidental, consequential, direct, indirect, */
+/* or special damages, whether under contract, tort, warranty or otherwise, */
+/* arising in any way out of use or reliance upon this specification or any */
+/* information herein. */
+/* */
+/* (c) Copyright IBM Corp. and others, 2016 - 2019 */
+/* */
+/********************************************************************************/
+
+#include "Tpm.h"
+#include "Duplicate_fp.h"
+#if CC_Duplicate // Conditional expansion of this file
+#include "Object_spt_fp.h"
+TPM_RC
+TPM2_Duplicate(
+ Duplicate_In *in, // IN: input parameter list
+ Duplicate_Out *out // OUT: output parameter list
+ )
+{
+ TPM_RC result = TPM_RC_SUCCESS;
+ TPMT_SENSITIVE sensitive;
+ UINT16 innerKeySize = 0; // encrypt key size for inner wrap
+ OBJECT *object;
+ OBJECT *newParent;
+ TPM2B_DATA data;
+ // Input Validation
+ // Get duplicate object pointer
+ object = HandleToObject(in->objectHandle);
+ // Get new parent
+ newParent = HandleToObject(in->newParentHandle);
+ // duplicate key must have fixParent bit CLEAR.
+ if(IS_ATTRIBUTE(object->publicArea.objectAttributes, TPMA_OBJECT, fixedParent))
+ return TPM_RCS_ATTRIBUTES + RC_Duplicate_objectHandle;
+ // Do not duplicate object with NULL nameAlg
+ if(object->publicArea.nameAlg == TPM_ALG_NULL)
+ return TPM_RCS_TYPE + RC_Duplicate_objectHandle;
+ // new parent key must be a storage object or TPM_RH_NULL
+ if(in->newParentHandle != TPM_RH_NULL
+ && !ObjectIsStorage(in->newParentHandle))
+ return TPM_RCS_TYPE + RC_Duplicate_newParentHandle;
+ // If the duplicated object has encryptedDuplication SET, then there must be
+ // an inner wrapper and the new parent may not be TPM_RH_NULL
+ if(IS_ATTRIBUTE(object->publicArea.objectAttributes, TPMA_OBJECT,
+ encryptedDuplication))
+ {
+ if(in->symmetricAlg.algorithm == TPM_ALG_NULL)
+ return TPM_RCS_SYMMETRIC + RC_Duplicate_symmetricAlg;
+ if(in->newParentHandle == TPM_RH_NULL)
+ return TPM_RCS_HIERARCHY + RC_Duplicate_newParentHandle;
+ }
+ if(in->symmetricAlg.algorithm == TPM_ALG_NULL)
+ {
+ // if algorithm is TPM_ALG_NULL, input key size must be 0
+ if(in->encryptionKeyIn.t.size != 0)
+ return TPM_RCS_SIZE + RC_Duplicate_encryptionKeyIn;
+ }
+ else
+ {
+ // Get inner wrap key size
+ innerKeySize = in->symmetricAlg.keyBits.sym;
+ // If provided the input symmetric key must match the size of the algorithm
+ if(in->encryptionKeyIn.t.size != 0
+ && in->encryptionKeyIn.t.size != (innerKeySize + 7) / 8)
+ return TPM_RCS_SIZE + RC_Duplicate_encryptionKeyIn;
+ }
+ // Command Output
+ if(in->newParentHandle != TPM_RH_NULL)
+ {
+ // Make encrypt key and its associated secret structure. A TPM_RC_KEY
+ // error may be returned at this point
+ out->outSymSeed.t.size = sizeof(out->outSymSeed.t.secret);
+ result = CryptSecretEncrypt(newParent, DUPLICATE_STRING, &data,
+ &out->outSymSeed);
+ if(result != TPM_RC_SUCCESS)
+ return result;
+ }
+ else
+ {
+ // Do not apply outer wrapper
+ data.t.size = 0;
+ out->outSymSeed.t.size = 0;
+ }
+ // Copy sensitive area
+ sensitive = object->sensitive;
+ // Prepare output private data from sensitive.
+ // Note: If there is no encryption key, one will be provided by
+ // SensitiveToDuplicate(). This is why the assignment of encryptionKeyIn to
+ // encryptionKeyOut will work properly and is not conditional.
+ SensitiveToDuplicate(&sensitive, &object->name.b, newParent,
+ object->publicArea.nameAlg, &data.b,
+ &in->symmetricAlg, &in->encryptionKeyIn,
+ &out->duplicate);
+ out->encryptionKeyOut = in->encryptionKeyIn;
+ return TPM_RC_SUCCESS;
+}
+#endif // CC_Duplicate
+#include "Tpm.h"
+#include "Rewrap_fp.h"
+#if CC_Rewrap // Conditional expansion of this file
+#include "Object_spt_fp.h"
+TPM_RC
+TPM2_Rewrap(
+ Rewrap_In *in, // IN: input parameter list
+ Rewrap_Out *out // OUT: output parameter list
+ )
+{
+ TPM_RC result = TPM_RC_SUCCESS;
+ TPM2B_DATA data; // symmetric key
+ UINT16 hashSize = 0;
+ TPM2B_PRIVATE privateBlob; // A temporary private blob
+ // to transit between old
+ // and new wrappers
+ // Input Validation
+ if((in->inSymSeed.t.size == 0 && in->oldParent != TPM_RH_NULL)
+ || (in->inSymSeed.t.size != 0 && in->oldParent == TPM_RH_NULL))
+ return TPM_RCS_HANDLE + RC_Rewrap_oldParent;
+ if(in->oldParent != TPM_RH_NULL)
+ {
+ OBJECT *oldParent = HandleToObject(in->oldParent);
+ // old parent key must be a storage object
+ if(!ObjectIsStorage(in->oldParent))
+ return TPM_RCS_TYPE + RC_Rewrap_oldParent;
+ // Decrypt input secret data via asymmetric decryption. A
+ // TPM_RC_VALUE, TPM_RC_KEY or unmarshal errors may be returned at this
+ // point
+ result = CryptSecretDecrypt(oldParent, NULL, DUPLICATE_STRING,
+ &in->inSymSeed, &data);
+ if(result != TPM_RC_SUCCESS)
+ return TPM_RCS_VALUE + RC_Rewrap_inSymSeed;
+ // Unwrap Outer
+ result = UnwrapOuter(oldParent, &in->name.b,
+ oldParent->publicArea.nameAlg, &data.b,
+ FALSE,
+ in->inDuplicate.t.size, in->inDuplicate.t.buffer);
+ if(result != TPM_RC_SUCCESS)
+ return RcSafeAddToResult(result, RC_Rewrap_inDuplicate);
+ // Copy unwrapped data to temporary variable, remove the integrity field
+ hashSize = sizeof(UINT16) +
+ CryptHashGetDigestSize(oldParent->publicArea.nameAlg);
+ privateBlob.t.size = in->inDuplicate.t.size - hashSize;
+ pAssert(privateBlob.t.size <= sizeof(privateBlob.t.buffer));
+ MemoryCopy(privateBlob.t.buffer, in->inDuplicate.t.buffer + hashSize,
+ privateBlob.t.size);
+ }
+ else
+ {
+ // No outer wrap from input blob. Direct copy.
+ privateBlob = in->inDuplicate;
+ }
+ if(in->newParent != TPM_RH_NULL)
+ {
+ OBJECT *newParent;
+ newParent = HandleToObject(in->newParent);
+ // New parent must be a storage object
+ if(!ObjectIsStorage(in->newParent))
+ return TPM_RCS_TYPE + RC_Rewrap_newParent;
+ // Make new encrypt key and its associated secret structure. A
+ // TPM_RC_VALUE error may be returned at this point if RSA algorithm is
+ // enabled in TPM
+ out->outSymSeed.t.size = sizeof(out->outSymSeed.t.secret);
+ result = CryptSecretEncrypt(newParent, DUPLICATE_STRING, &data,
+ &out->outSymSeed);
+ if(result != TPM_RC_SUCCESS)
+ return result;
+ // Copy temporary variable to output, reserve the space for integrity
+ hashSize = sizeof(UINT16) +
+ CryptHashGetDigestSize(newParent->publicArea.nameAlg);
+ // Make sure that everything fits into the output buffer
+ // Note: this is mostly only an issue if there was no outer wrapper on
+ // 'inDuplicate'. It could be as large as a TPM2B_PRIVATE buffer. If we add
+ // a digest for an outer wrapper, it won't fit anymore.
+ if((privateBlob.t.size + hashSize) > sizeof(out->outDuplicate.t.buffer))
+ return TPM_RCS_VALUE + RC_Rewrap_inDuplicate;
+ // Command output
+ out->outDuplicate.t.size = privateBlob.t.size;
+ pAssert(privateBlob.t.size
+ <= sizeof(out->outDuplicate.t.buffer) - hashSize);
+ MemoryCopy(out->outDuplicate.t.buffer + hashSize, privateBlob.t.buffer,
+ privateBlob.t.size);
+ // Produce outer wrapper for output
+ out->outDuplicate.t.size = ProduceOuterWrap(newParent, &in->name.b,
+ newParent->publicArea.nameAlg,
+ &data.b,
+ FALSE,
+ out->outDuplicate.t.size,
+ out->outDuplicate.t.buffer);
+ }
+ else // New parent is a null key so there is no seed
+ {
+ out->outSymSeed.t.size = 0;
+ // Copy privateBlob directly
+ out->outDuplicate = privateBlob;
+ }
+ return TPM_RC_SUCCESS;
+}
+#endif // CC_Rewrap
+#include "Tpm.h"
+#include "Import_fp.h"
+#if CC_Import // Conditional expansion of this file
+#include "Object_spt_fp.h"
+TPM_RC
+TPM2_Import(
+ Import_In *in, // IN: input parameter list
+ Import_Out *out // OUT: output parameter list
+ )
+{
+ TPM_RC result = TPM_RC_SUCCESS;
+ OBJECT *parentObject;
+ TPM2B_DATA data; // symmetric key
+ TPMT_SENSITIVE sensitive;
+ TPM2B_NAME name;
+ TPMA_OBJECT attributes;
+ UINT16 innerKeySize = 0; // encrypt key size for inner
+ // wrapper
+ // Input Validation
+ // to save typing
+ attributes = in->objectPublic.publicArea.objectAttributes;
+ // FixedTPM and fixedParent must be CLEAR
+ if(IS_ATTRIBUTE(attributes, TPMA_OBJECT, fixedTPM)
+ || IS_ATTRIBUTE(attributes, TPMA_OBJECT, fixedParent))
+ return TPM_RCS_ATTRIBUTES + RC_Import_objectPublic;
+ // Get parent pointer
+ parentObject = HandleToObject(in->parentHandle);
+ if(!ObjectIsParent(parentObject))
+ return TPM_RCS_TYPE + RC_Import_parentHandle;
+ if(in->symmetricAlg.algorithm != TPM_ALG_NULL)
+ {
+ // Get inner wrap key size
+ innerKeySize = in->symmetricAlg.keyBits.sym;
+ // Input symmetric key must match the size of algorithm.
+ if(in->encryptionKey.t.size != (innerKeySize + 7) / 8)
+ return TPM_RCS_SIZE + RC_Import_encryptionKey;
+ }
+ else
+ {
+ // If input symmetric algorithm is NULL, input symmetric key size must
+ // be 0 as well
+ if(in->encryptionKey.t.size != 0)
+ return TPM_RCS_SIZE + RC_Import_encryptionKey;
+ // If encryptedDuplication is SET, then the object must have an inner
+ // wrapper
+ if(IS_ATTRIBUTE(attributes, TPMA_OBJECT, encryptedDuplication))
+ return TPM_RCS_ATTRIBUTES + RC_Import_encryptionKey;
+ }
+ // See if there is an outer wrapper
+ if(in->inSymSeed.t.size != 0)
+ {
+ // in->inParentHandle is a parent, but in order to decrypt an outer wrapper,
+ // it must be able to do key exchange and a symmetric key can't do that.
+ if(parentObject->publicArea.type == TPM_ALG_SYMCIPHER)
+ return TPM_RCS_TYPE + RC_Import_parentHandle;
+ // Decrypt input secret data via asymmetric decryption. TPM_RC_ATTRIBUTES,
+ // TPM_RC_ECC_POINT, TPM_RC_INSUFFICIENT, TPM_RC_KEY, TPM_RC_NO_RESULT,
+ // TPM_RC_SIZE, TPM_RC_VALUE may be returned at this point
+ result = CryptSecretDecrypt(parentObject, NULL, DUPLICATE_STRING,
+ &in->inSymSeed, &data);
+ pAssert(result != TPM_RC_BINDING);
+ if(result != TPM_RC_SUCCESS)
+ return RcSafeAddToResult(result, RC_Import_inSymSeed);
+ }
+ else
+ {
+ // If encrytpedDuplication is set, then the object must have an outer
+ // wrapper
+ if(IS_ATTRIBUTE(attributes, TPMA_OBJECT, encryptedDuplication))
+ return TPM_RCS_ATTRIBUTES + RC_Import_inSymSeed;
+ data.t.size = 0;
+ }
+ // Compute name of object
+ PublicMarshalAndComputeName(&(in->objectPublic.publicArea), &name);
+ if(name.t.size == 0)
+ return TPM_RCS_HASH + RC_Import_objectPublic;
+ // Retrieve sensitive from private.
+ // TPM_RC_INSUFFICIENT, TPM_RC_INTEGRITY, TPM_RC_SIZE may be returned here.
+ result = DuplicateToSensitive(&in->duplicate.b, &name.b, parentObject,
+ in->objectPublic.publicArea.nameAlg,
+ &data.b, &in->symmetricAlg,
+ &in->encryptionKey.b, &sensitive);
+ if(result != TPM_RC_SUCCESS)
+ return RcSafeAddToResult(result, RC_Import_duplicate);
+ // If the parent of this object has fixedTPM SET, then validate this
+ // object as if it were being loaded so that validation can be skipped
+ // when it is actually loaded.
+ if(IS_ATTRIBUTE(parentObject->publicArea.objectAttributes, TPMA_OBJECT, fixedTPM))
+ {
+ result = ObjectLoad(NULL, NULL, &in->objectPublic.publicArea,
+ &sensitive, RC_Import_objectPublic, RC_Import_duplicate,
+ NULL);
+ }
+ // Command output
+ if(result == TPM_RC_SUCCESS)
+ {
+ // Prepare output private data from sensitive
+ SensitiveToPrivate(&sensitive, &name, parentObject,
+ in->objectPublic.publicArea.nameAlg,
+ &out->outPrivate);
+ }
+ return result;
+}
+#endif // CC_Import
diff --git a/src/tpm2/EACommands.c b/src/tpm2/EACommands.c
new file mode 100644
index 0000000..abf6074
--- /dev/null
+++ b/src/tpm2/EACommands.c
@@ -0,0 +1,1164 @@
+/********************************************************************************/
+/* */
+/* Enhanced Authorization Commands */
+/* Written by Ken Goldman */
+/* IBM Thomas J. Watson Research Center */
+/* $Id: EACommands.c 1519 2019-11-15 20:43:51Z kgoldman $ */
+/* */
+/* Licenses and Notices */
+/* */
+/* 1. Copyright Licenses: */
+/* */
+/* - Trusted Computing Group (TCG) grants to the user of the source code in */
+/* this specification (the "Source Code") a worldwide, irrevocable, */
+/* nonexclusive, royalty free, copyright license to reproduce, create */
+/* derivative works, distribute, display and perform the Source Code and */
+/* derivative works thereof, and to grant others the rights granted herein. */
+/* */
+/* - The TCG grants to the user of the other parts of the specification */
+/* (other than the Source Code) the rights to reproduce, distribute, */
+/* display, and perform the specification solely for the purpose of */
+/* developing products based on such documents. */
+/* */
+/* 2. Source Code Distribution Conditions: */
+/* */
+/* - Redistributions of Source Code must retain the above copyright licenses, */
+/* this list of conditions and the following disclaimers. */
+/* */
+/* - Redistributions in binary form must reproduce the above copyright */
+/* licenses, this list of conditions and the following disclaimers in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* 3. Disclaimers: */
+/* */
+/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
+/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
+/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
+/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
+/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
+/* information on specification licensing rights available through TCG */
+/* membership agreements. */
+/* */
+/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
+/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
+/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
+/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
+/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
+/* */
+/* - Without limitation, TCG and its members and licensors disclaim all */
+/* liability, including liability for infringement of any proprietary */
+/* rights, relating to use of information in this specification and to the */
+/* implementation of this specification, and TCG disclaims all liability for */
+/* cost of procurement of substitute goods or services, lost profits, loss */
+/* of use, loss of data or any incidental, consequential, direct, indirect, */
+/* or special damages, whether under contract, tort, warranty or otherwise, */
+/* arising in any way out of use or reliance upon this specification or any */
+/* information herein. */
+/* */
+/* (c) Copyright IBM Corp. and others, 2016 - 2019 */
+/* */
+/********************************************************************************/
+
+#include "Tpm.h"
+#include "Policy_spt_fp.h"
+#include "PolicySigned_fp.h"
+#if CC_PolicySigned // Conditional expansion of this file
+/*TPM_RC_CPHASH cpHash was previously set to a different value */
+/*TPM_RC_EXPIRED expiration indicates a time in the past or expiration is non-zero but no nonceTPM
+ is present */
+/*TPM_RC_NONCE nonceTPM is not the nonce associated with the policySession */
+/*TPM_RC_SCHEME the signing scheme of auth is not supported by the TPM */
+/*TPM_RC_SIGNATURE the signature is not genuine */
+/*TPM_RC_SIZE input cpHash has wrong size */
+TPM_RC
+TPM2_PolicySigned(
+ PolicySigned_In *in, // IN: input parameter list
+ PolicySigned_Out *out // OUT: output parameter list
+ )
+{
+ TPM_RC result = TPM_RC_SUCCESS;
+ SESSION *session;
+ TPM2B_NAME entityName;
+ TPM2B_DIGEST authHash;
+ HASH_STATE hashState;
+ UINT64 authTimeout = 0;
+ // Input Validation
+ // Set up local pointers
+ session = SessionGet(in->policySession); // the session structure
+ // Only do input validation if this is not a trial policy session
+ if(session->attributes.isTrialPolicy == CLEAR)
+ {
+ authTimeout = ComputeAuthTimeout(session, in->expiration, &in->nonceTPM);
+ result = PolicyParameterChecks(session, authTimeout,
+ &in->cpHashA, &in->nonceTPM,
+ RC_PolicySigned_nonceTPM,
+ RC_PolicySigned_cpHashA,
+ RC_PolicySigned_expiration);
+ if(result != TPM_RC_SUCCESS)
+ return result;
+ // Re-compute the digest being signed
+ // Start hash
+ authHash.t.size = CryptHashStart(&hashState,
+ CryptGetSignHashAlg(&in->auth));
+ // If there is no digest size, then we don't have a verification function
+ // for this algorithm (e.g. TPM_ALG_ECDAA) so indicate that it is a
+ // bad scheme.
+ if(authHash.t.size == 0)
+ return TPM_RCS_SCHEME + RC_PolicySigned_auth;
+ // nonceTPM
+ CryptDigestUpdate2B(&hashState, &in->nonceTPM.b);
+ // expiration
+ CryptDigestUpdateInt(&hashState, sizeof(UINT32), in->expiration);
+ // cpHashA
+ CryptDigestUpdate2B(&hashState, &in->cpHashA.b);
+ // policyRef
+ CryptDigestUpdate2B(&hashState, &in->policyRef.b);
+ // Complete digest
+ CryptHashEnd2B(&hashState, &authHash.b);
+ // Validate Signature. A TPM_RC_SCHEME, TPM_RC_HANDLE or TPM_RC_SIGNATURE
+ // error may be returned at this point
+ result = CryptValidateSignature(in->authObject, &authHash, &in->auth);
+ if(result != TPM_RC_SUCCESS)
+ return RcSafeAddToResult(result, RC_PolicySigned_auth);
+ }
+ // Internal Data Update
+ // Update policy with input policyRef and name of authorization key
+ // These values are updated even if the session is a trial session
+ PolicyContextUpdate(TPM_CC_PolicySigned,
+ EntityGetName(in->authObject, &entityName),
+ &in->policyRef,
+ &in->cpHashA, authTimeout, session);
+ // Command Output
+ // Create ticket and timeout buffer if in->expiration < 0 and this is not
+ // a trial session.
+ // NOTE: PolicyParameterChecks() makes sure that nonceTPM is present
+ // when expiration is non-zero.
+ if(in->expiration < 0
+ && session->attributes.isTrialPolicy == CLEAR)
+ {
+ BOOL expiresOnReset = (in->nonceTPM.t.size == 0);
+ // Compute policy ticket
+ authTimeout &= ~EXPIRATION_BIT;
+ TicketComputeAuth(TPM_ST_AUTH_SIGNED, EntityGetHierarchy(in->authObject),
+ authTimeout, expiresOnReset, &in->cpHashA, &in->policyRef,
+ &entityName, &out->policyTicket);
+ // Generate timeout buffer. The format of output timeout buffer is
+ // TPM-specific.
+ // Note: In this implementation, the timeout buffer value is computed after
+ // the ticket is produced so, when the ticket is checked, the expiration
+ // flag needs to be extracted before the ticket is checked.
+ // In the Windows compatible version, the least-significant bit of the
+ // timeout value is used as a flag to indicate if the authorization expires
+ // on reset. The flag is the MSb.
+ out->timeout.t.size = sizeof(authTimeout);
+ if(expiresOnReset)
+ authTimeout |= EXPIRATION_BIT;
+ UINT64_TO_BYTE_ARRAY(authTimeout, out->timeout.t.buffer);
+ }
+ else
+ {
+ // Generate a null ticket.
+ // timeout buffer is null
+ out->timeout.t.size = 0;
+ // authorization ticket is null
+ out->policyTicket.tag = TPM_ST_AUTH_SIGNED;
+ out->policyTicket.hierarchy = TPM_RH_NULL;
+ out->policyTicket.digest.t.size = 0;
+ }
+ return TPM_RC_SUCCESS;
+}
+#endif // CC_PolicySigned
+#include "Tpm.h"
+#include "PolicySecret_fp.h"
+#if CC_PolicySecret // Conditional expansion of this file
+#include "Policy_spt_fp.h"
+#include "NV_spt_fp.h"
+/* TPM_RC_CPHASH cpHash for policy was previously set to a value that is not the same as cpHashA */
+/* TPM_RC_EXPIRED expiration indicates a time in the past */
+/* TPM_RC_NONCE nonceTPM does not match the nonce associated with policySession */
+/* TPM_RC_SIZE cpHashA is not the size of a digest for the hash associated with policySession */
+TPM_RC
+TPM2_PolicySecret(
+ PolicySecret_In *in, // IN: input parameter list
+ PolicySecret_Out *out // OUT: output parameter list
+ )
+{
+ TPM_RC result;
+ SESSION *session;
+ TPM2B_NAME entityName;
+ UINT64 authTimeout = 0;
+ // Input Validation
+ // Get pointer to the session structure
+ session = SessionGet(in->policySession);
+ //Only do input validation if this is not a trial policy session
+ if(session->attributes.isTrialPolicy == CLEAR)
+ {
+ authTimeout = ComputeAuthTimeout(session, in->expiration, &in->nonceTPM);
+ result = PolicyParameterChecks(session, authTimeout,
+ &in->cpHashA, &in->nonceTPM,
+ RC_PolicySecret_nonceTPM,
+ RC_PolicySecret_cpHashA,
+ RC_PolicySecret_expiration);
+ if(result != TPM_RC_SUCCESS)
+ return result;
+ }
+ // Internal Data Update
+ // Update policy context with input policyRef and name of authorizing key
+ // This value is computed even for trial sessions. Possibly update the cpHash
+ PolicyContextUpdate(TPM_CC_PolicySecret,
+ EntityGetName(in->authHandle, &entityName), &in->policyRef,
+ &in->cpHashA, authTimeout, session);
+ // Command Output
+ // Create ticket and timeout buffer if in->expiration < 0 and this is not
+ // a trial session.
+ // NOTE: PolicyParameterChecks() makes sure that nonceTPM is present
+ // when expiration is non-zero.
+ if(in->expiration < 0
+ && session->attributes.isTrialPolicy == CLEAR
+ && !NvIsPinPassIndex(in->authHandle))
+ {
+ BOOL expiresOnReset = (in->nonceTPM.t.size == 0);
+ // Compute policy ticket
+ authTimeout &= ~EXPIRATION_BIT;
+ TicketComputeAuth(TPM_ST_AUTH_SECRET, EntityGetHierarchy(in->authHandle),
+ authTimeout, expiresOnReset, &in->cpHashA, &in->policyRef,
+ &entityName, &out->policyTicket);
+ // Generate timeout buffer. The format of output timeout buffer is
+ // TPM-specific.
+ // Note: In this implementation, the timeout buffer value is computed after
+ // the ticket is produced so, when the ticket is checked, the expiration
+ // flag needs to be extracted before the ticket is checked.
+ out->timeout.t.size = sizeof(authTimeout);
+ // In the Windows compatible version, the least-significant bit of the
+ // timeout value is used as a flag to indicate if the authorization expires
+ // on reset. The flag is the MSb.
+ if(expiresOnReset)
+ authTimeout |= EXPIRATION_BIT;
+ UINT64_TO_BYTE_ARRAY(authTimeout, out->timeout.t.buffer);
+ }
+ else
+ {
+ // timeout buffer is null
+ out->timeout.t.size = 0;
+ // authorization ticket is null
+ out->policyTicket.tag = TPM_ST_AUTH_SECRET;
+ out->policyTicket.hierarchy = TPM_RH_NULL;
+ out->policyTicket.digest.t.size = 0;
+ }
+ return TPM_RC_SUCCESS;
+}
+#endif // CC_PolicySecret
+#include "Tpm.h"
+#include "PolicyTicket_fp.h"
+#if CC_PolicyTicket // Conditional expansion of this file
+#include "Policy_spt_fp.h"
+/* TPM_RC_CPHASH policy's cpHash was previously set to a different value */
+/* TPM_RC_EXPIRED timeout value in the ticket is in the past and the ticket has expired */
+/* TPM_RC_SIZE timeout or cpHash has invalid size for the */
+/* TPM_RC_TICKET ticket is not valid */
+TPM_RC
+TPM2_PolicyTicket(
+ PolicyTicket_In *in // IN: input parameter list
+ )
+{
+ TPM_RC result;
+ SESSION *session;
+ UINT64 authTimeout;
+ TPMT_TK_AUTH ticketToCompare;
+ TPM_CC commandCode = TPM_CC_PolicySecret;
+ BOOL expiresOnReset;
+ // Input Validation
+ // Get pointer to the session structure
+ session = SessionGet(in->policySession);
+ // NOTE: A trial policy session is not allowed to use this command.
+ // A ticket is used in place of a previously given authorization. Since
+ // a trial policy doesn't actually authenticate, the validated
+ // ticket is not necessary and, in place of using a ticket, one
+ // should use the intended authorization for which the ticket
+ // would be a substitute.
+ if(session->attributes.isTrialPolicy)
+ return TPM_RCS_ATTRIBUTES + RC_PolicyTicket_policySession;
+ // Restore timeout data. The format of timeout buffer is TPM-specific.
+ // In this implementation, the most significant bit of the timeout value is
+ // used as the flag to indicate that the ticket expires on TPM Reset or
+ // TPM Restart. The flag has to be removed before the parameters and ticket
+ // are checked.
+ if(in->timeout.t.size != sizeof(UINT64))
+ return TPM_RCS_SIZE + RC_PolicyTicket_timeout;
+ authTimeout = BYTE_ARRAY_TO_UINT64(in->timeout.t.buffer);
+ // extract the flag
+ expiresOnReset = (authTimeout & EXPIRATION_BIT) != 0;
+ authTimeout &= ~EXPIRATION_BIT;
+ // Do the normal checks on the cpHashA and timeout values
+ result = PolicyParameterChecks(session, authTimeout,
+ &in->cpHashA,
+ NULL, // no nonce
+ 0, // no bad nonce return
+ RC_PolicyTicket_cpHashA,
+ RC_PolicyTicket_timeout);
+ if(result != TPM_RC_SUCCESS)
+ return result;
+ // Validate Ticket
+ // Re-generate policy ticket by input parameters
+ TicketComputeAuth(in->ticket.tag, in->ticket.hierarchy,
+ authTimeout, expiresOnReset, &in->cpHashA, &in->policyRef,
+ &in->authName, &ticketToCompare);
+ // Compare generated digest with input ticket digest
+ if(!MemoryEqual2B(&in->ticket.digest.b, &ticketToCompare.digest.b))
+ return TPM_RCS_TICKET + RC_PolicyTicket_ticket;
+ // Internal Data Update
+ // Is this ticket to take the place of a TPM2_PolicySigned() or
+ // a TPM2_PolicySecret()?
+ if(in->ticket.tag == TPM_ST_AUTH_SIGNED)
+ commandCode = TPM_CC_PolicySigned;
+ else if(in->ticket.tag == TPM_ST_AUTH_SECRET)
+ commandCode = TPM_CC_PolicySecret;
+ else
+ // There could only be two possible tag values. Any other value should
+ // be caught by the ticket validation process.
+ FAIL(FATAL_ERROR_INTERNAL);
+ // Update policy context
+ PolicyContextUpdate(commandCode, &in->authName, &in->policyRef,
+ &in->cpHashA, authTimeout, session);
+ return TPM_RC_SUCCESS;
+}
+#endif // CC_PolicyTicket
+#include "Tpm.h"
+#include "PolicyOR_fp.h"
+#if CC_PolicyOR // Conditional expansion of this file
+#include "Policy_spt_fp.h"
+TPM_RC
+TPM2_PolicyOR(
+ PolicyOR_In *in // IN: input parameter list
+ )
+{
+ SESSION *session;
+ UINT32 i;
+ // Input Validation and Update
+ // Get pointer to the session structure
+ session = SessionGet(in->policySession);
+ // Compare and Update Internal Session policy if match
+ for(i = 0; i < in->pHashList.count; i++)
+ {
+ if(session->attributes.isTrialPolicy == SET
+ || (MemoryEqual2B(&session->u2.policyDigest.b,
+ &in->pHashList.digests[i].b)))
+ {
+ // Found a match
+ HASH_STATE hashState;
+ TPM_CC commandCode = TPM_CC_PolicyOR;
+ // Start hash
+ session->u2.policyDigest.t.size
+ = CryptHashStart(&hashState, session->authHashAlg);
+ // Set policyDigest to 0 string and add it to hash
+ MemorySet(session->u2.policyDigest.t.buffer, 0,
+ session->u2.policyDigest.t.size);
+ CryptDigestUpdate2B(&hashState, &session->u2.policyDigest.b);
+ // add command code
+ CryptDigestUpdateInt(&hashState, sizeof(TPM_CC), commandCode);
+ // Add each of the hashes in the list
+ for(i = 0; i < in->pHashList.count; i++)
+ {
+ // Extend policyDigest
+ CryptDigestUpdate2B(&hashState, &in->pHashList.digests[i].b);
+ }
+ // Complete digest
+ CryptHashEnd2B(&hashState, &session->u2.policyDigest.b);
+ return TPM_RC_SUCCESS;
+ }
+ }
+ // None of the values in the list matched the current policyDigest
+ return TPM_RCS_VALUE + RC_PolicyOR_pHashList;
+}
+#endif // CC_PolicyOR
+#include "Tpm.h"
+#include "PolicyPCR_fp.h"
+#if CC_PolicyPCR // Conditional expansion of this file
+/* TPM_RC_VALUE if provided, pcrDigest does not match the current PCR settings */
+/* TPM_RC_PCR_CHANGED a previous TPM2_PolicyPCR() set pcrCounter and it has changed */
+TPM_RC
+TPM2_PolicyPCR(
+ PolicyPCR_In *in // IN: input parameter list
+ )
+{
+ SESSION *session;
+ TPM2B_DIGEST pcrDigest;
+ BYTE pcrs[sizeof(TPML_PCR_SELECTION)];
+ UINT32 pcrSize;
+ BYTE *buffer;
+ TPM_CC commandCode = TPM_CC_PolicyPCR;
+ HASH_STATE hashState;
+ // Input Validation
+ // Get pointer to the session structure
+ session = SessionGet(in->policySession);
+ // Compute current PCR digest
+ PCRComputeCurrentDigest(session->authHashAlg, &in->pcrs, &pcrDigest);
+ // Do validation for non trial session
+ if(session->attributes.isTrialPolicy == CLEAR)
+ {
+ // Make sure that this is not going to invalidate a previous PCR check
+ if(session->pcrCounter != 0 && session->pcrCounter != gr.pcrCounter)
+ return TPM_RC_PCR_CHANGED;
+ // If the caller specified the PCR digest and it does not
+ // match the current PCR settings, return an error..
+ if(in->pcrDigest.t.size != 0)
+ {
+ if(!MemoryEqual2B(&in->pcrDigest.b, &pcrDigest.b))
+ return TPM_RCS_VALUE + RC_PolicyPCR_pcrDigest;
+ }
+ }
+ else
+ {
+ // For trial session, just use the input PCR digest if one provided
+ // Note: It can't be too big because it is a TPM2B_DIGEST and the size
+ // would have been checked during unmarshaling
+ if(in->pcrDigest.t.size != 0)
+ pcrDigest = in->pcrDigest;
+ }
+ // Internal Data Update
+ // Update policy hash
+ // policyDigestnew = hash( policyDigestold || TPM_CC_PolicyPCR
+ // || PCRS || pcrDigest)
+ // Start hash
+ CryptHashStart(&hashState, session->authHashAlg);
+ // add old digest
+ CryptDigestUpdate2B(&hashState, &session->u2.policyDigest.b);
+ // add commandCode
+ CryptDigestUpdateInt(&hashState, sizeof(TPM_CC), commandCode);
+ // add PCRS
+ buffer = pcrs;
+ pcrSize = TPML_PCR_SELECTION_Marshal(&in->pcrs, &buffer, NULL);
+ CryptDigestUpdate(&hashState, pcrSize, pcrs);
+ // add PCR digest
+ CryptDigestUpdate2B(&hashState, &pcrDigest.b);
+ // complete the hash and get the results
+ CryptHashEnd2B(&hashState, &session->u2.policyDigest.b);
+ // update pcrCounter in session context for non trial session
+ if(session->attributes.isTrialPolicy == CLEAR)
+ {
+ session->pcrCounter = gr.pcrCounter;
+ }
+ return TPM_RC_SUCCESS;
+}
+#endif // CC_PolicyPCR
+#include "Tpm.h"
+#include "PolicyLocality_fp.h"
+#if CC_PolicyLocality // Conditional expansion of this file
+TPM_RC
+TPM2_PolicyLocality(
+ PolicyLocality_In *in // IN: input parameter list
+ )
+{
+ SESSION *session;
+ BYTE marshalBuffer[sizeof(TPMA_LOCALITY)];
+ BYTE prevSetting[sizeof(TPMA_LOCALITY)];
+ UINT32 marshalSize;
+ BYTE *buffer;
+ TPM_CC commandCode = TPM_CC_PolicyLocality;
+ HASH_STATE hashState;
+ // Input Validation
+ // Get pointer to the session structure
+ session = SessionGet(in->policySession);
+ // Get new locality setting in canonical form
+ marshalBuffer[0] = 0; // Code analysis says that this is not initialized
+ buffer = marshalBuffer;
+ marshalSize = TPMA_LOCALITY_Marshal(&in->locality, &buffer, NULL);
+ // Its an error if the locality parameter is zero
+ if(marshalBuffer[0] == 0)
+ return TPM_RCS_RANGE + RC_PolicyLocality_locality;
+ // Get existing locality setting in canonical form
+ prevSetting[0] = 0; // Code analysis says that this is not initialized
+ buffer = prevSetting;
+ TPMA_LOCALITY_Marshal(&session->commandLocality, &buffer, NULL);
+ // If the locality has previously been set
+ if(prevSetting[0] != 0
+ // then the current locality setting and the requested have to be the same
+ // type (that is, either both normal or both extended
+ && ((prevSetting[0] < 32) != (marshalBuffer[0] < 32)))
+ return TPM_RCS_RANGE + RC_PolicyLocality_locality;
+ // See if the input is a regular or extended locality
+ if(marshalBuffer[0] < 32)
+ {
+ // if there was no previous setting, start with all normal localities
+ // enabled
+ if(prevSetting[0] == 0)
+ prevSetting[0] = 0x1F;
+ // AND the new setting with the previous setting and store it in prevSetting
+ prevSetting[0] &= marshalBuffer[0];
+ // The result setting can not be 0
+ if(prevSetting[0] == 0)
+ return TPM_RCS_RANGE + RC_PolicyLocality_locality;
+ }
+ else
+ {
+ // for extended locality
+ // if the locality has already been set, then it must match the
+ if(prevSetting[0] != 0 && prevSetting[0] != marshalBuffer[0])
+ return TPM_RCS_RANGE + RC_PolicyLocality_locality;
+ // Setting is OK
+ prevSetting[0] = marshalBuffer[0];
+ }
+ // Internal Data Update
+ // Update policy hash
+ // policyDigestnew = hash(policyDigestold || TPM_CC_PolicyLocality || locality)
+ // Start hash
+ CryptHashStart(&hashState, session->authHashAlg);
+ // add old digest
+ CryptDigestUpdate2B(&hashState, &session->u2.policyDigest.b);
+ // add commandCode
+ CryptDigestUpdateInt(&hashState, sizeof(TPM_CC), commandCode);
+ // add input locality
+ CryptDigestUpdate(&hashState, marshalSize, marshalBuffer);
+ // complete the digest
+ CryptHashEnd2B(&hashState, &session->u2.policyDigest.b);
+ // update session locality by unmarshal function. The function must succeed
+ // because both input and existing locality setting have been validated.
+ buffer = prevSetting;
+ TPMA_LOCALITY_Unmarshal(&session->commandLocality, &buffer,
+ (INT32 *)&marshalSize);
+ return TPM_RC_SUCCESS;
+}
+#endif // CC_PolicyLocality
+#include "Tpm.h"
+#include "PolicyNV_fp.h"
+#if CC_PolicyNV // Conditional expansion of this file
+#include "Policy_spt_fp.h"
+TPM_RC
+TPM2_PolicyNV(
+ PolicyNV_In *in // IN: input parameter list
+ )
+{
+ TPM_RC result;
+ SESSION *session;
+ NV_REF locator;
+ NV_INDEX *nvIndex;
+ BYTE nvBuffer[sizeof(in->operandB.t.buffer)];
+ TPM2B_NAME nvName;
+ TPM_CC commandCode = TPM_CC_PolicyNV;
+ HASH_STATE hashState;
+ TPM2B_DIGEST argHash;
+ // Input Validation
+ // Get pointer to the session structure
+ session = SessionGet(in->policySession);
+ //If this is a trial policy, skip all validations and the operation
+ if(session->attributes.isTrialPolicy == CLEAR)
+ {
+ // No need to access the actual NV index information for a trial policy.
+ nvIndex = NvGetIndexInfo(in->nvIndex, &locator);
+ // Common read access checks. NvReadAccessChecks() may return
+ // TPM_RC_NV_AUTHORIZATION, TPM_RC_NV_LOCKED, or TPM_RC_NV_UNINITIALIZED
+ result = NvReadAccessChecks(in->authHandle,
+ in->nvIndex,
+ nvIndex->publicArea.attributes);
+ if(result != TPM_RC_SUCCESS)
+ return result;
+ // Make sure that offset is withing range
+ if(in->offset > nvIndex->publicArea.dataSize)
+ return TPM_RCS_VALUE + RC_PolicyNV_offset;
+ // Valid NV data size should not be smaller than input operandB size
+ if((nvIndex->publicArea.dataSize - in->offset) < in->operandB.t.size)
+ return TPM_RCS_SIZE + RC_PolicyNV_operandB;
+ // Get NV data. The size of NV data equals the input operand B size
+ NvGetIndexData(nvIndex, locator, in->offset, in->operandB.t.size, nvBuffer);
+ // Check to see if the condition is valid
+ if(!PolicySptCheckCondition(in->operation, nvBuffer,
+ in->operandB.t.buffer, in->operandB.t.size))
+ return TPM_RC_POLICY;
+ }
+ // Internal Data Update
+ // Start argument hash
+ argHash.t.size = CryptHashStart(&hashState, session->authHashAlg);
+ // add operandB
+ CryptDigestUpdate2B(&hashState, &in->operandB.b);
+ // add offset
+ CryptDigestUpdateInt(&hashState, sizeof(UINT16), in->offset);
+ // add operation
+ CryptDigestUpdateInt(&hashState, sizeof(TPM_EO), in->operation);
+ // complete argument digest
+ CryptHashEnd2B(&hashState, &argHash.b);
+ // Update policyDigest
+ // Start digest
+ CryptHashStart(&hashState, session->authHashAlg);
+ // add old digest
+ CryptDigestUpdate2B(&hashState, &session->u2.policyDigest.b);
+ // add commandCode
+ CryptDigestUpdateInt(&hashState, sizeof(TPM_CC), commandCode);
+ // add argument digest
+ CryptDigestUpdate2B(&hashState, &argHash.b);
+ // Adding nvName
+ CryptDigestUpdate2B(&hashState, &EntityGetName(in->nvIndex, &nvName)->b);
+ // complete the digest
+ CryptHashEnd2B(&hashState, &session->u2.policyDigest.b);
+ return TPM_RC_SUCCESS;
+}
+#endif // CC_PolicyNV
+#include "Tpm.h"
+#include "PolicyCounterTimer_fp.h"
+#if CC_PolicyCounterTimer // Conditional expansion of this file
+#include "Policy_spt_fp.h"
+TPM_RC
+TPM2_PolicyCounterTimer(
+ PolicyCounterTimer_In *in // IN: input parameter list
+ )
+{
+ SESSION *session;
+ TIME_INFO infoData; // data buffer of TPMS_TIME_INFO
+ BYTE *pInfoData = (BYTE *)&infoData;
+ UINT16 infoDataSize;
+ TPM_CC commandCode = TPM_CC_PolicyCounterTimer;
+ HASH_STATE hashState;
+ TPM2B_DIGEST argHash;
+ // Input Validation
+ // Get a marshaled time structure
+ infoDataSize = TimeGetMarshaled(&infoData);
+ pAssert(infoDataSize <= sizeof(infoData)); // libtpms added; 25 < 32 ==> unfounded coverity complaint
+ // Make sure that the referenced stays within the bounds of the structure.
+ // NOTE: the offset checks are made even for a trial policy because the policy
+ // will not make any sense if the references are out of bounds of the timer
+ // structure.
+ if(in->offset > infoDataSize)
+ return TPM_RCS_VALUE + RC_PolicyCounterTimer_offset;
+ if((UINT32)in->offset + (UINT32)in->operandB.t.size > infoDataSize)
+ return TPM_RCS_RANGE;
+ // Get pointer to the session structure
+ session = SessionGet(in->policySession);
+ //If this is a trial policy, skip the check to see if the condition is met.
+ if(session->attributes.isTrialPolicy == CLEAR)
+ {
+ // If the command is going to use any part of the counter or timer, need
+ // to verify that time is advancing.
+ // The time and clock vales are the first two 64-bit values in the clock
+ if(in->offset < sizeof(UINT64) + sizeof(UINT64))
+ {
+ // Using Clock or Time so see if clock is running. Clock doesn't
+ // run while NV is unavailable.
+ // TPM_RC_NV_UNAVAILABLE or TPM_RC_NV_RATE error may be returned here.
+ RETURN_IF_NV_IS_NOT_AVAILABLE;
+ }
+ // offset to the starting position
+ pInfoData = (BYTE *)infoData;
+ // Check to see if the condition is valid
+ if(!PolicySptCheckCondition(in->operation, pInfoData + in->offset,
+ in->operandB.t.buffer, in->operandB.t.size))
+ return TPM_RC_POLICY;
+ }
+ // Internal Data Update
+ // Start argument list hash
+ argHash.t.size = CryptHashStart(&hashState, session->authHashAlg);
+ // add operandB
+ CryptDigestUpdate2B(&hashState, &in->operandB.b);
+ // add offset
+ CryptDigestUpdateInt(&hashState, sizeof(UINT16), in->offset);
+ // add operation
+ CryptDigestUpdateInt(&hashState, sizeof(TPM_EO), in->operation);
+ // complete argument hash
+ CryptHashEnd2B(&hashState, &argHash.b);
+ // update policyDigest
+ // start hash
+ CryptHashStart(&hashState, session->authHashAlg);
+ // add old digest
+ CryptDigestUpdate2B(&hashState, &session->u2.policyDigest.b);
+ // add commandCode
+ CryptDigestUpdateInt(&hashState, sizeof(TPM_CC), commandCode);
+ // add argument digest
+ CryptDigestUpdate2B(&hashState, &argHash.b);
+ // complete the digest
+ CryptHashEnd2B(&hashState, &session->u2.policyDigest.b);
+ return TPM_RC_SUCCESS;
+}
+#endif // CC_PolicyCounterTimer
+#include "Tpm.h"
+#include "PolicyCommandCode_fp.h"
+#if CC_PolicyCommandCode // Conditional expansion of this file
+/* Error Returns Meaning */
+/* TPM_RC_VALUE commandCode of policySession previously set to a different value */
+TPM_RC
+TPM2_PolicyCommandCode(
+ PolicyCommandCode_In *in // IN: input parameter list
+ )
+{
+ SESSION *session;
+ TPM_CC commandCode = TPM_CC_PolicyCommandCode;
+ HASH_STATE hashState;
+ // Input validation
+ // Get pointer to the session structure
+ session = SessionGet(in->policySession);
+ if(session->commandCode != 0 && session->commandCode != in->code)
+ return TPM_RCS_VALUE + RC_PolicyCommandCode_code;
+ if(CommandCodeToCommandIndex(in->code) == UNIMPLEMENTED_COMMAND_INDEX)
+ return TPM_RCS_POLICY_CC + RC_PolicyCommandCode_code;
+ // Internal Data Update
+ // Update policy hash
+ // policyDigestnew = hash(policyDigestold || TPM_CC_PolicyCommandCode || code)
+ // Start hash
+ CryptHashStart(&hashState, session->authHashAlg);
+ // add old digest
+ CryptDigestUpdate2B(&hashState, &session->u2.policyDigest.b);
+ // add commandCode
+ CryptDigestUpdateInt(&hashState, sizeof(TPM_CC), commandCode);
+ // add input commandCode
+ CryptDigestUpdateInt(&hashState, sizeof(TPM_CC), in->code);
+ // complete the hash and get the results
+ CryptHashEnd2B(&hashState, &session->u2.policyDigest.b);
+ // update commandCode value in session context
+ session->commandCode = in->code;
+ return TPM_RC_SUCCESS;
+}
+#endif // CC_PolicyCommandCode
+#include "Tpm.h"
+#include "PolicyPhysicalPresence_fp.h"
+#if CC_PolicyPhysicalPresence // Conditional expansion of this file
+TPM_RC
+TPM2_PolicyPhysicalPresence(
+ PolicyPhysicalPresence_In *in // IN: input parameter list
+ )
+{
+ SESSION *session;
+ TPM_CC commandCode = TPM_CC_PolicyPhysicalPresence;
+ HASH_STATE hashState;
+ // Internal Data Update
+ // Get pointer to the session structure
+ session = SessionGet(in->policySession);
+ // Update policy hash
+ // policyDigestnew = hash(policyDigestold || TPM_CC_PolicyPhysicalPresence)
+ // Start hash
+ CryptHashStart(&hashState, session->authHashAlg);
+ // add old digest
+ CryptDigestUpdate2B(&hashState, &session->u2.policyDigest.b);
+ // add commandCode
+ CryptDigestUpdateInt(&hashState, sizeof(TPM_CC), commandCode);
+ // complete the digest
+ CryptHashEnd2B(&hashState, &session->u2.policyDigest.b);
+ // update session attribute
+ session->attributes.isPPRequired = SET;
+ return TPM_RC_SUCCESS;
+}
+#endif // CC_PolicyPhysicalPresence
+#include "Tpm.h"
+#include "PolicyCpHash_fp.h"
+#if CC_PolicyCpHash // Conditional expansion of this file
+TPM_RC
+TPM2_PolicyCpHash(
+ PolicyCpHash_In *in // IN: input parameter list
+ )
+{
+ SESSION *session;
+ TPM_CC commandCode = TPM_CC_PolicyCpHash;
+ HASH_STATE hashState;
+ // Input Validation
+ // Get pointer to the session structure
+ session = SessionGet(in->policySession);
+ // A valid cpHash must have the same size as session hash digest
+ // NOTE: the size of the digest can't be zero because TPM_ALG_NULL
+ // can't be used for the authHashAlg.
+ if(in->cpHashA.t.size != CryptHashGetDigestSize(session->authHashAlg))
+ return TPM_RCS_SIZE + RC_PolicyCpHash_cpHashA;
+ // error if the cpHash in session context is not empty and is not the same
+ // as the input or is not a cpHash
+ if((session->u1.cpHash.t.size != 0)
+ && (!session->attributes.isCpHashDefined
+ || !MemoryEqual2B(&in->cpHashA.b, &session->u1.cpHash.b)))
+ return TPM_RC_CPHASH;
+ // Internal Data Update
+ // Update policy hash
+ // policyDigestnew = hash(policyDigestold || TPM_CC_PolicyCpHash || cpHashA)
+ // Start hash
+ CryptHashStart(&hashState, session->authHashAlg);
+ // add old digest
+ CryptDigestUpdate2B(&hashState, &session->u2.policyDigest.b);
+ // add commandCode
+ CryptDigestUpdateInt(&hashState, sizeof(TPM_CC), commandCode);
+ // add cpHashA
+ CryptDigestUpdate2B(&hashState, &in->cpHashA.b);
+ // complete the digest and get the results
+ CryptHashEnd2B(&hashState, &session->u2.policyDigest.b);
+ // update cpHash in session context
+ session->u1.cpHash = in->cpHashA;
+ session->attributes.isCpHashDefined = SET;
+ return TPM_RC_SUCCESS;
+}
+#endif // CC_PolicyCpHash
+#include "Tpm.h"
+#include "PolicyNameHash_fp.h"
+#if CC_PolicyNameHash // Conditional expansion of this file
+TPM_RC
+TPM2_PolicyNameHash(
+ PolicyNameHash_In *in // IN: input parameter list
+ )
+{
+ SESSION *session;
+ TPM_CC commandCode = TPM_CC_PolicyNameHash;
+ HASH_STATE hashState;
+ // Input Validation
+ // Get pointer to the session structure
+ session = SessionGet(in->policySession);
+ // A valid nameHash must have the same size as session hash digest
+ // Since the authHashAlg for a session cannot be TPM_ALG_NULL, the digest size
+ // is always non-zero.
+ if(in->nameHash.t.size != CryptHashGetDigestSize(session->authHashAlg))
+ return TPM_RCS_SIZE + RC_PolicyNameHash_nameHash;
+ // u1 in the policy session context cannot otherwise be occupied
+ if(session->u1.cpHash.b.size != 0
+ || session->attributes.isBound
+ || session->attributes.isCpHashDefined
+ || session->attributes.isTemplateSet)
+ return TPM_RC_CPHASH;
+ // Internal Data Update
+ // Update policy hash
+ // policyDigestnew = hash(policyDigestold || TPM_CC_PolicyNameHash || nameHash)
+ // Start hash
+ CryptHashStart(&hashState, session->authHashAlg);
+ // add old digest
+ CryptDigestUpdate2B(&hashState, &session->u2.policyDigest.b);
+ // add commandCode
+ CryptDigestUpdateInt(&hashState, sizeof(TPM_CC), commandCode);
+ // add nameHash
+ CryptDigestUpdate2B(&hashState, &in->nameHash.b);
+ // complete the digest
+ CryptHashEnd2B(&hashState, &session->u2.policyDigest.b);
+ // update nameHash in session context
+ session->u1.cpHash = in->nameHash;
+ return TPM_RC_SUCCESS;
+}
+#endif // CC_PolicyNameHash
+#include "Tpm.h"
+#include "PolicyDuplicationSelect_fp.h"
+#if CC_PolicyDuplicationSelect // Conditional expansion of this file
+TPM_RC
+TPM2_PolicyDuplicationSelect(
+ PolicyDuplicationSelect_In *in // IN: input parameter list
+ )
+{
+ SESSION *session;
+ HASH_STATE hashState;
+ TPM_CC commandCode = TPM_CC_PolicyDuplicationSelect;
+ // Input Validation
+ // Get pointer to the session structure
+ session = SessionGet(in->policySession);
+ // cpHash in session context must be empty
+ if(session->u1.cpHash.t.size != 0)
+ return TPM_RC_CPHASH;
+ // commandCode in session context must be empty
+ if(session->commandCode != 0)
+ return TPM_RC_COMMAND_CODE;
+ // Internal Data Update
+ // Update name hash
+ session->u1.cpHash.t.size = CryptHashStart(&hashState, session->authHashAlg);
+ // add objectName
+ CryptDigestUpdate2B(&hashState, &in->objectName.b);
+ // add new parent name
+ CryptDigestUpdate2B(&hashState, &in->newParentName.b);
+ // complete hash
+ CryptHashEnd2B(&hashState, &session->u1.cpHash.b);
+ // update policy hash
+ // Old policyDigest size should be the same as the new policyDigest size since
+ // they are using the same hash algorithm
+ session->u2.policyDigest.t.size
+ = CryptHashStart(&hashState, session->authHashAlg);
+ // add old policy
+ CryptDigestUpdate2B(&hashState, &session->u2.policyDigest.b);
+ // add command code
+ CryptDigestUpdateInt(&hashState, sizeof(TPM_CC), commandCode);
+ // add objectName
+ if(in->includeObject == YES)
+ CryptDigestUpdate2B(&hashState, &in->objectName.b);
+ // add new parent name
+ CryptDigestUpdate2B(&hashState, &in->newParentName.b);
+ // add includeObject
+ CryptDigestUpdateInt(&hashState, sizeof(TPMI_YES_NO), in->includeObject);
+ // complete digest
+ CryptHashEnd2B(&hashState, &session->u2.policyDigest.b);
+ // set commandCode in session context
+ session->commandCode = TPM_CC_Duplicate;
+ return TPM_RC_SUCCESS;
+}
+#endif // CC_PolicyDuplicationSelect
+#include "Tpm.h"
+#include "PolicyAuthorize_fp.h"
+#if CC_PolicyAuthorize // Conditional expansion of this file
+#include "Policy_spt_fp.h"
+TPM_RC
+TPM2_PolicyAuthorize(
+ PolicyAuthorize_In *in // IN: input parameter list
+ )
+{
+ SESSION *session;
+ TPM2B_DIGEST authHash;
+ HASH_STATE hashState;
+ TPMT_TK_VERIFIED ticket;
+ TPM_ALG_ID hashAlg;
+ UINT16 digestSize;
+ // Input Validation
+ // Get pointer to the session structure
+ session = SessionGet(in->policySession);
+ // Extract from the Name of the key, the algorithm used to compute it's Name
+ hashAlg = BYTE_ARRAY_TO_UINT16(in->keySign.t.name);
+ // 'keySign' parameter needs to use a supported hash algorithm, otherwise
+ // can't tell how large the digest should be
+ if(!CryptHashIsValidAlg(hashAlg, FALSE))
+ return TPM_RCS_HASH + RC_PolicyAuthorize_keySign;
+ digestSize = CryptHashGetDigestSize(hashAlg);
+ if(digestSize != (in->keySign.t.size - 2))
+ return TPM_RCS_SIZE + RC_PolicyAuthorize_keySign;
+ //If this is a trial policy, skip all validations
+ if(session->attributes.isTrialPolicy == CLEAR)
+ {
+ // Check that "approvedPolicy" matches the current value of the
+ // policyDigest in policy session
+ if(!MemoryEqual2B(&session->u2.policyDigest.b,
+ &in->approvedPolicy.b))
+ return TPM_RCS_VALUE + RC_PolicyAuthorize_approvedPolicy;
+ // Validate ticket TPMT_TK_VERIFIED
+ // Compute aHash. The authorizing object sign a digest
+ // aHash := hash(approvedPolicy || policyRef).
+ // Start hash
+ authHash.t.size = CryptHashStart(&hashState, hashAlg);
+ // add approvedPolicy
+ CryptDigestUpdate2B(&hashState, &in->approvedPolicy.b);
+ // add policyRef
+ CryptDigestUpdate2B(&hashState, &in->policyRef.b);
+ // complete hash
+ CryptHashEnd2B(&hashState, &authHash.b);
+ // re-compute TPMT_TK_VERIFIED
+ TicketComputeVerified(in->checkTicket.hierarchy, &authHash,
+ &in->keySign, &ticket);
+ // Compare ticket digest. If not match, return error
+ if(!MemoryEqual2B(&in->checkTicket.digest.b, &ticket.digest.b))
+ return TPM_RCS_VALUE + RC_PolicyAuthorize_checkTicket;
+ }
+ // Internal Data Update
+ // Set policyDigest to zero digest
+ PolicyDigestClear(session);
+ // Update policyDigest
+ PolicyContextUpdate(TPM_CC_PolicyAuthorize, &in->keySign, &in->policyRef,
+ NULL, 0, session);
+ return TPM_RC_SUCCESS;
+}
+#endif // CC_PolicyAuthorize
+#include "Tpm.h"
+#include "PolicyAuthValue_fp.h"
+#if CC_PolicyAuthValue // Conditional expansion of this file
+#include "Policy_spt_fp.h"
+TPM_RC
+TPM2_PolicyAuthValue(
+ PolicyAuthValue_In *in // IN: input parameter list
+ )
+{
+ SESSION *session;
+ TPM_CC commandCode = TPM_CC_PolicyAuthValue;
+ HASH_STATE hashState;
+ // Internal Data Update
+ // Get pointer to the session structure
+ session = SessionGet(in->policySession);
+ // Update policy hash
+ // policyDigestnew = hash(policyDigestold || TPM_CC_PolicyAuthValue)
+ // Start hash
+ CryptHashStart(&hashState, session->authHashAlg);
+ // add old digest
+ CryptDigestUpdate2B(&hashState, &session->u2.policyDigest.b);
+ // add commandCode
+ CryptDigestUpdateInt(&hashState, sizeof(TPM_CC), commandCode);
+ // complete the hash and get the results
+ CryptHashEnd2B(&hashState, &session->u2.policyDigest.b);
+ // update isAuthValueNeeded bit in the session context
+ session->attributes.isAuthValueNeeded = SET;
+ session->attributes.isPasswordNeeded = CLEAR;
+ return TPM_RC_SUCCESS;
+}
+#endif // CC_PolicyAuthValue
+#include "Tpm.h"
+#include "PolicyPassword_fp.h"
+#if CC_PolicyPassword // Conditional expansion of this file
+#include "Policy_spt_fp.h"
+TPM_RC
+TPM2_PolicyPassword(
+ PolicyPassword_In *in // IN: input parameter list
+ )
+{
+ SESSION *session;
+ TPM_CC commandCode = TPM_CC_PolicyAuthValue;
+ HASH_STATE hashState;
+ // Internal Data Update
+ // Get pointer to the session structure
+ session = SessionGet(in->policySession);
+ // Update policy hash
+ // policyDigestnew = hash(policyDigestold || TPM_CC_PolicyAuthValue)
+ // Start hash
+ CryptHashStart(&hashState, session->authHashAlg);
+ // add old digest
+ CryptDigestUpdate2B(&hashState, &session->u2.policyDigest.b);
+ // add commandCode
+ CryptDigestUpdateInt(&hashState, sizeof(TPM_CC), commandCode);
+ // complete the digest
+ CryptHashEnd2B(&hashState, &session->u2.policyDigest.b);
+ // Update isPasswordNeeded bit
+ session->attributes.isPasswordNeeded = SET;
+ session->attributes.isAuthValueNeeded = CLEAR;
+ return TPM_RC_SUCCESS;
+}
+#endif // CC_PolicyPassword
+#include "Tpm.h"
+#include "PolicyGetDigest_fp.h"
+#if CC_PolicyGetDigest // Conditional expansion of this file
+TPM_RC
+TPM2_PolicyGetDigest(
+ PolicyGetDigest_In *in, // IN: input parameter list
+ PolicyGetDigest_Out *out // OUT: output parameter list
+ )
+{
+ SESSION *session;
+ // Command Output
+ // Get pointer to the session structure
+ session = SessionGet(in->policySession);
+ out->policyDigest = session->u2.policyDigest;
+ return TPM_RC_SUCCESS;
+}
+#endif // CC_PolicyGetDigest
+#include "Tpm.h"
+#include "PolicyNvWritten_fp.h"
+#if CC_PolicyNvWritten // Conditional expansion of this file
+TPM_RC
+TPM2_PolicyNvWritten(
+ PolicyNvWritten_In *in // IN: input parameter list
+ )
+{
+ SESSION *session;
+ TPM_CC commandCode = TPM_CC_PolicyNvWritten;
+ HASH_STATE hashState;
+ // Input Validation
+ // Get pointer to the session structure
+ session = SessionGet(in->policySession);
+ // If already set is this a duplicate (the same setting)? If it
+ // is a conflicting setting, it is an error
+ if(session->attributes.checkNvWritten == SET)
+ {
+ if(((session->attributes.nvWrittenState == SET)
+ != (in->writtenSet == YES)))
+ return TPM_RCS_VALUE + RC_PolicyNvWritten_writtenSet;
+ }
+ // Internal Data Update
+ // Set session attributes so that the NV Index needs to be checked
+ session->attributes.checkNvWritten = SET;
+ session->attributes.nvWrittenState = (in->writtenSet == YES);
+ // Update policy hash
+ // policyDigestnew = hash(policyDigestold || TPM_CC_PolicyNvWritten
+ // || writtenSet)
+ // Start hash
+ CryptHashStart(&hashState, session->authHashAlg);
+ // add old digest
+ CryptDigestUpdate2B(&hashState, &session->u2.policyDigest.b);
+ // add commandCode
+ CryptDigestUpdateInt(&hashState, sizeof(TPM_CC), commandCode);
+ // add the byte of writtenState
+ CryptDigestUpdateInt(&hashState, sizeof(TPMI_YES_NO), in->writtenSet);
+ // complete the digest
+ CryptHashEnd2B(&hashState, &session->u2.policyDigest.b);
+ return TPM_RC_SUCCESS;
+}
+#endif // CC_PolicyNvWritten
+#include "Tpm.h"
+#include "PolicyTemplate_fp.h"
+#if CC_PolicyTemplate // Conditional expansion of this file
+TPM_RC
+TPM2_PolicyTemplate(
+ PolicyTemplate_In *in // IN: input parameter list
+ )
+{
+ SESSION *session;
+ TPM_CC commandCode = TPM_CC_PolicyTemplate;
+ HASH_STATE hashState;
+ // Input Validation
+ // Get pointer to the session structure
+ session = SessionGet(in->policySession);
+ // If the template is set, make sure that it is the same as the input value
+ if(session->attributes.isTemplateSet)
+ {
+ if(!MemoryEqual2B(&in->templateHash.b, &session->u1.cpHash.b))
+ return TPM_RCS_VALUE + RC_PolicyTemplate_templateHash;
+ }
+ // error if cpHash contains something that is not a template
+ else if(session->u1.templateHash.t.size != 0)
+ return TPM_RC_CPHASH;
+ // A valid templateHash must have the same size as session hash digest
+ if(in->templateHash.t.size != CryptHashGetDigestSize(session->authHashAlg))
+ return TPM_RCS_SIZE + RC_PolicyTemplate_templateHash;
+ // Internal Data Update
+ // Update policy hash
+ // policyDigestnew = hash(policyDigestold || TPM_CC_PolicyCpHash
+ // || cpHashA.buffer)
+ // Start hash
+ CryptHashStart(&hashState, session->authHashAlg);
+ // add old digest
+ CryptDigestUpdate2B(&hashState, &session->u2.policyDigest.b);
+ // add commandCode
+ CryptDigestUpdateInt(&hashState, sizeof(TPM_CC), commandCode);
+ // add cpHashA
+ CryptDigestUpdate2B(&hashState, &in->templateHash.b);
+ // complete the digest and get the results
+ CryptHashEnd2B(&hashState, &session->u2.policyDigest.b);
+ // update cpHash in session context
+ session->u1.templateHash = in->templateHash;
+ session->attributes.isTemplateSet = SET;
+ return TPM_RC_SUCCESS;
+}
+#endif // CC_PolicyTemplateHash
+#include "Tpm.h"
+#if CC_PolicyAuthorizeNV // Conditional expansion of this file
+#include "PolicyAuthorizeNV_fp.h"
+#include "Policy_spt_fp.h"
+TPM_RC
+TPM2_PolicyAuthorizeNV(
+ PolicyAuthorizeNV_In *in
+ )
+{
+ SESSION *session;
+ TPM_RC result;
+ NV_REF locator;
+ NV_INDEX *nvIndex = NvGetIndexInfo(in->nvIndex, &locator);
+ TPM2B_NAME name;
+ TPMT_HA policyInNv;
+ BYTE nvTemp[sizeof(TPMT_HA)];
+ BYTE *buffer = nvTemp;
+ INT32 size;
+ // Input Validation
+ // Get pointer to the session structure
+ session = SessionGet(in->policySession);
+ // Skip checks if this is a trial policy
+ if(!session->attributes.isTrialPolicy)
+ {
+ // Check the authorizations for reading
+ // Common read access checks. NvReadAccessChecks() returns
+ // TPM_RC_NV_AUTHORIZATION, TPM_RC_NV_LOCKED, or TPM_RC_NV_UNINITIALIZED
+ // error may be returned at this point
+ result = NvReadAccessChecks(in->authHandle, in->nvIndex,
+ nvIndex->publicArea.attributes);
+ if(result != TPM_RC_SUCCESS)
+ return result;
+ // Read the contents of the index into a temp buffer
+ size = MIN(nvIndex->publicArea.dataSize, sizeof(TPMT_HA));
+ NvGetIndexData(nvIndex, locator, 0, (UINT16)size, nvTemp);
+ // Unmarshal the contents of the buffer into the internal format of a
+ // TPMT_HA so that the hash and digest elements can be accessed from the
+ // structure rather than the byte array that is in the Index (written by
+ // user of the Index).
+ result = TPMT_HA_Unmarshal(&policyInNv, &buffer, &size, FALSE);
+ if(result != TPM_RC_SUCCESS)
+ return result;
+ // Verify that the hash is the same
+ if(policyInNv.hashAlg != session->authHashAlg)
+ return TPM_RC_HASH;
+ // See if the contents of the digest in the Index matches the value
+ // in the policy
+ if(!MemoryEqual(&policyInNv.digest, &session->u2.policyDigest.t.buffer,
+ session->u2.policyDigest.t.size))
+ return TPM_RC_VALUE;
+ }
+ // Internal Data Update
+ // Set policyDigest to zero digest
+ PolicyDigestClear(session);
+ // Update policyDigest
+ PolicyContextUpdate(TPM_CC_PolicyAuthorizeNV, EntityGetName(in->nvIndex, &name),
+ NULL, NULL, 0, session);
+ return TPM_RC_SUCCESS;
+}
+#endif // CC_PolicyAuthorizeNV
diff --git a/src/tpm2/ECC_Parameters_fp.h b/src/tpm2/ECC_Parameters_fp.h
new file mode 100644
index 0000000..75f9cdf
--- /dev/null
+++ b/src/tpm2/ECC_Parameters_fp.h
@@ -0,0 +1,84 @@
+/********************************************************************************/
+/* */
+/* */
+/* Written by Ken Goldman */
+/* IBM Thomas J. Watson Research Center */
+/* $Id: ECC_Parameters_fp.h 809 2016-11-16 18:31:54Z kgoldman $ */
+/* */
+/* Licenses and Notices */
+/* */
+/* 1. Copyright Licenses: */
+/* */
+/* - Trusted Computing Group (TCG) grants to the user of the source code in */
+/* this specification (the "Source Code") a worldwide, irrevocable, */
+/* nonexclusive, royalty free, copyright license to reproduce, create */
+/* derivative works, distribute, display and perform the Source Code and */
+/* derivative works thereof, and to grant others the rights granted herein. */
+/* */
+/* - The TCG grants to the user of the other parts of the specification */
+/* (other than the Source Code) the rights to reproduce, distribute, */
+/* display, and perform the specification solely for the purpose of */
+/* developing products based on such documents. */
+/* */
+/* 2. Source Code Distribution Conditions: */
+/* */
+/* - Redistributions of Source Code must retain the above copyright licenses, */
+/* this list of conditions and the following disclaimers. */
+/* */
+/* - Redistributions in binary form must reproduce the above copyright */
+/* licenses, this list of conditions and the following disclaimers in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* 3. Disclaimers: */
+/* */
+/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
+/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
+/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
+/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
+/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
+/* information on specification licensing rights available through TCG */
+/* membership agreements. */
+/* */
+/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
+/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
+/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
+/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
+/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
+/* */
+/* - Without limitation, TCG and its members and licensors disclaim all */
+/* liability, including liability for infringement of any proprietary */
+/* rights, relating to use of information in this specification and to the */
+/* implementation of this specification, and TCG disclaims all liability for */
+/* cost of procurement of substitute goods or services, lost profits, loss */
+/* of use, loss of data or any incidental, consequential, direct, indirect, */
+/* or special damages, whether under contract, tort, warranty or otherwise, */
+/* arising in any way out of use or reliance upon this specification or any */
+/* information herein. */
+/* */
+/* (c) Copyright IBM Corp. and others, 2012-2015 */
+/* */
+/********************************************************************************/
+
+/* rev 119 */
+
+#ifndef ECC_PARAMETERS_FP_H
+#define ECC_PARAMETERS_FP_H
+
+typedef struct {
+ TPMI_ECC_CURVE curveID;
+} ECC_Parameters_In;
+
+#define RC_ECC_Parameters_curveID (TPM_RC_P + TPM_RC_1)
+
+typedef struct {
+ TPMS_ALGORITHM_DETAIL_ECC parameters;
+} ECC_Parameters_Out;
+
+TPM_RC
+TPM2_ECC_Parameters(
+ ECC_Parameters_In *in, // IN: input parameter list
+ ECC_Parameters_Out *out // OUT: output parameter list
+ );
+
+
+#endif
diff --git a/src/tpm2/ECDH_KeyGen_fp.h b/src/tpm2/ECDH_KeyGen_fp.h
new file mode 100644
index 0000000..85f16f5
--- /dev/null
+++ b/src/tpm2/ECDH_KeyGen_fp.h
@@ -0,0 +1,85 @@
+/********************************************************************************/
+/* */
+/* */
+/* Written by Ken Goldman */
+/* IBM Thomas J. Watson Research Center */
+/* $Id: ECDH_KeyGen_fp.h 809 2016-11-16 18:31:54Z kgoldman $ */
+/* */
+/* Licenses and Notices */
+/* */
+/* 1. Copyright Licenses: */
+/* */
+/* - Trusted Computing Group (TCG) grants to the user of the source code in */
+/* this specification (the "Source Code") a worldwide, irrevocable, */
+/* nonexclusive, royalty free, copyright license to reproduce, create */
+/* derivative works, distribute, display and perform the Source Code and */
+/* derivative works thereof, and to grant others the rights granted herein. */
+/* */
+/* - The TCG grants to the user of the other parts of the specification */
+/* (other than the Source Code) the rights to reproduce, distribute, */
+/* display, and perform the specification solely for the purpose of */
+/* developing products based on such documents. */
+/* */
+/* 2. Source Code Distribution Conditions: */
+/* */
+/* - Redistributions of Source Code must retain the above copyright licenses, */
+/* this list of conditions and the following disclaimers. */
+/* */
+/* - Redistributions in binary form must reproduce the above copyright */
+/* licenses, this list of conditions and the following disclaimers in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* 3. Disclaimers: */
+/* */
+/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
+/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
+/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
+/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
+/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
+/* information on specification licensing rights available through TCG */
+/* membership agreements. */
+/* */
+/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
+/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
+/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
+/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
+/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
+/* */
+/* - Without limitation, TCG and its members and licensors disclaim all */
+/* liability, including liability for infringement of any proprietary */
+/* rights, relating to use of information in this specification and to the */
+/* implementation of this specification, and TCG disclaims all liability for */
+/* cost of procurement of substitute goods or services, lost profits, loss */
+/* of use, loss of data or any incidental, consequential, direct, indirect, */
+/* or special damages, whether under contract, tort, warranty or otherwise, */
+/* arising in any way out of use or reliance upon this specification or any */
+/* information herein. */
+/* */
+/* (c) Copyright IBM Corp. and others, 2012-2015 */
+/* */
+/********************************************************************************/
+
+/* rev 119 */
+
+#ifndef ECDH_KEYGEN_FP_H
+#define ECDH_KEYGEN_FP_H
+
+typedef struct {
+ TPMI_DH_OBJECT keyHandle;
+} ECDH_KeyGen_In;
+
+#define RC_ECDH_KeyGen_keyHandle (TPM_RC_H + TPM_RC_1)
+
+typedef struct {
+ TPM2B_ECC_POINT zPoint;
+ TPM2B_ECC_POINT pubPoint;
+} ECDH_KeyGen_Out;
+
+TPM_RC
+TPM2_ECDH_KeyGen(
+ ECDH_KeyGen_In *in, // IN: input parameter list
+ ECDH_KeyGen_Out *out // OUT: output parameter list
+ );
+
+
+#endif
diff --git a/src/tpm2/ECDH_ZGen_fp.h b/src/tpm2/ECDH_ZGen_fp.h
new file mode 100644
index 0000000..5cc5b71
--- /dev/null
+++ b/src/tpm2/ECDH_ZGen_fp.h
@@ -0,0 +1,86 @@
+/********************************************************************************/
+/* */
+/* */
+/* Written by Ken Goldman */
+/* IBM Thomas J. Watson Research Center */
+/* $Id: ECDH_ZGen_fp.h 809 2016-11-16 18:31:54Z kgoldman $ */
+/* */
+/* Licenses and Notices */
+/* */
+/* 1. Copyright Licenses: */
+/* */
+/* - Trusted Computing Group (TCG) grants to the user of the source code in */
+/* this specification (the "Source Code") a worldwide, irrevocable, */
+/* nonexclusive, royalty free, copyright license to reproduce, create */
+/* derivative works, distribute, display and perform the Source Code and */
+/* derivative works thereof, and to grant others the rights granted herein. */
+/* */
+/* - The TCG grants to the user of the other parts of the specification */
+/* (other than the Source Code) the rights to reproduce, distribute, */
+/* display, and perform the specification solely for the purpose of */
+/* developing products based on such documents. */
+/* */
+/* 2. Source Code Distribution Conditions: */
+/* */
+/* - Redistributions of Source Code must retain the above copyright licenses, */
+/* this list of conditions and the following disclaimers. */
+/* */
+/* - Redistributions in binary form must reproduce the above copyright */
+/* licenses, this list of conditions and the following disclaimers in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* 3. Disclaimers: */
+/* */
+/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
+/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
+/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
+/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
+/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
+/* information on specification licensing rights available through TCG */
+/* membership agreements. */
+/* */
+/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
+/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
+/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
+/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
+/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
+/* */
+/* - Without limitation, TCG and its members and licensors disclaim all */
+/* liability, including liability for infringement of any proprietary */
+/* rights, relating to use of information in this specification and to the */
+/* implementation of this specification, and TCG disclaims all liability for */
+/* cost of procurement of substitute goods or services, lost profits, loss */
+/* of use, loss of data or any incidental, consequential, direct, indirect, */
+/* or special damages, whether under contract, tort, warranty or otherwise, */
+/* arising in any way out of use or reliance upon this specification or any */
+/* information herein. */
+/* */
+/* (c) Copyright IBM Corp. and others, 2012-2015 */
+/* */
+/********************************************************************************/
+
+/* rev 119 */
+
+#ifndef ECDH_ZGEN_FP_H
+#define ECDH_ZGEN_FP_H
+
+typedef struct {
+ TPMI_DH_OBJECT keyHandle;
+ TPM2B_ECC_POINT inPoint;
+} ECDH_ZGen_In;
+
+#define RC_ECDH_ZGen_keyHandle (TPM_RC_H + TPM_RC_1)
+#define RC_ECDH_ZGen_inPoint (TPM_RC_P + TPM_RC_1)
+
+typedef struct {
+ TPM2B_ECC_POINT outPoint;
+} ECDH_ZGen_Out;
+
+TPM_RC
+TPM2_ECDH_ZGen(
+ ECDH_ZGen_In *in, // IN: input parameter list
+ ECDH_ZGen_Out *out // OUT: output parameter list
+ );
+
+
+#endif
diff --git a/src/tpm2/EC_Ephemeral_fp.h b/src/tpm2/EC_Ephemeral_fp.h
new file mode 100644
index 0000000..c004767
--- /dev/null
+++ b/src/tpm2/EC_Ephemeral_fp.h
@@ -0,0 +1,84 @@
+/********************************************************************************/
+/* */
+/* */
+/* Written by Ken Goldman */
+/* IBM Thomas J. Watson Research Center */
+/* $Id: EC_Ephemeral_fp.h 1521 2019-11-15 21:00:47Z kgoldman $ */
+/* */
+/* Licenses and Notices */
+/* */
+/* 1. Copyright Licenses: */
+/* */
+/* - Trusted Computing Group (TCG) grants to the user of the source code in */
+/* this specification (the "Source Code") a worldwide, irrevocable, */
+/* nonexclusive, royalty free, copyright license to reproduce, create */
+/* derivative works, distribute, display and perform the Source Code and */
+/* derivative works thereof, and to grant others the rights granted herein. */
+/* */
+/* - The TCG grants to the user of the other parts of the specification */
+/* (other than the Source Code) the rights to reproduce, distribute, */
+/* display, and perform the specification solely for the purpose of */
+/* developing products based on such documents. */
+/* */
+/* 2. Source Code Distribution Conditions: */
+/* */
+/* - Redistributions of Source Code must retain the above copyright licenses, */
+/* this list of conditions and the following disclaimers. */
+/* */
+/* - Redistributions in binary form must reproduce the above copyright */
+/* licenses, this list of conditions and the following disclaimers in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* 3. Disclaimers: */
+/* */
+/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
+/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
+/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
+/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
+/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
+/* information on specification licensing rights available through TCG */
+/* membership agreements. */
+/* */
+/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
+/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
+/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
+/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
+/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
+/* */
+/* - Without limitation, TCG and its members and licensors disclaim all */
+/* liability, including liability for infringement of any proprietary */
+/* rights, relating to use of information in this specification and to the */
+/* implementation of this specification, and TCG disclaims all liability for */
+/* cost of procurement of substitute goods or services, lost profits, loss */
+/* of use, loss of data or any incidental, consequential, direct, indirect, */
+/* or special damages, whether under contract, tort, warranty or otherwise, */
+/* arising in any way out of use or reliance upon this specification or any */
+/* information herein. */
+/* */
+/* (c) Copyright IBM Corp. and others, 2012-2015 */
+/* */
+/********************************************************************************/
+
+/* rev 119 */
+
+#ifndef EC_EPHEMERAL_FP_H
+#define EC_EPHEMERAL_FP_H
+
+typedef struct {
+ TPMI_ECC_CURVE curveID;
+} EC_Ephemeral_In;
+
+#define RC_EC_Ephemeral_curveID (TPM_RC_P + TPM_RC_1)
+
+typedef struct {
+ TPM2B_ECC_POINT Q;
+ UINT16 counter;
+} EC_Ephemeral_Out;
+
+TPM_RC
+TPM2_EC_Ephemeral(
+ EC_Ephemeral_In *in, // IN: input parameter list
+ EC_Ephemeral_Out *out // OUT: output parameter list
+ );
+
+#endif
diff --git a/src/tpm2/EccTestData.h b/src/tpm2/EccTestData.h
new file mode 100644
index 0000000..44ebaca
--- /dev/null
+++ b/src/tpm2/EccTestData.h
@@ -0,0 +1,155 @@
+/********************************************************************************/
+/* */
+/* Parameter data for ECC testing */
+/* Written by Ken Goldman */
+/* IBM Thomas J. Watson Research Center */
+/* $Id: EccTestData.h 1259 2018-07-10 19:11:09Z kgoldman $ */
+/* */
+/* Licenses and Notices */
+/* */
+/* 1. Copyright Licenses: */
+/* */
+/* - Trusted Computing Group (TCG) grants to the user of the source code in */
+/* this specification (the "Source Code") a worldwide, irrevocable, */
+/* nonexclusive, royalty free, copyright license to reproduce, create */
+/* derivative works, distribute, display and perform the Source Code and */
+/* derivative works thereof, and to grant others the rights granted herein. */
+/* */
+/* - The TCG grants to the user of the other parts of the specification */
+/* (other than the Source Code) the rights to reproduce, distribute, */
+/* display, and perform the specification solely for the purpose of */
+/* developing products based on such documents. */
+/* */
+/* 2. Source Code Distribution Conditions: */
+/* */
+/* - Redistributions of Source Code must retain the above copyright licenses, */
+/* this list of conditions and the following disclaimers. */
+/* */
+/* - Redistributions in binary form must reproduce the above copyright */
+/* licenses, this list of conditions and the following disclaimers in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* 3. Disclaimers: */
+/* */
+/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
+/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
+/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
+/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
+/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
+/* information on specification licensing rights available through TCG */
+/* membership agreements. */
+/* */
+/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
+/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
+/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
+/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
+/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
+/* */
+/* - Without limitation, TCG and its members and licensors disclaim all */
+/* liability, including liability for infringement of any proprietary */
+/* rights, relating to use of information in this specification and to the */
+/* implementation of this specification, and TCG disclaims all liability for */
+/* cost of procurement of substitute goods or services, lost profits, loss */
+/* of use, loss of data or any incidental, consequential, direct, indirect, */
+/* or special damages, whether under contract, tort, warranty or otherwise, */
+/* arising in any way out of use or reliance upon this specification or any */
+/* information herein. */
+/* */
+/* (c) Copyright IBM Corp. and others, 2016 - 2018 */
+/* */
+/********************************************************************************/
+
+#ifdef SELF_TEST_DATA
+TPM2B_TYPE(EC_TEST, 32);
+const TPM_ECC_CURVE c_testCurve = 00003;
+// The static key
+const TPM2B_EC_TEST c_ecTestKey_ds = {{32, {
+ 0xdf,0x8d,0xa4,0xa3,0x88,0xf6,0x76,0x96,0x89,0xfc,0x2f,0x2d,0xa1,0xb4,0x39,0x7a,
+ 0x78,0xc4,0x7f,0x71,0x8c,0xa6,0x91,0x85,0xc0,0xbf,0xf3,0x54,0x20,0x91,0x2f,0x73}}};
+const TPM2B_EC_TEST c_ecTestKey_QsX = {{32, {
+ 0x17,0xad,0x2f,0xcb,0x18,0xd4,0xdb,0x3f,0x2c,0x53,0x13,0x82,0x42,0x97,0xff,0x8d,
+ 0x99,0x50,0x16,0x02,0x35,0xa7,0x06,0xae,0x1f,0xda,0xe2,0x9c,0x12,0x77,0xc0,0xf9}}};
+const TPM2B_EC_TEST c_ecTestKey_QsY = {{32, {
+ 0xa6,0xca,0xf2,0x18,0x45,0x96,0x6e,0x58,0xe6,0x72,0x34,0x12,0x89,0xcd,0xaa,0xad,
+ 0xcb,0x68,0xb2,0x51,0xdc,0x5e,0xd1,0x6d,0x38,0x20,0x35,0x57,0xb2,0xfd,0xc7,0x52}}};
+// The ephemeral key
+const TPM2B_EC_TEST c_ecTestKey_de = {{32, {
+ 0xb6,0xb5,0x33,0x5c,0xd1,0xee,0x52,0x07,0x99,0xea,0x2e,0x8f,0x8b,0x19,0x18,0x07,
+ 0xc1,0xf8,0xdf,0xdd,0xb8,0x77,0x00,0xc7,0xd6,0x53,0x21,0xed,0x02,0x53,0xee,0xac}}};
+const TPM2B_EC_TEST c_ecTestKey_QeX = {{32, {
+ 0xa5,0x1e,0x80,0xd1,0x76,0x3e,0x8b,0x96,0xce,0xcc,0x21,0x82,0xc9,0xa2,0xa2,0xed,
+ 0x47,0x21,0x89,0x53,0x44,0xe9,0xc7,0x92,0xe7,0x31,0x48,0x38,0xe6,0xea,0x93,0x47}}};
+const TPM2B_EC_TEST c_ecTestKey_QeY = {{32, {
+ 0x30,0xe6,0x4f,0x97,0x03,0xa1,0xcb,0x3b,0x32,0x2a,0x70,0x39,0x94,0xeb,0x4e,0xea,
+ 0x55,0x88,0x81,0x3f,0xb5,0x00,0xb8,0x54,0x25,0xab,0xd4,0xda,0xfd,0x53,0x7a,0x18}}};
+// ECDH test results
+const TPM2B_EC_TEST c_ecTestEcdh_X = {{32, {
+ 0x64,0x02,0x68,0x92,0x78,0xdb,0x33,0x52,0xed,0x3b,0xfa,0x3b,0x74,0xa3,0x3d,0x2c,
+ 0x2f,0x9c,0x59,0x03,0x07,0xf8,0x22,0x90,0xed,0xe3,0x45,0xf8,0x2a,0x0a,0xd8,0x1d}}};
+const TPM2B_EC_TEST c_ecTestEcdh_Y = {{32, {
+ 0x58,0x94,0x05,0x82,0xbe,0x5f,0x33,0x02,0x25,0x90,0x3a,0x33,0x90,0x89,0xe3,0xe5,
+ 0x10,0x4a,0xbc,0x78,0xa5,0xc5,0x07,0x64,0xaf,0x91,0xbc,0xe6,0xff,0x85,0x11,0x40}}};
+TPM2B_TYPE(TEST_VALUE, 64);
+const TPM2B_TEST_VALUE c_ecTestValue = {{64, {
+ 0x78,0xd5,0xd4,0x56,0x43,0x61,0xdb,0x97,0xa4,0x32,0xc4,0x0b,0x06,0xa9,0xa8,0xa0,
+ 0xf4,0x45,0x7f,0x13,0xd8,0x13,0x81,0x0b,0xe5,0x76,0xbe,0xaa,0xb6,0x3f,0x8d,0x4d,
+ 0x23,0x65,0xcc,0xa7,0xc9,0x19,0x10,0xce,0x69,0xcb,0x0c,0xc7,0x11,0x8d,0xc3,0xff,
+ 0x62,0x69,0xa2,0xbe,0x46,0x90,0xe7,0x7d,0x81,0x77,0x94,0x65,0x1c,0x3e,0xc1,0x3e}}};
+#if ALG_SHA1_VALUE == DEFAULT_TEST_HASH
+const TPM2B_EC_TEST c_TestEcDsa_r = {{32, {
+ 0x57,0xf3,0x36,0xb7,0xec,0xc2,0xdd,0x76,0x0e,0xe2,0x81,0x21,0x49,0xc5,0x66,0x11,
+ 0x4b,0x8a,0x4f,0x17,0x62,0x82,0xcc,0x06,0xf6,0x64,0x78,0xef,0x6b,0x7c,0xf2,0x6c}}};
+const TPM2B_EC_TEST c_TestEcDsa_s = {{32, {
+ 0x1b,0xed,0x23,0x72,0x8f,0x17,0x5f,0x47,0x2e,0xa7,0x97,0x2c,0x51,0x57,0x20,0x70,
+ 0x6f,0x89,0x74,0x8a,0xa8,0xf4,0x26,0xf4,0x96,0xa1,0xb8,0x3e,0xe5,0x35,0xc5,0x94}}};
+const TPM2B_EC_TEST c_TestEcSchnorr_r = {{32,{
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1b,0x08,0x9f,0xde,
+ 0xef,0x62,0xe3,0xf1,0x14,0xcb,0x54,0x28,0x13,0x76,0xfc,0x6d,0x69,0x22,0xb5,0x3e}}};
+const TPM2B_EC_TEST c_TestEcSchnorr_s = {{32,{
+ 0xd9,0xd3,0x20,0xfb,0x4d,0x16,0xf2,0xe6,0xe2,0x45,0x07,0x45,0x1c,0x92,0x92,0x92,
+ 0xa9,0x6b,0x48,0xf8,0xd1,0x98,0x29,0x4d,0xd3,0x8f,0x56,0xf2,0xbb,0x2e,0x22,0x3b}}};
+#endif // SHA1
+#if ALG_SHA256_VALUE == DEFAULT_TEST_HASH
+const TPM2B_EC_TEST c_TestEcDsa_r = {{32, {
+ 0x04,0x7d,0x54,0xeb,0x04,0x6f,0x56,0xec,0xa2,0x6c,0x38,0x8c,0xeb,0x43,0x0b,0x71,
+ 0xf8,0xf2,0xf4,0xa5,0xe0,0x1d,0x3c,0xa2,0x39,0x31,0xe4,0xe7,0x36,0x3b,0xb5,0x5f}}};
+const TPM2B_EC_TEST c_TestEcDsa_s = {{32, {
+ 0x8f,0xd0,0x12,0xd9,0x24,0x75,0xf6,0xc4,0x3b,0xb5,0x46,0x75,0x3a,0x41,0x8d,0x80,
+ 0x23,0x99,0x38,0xd7,0xe2,0x40,0xca,0x9a,0x19,0x2a,0xfc,0x54,0x75,0xd3,0x4a,0x6e}}};
+const TPM2B_EC_TEST c_TestEcSchnorr_r = {{32, {
+ 0xf7,0xb9,0x15,0x4c,0x34,0xf6,0x41,0x19,0xa3,0xd2,0xf1,0xbd,0xf4,0x13,0x6a,0x4f,
+ 0x63,0xb8,0x4d,0xb5,0xc8,0xcd,0xde,0x85,0x95,0xa5,0x39,0x0a,0x14,0x49,0x3d,0x2f}}};
+const TPM2B_EC_TEST c_TestEcSchnorr_s = {{32,{
+ 0xfe,0xbe,0x17,0xaa,0x31,0x22,0x9f,0xd0,0xd2,0xf5,0x25,0x04,0x92,0xb0,0xaa,0x4e,
+ 0xcc,0x1c,0xb6,0x79,0xd6,0x42,0xb3,0x4e,0x3f,0xbb,0xfe,0x5f,0xd0,0xd0,0x8b,0xc3}}};
+#endif // SHA256
+#if ALG_SHA384_VALUE == DEFAULT_TEST_HASH
+const TPM2B_EC_TEST c_TestEcDsa_r = {{32, {
+ 0xf5,0x74,0x6d,0xd6,0xc6,0x56,0x86,0xbb,0xba,0x1c,0xba,0x75,0x65,0xee,0x64,0x31,
+ 0xce,0x04,0xe3,0x9f,0x24,0x3f,0xbd,0xfe,0x04,0xcd,0xab,0x7e,0xfe,0xad,0xcb,0x82}}};
+const TPM2B_EC_TEST c_TestEcDsa_s = {{32, {
+ 0xc2,0x4f,0x32,0xa1,0x06,0xc0,0x85,0x4f,0xc6,0xd8,0x31,0x66,0x91,0x9f,0x79,0xcd,
+ 0x5b,0xe5,0x7b,0x94,0xa1,0x91,0x38,0xac,0xd4,0x20,0xa2,0x10,0xf0,0xd5,0x9d,0xbf}}};
+const TPM2B_EC_TEST c_TestEcSchnorr_r = {{32, {
+ 0x1e,0xb8,0xe1,0xbf,0xa1,0x9e,0x39,0x1e,0x58,0xa2,0xe6,0x59,0xd0,0x1a,0x6a,0x03,
+ 0x6a,0x1f,0x1c,0x4f,0x36,0x19,0xc1,0xec,0x30,0xa4,0x85,0x1b,0xe9,0x74,0x35,0x66}}};
+const TPM2B_EC_TEST c_TestEcSchnorr_s = {{32,{
+ 0xb9,0xe6,0xe3,0x7e,0xcb,0xb9,0xea,0xf1,0xcc,0xf4,0x48,0x44,0x4a,0xda,0xc8,0xd7,
+ 0x87,0xb4,0xba,0x40,0xfe,0x5b,0x68,0x11,0x14,0xcf,0xa0,0x0e,0x85,0x46,0x99,0x01}}};
+#endif // SHA384
+#if ALG_SHA512_VALUE == DEFAULT_TEST_HASH
+const TPM2B_EC_TEST c_TestEcDsa_r = {{32, {
+ 0xc9,0x71,0xa6,0xb4,0xaf,0x46,0x26,0x8c,0x27,0x00,0x06,0x3b,0x00,0x0f,0xa3,0x17,
+ 0x72,0x48,0x40,0x49,0x4d,0x51,0x4f,0xa4,0xcb,0x7e,0x86,0xe9,0xe7,0xb4,0x79,0xb2}}};
+const TPM2B_EC_TEST c_TestEcDsa_s = {{32,{
+ 0x87,0xbc,0xc0,0xed,0x74,0x60,0x9e,0xfa,0x4e,0xe8,0x16,0xf3,0xf9,0x6b,0x26,0x07,
+ 0x3c,0x74,0x31,0x7e,0xf0,0x62,0x46,0xdc,0xd6,0x45,0x22,0x47,0x3e,0x0c,0xa0,0x02}}};
+const TPM2B_EC_TEST c_TestEcSchnorr_r = {{32,{
+ 0xcc,0x07,0xad,0x65,0x91,0xdd,0xa0,0x10,0x23,0xae,0x53,0xec,0xdf,0xf1,0x50,0x90,
+ 0x16,0x96,0xf4,0x45,0x09,0x73,0x9c,0x84,0xb5,0x5c,0x5f,0x08,0x51,0xcb,0x60,0x01}}};
+const TPM2B_EC_TEST c_TestEcSchnorr_s = {{32,{
+ 0x55,0x20,0x21,0x54,0xe2,0x49,0x07,0x47,0x71,0xf4,0x99,0x15,0x54,0xf3,0xab,0x14,
+ 0xdb,0x8e,0xda,0x79,0xb6,0x02,0x0e,0xe3,0x5e,0x6f,0x2c,0xb6,0x05,0xbd,0x14,0x10}}};
+#endif // SHA512
+#endif // SELF_TEST_DATA
+
diff --git a/src/tpm2/EncryptDecrypt2_fp.h b/src/tpm2/EncryptDecrypt2_fp.h
new file mode 100644
index 0000000..7696465
--- /dev/null
+++ b/src/tpm2/EncryptDecrypt2_fp.h
@@ -0,0 +1,93 @@
+/********************************************************************************/
+/* */
+/* */
+/* Written by Ken Goldman */
+/* IBM Thomas J. Watson Research Center */
+/* $Id: EncryptDecrypt2_fp.h 1047 2017-07-20 18:27:34Z kgoldman $ */
+/* */
+/* Licenses and Notices */
+/* */
+/* 1. Copyright Licenses: */
+/* */
+/* - Trusted Computing Group (TCG) grants to the user of the source code in */
+/* this specification (the "Source Code") a worldwide, irrevocable, */
+/* nonexclusive, royalty free, copyright license to reproduce, create */
+/* derivative works, distribute, display and perform the Source Code and */
+/* derivative works thereof, and to grant others the rights granted herein. */
+/* */
+/* - The TCG grants to the user of the other parts of the specification */
+/* (other than the Source Code) the rights to reproduce, distribute, */
+/* display, and perform the specification solely for the purpose of */
+/* developing products based on such documents. */
+/* */
+/* 2. Source Code Distribution Conditions: */
+/* */
+/* - Redistributions of Source Code must retain the above copyright licenses, */
+/* this list of conditions and the following disclaimers. */
+/* */
+/* - Redistributions in binary form must reproduce the above copyright */
+/* licenses, this list of conditions and the following disclaimers in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* 3. Disclaimers: */
+/* */
+/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
+/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
+/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
+/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
+/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
+/* information on specification licensing rights available through TCG */
+/* membership agreements. */
+/* */
+/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
+/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
+/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
+/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
+/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
+/* */
+/* - Without limitation, TCG and its members and licensors disclaim all */
+/* liability, including liability for infringement of any proprietary */
+/* rights, relating to use of information in this specification and to the */
+/* implementation of this specification, and TCG disclaims all liability for */
+/* cost of procurement of substitute goods or services, lost profits, loss */
+/* of use, loss of data or any incidental, consequential, direct, indirect, */
+/* or special damages, whether under contract, tort, warranty or otherwise, */
+/* arising in any way out of use or reliance upon this specification or any */
+/* information herein. */
+/* */
+/* (c) Copyright IBM Corp. and others, 2012-2015, 2016 */
+/* */
+/********************************************************************************/
+
+/* rev 146 */
+
+#ifndef ENCRYPTDECRYPT2_FP_H
+#define ENCRYPTDECRYPT2_FP_H
+
+typedef struct {
+ TPMI_DH_OBJECT keyHandle;
+ TPM2B_MAX_BUFFER inData;
+ TPMI_YES_NO decrypt;
+ TPMI_ALG_CIPHER_MODE mode;
+ TPM2B_IV ivIn;
+} EncryptDecrypt2_In;
+
+#define RC_EncryptDecrypt2_keyHandle (TPM_RC_H + TPM_RC_1)
+#define RC_EncryptDecrypt2_inData (TPM_RC_P + TPM_RC_1)
+#define RC_EncryptDecrypt2_decrypt (TPM_RC_P + TPM_RC_2)
+#define RC_EncryptDecrypt2_mode (TPM_RC_P + TPM_RC_3)
+#define RC_EncryptDecrypt2_ivIn (TPM_RC_P + TPM_RC_4)
+
+typedef struct {
+ TPM2B_MAX_BUFFER outData;
+ TPM2B_IV ivOut;
+} EncryptDecrypt2_Out;
+
+TPM_RC
+TPM2_EncryptDecrypt2(
+ EncryptDecrypt2_In *in, // IN: input parameter list
+ EncryptDecrypt2_Out *out // OUT: output parameter list
+ );
+
+
+#endif
diff --git a/src/tpm2/EncryptDecrypt_fp.h b/src/tpm2/EncryptDecrypt_fp.h
new file mode 100644
index 0000000..814acce
--- /dev/null
+++ b/src/tpm2/EncryptDecrypt_fp.h
@@ -0,0 +1,93 @@
+/********************************************************************************/
+/* */
+/* */
+/* Written by Ken Goldman */
+/* IBM Thomas J. Watson Research Center */
+/* $Id: EncryptDecrypt_fp.h 1521 2019-11-15 21:00:47Z kgoldman $ */
+/* */
+/* Licenses and Notices */
+/* */
+/* 1. Copyright Licenses: */
+/* */
+/* - Trusted Computing Group (TCG) grants to the user of the source code in */
+/* this specification (the "Source Code") a worldwide, irrevocable, */
+/* nonexclusive, royalty free, copyright license to reproduce, create */
+/* derivative works, distribute, display and perform the Source Code and */
+/* derivative works thereof, and to grant others the rights granted herein. */
+/* */
+/* - The TCG grants to the user of the other parts of the specification */
+/* (other than the Source Code) the rights to reproduce, distribute, */
+/* display, and perform the specification solely for the purpose of */
+/* developing products based on such documents. */
+/* */
+/* 2. Source Code Distribution Conditions: */
+/* */
+/* - Redistributions of Source Code must retain the above copyright licenses, */
+/* this list of conditions and the following disclaimers. */
+/* */
+/* - Redistributions in binary form must reproduce the above copyright */
+/* licenses, this list of conditions and the following disclaimers in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* 3. Disclaimers: */
+/* */
+/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
+/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
+/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
+/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
+/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
+/* information on specification licensing rights available through TCG */
+/* membership agreements. */
+/* */
+/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
+/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
+/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
+/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
+/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
+/* */
+/* - Without limitation, TCG and its members and licensors disclaim all */
+/* liability, including liability for infringement of any proprietary */
+/* rights, relating to use of information in this specification and to the */
+/* implementation of this specification, and TCG disclaims all liability for */
+/* cost of procurement of substitute goods or services, lost profits, loss */
+/* of use, loss of data or any incidental, consequential, direct, indirect, */
+/* or special damages, whether under contract, tort, warranty or otherwise, */
+/* arising in any way out of use or reliance upon this specification or any */
+/* information herein. */
+/* */
+/* (c) Copyright IBM Corp. and others, 2012-2015 */
+/* */
+/********************************************************************************/
+
+/* rev 119 */
+
+#ifndef ENCRYPTDECRYPT_FP_H
+#define ENCRYPTDECRYPT_FP_H
+
+typedef struct {
+ TPMI_DH_OBJECT keyHandle;
+ TPMI_YES_NO decrypt;
+ TPMI_ALG_CIPHER_MODE mode;
+ TPM2B_IV ivIn;
+ TPM2B_MAX_BUFFER inData;
+} EncryptDecrypt_In;
+
+#define RC_EncryptDecrypt_keyHandle (TPM_RC_H + TPM_RC_1)
+#define RC_EncryptDecrypt_decrypt (TPM_RC_P + TPM_RC_1)
+#define RC_EncryptDecrypt_mode (TPM_RC_P + TPM_RC_2)
+#define RC_EncryptDecrypt_ivIn (TPM_RC_P + TPM_RC_3)
+#define RC_EncryptDecrypt_inData (TPM_RC_P + TPM_RC_4)
+
+typedef struct {
+ TPM2B_MAX_BUFFER outData;
+ TPM2B_IV ivOut;
+} EncryptDecrypt_Out;
+
+TPM_RC
+TPM2_EncryptDecrypt(
+ EncryptDecrypt_In *in, // IN: input parameter list
+ EncryptDecrypt_Out *out // OUT: output parameter list
+ );
+
+
+#endif
diff --git a/src/tpm2/EncryptDecrypt_spt.c b/src/tpm2/EncryptDecrypt_spt.c
new file mode 100644
index 0000000..13e8cca
--- /dev/null
+++ b/src/tpm2/EncryptDecrypt_spt.c
@@ -0,0 +1,166 @@
+/********************************************************************************/
+/* */
+/* Encrypt Decrypt Support */
+/* Written by Ken Goldman */
+/* IBM Thomas J. Watson Research Center */
+/* $Id: EncryptDecrypt_spt.c 1658 2021-01-22 23:14:01Z kgoldman $ */
+/* */
+/* Licenses and Notices */
+/* */
+/* 1. Copyright Licenses: */
+/* */
+/* - Trusted Computing Group (TCG) grants to the user of the source code in */
+/* this specification (the "Source Code") a worldwide, irrevocable, */
+/* nonexclusive, royalty free, copyright license to reproduce, create */
+/* derivative works, distribute, display and perform the Source Code and */
+/* derivative works thereof, and to grant others the rights granted herein. */
+/* */
+/* - The TCG grants to the user of the other parts of the specification */
+/* (other than the Source Code) the rights to reproduce, distribute, */
+/* display, and perform the specification solely for the purpose of */
+/* developing products based on such documents. */
+/* */
+/* 2. Source Code Distribution Conditions: */
+/* */
+/* - Redistributions of Source Code must retain the above copyright licenses, */
+/* this list of conditions and the following disclaimers. */
+/* */
+/* - Redistributions in binary form must reproduce the above copyright */
+/* licenses, this list of conditions and the following disclaimers in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* 3. Disclaimers: */
+/* */
+/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
+/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
+/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
+/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
+/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
+/* information on specification licensing rights available through TCG */
+/* membership agreements. */
+/* */
+/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
+/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
+/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
+/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
+/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
+/* */
+/* - Without limitation, TCG and its members and licensors disclaim all */
+/* liability, including liability for infringement of any proprietary */
+/* rights, relating to use of information in this specification and to the */
+/* implementation of this specification, and TCG disclaims all liability for */
+/* cost of procurement of substitute goods or services, lost profits, loss */
+/* of use, loss of data or any incidental, consequential, direct, indirect, */
+/* or special damages, whether under contract, tort, warranty or otherwise, */
+/* arising in any way out of use or reliance upon this specification or any */
+/* information herein. */
+/* */
+/* (c) Copyright IBM Corp. and others, 2016 - 2021 */
+/* */
+/********************************************************************************/
+
+/* 7.7 Encrypt Decrypt Support (EncryptDecrypt_spt.c) */
+#include "Tpm.h"
+#include "EncryptDecrypt_fp.h"
+#include "EncryptDecrypt_spt_fp.h"
+#if CC_EncryptDecrypt2
+/* Error Returns Meaning */
+/* TPM_RC_KEY is not a symmetric decryption key with both public and private portions loaded */
+/* TPM_RC_SIZE IvIn size is incompatible with the block cipher mode; or inData size is not an even
+ multiple of the block size for CBC or ECB mode */
+/* TPM_RC_VALUE keyHandle is restricted and the argument mode does not match the key's mode */
+TPM_RC
+EncryptDecryptShared(
+ TPMI_DH_OBJECT keyHandleIn,
+ TPMI_YES_NO decryptIn,
+ TPMI_ALG_SYM_MODE modeIn,
+ TPM2B_IV *ivIn,
+ TPM2B_MAX_BUFFER *inData,
+ EncryptDecrypt_Out *out
+ )
+{
+ OBJECT *symKey;
+ UINT16 keySize;
+ UINT16 blockSize;
+ BYTE *key;
+ TPM_ALG_ID alg;
+ TPM_ALG_ID mode;
+ TPM_RC result;
+ BOOL OK;
+ // Input Validation
+ symKey = HandleToObject(keyHandleIn);
+ mode = symKey->publicArea.parameters.symDetail.sym.mode.sym;
+ // The input key should be a symmetric key
+ if(symKey->publicArea.type != TPM_ALG_SYMCIPHER)
+ return TPM_RCS_KEY + RC_EncryptDecrypt_keyHandle;
+ // The key must be unrestricted and allow the selected operation
+ OK = !IS_ATTRIBUTE(symKey->publicArea.objectAttributes,
+ TPMA_OBJECT, restricted);
+ if(YES == decryptIn)
+ OK = OK && IS_ATTRIBUTE(symKey->publicArea.objectAttributes,
+ TPMA_OBJECT, decrypt);
+ else
+ OK = OK && IS_ATTRIBUTE(symKey->publicArea.objectAttributes,
+ TPMA_OBJECT, sign);
+ if(!OK)
+ return TPM_RCS_ATTRIBUTES + RC_EncryptDecrypt_keyHandle;
+ // Make sure that key is an encrypt/decrypt key and not SMAC
+ if(!CryptSymModeIsValid(mode, TRUE))
+ return TPM_RCS_MODE + RC_EncryptDecrypt_keyHandle;
+ // If the key mode is not TPM_ALG_NULL...
+ // or TPM_ALG_NULL
+ if(mode != TPM_ALG_NULL)
+ {
+ // then the input mode has to be TPM_ALG_NULL or the same as the key
+ if((modeIn != TPM_ALG_NULL) && (modeIn != mode))
+ return TPM_RCS_MODE + RC_EncryptDecrypt_mode;
+ }
+ else
+ {
+ // if the key mode is null, then the input can't be null
+ if(modeIn == TPM_ALG_NULL)
+ return TPM_RCS_MODE + RC_EncryptDecrypt_mode;
+ mode = modeIn;
+ }
+ // The input iv for ECB mode should be an Empty Buffer. All the other modes
+ // should have an iv size same as encryption block size
+ keySize = symKey->publicArea.parameters.symDetail.sym.keyBits.sym;
+ alg = symKey->publicArea.parameters.symDetail.sym.algorithm;
+ blockSize = CryptGetSymmetricBlockSize(alg, keySize);
+ // reverify the algorithm. This is mainly to keep static analysis tools happy
+ if(blockSize == 0)
+ return TPM_RCS_KEY + RC_EncryptDecrypt_keyHandle;
+ if(((mode == TPM_ALG_ECB) && (ivIn->t.size != 0))
+ || ((mode != TPM_ALG_ECB) && (ivIn->t.size != blockSize)))
+ return TPM_RCS_SIZE + RC_EncryptDecrypt_ivIn;
+ // The input data size of CBC mode or ECB mode must be an even multiple of
+ // the symmetric algorithm's block size
+ if(((mode == TPM_ALG_CBC) || (mode == TPM_ALG_ECB))
+ && ((inData->t.size % blockSize) != 0))
+ return TPM_RCS_SIZE + RC_EncryptDecrypt_inData;
+ // Copy IV
+ // Note: This is copied here so that the calls to the encrypt/decrypt functions
+ // will modify the output buffer, not the input buffer
+ out->ivOut = *ivIn;
+ // Command Output
+ key = symKey->sensitive.sensitive.sym.t.buffer;
+ // For symmetric encryption, the cipher data size is the same as plain data
+ // size.
+ out->outData.t.size = inData->t.size;
+ if(decryptIn == YES)
+ {
+ // Decrypt data to output
+ result = CryptSymmetricDecrypt(out->outData.t.buffer, alg, keySize, key,
+ &(out->ivOut), mode, inData->t.size,
+ inData->t.buffer);
+ }
+ else
+ {
+ // Encrypt data to output
+ result = CryptSymmetricEncrypt(out->outData.t.buffer, alg, keySize, key,
+ &(out->ivOut), mode, inData->t.size,
+ inData->t.buffer);
+ }
+ return result;
+}
+#endif // CC_EncryptDecrypt
diff --git a/src/tpm2/EncryptDecrypt_spt_fp.h b/src/tpm2/EncryptDecrypt_spt_fp.h
new file mode 100644
index 0000000..563a435
--- /dev/null
+++ b/src/tpm2/EncryptDecrypt_spt_fp.h
@@ -0,0 +1,75 @@
+/********************************************************************************/
+/* */
+/* */
+/* Written by Ken Goldman */
+/* IBM Thomas J. Watson Research Center */
+/* $Id: EncryptDecrypt_spt_fp.h 809 2016-11-16 18:31:54Z kgoldman $ */
+/* */
+/* Licenses and Notices */
+/* */
+/* 1. Copyright Licenses: */
+/* */
+/* - Trusted Computing Group (TCG) grants to the user of the source code in */
+/* this specification (the "Source Code") a worldwide, irrevocable, */
+/* nonexclusive, royalty free, copyright license to reproduce, create */
+/* derivative works, distribute, display and perform the Source Code and */
+/* derivative works thereof, and to grant others the rights granted herein. */
+/* */
+/* - The TCG grants to the user of the other parts of the specification */
+/* (other than the Source Code) the rights to reproduce, distribute, */
+/* display, and perform the specification solely for the purpose of */
+/* developing products based on such documents. */
+/* */
+/* 2. Source Code Distribution Conditions: */
+/* */
+/* - Redistributions of Source Code must retain the above copyright licenses, */
+/* this list of conditions and the following disclaimers. */
+/* */
+/* - Redistributions in binary form must reproduce the above copyright */
+/* licenses, this list of conditions and the following disclaimers in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* 3. Disclaimers: */
+/* */
+/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
+/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
+/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
+/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
+/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
+/* information on specification licensing rights available through TCG */
+/* membership agreements. */
+/* */
+/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
+/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
+/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
+/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
+/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
+/* */
+/* - Without limitation, TCG and its members and licensors disclaim all */
+/* liability, including liability for infringement of any proprietary */
+/* rights, relating to use of information in this specification and to the */
+/* implementation of this specification, and TCG disclaims all liability for */
+/* cost of procurement of substitute goods or services, lost profits, loss */
+/* of use, loss of data or any incidental, consequential, direct, indirect, */
+/* or special damages, whether under contract, tort, warranty or otherwise, */
+/* arising in any way out of use or reliance upon this specification or any */
+/* information herein. */
+/* */
+/* (c) Copyright IBM Corp. and others, 2016 */
+/* */
+/********************************************************************************/
+
+#ifndef ENCRYPTDECRYPT_SPT_FP_H
+#define ENCRYPTDECRYPT_SPT_FP_H
+
+TPM_RC
+EncryptDecryptShared(
+ TPMI_DH_OBJECT keyHandleIn,
+ TPMI_YES_NO decryptIn,
+ TPMI_ALG_SYM_MODE modeIn,
+ TPM2B_IV *ivIn,
+ TPM2B_MAX_BUFFER *inData,
+ EncryptDecrypt_Out *out
+ );
+
+#endif
diff --git a/src/tpm2/Entity.c b/src/tpm2/Entity.c
new file mode 100644
index 0000000..6940262
--- /dev/null
+++ b/src/tpm2/Entity.c
@@ -0,0 +1,507 @@
+/********************************************************************************/
+/* */
+/* Accessing properties for handles of various types */
+/* Written by Ken Goldman */
+/* IBM Thomas J. Watson Research Center */
+/* $Id: Entity.c 1594 2020-03-26 22:15:48Z kgoldman $ */
+/* */
+/* Licenses and Notices */
+/* */
+/* 1. Copyright Licenses: */
+/* */
+/* - Trusted Computing Group (TCG) grants to the user of the source code in */
+/* this specification (the "Source Code") a worldwide, irrevocable, */
+/* nonexclusive, royalty free, copyright license to reproduce, create */
+/* derivative works, distribute, display and perform the Source Code and */
+/* derivative works thereof, and to grant others the rights granted herein. */
+/* */
+/* - The TCG grants to the user of the other parts of the specification */
+/* (other than the Source Code) the rights to reproduce, distribute, */
+/* display, and perform the specification solely for the purpose of */
+/* developing products based on such documents. */
+/* */
+/* 2. Source Code Distribution Conditions: */
+/* */
+/* - Redistributions of Source Code must retain the above copyright licenses, */
+/* this list of conditions and the following disclaimers. */
+/* */
+/* - Redistributions in binary form must reproduce the above copyright */
+/* licenses, this list of conditions and the following disclaimers in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* 3. Disclaimers: */
+/* */
+/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
+/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
+/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
+/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
+/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
+/* information on specification licensing rights available through TCG */
+/* membership agreements. */
+/* */
+/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
+/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
+/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
+/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
+/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
+/* */
+/* - Without limitation, TCG and its members and licensors disclaim all */
+/* liability, including liability for infringement of any proprietary */
+/* rights, relating to use of information in this specification and to the */
+/* implementation of this specification, and TCG disclaims all liability for */
+/* cost of procurement of substitute goods or services, lost profits, loss */
+/* of use, loss of data or any incidental, consequential, direct, indirect, */
+/* or special damages, whether under contract, tort, warranty or otherwise, */
+/* arising in any way out of use or reliance upon this specification or any */
+/* information herein. */
+/* */
+/* (c) Copyright IBM Corp. and others, 2016 - 2020 */
+/* */
+/********************************************************************************/
+
+/* 9.4 Entity.c */
+/* 9.4.1 Description */
+/* The functions in this file are used for accessing properties for handles of various
+ types. Functions in other files require handles of a specific type but the functions in this file
+ allow use of any handle type. */
+/* 9.4.2 Includes */
+#include "Tpm.h"
+/* 9.4.3 Functions */
+/* 9.4.3.1 EntityGetLoadStatus() */
+/* This function will check that all the handles access loaded entities. */
+/* Error Returns Meaning */
+/* TPM_RC_HANDLE handle type does not match */
+/* TPM_RC_REFERENCE_Hx() entity is not present */
+/* TPM_RC_HIERARCHY entity belongs to a disabled hierarchy */
+/* TPM_RC_OBJECT_MEMORY handle is an evict object but there is no space to load it to RAM */
+TPM_RC
+EntityGetLoadStatus(
+ COMMAND *command // IN/OUT: command parsing structure
+ )
+{
+ UINT32 i;
+ TPM_RC result = TPM_RC_SUCCESS;
+ //
+ for(i = 0; i < command->handleNum; i++)
+ {
+ TPM_HANDLE handle = command->handles[i];
+ switch(HandleGetType(handle))
+ {
+ // For handles associated with hierarchies, the entity is present
+ // only if the associated enable is SET.
+ case TPM_HT_PERMANENT:
+ switch(handle)
+ {
+ case TPM_RH_OWNER:
+ if(!gc.shEnable)
+ result = TPM_RC_HIERARCHY;
+ break;
+#ifdef VENDOR_PERMANENT
+ case VENDOR_PERMANENT:
+#endif
+ case TPM_RH_ENDORSEMENT:
+ if(!gc.ehEnable)
+ result = TPM_RC_HIERARCHY;
+ break;
+ case TPM_RH_PLATFORM:
+ if(!g_phEnable)
+ result = TPM_RC_HIERARCHY;
+ break;
+ // null handle, PW session handle and lockout
+ // handle are always available
+ case TPM_RH_NULL:
+ case TPM_RS_PW:
+ // Need to be careful for lockout. Lockout is always available
+ // for policy checks but not always available when authValue
+ // is being checked.
+ case TPM_RH_LOCKOUT:
+ // Rather than have #ifdefs all over the code,
+ // CASE_ACT_HANDLE is defined in ACT.h. It is 'case TPM_RH_ACT_x:'
+ // FOR_EACH_ACT(CASE_ACT_HANDLE) creates a simple
+ // case TPM_RH_ACT_x: // for each of the implemented ACT.
+ FOR_EACH_ACT(CASE_ACT_HANDLE)
+ break;
+
+ default:
+ // If the implementation has a manufacturer-specific value
+ // then test for it here. Since this implementation does
+ // not have any, this implementation returns the same failure
+ // that unmarshaling of a bad handle would produce.
+ if(((TPM_RH)handle >= TPM_RH_AUTH_00)
+ && ((TPM_RH)handle <= TPM_RH_AUTH_FF))
+ // if the implementation has a manufacturer-specific value
+ result = TPM_RC_VALUE;
+ else
+ // The handle is in the range of reserved handles but is
+ // not implemented in this TPM.
+ result = TPM_RC_VALUE;
+ break;
+ }
+ break;
+ case TPM_HT_TRANSIENT:
+ // For a transient object, check if the handle is associated
+ // with a loaded object.
+ if(!IsObjectPresent(handle))
+ result = TPM_RC_REFERENCE_H0;
+ break;
+ case TPM_HT_PERSISTENT:
+ // Persistent object
+ // Copy the persistent object to RAM and replace the handle with the
+ // handle of the assigned slot. A TPM_RC_OBJECT_MEMORY,
+ // TPM_RC_HIERARCHY or TPM_RC_REFERENCE_H0 error may be returned by
+ // ObjectLoadEvict()
+ result = ObjectLoadEvict(&command->handles[i], command->index);
+ break;
+ case TPM_HT_HMAC_SESSION:
+ // For an HMAC session, see if the session is loaded
+ // and if the session in the session slot is actually
+ // an HMAC session.
+ if(SessionIsLoaded(handle))
+ {
+ SESSION *session;
+ session = SessionGet(handle);
+ // Check if the session is a HMAC session
+ if(session->attributes.isPolicy == SET)
+ result = TPM_RC_HANDLE;
+ }
+ else
+ result = TPM_RC_REFERENCE_H0;
+ break;
+ case TPM_HT_POLICY_SESSION:
+ // For a policy session, see if the session is loaded
+ // and if the session in the session slot is actually
+ // a policy session.
+ if(SessionIsLoaded(handle))
+ {
+ SESSION *session;
+ session = SessionGet(handle);
+ // Check if the session is a policy session
+ if(session->attributes.isPolicy == CLEAR)
+ result = TPM_RC_HANDLE;
+ }
+ else
+ result = TPM_RC_REFERENCE_H0;
+ break;
+ case TPM_HT_NV_INDEX:
+ // For an NV Index, use the TPM-specific routine
+ // to search the IN Index space.
+ result = NvIndexIsAccessible(handle);
+ break;
+ case TPM_HT_PCR:
+ // Any PCR handle that is unmarshaled successfully referenced
+ // a PCR that is defined.
+ break;
+#if CC_AC_Send
+ case TPM_HT_AC:
+ // Use the TPM-specific routine to search for the AC
+ result = AcIsAccessible(handle);
+ break;
+#endif
+ default:
+ // Any other handle type is a defect in the unmarshaling code.
+ FAIL(FATAL_ERROR_INTERNAL);
+ break;
+ }
+ if(result != TPM_RC_SUCCESS)
+ {
+ if(result == TPM_RC_REFERENCE_H0)
+ result = result + i;
+ else
+ result = RcSafeAddToResult(result, TPM_RC_H + g_rcIndex[i]);
+ break;
+ }
+ }
+ return result;
+}
+/* 9.4.3.2 EntityGetAuthValue() */
+/* This function is used to access the authValue associated with a handle. This function assumes
+ that the handle references an entity that is accessible and the handle is not for a persistent
+ objects. That is EntityGetLoadStatus() should have been called. Also, the accessibility of the
+ authValue should have been verified by IsAuthValueAvailable(). */
+/* This function copies the authorization value of the entity to auth. */
+/* Return Values Meaning */
+/* count number of bytes in the authValue with zeros stripped */
+UINT16
+EntityGetAuthValue(
+ TPMI_DH_ENTITY handle, // IN: handle of entity
+ TPM2B_AUTH *auth // OUT: authValue of the entity
+ )
+{
+ TPM2B_AUTH *pAuth = NULL;
+ auth->t.size = 0;
+ switch(HandleGetType(handle))
+ {
+ case TPM_HT_PERMANENT:
+ {
+ switch(handle)
+ {
+ case TPM_RH_OWNER:
+ // ownerAuth for TPM_RH_OWNER
+ pAuth = &gp.ownerAuth;
+ break;
+ case TPM_RH_ENDORSEMENT:
+ // endorsementAuth for TPM_RH_ENDORSEMENT
+ pAuth = &gp.endorsementAuth;
+ break;
+ // The ACT use platformAuth for auth
+ FOR_EACH_ACT(CASE_ACT_HANDLE)
+ case TPM_RH_PLATFORM:
+ // platformAuth for TPM_RH_PLATFORM
+ pAuth = &gc.platformAuth;
+ break;
+ case TPM_RH_LOCKOUT:
+ // lockoutAuth for TPM_RH_LOCKOUT
+ pAuth = &gp.lockoutAuth;
+ break;
+ case TPM_RH_NULL:
+ // nullAuth for TPM_RH_NULL. Return 0 directly here
+ return 0;
+ break;
+#ifdef VENDOR_PERMANENT
+ case VENDOR_PERMANENT:
+ // vendor authorization value
+ pAuth = &g_platformUniqueDetails;
+#endif
+ default:
+ // If any other permanent handle is present it is
+ // a code defect.
+ FAIL(FATAL_ERROR_INTERNAL);
+ break;
+ }
+ break;
+ }
+ case TPM_HT_TRANSIENT:
+ // authValue for an object
+ // A persistent object would have been copied into RAM
+ // and would have an transient object handle here.
+ {
+ OBJECT *object;
+ object = HandleToObject(handle);
+ // special handling if this is a sequence object
+ if(ObjectIsSequence(object))
+ {
+ pAuth = &((HASH_OBJECT *)object)->auth;
+ }
+ else
+ {
+ // Authorization is available only when the private portion of
+ // the object is loaded. The check should be made before
+ // this function is called
+ pAssert(object->attributes.publicOnly == CLEAR);
+ pAuth = &object->sensitive.authValue;
+ }
+ }
+ break;
+ case TPM_HT_NV_INDEX:
+ // authValue for an NV index
+ {
+ NV_INDEX *nvIndex = NvGetIndexInfo(handle, NULL);
+ pAssert(nvIndex != NULL);
+ pAuth = &nvIndex->authValue;
+ }
+ break;
+ case TPM_HT_PCR:
+ // authValue for PCR
+ pAuth = PCRGetAuthValue(handle);
+ break;
+ default:
+ // If any other handle type is present here, then there is a defect
+ // in the unmarshaling code.
+ FAIL(FATAL_ERROR_INTERNAL);
+ break;
+ }
+ // Copy the authValue
+ MemoryCopy2B((TPM2B *)auth, (TPM2B *)pAuth, sizeof(auth->t.buffer));
+ MemoryRemoveTrailingZeros(auth);
+ return auth->t.size;
+}
+/* 9.4.3.3 EntityGetAuthPolicy() */
+/* This function is used to access the authPolicy associated with a handle. This function assumes
+ that the handle references an entity that is accessible and the handle is not for a persistent
+ objects. That is EntityGetLoadStatus() should have been called. Also, the accessibility of the
+ authPolicy should have been verified by IsAuthPolicyAvailable(). */
+/* This function copies the authorization policy of the entity to authPolicy. */
+/* The return value is the hash algorithm for the policy. */
+TPMI_ALG_HASH
+EntityGetAuthPolicy(
+ TPMI_DH_ENTITY handle, // IN: handle of entity
+ TPM2B_DIGEST *authPolicy // OUT: authPolicy of the entity
+ )
+{
+ TPMI_ALG_HASH hashAlg = TPM_ALG_NULL;
+ authPolicy->t.size = 0;
+ switch(HandleGetType(handle))
+ {
+ case TPM_HT_PERMANENT:
+ switch(handle)
+ {
+ case TPM_RH_OWNER:
+ // ownerPolicy for TPM_RH_OWNER
+ *authPolicy = gp.ownerPolicy;
+ hashAlg = gp.ownerAlg;
+ break;
+ case TPM_RH_ENDORSEMENT:
+ // endorsementPolicy for TPM_RH_ENDORSEMENT
+ *authPolicy = gp.endorsementPolicy;
+ hashAlg = gp.endorsementAlg;
+ break;
+ case TPM_RH_PLATFORM:
+ // platformPolicy for TPM_RH_PLATFORM
+ *authPolicy = gc.platformPolicy;
+ hashAlg = gc.platformAlg;
+ break;
+ case TPM_RH_LOCKOUT:
+ // lockoutPolicy for TPM_RH_LOCKOUT
+ *authPolicy = gp.lockoutPolicy;
+ hashAlg = gp.lockoutAlg;
+ break;
+
+#define ACT_GET_POLICY(N) \
+ case TPM_RH_ACT_##N: \
+ *authPolicy = go.ACT_##N.authPolicy; \
+ hashAlg = go.ACT_##N.hashAlg; \
+ break;
+ // Get the policy for each implemented ACT
+ FOR_EACH_ACT(ACT_GET_POLICY)
+ default:
+ hashAlg = TPM_ALG_ERROR;
+ break;
+ }
+ break;
+ case TPM_HT_TRANSIENT:
+ // authPolicy for an object
+ {
+ OBJECT *object = HandleToObject(handle);
+ *authPolicy = object->publicArea.authPolicy;
+ hashAlg = object->publicArea.nameAlg;
+ }
+ break;
+ case TPM_HT_NV_INDEX:
+ // authPolicy for a NV index
+ {
+ NV_INDEX *nvIndex = NvGetIndexInfo(handle, NULL);
+ pAssert(nvIndex != 0);
+ *authPolicy = nvIndex->publicArea.authPolicy;
+ hashAlg = nvIndex->publicArea.nameAlg;
+ }
+ break;
+ case TPM_HT_PCR:
+ // authPolicy for a PCR
+ hashAlg = PCRGetAuthPolicy(handle, authPolicy);
+ break;
+ default:
+ // If any other handle type is present it is a code defect.
+ FAIL(FATAL_ERROR_INTERNAL);
+ break;
+ }
+ return hashAlg;
+}
+/* 9.4.3.4 EntityGetName() */
+/* This function returns the Name associated with a handle. */
+TPM2B_NAME *
+EntityGetName(
+ TPMI_DH_ENTITY handle, // IN: handle of entity
+ TPM2B_NAME *name // OUT: name of entity
+ )
+{
+ switch(HandleGetType(handle))
+ {
+ case TPM_HT_TRANSIENT:
+ {
+ // Name for an object
+ OBJECT *object = HandleToObject(handle);
+ // an object with no nameAlg has no name
+ if(object->publicArea.nameAlg == TPM_ALG_NULL)
+ name->b.size = 0;
+ else
+ *name = object->name;
+ break;
+ }
+ case TPM_HT_NV_INDEX:
+ // Name for a NV index
+ NvGetNameByIndexHandle(handle, name);
+ break;
+ default:
+ // For all other types, the handle is the Name
+ name->t.size = sizeof(TPM_HANDLE);
+ UINT32_TO_BYTE_ARRAY(handle, name->t.name);
+ break;
+ }
+ return name;
+}
+/* 9.4.3.5 EntityGetHierarchy() */
+/* This function returns the hierarchy handle associated with an entity. */
+/* a) A handle that is a hierarchy handle is associated with itself. */
+/* b) An NV index belongs to TPM_RH_PLATFORM if TPMA_NV_PLATFORMCREATE, is SET, otherwise it belongs
+ to TPM_RH_OWNER */
+/* c) An object handle belongs to its hierarchy. All other handles belong to the platform
+ hierarchy. or an NV Index. */
+TPMI_RH_HIERARCHY
+EntityGetHierarchy(
+ TPMI_DH_ENTITY handle // IN :handle of entity
+ )
+{
+ TPMI_RH_HIERARCHY hierarchy = TPM_RH_NULL;
+ switch(HandleGetType(handle))
+ {
+ case TPM_HT_PERMANENT:
+ // hierarchy for a permanent handle
+ switch(handle)
+ {
+ case TPM_RH_PLATFORM:
+ case TPM_RH_ENDORSEMENT:
+ case TPM_RH_NULL:
+ hierarchy = handle;
+ break;
+ // all other permanent handles are associated with the owner
+ // hierarchy. (should only be TPM_RH_OWNER and TPM_RH_LOCKOUT)
+ default:
+ hierarchy = TPM_RH_OWNER;
+ break;
+ }
+ break;
+ case TPM_HT_NV_INDEX:
+ // hierarchy for NV index
+ {
+ NV_INDEX *nvIndex = NvGetIndexInfo(handle, NULL);
+ pAssert(nvIndex != NULL);
+ // If only the platform can delete the index, then it is
+ // considered to be in the platform hierarchy, otherwise it
+ // is in the owner hierarchy.
+ if(IS_ATTRIBUTE(nvIndex->publicArea.attributes, TPMA_NV,
+ PLATFORMCREATE))
+ hierarchy = TPM_RH_PLATFORM;
+ else
+ hierarchy = TPM_RH_OWNER;
+ }
+ break;
+ case TPM_HT_TRANSIENT:
+ // hierarchy for an object
+ {
+ OBJECT *object;
+ object = HandleToObject(handle);
+ if(object->attributes.ppsHierarchy)
+ {
+ hierarchy = TPM_RH_PLATFORM;
+ }
+ else if(object->attributes.epsHierarchy)
+ {
+ hierarchy = TPM_RH_ENDORSEMENT;
+ }
+ else if(object->attributes.spsHierarchy)
+ {
+ hierarchy = TPM_RH_OWNER;
+ }
+ }
+ break;
+ case TPM_HT_PCR:
+ hierarchy = TPM_RH_OWNER;
+ break;
+ default:
+ FAIL(FATAL_ERROR_INTERNAL);
+ break;
+ }
+ // this is unreachable but it provides a return value for the default
+ // case which makes the compiler happy
+ return hierarchy;
+}
diff --git a/src/tpm2/Entity_fp.h b/src/tpm2/Entity_fp.h
new file mode 100644
index 0000000..fd94a87
--- /dev/null
+++ b/src/tpm2/Entity_fp.h
@@ -0,0 +1,90 @@
+/********************************************************************************/
+/* */
+/* */
+/* Written by Ken Goldman */
+/* IBM Thomas J. Watson Research Center */
+/* $Id: Entity_fp.h 1490 2019-07-26 21:13:22Z kgoldman $ */
+/* */
+/* Licenses and Notices */
+/* */
+/* 1. Copyright Licenses: */
+/* */
+/* - Trusted Computing Group (TCG) grants to the user of the source code in */
+/* this specification (the "Source Code") a worldwide, irrevocable, */
+/* nonexclusive, royalty free, copyright license to reproduce, create */
+/* derivative works, distribute, display and perform the Source Code and */
+/* derivative works thereof, and to grant others the rights granted herein. */
+/* */
+/* - The TCG grants to the user of the other parts of the specification */
+/* (other than the Source Code) the rights to reproduce, distribute, */
+/* display, and perform the specification solely for the purpose of */
+/* developing products based on such documents. */
+/* */
+/* 2. Source Code Distribution Conditions: */
+/* */
+/* - Redistributions of Source Code must retain the above copyright licenses, */
+/* this list of conditions and the following disclaimers. */
+/* */
+/* - Redistributions in binary form must reproduce the above copyright */
+/* licenses, this list of conditions and the following disclaimers in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* 3. Disclaimers: */
+/* */
+/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
+/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
+/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
+/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
+/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
+/* information on specification licensing rights available through TCG */
+/* membership agreements. */
+/* */
+/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
+/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
+/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
+/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
+/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
+/* */
+/* - Without limitation, TCG and its members and licensors disclaim all */
+/* liability, including liability for infringement of any proprietary */
+/* rights, relating to use of information in this specification and to the */
+/* implementation of this specification, and TCG disclaims all liability for */
+/* cost of procurement of substitute goods or services, lost profits, loss */
+/* of use, loss of data or any incidental, consequential, direct, indirect, */
+/* or special damages, whether under contract, tort, warranty or otherwise, */
+/* arising in any way out of use or reliance upon this specification or any */
+/* information herein. */
+/* */
+/* (c) Copyright IBM Corp. and others, 2016 */
+/* */
+/********************************************************************************/
+
+#ifndef ENTITY_FP_H
+#define ENTITY_FP_H
+
+TPM_RC
+EntityGetLoadStatus(
+ COMMAND *command // IN/OUT: command parsing structure
+ );
+UINT16
+EntityGetAuthValue(
+ TPMI_DH_ENTITY handle, // IN: handle of entity
+ TPM2B_AUTH *auth // OUT: authValue of the entity
+ );
+TPMI_ALG_HASH
+EntityGetAuthPolicy(
+ TPMI_DH_ENTITY handle, // IN: handle of entity
+ TPM2B_DIGEST *authPolicy // OUT: authPolicy of the entity
+ );
+TPM2B_NAME *
+EntityGetName(
+ TPMI_DH_ENTITY handle, // IN: handle of entity
+ TPM2B_NAME *name // OUT: name of entity
+ );
+TPMI_RH_HIERARCHY
+EntityGetHierarchy(
+ TPMI_DH_ENTITY handle // IN :handle of entity
+ );
+
+
+#endif
diff --git a/src/tpm2/Entropy.c b/src/tpm2/Entropy.c
new file mode 100644
index 0000000..2c2cc18
--- /dev/null
+++ b/src/tpm2/Entropy.c
@@ -0,0 +1,184 @@
+/********************************************************************************/
+/* */
+/* Entropy */
+/* Written by Ken Goldman */
+/* IBM Thomas J. Watson Research Center */
+/* $Id: Entropy.c 1490 2019-07-26 21:13:22Z kgoldman $ */
+/* */
+/* Licenses and Notices */
+/* */
+/* 1. Copyright Licenses: */
+/* */
+/* - Trusted Computing Group (TCG) grants to the user of the source code in */
+/* this specification (the "Source Code") a worldwide, irrevocable, */
+/* nonexclusive, royalty free, copyright license to reproduce, create */
+/* derivative works, distribute, display and perform the Source Code and */
+/* derivative works thereof, and to grant others the rights granted herein. */
+/* */
+/* - The TCG grants to the user of the other parts of the specification */
+/* (other than the Source Code) the rights to reproduce, distribute, */
+/* display, and perform the specification solely for the purpose of */
+/* developing products based on such documents. */
+/* */
+/* 2. Source Code Distribution Conditions: */
+/* */
+/* - Redistributions of Source Code must retain the above copyright licenses, */
+/* this list of conditions and the following disclaimers. */
+/* */
+/* - Redistributions in binary form must reproduce the above copyright */
+/* licenses, this list of conditions and the following disclaimers in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* 3. Disclaimers: */
+/* */
+/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
+/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
+/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
+/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
+/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
+/* information on specification licensing rights available through TCG */
+/* membership agreements. */
+/* */
+/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
+/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
+/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
+/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
+/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
+/* */
+/* - Without limitation, TCG and its members and licensors disclaim all */
+/* liability, including liability for infringement of any proprietary */
+/* rights, relating to use of information in this specification and to the */
+/* implementation of this specification, and TCG disclaims all liability for */
+/* cost of procurement of substitute goods or services, lost profits, loss */
+/* of use, loss of data or any incidental, consequential, direct, indirect, */
+/* or special damages, whether under contract, tort, warranty or otherwise, */
+/* arising in any way out of use or reliance upon this specification or any */
+/* information herein. */
+/* */
+/* (c) Copyright IBM Corp. and others, 2016 - 2019 */
+/* */
+/********************************************************************************/
+
+/* C.4 Entropy.c */
+/* C.4.1. Includes and Local values*/
+#define _CRT_RAND_S
+#include <stdlib.h>
+#include <memory.h>
+
+#include <openssl/rand.h> /* libtpms added */
+
+#include <time.h>
+#include "Platform.h"
+#ifdef _MSC_VER
+#include <process.h>
+#else
+#include <unistd.h>
+#endif
+
+/* This is the last 32-bits of hardware entropy produced. We have to check to see that two
+ consecutive 32-bit values are not the same because (according to FIPS 140-2, annex C */
+/* "If each call to a RNG produces blocks of n bits (where n > 15), the first n-bit block generated
+ after power-up, initialization, or reset shall not be used, but shall be saved for comparison
+ with the next n-bit block to be generated. Each subsequent generation of an n-bit block shall be
+ compared with the previously generated block. The test shall fail if any two compared n-bit
+ blocks are equal." */
+extern uint32_t lastEntropy;
+
+/* C.4.2. Functions */
+/* C.4.2.1. rand32() */
+/* Local function to get a 32-bit random number */
+
+static uint32_t
+rand32(
+ void
+ )
+{
+ uint32_t rndNum = rand();
+#if RAND_MAX < UINT16_MAX
+ // If the maximum value of the random number is a 15-bit number, then shift it up
+ // 15 bits, get 15 more bits, shift that up 2 and then XOR in another value to get
+ // a full 32 bits.
+ rndNum = (rndNum << 15) ^ rand();
+ rndNum = (rndNum << 2) ^ rand();
+#elif RAND_MAX == UINT16_MAX
+ // If the maximum size is 16-bits, shift it and add another 16 bits
+ rndNum = (rndNum << 16) ^ rand();
+#elif RAND_MAX < UINT32_MAX
+ // If 31 bits, then shift 1 and include another random value to get the extra bit
+ rndNum = (rndNum << 1) ^ rand();
+#endif
+ return rndNum;
+}
+
+/* C.4.2.2 _plat__GetEntropy() */
+/* This function is used to get available hardware entropy. In a hardware implementation of this
+ function, there would be no call to the system to get entropy. */
+/* Return Values Meaning */
+/* < 0 hardware failure of the entropy generator, this is sticky */
+/* >= 0 the returned amount of entropy (bytes) */
+LIB_EXPORT int32_t
+_plat__GetEntropy(
+ unsigned char *entropy, // output buffer
+ uint32_t amount // amount requested
+ )
+{
+ uint32_t rndNum;
+ int32_t ret;
+ //
+ // libtpms added begin
+ if (amount > 0 && RAND_bytes(entropy, amount) == 1)
+ return amount;
+ // fall back to 'original' method
+ // libtpms added end
+
+ if(amount == 0)
+ {
+ // Seed the platform entropy source if the entropy source is software. There is
+ // no reason to put a guard macro (#if or #ifdef) around this code because this
+ // code would not be here if someone was changing it for a system with actual
+ // hardware.
+ //
+ // NOTE 1: The following command does not provide proper cryptographic entropy.
+ // Its primary purpose to make sure that different instances of the simulator,
+ // possibly started by a script on the same machine, are seeded differently.
+ // Vendors of the actual TPMs need to ensure availability of proper entropy
+ // using their platform specific means.
+ //
+ // NOTE 2: In debug builds by default the reference implementation will seed
+ // its RNG deterministically (without using any platform provided randomness).
+ // See the USE_DEBUG_RNG macro and DRBG_GetEntropy() function.
+#ifdef _MSC_VER
+ srand((unsigned)_plat__RealTime() ^ _getpid());
+#else
+ srand((unsigned)_plat__RealTime() ^ getpid());
+#endif
+ lastEntropy = rand32();
+ ret = 0;
+ }
+ else
+ {
+ rndNum = rand32();
+ if(rndNum == lastEntropy)
+ {
+ ret = -1;
+ }
+ else
+ {
+ lastEntropy = rndNum;
+ // Each process will have its random number generator initialized according
+ // to the process id and the initialization time. This is not a lot of
+ // entropy so, to add a bit more, XOR the current time value into the
+ // returned entropy value.
+ // NOTE: the reason for including the time here rather than have it in
+ // in the value assigned to lastEntropy is that rand() could be broken and
+ // using the time would in the lastEntropy value would hide this.
+ rndNum ^= (uint32_t)_plat__RealTime();
+ // Only provide entropy 32 bits at a time to test the ability
+ // of the caller to deal with partial results.
+ ret = MIN(amount, sizeof(rndNum));
+ memcpy(entropy, &rndNum, ret);
+ }
+ }
+ return ret;
+}
+
diff --git a/src/tpm2/EphemeralCommands.c b/src/tpm2/EphemeralCommands.c
new file mode 100644
index 0000000..0fe0b3a
--- /dev/null
+++ b/src/tpm2/EphemeralCommands.c
@@ -0,0 +1,190 @@
+/********************************************************************************/
+/* */
+/* Ephemeral EC Keys */
+/* Written by Ken Goldman */
+/* IBM Thomas J. Watson Research Center */
+/* $Id: EphemeralCommands.c 1490 2019-07-26 21:13:22Z kgoldman $ */
+/* */
+/* Licenses and Notices */
+/* */
+/* 1. Copyright Licenses: */
+/* */
+/* - Trusted Computing Group (TCG) grants to the user of the source code in */
+/* this specification (the "Source Code") a worldwide, irrevocable, */
+/* nonexclusive, royalty free, copyright license to reproduce, create */
+/* derivative works, distribute, display and perform the Source Code and */
+/* derivative works thereof, and to grant others the rights granted herein. */
+/* */
+/* - The TCG grants to the user of the other parts of the specification */
+/* (other than the Source Code) the rights to reproduce, distribute, */
+/* display, and perform the specification solely for the purpose of */
+/* developing products based on such documents. */
+/* */
+/* 2. Source Code Distribution Conditions: */
+/* */
+/* - Redistributions of Source Code must retain the above copyright licenses, */
+/* this list of conditions and the following disclaimers. */
+/* */
+/* - Redistributions in binary form must reproduce the above copyright */
+/* licenses, this list of conditions and the following disclaimers in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* 3. Disclaimers: */
+/* */
+/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
+/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
+/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
+/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
+/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
+/* information on specification licensing rights available through TCG */
+/* membership agreements. */
+/* */
+/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
+/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
+/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
+/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
+/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
+/* */
+/* - Without limitation, TCG and its members and licensors disclaim all */
+/* liability, including liability for infringement of any proprietary */
+/* rights, relating to use of information in this specification and to the */
+/* implementation of this specification, and TCG disclaims all liability for */
+/* cost of procurement of substitute goods or services, lost profits, loss */
+/* of use, loss of data or any incidental, consequential, direct, indirect, */
+/* or special damages, whether under contract, tort, warranty or otherwise, */
+/* arising in any way out of use or reliance upon this specification or any */
+/* information herein. */
+/* */
+/* (c) Copyright IBM Corp. and others, 2016 - 2019 */
+/* */
+/********************************************************************************/
+
+#include "Tpm.h"
+#include "Commit_fp.h"
+#if CC_Commit // Conditional expansion of this file
+TPM_RC
+TPM2_Commit(
+ Commit_In *in, // IN: input parameter list
+ Commit_Out *out // OUT: output parameter list
+ )
+{
+ OBJECT *eccKey;
+ TPMS_ECC_POINT P2;
+ TPMS_ECC_POINT *pP2 = NULL;
+ TPMS_ECC_POINT *pP1 = NULL;
+ TPM2B_ECC_PARAMETER r;
+ TPM2B_ECC_PARAMETER p;
+ TPM_RC result;
+ TPMS_ECC_PARMS *parms;
+ // Input Validation
+ eccKey = HandleToObject(in->signHandle);
+ parms = &eccKey->publicArea.parameters.eccDetail;
+ // Input key must be an ECC key
+ if(eccKey->publicArea.type != TPM_ALG_ECC)
+ return TPM_RCS_KEY + RC_Commit_signHandle;
+ // This command may only be used with a sign-only key using an anonymous
+ // scheme.
+ // NOTE: a sign + decrypt key has no scheme so it will not be an anonymous one
+ // and an unrestricted sign key might no have a signing scheme but it can't
+ // be use in Commit()
+ if(!CryptIsSchemeAnonymous(parms->scheme.scheme))
+ return TPM_RCS_SCHEME + RC_Commit_signHandle;
+ // Make sure that both parts of P2 are present if either is present
+ if((in->s2.t.size == 0) != (in->y2.t.size == 0))
+ return TPM_RCS_SIZE + RC_Commit_y2;
+ // Get prime modulus for the curve. This is needed later but getting this now
+ // allows confirmation that the curve exists.
+ if(!CryptEccGetParameter(&p, 'p', parms->curveID))
+ return TPM_RCS_KEY + RC_Commit_signHandle;
+ // Get the random value that will be used in the point multiplications
+ // Note: this does not commit the count.
+ if(!CryptGenerateR(&r, NULL, parms->curveID, &eccKey->name))
+ return TPM_RC_NO_RESULT;
+ // Set up P2 if s2 and Y2 are provided
+ if(in->s2.t.size != 0)
+ {
+ TPM2B_DIGEST x2;
+ pP2 = &P2;
+ // copy y2 for P2
+ P2.y = in->y2;
+ // Compute x2 HnameAlg(s2) mod p
+ // do the hash operation on s2 with the size of curve 'p'
+ x2.t.size = CryptHashBlock(eccKey->publicArea.nameAlg,
+ in->s2.t.size,
+ in->s2.t.buffer,
+ sizeof(x2.t.buffer),
+ x2.t.buffer);
+ // If there were error returns in the hash routine, indicate a problem
+ // with the hash algorithm selection
+ if(x2.t.size == 0)
+ return TPM_RCS_HASH + RC_Commit_signHandle;
+ // The size of the remainder will be same as the size of p. DivideB() will
+ // pad the results (leading zeros) if necessary to make the size the same
+ P2.x.t.size = p.t.size;
+ // set p2.x = hash(s2) mod p
+ if(DivideB(&x2.b, &p.b, NULL, &P2.x.b) != TPM_RC_SUCCESS)
+ return TPM_RC_NO_RESULT;
+ if(!CryptEccIsPointOnCurve(parms->curveID, pP2))
+ return TPM_RCS_ECC_POINT + RC_Commit_s2;
+ if(eccKey->attributes.publicOnly == SET)
+ return TPM_RCS_KEY + RC_Commit_signHandle;
+ }
+ // If there is a P1, make sure that it is on the curve
+ // NOTE: an "empty" point has two UINT16 values which are the size values
+ // for each of the coordinates.
+ if(in->P1.size > 4)
+ {
+ pP1 = &in->P1.point;
+ if(!CryptEccIsPointOnCurve(parms->curveID, pP1))
+ return TPM_RCS_ECC_POINT + RC_Commit_P1;
+ }
+ // Pass the parameters to CryptCommit.
+ // The work is not done in-line because it does several point multiplies
+ // with the same curve. It saves work by not having to reload the curve
+ // parameters multiple times.
+ result = CryptEccCommitCompute(&out->K.point,
+ &out->L.point,
+ &out->E.point,
+ parms->curveID,
+ pP1,
+ pP2,
+ &eccKey->sensitive.sensitive.ecc,
+ &r);
+ if(result != TPM_RC_SUCCESS)
+ return result;
+ // The commit computation was successful so complete the commit by setting
+ // the bit
+ out->counter = CryptCommit();
+ return TPM_RC_SUCCESS;
+}
+#endif // CC_Commit
+#include "Tpm.h"
+#include "EC_Ephemeral_fp.h"
+#if CC_EC_Ephemeral // Conditional expansion of this file
+TPM_RC
+TPM2_EC_Ephemeral(
+ EC_Ephemeral_In *in, // IN: input parameter list
+ EC_Ephemeral_Out *out // OUT: output parameter list
+ )
+{
+ TPM2B_ECC_PARAMETER r;
+ TPM_RC result;
+ //
+ do
+ {
+ // Get the random value that will be used in the point multiplications
+ // Note: this does not commit the count.
+ if(!CryptGenerateR(&r, NULL, in->curveID, NULL))
+ return TPM_RC_NO_RESULT;
+ // do a point multiply
+ result = CryptEccPointMultiply(&out->Q.point, in->curveID, NULL, &r,
+ NULL, NULL);
+ // commit the count value if either the r value results in the point at
+ // infinity or if the value is good. The commit on the r value for infinity
+ // is so that the r value will be skipped.
+ if((result == TPM_RC_SUCCESS) || (result == TPM_RC_NO_RESULT))
+ out->counter = CryptCommit();
+ } while(result == TPM_RC_NO_RESULT);
+ return TPM_RC_SUCCESS;
+}
+#endif // CC_EC_Ephemeral
diff --git a/src/tpm2/EventSequenceComplete_fp.h b/src/tpm2/EventSequenceComplete_fp.h
new file mode 100644
index 0000000..aa75a81
--- /dev/null
+++ b/src/tpm2/EventSequenceComplete_fp.h
@@ -0,0 +1,88 @@
+/********************************************************************************/
+/* */
+/* */
+/* Written by Ken Goldman */
+/* IBM Thomas J. Watson Research Center */
+/* $Id: EventSequenceComplete_fp.h 809 2016-11-16 18:31:54Z kgoldman $ */
+/* */
+/* Licenses and Notices */
+/* */
+/* 1. Copyright Licenses: */
+/* */
+/* - Trusted Computing Group (TCG) grants to the user of the source code in */
+/* this specification (the "Source Code") a worldwide, irrevocable, */
+/* nonexclusive, royalty free, copyright license to reproduce, create */
+/* derivative works, distribute, display and perform the Source Code and */
+/* derivative works thereof, and to grant others the rights granted herein. */
+/* */
+/* - The TCG grants to the user of the other parts of the specification */
+/* (other than the Source Code) the rights to reproduce, distribute, */
+/* display, and perform the specification solely for the purpose of */
+/* developing products based on such documents. */
+/* */
+/* 2. Source Code Distribution Conditions: */
+/* */
+/* - Redistributions of Source Code must retain the above copyright licenses, */
+/* this list of conditions and the following disclaimers. */
+/* */
+/* - Redistributions in binary form must reproduce the above copyright */
+/* licenses, this list of conditions and the following disclaimers in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* 3. Disclaimers: */
+/* */
+/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
+/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
+/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
+/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
+/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
+/* information on specification licensing rights available through TCG */
+/* membership agreements. */
+/* */
+/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
+/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
+/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
+/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
+/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
+/* */
+/* - Without limitation, TCG and its members and licensors disclaim all */
+/* liability, including liability for infringement of any proprietary */
+/* rights, relating to use of information in this specification and to the */
+/* implementation of this specification, and TCG disclaims all liability for */
+/* cost of procurement of substitute goods or services, lost profits, loss */
+/* of use, loss of data or any incidental, consequential, direct, indirect, */
+/* or special damages, whether under contract, tort, warranty or otherwise, */
+/* arising in any way out of use or reliance upon this specification or any */
+/* information herein. */
+/* */
+/* (c) Copyright IBM Corp. and others, 2012-2015 */
+/* */
+/********************************************************************************/
+
+/* rev 119 */
+
+#ifndef EVENTSEQUENCECOMPLETE_FP_H
+#define EVENTSEQUENCECOMPLETE_FP_H
+
+typedef struct {
+ TPMI_DH_PCR pcrHandle;
+ TPMI_DH_OBJECT sequenceHandle;
+ TPM2B_MAX_BUFFER buffer;
+} EventSequenceComplete_In;
+
+#define RC_EventSequenceComplete_pcrHandle (TPM_RC_H + TPM_RC_1)
+#define RC_EventSequenceComplete_sequenceHandle (TPM_RC_H + TPM_RC_2)
+#define RC_EventSequenceComplete_buffer (TPM_RC_P + TPM_RC_1)
+
+typedef struct {
+ TPML_DIGEST_VALUES results;
+} EventSequenceComplete_Out;
+
+TPM_RC
+TPM2_EventSequenceComplete(
+ EventSequenceComplete_In *in, // IN: input parameter list
+ EventSequenceComplete_Out *out // OUT: output parameter list
+ );
+
+
+#endif
diff --git a/src/tpm2/EvictControl_fp.h b/src/tpm2/EvictControl_fp.h
new file mode 100644
index 0000000..0de7abb
--- /dev/null
+++ b/src/tpm2/EvictControl_fp.h
@@ -0,0 +1,82 @@
+/********************************************************************************/
+/* */
+/* */
+/* Written by Ken Goldman */
+/* IBM Thomas J. Watson Research Center */
+/* $Id: EvictControl_fp.h 1521 2019-11-15 21:00:47Z kgoldman $ */
+/* */
+/* Licenses and Notices */
+/* */
+/* 1. Copyright Licenses: */
+/* */
+/* - Trusted Computing Group (TCG) grants to the user of the source code in */
+/* this specification (the "Source Code") a worldwide, irrevocable, */
+/* nonexclusive, royalty free, copyright license to reproduce, create */
+/* derivative works, distribute, display and perform the Source Code and */
+/* derivative works thereof, and to grant others the rights granted herein. */
+/* */
+/* - The TCG grants to the user of the other parts of the specification */
+/* (other than the Source Code) the rights to reproduce, distribute, */
+/* display, and perform the specification solely for the purpose of */
+/* developing products based on such documents. */
+/* */
+/* 2. Source Code Distribution Conditions: */
+/* */
+/* - Redistributions of Source Code must retain the above copyright licenses, */
+/* this list of conditions and the following disclaimers. */
+/* */
+/* - Redistributions in binary form must reproduce the above copyright */
+/* licenses, this list of conditions and the following disclaimers in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* 3. Disclaimers: */
+/* */
+/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
+/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
+/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
+/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
+/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
+/* information on specification licensing rights available through TCG */
+/* membership agreements. */
+/* */
+/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
+/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
+/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
+/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
+/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
+/* */
+/* - Without limitation, TCG and its members and licensors disclaim all */
+/* liability, including liability for infringement of any proprietary */
+/* rights, relating to use of information in this specification and to the */
+/* implementation of this specification, and TCG disclaims all liability for */
+/* cost of procurement of substitute goods or services, lost profits, loss */
+/* of use, loss of data or any incidental, consequential, direct, indirect, */
+/* or special damages, whether under contract, tort, warranty or otherwise, */
+/* arising in any way out of use or reliance upon this specification or any */
+/* information herein. */
+/* */
+/* (c) Copyright IBM Corp. and others, 2012-2015 */
+/* */
+/********************************************************************************/
+
+/* rev 119 */
+
+#ifndef EVICTCONTROL_FP_H
+#define EVICTCONTROL_FP_H
+
+typedef struct {
+ TPMI_RH_PROVISION auth;
+ TPMI_DH_OBJECT objectHandle;
+ TPMI_DH_PERSISTENT persistentHandle;
+} EvictControl_In;
+
+#define RC_EvictControl_auth (TPM_RC_H + TPM_RC_1)
+#define RC_EvictControl_objectHandle (TPM_RC_H + TPM_RC_2)
+#define RC_EvictControl_persistentHandle (TPM_RC_P + TPM_RC_1)
+
+TPM_RC
+TPM2_EvictControl(
+ EvictControl_In *in // IN: input parameter list
+ );
+
+#endif
diff --git a/src/tpm2/ExecCommand.c b/src/tpm2/ExecCommand.c
new file mode 100644
index 0000000..f21934b
--- /dev/null
+++ b/src/tpm2/ExecCommand.c
@@ -0,0 +1,317 @@
+/********************************************************************************/
+/* */
+/* ExecCommand */
+/* Written by Ken Goldman */
+/* IBM Thomas J. Watson Research Center */
+/* $Id: ExecCommand.c 1600 2020-03-30 22:08:01Z kgoldman $ */
+/* */
+/* Licenses and Notices */
+/* */
+/* 1. Copyright Licenses: */
+/* */
+/* - Trusted Computing Group (TCG) grants to the user of the source code in */
+/* this specification (the "Source Code") a worldwide, irrevocable, */
+/* nonexclusive, royalty free, copyright license to reproduce, create */
+/* derivative works, distribute, display and perform the Source Code and */
+/* derivative works thereof, and to grant others the rights granted herein. */
+/* */
+/* - The TCG grants to the user of the other parts of the specification */
+/* (other than the Source Code) the rights to reproduce, distribute, */
+/* display, and perform the specification solely for the purpose of */
+/* developing products based on such documents. */
+/* */
+/* 2. Source Code Distribution Conditions: */
+/* */
+/* - Redistributions of Source Code must retain the above copyright licenses, */
+/* this list of conditions and the following disclaimers. */
+/* */
+/* - Redistributions in binary form must reproduce the above copyright */
+/* licenses, this list of conditions and the following disclaimers in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* 3. Disclaimers: */
+/* */
+/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
+/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
+/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
+/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
+/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
+/* information on specification licensing rights available through TCG */
+/* membership agreements. */
+/* */
+/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
+/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
+/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
+/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
+/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
+/* */
+/* - Without limitation, TCG and its members and licensors disclaim all */
+/* liability, including liability for infringement of any proprietary */
+/* rights, relating to use of information in this specification and to the */
+/* implementation of this specification, and TCG disclaims all liability for */
+/* cost of procurement of substitute goods or services, lost profits, loss */
+/* of use, loss of data or any incidental, consequential, direct, indirect, */
+/* or special damages, whether under contract, tort, warranty or otherwise, */
+/* arising in any way out of use or reliance upon this specification or any */
+/* information herein. */
+/* */
+/* (c) Copyright IBM Corp. and others, 2016 - 2020 */
+/* */
+/********************************************************************************/
+
+/* 6.2 ExecCommand.c */
+/* This file contains the entry function ExecuteCommand() which provides the main control flow for
+ TPM command execution. */
+#include "Tpm.h"
+#include "ExecCommand_fp.h"
+
+#define TPM_HAVE_TPM2_DECLARATIONS
+#include "tpm_library_intern.h" // libtpms added
+
+/* Uncomment this next #include if doing static command/response buffer sizing */
+// #include "CommandResponseSizes_fp.h"
+// The function performs the following steps.
+// a) Parses the command header from input buffer.
+// b) Calls ParseHandleBuffer() to parse the handle area of the command.
+// c) Validates that each of the handles references a loaded entity.
+// d) Calls ParseSessionBuffer() () to:
+// 1) unmarshal and parse the session area;
+// 2) check the authorizations; and
+// 3) when necessary, decrypt a parameter.
+// e) Calls CommandDispatcher() to:
+// 1) unmarshal the command parameters from the command buffer;
+// 2) call the routine that performs the command actions; and
+// 3) marshal the responses into the response buffer.
+// f) If any error occurs in any of the steps above create the error response and return.
+// g) Calls BuildResponseSession() to:
+// 1) when necessary, encrypt a parameter
+// 2) build the response authorization sessions
+// 3) update the audit sessions and nonces
+// h) Calls BuildResponseHeader() to complete the construction of the response.
+
+// responseSize is set by the caller to the maximum number of bytes available in the output
+// buffer. ExecuteCommand() will adjust the value and return the number of bytes placed in
+// the buffer.
+// response is also set by the caller to indicate the buffer into which ExecuteCommand() is
+// to place the response.
+// request and response may point to the same buffer
+// NOTE: As of February, 2016, the failure processing has been moved to the platform-specific
+// code. When the TPM code encounters an unrecoverable failure, it will SET g_inFailureMode
+// and call _plat__Fail(). That function should not return but may call ExecuteCommand().
+LIB_EXPORT void
+ExecuteCommand(
+ uint32_t requestSize, // IN: command buffer size
+ unsigned char *request, // IN: command buffer
+ uint32_t *responseSize, // IN/OUT: response buffer size
+ unsigned char **response // IN/OUT: response buffer
+ )
+{
+ // Command local variables
+ UINT32 commandSize;
+ COMMAND command;
+ // Response local variables
+ UINT32 maxResponse = *responseSize;
+ TPM_RC result; // return code for the command
+ // This next function call is used in development to size the command and response
+ // buffers. The values printed are the sizes of the internal structures and
+ // not the sizes of the canonical forms of he command response structures. Also,
+ // the sizes do not include the tag, command.code, requestSize, or the authorization
+ // fields.
+ //CommandResponseSizes();
+ // Set flags for NV access state. This should happen before any other
+ // operation that may require a NV write. Note, that this needs to be done
+ // even when in failure mode. Otherwise, g_updateNV would stay SET while in
+ // Failure mode and the NV would be written on each call.
+ g_updateNV = UT_NONE;
+ g_clearOrderly = FALSE;
+ if(g_inFailureMode)
+ {
+ // Do failure mode processing
+ TpmFailureMode(requestSize, request, responseSize, response);
+ return;
+ }
+ // Query platform to get the NV state. The result state is saved internally
+ // and will be reported by NvIsAvailable(). The reference code requires that
+ // accessibility of NV does not change during the execution of a command.
+ // Specifically, if NV is available when the command execution starts and then
+ // is not available later when it is necessary to write to NV, then the TPM
+ // will go into failure mode.
+ NvCheckState();
+ // Due to the limitations of the simulation, TPM clock must be explicitly
+ // synchronized with the system clock whenever a command is received.
+ // This function call is not necessary in a hardware TPM. However, taking
+ // a snapshot of the hardware timer at the beginning of the command allows
+ // the time value to be consistent for the duration of the command execution.
+ TimeUpdateToCurrent();
+ // Any command through this function will unceremoniously end the
+ // _TPM_Hash_Data/_TPM_Hash_End sequence.
+ if(g_DRTMHandle != TPM_RH_UNASSIGNED)
+ ObjectTerminateEvent();
+ // Get command buffer size and command buffer.
+ command.parameterBuffer = request;
+ command.parameterSize = requestSize;
+ // Parse command header: tag, commandSize and command.code.
+ // First parse the tag. The unmarshaling routine will validate
+ // that it is either TPM_ST_SESSIONS or TPM_ST_NO_SESSIONS.
+ result = TPMI_ST_COMMAND_TAG_Unmarshal(&command.tag,
+ &command.parameterBuffer,
+ &command.parameterSize);
+ if(result != TPM_RC_SUCCESS)
+ goto Cleanup;
+ // Unmarshal the commandSize indicator.
+ result = UINT32_Unmarshal(&commandSize,
+ &command.parameterBuffer,
+ &command.parameterSize);
+ if(result != TPM_RC_SUCCESS)
+ goto Cleanup;
+ // On a TPM that receives bytes on a port, the number of bytes that were
+ // received on that port is requestSize it must be identical to commandSize.
+ // In addition, commandSize must not be larger than MAX_COMMAND_SIZE allowed
+ // by the implementation. The check against MAX_COMMAND_SIZE may be redundant
+ // as the input processing (the function that receives the command bytes and
+ // places them in the input buffer) would likely have the input truncated when
+ // it reaches MAX_COMMAND_SIZE, and requestSize would not equal commandSize.
+ if(commandSize != requestSize || commandSize > MAX_COMMAND_SIZE)
+ {
+ result = TPM_RC_COMMAND_SIZE;
+ goto Cleanup;
+ }
+ // Unmarshal the command code.
+ result = TPM_CC_Unmarshal(&command.code, &command.parameterBuffer,
+ &command.parameterSize);
+ if(result != TPM_RC_SUCCESS)
+ goto Cleanup;
+ // Check to see if the command is implemented.
+ command.index = CommandCodeToCommandIndex(command.code);
+ if(UNIMPLEMENTED_COMMAND_INDEX == command.index)
+ {
+ result = TPM_RC_COMMAND_CODE;
+ goto Cleanup;
+ }
+#if FIELD_UPGRADE_IMPLEMENTED == YES
+ // If the TPM is in FUM, then the only allowed command is
+ // TPM_CC_FieldUpgradeData.
+ if(IsFieldUgradeMode() && (command.code != TPM_CC_FieldUpgradeData))
+ {
+ result = TPM_RC_UPGRADE;
+ goto Cleanup;
+ }
+ else
+#endif
+ // Excepting FUM, the TPM only accepts TPM2_Startup() after
+ // _TPM_Init. After getting a TPM2_Startup(), TPM2_Startup()
+ // is no longer allowed.
+ if((!TPMIsStarted() && command.code != TPM_CC_Startup)
+ || (TPMIsStarted() && command.code == TPM_CC_Startup))
+ {
+ result = TPM_RC_INITIALIZE;
+ goto Cleanup;
+ }
+ // Start regular command process.
+ NvIndexCacheInit();
+ // Parse Handle buffer.
+ result = ParseHandleBuffer(&command);
+ if(result != TPM_RC_SUCCESS)
+ goto Cleanup;
+ // All handles in the handle area are required to reference TPM-resident
+ // entities.
+ result = EntityGetLoadStatus(&command);
+ if(result != TPM_RC_SUCCESS)
+ goto Cleanup;
+ // Authorization session handling for the command.
+ ClearCpRpHashes(&command);
+ if(command.tag == TPM_ST_SESSIONS)
+ {
+ // Find out session buffer size.
+ result = UINT32_Unmarshal((UINT32 *)&command.authSize,
+ &command.parameterBuffer,
+ &command.parameterSize);
+ if(result != TPM_RC_SUCCESS)
+ goto Cleanup;
+ // Perform sanity check on the unmarshaled value. If it is smaller than
+ // the smallest possible session or larger than the remaining size of
+ // the command, then it is an error. NOTE: This check could pass but the
+ // session size could still be wrong. That will be determined after the
+ // sessions are unmarshaled.
+ if(command.authSize < 9
+ || command.authSize > command.parameterSize)
+ {
+ result = TPM_RC_SIZE;
+ goto Cleanup;
+ }
+ command.parameterSize -= command.authSize;
+ // The actions of ParseSessionBuffer() are described in the introduction.
+ // As the sessions are parsed command.parameterBuffer is advanced so, on a
+ // successful return, command.parameterBuffer should be pointing at the
+ // first byte of the parameters.
+ result = ParseSessionBuffer(&command);
+ if(result != TPM_RC_SUCCESS)
+ goto Cleanup;
+ }
+ else
+ {
+ command.authSize = 0;
+ // The command has no authorization sessions.
+ // If the command requires authorizations, then CheckAuthNoSession() will
+ // return an error.
+ result = CheckAuthNoSession(&command);
+ if(result != TPM_RC_SUCCESS)
+ goto Cleanup;
+ }
+ // Set up the response buffer pointers. CommandDispatch will marshal the
+ // response parameters starting at the address in command.responseBuffer.
+ // *response = MemoryGetResponseBuffer(command.index);
+ // leave space for the command header
+ command.responseBuffer = *response + STD_RESPONSE_HEADER;
+ // leave space for the parameter size field if needed
+ if(command.tag == TPM_ST_SESSIONS)
+ command.responseBuffer += sizeof(UINT32);
+ if(IsHandleInResponse(command.index))
+ command.responseBuffer += sizeof(TPM_HANDLE);
+ // CommandDispatcher returns a response handle buffer and a response parameter
+ // buffer if it succeeds. It will also set the parameterSize field in the
+ // buffer if the tag is TPM_RC_SESSIONS.
+ result = CommandDispatcher(&command);
+ if(result != TPM_RC_SUCCESS)
+ goto Cleanup;
+ // Build the session area at the end of the parameter area.
+ BuildResponseSession(&command);
+ Cleanup:
+ if(g_clearOrderly == TRUE
+ && NV_IS_ORDERLY)
+ {
+#if USE_DA_USED
+ gp.orderlyState = g_daUsed ? SU_DA_USED_VALUE : SU_NONE_VALUE;
+#else
+ gp.orderlyState = SU_NONE_VALUE;
+#endif
+ NV_SYNC_PERSISTENT(orderlyState);
+ }
+ // This implementation loads an "evict" object to a transient object slot in
+ // RAM whenever an "evict" object handle is used in a command so that the
+ // access to any object is the same. These temporary objects need to be
+ // cleared from RAM whether the command succeeds or fails.
+ ObjectCleanupEvict();
+ // The parameters and sessions have been marshaled. Now tack on the header and
+ // set the sizes
+ BuildResponseHeader(&command, *response, result);
+ // Try to commit all the writes to NV if any NV write happened during this
+ // command execution. This check should be made for both succeeded and failed
+ // commands, because a failed one may trigger a NV write in DA logic as well.
+ // This is the only place in the command execution path that may call the NV
+ // commit. If the NV commit fails, the TPM should be put in failure mode.
+ if((g_updateNV != UT_NONE) && !g_inFailureMode)
+ {
+ if(g_updateNV == UT_ORDERLY)
+ NvUpdateIndexOrderlyData();
+ if(!NvCommit())
+ FAIL(FATAL_ERROR_INTERNAL);
+ g_updateNV = UT_NONE;
+ }
+ pAssert((UINT32)command.parameterSize <= maxResponse);
+ // Clear unused bits in response buffer.
+ MemorySet(*response + *responseSize, 0, maxResponse - *responseSize);
+ // as a final act, and not before, update the response size.
+ *responseSize = (UINT32)command.parameterSize;
+ return;
+}
diff --git a/src/tpm2/ExecCommand_fp.h b/src/tpm2/ExecCommand_fp.h
new file mode 100644
index 0000000..43b5dbe
--- /dev/null
+++ b/src/tpm2/ExecCommand_fp.h
@@ -0,0 +1,73 @@
+/********************************************************************************/
+/* */
+/* */
+/* Written by Ken Goldman */
+/* IBM Thomas J. Watson Research Center */
+/* $Id: ExecCommand_fp.h 1490 2019-07-26 21:13:22Z kgoldman $ */
+/* */
+/* Licenses and Notices */
+/* */
+/* 1. Copyright Licenses: */
+/* */
+/* - Trusted Computing Group (TCG) grants to the user of the source code in */
+/* this specification (the "Source Code") a worldwide, irrevocable, */
+/* nonexclusive, royalty free, copyright license to reproduce, create */
+/* derivative works, distribute, display and perform the Source Code and */
+/* derivative works thereof, and to grant others the rights granted herein. */
+/* */
+/* - The TCG grants to the user of the other parts of the specification */
+/* (other than the Source Code) the rights to reproduce, distribute, */
+/* display, and perform the specification solely for the purpose of */
+/* developing products based on such documents. */
+/* */
+/* 2. Source Code Distribution Conditions: */
+/* */
+/* - Redistributions of Source Code must retain the above copyright licenses, */
+/* this list of conditions and the following disclaimers. */
+/* */
+/* - Redistributions in binary form must reproduce the above copyright */
+/* licenses, this list of conditions and the following disclaimers in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* 3. Disclaimers: */
+/* */
+/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
+/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
+/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
+/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
+/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
+/* information on specification licensing rights available through TCG */
+/* membership agreements. */
+/* */
+/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
+/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
+/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
+/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
+/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
+/* */
+/* - Without limitation, TCG and its members and licensors disclaim all */
+/* liability, including liability for infringement of any proprietary */
+/* rights, relating to use of information in this specification and to the */
+/* implementation of this specification, and TCG disclaims all liability for */
+/* cost of procurement of substitute goods or services, lost profits, loss */
+/* of use, loss of data or any incidental, consequential, direct, indirect, */
+/* or special damages, whether under contract, tort, warranty or otherwise, */
+/* arising in any way out of use or reliance upon this specification or any */
+/* information herein. */
+/* */
+/* (c) Copyright IBM Corp. and others, 2016 */
+/* */
+/********************************************************************************/
+
+#ifndef EXECCOMMAND_FP_H
+#define EXECCOMMAND_FP_H
+
+LIB_EXPORT void
+ExecuteCommand(
+ uint32_t requestSize, // IN: command buffer size
+ unsigned char *request, // IN: command buffer
+ uint32_t *responseSize, // IN/OUT: response buffer size
+ unsigned char **response // IN/OUT: response buffer
+ );
+
+#endif
diff --git a/src/tpm2/FlushContext_fp.h b/src/tpm2/FlushContext_fp.h
new file mode 100644
index 0000000..6426e9f
--- /dev/null
+++ b/src/tpm2/FlushContext_fp.h
@@ -0,0 +1,78 @@
+/********************************************************************************/
+/* */
+/* */
+/* Written by Ken Goldman */
+/* IBM Thomas J. Watson Research Center */
+/* $Id: FlushContext_fp.h 1521 2019-11-15 21:00:47Z kgoldman $ */
+/* */
+/* Licenses and Notices */
+/* */
+/* 1. Copyright Licenses: */
+/* */
+/* - Trusted Computing Group (TCG) grants to the user of the source code in */
+/* this specification (the "Source Code") a worldwide, irrevocable, */
+/* nonexclusive, royalty free, copyright license to reproduce, create */
+/* derivative works, distribute, display and perform the Source Code and */
+/* derivative works thereof, and to grant others the rights granted herein. */
+/* */
+/* - The TCG grants to the user of the other parts of the specification */
+/* (other than the Source Code) the rights to reproduce, distribute, */
+/* display, and perform the specification solely for the purpose of */
+/* developing products based on such documents. */
+/* */
+/* 2. Source Code Distribution Conditions: */
+/* */
+/* - Redistributions of Source Code must retain the above copyright licenses, */
+/* this list of conditions and the following disclaimers. */
+/* */
+/* - Redistributions in binary form must reproduce the above copyright */
+/* licenses, this list of conditions and the following disclaimers in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* 3. Disclaimers: */
+/* */
+/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
+/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
+/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
+/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
+/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
+/* information on specification licensing rights available through TCG */
+/* membership agreements. */
+/* */
+/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
+/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
+/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
+/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
+/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
+/* */
+/* - Without limitation, TCG and its members and licensors disclaim all */
+/* liability, including liability for infringement of any proprietary */
+/* rights, relating to use of information in this specification and to the */
+/* implementation of this specification, and TCG disclaims all liability for */
+/* cost of procurement of substitute goods or services, lost profits, loss */
+/* of use, loss of data or any incidental, consequential, direct, indirect, */
+/* or special damages, whether under contract, tort, warranty or otherwise, */
+/* arising in any way out of use or reliance upon this specification or any */
+/* information herein. */
+/* */
+/* (c) Copyright IBM Corp. and others, 2012-2015 */
+/* */
+/********************************************************************************/
+
+/* rev 119 */
+
+#ifndef FLUSHCONTEXT_FP_H
+#define FLUSHCONTEXT_FP_H
+
+typedef struct {
+ TPMI_DH_CONTEXT flushHandle;
+} FlushContext_In;
+
+#define RC_FlushContext_flushHandle (TPM_RC_P + TPM_RC_1)
+
+TPM_RC
+TPM2_FlushContext(
+ FlushContext_In *in // IN: input parameter list
+ );
+
+#endif
diff --git a/src/tpm2/GetCapability_fp.h b/src/tpm2/GetCapability_fp.h
new file mode 100644
index 0000000..52b81d3
--- /dev/null
+++ b/src/tpm2/GetCapability_fp.h
@@ -0,0 +1,90 @@
+/********************************************************************************/
+/* */
+/* */
+/* Written by Ken Goldman */
+/* IBM Thomas J. Watson Research Center */
+/* $Id: GetCapability_fp.h 809 2016-11-16 18:31:54Z kgoldman $ */
+/* */
+/* Licenses and Notices */
+/* */
+/* 1. Copyright Licenses: */
+/* */
+/* - Trusted Computing Group (TCG) grants to the user of the source code in */
+/* this specification (the "Source Code") a worldwide, irrevocable, */
+/* nonexclusive, royalty free, copyright license to reproduce, create */
+/* derivative works, distribute, display and perform the Source Code and */
+/* derivative works thereof, and to grant others the rights granted herein. */
+/* */
+/* - The TCG grants to the user of the other parts of the specification */
+/* (other than the Source Code) the rights to reproduce, distribute, */
+/* display, and perform the specification solely for the purpose of */
+/* developing products based on such documents. */
+/* */
+/* 2. Source Code Distribution Conditions: */
+/* */
+/* - Redistributions of Source Code must retain the above copyright licenses, */
+/* this list of conditions and the following disclaimers. */
+/* */
+/* - Redistributions in binary form must reproduce the above copyright */
+/* licenses, this list of conditions and the following disclaimers in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* 3. Disclaimers: */
+/* */
+/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
+/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
+/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
+/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
+/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
+/* information on specification licensing rights available through TCG */
+/* membership agreements. */
+/* */
+/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
+/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
+/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
+/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
+/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
+/* */
+/* - Without limitation, TCG and its members and licensors disclaim all */
+/* liability, including liability for infringement of any proprietary */
+/* rights, relating to use of information in this specification and to the */
+/* implementation of this specification, and TCG disclaims all liability for */
+/* cost of procurement of substitute goods or services, lost profits, loss */
+/* of use, loss of data or any incidental, consequential, direct, indirect, */
+/* or special damages, whether under contract, tort, warranty or otherwise, */
+/* arising in any way out of use or reliance upon this specification or any */
+/* information herein. */
+/* */
+/* (c) Copyright IBM Corp. and others, 2012-2015 */
+/* */
+/********************************************************************************/
+
+/* rev 119 */
+
+#ifndef GETCAPABILITY_FP_H
+#define GETCAPABILITY_FP_H
+
+typedef struct {
+ TPM_CAP capability;
+ UINT32 property;
+ UINT32 propertyCount;
+} GetCapability_In;
+
+#define RC_GetCapability_capability (TPM_RC_P + TPM_RC_1)
+#define RC_GetCapability_property (TPM_RC_P + TPM_RC_2)
+#define RC_GetCapability_propertyCount (TPM_RC_P + TPM_RC_3)
+
+typedef struct {
+ TPMI_YES_NO moreData;
+ TPMS_CAPABILITY_DATA capabilityData;
+} GetCapability_Out;
+
+
+TPM_RC
+TPM2_GetCapability(
+ GetCapability_In *in, // IN: input parameter list
+ GetCapability_Out *out // OUT: output parameter list
+ );
+
+
+#endif
diff --git a/src/tpm2/GetCommandAuditDigest_fp.h b/src/tpm2/GetCommandAuditDigest_fp.h
new file mode 100644
index 0000000..e3467ca
--- /dev/null
+++ b/src/tpm2/GetCommandAuditDigest_fp.h
@@ -0,0 +1,91 @@
+/********************************************************************************/
+/* */
+/* */
+/* Written by Ken Goldman */
+/* IBM Thomas J. Watson Research Center */
+/* $Id: GetCommandAuditDigest_fp.h 809 2016-11-16 18:31:54Z kgoldman $ */
+/* */
+/* Licenses and Notices */
+/* */
+/* 1. Copyright Licenses: */
+/* */
+/* - Trusted Computing Group (TCG) grants to the user of the source code in */
+/* this specification (the "Source Code") a worldwide, irrevocable, */
+/* nonexclusive, royalty free, copyright license to reproduce, create */
+/* derivative works, distribute, display and perform the Source Code and */
+/* derivative works thereof, and to grant others the rights granted herein. */
+/* */
+/* - The TCG grants to the user of the other parts of the specification */
+/* (other than the Source Code) the rights to reproduce, distribute, */
+/* display, and perform the specification solely for the purpose of */
+/* developing products based on such documents. */
+/* */
+/* 2. Source Code Distribution Conditions: */
+/* */
+/* - Redistributions of Source Code must retain the above copyright licenses, */
+/* this list of conditions and the following disclaimers. */
+/* */
+/* - Redistributions in binary form must reproduce the above copyright */
+/* licenses, this list of conditions and the following disclaimers in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* 3. Disclaimers: */
+/* */
+/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
+/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
+/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
+/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
+/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
+/* information on specification licensing rights available through TCG */
+/* membership agreements. */
+/* */
+/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
+/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
+/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
+/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
+/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
+/* */
+/* - Without limitation, TCG and its members and licensors disclaim all */
+/* liability, including liability for infringement of any proprietary */
+/* rights, relating to use of information in this specification and to the */
+/* implementation of this specification, and TCG disclaims all liability for */
+/* cost of procurement of substitute goods or services, lost profits, loss */
+/* of use, loss of data or any incidental, consequential, direct, indirect, */
+/* or special damages, whether under contract, tort, warranty or otherwise, */
+/* arising in any way out of use or reliance upon this specification or any */
+/* information herein. */
+/* */
+/* (c) Copyright IBM Corp. and others, 2012-2015 */
+/* */
+/********************************************************************************/
+
+/* rev 119 */
+
+#ifndef GETCOMMANDAUDITDIGEST_FP_H
+#define GETCOMMANDAUDITDIGEST_FP_H
+
+typedef struct {
+ TPMI_RH_ENDORSEMENT privacyHandle;
+ TPMI_DH_OBJECT signHandle;
+ TPM2B_DATA qualifyingData;
+ TPMT_SIG_SCHEME inScheme;
+} GetCommandAuditDigest_In;
+
+#define RC_GetCommandAuditDigest_privacyHandle (TPM_RC_H + TPM_RC_1)
+#define RC_GetCommandAuditDigest_signHandle (TPM_RC_H + TPM_RC_2)
+#define RC_GetCommandAuditDigest_qualifyingData (TPM_RC_P + TPM_RC_1)
+#define RC_GetCommandAuditDigest_inScheme (TPM_RC_P + TPM_RC_2)
+
+typedef struct {
+ TPM2B_ATTEST auditInfo;
+ TPMT_SIGNATURE signature;
+} GetCommandAuditDigest_Out;
+
+TPM_RC
+TPM2_GetCommandAuditDigest(
+ GetCommandAuditDigest_In *in, // IN: input parameter list
+ GetCommandAuditDigest_Out *out // OUT: output parameter list
+ );
+
+
+#endif
diff --git a/src/tpm2/GetRandom_fp.h b/src/tpm2/GetRandom_fp.h
new file mode 100644
index 0000000..27326d0
--- /dev/null
+++ b/src/tpm2/GetRandom_fp.h
@@ -0,0 +1,84 @@
+/********************************************************************************/
+/* */
+/* */
+/* Written by Ken Goldman */
+/* IBM Thomas J. Watson Research Center */
+/* $Id: GetRandom_fp.h 809 2016-11-16 18:31:54Z kgoldman $ */
+/* */
+/* Licenses and Notices */
+/* */
+/* 1. Copyright Licenses: */
+/* */
+/* - Trusted Computing Group (TCG) grants to the user of the source code in */
+/* this specification (the "Source Code") a worldwide, irrevocable, */
+/* nonexclusive, royalty free, copyright license to reproduce, create */
+/* derivative works, distribute, display and perform the Source Code and */
+/* derivative works thereof, and to grant others the rights granted herein. */
+/* */
+/* - The TCG grants to the user of the other parts of the specification */
+/* (other than the Source Code) the rights to reproduce, distribute, */
+/* display, and perform the specification solely for the purpose of */
+/* developing products based on such documents. */
+/* */
+/* 2. Source Code Distribution Conditions: */
+/* */
+/* - Redistributions of Source Code must retain the above copyright licenses, */
+/* this list of conditions and the following disclaimers. */
+/* */
+/* - Redistributions in binary form must reproduce the above copyright */
+/* licenses, this list of conditions and the following disclaimers in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* 3. Disclaimers: */
+/* */
+/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
+/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
+/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
+/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
+/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
+/* information on specification licensing rights available through TCG */
+/* membership agreements. */
+/* */
+/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
+/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
+/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
+/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
+/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
+/* */
+/* - Without limitation, TCG and its members and licensors disclaim all */
+/* liability, including liability for infringement of any proprietary */
+/* rights, relating to use of information in this specification and to the */
+/* implementation of this specification, and TCG disclaims all liability for */
+/* cost of procurement of substitute goods or services, lost profits, loss */
+/* of use, loss of data or any incidental, consequential, direct, indirect, */
+/* or special damages, whether under contract, tort, warranty or otherwise, */
+/* arising in any way out of use or reliance upon this specification or any */
+/* information herein. */
+/* */
+/* (c) Copyright IBM Corp. and others, 2012-2015 */
+/* */
+/********************************************************************************/
+
+/* rev 119 */
+
+#ifndef GETRANDOM_FP_H
+#define GETRANDOM_FP_H
+
+typedef struct {
+ UINT16 bytesRequested;
+} GetRandom_In;
+
+#define RC_GetRandom_bytesRequested (TPM_RC_P + TPM_RC_1)
+
+typedef struct {
+ TPM2B_DIGEST randomBytes;
+} GetRandom_Out;
+
+TPM_RC
+TPM2_GetRandom(
+ GetRandom_In *in, // IN: input parameter list
+ GetRandom_Out *out // OUT: output parameter list
+ );
+
+
+#endif
diff --git a/src/tpm2/GetSessionAuditDigest_fp.h b/src/tpm2/GetSessionAuditDigest_fp.h
new file mode 100644
index 0000000..412ce4b
--- /dev/null
+++ b/src/tpm2/GetSessionAuditDigest_fp.h
@@ -0,0 +1,93 @@
+/********************************************************************************/
+/* */
+/* */
+/* Written by Ken Goldman */
+/* IBM Thomas J. Watson Research Center */
+/* $Id: GetSessionAuditDigest_fp.h 809 2016-11-16 18:31:54Z kgoldman $ */
+/* */
+/* Licenses and Notices */
+/* */
+/* 1. Copyright Licenses: */
+/* */
+/* - Trusted Computing Group (TCG) grants to the user of the source code in */
+/* this specification (the "Source Code") a worldwide, irrevocable, */
+/* nonexclusive, royalty free, copyright license to reproduce, create */
+/* derivative works, distribute, display and perform the Source Code and */
+/* derivative works thereof, and to grant others the rights granted herein. */
+/* */
+/* - The TCG grants to the user of the other parts of the specification */
+/* (other than the Source Code) the rights to reproduce, distribute, */
+/* display, and perform the specification solely for the purpose of */
+/* developing products based on such documents. */
+/* */
+/* 2. Source Code Distribution Conditions: */
+/* */
+/* - Redistributions of Source Code must retain the above copyright licenses, */
+/* this list of conditions and the following disclaimers. */
+/* */
+/* - Redistributions in binary form must reproduce the above copyright */
+/* licenses, this list of conditions and the following disclaimers in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* 3. Disclaimers: */
+/* */
+/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
+/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
+/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
+/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
+/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
+/* information on specification licensing rights available through TCG */
+/* membership agreements. */
+/* */
+/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
+/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
+/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
+/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
+/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
+/* */
+/* - Without limitation, TCG and its members and licensors disclaim all */
+/* liability, including liability for infringement of any proprietary */
+/* rights, relating to use of information in this specification and to the */
+/* implementation of this specification, and TCG disclaims all liability for */
+/* cost of procurement of substitute goods or services, lost profits, loss */
+/* of use, loss of data or any incidental, consequential, direct, indirect, */
+/* or special damages, whether under contract, tort, warranty or otherwise, */
+/* arising in any way out of use or reliance upon this specification or any */
+/* information herein. */
+/* */
+/* (c) Copyright IBM Corp. and others, 2012-2015 */
+/* */
+/********************************************************************************/
+
+/* rev 119 */
+
+#ifndef GETSESSIONAUDITDIGEST_FP_H
+#define GETSESSIONAUDITDIGEST_FP_H
+
+typedef struct {
+ TPMI_RH_ENDORSEMENT privacyAdminHandle;
+ TPMI_DH_OBJECT signHandle;
+ TPMI_SH_HMAC sessionHandle;
+ TPM2B_DATA qualifyingData;
+ TPMT_SIG_SCHEME inScheme;
+} GetSessionAuditDigest_In;
+
+#define RC_GetSessionAuditDigest_privacyAdminHandle (TPM_RC_H + TPM_RC_1)
+#define RC_GetSessionAuditDigest_signHandle (TPM_RC_H + TPM_RC_2)
+#define RC_GetSessionAuditDigest_sessionHandle (TPM_RC_H + TPM_RC_3)
+#define RC_GetSessionAuditDigest_qualifyingData (TPM_RC_P + TPM_RC_1)
+#define RC_GetSessionAuditDigest_inScheme (TPM_RC_P + TPM_RC_2)
+
+typedef struct {
+ TPM2B_ATTEST auditInfo;
+ TPMT_SIGNATURE signature;
+} GetSessionAuditDigest_Out;
+
+TPM_RC
+TPM2_GetSessionAuditDigest(
+ GetSessionAuditDigest_In *in, // IN: input parameter list
+ GetSessionAuditDigest_Out *out // OUT: output parameter list
+ );
+
+
+#endif
diff --git a/src/tpm2/GetTestResult_fp.h b/src/tpm2/GetTestResult_fp.h
new file mode 100644
index 0000000..21d1e9c
--- /dev/null
+++ b/src/tpm2/GetTestResult_fp.h
@@ -0,0 +1,79 @@
+/********************************************************************************/
+/* */
+/* */
+/* Written by Ken Goldman */
+/* IBM Thomas J. Watson Research Center */
+/* $Id: GetTestResult_fp.h 1521 2019-11-15 21:00:47Z kgoldman $ */
+/* */
+/* Licenses and Notices */
+/* */
+/* 1. Copyright Licenses: */
+/* */
+/* - Trusted Computing Group (TCG) grants to the user of the source code in */
+/* this specification (the "Source Code") a worldwide, irrevocable, */
+/* nonexclusive, royalty free, copyright license to reproduce, create */
+/* derivative works, distribute, display and perform the Source Code and */
+/* derivative works thereof, and to grant others the rights granted herein. */
+/* */
+/* - The TCG grants to the user of the other parts of the specification */
+/* (other than the Source Code) the rights to reproduce, distribute, */
+/* display, and perform the specification solely for the purpose of */
+/* developing products based on such documents. */
+/* */
+/* 2. Source Code Distribution Conditions: */
+/* */
+/* - Redistributions of Source Code must retain the above copyright licenses, */
+/* this list of conditions and the following disclaimers. */
+/* */
+/* - Redistributions in binary form must reproduce the above copyright */
+/* licenses, this list of conditions and the following disclaimers in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* 3. Disclaimers: */
+/* */
+/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
+/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
+/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
+/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
+/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
+/* information on specification licensing rights available through TCG */
+/* membership agreements. */
+/* */
+/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
+/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
+/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
+/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
+/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
+/* */
+/* - Without limitation, TCG and its members and licensors disclaim all */
+/* liability, including liability for infringement of any proprietary */
+/* rights, relating to use of information in this specification and to the */
+/* implementation of this specification, and TCG disclaims all liability for */
+/* cost of procurement of substitute goods or services, lost profits, loss */
+/* of use, loss of data or any incidental, consequential, direct, indirect, */
+/* or special damages, whether under contract, tort, warranty or otherwise, */
+/* arising in any way out of use or reliance upon this specification or any */
+/* information herein. */
+/* */
+/* (c) Copyright IBM Corp. and others, 2012-2016 */
+/* */
+/********************************************************************************/
+
+/* rev 119 */
+
+#ifndef GETTESTRESULT_FP_H
+#define GETTESTRESULT_FP_H
+
+typedef struct{
+ TPM2B_MAX_BUFFER outData;
+ TPM_RC testResult;
+} GetTestResult_Out;
+
+
+ TPM_RC
+TPM2_GetTestResult(
+ GetTestResult_Out *out // OUT: output parameter list
+ );
+
+
+#endif
diff --git a/src/tpm2/GetTime_fp.h b/src/tpm2/GetTime_fp.h
new file mode 100644
index 0000000..0aeba2a
--- /dev/null
+++ b/src/tpm2/GetTime_fp.h
@@ -0,0 +1,91 @@
+/********************************************************************************/
+/* */
+/* */
+/* Written by Ken Goldman */
+/* IBM Thomas J. Watson Research Center */
+/* $Id: GetTime_fp.h 809 2016-11-16 18:31:54Z kgoldman $ */
+/* */
+/* Licenses and Notices */
+/* */
+/* 1. Copyright Licenses: */
+/* */
+/* - Trusted Computing Group (TCG) grants to the user of the source code in */
+/* this specification (the "Source Code") a worldwide, irrevocable, */
+/* nonexclusive, royalty free, copyright license to reproduce, create */
+/* derivative works, distribute, display and perform the Source Code and */
+/* derivative works thereof, and to grant others the rights granted herein. */
+/* */
+/* - The TCG grants to the user of the other parts of the specification */
+/* (other than the Source Code) the rights to reproduce, distribute, */
+/* display, and perform the specification solely for the purpose of */
+/* developing products based on such documents. */
+/* */
+/* 2. Source Code Distribution Conditions: */
+/* */
+/* - Redistributions of Source Code must retain the above copyright licenses, */
+/* this list of conditions and the following disclaimers. */
+/* */
+/* - Redistributions in binary form must reproduce the above copyright */
+/* licenses, this list of conditions and the following disclaimers in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* 3. Disclaimers: */
+/* */
+/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
+/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
+/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
+/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
+/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
+/* information on specification licensing rights available through TCG */
+/* membership agreements. */
+/* */
+/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
+/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
+/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
+/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
+/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
+/* */
+/* - Without limitation, TCG and its members and licensors disclaim all */
+/* liability, including liability for infringement of any proprietary */
+/* rights, relating to use of information in this specification and to the */
+/* implementation of this specification, and TCG disclaims all liability for */
+/* cost of procurement of substitute goods or services, lost profits, loss */
+/* of use, loss of data or any incidental, consequential, direct, indirect, */
+/* or special damages, whether under contract, tort, warranty or otherwise, */
+/* arising in any way out of use or reliance upon this specification or any */
+/* information herein. */
+/* */
+/* (c) Copyright IBM Corp. and others, 2012-2015 */
+/* */
+/********************************************************************************/
+
+/* rev 119 */
+
+#ifndef GETTIME_FP_H
+#define GETTIME_FP_H
+
+typedef struct {
+ TPMI_RH_ENDORSEMENT privacyAdminHandle;
+ TPMI_DH_OBJECT signHandle;
+ TPM2B_DATA qualifyingData;
+ TPMT_SIG_SCHEME inScheme;
+} GetTime_In;
+
+#define RC_GetTime_privacyAdminHandle (TPM_RC_H + TPM_RC_1)
+#define RC_GetTime_signHandle (TPM_RC_H + TPM_RC_2)
+#define RC_GetTime_qualifyingData (TPM_RC_P + TPM_RC_1)
+#define RC_GetTime_inScheme (TPM_RC_P + TPM_RC_2)
+
+typedef struct {
+ TPM2B_ATTEST timeInfo;
+ TPMT_SIGNATURE signature;
+} GetTime_Out;
+
+TPM_RC
+TPM2_GetTime(
+ GetTime_In *in, // IN: input parameter list
+ GetTime_Out *out // OUT: output parameter list
+ );
+
+
+#endif
diff --git a/src/tpm2/Global.c b/src/tpm2/Global.c
new file mode 100644
index 0000000..256b721
--- /dev/null
+++ b/src/tpm2/Global.c
@@ -0,0 +1,83 @@
+/********************************************************************************/
+/* */
+/* TPM variables that are not stack allocated */
+/* Written by Ken Goldman */
+/* IBM Thomas J. Watson Research Center */
+/* $Id: Global.c 1519 2019-11-15 20:43:51Z kgoldman $ */
+/* */
+/* Licenses and Notices */
+/* */
+/* 1. Copyright Licenses: */
+/* */
+/* - Trusted Computing Group (TCG) grants to the user of the source code in */
+/* this specification (the "Source Code") a worldwide, irrevocable, */
+/* nonexclusive, royalty free, copyright license to reproduce, create */
+/* derivative works, distribute, display and perform the Source Code and */
+/* derivative works thereof, and to grant others the rights granted herein. */
+/* */
+/* - The TCG grants to the user of the other parts of the specification */
+/* (other than the Source Code) the rights to reproduce, distribute, */
+/* display, and perform the specification solely for the purpose of */
+/* developing products based on such documents. */
+/* */
+/* 2. Source Code Distribution Conditions: */
+/* */
+/* - Redistributions of Source Code must retain the above copyright licenses, */
+/* this list of conditions and the following disclaimers. */
+/* */
+/* - Redistributions in binary form must reproduce the above copyright */
+/* licenses, this list of conditions and the following disclaimers in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* 3. Disclaimers: */
+/* */
+/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
+/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
+/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
+/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
+/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
+/* information on specification licensing rights available through TCG */
+/* membership agreements. */
+/* */
+/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
+/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
+/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
+/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
+/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
+/* */
+/* - Without limitation, TCG and its members and licensors disclaim all */
+/* liability, including liability for infringement of any proprietary */
+/* rights, relating to use of information in this specification and to the */
+/* implementation of this specification, and TCG disclaims all liability for */
+/* cost of procurement of substitute goods or services, lost profits, loss */
+/* of use, loss of data or any incidental, consequential, direct, indirect, */
+/* or special damages, whether under contract, tort, warranty or otherwise, */
+/* arising in any way out of use or reliance upon this specification or any */
+/* information herein. */
+/* */
+/* (c) Copyright IBM Corp. and others, 2016 - 2019 */
+/* */
+/********************************************************************************/
+
+/* 9.5 Global.c */
+/* 9.5.1 Description */
+/* This file will instance the TPM variables that are not stack allocated. Descriptions of global
+ variables are in Global.h. There macro macro definitions that allows a variable to be instanced
+ or simply defined as an external variable. When global.h is included from this .c file, GLOBAL_C
+ is defined and values are instanced (and possibly initialized), but when global.h is included by
+ any other file, they are simply defined as external values. DO NOT DEFINE GLOBAL_C IN ANY OTHER
+ FILE. */
+/* NOTE: This is a change from previous implementations where Global.h just contained the extern
+ declaration and values were instanced in this file. This change keeps the definition and
+ instance in one file making maintenance easier. The instanced data will still be in the
+ global.obj file. */
+/* The OIDs.h file works in a way that is similar to the Global.h with the definition of the
+ values in OIDs.h such that they are instanced in global.obj. The macros that are defined in
+ Global.h are used in OIDs.h in the same way as they are in Global.h. */
+
+#define GLOBAL_C
+#include "Tpm.h"
+#include "OIDs.h"
+#if CC_CertifyX509
+# include "X509.h"
+#endif // CC_CertifyX509
diff --git a/src/tpm2/Global.h b/src/tpm2/Global.h
new file mode 100644
index 0000000..84a0d13
--- /dev/null
+++ b/src/tpm2/Global.h
@@ -0,0 +1,1350 @@
+/********************************************************************************/
+/* */
+/* Internal Global Type Definitions */
+/* Written by Ken Goldman */
+/* IBM Thomas J. Watson Research Center */
+/* $Id: Global.h 1658 2021-01-22 23:14:01Z kgoldman $ */
+/* */
+/* Licenses and Notices */
+/* */
+/* 1. Copyright Licenses: */
+/* */
+/* - Trusted Computing Group (TCG) grants to the user of the source code in */
+/* this specification (the "Source Code") a worldwide, irrevocable, */
+/* nonexclusive, royalty free, copyright license to reproduce, create */
+/* derivative works, distribute, display and perform the Source Code and */
+/* derivative works thereof, and to grant others the rights granted herein. */
+/* */
+/* - The TCG grants to the user of the other parts of the specification */
+/* (other than the Source Code) the rights to reproduce, distribute, */
+/* display, and perform the specification solely for the purpose of */
+/* developing products based on such documents. */
+/* */
+/* 2. Source Code Distribution Conditions: */
+/* */
+/* - Redistributions of Source Code must retain the above copyright licenses, */
+/* this list of conditions and the following disclaimers. */
+/* */
+/* - Redistributions in binary form must reproduce the above copyright */
+/* licenses, this list of conditions and the following disclaimers in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* 3. Disclaimers: */
+/* */
+/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
+/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
+/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
+/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
+/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
+/* information on specification licensing rights available through TCG */
+/* membership agreements. */
+/* */
+/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
+/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
+/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
+/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
+/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
+/* */
+/* - Without limitation, TCG and its members and licensors disclaim all */
+/* liability, including liability for infringement of any proprietary */
+/* rights, relating to use of information in this specification and to the */
+/* implementation of this specification, and TCG disclaims all liability for */
+/* cost of procurement of substitute goods or services, lost profits, loss */
+/* of use, loss of data or any incidental, consequential, direct, indirect, */
+/* or special damages, whether under contract, tort, warranty or otherwise, */
+/* arising in any way out of use or reliance upon this specification or any */
+/* information herein. */
+/* */
+/* (c) Copyright IBM Corp. and others, 2016 - 2021 */
+/* */
+/********************************************************************************/
+
+/* 5.9 Global.h */
+/* 5.9.2 Includes */
+
+#if !defined _TPM_H_
+#error "Should only be instanced in TPM.h"
+#endif
+
+#ifndef GLOBAL_H
+#define GLOBAL_H
+_REDUCE_WARNING_LEVEL_(2)
+#include <string.h>
+#include <stddef.h>
+_NORMAL_WARNING_LEVEL_
+#include "BackwardsCompatibility.h" // libtpms added
+
+#include "Capabilities.h"
+#include "TpmTypes.h"
+#include "CommandAttributes.h"
+#include "CryptTest.h"
+#include "BnValues.h"
+#include "CryptHash.h"
+#include "CryptSym.h"
+#include "CryptRand.h"
+#include "CryptEcc.h"
+#include "CryptRsa.h"
+#include "CryptTest.h"
+#include "TpmError.h"
+#include "NV.h"
+#include "ACT.h"
+#include "Utils.h" // libtpms added
+
+//** Defines and Types
+
+//*** Size Types
+// These types are used to differentiate the two different size values used.
+//
+// NUMBYTES is used when a size is a number of bytes (usually a TPM2B)
+typedef UINT16 NUMBYTES;
+
+//*** Other Types
+// An AUTH_VALUE is a BYTE array containing a digest (TPMU_HA)
+typedef BYTE AUTH_VALUE[sizeof(TPMU_HA)];
+
+/* A TIME_INFO is a BYTE array that can contain a TPMS_TIME_INFO */
+typedef BYTE TIME_INFO[sizeof(TPMS_TIME_INFO)];
+
+/* A NAME is a BYTE array that can contain a TPMU_NAME */
+typedef BYTE NAME[sizeof(TPMU_NAME)];
+
+/* Definition for a PROOF value */
+TPM2B_TYPE(PROOF, PROOF_SIZE);
+
+/* Definition for a Primary Seed value */
+TPM2B_TYPE(SEED, PRIMARY_SEED_SIZE);
+
+/* A CLOCK_NONCE is used to tag the time value in the authorization session and in the ticket
+ computation so that the ticket expires when there is a time discontinuity. When the clock stops
+ during normal operation, the nonce is 64-bit value kept in RAM but it is a 32-bit counter when
+ the clock only stops during power events. */
+#if CLOCK_STOPS
+typedef UINT64 CLOCK_NONCE;
+#else
+typedef UINT32 CLOCK_NONCE;
+#endif
+
+// 5.9.3 Loaded Object Structures
+// 5.9.3.1 Description
+// The structures in this section define the object layout as it exists in TPM memory.
+// Two types of objects are defined: an ordinary object such as a key, and a sequence object that
+// may be a hash, HMAC, or event.
+
+/* 5.9.3.2 OBJECT_ATTRIBUTES */
+/* An OBJECT_ATTRIBUTES structure contains the variable attributes of an object. These properties
+ are not part of the public properties but are used by the TPM in managing the object. An
+ OBJECT_ATTRIBUTES is used in the definition of the OBJECT data type. */
+typedef struct
+{
+#if LITTLE_ENDIAN_TPM == YES /* libtpms added */
+ unsigned publicOnly : 1; //0) SET if only the public portion of
+ // an object is loaded
+ unsigned epsHierarchy : 1; //1) SET if the object belongs to EPS
+ // Hierarchy
+ unsigned ppsHierarchy : 1; //2) SET if the object belongs to PPS
+ // Hierarchy
+ unsigned spsHierarchy : 1; //3) SET f the object belongs to SPS
+ // Hierarchy
+ unsigned evict : 1; //4) SET if the object is a platform or
+ // owner evict object. Platform-
+ // evict object belongs to PPS
+ // hierarchy, owner-evict object
+ // belongs to SPS or EPS hierarchy.
+ // This bit is also used to mark a
+ // completed sequence object so it
+ // will be flush when the
+ // SequenceComplete command succeeds.
+ unsigned primary : 1; //5) SET for a primary object
+ unsigned temporary : 1; //6) SET for a temporary object
+ unsigned stClear : 1; //7) SET for an stClear object
+ unsigned hmacSeq : 1; //8) SET for an HMAC or MAC sequence object
+ unsigned hashSeq : 1; //9) SET for a hash sequence object
+ unsigned eventSeq : 1; //10) SET for an event sequence object
+ unsigned ticketSafe : 1; //11) SET if a ticket is safe to create
+ // for hash sequence object
+ unsigned firstBlock : 1; //12) SET if the first block of hash
+ // data has been received. It
+ // works with ticketSafe bit
+ unsigned isParent : 1; //13) SET if the key has the proper
+ // attributes to be a parent key
+ unsigned privateExp : 1; //14) SET when the private exponent
+ // of an RSA key has been validated.
+ unsigned occupied : 1; //15) SET when the slot is occupied.
+ unsigned derivation : 1; //16) SET when the key is a derivation
+ // parent
+ unsigned external : 1; //17) SET when the object is loaded with
+ // TPM2_LoadExternal();
+ unsigned reserved : 14; //18-31) /* libtpms added */
+#endif /* libtpms added */
+#if BIG_ENDIAN_TPM == YES /* libtpms added begin */
+ unsigned reserved : 14; //18-31)
+ unsigned external : 1; //17) SET when the object is loaded with
+ unsigned derivation : 1; //16) SET when the key is a derivation
+ unsigned occupied : 1; //15) SET when the slot is occupied.
+ unsigned privateExp : 1; //14) SET when the private exponent
+ unsigned isParent : 1; //13) SET if the key has the proper
+ unsigned firstBlock : 1; //12) SET if the first block of hash
+ unsigned ticketSafe : 1; //11) SET if a ticket is safe to create
+ unsigned eventSeq : 1; //10) SET for an event sequence object
+ unsigned hashSeq : 1; //9) SET for a hash sequence object
+ unsigned hmacSeq : 1; //8) SET for an HMAC sequence object
+ unsigned stClear : 1; //7) SET for an stClear object
+ unsigned temporary : 1; //6) SET for a temporary object
+ unsigned primary : 1; //5) SET for a primary object
+
+ unsigned evict : 1; //4) SET if the object is a platform or
+ unsigned spsHierarchy : 1; //3) SET f the object belongs to SPS
+ unsigned ppsHierarchy : 1; //2) SET if the object belongs to PPS
+ unsigned epsHierarchy : 1; //1) SET if the object belongs to EPS
+ unsigned publicOnly : 1; //0) SET if only the public portion of
+#endif /* libtpms added end */
+} OBJECT_ATTRIBUTES;
+
+#if ALG_RSA
+/* There is an overload of the sensitive.rsa.t.size field of a TPMT_SENSITIVE when an RSA key is
+ loaded. When the sensitive->sensitive contains an RSA key with all of the CRT values, then the
+ MSB of the size field will be set to indicate that the buffer contains all 5 of the CRT private
+ key values. */
+#define RSA_prime_flag 0x8000
+#endif
+
+/* 5.9.3.3 OBJECT Structure */
+/* An OBJECT structure holds the object public, sensitive, and meta-data associated. This structure
+ is implementation dependent. For this implementation, the structure is not optimized for space
+ but rather for clarity of the reference implementation. Other implementations may choose to
+ overlap portions of the structure that are not used simultaneously. These changes would
+ necessitate changes to the source code but those changes would be compatible with the reference
+ implementation. */
+typedef struct OBJECT
+{
+ // The attributes field is required to be first followed by the publicArea.
+ // This allows the overlay of the object structure and a sequence structure
+ OBJECT_ATTRIBUTES attributes; // object attributes
+ TPMT_PUBLIC publicArea; // public area of an object
+ TPMT_SENSITIVE sensitive; // sensitive area of an object
+#if ALG_RSA
+ privateExponent_t privateExponent; // Additional field for the private
+#endif
+ TPM2B_NAME qualifiedName; // object qualified name
+ TPMI_DH_OBJECT evictHandle; // if the object is an evict object,
+ // the original handle is kept here.
+ // The 'working' handle will be the
+ // handle of an object slot.
+ TPM2B_NAME name; // Name of the object name. Kept here
+ // to avoid repeatedly computing it.
+
+ // libtpms added: SEED_COMPAT_LEVEL to use for deriving child keys
+ SEED_COMPAT_LEVEL seedCompatLevel;
+ // libtpms added: OBJECT lies in NVRAM; to avoid that it needs different number
+ // of bytes on 32 bit and 64 bit architectures, we need to make sure it's the
+ // same size; simple padding at the end works here
+ UINT8 _pad[3];
+} OBJECT;
+
+/* 5.9.3.4 HASH_OBJECT Structure */
+/* This structure holds a hash sequence object or an event sequence object. */
+/* The first four components of this structure are manually set to be the same as the first four
+ components of the object structure. This prevents the object from being inadvertently misused as
+ sequence objects occupy the same memory as a regular object. A debug check is present to make
+ sure that the offsets are what they are supposed to be. */
+/* NOTE: In a future version, this will probably be renamed as SEQUENCE_OBJECT */
+typedef struct HASH_OBJECT
+{
+ OBJECT_ATTRIBUTES attributes; // The attributes of the HASH object
+ TPMI_ALG_PUBLIC type; // algorithm
+ TPMI_ALG_HASH nameAlg; // name algorithm
+ TPMA_OBJECT objectAttributes; // object attributes
+ // The data below is unique to a sequence object
+ TPM2B_AUTH auth; // authorization for use of sequence
+ union
+ {
+ HASH_STATE hashState[HASH_COUNT];
+ HMAC_STATE hmacState;
+ } state;
+} HASH_OBJECT;
+typedef BYTE HASH_OBJECT_BUFFER[sizeof(HASH_OBJECT)];
+
+/* 5.9.3.5 ANY_OBJECT */
+/* This is the union for holding either a sequence object or a regular object. for ContextSave() and
+ ContextLoad() */
+typedef union ANY_OBJECT
+{
+ OBJECT entity;
+ HASH_OBJECT hash;
+} ANY_OBJECT;
+typedef BYTE ANY_OBJECT_BUFFER[sizeof(ANY_OBJECT)];
+
+/* 5.9.4 AUTH_DUP Types */
+/* These values are used in the authorization processing. */
+typedef UINT32 AUTH_ROLE;
+#define AUTH_NONE ((AUTH_ROLE)(0))
+#define AUTH_USER ((AUTH_ROLE)(1))
+#define AUTH_ADMIN ((AUTH_ROLE)(2))
+#define AUTH_DUP ((AUTH_ROLE)(3))
+
+/* 5.9.5 Active Session Context */
+/* 5.9.5.1 Description */
+/* The structures in this section define the internal structure of a session context. */
+/* 5.9.5.2 SESSION_ATTRIBUTES */
+/* The attributes in the SESSION_ATTRIBUTES structure track the various properties of the
+ session. It maintains most of the tracking state information for the policy session. It is used
+ within the SESSION structure. */
+typedef struct SESSION_ATTRIBUTES
+{
+#if LITTLE_ENDIAN_TPM == YES /* libtpms added */
+ unsigned isPolicy : 1; //1) SET if the session may only be used
+ // for policy
+ unsigned isAudit : 1; //2) SET if the session is used for audit
+ unsigned isBound : 1; //3) SET if the session is bound to with an
+ // entity. This attribute will be CLEAR
+ // if either isPolicy or isAudit is SET.
+ unsigned isCpHashDefined : 1; //4) SET if the cpHash has been defined
+ // This attribute is not SET unless
+ // 'isPolicy' is SET.
+ unsigned isAuthValueNeeded : 1; //5) SET if the authValue is required for
+ // computing the session HMAC. This
+ // attribute is not SET unless 'isPolicy'
+ // is SET.
+ unsigned isPasswordNeeded : 1; //6) SET if a password authValue is required
+ // for authorization This attribute is not
+ // SET unless 'isPolicy' is SET.
+ unsigned isPPRequired : 1; //7) SET if physical presence is required to
+ // be asserted when the authorization is
+ // checked. This attribute is not SET
+ // unless 'isPolicy' is SET.
+ unsigned isTrialPolicy : 1; //8) SET if the policy session is created
+ // for trial of the policy's policyHash
+ // generation. This attribute is not SET
+ // unless 'isPolicy' is SET.
+ unsigned isDaBound : 1; //9) SET if the bind entity had noDA CLEAR.
+ // If this is SET, then an authorization
+ // failure using this session will count
+ // against lockout even if the object
+ // being authorized is exempt from DA.
+ unsigned isLockoutBound : 1; //10) SET if the session is bound to
+ // lockoutAuth.
+ unsigned includeAuth : 1; //11) This attribute is SET when the
+ // authValue of an object is to be
+ // included in the computation of the
+ // HMAC key for the command and response
+ // computations. (was 'requestWasBound')
+ unsigned checkNvWritten : 1; //12) SET if the TPMA_NV_WRITTEN attribute
+ // needs to be checked when the policy is
+ // used for authorization for NV access.
+ // If this is SET for any other type, the
+ // policy will fail.
+ unsigned nvWrittenState : 1; //13) SET if TPMA_NV_WRITTEN is required to
+ // be SET. Used when 'checkNvWritten' is
+ // SET
+ unsigned isTemplateSet : 1; //14) SET if the templateHash needs to be
+ // checked for Create, CreatePrimary, or
+ // CreateLoaded.
+ unsigned _reserved : 18; //15-32 /* libtpms added */
+#endif /* libtpms added */
+#if BIG_ENDIAN_TPM == YES /* libtpms added begin */
+ unsigned _reserved : 18; //15-32
+ unsigned isTemplateSet : 1; //14) SET if the templateHash needs to be
+ unsigned nvWrittenState : 1; //13) SET if TPMA_NV_WRITTEN is required to
+ unsigned checkNvWritten : 1; //12) SET if the TPMA_NV_WRITTEN attribute
+ unsigned includeAuth : 1; //11) This attribute is SET when the
+ unsigned isLockoutBound : 1; //10) SET if the session is bound to
+ unsigned isDaBound : 1; //9) SET if the bind entity had noDA CLEAR.
+ unsigned isTrialPolicy : 1; //8) SET if the policy session is created
+ unsigned isPPRequired : 1; //7) SET if physical presence is required to
+ unsigned isPasswordNeeded : 1; //6) SET if a password authValue is required
+ unsigned isAuthValueNeeded : 1; //5) SET if the authValue is required for
+ unsigned isCpHashDefined : 1; //4) SET if the cpHash has been defined
+ unsigned isBound : 1; //3) SET if the session is bound to with an
+ unsigned isAudit : 1; //2) SET if the session is used for audit
+ unsigned isPolicy : 1; //1) SET if the session may only be used
+#endif /* libtpms added end */
+} SESSION_ATTRIBUTES;
+
+/* 5.9.5.3 SESSION Structure */
+/* The SESSION structure contains all the context of a session except for the associated
+ contextID. */
+/* NOTE: The contextID of a session is only relevant when the session context is stored off the
+ TPM. */
+typedef struct SESSION
+{
+ SESSION_ATTRIBUTES attributes; // session attributes
+ UINT32 pcrCounter; // PCR counter value when PCR is
+ // included (policy session)
+ // If no PCR is included, this
+ // value is 0.
+ UINT64 startTime; // The value in g_time
+ // when the session was started (policy session)
+ UINT64 timeout; // The timeout relative to g_time
+ // There is no timeout if this value
+ // is 0.
+ CLOCK_NONCE epoch; // The g_clockEpoch value when the
+ // session was started. If g_clockEpoch
+ // does not match this value when the
+ // timeout is used, then
+ // then the command will fail.
+ TPM_CC commandCode; // command code (policy session)
+ TPM_ALG_ID authHashAlg; // session hash algorithm
+ TPMA_LOCALITY commandLocality; // command locality (policy session)
+ TPMT_SYM_DEF symmetric; // session symmetric algorithm (if any)
+ TPM2B_AUTH sessionKey; // session secret value used for
+ // this session
+ TPM2B_NONCE nonceTPM; // last TPM-generated nonce for
+ // generating HMAC and encryption keys
+ union
+ {
+ TPM2B_NAME boundEntity; // value used to track the entity to
+ // which the session is bound
+ TPM2B_DIGEST cpHash; // the required cpHash value for the
+ // command being authorized
+ TPM2B_DIGEST nameHash; // the required nameHash
+ TPM2B_DIGEST templateHash; // the required template for creation
+ } u1;
+ union
+ {
+ TPM2B_DIGEST auditDigest; // audit session digest
+ TPM2B_DIGEST policyDigest; // policyHash
+ } u2; // audit log and policyHash may
+ // share space to save memory
+} SESSION;
+#define EXPIRES_ON_RESET INT32_MIN
+#define TIMEOUT_ON_RESET UINT64_MAX
+#define EXPIRES_ON_RESTART (INT32_MIN + 1)
+#define TIMEOUT_ON_RESTART (UINT64_MAX - 1)
+typedef BYTE SESSION_BUF[sizeof(SESSION)];
+
+/* 5.9.7 PCR */
+/* 5.9.7.1 PCR_SAVE Structure */
+/* The PCR_SAVE structure type contains the PCR data that are saved across power cycles. Only the
+ static PCR are required to be saved across power cycles. The DRTM and resettable PCR are not
+ saved. The number of static and resettable PCR is determined by the platform-specific
+ specification to which the TPM is built. */
+
+#define PCR_SAVE_SPACE(HASH, Hash) BYTE Hash[NUM_STATIC_PCR][HASH##_DIGEST_SIZE];
+
+typedef struct PCR_SAVE
+{
+ FOR_EACH_HASH(PCR_SAVE_SPACE)
+
+ // This counter increments whenever the PCR are updated.
+ // NOTE: A platform-specific specification may designate
+ // certain PCR changes as not causing this counter
+ // to increment.
+ UINT32 pcrCounter;
+} PCR_SAVE;
+
+/* 5.9.6.2 PCR_POLICY */
+#if defined NUM_POLICY_PCR_GROUP && NUM_POLICY_PCR_GROUP > 0
+/* This structure holds the PCR policies, one for each group of PCR controlled by policy. */
+typedef struct PCR_POLICY
+{
+ TPMI_ALG_HASH hashAlg[NUM_POLICY_PCR_GROUP];
+ TPM2B_DIGEST a_unused; /* libtpms: renamed field since not used and not initialized */
+ TPM2B_DIGEST policy[NUM_POLICY_PCR_GROUP];
+} PCR_POLICY;
+#endif
+
+/* 5.9.6.3 PCR_AUTHVALUE */
+/* This structure holds the PCR policies, one for each group of PCR controlled by policy. */
+typedef struct PCR_AUTH_VALUE
+{
+ TPM2B_DIGEST auth[NUM_AUTHVALUE_PCR_GROUP];
+} PCR_AUTHVALUE;
+
+/* 5.9.7 STARTUP_TYPE */
+/* This enumeration is the possible startup types. The type is determined by the combination of
+ TPM2_ShutDown() and TPM2_Startup(). */
+typedef enum
+ {
+ SU_RESET,
+ SU_RESTART,
+ SU_RESUME
+ } STARTUP_TYPE;
+
+/* 5.9.8 NV */
+/* 5.9.8.1 NV_INDEX */
+/* The NV_INDEX structure defines the internal format for an NV index. The indexData size varies
+ according to the type of the index. In this implementation, all of the index is manipulated as a
+ unit. */
+typedef struct NV_INDEX
+{
+ TPMS_NV_PUBLIC publicArea;
+ TPM2B_AUTH authValue;
+} NV_INDEX;
+
+/* 5.9.8.2 NV_REF */
+/* An NV_REF is an opaque value returned by the NV subsystem. It is used to reference and NV Index
+ in a relatively efficient way. Rather than having to continually search for an Index, its
+ reference value may be used. In this implementation, an NV_REF is a byte pointer that points to
+ the copy of the NV memory that is kept in RAM. */
+typedef UINT32 NV_REF;
+typedef BYTE *NV_RAM_REF;
+
+/* 5.9.8.3 NV_PIN */
+/* This structure deals with the possible endianness differences between the canonical form of the
+ TPMS_NV_PIN_COUNTER_PARAMETERS structure and the internal value. The structures allow the data in
+ a PIN index to be read as an 8-octet value using NvReadUINT64Data(). That function will byte swap
+ all the values on a little endian system. This will put the bytes with the 4-octet values in the
+ correct order but will swap the pinLimit and pinCount values. When written, the PIN index is
+ simply handled as a normal index with the octets in canonical order. */
+#if BIG_ENDIAN_TPM
+typedef struct
+{
+ UINT32 pinCount;
+ UINT32 pinLimit;
+} PIN_DATA;
+#else
+typedef struct
+{
+ UINT32 pinLimit;
+ UINT32 pinCount;
+} PIN_DATA;
+#endif
+typedef union
+{
+ UINT64 intVal;
+ PIN_DATA pin;
+} NV_PIN;
+
+/* 5.9.9 COMMIT_INDEX_MASK */
+/* This is the define for the mask value that is used when manipulating the bits in the commit bit
+ array. The commit counter is a 64-bit value and the low order bits are used to index the
+ commitArray. This mask value is applied to the commit counter to extract the bit number in the
+ array. */
+#if ALG_ECC
+#define COMMIT_INDEX_MASK ((UINT16)((sizeof(gr.commitArray)*8)-1))
+#endif
+
+/* 5.9.10 RAM Global Values */
+/* 5.9.10.1 Description */
+/* The values in this section are only extant in RAM or ROM as constant values. */
+/* 5.9.10.2 Crypto Self-Test Values */
+EXTERN ALGORITHM_VECTOR g_implementedAlgorithms;
+EXTERN ALGORITHM_VECTOR g_toTest;
+
+/* 5.9.10.3 g_rcIndex[] */
+/* This array is used to contain the array of values that are added to a return code when it is a
+ parameter-, handle-, or session-related error. This is an implementation choice and the same
+ result can be achieved by using a macro. */
+#define g_rcIndexInitializer { TPM_RC_1, TPM_RC_2, TPM_RC_3, TPM_RC_4, \
+ TPM_RC_5, TPM_RC_6, TPM_RC_7, TPM_RC_8, \
+ TPM_RC_9, TPM_RC_A, TPM_RC_B, TPM_RC_C, \
+ TPM_RC_D, TPM_RC_E, TPM_RC_F }
+EXTERN const UINT16 g_rcIndex[15] INITIALIZER(g_rcIndexInitializer);
+
+/* 5.9.10.4 g_exclusiveAuditSession */
+/* This location holds the session handle for the current exclusive audit session. If there is no
+ exclusive audit session, the location is set to TPM_RH_UNASSIGNED. */
+EXTERN TPM_HANDLE g_exclusiveAuditSession;
+
+/* 5.9.10.5 g_time */
+/* This is the value in which we keep the current command time. This is initialized at the start of
+ each command. The time is the accumulated time since the last time that the TPM's timer was last
+ powered up. Clock is the accumulated time since the last time that the TPM was cleared. g_time is
+ in mS. */
+EXTERN UINT64 g_time;
+
+/* 5.9.10.6 g_timeEpoch */
+/* This value contains the current clock Epoch. It changes when there is a clock discontinuity. It
+ may be necessary to place this in NV should the timer be able to run across a power down of the
+ TPM but not in all cases (e.g. dead battery). If the nonce is placed in NV, it should go in gp
+ because it should be changing slowly. */
+#if CLOCK_STOPS
+EXTERN CLOCK_NONCE g_timeEpoch;
+#else
+#define g_timeEpoch gp.timeEpoch
+#endif
+
+/* 5.9.10.7 g_phEnable */
+/* This is the platform hierarchy control and determines if the platform hierarchy is
+ available. This value is SET on each TPM2_Startup(). The default value is SET. */
+EXTERN BOOL g_phEnable;
+
+/* 5.9.10.8 g_pcrReConfig */
+/* This value is SET if a TPM2_PCR_Allocate() command successfully executed since the last
+ TPM2_Startup(). If so, then the next shutdown is required to be Shutdown(CLEAR). */
+EXTERN BOOL g_pcrReConfig;
+
+/* 5.9.10.9 g_DRTMHandle */
+/* This location indicates the sequence object handle that holds the DRTM sequence data. When not
+ used, it is set to TPM_RH_UNASSIGNED. A sequence DRTM sequence is started on either _TPM_Init()
+ or _TPM_Hash_Start(). */
+EXTERN TPMI_DH_OBJECT g_DRTMHandle;
+
+/* 5.9.10.10 g_DrtmPreStartup */
+/* This value indicates that an H-CRTM occurred after _TPM_Init() but before TPM2_Startup(). The
+ define for PRE_STARTUP_FLAG is used to add the g_DrtmPreStartup value to gp_orderlyState at
+ shutdown. This hack is to avoid adding another NV variable. */
+EXTERN BOOL g_DrtmPreStartup;
+
+/* 5.9.10.11 g_StartupLocality3 */
+/* This value indicates that a TPM2_Startup() occurred at locality 3. Otherwise, it at locality
+ 0. The define for STARTUP_LOCALITY_3 is to indicate that the startup was not at locality 0. This
+ hack is to avoid adding another NV variable. */
+EXTERN BOOL g_StartupLocality3;
+
+/* 5.9.10.12 TPM_SU_NONE */
+/* Part 2 defines the two shutdown/startup types that may be used in TPM2_Shutdown() and
+ TPM2_Starup(). This additional define is used by the TPM to indicate that no shutdown was
+ received. */
+/* NOTE: This is a reserved value. */
+#define SU_NONE_VALUE (0xFFFF)
+#define TPM_SU_NONE (TPM_SU)(SU_NONE_VALUE)
+
+/* 5.9.10.13 TPM_SU_DA_USED */
+/* As with TPM_SU_NONE, this value is added to allow indication that the shutdown was not orderly
+ and that a DA=protected object was reference during the previous cycle. */
+#define SU_DA_USED_VALUE (SU_NONE_VALUE - 1)
+#define TPM_SU_DA_USED (TPM_SU)(SU_DA_USED_VALUE)
+
+/* 5.9.10.14 Startup Flags */
+/* These flags are included in gp.orderlyState. These are hacks and are being used to avoid having
+ to change the layout of gp. The PRE_STARTUP_FLAG indicates that a
+ _TPM_Hash_Start()/_Data()/_End() sequence was received after _TPM_Init() but before
+ TPM2_StartUp(). STARTUP_LOCALITY_3 indicates that the last TPM2_Startup() was received at
+ locality 3. These flags are only relevant if after a TPM2_Shutdown(STATE). */
+#define PRE_STARTUP_FLAG 0x8000
+#define STARTUP_LOCALITY_3 0x4000
+#define TPM_SU_STATE_MASK ~(PRE_STARTUP_FLAG | STARTUP_LOCALITY_3) // libtpms added
+#if USE_DA_USED
+
+/* 5.9.10.15 g_daUsed */
+/* This location indicates if a DA-protected value is accessed during a boot cycle. If none has,
+ then there is no need to increment failedTries on the next non-orderly startup. This bit is
+ merged with gp.orderlyState when gp.orderly is set to SU_NONE_VALUE */
+
+/* This global is set to FALSE on startup (after a decision has been made on whether to increment
+ the failedTries or not). On a first attempt to access a DA protected object: this global is set
+ to 1, the orderlyState is set to SU_DA_USED, committed to NV and the command execution returns
+ with RC_RETRY (without exposing any information on the DA attempt). */
+EXTERN BOOL g_daUsed;
+#endif
+
+/* 5.9.10.16 g_updateNV */
+/* This flag indicates if NV should be updated at the end of a command. This flag is set to UT_NONE
+ at the beginning of each command in ExecuteCommand(). This flag is checked in ExecuteCommand()
+ after the detailed actions of a command complete. If the command execution was successful and
+ this flag is not UT_NONE, any pending NV writes will be committed to NV. UT_ORDERLY causes any
+ RAM data to be written to the orderly space for staging the write to NV. */
+typedef BYTE UPDATE_TYPE;
+#define UT_NONE (UPDATE_TYPE)0
+#define UT_NV (UPDATE_TYPE)1
+#define UT_ORDERLY (UPDATE_TYPE)(UT_NV + 2)
+EXTERN UPDATE_TYPE g_updateNV;
+/* 5.9.10.17 g_powerWasLost */
+/* This flag is used to indicate if the power was lost. It is SET in _TPM__Init(). This flag is
+ cleared by TPM2_Startup() after all power-lost activities are completed. */
+/* NOTE: When power is applied, this value can come up as anything. However, _plat__WasPowerLost()
+ will provide the proper indication in that case. So, when power is actually lost, we get the
+ correct answer. When power was not lost, but the power-lost processing has not been completed
+ before the next _TPM_Init(), then the TPM still does the correct thing. */
+EXTERN BOOL g_powerWasLost;
+
+/* 5.9.10.18 g_clearOrderly */
+/* This flag indicates if the execution of a command should cause the orderly state to be cleared.
+ This flag is set to FALSE at the beginning of each command in ExecuteCommand() and is checked in
+ ExecuteCommand() after the detailed actions of a command complete but before the check of
+ g_updateNV. If this flag is TRUE, and the orderly state is not SU_NONE_VALUE, then the orderly
+ state in NV memory will be changed to SU_NONE_VALUE or SU_DA_USED_VALUE. */
+EXTERN BOOL g_clearOrderly;
+
+/* 5.9.10.19 g_prevOrderlyState */
+/* This location indicates how the TPM was shut down before the most recent TPM2_Startup(). This
+ value, along with the startup type, determines if the TPM should do a TPM Reset, TPM Restart, or
+ TPM Resume. */
+EXTERN TPM_SU g_prevOrderlyState;
+
+/* 5.9.10.20 g_nvOk */
+/* This value indicates if the NV integrity check was successful or not. If not and the failure was
+ severe, then the TPM would have been put into failure mode after it had been re-manufactured. If
+ the NV failure was in the area where the state-save data is kept, then this variable will have a
+ value of FALSE indicating that a TPM2_Startup(CLEAR) is required. */
+EXTERN BOOL g_nvOk;
+
+/* NV availability is sampled as the start of each command and stored here so that its value remains
+ consistent during the command execution */
+EXTERN TPM_RC g_NvStatus;
+
+/* 5.9.10.21 g_platformUnique */
+/* This location contains the unique value(s) used to identify the TPM. It is loaded on every
+ _TPM2_Startup() The first value is used to seed the RNG. The second value is used as a vendor
+ authValue. The value used by the RNG would be the value derived from the chip unique value (such
+ as fused) with a dependency on the authorities of the code in the TPM boot path. The second would
+ be derived from the chip unique value with a dependency on the details of the code in the boot
+ path. That is, the first value depends on the various signers of the code and the second depends
+ on what was signed. The TPM vendor should not be able to know the first value but they are
+ expected to know the second. */
+EXTERN TPM2B_AUTH g_platformUniqueAuthorities; // Reserved for RNG
+EXTERN TPM2B_AUTH g_platformUniqueDetails; // referenced by VENDOR_PERMANENT
+
+//*********************************************************************************
+//*********************************************************************************
+//** Persistent Global Values
+//*********************************************************************************
+//*********************************************************************************
+//*** Description
+// The values in this section are global values that are persistent across power
+// events. The lifetime of the values determines the structure in which the value
+// is placed.
+
+/* 5.9.11.2 PERSISTENT_DATA */
+/* This structure holds the persistent values that only change as a consequence of a specific
+ Protected Capability and are not affected by TPM power events (TPM2_Startup() or
+ TPM2_Shutdown(). */
+typedef struct
+{
+ //*********************************************************************************
+ // Hierarchy
+ //*********************************************************************************
+ // The values in this section are related to the hierarchies.
+ BOOL disableClear; // TRUE if TPM2_Clear() using
+ // lockoutAuth is disabled
+ // Hierarchy authPolicies
+ TPMI_ALG_HASH ownerAlg;
+ TPMI_ALG_HASH endorsementAlg;
+ TPMI_ALG_HASH lockoutAlg;
+ TPM2B_DIGEST ownerPolicy;
+ TPM2B_DIGEST endorsementPolicy;
+ TPM2B_DIGEST lockoutPolicy;
+ // Hierarchy authValues
+ TPM2B_AUTH ownerAuth;
+ TPM2B_AUTH endorsementAuth;
+ TPM2B_AUTH lockoutAuth;
+ // Primary Seeds
+ TPM2B_SEED EPSeed;
+ TPM2B_SEED SPSeed;
+ TPM2B_SEED PPSeed;
+ // SEED_COMPAT_LEVELs related to creation time of seeds
+ SEED_COMPAT_LEVEL EPSeedCompatLevel; // libtpms added begin
+ SEED_COMPAT_LEVEL SPSeedCompatLevel;
+ SEED_COMPAT_LEVEL PPSeedCompatLevel; // libtpms added end
+ // Note there is a nullSeed in the state_reset memory.
+ // Hierarchy proofs
+ TPM2B_PROOF phProof;
+ TPM2B_PROOF shProof;
+ TPM2B_PROOF ehProof;
+ // Note there is a nullProof in the state_reset memory.
+ //*********************************************************************************
+ // Reset Events
+ //*********************************************************************************
+ // A count that increments at each TPM reset and never get reset during the life
+ // time of TPM. The value of this counter is initialized to 1 during TPM
+ // manufacture process. It is used to invalidate all saved contexts after a TPM
+ // Reset.
+ UINT64 totalResetCount;
+ // This counter increments on each TPM Reset. The counter is reset by
+ // TPM2_Clear().
+ UINT32 resetCount;
+ //*********************************************************************************
+ // PCR
+ //*********************************************************************************
+ // This structure hold the policies for those PCR that have an update policy.
+ // This implementation only supports a single group of PCR controlled by
+ // policy. If more are required, then this structure would be changed to
+ // an array.
+#if defined NUM_POLICY_PCR_GROUP && NUM_POLICY_PCR_GROUP > 0
+ PCR_POLICY pcrPolicies;
+#endif
+ // This structure indicates the allocation of PCR. The structure contains a
+ // list of PCR allocations for each implemented algorithm. If no PCR are
+ // allocated for an algorithm, a list entry still exists but the bit map
+ // will contain no SET bits.
+ TPML_PCR_SELECTION pcrAllocated;
+ //*********************************************************************************
+ // Physical Presence
+ //*********************************************************************************
+ // The PP_LIST type contains a bit map of the commands that require physical
+ // to be asserted when the authorization is evaluated. Physical presence will be
+ // checked if the corresponding bit in the array is SET and if the authorization
+ // handle is TPM_RH_PLATFORM.
+ //
+ // These bits may be changed with TPM2_PP_Commands().
+ BYTE ppList[(COMMAND_COUNT + 7) / 8];
+ //*********************************************************************************
+ // Dictionary attack values
+ //*********************************************************************************
+ // These values are used for dictionary attack tracking and control.
+ UINT32 failedTries; // the current count of unexpired
+ // authorization failures
+ UINT32 maxTries; // number of unexpired authorization
+ // failures before the TPM is in
+ // lockout
+ UINT32 recoveryTime; // time between authorization failures
+ // before failedTries is decremented
+ UINT32 lockoutRecovery; // time that must expire between
+ // authorization failures associated
+ // with lockoutAuth
+ BOOL lockOutAuthEnabled; // TRUE if use of lockoutAuth is
+ // allowed
+ //*****************************************************************************
+ // Orderly State
+ //*****************************************************************************
+ // The orderly state for current cycle
+ TPM_SU orderlyState;
+ //*****************************************************************************
+ // Command audit values.
+ //*****************************************************************************
+ BYTE auditCommands[((COMMAND_COUNT + 1) + 7) / 8];
+ TPMI_ALG_HASH auditHashAlg;
+ UINT64 auditCounter;
+ //*****************************************************************************
+ // Algorithm selection
+ //*****************************************************************************
+ //
+ // The 'algorithmSet' value indicates the collection of algorithms that are
+ // currently in used on the TPM. The interpretation of value is vendor dependent.
+ UINT32 algorithmSet;
+ //*****************************************************************************
+ // Firmware version
+ //*****************************************************************************
+ // The firmwareV1 and firmwareV2 values are instanced in TimeStamp.c. This is
+ // a scheme used in development to allow determination of the linker build time
+ // of the TPM. An actual implementation would implement these values in a way that
+ // is consistent with vendor needs. The values are maintained in RAM for simplified
+ // access with a master version in NV. These values are modified in a
+ // vendor-specific way.
+ // g_firmwareV1 contains the more significant 32-bits of the vendor version number.
+ // In the reference implementation, if this value is printed as a hex
+ // value, it will have the format of YYYYMMDD
+ UINT32 firmwareV1;
+ // g_firmwareV1 contains the less significant 32-bits of the vendor version number.
+ // In the reference implementation, if this value is printed as a hex
+ // value, it will have the format of 00 HH MM SS
+ UINT32 firmwareV2;
+ //*****************************************************************************
+ // Timer Epoch
+ //*****************************************************************************
+ // timeEpoch contains a nonce that has a vendor=specific size (should not be
+ // less than 8 bytes. This nonce changes when the clock epoch changes. The clock
+ // epoch changes when there is a discontinuity in the timing of the TPM.
+#if !CLOCK_STOPS
+ CLOCK_NONCE timeEpoch;
+#endif
+} PERSISTENT_DATA;
+EXTERN PERSISTENT_DATA gp;
+
+/* 5.9.11.3 ORDERLY_DATA */
+/* The data in this structure is saved to NV on each TPM2_Shutdown(). */
+typedef struct orderly_data
+{
+ //*****************************************************************************
+ // TIME
+ //*****************************************************************************
+ // Clock has two parts. One is the state save part and one is the NV part. The
+ // state save version is updated on each command. When the clock rolls over, the
+ // NV version is updated. When the TPM starts up, if the TPM was shutdown in and
+ // orderly way, then the sClock value is used to initialize the clock. If the
+ // TPM shutdown was not orderly, then the persistent value is used and the safe
+ // attribute is clear.
+ UINT64 clock; // The orderly version of clock
+ TPMI_YES_NO clockSafe; // Indicates if the clock value is
+ // safe.
+ // In many implementations, the quality of the entropy available is not that
+ // high. To compensate, the current value of the drbgState can be saved and
+ // restored on each power cycle. This prevents the internal state from reverting
+ // to the initial state on each power cycle and starting with a limited amount
+ // of entropy. By keeping the old state and adding entropy, the entropy will
+ // accumulate.
+ DRBG_STATE drbgState;
+ // These values allow the accumulation of self-healing time across orderly shutdown
+ // of the TPM.
+#if ACCUMULATE_SELF_HEAL_TIMER
+ UINT64 selfHealTimer; // current value of s_selfHealTimer
+ UINT64 lockoutTimer; // current value of s_lockoutTimer
+ UINT64 time; // current value of g_time at shutdown
+#endif // ACCUMULATE_SELF_HEAL_TIMER
+
+#ifndef __ACT_DISABLED // libtpms added
+#error ACT not supported in ORDERLY_DATA!
+ // These are the ACT Timeout values. They are saved with the other timers
+#define DefineActData(N) ACT_STATE ACT_##N;
+ FOR_EACH_ACT(DefineActData)
+
+ // this is the 'signaled' attribute data for all the ACT. It is done this way so
+ // that they can be manipulated by ACT number rather than having to access a
+ // structure.
+ UINT16 signaledACT;
+ UINT16 preservedSignaled;
+#endif // libtpms added
+} ORDERLY_DATA;
+#if ACCUMULATE_SELF_HEAL_TIMER
+#define s_selfHealTimer go.selfHealTimer
+#define s_lockoutTimer go.lockoutTimer
+#endif // ACCUMULATE_SELF_HEAL_TIMER
+# define drbgDefault go.drbgState
+EXTERN ORDERLY_DATA go;
+
+/* 5.9.11.4 STATE_CLEAR_DATA */
+/* This structure contains the data that is saved on Shutdown(STATE). and restored on
+ Startup(STATE). The values are set to their default settings on any Startup(Clear). In other
+ words the data is only persistent across TPM Resume. */
+/* If the comments associated with a parameter indicate a default reset value, the value is applied
+ on each Startup(CLEAR). */
+typedef struct state_clear_data
+{
+ //*****************************************************************************
+ // Hierarchy Control
+ //*****************************************************************************
+ BOOL shEnable; // default reset is SET
+ BOOL ehEnable; // default reset is SET
+ BOOL phEnableNV; // default reset is SET
+ TPMI_ALG_HASH platformAlg; // default reset is TPM_ALG_NULL
+ TPM2B_DIGEST platformPolicy; // default reset is an Empty Buffer
+ TPM2B_AUTH platformAuth; // default reset is an Empty Buffer
+ //*****************************************************************************
+ // PCR
+ //*****************************************************************************
+ // The set of PCR to be saved on Shutdown(STATE)
+ PCR_SAVE pcrSave; // default reset is 0...0
+ // This structure hold the authorization values for those PCR that have an
+ // update authorization.
+ // This implementation only supports a single group of PCR controlled by
+ // authorization. If more are required, then this structure would be changed to
+ // an array.
+ PCR_AUTHVALUE pcrAuthValues;
+
+#ifndef __ACT_DISABLED // libtpms added
+ //*****************************************************************************
+ // ACT
+ //*****************************************************************************
+#define DefineActPolicySpace(N) TPMT_HA act_##N;
+ FOR_EACH_ACT(DefineActPolicySpace)
+
+#endif // libtpms added
+} STATE_CLEAR_DATA;
+EXTERN STATE_CLEAR_DATA gc;
+
+/* 5.9.11.5 State Reset Data */
+/* This structure contains data is that is saved on Shutdown(STATE) and restored on the subsequent
+ Startup(ANY). That is, the data is preserved across TPM Resume and TPM Restart. */
+/* If a default value is specified in the comments this value is applied on TPM Reset. */
+typedef struct state_reset_data
+{
+ //*****************************************************************************
+ // Hierarchy Control
+ //*****************************************************************************
+ TPM2B_PROOF nullProof; // The proof value associated with
+ // the TPM_RH_NULL hierarchy. The
+ // default reset value is from the RNG.
+ TPM2B_SEED nullSeed; // The seed value for the TPM_RN_NULL
+ SEED_COMPAT_LEVEL nullSeedCompatLevel; // libtpms added
+ // hierarchy. The default reset value
+ // is from the RNG.
+ //*****************************************************************************
+ // Context
+ //*****************************************************************************
+ // The 'clearCount' counter is incremented each time the TPM successfully executes
+ // a TPM Resume. The counter is included in each saved context that has 'stClear'
+ // SET (including descendants of keys that have 'stClear' SET). This prevents these
+ // objects from being loaded after a TPM Resume.
+ // If 'clearCount' is at its maximum value when the TPM receives a Shutdown(STATE),
+ // the TPM will return TPM_RC_RANGE and the TPM will only accept Shutdown(CLEAR).
+ UINT32 clearCount; // The default reset value is 0.
+ UINT64 objectContextID; // This is the context ID for a saved
+ // object context. The default reset
+ // value is 0.
+ CONTEXT_SLOT contextArray[MAX_ACTIVE_SESSIONS]; // This array contains
+ // contains the values used to track
+ // the version numbers of saved
+ // contexts (see
+ // Session.c in for details). The
+ // default reset value is {0}.
+ CONTEXT_COUNTER contextCounter; // This is the value from which the
+ // 'contextID' is derived. The
+ // default reset value is {0}.
+ //*****************************************************************************
+ // Command Audit
+ //*****************************************************************************
+ // When an audited command completes, ExecuteCommand() checks the return
+ // value. If it is TPM_RC_SUCCESS, and the command is an audited command, the
+ // TPM will extend the cpHash and rpHash for the command to this value. If this
+ // digest was the Zero Digest before the cpHash was extended, the audit counter
+ // is incremented.
+ TPM2B_DIGEST commandAuditDigest; // This value is set to an Empty Digest
+ // by TPM2_GetCommandAuditDigest() or a
+ // TPM Reset.
+ //*****************************************************************************
+ // Boot counter
+ //*****************************************************************************
+ UINT32 restartCount; // This counter counts TPM Restarts.
+ // The default reset value is 0.
+ //*********************************************************************************
+ // PCR
+ //*********************************************************************************
+ // This counter increments whenever the PCR are updated. This counter is preserved
+ // across TPM Resume even though the PCR are not preserved. This is because
+ // sessions remain active across TPM Restart and the count value in the session
+ // is compared to this counter so this counter must have values that are unique
+ // as long as the sessions are active.
+ // NOTE: A platform-specific specification may designate that certain PCR changes
+ // do not increment this counter to increment.
+ UINT32 pcrCounter; // The default reset value is 0.
+#if ALG_ECC
+ //*****************************************************************************
+ // ECDAA
+ //*****************************************************************************
+ UINT64 commitCounter; // This counter increments each time
+ // TPM2_Commit() returns
+ // TPM_RC_SUCCESS. The default reset
+ // value is 0.
+ TPM2B_NONCE commitNonce; // This random value is used to compute
+ // the commit values. The default reset
+ // value is from the RNG.
+ // This implementation relies on the number of bits in g_commitArray being a
+ // power of 2 (8, 16, 32, 64, etc.) and no greater than 64K.
+ BYTE commitArray[16]; // The default reset value is {0}.
+#endif // ALG_ECC
+} STATE_RESET_DATA;
+EXTERN STATE_RESET_DATA gr;
+
+ // libtpms added begin
+/* The s_ContextSlotMask masks CONTEXT_SLOT values; this variable can have
+ * only two valid values, 0xff or 0xffff. The former is used to simulate
+ * a CONTEXT_SLOT defined as UINT8, the latter is used for the CONTEXT_SLOT
+ * when it is a UINT16. The original TPM 2 code uses a cast to CONTEXT_SLOT
+ * to truncate larger values and has been modified to use CONTEXT_SLOT_MASKED
+ * to achieve the same effect with the above two values.
+ *
+ * Using CONTEXT_SLOT_MASKED we make sure that when we write values into
+ * gr.contextArray that these values are properly masked/truncated so that
+ * when we read values from gr.contextArray that we don't have to mask
+ * them again.
+ *
+ * s_ContextSlotMask may only be initialized to 0xff when resuming an older
+ * state from the time when CONTEXT_SLOT was UINT8, otherwise it must be set
+ * to 0xffff. We set it to 0xffff in SessionStartup(SU_CLEAR) and to be
+ * able to save the TPM state really early (and restore it) also in
+ * TPM_Manufacture().
+ */
+EXTERN CONTEXT_SLOT s_ContextSlotMask;
+#define CONTEXT_SLOT_MASKED(val) ((CONTEXT_SLOT)(val) & s_ContextSlotMask) // libtpms added end
+
+/* 5.9.12 NV Layout */
+/* The NV data organization is */
+/* a) a PERSISTENT_DATA structure */
+/* b) a STATE_RESET_DATA structure */
+/* c) a STATE_CLEAR_DATA structure */
+/* d) an ORDERLY_DATA structure */
+/* e) the user defined NV index space */
+
+/* libtpms added: to put certain data structure at fixed offsets
+ * to give the ones below some room to expand
+ */
+#define NV_PERSISTENT_DATA (0)
+#define NV_STATE_RESET_DATA (NV_PERSISTENT_DATA + sizeof(PERSISTENT_DATA))
+#define NV_STATE_CLEAR_DATA (NV_STATE_RESET_DATA + sizeof(STATE_RESET_DATA))
+#define NV_ORDERLY_DATA (NV_STATE_CLEAR_DATA + sizeof(STATE_CLEAR_DATA))
+#define NV_INDEX_RAM_DATA TPM2_ROUNDUP(NV_ORDERLY_DATA + sizeof(ORDERLY_DATA),\
+ 1024) /* libtpms added */
+#define NV_USER_DYNAMIC (NV_INDEX_RAM_DATA + sizeof(s_indexOrderlyRam))
+#define NV_USER_DYNAMIC_END NV_MEMORY_SIZE
+
+/* 5.9.13 Global Macro Definitions */
+/* The NV_READ_PERSISTENT and NV_WRITE_PERSISTENT macros are used to access members of the
+ PERSISTENT_DATA structure in NV. */
+#define NV_READ_PERSISTENT(to, from) \
+ NvRead(&to, offsetof(PERSISTENT_DATA, from), sizeof(to))
+#define NV_WRITE_PERSISTENT(to, from) \
+ NvWrite(offsetof(PERSISTENT_DATA, to), sizeof(gp.to), &from)
+#define CLEAR_PERSISTENT(item) \
+ NvClearPersistent(offsetof(PERSISTENT_DATA, item), sizeof(gp.item))
+#define NV_SYNC_PERSISTENT(item) NV_WRITE_PERSISTENT(item, gp.item)
+
+/* At the start of command processing, the index of the command is determined. This index value is
+ used to access the various data tables that contain per-command information. There are multiple
+ options for how the per-command tables can be implemented. This is resolved in
+ GetClosestCommandIndex(). */
+typedef UINT16 COMMAND_INDEX;
+#define UNIMPLEMENTED_COMMAND_INDEX ((COMMAND_INDEX)(~0))
+#if 0 /* libtpms added */
+typedef struct _COMMAND_FLAGS_
+{
+#if LITTLE_ENDIAN_TPM == YES /* libtpms added */
+ unsigned trialPolicy : 1; //1) If SET, one of the handles references a
+ // trial policy and authorization may be
+ // skipped. This is only allowed for a policy
+ // command.
+ unsigned reserved : 31; //2-31) /* libtpms added begin */
+#endif
+#if BIG_ENDIAN_TPM == YES
+ unsigned reserved : 31; //2-31)
+ unsigned trialPolicy : 1; //1) If SET, one of the handles references a
+#endif /* libtpms added end */
+} COMMAND_FLAGS;
+#endif /* libtpms added */
+
+/* This structure is used to avoid having to manage a large number of parameters being passed
+ through various levels of the command input processing.
+
+ The following macros are used to define the space for the CP and RP hashes. Space is provided
+ for each implemented hash algorithm because it is not known what the caller may use.
+*/
+
+#define CP_HASH(HASH, Hash) TPM2B_##HASH##_DIGEST Hash##CpHash;
+#define RP_HASH(HASH, Hash) TPM2B_##HASH##_DIGEST Hash##RpHash;
+
+typedef struct _COMMAND_
+{
+ TPM_ST tag; // the parsed command tag
+ TPM_CC code; // the parsed command code
+ COMMAND_INDEX index; // the computed command index
+ UINT32 handleNum; // the number of entity handles in the
+ // handle area of the command
+ TPM_HANDLE handles[MAX_HANDLE_NUM]; // the parsed handle values
+ UINT32 sessionNum; // the number of sessions found
+ INT32 parameterSize; // starts out with the parsed command size
+ // and is reduced and values are unmarshaled. Just before calling the command actions, this
+ // should be zero. After the command actions, this number should grow as values are marshaled
+ // in to the response buffer.
+ INT32 authSize; // this is initialized with the parsed size
+ // of authorizationSize field and should be zero when the authorizations are parsed.
+ BYTE *parameterBuffer; // input to ExecuteCommand
+ BYTE *responseBuffer; // input to ExecuteCommand
+ FOR_EACH_HASH(CP_HASH) // space for the CP hashes
+ FOR_EACH_HASH(RP_HASH) // space for the RP hashes
+} COMMAND;
+
+// Global string constants for consistency in KDF function calls. These string constants are shared
+// across functions to make sure that they are all using consistent string values.
+#define STRING_INITIALIZER(value) {{sizeof(value), {value}}}
+#define TPM2B_STRING(name, value) \
+ typedef union name##_ { \
+ struct { \
+ UINT16 size; \
+ BYTE buffer[sizeof(value)]; \
+ } t; \
+ TPM2B b; \
+ } TPM2B_##name##_; \
+ EXTERN const TPM2B_##name##_ name##_ INITIALIZER(STRING_INITIALIZER(value)); \
+ EXTERN const TPM2B *name INITIALIZER(&name##_.b)
+TPM2B_STRING(PRIMARY_OBJECT_CREATION, "Primary Object Creation");
+TPM2B_STRING(CFB_KEY, "CFB");
+TPM2B_STRING(CONTEXT_KEY, "CONTEXT");
+TPM2B_STRING(INTEGRITY_KEY, "INTEGRITY");
+TPM2B_STRING(SECRET_KEY, "SECRET");
+TPM2B_STRING(SESSION_KEY, "ATH");
+TPM2B_STRING(STORAGE_KEY, "STORAGE");
+TPM2B_STRING(XOR_KEY, "XOR");
+TPM2B_STRING(COMMIT_STRING, "ECDAA Commit");
+TPM2B_STRING(DUPLICATE_STRING, "DUPLICATE");
+TPM2B_STRING(IDENTITY_STRING, "IDENTITY");
+TPM2B_STRING(OBFUSCATE_STRING, "OBFUSCATE");
+#if SELF_TEST
+TPM2B_STRING(OAEP_TEST_STRING, "OAEP Test Value");
+#endif // SELF_TEST
+
+// 5.9.14 From CryptTest.c
+// This structure contains the self-test state values for the cryptographic modules.
+EXTERN CRYPTO_SELF_TEST_STATE g_cryptoSelfTestState;
+
+/* 5.9.15 From Manufacture.c */
+EXTERN BOOL g_manufactured;
+/* This value indicates if a TPM2_Startup() commands has been receive since the power on event.
+ This flag is maintained in power simulation module because this is the only place that may
+ reliably set this flag to FALSE. */
+EXTERN BOOL g_initialized;
+
+/* 5.9.16 Private data */
+#if defined SESSION_PROCESS_C || defined GLOBAL_C || defined MANUFACTURE_C
+/* From SessionProcess.c */
+/* The following arrays are used to save command sessions information so that the command
+ handle/session buffer does not have to be preserved for the duration of the command. These arrays
+ are indexed by the session index in accordance with the order of sessions in the session area of
+ the command. */
+
+/* Array of the authorization session handles */
+EXTERN TPM_HANDLE s_sessionHandles[MAX_SESSION_NUM];
+
+/* Array of authorization session attributes */
+EXTERN TPMA_SESSION s_attributes[MAX_SESSION_NUM];
+
+/* Array of handles authorized by the corresponding authorization sessions; and if none, then
+ TPM_RH_UNASSIGNED value is used */
+
+EXTERN TPM_HANDLE s_associatedHandles[MAX_SESSION_NUM];
+
+/* Array of nonces provided by the caller for the corresponding sessions */
+EXTERN TPM2B_NONCE s_nonceCaller[MAX_SESSION_NUM];
+
+/* Array of authorization values (HMAC's or passwords) for the corresponding sessions */
+EXTERN TPM2B_AUTH s_inputAuthValues[MAX_SESSION_NUM];
+
+/* Array of pointers to the SESSION structures for the sessions in a command */
+EXTERN SESSION *s_usedSessions[MAX_SESSION_NUM];
+
+/* Special value to indicate an undefined session index */
+#define UNDEFINED_INDEX (0xFFFF)
+/* Index of the session used for encryption of a response parameter */
+EXTERN UINT32 s_encryptSessionIndex;
+
+/* Index of the session used for decryption of a command parameter */
+EXTERN UINT32 s_decryptSessionIndex;
+
+/* Index of a session used for audit */
+EXTERN UINT32 s_auditSessionIndex;
+
+/* The cpHash for command audit */
+#if CC_GetCommandAuditDigest
+EXTERN TPM2B_DIGEST s_cpHashForCommandAudit;
+#endif
+
+/* Flag indicating if NV update is pending for the lockOutAuthEnabled or failedTries DA parameter */
+EXTERN BOOL s_DAPendingOnNV;
+
+#endif // SESSION_PROCESS_C
+
+/* 5.9.16.2 From DA.c */
+#if defined DA_C || defined GLOBAL_C || defined MANUFACTURE_C
+
+/* From DA.c */
+/* This variable holds the accumulated time since the last time that failedTries was
+ decremented. This value is in millisecond. */
+
+#if !ACCUMULATE_SELF_HEAL_TIMER
+EXTERN UINT64 s_selfHealTimer;
+
+/* This variable holds the accumulated time that the lockoutAuth has been blocked. */
+EXTERN UINT64 s_lockoutTimer;
+
+#endif // ACCUMULATE_SELF_HEAL_TIMER
+#endif // DA_C
+
+/* 5.9.16.3 From NV.c */
+
+#if defined NV_C || defined GLOBAL_C
+
+/* From NV.c */
+/* This marks the end of the NV area. This is a run-time variable as it might not be compile-time
+ constant. */
+EXTERN NV_REF s_evictNvEnd;
+
+/* This space is used to hold the index data for an orderly Index. It also contains the attributes
+ for the index. */
+EXTERN BYTE s_indexOrderlyRam[RAM_INDEX_SPACE]; // The orderly NV Index data
+
+/* This value contains the current max counter value. It is written to the end of allocatable NV
+ space each time an index is deleted or added. This value is initialized on Startup. The indices
+ are searched and the maximum of all the current counter indices and this value is the initial
+ value for this. */
+EXTERN UINT64 s_maxCounter;
+
+/* This is space used for the NV Index cache. As with a persistent object, the contents of a
+ referenced index are copied into the cache so that the NV Index memory scanning and data copying
+ can be reduced. Only code that operates on NV Index data should use this cache directly. When
+ that action code runs, s_lastNvIndex will contain the index header information. It will have been
+ loaded when the handles were verified. */
+/* NOTE: An NV index handle can appear in many commands that do not operate on the NV data
+ (e.g. TPM2_StartAuthSession()). However, only one NV Index at a time is ever directly referenced
+ by any command. If that changes, then the NV Index caching needs to be changed to accommodate
+ that. Currently, the code will verify that only one NV Index is referenced by the handles of the
+ command. */
+
+EXTERN NV_INDEX s_cachedNvIndex;
+EXTERN NV_REF s_cachedNvRef;
+EXTERN BYTE *s_cachedNvRamRef;
+
+/* Initial NV Index/evict object iterator value */
+#define NV_REF_INIT (NV_REF)0xFFFFFFFF
+#endif
+
+/* 5.9.16.4 From Object.c */
+#if defined OBJECT_C || defined GLOBAL_C
+
+/* This type is the container for an object. */
+
+EXTERN OBJECT s_objects[MAX_LOADED_OBJECTS];
+#endif // OBJECT_C
+
+/* 5.9.17.5 From PCR.c */
+
+#if defined PCR_C || defined GLOBAL_C
+
+/* The following macro is used to define the per-implemented-hash space. This implementation
+ reserves space for all implemented hashes. */
+
+#define PCR_ALL_HASH(HASH, Hash) BYTE Hash##Pcr[HASH##_DIGEST_SIZE];
+
+typedef struct
+{
+ FOR_EACH_HASH(PCR_ALL_HASH)
+} PCR;
+
+typedef struct
+{
+ unsigned int stateSave : 1; // if the PCR value should be
+ // saved in state save
+ unsigned int resetLocality : 5; // The locality that the PCR
+ // can be reset
+ unsigned int extendLocality : 5; // The locality that the PCR
+ // can be extend
+} PCR_Attributes;
+EXTERN PCR s_pcrs[IMPLEMENTATION_PCR];
+#endif // PCR_C
+
+/* 5.9.16.6 From Session.c */
+
+#if defined SESSION_C || defined GLOBAL_C
+
+/* Container for HMAC or policy session tracking information */
+typedef struct
+{
+ BOOL occupied;
+ SESSION session; // session structure
+} SESSION_SLOT;
+EXTERN SESSION_SLOT s_sessions[MAX_LOADED_SESSIONS];
+/* The index in contextArray that has the value of the oldest saved session context. When no context
+ is saved, this will have a value that is greater than or equal to MAX_ACTIVE_SESSIONS. */
+
+EXTERN UINT32 s_oldestSavedSession;
+/* The number of available session slot openings. When this is 1, a session can't be created or
+ loaded if the GAP is maxed out. The exception is that the oldest saved session context can always
+ be loaded (assuming that there is a space in memory to put it) */
+EXTERN int s_freeSessionSlots;
+
+#endif // SESSION_C
+
+/* 5.9.16.7 From IoBuffers.c */
+
+#if defined IO_BUFFER_C || defined GLOBAL_C
+
+/* The value of s_actionIoAllocation is the number of UINT64 values allocated. It is used to set the
+ pointer for the response structure. */
+EXTERN UINT64 s_actionIoBuffer[768]; // action I/O buffer
+EXTERN UINT32 s_actionIoAllocation; // number of UIN64 allocated for the action input
+ // structure
+#endif // MEMORY_LIB_C
+
+/* 5.9.16.8 From TPMFail.c */
+
+/* This value holds the address of the string containing the name of the function in which the
+ failure occurred. This address value isn't useful for anything other than helping the vendor to
+ know in which file the failure occurred. */
+EXTERN BOOL g_inFailureMode; // Indicates that the TPM is in failure mode
+#if SIMULATION
+EXTERN BOOL g_forceFailureMode; // flag to force failure mode during test
+#endif
+typedef void(FailFunction)(const char *function, int line, int code);
+#if defined TPM_FAIL_C || defined GLOBAL_C || 1
+EXTERN UINT32 s_failFunction;
+EXTERN UINT32 s_failLine; // the line in the file at which
+// the error was signaled
+EXTERN UINT32 s_failCode; // the error code used
+EXTERN FailFunction *LibFailCallback;
+#endif // TPM_FAIL_C
+
+//*****************************************************************************
+//*** From ACT_spt.c
+//*****************************************************************************
+// This value is used to indicate if an ACT has been updated since the last
+// TPM2_Startup() (one bit for each ACT). If the ACT is not updated
+// (TPM2_ACT_SetTimeout()) after a startup, then on each TPM2_Shutdown() the TPM will
+// save 1/2 of the current timer value. This prevents an attack on the ACT by saving
+// the counter and then running for a long period of time before doing a TPM Restart.
+// A quick TPM2_Shutdown() after each
+EXTERN UINT16 s_ActUpdated;
+
+/* 5.9.16.9 From CommandCodeAttributes.c */
+
+extern const TPMA_CC s_ccAttr[];
+extern const COMMAND_ATTRIBUTES s_commandAttributes[];
+
+#endif // GLOBAL_H
diff --git a/src/tpm2/GpMacros.h b/src/tpm2/GpMacros.h
new file mode 100644
index 0000000..d557e02
--- /dev/null
+++ b/src/tpm2/GpMacros.h
@@ -0,0 +1,354 @@
+/********************************************************************************/
+/* */
+/* This file is a collection of miscellaneous macros. */
+/* Written by Ken Goldman */
+/* IBM Thomas J. Watson Research Center */
+/* $Id: GpMacros.h 1658 2021-01-22 23:14:01Z kgoldman $ */
+/* */
+/* Licenses and Notices */
+/* */
+/* 1. Copyright Licenses: */
+/* */
+/* - Trusted Computing Group (TCG) grants to the user of the source code in */
+/* this specification (the "Source Code") a worldwide, irrevocable, */
+/* nonexclusive, royalty free, copyright license to reproduce, create */
+/* derivative works, distribute, display and perform the Source Code and */
+/* derivative works thereof, and to grant others the rights granted herein. */
+/* */
+/* - The TCG grants to the user of the other parts of the specification */
+/* (other than the Source Code) the rights to reproduce, distribute, */
+/* display, and perform the specification solely for the purpose of */
+/* developing products based on such documents. */
+/* */
+/* 2. Source Code Distribution Conditions: */
+/* */
+/* - Redistributions of Source Code must retain the above copyright licenses, */
+/* this list of conditions and the following disclaimers. */
+/* */
+/* - Redistributions in binary form must reproduce the above copyright */
+/* licenses, this list of conditions and the following disclaimers in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* 3. Disclaimers: */
+/* */
+/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
+/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
+/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
+/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
+/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
+/* information on specification licensing rights available through TCG */
+/* membership agreements. */
+/* */
+/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
+/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
+/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
+/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
+/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
+/* */
+/* - Without limitation, TCG and its members and licensors disclaim all */
+/* liability, including liability for infringement of any proprietary */
+/* rights, relating to use of information in this specification and to the */
+/* implementation of this specification, and TCG disclaims all liability for */
+/* cost of procurement of substitute goods or services, lost profits, loss */
+/* of use, loss of data or any incidental, consequential, direct, indirect, */
+/* or special damages, whether under contract, tort, warranty or otherwise, */
+/* arising in any way out of use or reliance upon this specification or any */
+/* information herein. */
+/* */
+/* (c) Copyright IBM Corp. and others, 2016 - 2021 */
+/* */
+/********************************************************************************/
+
+#ifndef GPMACROS_H
+#define GPMACROS_H
+
+/* 5.10.1 Introduction */
+/* This file is a collection of miscellaneous macros. */
+#ifndef NULL
+#define NULL 0
+#endif
+#include "swap.h"
+#include "VendorString.h"
+/* 5.10.2 For Self-test */
+/* These macros are used in CryptUtil() to invoke the incremental self test. */
+#if SELF_TEST
+# define TEST(alg) if(TEST_BIT(alg, g_toTest)) CryptTestAlgorithm(alg, NULL)
+/* Use of TPM_ALG_NULL is reserved for RSAEP/RSADP testing. If someone is wanting to test a hash
+ with that value, don't do it. */
+# define TEST_HASH(alg) \
+ if(TEST_BIT(alg, g_toTest) \
+ && (alg != TPM_ALG_NULL)) \
+ CryptTestAlgorithm(alg, NULL)
+#else
+# define TEST(alg)
+# define TEST_HASH(alg)
+#endif // SELF_TEST
+/* 5.10.3 For Failures */
+#if defined _POSIX_
+# define FUNCTION_NAME __func__ /* libtpms changed */
+#else
+# define FUNCTION_NAME __FUNCTION__
+#endif
+#if !FAIL_TRACE
+# define FAIL(errorCode) (TpmFail(errorCode))
+# define LOG_FAILURE(errorCode) (TpmLogFailure(errorCode))
+#else
+# define FAIL(errorCode) TpmFail(FUNCTION_NAME, __LINE__, errorCode)
+# define LOG_FAILURE(errorCode) TpmLogFailure(FUNCTION_NAME, __LINE__, errorCode)
+#endif
+/* If implementation is using longjmp, then the call to TpmFail() does not return and the compiler
+ will complain about unreachable code that comes after. To allow for not having longjmp, TpmFail()
+ will return and the subsequent code will be executed. This macro accounts for the difference. */
+#ifndef NO_LONGJMP
+# define FAIL_RETURN(returnCode)
+# define TPM_FAIL_RETURN NORETURN void
+#else
+# define FAIL_RETURN(returnCode) return (returnCode)
+# define TPM_FAIL_RETURN void
+#endif
+/* This macro tests that a condition is TRUE and puts the TPM into failure mode if it is not. If
+ longjmp is being used, then the FAIL(FATAL_ERROR_) macro makes a call from which there is no
+ return. Otherwise, it returns and the function will exit with the appropriate return code. */
+#define REQUIRE(condition, errorCode, returnCode) \
+ { \
+ if(!!(condition)) \
+ { \
+ FAIL(FATAL_ERROR_errorCode); \
+ FAIL_RETURN(returnCode); \
+ } \
+ }
+#define PARAMETER_CHECK(condition, returnCode) \
+ REQUIRE((condition), PARAMETER, returnCode)
+#if defined EMPTY_ASSERT && (EMPTY_ASSERT != NO)
+# define pAssert(a) ((void)0)
+#else
+# define pAssert(a) {if(!(a)) FAIL(FATAL_ERROR_PARAMETER);}
+#endif
+/* 5.10.4 Derived from Vendor-specific values */
+/* Values derived from vendor specific settings in TpmProfile.h */
+#define PCR_SELECT_MIN ((PLATFORM_PCR+7)/8)
+#define PCR_SELECT_MAX ((IMPLEMENTATION_PCR+7)/8)
+#define MAX_ORDERLY_COUNT ((1 << ORDERLY_BITS) - 1)
+#define RSA_MAX_PRIME (MAX_RSA_KEY_BYTES / 2)
+#define RSA_PRIVATE_SIZE (RSA_MAX_PRIME * 5)
+
+/* 5.10.5 Compile-time Checks */
+/* In some cases, the relationship between two values may be dependent on things that change based
+ on various selections like the chosen cryptographic libraries. It is possible that these
+ selections will result in incompatible settings. These are often detectable by the compiler but
+ it isn't always possible to do the check in the preprocessor code. For example, when the check
+ requires use of sizeof then the preprocessor can't do the comparison. For these cases, we include
+ a special macro that, depending on the compiler will generate a warning to indicate if the check
+ always passes or always fails because it involves fixed constants. To run these checks, define
+ COMPILER_CHECKS in TpmBuildSwitches.h */
+#if COMPILER_CHECKS
+# define cAssert pAssert
+#else
+# define cAssert(value)
+#endif
+/* This is used commonly in the Crypt code as a way to keep listings from getting too long. This is
+ not to save paper but to allow one to see more useful stuff on the screen at any given time. */
+#define ERROR_RETURN(returnCode) \
+ { \
+ retVal = returnCode; \
+ goto Exit; \
+ }
+#ifndef MAX
+# define MAX(a, b) ((a) > (b) ? (a) : (b))
+#endif
+#ifndef MIN
+# define MIN(a, b) ((a) < (b) ? (a) : (b))
+#endif
+#ifndef IsOdd
+# define IsOdd(a) (((a) & 1) != 0)
+#endif
+#ifndef BITS_TO_BYTES
+# define BITS_TO_BYTES(bits) (((bits) + 7) >> 3)
+#endif
+#ifndef DIV_UP
+# define DIV_UP(var, div) ((var + div - 1) / (div))
+#endif
+/* These are defined for use when the size of the vector being checked is known at compile time. */
+#define TEST_BIT(bit, vector) TestBit((bit), (BYTE *)&(vector), sizeof(vector))
+#define SET_BIT(bit, vector) SetBit((bit), (BYTE *)&(vector), sizeof(vector))
+#define CLEAR_BIT(bit, vector) ClearBit((bit), (BYTE *)&(vector), sizeof(vector))
+/* The following definitions are used if they have not already been defined. The defaults for these
+ settings are compatible with ISO/IEC 9899:2011 (E) */
+#ifndef LIB_EXPORT
+# define LIB_EXPORT
+# define LIB_IMPORT
+#endif
+#ifndef NORETURN
+# define NORETURN _Noreturn
+#endif
+#ifndef NOT_REFERENCED
+# define NOT_REFERENCED(x = x) ((void) (x))
+#endif
+#define STD_RESPONSE_HEADER (sizeof(TPM_ST) + sizeof(UINT32) + sizeof(TPM_RC))
+#define JOIN(x,y) x##y
+#define JOIN3(x, y, z) x##y##z
+#define CONCAT(x,y) JOIN(x, y)
+#define CONCAT3(x, y, z) JOIN3(x,y,z)
+
+/* If CONTEXT_INTEGRITY_HASH_ALG is defined, then the vendor is using the old style
+ table. Otherwise, pick the strongest implemented hash algorithm as the context hash. */
+
+#ifndef CONTEXT_HASH_ALGORITHM
+# if defined ALG_SHA3_512 && ALG_SHA3_512 == YES
+# define CONTEXT_HASH_ALGORITHM SHA3_512
+# elif defined ALG_SHA512 && ALG_SHA512 == YES
+# define CONTEXT_HASH_ALGORITHM SHA512
+# elif defined ALG_SHA3_384 && ALG_SHA3_384 == YES
+# define CONTEXT_HASH_ALGORITHM SHA3_384
+# elif defined ALG_SHA384 && ALG_SHA384 == YES
+# define CONTEXT_HASH_ALGORITHM SHA384
+# elif defined ALG_SHA3_256 && ALG_SHA3_256 == YES
+# define CONTEXT_HASH_ALGORITHM SHA3_256
+# elif defined ALG_SHA256 && ALG_SHA256 == YES
+# define CONTEXT_HASH_ALGORITHM SHA256
+# elif defined ALG_SM3_256 && ALG_SM3_256 == YES
+# define CONTEXT_HASH_ALGORITHM SM3_256
+# elif defined ALG_SHA1 && ALG_SHA1 == YES
+# define CONTEXT_HASH_ALGORITHM SHA1
+# endif
+# define CONTEXT_INTEGRITY_HASH_ALG CONCAT(TPM_ALG_, CONTEXT_HASH_ALGORITHM)
+#if CONTEXT_HASH_ALGORITHM != SHA512 // libtpms added begin
+#error CONTEXT_HASH_ALGORITHM must remain SHA512
+#endif // libtpms added end
+#endif
+
+#ifndef CONTEXT_INTEGRITY_HASH_SIZE
+#define CONTEXT_INTEGRITY_HASH_SIZE CONCAT(CONTEXT_HASH_ALGORITHM, _DIGEST_SIZE)
+#endif
+#if ALG_RSA
+#define RSA_SECURITY_STRENGTH (MAX_RSA_KEY_BITS >= 15360 ? 256 : \
+ (MAX_RSA_KEY_BITS >= 7680 ? 192 : \
+ (MAX_RSA_KEY_BITS >= 3072 ? 128 : \
+ (MAX_RSA_KEY_BITS >= 2048 ? 112 : \
+ (MAX_RSA_KEY_BITS >= 1024 ? 80 : 0)))))
+#else
+#define RSA_SECURITY_STRENGTH 0
+#endif // ALG_RSA
+#if ALG_ECC
+#define ECC_SECURITY_STRENGTH (MAX_ECC_KEY_BITS >= 521 ? 256 : \
+ (MAX_ECC_KEY_BITS >= 384 ? 192 : \
+ (MAX_ECC_KEY_BITS >= 256 ? 128 : 0)))
+#else
+#define ECC_SECURITY_STRENGTH 0
+#endif // ALG_ECC
+#define MAX_ASYM_SECURITY_STRENGTH \
+ MAX(RSA_SECURITY_STRENGTH, ECC_SECURITY_STRENGTH)
+#define MAX_HASH_SECURITY_STRENGTH ((CONTEXT_INTEGRITY_HASH_SIZE * 8) / 2)
+
+/* Unless some algorithm is broken... */
+
+#define MAX_SYM_SECURITY_STRENGTH MAX_SYM_KEY_BITS
+#define MAX_SECURITY_STRENGTH_BITS \
+ MAX(MAX_ASYM_SECURITY_STRENGTH, \
+ MAX(MAX_SYM_SECURITY_STRENGTH, \
+ MAX_HASH_SECURITY_STRENGTH))
+/* This is the size that was used before the 1.38 errata requiring that P1.14.4 be followed */
+#define PROOF_SIZE CONTEXT_INTEGRITY_HASH_SIZE
+/* As required by P1.14.4 */
+#define COMPLIANT_PROOF_SIZE \
+ (MAX(CONTEXT_INTEGRITY_HASH_SIZE, (2 * MAX_SYM_KEY_BYTES)))
+/* As required by P1.14.3.1 */
+#define COMPLIANT_PRIMARY_SEED_SIZE \
+ BITS_TO_BYTES(MAX_SECURITY_STRENGTH_BITS * 2)
+/* This is the pre-errata version */
+#ifndef PRIMARY_SEED_SIZE
+# define PRIMARY_SEED_SIZE PROOF_SIZE
+#endif
+#if USE_SPEC_COMPLIANT_PROOFS
+# undef PROOF_SIZE
+# define PROOF_SIZE COMPLIANT_PROOF_SIZE
+# undef PRIMARY_SEED_SIZE
+# define PRIMARY_SEED_SIZE COMPLIANT_PRIMARY_SEED_SIZE
+#endif // USE_SPEC_COMPLIANT_PROOFS
+#if !SKIP_PROOF_ERRORS
+# if PROOF_SIZE < COMPLIANT_PROOF_SIZE
+# error "PROOF_SIZE is not compliant with TPM specification"
+# endif
+# if PRIMARY_SEED_SIZE < COMPLIANT_PRIMARY_SEED_SIZE
+# error "Non-compliant PRIMARY_SEED_SIZE"
+# endif
+#endif // !SKIP_PROOF_ERRORS
+
+/* If CONTEXT_ENCRYPT_ALG is defined, then the vendor is using the old style table */
+#if defined CONTEXT_ENCRYPT_ALG
+# undef CONTEXT_ENCRYPT_ALGORITHM
+# if CONTEXT_ENCRYPT_ALG == ALG_AES_VALUE
+# define CONTEXT_ENCRYPT_ALGORITHM AES
+# elif CONTEXT_ENCRYPT_ALG == ALG_SM4_VALUE
+# define CONTEXT_ENCRYPT_ALGORITHM SM4
+# elif CONTEXT_ENCRYPT_ALG == ALG_CAMELLIA_VALUE
+# define CONTEXT_ENCRYPT_ALGORITHM CAMELLIA
+# elif CONTEXT_ENCRYPT_ALG == ALG_TDES_VALUE
+# error Are you kidding?
+# else
+# error Unknown value for CONTEXT_ENCRYPT_ALG
+# endif // CONTEXT_ENCRYPT_ALG == ALG_AES_VALUE
+#else
+# define CONTEXT_ENCRYPT_ALG \
+ CONCAT3(ALG_, CONTEXT_ENCRYPT_ALGORITHM, _VALUE)
+#endif // CONTEXT_ENCRYPT_ALG
+#define CONTEXT_ENCRYPT_KEY_BITS \
+ CONCAT(CONTEXT_ENCRYPT_ALGORITHM, _MAX_KEY_SIZE_BITS)
+#define CONTEXT_ENCRYPT_KEY_BYTES ((CONTEXT_ENCRYPT_KEY_BITS+7)/8)
+
+/* This is updated to follow the requirement of P2 that the label not be larger than 32 bytes. */
+#ifndef LABEL_MAX_BUFFER
+#define LABEL_MAX_BUFFER MIN(32, MAX(MAX_ECC_KEY_BYTES, MAX_DIGEST_SIZE))
+#endif
+/* This bit is used to indicate that an authorization ticket expires on TPM Reset and TPM Restart.It
+ is added to the timeout value returned by TPM2_PoliySigned() and TPM2_PolicySecret() and used by
+ TPM2_PolicyTicket(). The timeout value is relative to Time (g_time). Time is reset whenever the
+ TPM loses power and cannot be moved forward by the user (as can Clock). g_time is a 64-bit value
+ expressing time in ms. Stealing the MSb() for a flag means that the TPM needs to be reset at least
+ once every 292,471,208 years rather than once every 584,942,417 years. */
+#define EXPIRATION_BIT ((UINT64)1 << 63)
+/* Check for consistency of the bit ordering of bit fields */
+#if BIG_ENDIAN_TPM && MOST_SIGNIFICANT_BIT_0 && USE_BIT_FIELD_STRUCTURES
+# error "Settings not consistent"
+#endif
+/* These macros are used to handle the variation in handling of bit fields. If */
+#if USE_BIT_FIELD_STRUCTURES // The default, old version, with bit fields
+# define IS_ATTRIBUTE(a, type, b) ((a.b) != 0)
+# define SET_ATTRIBUTE(a, type, b) (a.b = SET)
+# define CLEAR_ATTRIBUTE(a, type, b) (a.b = CLEAR)
+# define GET_ATTRIBUTE(a, type, b) (a.b)
+# define TPMA_ZERO_INITIALIZER() {0}
+#else
+# define IS_ATTRIBUTE(a, type, b) ((a & type##_##b) != 0)
+# define SET_ATTRIBUTE(a, type, b) (a |= type##_##b)
+# define CLEAR_ATTRIBUTE(a, type, b) (a &= ~type##_##b)
+# define GET_ATTRIBUTE(a, type, b) \
+ (type)((a & type##_##b) >> type##_##b##_SHIFT)
+# define TPMA_ZERO_INITIALIZER() (0)
+#endif
+#define VERIFY(_X) if(!(_X)) goto Error
+// These macros determine if the values in this file are referenced or instanced.
+// Global.c defines GLOBAL_C so all the values in this file will be instanced in
+// Global.obj. For all other files that include this file, the values will simply
+// be external references. For constants, there can be an initializer.
+
+#ifdef GLOBAL_C
+#define EXTERN
+#define INITIALIZER(_value_) = _value_
+#else
+#define EXTERN extern
+#define INITIALIZER(_value_)
+#endif
+
+// This macro will create an OID. All OIDs are in DER form with a first octet of
+// 0x06 indicating an OID fallowed by an octet indicating the number of octets in the
+// rest of the OID. This allows a user of this OID to know how much/little to copy.
+#define MAKE_OID(NAME) \
+ EXTERN const BYTE OID##NAME[] INITIALIZER({OID##NAME##_VALUE})
+
+/* This definition is moved from TpmProfile.h because it is not actually vendor- specific. It has to
+ be the same size as the sequence parameter of a TPMS_CONTEXT and that is a UINT64. So, this is an
+ invariant value */
+#define CONTEXT_COUNTER UINT64
+
+#endif // GP_MACROS_H
diff --git a/src/tpm2/HMAC_Start_fp.h b/src/tpm2/HMAC_Start_fp.h
new file mode 100644
index 0000000..a05ddf1
--- /dev/null
+++ b/src/tpm2/HMAC_Start_fp.h
@@ -0,0 +1,88 @@
+/********************************************************************************/
+/* */
+/* */
+/* Written by Ken Goldman */
+/* IBM Thomas J. Watson Research Center */
+/* $Id: HMAC_Start_fp.h 809 2016-11-16 18:31:54Z kgoldman $ */
+/* */
+/* Licenses and Notices */
+/* */
+/* 1. Copyright Licenses: */
+/* */
+/* - Trusted Computing Group (TCG) grants to the user of the source code in */
+/* this specification (the "Source Code") a worldwide, irrevocable, */
+/* nonexclusive, royalty free, copyright license to reproduce, create */
+/* derivative works, distribute, display and perform the Source Code and */
+/* derivative works thereof, and to grant others the rights granted herein. */
+/* */
+/* - The TCG grants to the user of the other parts of the specification */
+/* (other than the Source Code) the rights to reproduce, distribute, */
+/* display, and perform the specification solely for the purpose of */
+/* developing products based on such documents. */
+/* */
+/* 2. Source Code Distribution Conditions: */
+/* */
+/* - Redistributions of Source Code must retain the above copyright licenses, */
+/* this list of conditions and the following disclaimers. */
+/* */
+/* - Redistributions in binary form must reproduce the above copyright */
+/* licenses, this list of conditions and the following disclaimers in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* 3. Disclaimers: */
+/* */
+/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
+/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
+/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
+/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
+/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
+/* information on specification licensing rights available through TCG */
+/* membership agreements. */
+/* */
+/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
+/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
+/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
+/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
+/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
+/* */
+/* - Without limitation, TCG and its members and licensors disclaim all */
+/* liability, including liability for infringement of any proprietary */
+/* rights, relating to use of information in this specification and to the */
+/* implementation of this specification, and TCG disclaims all liability for */
+/* cost of procurement of substitute goods or services, lost profits, loss */
+/* of use, loss of data or any incidental, consequential, direct, indirect, */
+/* or special damages, whether under contract, tort, warranty or otherwise, */
+/* arising in any way out of use or reliance upon this specification or any */
+/* information herein. */
+/* */
+/* (c) Copyright IBM Corp. and others, 2012-2015 */
+/* */
+/********************************************************************************/
+
+/* rev 119 */
+
+#ifndef HMAC_START_FP_H
+#define HMAC_START_FP_H
+
+typedef struct {
+ TPMI_DH_OBJECT handle;
+ TPM2B_AUTH auth;
+ TPMI_ALG_HASH hashAlg;
+} HMAC_Start_In;
+
+typedef struct {
+ TPMI_DH_OBJECT sequenceHandle;
+} HMAC_Start_Out;
+
+#define RC_HMAC_Start_handle (TPM_RC_H + TPM_RC_1)
+#define RC_HMAC_Start_auth (TPM_RC_P + TPM_RC_1)
+#define RC_HMAC_Start_hashAlg (TPM_RC_P + TPM_RC_2)
+
+TPM_RC
+TPM2_HMAC_Start(
+ HMAC_Start_In *in, // IN: input parameter list
+ HMAC_Start_Out *out // OUT: output parameter list
+ );
+
+
+#endif
diff --git a/src/tpm2/HMAC_fp.h b/src/tpm2/HMAC_fp.h
new file mode 100644
index 0000000..deb4fc2
--- /dev/null
+++ b/src/tpm2/HMAC_fp.h
@@ -0,0 +1,88 @@
+/********************************************************************************/
+/* */
+/* */
+/* Written by Ken Goldman */
+/* IBM Thomas J. Watson Research Center */
+/* $Id: HMAC_fp.h 1521 2019-11-15 21:00:47Z kgoldman $ */
+/* */
+/* Licenses and Notices */
+/* */
+/* 1. Copyright Licenses: */
+/* */
+/* - Trusted Computing Group (TCG) grants to the user of the source code in */
+/* this specification (the "Source Code") a worldwide, irrevocable, */
+/* nonexclusive, royalty free, copyright license to reproduce, create */
+/* derivative works, distribute, display and perform the Source Code and */
+/* derivative works thereof, and to grant others the rights granted herein. */
+/* */
+/* - The TCG grants to the user of the other parts of the specification */
+/* (other than the Source Code) the rights to reproduce, distribute, */
+/* display, and perform the specification solely for the purpose of */
+/* developing products based on such documents. */
+/* */
+/* 2. Source Code Distribution Conditions: */
+/* */
+/* - Redistributions of Source Code must retain the above copyright licenses, */
+/* this list of conditions and the following disclaimers. */
+/* */
+/* - Redistributions in binary form must reproduce the above copyright */
+/* licenses, this list of conditions and the following disclaimers in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* 3. Disclaimers: */
+/* */
+/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
+/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
+/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
+/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
+/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
+/* information on specification licensing rights available through TCG */
+/* membership agreements. */
+/* */
+/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
+/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
+/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
+/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
+/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
+/* */
+/* - Without limitation, TCG and its members and licensors disclaim all */
+/* liability, including liability for infringement of any proprietary */
+/* rights, relating to use of information in this specification and to the */
+/* implementation of this specification, and TCG disclaims all liability for */
+/* cost of procurement of substitute goods or services, lost profits, loss */
+/* of use, loss of data or any incidental, consequential, direct, indirect, */
+/* or special damages, whether under contract, tort, warranty or otherwise, */
+/* arising in any way out of use or reliance upon this specification or any */
+/* information herein. */
+/* */
+/* (c) Copyright IBM Corp. and others, 2012-2015 */
+/* */
+/********************************************************************************/
+
+/* rev 119 */
+
+#ifndef HMAC_FP_H
+#define HMAC_FP_H
+
+typedef struct {
+ TPMI_DH_OBJECT handle;
+ TPM2B_MAX_BUFFER buffer;
+ TPMI_ALG_HASH hashAlg;
+} HMAC_In;
+
+#define RC_HMAC_handle (TPM_RC_H + TPM_RC_1)
+#define RC_HMAC_buffer (TPM_RC_P + TPM_RC_1)
+#define RC_HMAC_hashAlg (TPM_RC_P + TPM_RC_2)
+
+typedef struct {
+ TPM2B_DIGEST outHMAC;
+} HMAC_Out;
+
+TPM_RC
+TPM2_HMAC(
+ HMAC_In *in, // IN: input parameter list
+ HMAC_Out *out // OUT: output parameter list
+ );
+
+
+#endif
diff --git a/src/tpm2/Handle.c b/src/tpm2/Handle.c
new file mode 100644
index 0000000..d762135
--- /dev/null
+++ b/src/tpm2/Handle.c
@@ -0,0 +1,213 @@
+/********************************************************************************/
+/* */
+/* fUnctions that return the type of a handle. */
+/* Written by Ken Goldman */
+/* IBM Thomas J. Watson Research Center */
+/* $Id: Handle.c 1519 2019-11-15 20:43:51Z kgoldman $ */
+/* */
+/* Licenses and Notices */
+/* */
+/* 1. Copyright Licenses: */
+/* */
+/* - Trusted Computing Group (TCG) grants to the user of the source code in */
+/* this specification (the "Source Code") a worldwide, irrevocable, */
+/* nonexclusive, royalty free, copyright license to reproduce, create */
+/* derivative works, distribute, display and perform the Source Code and */
+/* derivative works thereof, and to grant others the rights granted herein. */
+/* */
+/* - The TCG grants to the user of the other parts of the specification */
+/* (other than the Source Code) the rights to reproduce, distribute, */
+/* display, and perform the specification solely for the purpose of */
+/* developing products based on such documents. */
+/* */
+/* 2. Source Code Distribution Conditions: */
+/* */
+/* - Redistributions of Source Code must retain the above copyright licenses, */
+/* this list of conditions and the following disclaimers. */
+/* */
+/* - Redistributions in binary form must reproduce the above copyright */
+/* licenses, this list of conditions and the following disclaimers in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* 3. Disclaimers: */
+/* */
+/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
+/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
+/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
+/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
+/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
+/* information on specification licensing rights available through TCG */
+/* membership agreements. */
+/* */
+/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
+/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
+/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
+/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
+/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
+/* */
+/* - Without limitation, TCG and its members and licensors disclaim all */
+/* liability, including liability for infringement of any proprietary */
+/* rights, relating to use of information in this specification and to the */
+/* implementation of this specification, and TCG disclaims all liability for */
+/* cost of procurement of substitute goods or services, lost profits, loss */
+/* of use, loss of data or any incidental, consequential, direct, indirect, */
+/* or special damages, whether under contract, tort, warranty or otherwise, */
+/* arising in any way out of use or reliance upon this specification or any */
+/* information herein. */
+/* */
+/* (c) Copyright IBM Corp. and others, 2016 - 2019 */
+/* */
+/********************************************************************************/
+
+/* 9.6 Handle.c */
+/* 9.6.1 Description */
+/* This file contains the functions that return the type of a handle. */
+/* 9.6.2 Includes */
+#include "Tpm.h"
+/* 9.6.3 Functions */
+/* 9.6.3.1 HandleGetType() */
+/* This function returns the type of a handle which is the MSO of the handle. */
+TPM_HT
+HandleGetType(
+ TPM_HANDLE handle // IN: a handle to be checked
+ )
+{
+ // return the upper bytes of input data
+ return (TPM_HT)((handle & HR_RANGE_MASK) >> HR_SHIFT);
+}
+/* 9.6.3.2 NextPermanentHandle() */
+/* This function returns the permanent handle that is equal to the input value or is the next higher
+ value. If there is no handle with the input value and there is no next higher value, it returns
+ 0: */
+TPM_HANDLE
+NextPermanentHandle(
+ TPM_HANDLE inHandle // IN: the handle to check
+ )
+{
+ // If inHandle is below the start of the range of permanent handles
+ // set it to the start and scan from there
+ if(inHandle < TPM_RH_FIRST)
+ inHandle = TPM_RH_FIRST;
+ // scan from input value until we find an implemented permanent handle
+ // or go out of range
+ for(; inHandle <= TPM_RH_LAST; inHandle++)
+ {
+ switch(inHandle)
+ {
+ case TPM_RH_OWNER:
+ case TPM_RH_NULL:
+ case TPM_RS_PW:
+ case TPM_RH_LOCKOUT:
+ case TPM_RH_ENDORSEMENT:
+ case TPM_RH_PLATFORM:
+ case TPM_RH_PLATFORM_NV:
+#ifdef VENDOR_PERMANENT
+ case VENDOR_PERMANENT:
+#endif
+ // Each of the implemented ACT
+#define ACT_IMPLEMENTED_CASE(N) \
+ case TPM_RH_ACT_##N:
+
+ FOR_EACH_ACT(ACT_IMPLEMENTED_CASE)
+
+ return inHandle;
+ break;
+ default:
+ break;
+ }
+ }
+ // Out of range on the top
+ return 0;
+}
+/* 9.6.3.3 PermanentCapGetHandles() */
+/* This function returns a list of the permanent handles of PCR, started from handle. If handle is
+ larger than the largest permanent handle, an empty list will be returned with more set to NO. */
+/* Return Values Meaning */
+/* YES if there are more handles available */
+/* NO all the available handles has been returned */
+TPMI_YES_NO
+PermanentCapGetHandles(
+ TPM_HANDLE handle, // IN: start handle
+ UINT32 count, // IN: count of returned handles
+ TPML_HANDLE *handleList // OUT: list of handle
+ )
+{
+ TPMI_YES_NO more = NO;
+ UINT32 i;
+ pAssert(HandleGetType(handle) == TPM_HT_PERMANENT);
+ // Initialize output handle list
+ handleList->count = 0;
+ // The maximum count of handles we may return is MAX_CAP_HANDLES
+ if(count > MAX_CAP_HANDLES) count = MAX_CAP_HANDLES;
+ // Iterate permanent handle range
+ for(i = NextPermanentHandle(handle);
+ i != 0; i = NextPermanentHandle(i + 1))
+ {
+ if(handleList->count < count)
+ {
+ // If we have not filled up the return list, add this permanent
+ // handle to it
+ handleList->handle[handleList->count] = i;
+ handleList->count++;
+ }
+ else
+ {
+ // If the return list is full but we still have permanent handle
+ // available, report this and stop iterating
+ more = YES;
+ break;
+ }
+ }
+ return more;
+}
+/* 9.6.3.4 PermanentHandleGetPolicy() */
+/* This function returns a list of the permanent handles of PCR, started from handle. If handle is
+ larger than the largest permanent handle, an empty list will be returned with more set to NO. */
+/* Return Values Meaning */
+/* YES if there are more handles available */
+/* NO all the available handles has been returned */
+TPMI_YES_NO
+PermanentHandleGetPolicy(
+ TPM_HANDLE handle, // IN: start handle
+ UINT32 count, // IN: max count of returned handles
+ TPML_TAGGED_POLICY *policyList // OUT: list of handle
+ )
+{
+ TPMI_YES_NO more = NO;
+ pAssert(HandleGetType(handle) == TPM_HT_PERMANENT);
+ // Initialize output handle list
+ policyList->count = 0;
+ // The maximum count of policies we may return is MAX_TAGGED_POLICIES
+ if(count > MAX_TAGGED_POLICIES)
+ count = MAX_TAGGED_POLICIES;
+ // Iterate permanent handle range
+ for(handle = NextPermanentHandle(handle);
+ handle != 0;
+ handle = NextPermanentHandle(handle + 1))
+ {
+ TPM2B_DIGEST policyDigest;
+ TPM_ALG_ID policyAlg;
+ // Check to see if this permanent handle has a policy
+ policyAlg = EntityGetAuthPolicy(handle, &policyDigest);
+ if(policyAlg == TPM_ALG_ERROR)
+ continue;
+ if(policyList->count < count)
+ {
+ // If we have not filled up the return list, add this
+ // policy to the list;
+ policyList->policies[policyList->count].handle = handle;
+ policyList->policies[policyList->count].policyHash.hashAlg = policyAlg;
+ MemoryCopy(&policyList->policies[policyList->count].policyHash.digest,
+ policyDigest.t.buffer, policyDigest.t.size);
+ policyList->count++;
+ }
+ else
+ {
+ // If the return list is full but we still have permanent handle
+ // available, report this and stop iterating
+ more = YES;
+ break;
+ }
+ }
+ return more;
+}
diff --git a/src/tpm2/Handle_fp.h b/src/tpm2/Handle_fp.h
new file mode 100644
index 0000000..fa6bc83
--- /dev/null
+++ b/src/tpm2/Handle_fp.h
@@ -0,0 +1,87 @@
+/********************************************************************************/
+/* */
+/* */
+/* Written by Ken Goldman */
+/* IBM Thomas J. Watson Research Center */
+/* $Id: Handle_fp.h 1490 2019-07-26 21:13:22Z kgoldman $ */
+/* */
+/* Licenses and Notices */
+/* */
+/* 1. Copyright Licenses: */
+/* */
+/* - Trusted Computing Group (TCG) grants to the user of the source code in */
+/* this specification (the "Source Code") a worldwide, irrevocable, */
+/* nonexclusive, royalty free, copyright license to reproduce, create */
+/* derivative works, distribute, display and perform the Source Code and */
+/* derivative works thereof, and to grant others the rights granted herein. */
+/* */
+/* - The TCG grants to the user of the other parts of the specification */
+/* (other than the Source Code) the rights to reproduce, distribute, */
+/* display, and perform the specification solely for the purpose of */
+/* developing products based on such documents. */
+/* */
+/* 2. Source Code Distribution Conditions: */
+/* */
+/* - Redistributions of Source Code must retain the above copyright licenses, */
+/* this list of conditions and the following disclaimers. */
+/* */
+/* - Redistributions in binary form must reproduce the above copyright */
+/* licenses, this list of conditions and the following disclaimers in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* 3. Disclaimers: */
+/* */
+/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
+/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
+/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
+/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
+/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
+/* information on specification licensing rights available through TCG */
+/* membership agreements. */
+/* */
+/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
+/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
+/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
+/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
+/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
+/* */
+/* - Without limitation, TCG and its members and licensors disclaim all */
+/* liability, including liability for infringement of any proprietary */
+/* rights, relating to use of information in this specification and to the */
+/* implementation of this specification, and TCG disclaims all liability for */
+/* cost of procurement of substitute goods or services, lost profits, loss */
+/* of use, loss of data or any incidental, consequential, direct, indirect, */
+/* or special damages, whether under contract, tort, warranty or otherwise, */
+/* arising in any way out of use or reliance upon this specification or any */
+/* information herein. */
+/* */
+/* (c) Copyright IBM Corp. and others, 2016 */
+/* */
+/********************************************************************************/
+
+#ifndef HANDLE_FP_H
+#define HANDLE_FP_H
+
+TPM_HT
+HandleGetType(
+ TPM_HANDLE handle // IN: a handle to be checked
+ );
+TPM_HANDLE
+NextPermanentHandle(
+ TPM_HANDLE inHandle // IN: the handle to check
+ );
+TPMI_YES_NO
+PermanentCapGetHandles(
+ TPM_HANDLE handle, // IN: start handle
+ UINT32 count, // IN: count of returned handles
+ TPML_HANDLE *handleList // OUT: list of handle
+ );
+TPMI_YES_NO
+PermanentHandleGetPolicy(
+ TPM_HANDLE handle, // IN: start handle
+ UINT32 count, // IN: count of returned handles
+ TPML_TAGGED_POLICY *policyList // OUT: list of handle
+ );
+
+
+#endif
diff --git a/src/tpm2/HashCommands.c b/src/tpm2/HashCommands.c
new file mode 100644
index 0000000..ba74cc3
--- /dev/null
+++ b/src/tpm2/HashCommands.c
@@ -0,0 +1,381 @@
+/********************************************************************************/
+/* */
+/* Hash/HMAC/Event Sequences */
+/* Written by Ken Goldman */
+/* IBM Thomas J. Watson Research Center */
+/* $Id: HashCommands.c 1490 2019-07-26 21:13:22Z kgoldman $ */
+/* */
+/* Licenses and Notices */
+/* */
+/* 1. Copyright Licenses: */
+/* */
+/* - Trusted Computing Group (TCG) grants to the user of the source code in */
+/* this specification (the "Source Code") a worldwide, irrevocable, */
+/* nonexclusive, royalty free, copyright license to reproduce, create */
+/* derivative works, distribute, display and perform the Source Code and */
+/* derivative works thereof, and to grant others the rights granted herein. */
+/* */
+/* - The TCG grants to the user of the other parts of the specification */
+/* (other than the Source Code) the rights to reproduce, distribute, */
+/* display, and perform the specification solely for the purpose of */
+/* developing products based on such documents. */
+/* */
+/* 2. Source Code Distribution Conditions: */
+/* */
+/* - Redistributions of Source Code must retain the above copyright licenses, */
+/* this list of conditions and the following disclaimers. */
+/* */
+/* - Redistributions in binary form must reproduce the above copyright */
+/* licenses, this list of conditions and the following disclaimers in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* 3. Disclaimers: */
+/* */
+/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
+/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
+/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
+/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
+/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
+/* information on specification licensing rights available through TCG */
+/* membership agreements. */
+/* */
+/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
+/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
+/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
+/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
+/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
+/* */
+/* - Without limitation, TCG and its members and licensors disclaim all */
+/* liability, including liability for infringement of any proprietary */
+/* rights, relating to use of information in this specification and to the */
+/* implementation of this specification, and TCG disclaims all liability for */
+/* cost of procurement of substitute goods or services, lost profits, loss */
+/* of use, loss of data or any incidental, consequential, direct, indirect, */
+/* or special damages, whether under contract, tort, warranty or otherwise, */
+/* arising in any way out of use or reliance upon this specification or any */
+/* information herein. */
+/* */
+/* (c) Copyright IBM Corp. and others, 2016 - 2018 */
+/* */
+/********************************************************************************/
+
+#include "Tpm.h"
+#include "HMAC_Start_fp.h"
+#if CC_HMAC_Start // Conditional expansion of this file
+TPM_RC
+TPM2_HMAC_Start(
+ HMAC_Start_In *in, // IN: input parameter list
+ HMAC_Start_Out *out // OUT: output parameter list
+ )
+{
+ OBJECT *keyObject;
+ TPMT_PUBLIC *publicArea;
+ TPM_ALG_ID hashAlg;
+ // Input Validation
+ // Get HMAC key object and public area pointers
+ keyObject = HandleToObject(in->handle);
+ publicArea = &keyObject->publicArea;
+ // Make sure that the key is an HMAC key
+ if(publicArea->type != TPM_ALG_KEYEDHASH)
+ return TPM_RCS_TYPE + RC_HMAC_Start_handle;
+ // and that it is unrestricted
+ if (IS_ATTRIBUTE(publicArea->objectAttributes, TPMA_OBJECT, restricted))
+ return TPM_RCS_ATTRIBUTES + RC_HMAC_Start_handle;
+ // and that it is a signing key
+ if (!IS_ATTRIBUTE(publicArea->objectAttributes, TPMA_OBJECT, sign))
+ return TPM_RCS_KEY + RC_HMAC_Start_handle;
+ // See if the key has a default
+ if(publicArea->parameters.keyedHashDetail.scheme.scheme == TPM_ALG_NULL)
+ // it doesn't so use the input value
+ hashAlg = in->hashAlg;
+ else
+ {
+ // key has a default so use it
+ hashAlg
+ = publicArea->parameters.keyedHashDetail.scheme.details.hmac.hashAlg;
+ // and verify that the input was either the TPM_ALG_NULL or the default
+ if(in->hashAlg != TPM_ALG_NULL && in->hashAlg != hashAlg)
+ hashAlg = TPM_ALG_NULL;
+ }
+ // if we ended up without a hash algorithm then return an error
+ if(hashAlg == TPM_ALG_NULL)
+ return TPM_RCS_VALUE + RC_HMAC_Start_hashAlg;
+ // Internal Data Update
+ // Create a HMAC sequence object. A TPM_RC_OBJECT_MEMORY error may be
+ // returned at this point
+ return ObjectCreateHMACSequence(hashAlg,
+ keyObject,
+ &in->auth,
+ &out->sequenceHandle);
+}
+#endif // CC_HMAC_Start
+#include "Tpm.h"
+#include "MAC_Start_fp.h"
+#if CC_MAC_Start // Conditional expansion of this file
+/* Error Returns Meaning */
+/* TPM_RC_ATTRIBUTES key referenced by handle is not a signing key or is restricted */
+/* TPM_RC_OBJECT_MEMORY no space to create an internal object */
+/* TPM_RC_KEY key referenced by handle is not an HMAC key */
+/* TPM_RC_VALUE hashAlg is not compatible with the hash algorithm of the scheme of the object
+ referenced by handle */
+TPM_RC
+TPM2_MAC_Start(
+ MAC_Start_In *in, // IN: input parameter list
+ MAC_Start_Out *out // OUT: output parameter list
+ )
+{
+ OBJECT *keyObject;
+ TPMT_PUBLIC *publicArea;
+ TPM_RC result;
+ // Input Validation
+ // Get HMAC key object and public area pointers
+ keyObject = HandleToObject(in->handle);
+ publicArea = &keyObject->publicArea;
+ // Make sure that the key can do what is required
+ result = CryptSelectMac(publicArea, &in->inScheme);
+ // If the key is not able to do a MAC, indicate that the handle selects an
+ // object that can't do a MAC
+ if(result == TPM_RCS_TYPE)
+ return TPM_RCS_TYPE + RC_MAC_Start_handle;
+ // If there is another error type, indicate that the scheme and key are not
+ // compatible
+ if(result != TPM_RC_SUCCESS)
+ return RcSafeAddToResult(result, RC_MAC_Start_inScheme);
+ // Make sure that the key is not restricted
+ if(IS_ATTRIBUTE(publicArea->objectAttributes, TPMA_OBJECT, restricted))
+ return TPM_RCS_ATTRIBUTES + RC_MAC_Start_handle;
+ // and that it is a signing key
+ if(!IS_ATTRIBUTE(publicArea->objectAttributes, TPMA_OBJECT, sign))
+ return TPM_RCS_KEY + RC_MAC_Start_handle;
+ // Internal Data Update
+ // Create a HMAC sequence object. A TPM_RC_OBJECT_MEMORY error may be
+ // returned at this point
+ return ObjectCreateHMACSequence(in->inScheme,
+ keyObject,
+ &in->auth,
+ &out->sequenceHandle);
+}
+#endif // CC_MAC_Start
+#include "Tpm.h"
+#include "HashSequenceStart_fp.h"
+#if CC_HashSequenceStart // Conditional expansion of this file
+TPM_RC
+TPM2_HashSequenceStart(
+ HashSequenceStart_In *in, // IN: input parameter list
+ HashSequenceStart_Out *out // OUT: output parameter list
+ )
+{
+ // Internal Data Update
+ if(in->hashAlg == TPM_ALG_NULL)
+ // Start a event sequence. A TPM_RC_OBJECT_MEMORY error may be
+ // returned at this point
+ return ObjectCreateEventSequence(&in->auth, &out->sequenceHandle);
+ // Start a hash sequence. A TPM_RC_OBJECT_MEMORY error may be
+ // returned at this point
+ return ObjectCreateHashSequence(in->hashAlg, &in->auth, &out->sequenceHandle);
+}
+#endif // CC_HashSequenceStart
+#include "Tpm.h"
+#include "SequenceUpdate_fp.h"
+#if CC_SequenceUpdate // Conditional expansion of this file
+TPM_RC
+TPM2_SequenceUpdate(
+ SequenceUpdate_In *in // IN: input parameter list
+ )
+{
+ OBJECT *object;
+ HASH_OBJECT *hashObject;
+ // Input Validation
+ // Get sequence object pointer
+ object = HandleToObject(in->sequenceHandle);
+ hashObject = (HASH_OBJECT *)object;
+ // Check that referenced object is a sequence object.
+ if(!ObjectIsSequence(object))
+ return TPM_RCS_MODE + RC_SequenceUpdate_sequenceHandle;
+ // Internal Data Update
+ if(object->attributes.eventSeq == SET)
+ {
+ // Update event sequence object
+ UINT32 i;
+ for(i = 0; i < HASH_COUNT; i++)
+ {
+ // Update sequence object
+ CryptDigestUpdate2B(&hashObject->state.hashState[i], &in->buffer.b);
+ }
+ }
+ else
+ {
+ // Update hash/HMAC sequence object
+ if(hashObject->attributes.hashSeq == SET)
+ {
+ // Is this the first block of the sequence
+ if(hashObject->attributes.firstBlock == CLEAR)
+ {
+ // If so, indicate that first block was received
+ hashObject->attributes.firstBlock = SET;
+ // Check the first block to see if the first block can contain
+ // the TPM_GENERATED_VALUE. If it does, it is not safe for
+ // a ticket.
+ if(TicketIsSafe(&in->buffer.b))
+ hashObject->attributes.ticketSafe = SET;
+ }
+ // Update sequence object hash/HMAC stack
+ CryptDigestUpdate2B(&hashObject->state.hashState[0], &in->buffer.b);
+ }
+ else if(object->attributes.hmacSeq == SET)
+ {
+ // Update sequence object HMAC stack
+ CryptDigestUpdate2B(&hashObject->state.hmacState.hashState,
+ &in->buffer.b);
+ }
+ }
+ return TPM_RC_SUCCESS;
+}
+#endif // CC_SequenceUpdate
+#include "Tpm.h"
+#include "SequenceComplete_fp.h"
+#if CC_SequenceComplete // Conditional expansion of this file
+/* Error Returns Meaning */
+/* TPM_RC_MODE sequenceHandle does not reference a hash or HMAC sequence object */
+TPM_RC
+TPM2_SequenceComplete(
+ SequenceComplete_In *in, // IN: input parameter list
+ SequenceComplete_Out *out // OUT: output parameter list
+ )
+{
+ HASH_OBJECT *hashObject;
+ // Input validation
+ // Get hash object pointer
+ hashObject = (HASH_OBJECT *)HandleToObject(in->sequenceHandle);
+ // input handle must be a hash or HMAC sequence object.
+ if(hashObject->attributes.hashSeq == CLEAR
+ && hashObject->attributes.hmacSeq == CLEAR)
+ return TPM_RCS_MODE + RC_SequenceComplete_sequenceHandle;
+ // Command Output
+ if(hashObject->attributes.hashSeq == SET) // sequence object for hash
+ {
+ // Get the hash algorithm before the algorithm is lost in CryptHashEnd
+ TPM_ALG_ID hashAlg = hashObject->state.hashState[0].hashAlg;
+ // Update last piece of the data
+ CryptDigestUpdate2B(&hashObject->state.hashState[0], &in->buffer.b);
+ // Complete hash
+ out->result.t.size = CryptHashEnd(&hashObject->state.hashState[0],
+ sizeof(out->result.t.buffer),
+ out->result.t.buffer);
+ // Check if the first block of the sequence has been received
+ if(hashObject->attributes.firstBlock == CLEAR)
+ {
+ // If not, then this is the first block so see if it is 'safe'
+ // to sign.
+ if(TicketIsSafe(&in->buffer.b))
+ hashObject->attributes.ticketSafe = SET;
+ }
+ // Output ticket
+ out->validation.tag = TPM_ST_HASHCHECK;
+ out->validation.hierarchy = in->hierarchy;
+ if(in->hierarchy == TPM_RH_NULL)
+ {
+ // Ticket is not required
+ out->validation.digest.t.size = 0;
+ }
+ else if(hashObject->attributes.ticketSafe == CLEAR)
+ {
+ // Ticket is not safe to generate
+ out->validation.hierarchy = TPM_RH_NULL;
+ out->validation.digest.t.size = 0;
+ }
+ else
+ {
+ // Compute ticket
+ TicketComputeHashCheck(out->validation.hierarchy, hashAlg,
+ &out->result, &out->validation);
+ }
+ }
+ else
+ {
+ // Update last piece of data
+ CryptDigestUpdate2B(&hashObject->state.hmacState.hashState, &in->buffer.b);
+#if !SMAC_IMPLEMENTED
+ // Complete HMAC
+ out->result.t.size = CryptHmacEnd(&(hashObject->state.hmacState),
+ sizeof(out->result.t.buffer),
+ out->result.t.buffer);
+#else
+ // Complete the MAC
+ out->result.t.size = CryptMacEnd(&hashObject->state.hmacState,
+ sizeof(out->result.t.buffer),
+ out->result.t.buffer);
+#endif
+ // No ticket is generated for HMAC sequence
+ out->validation.tag = TPM_ST_HASHCHECK;
+ out->validation.hierarchy = TPM_RH_NULL;
+ out->validation.digest.t.size = 0;
+ }
+ // Internal Data Update
+ // mark sequence object as evict so it will be flushed on the way out
+ hashObject->attributes.evict = SET;
+ return TPM_RC_SUCCESS;
+}
+#endif // CC_SequenceComplete
+#include "Tpm.h"
+#include "EventSequenceComplete_fp.h"
+#if CC_EventSequenceComplete // Conditional expansion of this file
+TPM_RC
+TPM2_EventSequenceComplete(
+ EventSequenceComplete_In *in, // IN: input parameter list
+ EventSequenceComplete_Out *out // OUT: output parameter list
+ )
+{
+ HASH_OBJECT *hashObject;
+ UINT32 i;
+ TPM_ALG_ID hashAlg;
+ // Input validation
+ // get the event sequence object pointer
+ hashObject = (HASH_OBJECT *)HandleToObject(in->sequenceHandle);
+ // input handle must reference an event sequence object
+ if(hashObject->attributes.eventSeq != SET)
+ return TPM_RCS_MODE + RC_EventSequenceComplete_sequenceHandle;
+ // see if a PCR extend is requested in call
+ if(in->pcrHandle != TPM_RH_NULL)
+ {
+ // see if extend of the PCR is allowed at the locality of the command,
+ if(!PCRIsExtendAllowed(in->pcrHandle))
+ return TPM_RC_LOCALITY;
+ // if an extend is going to take place, then check to see if there has
+ // been an orderly shutdown. If so, and the selected PCR is one of the
+ // state saved PCR, then the orderly state has to change. The orderly state
+ // does not change for PCR that are not preserved.
+ // NOTE: This doesn't just check for Shutdown(STATE) because the orderly
+ // state will have to change if this is a state-saved PCR regardless
+ // of the current state. This is because a subsequent Shutdown(STATE) will
+ // check to see if there was an orderly shutdown and not do anything if
+ // there was. So, this must indicate that a future Shutdown(STATE) has
+ // something to do.
+ if(PCRIsStateSaved(in->pcrHandle))
+ RETURN_IF_ORDERLY;
+ }
+ // Command Output
+ out->results.count = 0;
+ for(i = 0; i < HASH_COUNT; i++)
+ {
+ hashAlg = CryptHashGetAlgByIndex(i);
+ // Update last piece of data
+ CryptDigestUpdate2B(&hashObject->state.hashState[i], &in->buffer.b);
+ // Complete hash
+ out->results.digests[out->results.count].hashAlg = hashAlg;
+ CryptHashEnd(&hashObject->state.hashState[i],
+ CryptHashGetDigestSize(hashAlg),
+ (BYTE *)&out->results.digests[out->results.count].digest);
+ // Extend PCR
+ if(in->pcrHandle != TPM_RH_NULL)
+ PCRExtend(in->pcrHandle, hashAlg,
+ CryptHashGetDigestSize(hashAlg),
+ (BYTE *)&out->results.digests[out->results.count].digest);
+ out->results.count++;
+ }
+ // Internal Data Update
+ // mark sequence object as evict so it will be flushed on the way out
+ hashObject->attributes.evict = SET;
+ return TPM_RC_SUCCESS;
+}
+#endif // CC_EventSequenceComplete
diff --git a/src/tpm2/HashSequenceStart_fp.h b/src/tpm2/HashSequenceStart_fp.h
new file mode 100644
index 0000000..9f7d9fc
--- /dev/null
+++ b/src/tpm2/HashSequenceStart_fp.h
@@ -0,0 +1,88 @@
+/********************************************************************************/
+/* */
+/* */
+/* Written by Ken Goldman */
+/* IBM Thomas J. Watson Research Center */
+/* $Id: HashSequenceStart_fp.h 809 2016-11-16 18:31:54Z kgoldman $ */
+/* */
+/* Licenses and Notices */
+/* */
+/* 1. Copyright Licenses: */
+/* */
+/* - Trusted Computing Group (TCG) grants to the user of the source code in */
+/* this specification (the "Source Code") a worldwide, irrevocable, */
+/* nonexclusive, royalty free, copyright license to reproduce, create */
+/* derivative works, distribute, display and perform the Source Code and */
+/* derivative works thereof, and to grant others the rights granted herein. */
+/* */
+/* - The TCG grants to the user of the other parts of the specification */
+/* (other than the Source Code) the rights to reproduce, distribute, */
+/* display, and perform the specification solely for the purpose of */
+/* developing products based on such documents. */
+/* */
+/* 2. Source Code Distribution Conditions: */
+/* */
+/* - Redistributions of Source Code must retain the above copyright licenses, */
+/* this list of conditions and the following disclaimers. */
+/* */
+/* - Redistributions in binary form must reproduce the above copyright */
+/* licenses, this list of conditions and the following disclaimers in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* 3. Disclaimers: */
+/* */
+/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
+/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
+/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
+/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
+/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
+/* information on specification licensing rights available through TCG */
+/* membership agreements. */
+/* */
+/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
+/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
+/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
+/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
+/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
+/* */
+/* - Without limitation, TCG and its members and licensors disclaim all */
+/* liability, including liability for infringement of any proprietary */
+/* rights, relating to use of information in this specification and to the */
+/* implementation of this specification, and TCG disclaims all liability for */
+/* cost of procurement of substitute goods or services, lost profits, loss */
+/* of use, loss of data or any incidental, consequential, direct, indirect, */
+/* or special damages, whether under contract, tort, warranty or otherwise, */
+/* arising in any way out of use or reliance upon this specification or any */
+/* information herein. */
+/* */
+/* (c) Copyright IBM Corp. and others, 2012-2015 */
+/* */
+/********************************************************************************/
+
+/* rev 119 */
+
+#ifndef HASHSEQUENCESTART_FP_H
+#define HASHSEQUENCESTART_FP_H
+
+typedef struct {
+ TPM2B_AUTH auth;
+ TPMI_ALG_HASH hashAlg;
+} HashSequenceStart_In;
+
+#define RC_HashSequenceStart_auth (TPM_RC_P + TPM_RC_1)
+#define RC_HashSequenceStart_hashAlg (TPM_RC_P + TPM_RC_2)
+
+typedef struct {
+ TPMI_DH_OBJECT sequenceHandle;
+} HashSequenceStart_Out;
+
+
+
+TPM_RC
+TPM2_HashSequenceStart(
+ HashSequenceStart_In *in, // IN: input parameter list
+ HashSequenceStart_Out *out // OUT: output parameter list
+ );
+
+
+#endif
diff --git a/src/tpm2/HashTestData.h b/src/tpm2/HashTestData.h
new file mode 100644
index 0000000..ea0b0af
--- /dev/null
+++ b/src/tpm2/HashTestData.h
@@ -0,0 +1,210 @@
+/********************************************************************************/
+/* */
+/* Hash Test Vectors */
+/* Written by Ken Goldman */
+/* IBM Thomas J. Watson Research Center */
+/* $Id: HashTestData.h 1658 2021-01-22 23:14:01Z kgoldman $ */
+/* */
+/* Licenses and Notices */
+/* */
+/* 1. Copyright Licenses: */
+/* */
+/* - Trusted Computing Group (TCG) grants to the user of the source code in */
+/* this specification (the "Source Code") a worldwide, irrevocable, */
+/* nonexclusive, royalty free, copyright license to reproduce, create */
+/* derivative works, distribute, display and perform the Source Code and */
+/* derivative works thereof, and to grant others the rights granted herein. */
+/* */
+/* - The TCG grants to the user of the other parts of the specification */
+/* (other than the Source Code) the rights to reproduce, distribute, */
+/* display, and perform the specification solely for the purpose of */
+/* developing products based on such documents. */
+/* */
+/* 2. Source Code Distribution Conditions: */
+/* */
+/* - Redistributions of Source Code must retain the above copyright licenses, */
+/* this list of conditions and the following disclaimers. */
+/* */
+/* - Redistributions in binary form must reproduce the above copyright */
+/* licenses, this list of conditions and the following disclaimers in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* 3. Disclaimers: */
+/* */
+/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
+/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
+/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
+/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
+/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
+/* information on specification licensing rights available through TCG */
+/* membership agreements. */
+/* */
+/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
+/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
+/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
+/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
+/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
+/* */
+/* - Without limitation, TCG and its members and licensors disclaim all */
+/* liability, including liability for infringement of any proprietary */
+/* rights, relating to use of information in this specification and to the */
+/* implementation of this specification, and TCG disclaims all liability for */
+/* cost of procurement of substitute goods or services, lost profits, loss */
+/* of use, loss of data or any incidental, consequential, direct, indirect, */
+/* or special damages, whether under contract, tort, warranty or otherwise, */
+/* arising in any way out of use or reliance upon this specification or any */
+/* information herein. */
+/* */
+/* (c) Copyright IBM Corp. and others, 2016 - 2021 */
+/* */
+/********************************************************************************/
+
+#ifndef HASHTESTDATA_H
+#define HASHTESTDATA_H
+
+/* 10.1.8 HashTestData.h */
+/* Hash Test Vectors */
+TPM2B_TYPE(HASH_TEST_KEY, 128); // Twice the largest digest size
+TPM2B_HASH_TEST_KEY c_hashTestKey = {{128, {
+ 0xa0,0xed,0x5c,0x9a,0xd2,0x4a,0x21,0x40,0x1a,0xd0,0x81,0x47,0x39,0x63,0xf9,0x50,
+ 0xdc,0x59,0x47,0x11,0x40,0x13,0x99,0x92,0xc0,0x72,0xa4,0x0f,0xe2,0x33,0xe4,0x63,
+ 0x9b,0xb6,0x76,0xc3,0x1e,0x6f,0x13,0xee,0xcc,0x99,0x71,0xa5,0xc0,0xcf,0x9a,0x40,
+ 0xcf,0xdb,0x66,0x70,0x05,0x63,0x54,0x12,0x25,0xf4,0xe0,0x1b,0x23,0x35,0xe3,0x70,
+ 0x7d,0x19,0x5f,0x00,0xe4,0xf1,0x61,0x73,0x05,0xd8,0x58,0x7f,0x60,0x61,0x84,0x36,
+ 0xec,0xbe,0x96,0x1b,0x69,0x00,0xf0,0x9a,0x6e,0xe3,0x26,0x73,0x0d,0x17,0x5b,0x33,
+ 0x41,0x44,0x9d,0x90,0xab,0xd9,0x6b,0x7d,0x48,0x99,0x25,0x93,0x29,0x14,0x2b,0xce,
+ 0x93,0x8d,0x8c,0xaf,0x31,0x0e,0x9c,0x57,0xd8,0x5b,0x57,0x20,0x1b,0x9f,0x2d,0xa5
+ }}};
+
+TPM2B_TYPE(HASH_TEST_DATA, 256); // Twice the largest block size
+TPM2B_HASH_TEST_DATA c_hashTestData = {{256, {
+ 0x88,0xac,0xc3,0xe5,0x5f,0x66,0x9d,0x18,0x80,0xc9,0x7a,0x9c,0xa4,0x08,0x90,0x98,
+ 0x0f,0x3a,0x53,0x92,0x4c,0x67,0x4e,0xb7,0x37,0xec,0x67,0x87,0xb6,0xbe,0x10,0xca,
+ 0x11,0x5b,0x4a,0x0b,0x45,0xc3,0x32,0x68,0x48,0x69,0xce,0x25,0x1b,0xc8,0xaf,0x44,
+ 0x79,0x22,0x83,0xc8,0xfb,0xe2,0x63,0x94,0xa2,0x3c,0x59,0x3e,0x3e,0xc6,0x64,0x2c,
+ 0x1f,0x8c,0x11,0x93,0x24,0xa3,0x17,0xc5,0x2f,0x37,0xcf,0x95,0x97,0x8e,0x63,0x39,
+ 0x68,0xd5,0xca,0xba,0x18,0x37,0x69,0x6e,0x4f,0x19,0xfd,0x8a,0xc0,0x8d,0x87,0x3a,
+ 0xbc,0x31,0x42,0x04,0x05,0xef,0xb5,0x02,0xef,0x1e,0x92,0x4b,0xb7,0x73,0x2c,0x8c,
+ 0xeb,0x23,0x13,0x81,0x34,0xb9,0xb5,0xc1,0x17,0x37,0x39,0xf8,0x3e,0xe4,0x4c,0x06,
+ 0xa8,0x81,0x52,0x2f,0xef,0xc9,0x9c,0x69,0x89,0xbc,0x85,0x9c,0x30,0x16,0x02,0xca,
+ 0xe3,0x61,0xd4,0x0f,0xed,0x34,0x1b,0xca,0xc1,0x1b,0xd1,0xfa,0xc1,0xa2,0xe0,0xdf,
+ 0x52,0x2f,0x0b,0x4b,0x9f,0x0e,0x45,0x54,0xb9,0x17,0xb6,0xaf,0xd6,0xd5,0xca,0x90,
+ 0x29,0x57,0x7b,0x70,0x50,0x94,0x5c,0x8e,0xf6,0x4e,0x21,0x8b,0xc6,0x8b,0xa6,0xbc,
+ 0xb9,0x64,0xd4,0x4d,0xf3,0x68,0xd8,0xac,0xde,0xd8,0xd8,0xb5,0x6d,0xcd,0x93,0xeb,
+ 0x28,0xa4,0xe2,0x5c,0x44,0xef,0xf0,0xe1,0x6f,0x38,0x1a,0x3c,0xe6,0xef,0xa2,0x9d,
+ 0xb9,0xa8,0x05,0x2a,0x95,0xec,0x5f,0xdb,0xb0,0x25,0x67,0x9c,0x86,0x7a,0x8e,0xea,
+ 0x51,0xcc,0xc3,0xd3,0xff,0x6e,0xf0,0xed,0xa3,0xae,0xf9,0x5d,0x33,0x70,0xf2,0x11
+ }}};
+#if ALG_SHA1 == YES
+TPM2B_TYPE(SHA1, 20);
+TPM2B_SHA1 c_SHA1_digest = {{20, {
+ 0xee,0x2c,0xef,0x93,0x76,0xbd,0xf8,0x91,0xbc,0xe6,0xe5,0x57,0x53,0x77,0x01,0xb5,
+ 0x70,0x95,0xe5,0x40
+ }}};
+#endif
+#if ALG_SHA256 == YES
+TPM2B_TYPE(SHA256, 32);
+TPM2B_SHA256 c_SHA256_digest = {{32, {
+ 0x64,0xe8,0xe0,0xc3,0xa9,0xa4,0x51,0x49,0x10,0x55,0x8d,0x31,0x71,0xe5,0x2f,0x69,
+ 0x3a,0xdc,0xc7,0x11,0x32,0x44,0x61,0xbd,0x34,0x39,0x57,0xb0,0xa8,0x75,0x86,0x1b
+ }}};
+#endif
+#if ALG_SHA384 == YES
+TPM2B_TYPE(SHA384, 48);
+TPM2B_SHA384 c_SHA384_digest = {{48, {
+ 0x37,0x75,0x29,0xb5,0x20,0x15,0x6e,0xa3,0x7e,0xa3,0x0d,0xcd,0x80,0xa8,0xa3,0x3d,
+ 0xeb,0xe8,0xad,0x4e,0x1c,0x77,0x94,0x5a,0xaf,0x6c,0xd0,0xc1,0xfa,0x43,0x3f,0xc7,
+ 0xb8,0xf1,0x01,0xc0,0x60,0xbf,0xf2,0x87,0xe8,0x71,0x9e,0x51,0x97,0xa0,0x09,0x8d
+ }}};
+#endif
+#if ALG_SHA512 == YES
+TPM2B_TYPE(SHA512, 64);
+TPM2B_SHA512 c_SHA512_digest = {{64, {
+ 0xe2,0x7b,0x10,0x3d,0x5e,0x48,0x58,0x44,0x67,0xac,0xa3,0x81,0x8c,0x1d,0xc5,0x71,
+ 0x66,0x92,0x8a,0x89,0xaa,0xd4,0x35,0x51,0x60,0x37,0x31,0xd7,0xba,0xe7,0x93,0x0b,
+ 0x16,0x4d,0xb3,0xc8,0x34,0x98,0x3c,0xd3,0x53,0xde,0x5e,0xe8,0x0c,0xbc,0xaf,0xc9,
+ 0x24,0x2c,0xcc,0xed,0xdb,0xde,0xba,0x1f,0x14,0x14,0x5a,0x95,0x80,0xde,0x66,0xbd
+ }}};
+#endif
+
+TPM2B_TYPE(EMPTY, 1);
+
+#if ALG_SM3_256 == YES
+TPM2B_EMPTY c_SM3_256_digest = {{0, {0}}};
+#endif
+
+#if ALG_SHA3_256 == YES
+TPM2B_EMPTY c_SHA3_256_digest = {{0, {0}}};
+#endif
+
+#if ALG_SHA3_384 == YES
+TPM2B_EMPTY c_SHA3_384_digest = {{0, {0}}};
+#endif
+
+#if ALG_SHA3_512 == YES
+TPM2B_EMPTY c_SHA3_512_digest = {{0, {0}}};
+#endif
+
+
+// libtpms added begin
+#if SMAC_IMPLEMENTED && ALG_CMAC
+TPM2B_TYPE(AES128, 16);
+static TPM2B_AES128 cmac_aeskey = {{16, {
+ 0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6,
+ 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c
+}}};
+static const struct CMACTest {
+ TPM2B *key;
+ const BYTE data[64];
+ UINT32 datalen;
+ const BYTE out[16];
+ UINT16 outlen;
+} CMACTests[] = {
+ {
+ .key = &cmac_aeskey.b,
+ .data = { },
+ .datalen = 0,
+ .out = { 0xbb, 0x1d, 0x69, 0x29, 0xe9, 0x59, 0x37, 0x28,
+ 0x7f, 0xa3, 0x7d, 0x12, 0x9b, 0x75, 0x67, 0x46},
+ .outlen = 16,
+ }, {
+ .key = &cmac_aeskey.b,
+ .data = { 0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96,
+ 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a},
+ .datalen = 16,
+ .out = { 0x07, 0x0a, 0x16, 0xb4, 0x6b, 0x4d, 0x41, 0x44,
+ 0xf7, 0x9b, 0xdd, 0x9d, 0xd0, 0x4a, 0x28, 0x7c},
+ .outlen = 16,
+ }, {
+ .key = &cmac_aeskey.b,
+ .data = { 0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96,
+ 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a,
+ 0xae, 0x2d, 0x8a, 0x57, 0x1e, 0x03, 0xac, 0x9c,
+ 0x9e, 0xb7, 0x6f, 0xac, 0x45, 0xaf, 0x8e, 0x51,
+ 0x30, 0xc8, 0x1c, 0x46, 0xa3, 0x5c, 0xe4, 0x11},
+ .datalen = 40,
+ .out = { 0xdf, 0xa6, 0x67, 0x47, 0xde, 0x9a, 0xe6, 0x30,
+ 0x30, 0xca, 0x32, 0x61, 0x14, 0x97, 0xc8, 0x27},
+ .outlen = 16,
+ }, {
+ .key = &cmac_aeskey.b,
+ .data = { 0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96,
+ 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a,
+ 0xae, 0x2d, 0x8a, 0x57, 0x1e, 0x03, 0xac, 0x9c,
+ 0x9e, 0xb7, 0x6f, 0xac, 0x45, 0xaf, 0x8e, 0x51,
+ 0x30, 0xc8, 0x1c, 0x46, 0xa3, 0x5c, 0xe4, 0x11,
+ 0xe5, 0xfb, 0xc1, 0x19, 0x1a, 0x0a, 0x52, 0xef,
+ 0xf6, 0x9f, 0x24, 0x45, 0xdf, 0x4f, 0x9b, 0x17,
+ 0xad, 0x2b, 0x41, 0x7b, 0xe6, 0x6c, 0x37, 0x10},
+ .datalen = 64,
+ .out = { 0x51, 0xf0, 0xbe, 0xbf, 0x7e, 0x3b, 0x9d, 0x92,
+ 0xfc, 0x49, 0x74, 0x17, 0x79, 0x36, 0x3c, 0xfe},
+ .outlen = 16,
+ }, {
+ .key = NULL,
+ }
+};
+#endif
+// libtpms added end
+
+#endif
diff --git a/src/tpm2/Hash_fp.h b/src/tpm2/Hash_fp.h
new file mode 100644
index 0000000..710fffc
--- /dev/null
+++ b/src/tpm2/Hash_fp.h
@@ -0,0 +1,89 @@
+/********************************************************************************/
+/* */
+/* */
+/* Written by Ken Goldman */
+/* IBM Thomas J. Watson Research Center */
+/* $Id: Hash_fp.h 1521 2019-11-15 21:00:47Z kgoldman $ */
+/* */
+/* Licenses and Notices */
+/* */
+/* 1. Copyright Licenses: */
+/* */
+/* - Trusted Computing Group (TCG) grants to the user of the source code in */
+/* this specification (the "Source Code") a worldwide, irrevocable, */
+/* nonexclusive, royalty free, copyright license to reproduce, create */
+/* derivative works, distribute, display and perform the Source Code and */
+/* derivative works thereof, and to grant others the rights granted herein. */
+/* */
+/* - The TCG grants to the user of the other parts of the specification */
+/* (other than the Source Code) the rights to reproduce, distribute, */
+/* display, and perform the specification solely for the purpose of */
+/* developing products based on such documents. */
+/* */
+/* 2. Source Code Distribution Conditions: */
+/* */
+/* - Redistributions of Source Code must retain the above copyright licenses, */
+/* this list of conditions and the following disclaimers. */
+/* */
+/* - Redistributions in binary form must reproduce the above copyright */
+/* licenses, this list of conditions and the following disclaimers in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* 3. Disclaimers: */
+/* */
+/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
+/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
+/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
+/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
+/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
+/* information on specification licensing rights available through TCG */
+/* membership agreements. */
+/* */
+/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
+/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
+/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
+/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
+/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
+/* */
+/* - Without limitation, TCG and its members and licensors disclaim all */
+/* liability, including liability for infringement of any proprietary */
+/* rights, relating to use of information in this specification and to the */
+/* implementation of this specification, and TCG disclaims all liability for */
+/* cost of procurement of substitute goods or services, lost profits, loss */
+/* of use, loss of data or any incidental, consequential, direct, indirect, */
+/* or special damages, whether under contract, tort, warranty or otherwise, */
+/* arising in any way out of use or reliance upon this specification or any */
+/* information herein. */
+/* */
+/* (c) Copyright IBM Corp. and others, 2012-2015 */
+/* */
+/********************************************************************************/
+
+/* rev 119 */
+
+#ifndef HASH_FP_H
+#define HASH_FP_H
+
+typedef struct {
+ TPM2B_MAX_BUFFER data;
+ TPMI_ALG_HASH hashAlg;
+ TPMI_RH_HIERARCHY hierarchy;
+} Hash_In;
+
+#define RC_Hash_data (TPM_RC_P + TPM_RC_1)
+#define RC_Hash_hashAlg (TPM_RC_P + TPM_RC_2)
+#define RC_Hash_hierarchy (TPM_RC_P + TPM_RC_3)
+
+typedef struct {
+ TPM2B_DIGEST outHash;
+ TPMT_TK_HASHCHECK validation;
+} Hash_Out;
+
+TPM_RC
+TPM2_Hash(
+ Hash_In *in, // IN: input parameter list
+ Hash_Out *out // OUT: output parameter list
+ );
+
+
+#endif
diff --git a/src/tpm2/Hierarchy.c b/src/tpm2/Hierarchy.c
new file mode 100644
index 0000000..fc522a7
--- /dev/null
+++ b/src/tpm2/Hierarchy.c
@@ -0,0 +1,273 @@
+/********************************************************************************/
+/* */
+/* Managing and accessing the hierarchy-related values */
+/* Written by Ken Goldman */
+/* IBM Thomas J. Watson Research Center */
+/* $Id: Hierarchy.c 1490 2019-07-26 21:13:22Z kgoldman $ */
+/* */
+/* Licenses and Notices */
+/* */
+/* 1. Copyright Licenses: */
+/* */
+/* - Trusted Computing Group (TCG) grants to the user of the source code in */
+/* this specification (the "Source Code") a worldwide, irrevocable, */
+/* nonexclusive, royalty free, copyright license to reproduce, create */
+/* derivative works, distribute, display and perform the Source Code and */
+/* derivative works thereof, and to grant others the rights granted herein. */
+/* */
+/* - The TCG grants to the user of the other parts of the specification */
+/* (other than the Source Code) the rights to reproduce, distribute, */
+/* display, and perform the specification solely for the purpose of */
+/* developing products based on such documents. */
+/* */
+/* 2. Source Code Distribution Conditions: */
+/* */
+/* - Redistributions of Source Code must retain the above copyright licenses, */
+/* this list of conditions and the following disclaimers. */
+/* */
+/* - Redistributions in binary form must reproduce the above copyright */
+/* licenses, this list of conditions and the following disclaimers in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* 3. Disclaimers: */
+/* */
+/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
+/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
+/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
+/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
+/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
+/* information on specification licensing rights available through TCG */
+/* membership agreements. */
+/* */
+/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
+/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
+/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
+/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
+/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
+/* */
+/* - Without limitation, TCG and its members and licensors disclaim all */
+/* liability, including liability for infringement of any proprietary */
+/* rights, relating to use of information in this specification and to the */
+/* implementation of this specification, and TCG disclaims all liability for */
+/* cost of procurement of substitute goods or services, lost profits, loss */
+/* of use, loss of data or any incidental, consequential, direct, indirect, */
+/* or special damages, whether under contract, tort, warranty or otherwise, */
+/* arising in any way out of use or reliance upon this specification or any */
+/* information herein. */
+/* */
+/* (c) Copyright IBM Corp. and others, 2016 - 2019 */
+/* */
+/********************************************************************************/
+/* 8.3 Hierarchy.c */
+/* 8.3.1 Introduction */
+/* This file contains the functions used for managing and accessing the hierarchy-related values. */
+/* 8.3.2 Includes */
+#include "Tpm.h"
+/* 8.3.3 Functions */
+/* 8.3.3.1 HierarchyPreInstall() */
+/* This function performs the initialization functions for the hierarchy when the TPM is
+ simulated. This function should not be called if the TPM is not in a manufacturing mode at the
+ manufacturer, or in a simulated environment. */
+void
+HierarchyPreInstall_Init(
+ void
+ )
+{
+ // Allow lockout clear command
+ gp.disableClear = FALSE;
+ // Initialize Primary Seeds
+ gp.EPSeed.t.size = sizeof(gp.EPSeed.t.buffer);
+ gp.SPSeed.t.size = sizeof(gp.SPSeed.t.buffer);
+ gp.PPSeed.t.size = sizeof(gp.PPSeed.t.buffer);
+#if (defined USE_PLATFORM_EPS) && (USE_PLATFORM_EPS != NO)
+ _plat__GetEPS(gp.EPSeed.t.size, gp.EPSeed.t.buffer);
+#else
+ CryptRandomGenerate(gp.EPSeed.t.size, gp.EPSeed.t.buffer);
+#endif
+ CryptRandomGenerate(gp.SPSeed.t.size, gp.SPSeed.t.buffer);
+ CryptRandomGenerate(gp.PPSeed.t.size, gp.PPSeed.t.buffer);
+ gp.EPSeedCompatLevel = SEED_COMPAT_LEVEL_LAST; // libtpms added begin
+ gp.SPSeedCompatLevel = SEED_COMPAT_LEVEL_LAST;
+ gp.PPSeedCompatLevel = SEED_COMPAT_LEVEL_LAST; // libtpms added end
+ // Initialize owner, endorsement and lockout authorization
+ gp.ownerAuth.t.size = 0;
+ gp.endorsementAuth.t.size = 0;
+ gp.lockoutAuth.t.size = 0;
+ // Initialize owner, endorsement, and lockout policy
+ gp.ownerAlg = TPM_ALG_NULL;
+ gp.ownerPolicy.t.size = 0;
+ gp.endorsementAlg = TPM_ALG_NULL;
+ gp.endorsementPolicy.t.size = 0;
+ gp.lockoutAlg = TPM_ALG_NULL;
+ gp.lockoutPolicy.t.size = 0;
+ // Initialize ehProof, shProof and phProof
+ gp.phProof.t.size = sizeof(gp.phProof.t.buffer);
+ gp.shProof.t.size = sizeof(gp.shProof.t.buffer);
+ gp.ehProof.t.size = sizeof(gp.ehProof.t.buffer);
+ CryptRandomGenerate(gp.phProof.t.size, gp.phProof.t.buffer);
+ CryptRandomGenerate(gp.shProof.t.size, gp.shProof.t.buffer);
+ CryptRandomGenerate(gp.ehProof.t.size, gp.ehProof.t.buffer);
+ // Write hierarchy data to NV
+ NV_SYNC_PERSISTENT(disableClear);
+ NV_SYNC_PERSISTENT(EPSeed);
+ NV_SYNC_PERSISTENT(SPSeed);
+ NV_SYNC_PERSISTENT(PPSeed);
+ NV_SYNC_PERSISTENT(EPSeedCompatLevel); // libtpms added begin
+ NV_SYNC_PERSISTENT(SPSeedCompatLevel);
+ NV_SYNC_PERSISTENT(PPSeedCompatLevel); // libtpms added end
+ NV_SYNC_PERSISTENT(ownerAuth);
+ NV_SYNC_PERSISTENT(endorsementAuth);
+ NV_SYNC_PERSISTENT(lockoutAuth);
+ NV_SYNC_PERSISTENT(ownerAlg);
+ NV_SYNC_PERSISTENT(ownerPolicy);
+ NV_SYNC_PERSISTENT(endorsementAlg);
+ NV_SYNC_PERSISTENT(endorsementPolicy);
+ NV_SYNC_PERSISTENT(lockoutAlg);
+ NV_SYNC_PERSISTENT(lockoutPolicy);
+ NV_SYNC_PERSISTENT(phProof);
+ NV_SYNC_PERSISTENT(shProof);
+ NV_SYNC_PERSISTENT(ehProof);
+ return;
+}
+/* 8.3.3.2 HierarchyStartup() */
+/* This function is called at TPM2_Startup() to initialize the hierarchy related values. */
+BOOL
+HierarchyStartup(
+ STARTUP_TYPE type // IN: start up type
+ )
+{
+ // phEnable is SET on any startup
+ g_phEnable = TRUE;
+ // Reset platformAuth, platformPolicy; enable SH and EH at TPM_RESET and
+ // TPM_RESTART
+ if(type != SU_RESUME)
+ {
+ gc.platformAuth.t.size = 0;
+ gc.platformPolicy.t.size = 0;
+ gc.platformAlg = TPM_ALG_NULL;
+ // enable the storage and endorsement hierarchies and the platformNV
+ gc.shEnable = gc.ehEnable = gc.phEnableNV = TRUE;
+ }
+ // nullProof and nullSeed are updated at every TPM_RESET
+ if((type != SU_RESTART) && (type != SU_RESUME))
+ {
+ gr.nullProof.t.size = sizeof(gr.nullProof.t.buffer);
+ CryptRandomGenerate(gr.nullProof.t.size, gr.nullProof.t.buffer);
+ gr.nullSeed.t.size = sizeof(gr.nullSeed.t.buffer);
+ CryptRandomGenerate(gr.nullSeed.t.size, gr.nullSeed.t.buffer);
+ gr.nullSeedCompatLevel = SEED_COMPAT_LEVEL_LAST; // libtpms added
+ }
+ return TRUE;
+}
+/* 8.3.3.3 HierarchyGetProof() */
+/* This function finds the proof value associated with a hierarchy.It returns a pointer to the proof
+ value. */
+TPM2B_PROOF *
+HierarchyGetProof(
+ TPMI_RH_HIERARCHY hierarchy // IN: hierarchy constant
+ )
+{
+ TPM2B_PROOF *proof = NULL;
+ switch(hierarchy)
+ {
+ case TPM_RH_PLATFORM:
+ // phProof for TPM_RH_PLATFORM
+ proof = &gp.phProof;
+ break;
+ case TPM_RH_ENDORSEMENT:
+ // ehProof for TPM_RH_ENDORSEMENT
+ proof = &gp.ehProof;
+ break;
+ case TPM_RH_OWNER:
+ // shProof for TPM_RH_OWNER
+ proof = &gp.shProof;
+ break;
+ default:
+ // nullProof for TPM_RH_NULL or anything else
+ proof = &gr.nullProof;
+ break;
+ }
+ return proof;
+}
+/* 8.3.3.4 HierarchyGetPrimarySeed() */
+/* This function returns the primary seed of a hierarchy. */
+TPM2B_SEED *
+HierarchyGetPrimarySeed(
+ TPMI_RH_HIERARCHY hierarchy // IN: hierarchy
+ )
+{
+ TPM2B_SEED *seed = NULL;
+ switch(hierarchy)
+ {
+ case TPM_RH_PLATFORM:
+ seed = &gp.PPSeed;
+ break;
+ case TPM_RH_OWNER:
+ seed = &gp.SPSeed;
+ break;
+ case TPM_RH_ENDORSEMENT:
+ seed = &gp.EPSeed;
+ break;
+ default:
+ seed = &gr.nullSeed;
+ break;
+ }
+ return seed;
+}
+// libtpms added begin
+SEED_COMPAT_LEVEL
+HierarchyGetPrimarySeedCompatLevel(
+ TPMI_RH_HIERARCHY hierarchy // IN: hierarchy
+ )
+{
+ switch(hierarchy)
+ {
+ case TPM_RH_PLATFORM:
+ return gp.PPSeedCompatLevel;
+ break;
+ case TPM_RH_OWNER:
+ return gp.SPSeedCompatLevel;
+ break;
+ case TPM_RH_ENDORSEMENT:
+ return gp.EPSeedCompatLevel;
+ break;
+ case TPM_RH_NULL:
+ return gr.nullSeedCompatLevel;
+ default:
+ FAIL(FATAL_ERROR_INTERNAL);
+ break;
+ }
+}
+// libtpms added end
+/* 8.3.3.5 HierarchyIsEnabled() */
+/* This function checks to see if a hierarchy is enabled. */
+/* NOTE: The TPM_RH_NULL hierarchy is always enabled. */
+/* Return Values Meaning */
+/* TRUE hierarchy is enabled */
+/* FALSE hierarchy is disabled */
+BOOL
+HierarchyIsEnabled(
+ TPMI_RH_HIERARCHY hierarchy // IN: hierarchy
+ )
+{
+ BOOL enabled = FALSE;
+ switch(hierarchy)
+ {
+ case TPM_RH_PLATFORM:
+ enabled = g_phEnable;
+ break;
+ case TPM_RH_OWNER:
+ enabled = gc.shEnable;
+ break;
+ case TPM_RH_ENDORSEMENT:
+ enabled = gc.ehEnable;
+ break;
+ case TPM_RH_NULL:
+ enabled = TRUE;
+ break;
+ default:
+ enabled = FALSE;
+ break;
+ }
+ return enabled;
+}
diff --git a/src/tpm2/HierarchyChangeAuth_fp.h b/src/tpm2/HierarchyChangeAuth_fp.h
new file mode 100644
index 0000000..74f0397
--- /dev/null
+++ b/src/tpm2/HierarchyChangeAuth_fp.h
@@ -0,0 +1,80 @@
+/********************************************************************************/
+/* */
+/* */
+/* Written by Ken Goldman */
+/* IBM Thomas J. Watson Research Center */
+/* $Id: HierarchyChangeAuth_fp.h 809 2016-11-16 18:31:54Z kgoldman $ */
+/* */
+/* Licenses and Notices */
+/* */
+/* 1. Copyright Licenses: */
+/* */
+/* - Trusted Computing Group (TCG) grants to the user of the source code in */
+/* this specification (the "Source Code") a worldwide, irrevocable, */
+/* nonexclusive, royalty free, copyright license to reproduce, create */
+/* derivative works, distribute, display and perform the Source Code and */
+/* derivative works thereof, and to grant others the rights granted herein. */
+/* */
+/* - The TCG grants to the user of the other parts of the specification */
+/* (other than the Source Code) the rights to reproduce, distribute, */
+/* display, and perform the specification solely for the purpose of */
+/* developing products based on such documents. */
+/* */
+/* 2. Source Code Distribution Conditions: */
+/* */
+/* - Redistributions of Source Code must retain the above copyright licenses, */
+/* this list of conditions and the following disclaimers. */
+/* */
+/* - Redistributions in binary form must reproduce the above copyright */
+/* licenses, this list of conditions and the following disclaimers in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* 3. Disclaimers: */
+/* */
+/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
+/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
+/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
+/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
+/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
+/* information on specification licensing rights available through TCG */
+/* membership agreements. */
+/* */
+/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
+/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
+/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
+/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
+/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
+/* */
+/* - Without limitation, TCG and its members and licensors disclaim all */
+/* liability, including liability for infringement of any proprietary */
+/* rights, relating to use of information in this specification and to the */
+/* implementation of this specification, and TCG disclaims all liability for */
+/* cost of procurement of substitute goods or services, lost profits, loss */
+/* of use, loss of data or any incidental, consequential, direct, indirect, */
+/* or special damages, whether under contract, tort, warranty or otherwise, */
+/* arising in any way out of use or reliance upon this specification or any */
+/* information herein. */
+/* */
+/* (c) Copyright IBM Corp. and others, 2012-2015 */
+/* */
+/********************************************************************************/
+
+/* rev 119 */
+
+#ifndef HIERARCHYCHANGEAUTH_FP_H
+#define HIERARCHYCHANGEAUTH_FP_H
+
+typedef struct {
+ TPMI_RH_HIERARCHY_AUTH authHandle;
+ TPM2B_AUTH newAuth;
+} HierarchyChangeAuth_In;
+
+#define RC_HierarchyChangeAuth_authHandle (TPM_RC_H + TPM_RC_1)
+#define RC_HierarchyChangeAuth_newAuth (TPM_RC_P + TPM_RC_2)
+
+TPM_RC
+TPM2_HierarchyChangeAuth(
+ HierarchyChangeAuth_In *in // IN: input parameter list
+ );
+
+#endif
diff --git a/src/tpm2/HierarchyCommands.c b/src/tpm2/HierarchyCommands.c
new file mode 100644
index 0000000..cbf777d
--- /dev/null
+++ b/src/tpm2/HierarchyCommands.c
@@ -0,0 +1,514 @@
+/********************************************************************************/
+/* */
+/* Hierarchy Commands */
+/* Written by Ken Goldman */
+/* IBM Thomas J. Watson Research Center */
+/* $Id: HierarchyCommands.c 1519 2019-11-15 20:43:51Z kgoldman $ */
+/* */
+/* Licenses and Notices */
+/* */
+/* 1. Copyright Licenses: */
+/* */
+/* - Trusted Computing Group (TCG) grants to the user of the source code in */
+/* this specification (the "Source Code") a worldwide, irrevocable, */
+/* nonexclusive, royalty free, copyright license to reproduce, create */
+/* derivative works, distribute, display and perform the Source Code and */
+/* derivative works thereof, and to grant others the rights granted herein. */
+/* */
+/* - The TCG grants to the user of the other parts of the specification */
+/* (other than the Source Code) the rights to reproduce, distribute, */
+/* display, and perform the specification solely for the purpose of */
+/* developing products based on such documents. */
+/* */
+/* 2. Source Code Distribution Conditions: */
+/* */
+/* - Redistributions of Source Code must retain the above copyright licenses, */
+/* this list of conditions and the following disclaimers. */
+/* */
+/* - Redistributions in binary form must reproduce the above copyright */
+/* licenses, this list of conditions and the following disclaimers in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* 3. Disclaimers: */
+/* */
+/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
+/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
+/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
+/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
+/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
+/* information on specification licensing rights available through TCG */
+/* membership agreements. */
+/* */
+/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
+/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
+/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
+/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
+/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
+/* */
+/* - Without limitation, TCG and its members and licensors disclaim all */
+/* liability, including liability for infringement of any proprietary */
+/* rights, relating to use of information in this specification and to the */
+/* implementation of this specification, and TCG disclaims all liability for */
+/* cost of procurement of substitute goods or services, lost profits, loss */
+/* of use, loss of data or any incidental, consequential, direct, indirect, */
+/* or special damages, whether under contract, tort, warranty or otherwise, */
+/* arising in any way out of use or reliance upon this specification or any */
+/* information herein. */
+/* */
+/* (c) Copyright IBM Corp. and others, 2016 - 2019 */
+/* */
+/********************************************************************************/
+
+#include "Tpm.h"
+#include "CreatePrimary_fp.h"
+#if CC_CreatePrimary // Conditional expansion of this file
+TPM_RC
+TPM2_CreatePrimary(
+ CreatePrimary_In *in, // IN: input parameter list
+ CreatePrimary_Out *out // OUT: output parameter list
+ )
+{
+ TPM_RC result = TPM_RC_SUCCESS;
+ TPMT_PUBLIC *publicArea;
+ DRBG_STATE rand;
+ OBJECT *newObject;
+ TPM2B_NAME name;
+ // Input Validation
+ // Will need a place to put the result
+ newObject = FindEmptyObjectSlot(&out->objectHandle);
+ if(newObject == NULL)
+ return TPM_RC_OBJECT_MEMORY;
+ // Get the address of the public area in the new object
+ // (this is just to save typing)
+ publicArea = &newObject->publicArea;
+ *publicArea = in->inPublic.publicArea;
+ // Check attributes in input public area. CreateChecks() checks the things that
+ // are unique to creation and then validates the attributes and values that are
+ // common to create and load.
+ result = CreateChecks(NULL, publicArea,
+ in->inSensitive.sensitive.data.t.size);
+ if(result != TPM_RC_SUCCESS)
+ return RcSafeAddToResult(result, RC_CreatePrimary_inPublic);
+ // Validate the sensitive area values
+ if(!AdjustAuthSize(&in->inSensitive.sensitive.userAuth,
+ publicArea->nameAlg))
+ return TPM_RCS_SIZE + RC_CreatePrimary_inSensitive;
+ // Command output
+ // Compute the name using out->name as a scratch area (this is not the value
+ // that ultimately will be returned, then instantiate the state that will be
+ // used as a random number generator during the object creation.
+ // The caller does not know the seed values so the actual name does not have
+ // to be over the input, it can be over the unmarshaled structure.
+ result = DRBG_InstantiateSeeded(&rand,
+ &HierarchyGetPrimarySeed(in->primaryHandle)->b,
+ PRIMARY_OBJECT_CREATION,
+ (TPM2B *)PublicMarshalAndComputeName(publicArea, &name),
+ &in->inSensitive.sensitive.data.b,
+ HierarchyGetPrimarySeedCompatLevel(in->primaryHandle)); // libtpms added
+ if (result == TPM_RC_SUCCESS)
+ {
+ newObject->attributes.primary = SET;
+ if(in->primaryHandle == TPM_RH_ENDORSEMENT)
+ newObject->attributes.epsHierarchy = SET;
+ // Create the primary object.
+ result = CryptCreateObject(newObject, &in->inSensitive.sensitive,
+ (RAND_STATE *)&rand);
+ }
+ if(result != TPM_RC_SUCCESS)
+ return result;
+ // Set the publicArea and name from the computed values
+ out->outPublic.publicArea = newObject->publicArea;
+ out->name = newObject->name;
+ // Fill in creation data
+ FillInCreationData(in->primaryHandle, publicArea->nameAlg,
+ &in->creationPCR, &in->outsideInfo, &out->creationData,
+ &out->creationHash);
+ // Compute creation ticket
+ TicketComputeCreation(EntityGetHierarchy(in->primaryHandle), &out->name,
+ &out->creationHash, &out->creationTicket);
+ // Set the remaining attributes for a loaded object
+ ObjectSetLoadedAttributes(newObject, in->primaryHandle,
+ HierarchyGetPrimarySeedCompatLevel(in->primaryHandle)); // libtpms added
+ return result;
+}
+#endif // CC_CreatePrimary
+#include "Tpm.h"
+#include "HierarchyControl_fp.h"
+#if CC_HierarchyControl // Conditional expansion of this file
+TPM_RC
+TPM2_HierarchyControl(
+ HierarchyControl_In *in // IN: input parameter list
+ )
+{
+ BOOL select = (in->state == YES);
+ BOOL *selected = NULL;
+ // Input Validation
+ switch(in->enable)
+ {
+ // Platform hierarchy has to be disabled by PlatformAuth
+ // If the platform hierarchy has already been disabled, only a reboot
+ // can enable it again
+ case TPM_RH_PLATFORM:
+ case TPM_RH_PLATFORM_NV:
+ if(in->authHandle != TPM_RH_PLATFORM)
+ return TPM_RC_AUTH_TYPE;
+ break;
+ // ShEnable may be disabled if PlatformAuth/PlatformPolicy or
+ // OwnerAuth/OwnerPolicy is provided. If ShEnable is disabled, then it
+ // may only be enabled if PlatformAuth/PlatformPolicy is provided.
+ case TPM_RH_OWNER:
+ if(in->authHandle != TPM_RH_PLATFORM
+ && in->authHandle != TPM_RH_OWNER)
+ return TPM_RC_AUTH_TYPE;
+ if(gc.shEnable == FALSE && in->state == YES
+ && in->authHandle != TPM_RH_PLATFORM)
+ return TPM_RC_AUTH_TYPE;
+ break;
+ // EhEnable may be disabled if either PlatformAuth/PlatformPolicy or
+ // EndosementAuth/EndorsementPolicy is provided. If EhEnable is disabled,
+ // then it may only be enabled if PlatformAuth/PlatformPolicy is
+ // provided.
+ case TPM_RH_ENDORSEMENT:
+ if(in->authHandle != TPM_RH_PLATFORM
+ && in->authHandle != TPM_RH_ENDORSEMENT)
+ return TPM_RC_AUTH_TYPE;
+ if(gc.ehEnable == FALSE && in->state == YES
+ && in->authHandle != TPM_RH_PLATFORM)
+ return TPM_RC_AUTH_TYPE;
+ break;
+ default:
+ FAIL(FATAL_ERROR_INTERNAL);
+ break;
+ }
+ // Internal Data Update
+ // Enable or disable the selected hierarchy
+ // Note: the authorization processing for this command may keep these
+ // command actions from being executed. For example, if phEnable is
+ // CLEAR, then platformAuth cannot be used for authorization. This
+ // means that would not be possible to use platformAuth to change the
+ // state of phEnable from CLEAR to SET.
+ // If it is decided that platformPolicy can still be used when phEnable
+ // is CLEAR, then this code could SET phEnable when proper platform
+ // policy is provided.
+ switch(in->enable)
+ {
+ case TPM_RH_OWNER:
+ selected = &gc.shEnable;
+ break;
+ case TPM_RH_ENDORSEMENT:
+ selected = &gc.ehEnable;
+ break;
+ case TPM_RH_PLATFORM:
+ selected = &g_phEnable;
+ break;
+ case TPM_RH_PLATFORM_NV:
+ selected = &gc.phEnableNV;
+ break;
+ default:
+ FAIL(FATAL_ERROR_INTERNAL);
+ break;
+ }
+ if(selected != NULL && *selected != select)
+ {
+ // Before changing the internal state, make sure that NV is available.
+ // Only need to update NV if changing the orderly state
+ RETURN_IF_ORDERLY;
+ // state is changing and NV is available so modify
+ *selected = select;
+ // If a hierarchy was just disabled, flush it
+ if(select == CLEAR && in->enable != TPM_RH_PLATFORM_NV)
+ // Flush hierarchy
+ ObjectFlushHierarchy(in->enable);
+ // orderly state should be cleared because of the update to state clear data
+ // This gets processed in ExecuteCommand() on the way out.
+ g_clearOrderly = TRUE;
+ }
+ return TPM_RC_SUCCESS;
+}
+#endif // CC_HierarchyControl
+#include "Tpm.h"
+#include "SetPrimaryPolicy_fp.h"
+#if CC_SetPrimaryPolicy // Conditional expansion of this file
+TPM_RC
+TPM2_SetPrimaryPolicy(
+ SetPrimaryPolicy_In *in // IN: input parameter list
+ )
+{
+ // Input Validation
+ // Check the authPolicy consistent with hash algorithm. If the policy size is
+ // zero, then the algorithm is required to be TPM_ALG_NULL
+ if(in->authPolicy.t.size != CryptHashGetDigestSize(in->hashAlg))
+ return TPM_RCS_SIZE + RC_SetPrimaryPolicy_authPolicy;
+ // The command need NV update for OWNER and ENDORSEMENT hierarchy, and
+ // might need orderlyState update for PLATFORM hierarchy.
+ // Check if NV is available. A TPM_RC_NV_UNAVAILABLE or TPM_RC_NV_RATE
+ // error may be returned at this point
+ RETURN_IF_NV_IS_NOT_AVAILABLE;
+ // Internal Data Update
+ // Set hierarchy policy
+ switch(in->authHandle)
+ {
+ case TPM_RH_OWNER:
+ gp.ownerAlg = in->hashAlg;
+ gp.ownerPolicy = in->authPolicy;
+ NV_SYNC_PERSISTENT(ownerAlg);
+ NV_SYNC_PERSISTENT(ownerPolicy);
+ break;
+ case TPM_RH_ENDORSEMENT:
+ gp.endorsementAlg = in->hashAlg;
+ gp.endorsementPolicy = in->authPolicy;
+ NV_SYNC_PERSISTENT(endorsementAlg);
+ NV_SYNC_PERSISTENT(endorsementPolicy);
+ break;
+ case TPM_RH_PLATFORM:
+ gc.platformAlg = in->hashAlg;
+ gc.platformPolicy = in->authPolicy;
+ // need to update orderly state
+ g_clearOrderly = TRUE;
+ break;
+ case TPM_RH_LOCKOUT:
+ gp.lockoutAlg = in->hashAlg;
+ gp.lockoutPolicy = in->authPolicy;
+ NV_SYNC_PERSISTENT(lockoutAlg);
+ NV_SYNC_PERSISTENT(lockoutPolicy);
+ break;
+
+#define SET_ACT_POLICY(N) \
+ case TPM_RH_ACT_##N: \
+ go.ACT_##N.hashAlg = in->hashAlg; \
+ go.ACT_##N.authPolicy = in->authPolicy; \
+ g_clearOrderly = TRUE; \
+ break;
+
+ FOR_EACH_ACT(SET_ACT_POLICY)
+
+ default:
+ FAIL(FATAL_ERROR_INTERNAL);
+ break;
+ }
+ return TPM_RC_SUCCESS;
+}
+#endif // CC_SetPrimaryPolicy
+#include "Tpm.h"
+#include "ChangePPS_fp.h"
+#if CC_ChangePPS // Conditional expansion of this file
+TPM_RC
+TPM2_ChangePPS(
+ ChangePPS_In *in // IN: input parameter list
+ )
+{
+ UINT32 i;
+ // Check if NV is available. A TPM_RC_NV_UNAVAILABLE or TPM_RC_NV_RATE
+ // error may be returned at this point
+ RETURN_IF_NV_IS_NOT_AVAILABLE;
+ // Input parameter is not reference in command action
+ NOT_REFERENCED(in);
+ // Internal Data Update
+ // Reset platform hierarchy seed from RNG
+ CryptRandomGenerate(sizeof(gp.PPSeed.t.buffer), gp.PPSeed.t.buffer);
+ gp.PPSeedCompatLevel = SEED_COMPAT_LEVEL_LAST; // libtpms added
+ // Create a new phProof value from RNG to prevent the saved platform
+ // hierarchy contexts being loaded
+ CryptRandomGenerate(sizeof(gp.phProof.t.buffer), gp.phProof.t.buffer);
+ // Set platform authPolicy to null
+ gc.platformAlg = TPM_ALG_NULL;
+ gc.platformPolicy.t.size = 0;
+ // Flush loaded object in platform hierarchy
+ ObjectFlushHierarchy(TPM_RH_PLATFORM);
+ // Flush platform evict object and index in NV
+ NvFlushHierarchy(TPM_RH_PLATFORM);
+ // Save hierarchy changes to NV
+ NV_SYNC_PERSISTENT(PPSeed);
+ NV_SYNC_PERSISTENT(PPSeedCompatLevel); // libtpms added
+ NV_SYNC_PERSISTENT(phProof);
+ // Re-initialize PCR policies
+#if defined NUM_POLICY_PCR_GROUP && NUM_POLICY_PCR_GROUP > 0
+ for(i = 0; i < NUM_POLICY_PCR_GROUP; i++)
+ {
+ gp.pcrPolicies.hashAlg[i] = TPM_ALG_NULL;
+ gp.pcrPolicies.policy[i].t.size = 0;
+ }
+ NV_SYNC_PERSISTENT(pcrPolicies);
+#endif
+ // orderly state should be cleared because of the update to state clear data
+ g_clearOrderly = TRUE;
+ return TPM_RC_SUCCESS;
+}
+#endif // CC_ChangePPS
+#include "Tpm.h"
+#include "ChangeEPS_fp.h"
+#if CC_ChangeEPS // Conditional expansion of this file
+TPM_RC
+TPM2_ChangeEPS(
+ ChangeEPS_In *in // IN: input parameter list
+ )
+{
+ // The command needs NV update. Check if NV is available.
+ // A TPM_RC_NV_UNAVAILABLE or TPM_RC_NV_RATE error may be returned at
+ // this point
+ RETURN_IF_NV_IS_NOT_AVAILABLE;
+ // Input parameter is not reference in command action
+ NOT_REFERENCED(in);
+ // Internal Data Update
+ // Reset endorsement hierarchy seed from RNG
+ CryptRandomGenerate(sizeof(gp.EPSeed.t.buffer), gp.EPSeed.t.buffer);
+ gp.EPSeedCompatLevel = SEED_COMPAT_LEVEL_LAST; // libtpms added
+ // Create new ehProof value from RNG
+ CryptRandomGenerate(sizeof(gp.ehProof.t.buffer), gp.ehProof.t.buffer);
+ // Enable endorsement hierarchy
+ gc.ehEnable = TRUE;
+ // set authValue buffer to zeros
+ MemorySet(gp.endorsementAuth.t.buffer, 0, gp.endorsementAuth.t.size);
+ // Set endorsement authValue to null
+ gp.endorsementAuth.t.size = 0;
+ // Set endorsement authPolicy to null
+ gp.endorsementAlg = TPM_ALG_NULL;
+ gp.endorsementPolicy.t.size = 0;
+ // Flush loaded object in endorsement hierarchy
+ ObjectFlushHierarchy(TPM_RH_ENDORSEMENT);
+ // Flush evict object of endorsement hierarchy stored in NV
+ NvFlushHierarchy(TPM_RH_ENDORSEMENT);
+ // Save hierarchy changes to NV
+ NV_SYNC_PERSISTENT(EPSeed);
+ NV_SYNC_PERSISTENT(EPSeedCompatLevel); // libtpms added
+ NV_SYNC_PERSISTENT(ehProof);
+ NV_SYNC_PERSISTENT(endorsementAuth);
+ NV_SYNC_PERSISTENT(endorsementAlg);
+ NV_SYNC_PERSISTENT(endorsementPolicy);
+ // orderly state should be cleared because of the update to state clear data
+ g_clearOrderly = TRUE;
+ return TPM_RC_SUCCESS;
+}
+#endif // CC_ChangeEPS
+#include "Tpm.h"
+#include "Clear_fp.h"
+#if CC_Clear // Conditional expansion of this file
+TPM_RC
+TPM2_Clear(
+ Clear_In *in // IN: input parameter list
+ )
+{
+ // Input parameter is not reference in command action
+ NOT_REFERENCED(in);
+ // The command needs NV update. Check if NV is available.
+ // A TPM_RC_NV_UNAVAILABLE or TPM_RC_NV_RATE error may be returned at
+ // this point
+ RETURN_IF_NV_IS_NOT_AVAILABLE;
+ // Input Validation
+ // If Clear command is disabled, return an error
+ if(gp.disableClear)
+ return TPM_RC_DISABLED;
+ // Internal Data Update
+ // Reset storage hierarchy seed from RNG
+ CryptRandomGenerate(sizeof(gp.SPSeed.t.buffer), gp.SPSeed.t.buffer);
+ gp.SPSeedCompatLevel = SEED_COMPAT_LEVEL_LAST; // libtpms added
+ // Create new shProof and ehProof value from RNG
+ CryptRandomGenerate(sizeof(gp.shProof.t.buffer), gp.shProof.t.buffer);
+ CryptRandomGenerate(sizeof(gp.ehProof.t.buffer), gp.ehProof.t.buffer);
+ // Enable storage and endorsement hierarchy
+ gc.shEnable = gc.ehEnable = TRUE;
+ // set the authValue buffers to zero
+ MemorySet(&gp.ownerAuth, 0, sizeof(gp.ownerAuth));
+ MemorySet(&gp.endorsementAuth, 0, sizeof(gp.endorsementAuth));
+ MemorySet(&gp.lockoutAuth, 0, sizeof(gp.lockoutAuth));
+ // Set storage, endorsement, and lockout authPolicy to null
+ gp.ownerAlg = gp.endorsementAlg = gp.lockoutAlg = TPM_ALG_NULL;
+ MemorySet(&gp.ownerPolicy, 0, sizeof(gp.ownerPolicy));
+ MemorySet(&gp.endorsementPolicy, 0, sizeof(gp.endorsementPolicy));
+ MemorySet(&gp.lockoutPolicy, 0, sizeof(gp.lockoutPolicy));
+ // Flush loaded object in storage and endorsement hierarchy
+ ObjectFlushHierarchy(TPM_RH_OWNER);
+ ObjectFlushHierarchy(TPM_RH_ENDORSEMENT);
+ // Flush owner and endorsement object and owner index in NV
+ NvFlushHierarchy(TPM_RH_OWNER);
+ NvFlushHierarchy(TPM_RH_ENDORSEMENT);
+ // Initialize dictionary attack parameters
+ DAPreInstall_Init();
+ // Reset clock
+ go.clock = 0;
+ go.clockSafe = YES;
+ NvWrite(NV_ORDERLY_DATA, sizeof(ORDERLY_DATA), &go);
+ // Reset counters
+ gp.resetCount = gr.restartCount = gr.clearCount = 0;
+ gp.auditCounter = 0;
+ // Save persistent data changes to NV
+ // Note: since there are so many changes to the persistent data structure, the
+ // entire PERSISTENT_DATA structure is written as a unit
+ NvWrite(NV_PERSISTENT_DATA, sizeof(PERSISTENT_DATA), &gp);
+ // Reset the PCR authValues (this does not change the PCRs)
+ PCR_ClearAuth();
+ // Bump the PCR counter
+ PCRChanged(0);
+ // orderly state should be cleared because of the update to state clear data
+ g_clearOrderly = TRUE;
+ return TPM_RC_SUCCESS;
+}
+#endif // CC_Clear
+#include "Tpm.h"
+#include "ClearControl_fp.h"
+#if CC_ClearControl // Conditional expansion of this file
+TPM_RC
+TPM2_ClearControl(
+ ClearControl_In *in // IN: input parameter list
+ )
+{
+ // The command needs NV update.
+ RETURN_IF_NV_IS_NOT_AVAILABLE;
+ // Input Validation
+ // LockoutAuth may be used to set disableLockoutClear to TRUE but not to FALSE
+ if(in->auth == TPM_RH_LOCKOUT && in->disable == NO)
+ return TPM_RC_AUTH_FAIL;
+ // Internal Data Update
+ if(in->disable == YES)
+ gp.disableClear = TRUE;
+ else
+ gp.disableClear = FALSE;
+ // Record the change to NV
+ NV_SYNC_PERSISTENT(disableClear);
+ return TPM_RC_SUCCESS;
+}
+#endif // CC_ClearControl
+#include "Tpm.h"
+#include "HierarchyChangeAuth_fp.h"
+#if CC_HierarchyChangeAuth // Conditional expansion of this file
+#include "Object_spt_fp.h"
+TPM_RC
+TPM2_HierarchyChangeAuth(
+ HierarchyChangeAuth_In *in // IN: input parameter list
+ )
+{
+ // The command needs NV update.
+ RETURN_IF_NV_IS_NOT_AVAILABLE;
+ // Make sure that the authorization value is a reasonable size (not larger than
+ // the size of the digest produced by the integrity hash. The integrity
+ // hash is assumed to produce the longest digest of any hash implemented
+ // on the TPM. This will also remove trailing zeros from the authValue.
+ if(MemoryRemoveTrailingZeros(&in->newAuth) > CONTEXT_INTEGRITY_HASH_SIZE)
+ return TPM_RCS_SIZE + RC_HierarchyChangeAuth_newAuth;
+ // Set hierarchy authValue
+ switch(in->authHandle)
+ {
+ case TPM_RH_OWNER:
+ gp.ownerAuth = in->newAuth;
+ NV_SYNC_PERSISTENT(ownerAuth);
+ break;
+ case TPM_RH_ENDORSEMENT:
+ gp.endorsementAuth = in->newAuth;
+ NV_SYNC_PERSISTENT(endorsementAuth);
+ break;
+ case TPM_RH_PLATFORM:
+ gc.platformAuth = in->newAuth;
+ // orderly state should be cleared
+ g_clearOrderly = TRUE;
+ break;
+ case TPM_RH_LOCKOUT:
+ gp.lockoutAuth = in->newAuth;
+ NV_SYNC_PERSISTENT(lockoutAuth);
+ break;
+ default:
+ FAIL(FATAL_ERROR_INTERNAL);
+ break;
+ }
+ return TPM_RC_SUCCESS;
+}
+#endif // CC_HierarchyChangeAuth
diff --git a/src/tpm2/HierarchyControl_fp.h b/src/tpm2/HierarchyControl_fp.h
new file mode 100644
index 0000000..ab22a35
--- /dev/null
+++ b/src/tpm2/HierarchyControl_fp.h
@@ -0,0 +1,83 @@
+/********************************************************************************/
+/* */
+/* */
+/* Written by Ken Goldman */
+/* IBM Thomas J. Watson Research Center */
+/* $Id: HierarchyControl_fp.h 809 2016-11-16 18:31:54Z kgoldman $ */
+/* */
+/* Licenses and Notices */
+/* */
+/* 1. Copyright Licenses: */
+/* */
+/* - Trusted Computing Group (TCG) grants to the user of the source code in */
+/* this specification (the "Source Code") a worldwide, irrevocable, */
+/* nonexclusive, royalty free, copyright license to reproduce, create */
+/* derivative works, distribute, display and perform the Source Code and */
+/* derivative works thereof, and to grant others the rights granted herein. */
+/* */
+/* - The TCG grants to the user of the other parts of the specification */
+/* (other than the Source Code) the rights to reproduce, distribute, */
+/* display, and perform the specification solely for the purpose of */
+/* developing products based on such documents. */
+/* */
+/* 2. Source Code Distribution Conditions: */
+/* */
+/* - Redistributions of Source Code must retain the above copyright licenses, */
+/* this list of conditions and the following disclaimers. */
+/* */
+/* - Redistributions in binary form must reproduce the above copyright */
+/* licenses, this list of conditions and the following disclaimers in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* 3. Disclaimers: */
+/* */
+/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
+/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
+/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
+/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
+/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
+/* information on specification licensing rights available through TCG */
+/* membership agreements. */
+/* */
+/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
+/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
+/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
+/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
+/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
+/* */
+/* - Without limitation, TCG and its members and licensors disclaim all */
+/* liability, including liability for infringement of any proprietary */
+/* rights, relating to use of information in this specification and to the */
+/* implementation of this specification, and TCG disclaims all liability for */
+/* cost of procurement of substitute goods or services, lost profits, loss */
+/* of use, loss of data or any incidental, consequential, direct, indirect, */
+/* or special damages, whether under contract, tort, warranty or otherwise, */
+/* arising in any way out of use or reliance upon this specification or any */
+/* information herein. */
+/* */
+/* (c) Copyright IBM Corp. and others, 2012-2015 */
+/* */
+/********************************************************************************/
+
+/* rev 119 */
+
+#ifndef HIERARCHYCONTROL_FP_H
+#define HIERARCHYCONTROL_FP_H
+
+typedef struct {
+ TPMI_RH_HIERARCHY authHandle;
+ TPMI_RH_ENABLES enable;
+ TPMI_YES_NO state;
+} HierarchyControl_In;
+
+#define RC_HierarchyControl_authHandle (TPM_RC_H + TPM_RC_1)
+#define RC_HierarchyControl_enable (TPM_RC_P + TPM_RC_1)
+#define RC_HierarchyControl_state (TPM_RC_P + TPM_RC_2)
+
+TPM_RC
+TPM2_HierarchyControl(
+ HierarchyControl_In *in // IN: input parameter list
+ );
+
+
+#endif
diff --git a/src/tpm2/Hierarchy_fp.h b/src/tpm2/Hierarchy_fp.h
new file mode 100644
index 0000000..3cc2a19
--- /dev/null
+++ b/src/tpm2/Hierarchy_fp.h
@@ -0,0 +1,93 @@
+/********************************************************************************/
+/* */
+/* */
+/* Written by Ken Goldman */
+/* IBM Thomas J. Watson Research Center */
+/* $Id: Hierarchy_fp.h 1490 2019-07-26 21:13:22Z kgoldman $ */
+/* */
+/* Licenses and Notices */
+/* */
+/* 1. Copyright Licenses: */
+/* */
+/* - Trusted Computing Group (TCG) grants to the user of the source code in */
+/* this specification (the "Source Code") a worldwide, irrevocable, */
+/* nonexclusive, royalty free, copyright license to reproduce, create */
+/* derivative works, distribute, display and perform the Source Code and */
+/* derivative works thereof, and to grant others the rights granted herein. */
+/* */
+/* - The TCG grants to the user of the other parts of the specification */
+/* (other than the Source Code) the rights to reproduce, distribute, */
+/* display, and perform the specification solely for the purpose of */
+/* developing products based on such documents. */
+/* */
+/* 2. Source Code Distribution Conditions: */
+/* */
+/* - Redistributions of Source Code must retain the above copyright licenses, */
+/* this list of conditions and the following disclaimers. */
+/* */
+/* - Redistributions in binary form must reproduce the above copyright */
+/* licenses, this list of conditions and the following disclaimers in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* 3. Disclaimers: */
+/* */
+/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
+/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
+/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
+/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
+/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
+/* information on specification licensing rights available through TCG */
+/* membership agreements. */
+/* */
+/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
+/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
+/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
+/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
+/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
+/* */
+/* - Without limitation, TCG and its members and licensors disclaim all */
+/* liability, including liability for infringement of any proprietary */
+/* rights, relating to use of information in this specification and to the */
+/* implementation of this specification, and TCG disclaims all liability for */
+/* cost of procurement of substitute goods or services, lost profits, loss */
+/* of use, loss of data or any incidental, consequential, direct, indirect, */
+/* or special damages, whether under contract, tort, warranty or otherwise, */
+/* arising in any way out of use or reliance upon this specification or any */
+/* information herein. */
+/* */
+/* (c) Copyright IBM Corp. and others, 2016 - 2019 */
+/* */
+/********************************************************************************/
+
+#ifndef HIERARCHY_FP_H
+#define HIERARCHY_FP_H
+
+void
+HierarchyPreInstall_Init(
+ void
+ );
+BOOL
+HierarchyStartup(
+ STARTUP_TYPE type // IN: start up type
+ );
+TPM2B_PROOF *
+HierarchyGetProof(
+ TPMI_RH_HIERARCHY hierarchy // IN: hierarchy constant
+ );
+TPM2B_SEED *
+HierarchyGetPrimarySeed(
+ TPMI_RH_HIERARCHY hierarchy // IN: hierarchy
+ );
+// libtpms added begin
+SEED_COMPAT_LEVEL
+HierarchyGetPrimarySeedCompatLevel(
+ TPMI_RH_HIERARCHY hierarchy // IN: hierarchy
+ );
+// libtpms added end
+BOOL
+HierarchyIsEnabled(
+ TPMI_RH_HIERARCHY hierarchy // IN: hierarchy
+ );
+
+
+#endif
diff --git a/src/tpm2/Import_fp.h b/src/tpm2/Import_fp.h
new file mode 100644
index 0000000..f059b98
--- /dev/null
+++ b/src/tpm2/Import_fp.h
@@ -0,0 +1,93 @@
+/********************************************************************************/
+/* */
+/* */
+/* Written by Ken Goldman */
+/* IBM Thomas J. Watson Research Center */
+/* $Id: Import_fp.h 809 2016-11-16 18:31:54Z kgoldman $ */
+/* */
+/* Licenses and Notices */
+/* */
+/* 1. Copyright Licenses: */
+/* */
+/* - Trusted Computing Group (TCG) grants to the user of the source code in */
+/* this specification (the "Source Code") a worldwide, irrevocable, */
+/* nonexclusive, royalty free, copyright license to reproduce, create */
+/* derivative works, distribute, display and perform the Source Code and */
+/* derivative works thereof, and to grant others the rights granted herein. */
+/* */
+/* - The TCG grants to the user of the other parts of the specification */
+/* (other than the Source Code) the rights to reproduce, distribute, */
+/* display, and perform the specification solely for the purpose of */
+/* developing products based on such documents. */
+/* */
+/* 2. Source Code Distribution Conditions: */
+/* */
+/* - Redistributions of Source Code must retain the above copyright licenses, */
+/* this list of conditions and the following disclaimers. */
+/* */
+/* - Redistributions in binary form must reproduce the above copyright */
+/* licenses, this list of conditions and the following disclaimers in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* 3. Disclaimers: */
+/* */
+/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
+/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
+/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
+/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
+/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
+/* information on specification licensing rights available through TCG */
+/* membership agreements. */
+/* */
+/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
+/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
+/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
+/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
+/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
+/* */
+/* - Without limitation, TCG and its members and licensors disclaim all */
+/* liability, including liability for infringement of any proprietary */
+/* rights, relating to use of information in this specification and to the */
+/* implementation of this specification, and TCG disclaims all liability for */
+/* cost of procurement of substitute goods or services, lost profits, loss */
+/* of use, loss of data or any incidental, consequential, direct, indirect, */
+/* or special damages, whether under contract, tort, warranty or otherwise, */
+/* arising in any way out of use or reliance upon this specification or any */
+/* information herein. */
+/* */
+/* (c) Copyright IBM Corp. and others, 2012-2015 */
+/* */
+/********************************************************************************/
+
+/* rev 119 */
+
+#ifndef IMPORT_FP_H
+#define IMPORT_FP_H
+
+typedef struct {
+ TPMI_DH_OBJECT parentHandle;
+ TPM2B_DATA encryptionKey;
+ TPM2B_PUBLIC objectPublic;
+ TPM2B_PRIVATE duplicate;
+ TPM2B_ENCRYPTED_SECRET inSymSeed;
+ TPMT_SYM_DEF_OBJECT symmetricAlg;
+} Import_In;
+
+#define RC_Import_parentHandle (TPM_RC_H + TPM_RC_1)
+#define RC_Import_encryptionKey (TPM_RC_P + TPM_RC_1)
+#define RC_Import_objectPublic (TPM_RC_P + TPM_RC_2)
+#define RC_Import_duplicate (TPM_RC_P + TPM_RC_3)
+#define RC_Import_inSymSeed (TPM_RC_P + TPM_RC_4)
+#define RC_Import_symmetricAlg (TPM_RC_P + TPM_RC_5)
+
+typedef struct {
+ TPM2B_PRIVATE outPrivate;
+} Import_Out;
+
+TPM_RC
+TPM2_Import(
+ Import_In *in, // IN: input parameter list
+ Import_Out *out // OUT: output parameter list
+ );
+
+#endif
diff --git a/src/tpm2/IncrementalSelfTest_fp.h b/src/tpm2/IncrementalSelfTest_fp.h
new file mode 100644
index 0000000..f817352
--- /dev/null
+++ b/src/tpm2/IncrementalSelfTest_fp.h
@@ -0,0 +1,84 @@
+/********************************************************************************/
+/* */
+/* */
+/* Written by Ken Goldman */
+/* IBM Thomas J. Watson Research Center */
+/* $Id: IncrementalSelfTest_fp.h 809 2016-11-16 18:31:54Z kgoldman $ */
+/* */
+/* Licenses and Notices */
+/* */
+/* 1. Copyright Licenses: */
+/* */
+/* - Trusted Computing Group (TCG) grants to the user of the source code in */
+/* this specification (the "Source Code") a worldwide, irrevocable, */
+/* nonexclusive, royalty free, copyright license to reproduce, create */
+/* derivative works, distribute, display and perform the Source Code and */
+/* derivative works thereof, and to grant others the rights granted herein. */
+/* */
+/* - The TCG grants to the user of the other parts of the specification */
+/* (other than the Source Code) the rights to reproduce, distribute, */
+/* display, and perform the specification solely for the purpose of */
+/* developing products based on such documents. */
+/* */
+/* 2. Source Code Distribution Conditions: */
+/* */
+/* - Redistributions of Source Code must retain the above copyright licenses, */
+/* this list of conditions and the following disclaimers. */
+/* */
+/* - Redistributions in binary form must reproduce the above copyright */
+/* licenses, this list of conditions and the following disclaimers in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* 3. Disclaimers: */
+/* */
+/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
+/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
+/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
+/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
+/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
+/* information on specification licensing rights available through TCG */
+/* membership agreements. */
+/* */
+/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
+/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
+/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
+/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
+/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
+/* */
+/* - Without limitation, TCG and its members and licensors disclaim all */
+/* liability, including liability for infringement of any proprietary */
+/* rights, relating to use of information in this specification and to the */
+/* implementation of this specification, and TCG disclaims all liability for */
+/* cost of procurement of substitute goods or services, lost profits, loss */
+/* of use, loss of data or any incidental, consequential, direct, indirect, */
+/* or special damages, whether under contract, tort, warranty or otherwise, */
+/* arising in any way out of use or reliance upon this specification or any */
+/* information herein. */
+/* */
+/* (c) Copyright IBM Corp. and others, 2012-2015 */
+/* */
+/********************************************************************************/
+
+/* rev 119 */
+
+#ifndef INCREMENTALSELFTEST_FP_H
+#define INCREMENTALSELFTEST_FP_H
+
+typedef struct{
+ TPML_ALG toTest;
+} IncrementalSelfTest_In;
+
+typedef struct{
+ TPML_ALG toDoList;
+} IncrementalSelfTest_Out;
+
+#define RC_IncrementalSelfTest_toTest (TPM_RC_P + TPM_RC_1)
+
+TPM_RC
+TPM2_IncrementalSelfTest(
+ IncrementalSelfTest_In *in, // IN: input parameter list
+ IncrementalSelfTest_Out *out // OUT: output parameter list
+ );
+
+
+#endif
diff --git a/src/tpm2/IntegrityCommands.c b/src/tpm2/IntegrityCommands.c
new file mode 100644
index 0000000..eb9f202
--- /dev/null
+++ b/src/tpm2/IntegrityCommands.c
@@ -0,0 +1,411 @@
+/********************************************************************************/
+/* */
+/* Integrity Collection (PCR) */
+/* Written by Ken Goldman */
+/* IBM Thomas J. Watson Research Center */
+/* $Id: IntegrityCommands.c 1490 2019-07-26 21:13:22Z kgoldman $ */
+/* */
+/* Licenses and Notices */
+/* */
+/* 1. Copyright Licenses: */
+/* */
+/* - Trusted Computing Group (TCG) grants to the user of the source code in */
+/* this specification (the "Source Code") a worldwide, irrevocable, */
+/* nonexclusive, royalty free, copyright license to reproduce, create */
+/* derivative works, distribute, display and perform the Source Code and */
+/* derivative works thereof, and to grant others the rights granted herein. */
+/* */
+/* - The TCG grants to the user of the other parts of the specification */
+/* (other than the Source Code) the rights to reproduce, distribute, */
+/* display, and perform the specification solely for the purpose of */
+/* developing products based on such documents. */
+/* */
+/* 2. Source Code Distribution Conditions: */
+/* */
+/* - Redistributions of Source Code must retain the above copyright licenses, */
+/* this list of conditions and the following disclaimers. */
+/* */
+/* - Redistributions in binary form must reproduce the above copyright */
+/* licenses, this list of conditions and the following disclaimers in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* 3. Disclaimers: */
+/* */
+/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
+/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
+/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
+/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
+/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
+/* information on specification licensing rights available through TCG */
+/* membership agreements. */
+/* */
+/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
+/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
+/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
+/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
+/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
+/* */
+/* - Without limitation, TCG and its members and licensors disclaim all */
+/* liability, including liability for infringement of any proprietary */
+/* rights, relating to use of information in this specification and to the */
+/* implementation of this specification, and TCG disclaims all liability for */
+/* cost of procurement of substitute goods or services, lost profits, loss */
+/* of use, loss of data or any incidental, consequential, direct, indirect, */
+/* or special damages, whether under contract, tort, warranty or otherwise, */
+/* arising in any way out of use or reliance upon this specification or any */
+/* information herein. */
+/* */
+/* (c) Copyright IBM Corp. and others, 2016 - 2018 */
+/* */
+/********************************************************************************/
+
+#include "Tpm.h"
+#include "PCR_Extend_fp.h"
+#if CC_PCR_Extend // Conditional expansion of this file
+TPM_RC
+TPM2_PCR_Extend(
+ PCR_Extend_In *in // IN: input parameter list
+ )
+{
+ UINT32 i;
+ // Input Validation
+ // NOTE: This function assumes that the unmarshaling function for 'digests' will
+ // have validated that all of the indicated hash algorithms are valid. If the
+ // hash algorithms are correct, the unmarshaling code will unmarshal a digest
+ // of the size indicated by the hash algorithm. If the overall size is not
+ // consistent, the unmarshaling code will run out of input data or have input
+ // data left over. In either case, it will cause an unmarshaling error and this
+ // function will not be called.
+ // For NULL handle, do nothing and return success
+ if(in->pcrHandle == TPM_RH_NULL)
+ return TPM_RC_SUCCESS;
+ // Check if the extend operation is allowed by the current command locality
+ if(!PCRIsExtendAllowed(in->pcrHandle))
+ return TPM_RC_LOCALITY;
+ // If PCR is state saved and we need to update orderlyState, check NV
+ // availability
+ if(PCRIsStateSaved(in->pcrHandle))
+ RETURN_IF_ORDERLY;
+ // Internal Data Update
+ // Iterate input digest list to extend
+ for(i = 0; i < in->digests.count; i++)
+ {
+ PCRExtend(in->pcrHandle, in->digests.digests[i].hashAlg,
+ CryptHashGetDigestSize(in->digests.digests[i].hashAlg),
+ (BYTE *)&in->digests.digests[i].digest);
+ }
+ return TPM_RC_SUCCESS;
+}
+#endif // CC_PCR_Extend
+#include "Tpm.h"
+#include "PCR_Event_fp.h"
+#if CC_PCR_Event // Conditional expansion of this file
+TPM_RC
+TPM2_PCR_Event(
+ PCR_Event_In *in, // IN: input parameter list
+ PCR_Event_Out *out // OUT: output parameter list
+ )
+{
+ HASH_STATE hashState;
+ UINT32 i;
+ UINT16 size;
+ // Input Validation
+ // If a PCR extend is required
+ if(in->pcrHandle != TPM_RH_NULL)
+ {
+ // If the PCR is not allow to extend, return error
+ if(!PCRIsExtendAllowed(in->pcrHandle))
+ return TPM_RC_LOCALITY;
+ // If PCR is state saved and we need to update orderlyState, check NV
+ // availability
+ if(PCRIsStateSaved(in->pcrHandle))
+ RETURN_IF_ORDERLY;
+ }
+ // Internal Data Update
+ out->digests.count = HASH_COUNT;
+ // Iterate supported PCR bank algorithms to extend
+ for(i = 0; i < HASH_COUNT; i++)
+ {
+ TPM_ALG_ID hash = CryptHashGetAlgByIndex(i);
+ out->digests.digests[i].hashAlg = hash;
+ size = CryptHashStart(&hashState, hash);
+ CryptDigestUpdate2B(&hashState, &in->eventData.b);
+ CryptHashEnd(&hashState, size,
+ (BYTE *)&out->digests.digests[i].digest);
+ if(in->pcrHandle != TPM_RH_NULL)
+ PCRExtend(in->pcrHandle, hash, size,
+ (BYTE *)&out->digests.digests[i].digest);
+ }
+ return TPM_RC_SUCCESS;
+}
+#endif // CC_PCR_Event
+#include "Tpm.h"
+#include "PCR_Read_fp.h"
+#if CC_PCR_Read // Conditional expansion of this file
+TPM_RC
+TPM2_PCR_Read(
+ PCR_Read_In *in, // IN: input parameter list
+ PCR_Read_Out *out // OUT: output parameter list
+ )
+{
+ // Command Output
+ // Call PCR read function. input pcrSelectionIn parameter could be changed
+ // to reflect the actual PCR being returned
+ PCRRead(&in->pcrSelectionIn, &out->pcrValues, &out->pcrUpdateCounter);
+ out->pcrSelectionOut = in->pcrSelectionIn;
+ return TPM_RC_SUCCESS;
+}
+#endif // CC_PCR_Read
+#include "Tpm.h"
+#include "PCR_Allocate_fp.h"
+#if CC_PCR_Allocate // Conditional expansion of this file
+TPM_RC
+TPM2_PCR_Allocate(
+ PCR_Allocate_In *in, // IN: input parameter list
+ PCR_Allocate_Out *out // OUT: output parameter list
+ )
+{
+ TPM_RC result;
+ // The command needs NV update. Check if NV is available.
+ // A TPM_RC_NV_UNAVAILABLE or TPM_RC_NV_RATE error may be returned at
+ // this point.
+ // Note: These codes are not listed in the return values above because it is
+ // an implementation choice to check in this routine rather than in a common
+ // function that is called before these actions are called. These return values
+ // are described in the Response Code section of Part 3.
+ RETURN_IF_NV_IS_NOT_AVAILABLE;
+ // Command Output
+ // Call PCR Allocation function.
+ result = PCRAllocate(&in->pcrAllocation, &out->maxPCR,
+ &out->sizeNeeded, &out->sizeAvailable);
+ if(result == TPM_RC_PCR)
+ return result;
+ //
+ out->allocationSuccess = (result == TPM_RC_SUCCESS);
+ // if re-configuration succeeds, set the flag to indicate PCR configuration is
+ // going to be changed in next boot
+ if(out->allocationSuccess == YES)
+ g_pcrReConfig = TRUE;
+ return TPM_RC_SUCCESS;
+}
+#endif // CC_PCR_Allocate
+#include "Tpm.h"
+#include "PCR_SetAuthPolicy_fp.h"
+#if CC_PCR_SetAuthPolicy // Conditional expansion of this file
+TPM_RC
+TPM2_PCR_SetAuthPolicy(
+ PCR_SetAuthPolicy_In *in // IN: input parameter list
+ )
+{
+ UINT32 groupIndex;
+ // The command needs NV update. Check if NV is available.
+ // A TPM_RC_NV_UNAVAILABLE or TPM_RC_NV_RATE error may be returned at
+ // this point
+ RETURN_IF_NV_IS_NOT_AVAILABLE;
+ // Input Validation:
+ // Check the authPolicy consistent with hash algorithm
+ if(in->authPolicy.t.size != CryptHashGetDigestSize(in->hashAlg))
+ return TPM_RCS_SIZE + RC_PCR_SetAuthPolicy_authPolicy;
+ // If PCR does not belong to a policy group, return TPM_RC_VALUE
+ if(!PCRBelongsPolicyGroup(in->pcrNum, &groupIndex))
+ return TPM_RCS_VALUE + RC_PCR_SetAuthPolicy_pcrNum;
+ // Internal Data Update
+ // Set PCR policy
+ gp.pcrPolicies.hashAlg[groupIndex] = in->hashAlg;
+ gp.pcrPolicies.policy[groupIndex] = in->authPolicy;
+ // Save new policy to NV
+ NV_SYNC_PERSISTENT(pcrPolicies);
+ return TPM_RC_SUCCESS;
+}
+#endif // CC_PCR_SetAuthPolicy
+#include "Tpm.h"
+#include "PCR_SetAuthValue_fp.h"
+#if CC_PCR_SetAuthValue // Conditional expansion of this file
+// CC_PCR_SetAuthPolicy
+TPM_RC
+TPM2_PCR_SetAuthValue(
+ PCR_SetAuthValue_In *in // IN: input parameter list
+ )
+{
+ UINT32 groupIndex;
+ // Input Validation:
+ // If PCR does not belong to an auth group, return TPM_RC_VALUE
+ if(!PCRBelongsAuthGroup(in->pcrHandle, &groupIndex))
+ return TPM_RC_VALUE;
+ // The command may cause the orderlyState to be cleared due to the update of
+ // state clear data. If this is the case, Check if NV is available.
+ // A TPM_RC_NV_UNAVAILABLE or TPM_RC_NV_RATE error may be returned at
+ // this point
+ RETURN_IF_ORDERLY;
+ // Internal Data Update
+ // Set PCR authValue
+ MemoryRemoveTrailingZeros(&in->auth);
+ gc.pcrAuthValues.auth[groupIndex] = in->auth;
+ return TPM_RC_SUCCESS;
+}
+#endif // CC_PCR_SetAuthValue
+#include "Tpm.h"
+#include "PCR_Reset_fp.h"
+#if CC_PCR_Reset // Conditional expansion of this file
+TPM_RC
+TPM2_PCR_Reset(
+ PCR_Reset_In *in // IN: input parameter list
+ )
+{
+ // Input Validation
+ // Check if the reset operation is allowed by the current command locality
+ if(!PCRIsResetAllowed(in->pcrHandle))
+ return TPM_RC_LOCALITY;
+ // If PCR is state saved and we need to update orderlyState, check NV
+ // availability
+ if(PCRIsStateSaved(in->pcrHandle))
+ RETURN_IF_ORDERLY;
+ // Internal Data Update
+ // Reset selected PCR in all banks to 0
+ PCRSetValue(in->pcrHandle, 0);
+ // Indicate that the PCR changed so that pcrCounter will be incremented if
+ // necessary.
+ PCRChanged(in->pcrHandle);
+ return TPM_RC_SUCCESS;
+}
+#endif // CC_PCR_Reset
+
+#include "Tpm.h"
+/* This function is called to process a _TPM_Hash_Start() indication. */
+LIB_EXPORT void
+_TPM_Hash_Start(
+ void
+ )
+{
+ TPM_RC result;
+ TPMI_DH_OBJECT handle;
+ // If a DRTM sequence object exists, free it up
+ if(g_DRTMHandle != TPM_RH_UNASSIGNED)
+ {
+ FlushObject(g_DRTMHandle);
+ g_DRTMHandle = TPM_RH_UNASSIGNED;
+ }
+ // Create an event sequence object and store the handle in global
+ // g_DRTMHandle. A TPM_RC_OBJECT_MEMORY error may be returned at this point
+ // The NULL value for the first parameter will cause the sequence structure to
+ // be allocated without being set as present. This keeps the sequence from
+ // being left behind if the sequence is terminated early.
+ result = ObjectCreateEventSequence(NULL, &g_DRTMHandle);
+ // If a free slot was not available, then free up a slot.
+ if(result != TPM_RC_SUCCESS)
+ {
+ // An implementation does not need to have a fixed relationship between
+ // slot numbers and handle numbers. To handle the general case, scan for
+ // a handle that is assigned and free it for the DRTM sequence.
+ // In the reference implementation, the relationship between handles and
+ // slots is fixed. So, if the call to ObjectCreateEvenSequence()
+ // failed indicating that all slots are occupied, then the first handle we
+ // are going to check (TRANSIENT_FIRST) will be occupied. It will be freed
+ // so that it can be assigned for use as the DRTM sequence object.
+ for(handle = TRANSIENT_FIRST; handle < TRANSIENT_LAST; handle++)
+ {
+ // try to flush the first object
+ if(IsObjectPresent(handle))
+ break;
+ }
+ // If the first call to find a slot fails but none of the slots is occupied
+ // then there's a big problem
+ pAssert(handle < TRANSIENT_LAST);
+ // Free the slot
+ FlushObject(handle);
+ // Try to create an event sequence object again. This time, we must
+ // succeed.
+ result = ObjectCreateEventSequence(NULL, &g_DRTMHandle);
+ if(result != TPM_RC_SUCCESS)
+ FAIL(FATAL_ERROR_INTERNAL);
+ }
+ return;
+}
+
+#include "Tpm.h"
+/* This function is called to process a _TPM_Hash_Data() indication. */
+LIB_EXPORT void
+_TPM_Hash_Data(
+ uint32_t dataSize, // IN: size of data to be extend
+ unsigned char *data // IN: data buffer
+ )
+{
+ UINT32 i;
+ HASH_OBJECT *hashObject;
+ TPMI_DH_PCR pcrHandle = TPMIsStarted()
+ ? PCR_FIRST + DRTM_PCR : PCR_FIRST + HCRTM_PCR;
+ // If there is no DRTM sequence object, then _TPM_Hash_Start
+ // was not called so this function returns without doing
+ // anything.
+ if(g_DRTMHandle == TPM_RH_UNASSIGNED)
+ return;
+ hashObject = (HASH_OBJECT *)HandleToObject(g_DRTMHandle);
+ pAssert(hashObject->attributes.eventSeq);
+ // For each of the implemented hash algorithms, update the digest with the
+ // data provided.
+ for(i = 0; i < HASH_COUNT; i++)
+ {
+ // make sure that the PCR is implemented for this algorithm
+ if(PcrIsAllocated(pcrHandle,
+ hashObject->state.hashState[i].hashAlg))
+ // Update sequence object
+ CryptDigestUpdate(&hashObject->state.hashState[i], dataSize, data);
+ }
+ return;
+}
+
+#include "Tpm.h"
+/* This function is called to process a _TPM_Hash_End() indication. */
+LIB_EXPORT void
+_TPM_Hash_End(
+ void
+ )
+{
+ UINT32 i;
+ TPM2B_DIGEST digest;
+ HASH_OBJECT *hashObject;
+ TPMI_DH_PCR pcrHandle;
+ // If the DRTM handle is not being used, then either _TPM_Hash_Start has not
+ // been called, _TPM_Hash_End was previously called, or some other command
+ // was executed and the sequence was aborted.
+ if(g_DRTMHandle == TPM_RH_UNASSIGNED)
+ return;
+ // Get DRTM sequence object
+ hashObject = (HASH_OBJECT *)HandleToObject(g_DRTMHandle);
+ // Is this _TPM_Hash_End after Startup or before
+ if(TPMIsStarted())
+ {
+ // After
+ // Reset the DRTM PCR
+ PCRResetDynamics();
+ // Extend the DRTM_PCR.
+ pcrHandle = PCR_FIRST + DRTM_PCR;
+ // DRTM sequence increments restartCount
+ gr.restartCount++;
+ }
+ else
+ {
+ pcrHandle = PCR_FIRST + HCRTM_PCR;
+ g_DrtmPreStartup = TRUE;
+ }
+ // Complete hash and extend PCR, or if this is an HCRTM, complete
+ // the hash, reset the H-CRTM register (PCR[0]) to 0...04, and then
+ // extend the H-CRTM data
+ for(i = 0; i < HASH_COUNT; i++)
+ {
+ TPMI_ALG_HASH hash = CryptHashGetAlgByIndex(i);
+ // make sure that the PCR is implemented for this algorithm
+ if(PcrIsAllocated(pcrHandle,
+ hashObject->state.hashState[i].hashAlg))
+ {
+ // Complete hash
+ digest.t.size = CryptHashGetDigestSize(hash);
+ CryptHashEnd2B(&hashObject->state.hashState[i], &digest.b);
+ PcrDrtm(pcrHandle, hash, &digest);
+ }
+ }
+ // Flush sequence object.
+ FlushObject(g_DRTMHandle);
+ g_DRTMHandle = TPM_RH_UNASSIGNED;
+ return;
+}
diff --git a/src/tpm2/InternalRoutines.h b/src/tpm2/InternalRoutines.h
new file mode 100644
index 0000000..48a5037
--- /dev/null
+++ b/src/tpm2/InternalRoutines.h
@@ -0,0 +1,146 @@
+/********************************************************************************/
+/* */
+/* Include Headers for Internal Routines */
+/* Written by Ken Goldman */
+/* IBM Thomas J. Watson Research Center */
+/* $Id: InternalRoutines.h 1594 2020-03-26 22:15:48Z kgoldman $ */
+/* */
+/* Licenses and Notices */
+/* */
+/* 1. Copyright Licenses: */
+/* */
+/* - Trusted Computing Group (TCG) grants to the user of the source code in */
+/* this specification (the "Source Code") a worldwide, irrevocable, */
+/* nonexclusive, royalty free, copyright license to reproduce, create */
+/* derivative works, distribute, display and perform the Source Code and */
+/* derivative works thereof, and to grant others the rights granted herein. */
+/* */
+/* - The TCG grants to the user of the other parts of the specification */
+/* (other than the Source Code) the rights to reproduce, distribute, */
+/* display, and perform the specification solely for the purpose of */
+/* developing products based on such documents. */
+/* */
+/* 2. Source Code Distribution Conditions: */
+/* */
+/* - Redistributions of Source Code must retain the above copyright licenses, */
+/* this list of conditions and the following disclaimers. */
+/* */
+/* - Redistributions in binary form must reproduce the above copyright */
+/* licenses, this list of conditions and the following disclaimers in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* 3. Disclaimers: */
+/* */
+/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
+/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
+/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
+/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
+/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
+/* information on specification licensing rights available through TCG */
+/* membership agreements. */
+/* */
+/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
+/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
+/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
+/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
+/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
+/* */
+/* - Without limitation, TCG and its members and licensors disclaim all */
+/* liability, including liability for infringement of any proprietary */
+/* rights, relating to use of information in this specification and to the */
+/* implementation of this specification, and TCG disclaims all liability for */
+/* cost of procurement of substitute goods or services, lost profits, loss */
+/* of use, loss of data or any incidental, consequential, direct, indirect, */
+/* or special damages, whether under contract, tort, warranty or otherwise, */
+/* arising in any way out of use or reliance upon this specification or any */
+/* information herein. */
+/* */
+/* (c) Copyright IBM Corp. and others, 2016 - 2020 */
+/* */
+/********************************************************************************/
+
+#ifndef INTERNALROUTINES_H
+#define INTERNALROUTINES_H
+
+#if !defined _LIB_SUPPORT_H_ && !defined _TPM_H_
+#error "Should not be called"
+#endif
+/* DRTM functions */
+#include "_TPM_Hash_Start_fp.h"
+#include "_TPM_Hash_Data_fp.h"
+#include "_TPM_Hash_End_fp.h"
+/* Internal subsystem functions */
+#include "Object_fp.h"
+#include "Context_spt_fp.h"
+#include "Object_spt_fp.h"
+#include "Entity_fp.h"
+#include "Session_fp.h"
+#include "Hierarchy_fp.h"
+#include "NVReserved_fp.h"
+#include "NVDynamic_fp.h"
+#include "NV_spt_fp.h"
+#include "ACT_spt_fp.h"
+#include "PCR_fp.h"
+#include "DA_fp.h"
+#include "TpmFail_fp.h"
+#include "SessionProcess_fp.h"
+/* Internal support functions */
+#include "CommandCodeAttributes_fp.h"
+#include "Marshal_fp.h"
+#include "Unmarshal_fp.h" /* kgold */
+#include "Time_fp.h"
+#include "Locality_fp.h"
+#include "PP_fp.h"
+#include "CommandAudit_fp.h"
+#include "Manufacture_fp.h"
+#include "Handle_fp.h"
+#include "Power_fp.h"
+#include "Response_fp.h"
+#include "CommandDispatcher_fp.h"
+#if CC_AC_Send
+# include "AC_spt_fp.h"
+#endif // CC_AC_Send
+/* Miscellaneous */
+#include "Bits_fp.h"
+#include "AlgorithmCap_fp.h"
+#include "PropertyCap_fp.h"
+#include "IoBuffers_fp.h"
+#include "Memory_fp.h"
+#include "ResponseCodeProcessing_fp.h"
+/* Internal cryptographic functions */
+#include "BnConvert_fp.h"
+#include "BnMath_fp.h"
+#include "BnMemory_fp.h"
+#include "Ticket_fp.h"
+#include "CryptUtil_fp.h"
+#include "CryptHash_fp.h"
+#include "CryptSym_fp.h"
+#include "CryptDes_fp.h"
+#include "CryptPrime_fp.h"
+#include "CryptRand_fp.h"
+#include "CryptSelfTest_fp.h"
+#include "MathOnByteBuffers_fp.h"
+#include "CryptSym_fp.h"
+#include "AlgorithmTests_fp.h"
+#if ALG_RSA
+#include "CryptRsa_fp.h"
+#include "CryptPrimeSieve_fp.h"
+#endif
+#if ALG_ECC
+#include "CryptEccMain_fp.h"
+#include "CryptEccSignature_fp.h"
+#include "CryptEccKeyExchange_fp.h"
+#include "CryptEccCrypt_fp.h"
+#endif
+#if CC_MAC || CC_MAC_Start
+# include "CryptSmac_fp.h"
+# if ALG_CMAC
+# include "CryptCmac_fp.h"
+# endif
+#endif
+/* Support library */
+#include "SupportLibraryFunctionPrototypes_fp.h"
+/* Linkage to platform functions */
+#include "Platform_fp.h"
+
+#endif
diff --git a/src/tpm2/IoBuffers.c b/src/tpm2/IoBuffers.c
new file mode 100644
index 0000000..03739ed
--- /dev/null
+++ b/src/tpm2/IoBuffers.c
@@ -0,0 +1,145 @@
+/********************************************************************************/
+/* */
+/* I/O Buffers */
+/* Written by Ken Goldman */
+/* IBM Thomas J. Watson Research Center */
+/* $Id: IoBuffers.c 1311 2018-08-23 21:39:29Z kgoldman $ */
+/* */
+/* Licenses and Notices */
+/* */
+/* 1. Copyright Licenses: */
+/* */
+/* - Trusted Computing Group (TCG) grants to the user of the source code in */
+/* this specification (the "Source Code") a worldwide, irrevocable, */
+/* nonexclusive, royalty free, copyright license to reproduce, create */
+/* derivative works, distribute, display and perform the Source Code and */
+/* derivative works thereof, and to grant others the rights granted herein. */
+/* */
+/* - The TCG grants to the user of the other parts of the specification */
+/* (other than the Source Code) the rights to reproduce, distribute, */
+/* display, and perform the specification solely for the purpose of */
+/* developing products based on such documents. */
+/* */
+/* 2. Source Code Distribution Conditions: */
+/* */
+/* - Redistributions of Source Code must retain the above copyright licenses, */
+/* this list of conditions and the following disclaimers. */
+/* */
+/* - Redistributions in binary form must reproduce the above copyright */
+/* licenses, this list of conditions and the following disclaimers in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* 3. Disclaimers: */
+/* */
+/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
+/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
+/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
+/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
+/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
+/* information on specification licensing rights available through TCG */
+/* membership agreements. */
+/* */
+/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
+/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
+/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
+/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
+/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
+/* */
+/* - Without limitation, TCG and its members and licensors disclaim all */
+/* liability, including liability for infringement of any proprietary */
+/* rights, relating to use of information in this specification and to the */
+/* implementation of this specification, and TCG disclaims all liability for */
+/* cost of procurement of substitute goods or services, lost profits, loss */
+/* of use, loss of data or any incidental, consequential, direct, indirect, */
+/* or special damages, whether under contract, tort, warranty or otherwise, */
+/* arising in any way out of use or reliance upon this specification or any */
+/* information herein. */
+/* */
+/* (c) Copyright IBM Corp. and others, 2016 - 2018 */
+/* */
+/********************************************************************************/
+
+/* 9.7 IoBuffers.c */
+/* 9.7.1 Includes and Data Definitions */
+/* This definition allows this module to see the values that are private to this module but kept in
+ Global.c for ease of state migration. */
+#define IO_BUFFER_C
+#include "Tpm.h"
+#include "IoBuffers_fp.h"
+/* 9.7.2 Buffers and Functions */
+/* These buffers are set aside to hold command and response values. In this implementation, it is
+ not guaranteed that the code will stop accessing the s_actionInputBuffer before starting to put
+ values in the s_actionOutputBuffer so different buffers are required. */
+/* 9.7.2.1 MemoryIoBufferAllocationReset() */
+/* This function is used to reset the allocation of buffers. */
+void
+MemoryIoBufferAllocationReset(
+ void
+ )
+{
+ s_actionIoAllocation = 0;
+}
+/* 9.7.2.2 MemoryIoBufferZero() */
+/* Function zeros the action I/O buffer at the end of a command. Calling this is not mandatory for
+ proper functionality. */
+void
+MemoryIoBufferZero(
+ void
+ )
+{
+ memset(s_actionIoBuffer, 0, s_actionIoAllocation);
+}
+/* 9.7.2.3 MemoryGetInBuffer() */
+/* This function returns the address of the buffer into which the command parameters will be
+ unmarshaled in preparation for calling the command actions. */
+BYTE *
+MemoryGetInBuffer(
+ UINT32 size // Size, in bytes, required for the input
+ // unmarshaling
+ )
+{
+ pAssert(size <= sizeof(s_actionIoBuffer));
+ // In this implementation, a static buffer is set aside for the command action
+ // buffers. The buffer is shared between input and output. This is because
+ // there is no need to allocate for the worst case input and worst case output
+ // at the same time.
+ // Round size up
+#define UoM (sizeof(s_actionIoBuffer[0]))
+ size = (size + (UoM - 1)) & (UINT32_MAX - (UoM - 1));
+ memset(s_actionIoBuffer, 0, size);
+ s_actionIoAllocation = size;
+ return (BYTE *)&s_actionIoBuffer[0];
+}
+/* 9.7.2.4 MemoryGetOutBuffer() */
+/* This function returns the address of the buffer into which the command action code places its
+ output values. */
+BYTE *
+MemoryGetOutBuffer(
+ UINT32 size // required size of the buffer
+ )
+{
+ BYTE *retVal = (BYTE *)(&s_actionIoBuffer[s_actionIoAllocation / UoM]);
+ pAssert((size + s_actionIoAllocation) < (sizeof(s_actionIoBuffer)));
+ // In this implementation, a static buffer is set aside for the command action
+ // output buffer.
+ memset(retVal, 0, size);
+ s_actionIoAllocation += size;
+ return retVal;
+}
+/* 9.7.2.5 IsLabelProperlyFormatted() */
+/* This function checks that a label is a null-terminated string. */
+/* NOTE: this function is here because there was no better place for it. */
+/* Return Value Meaning */
+/* FALSE string is not null terminated */
+/* TRUE string is null terminated */
+
+BOOL
+IsLabelProperlyFormatted(
+ TPM2B *x
+ )
+{
+ return (((x)->size == 0) || ((x)->buffer[(x)->size - 1] == 0));
+}
+
+
+
diff --git a/src/tpm2/IoBuffers_fp.h b/src/tpm2/IoBuffers_fp.h
new file mode 100644
index 0000000..91113e1
--- /dev/null
+++ b/src/tpm2/IoBuffers_fp.h
@@ -0,0 +1,87 @@
+/********************************************************************************/
+/* */
+/* I/O Buffers */
+/* Written by Ken Goldman */
+/* IBM Thomas J. Watson Research Center */
+/* $Id: IoBuffers_fp.h 1259 2018-07-10 19:11:09Z kgoldman $ */
+/* */
+/* Licenses and Notices */
+/* */
+/* 1. Copyright Licenses: */
+/* */
+/* - Trusted Computing Group (TCG) grants to the user of the source code in */
+/* this specification (the "Source Code") a worldwide, irrevocable, */
+/* nonexclusive, royalty free, copyright license to reproduce, create */
+/* derivative works, distribute, display and perform the Source Code and */
+/* derivative works thereof, and to grant others the rights granted herein. */
+/* */
+/* - The TCG grants to the user of the other parts of the specification */
+/* (other than the Source Code) the rights to reproduce, distribute, */
+/* display, and perform the specification solely for the purpose of */
+/* developing products based on such documents. */
+/* */
+/* 2. Source Code Distribution Conditions: */
+/* */
+/* - Redistributions of Source Code must retain the above copyright licenses, */
+/* this list of conditions and the following disclaimers. */
+/* */
+/* - Redistributions in binary form must reproduce the above copyright */
+/* licenses, this list of conditions and the following disclaimers in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* 3. Disclaimers: */
+/* */
+/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
+/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
+/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
+/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
+/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
+/* information on specification licensing rights available through TCG */
+/* membership agreements. */
+/* */
+/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
+/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
+/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
+/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
+/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
+/* */
+/* - Without limitation, TCG and its members and licensors disclaim all */
+/* liability, including liability for infringement of any proprietary */
+/* rights, relating to use of information in this specification and to the */
+/* implementation of this specification, and TCG disclaims all liability for */
+/* cost of procurement of substitute goods or services, lost profits, loss */
+/* of use, loss of data or any incidental, consequential, direct, indirect, */
+/* or special damages, whether under contract, tort, warranty or otherwise, */
+/* arising in any way out of use or reliance upon this specification or any */
+/* information herein. */
+/* */
+/* (c) Copyright IBM Corp. and others, 2016 - 2018 */
+/* */
+/********************************************************************************/
+
+#ifndef IOBUFFERS_FP_H
+#define IOBUFFERS_FP_H
+
+void
+MemoryIoBufferAllocationReset(
+ void
+ );
+void
+MemoryIoBufferZero(
+ void
+ );
+BYTE *
+MemoryGetInBuffer(
+ UINT32 size // Size, in bytes, required for the input
+ // unmarshaling
+ );
+BYTE *
+MemoryGetOutBuffer(
+ UINT32 size // required size of the buffer
+ );
+BOOL
+IsLabelProperlyFormatted(
+ TPM2B *x
+ );
+
+#endif
diff --git a/src/tpm2/KdfTestData.h b/src/tpm2/KdfTestData.h
new file mode 100644
index 0000000..aa6c9ce
--- /dev/null
+++ b/src/tpm2/KdfTestData.h
@@ -0,0 +1,100 @@
+/********************************************************************************/
+/* */
+/* Hash Test Vectors */
+/* Written by Ken Goldman */
+/* IBM Thomas J. Watson Research Center */
+/* $Id: KdfTestData.h 1311 2018-08-23 21:39:29Z kgoldman $ */
+/* */
+/* Licenses and Notices */
+/* */
+/* 1. Copyright Licenses: */
+/* */
+/* - Trusted Computing Group (TCG) grants to the user of the source code in */
+/* this specification (the "Source Code") a worldwide, irrevocable, */
+/* nonexclusive, royalty free, copyright license to reproduce, create */
+/* derivative works, distribute, display and perform the Source Code and */
+/* derivative works thereof, and to grant others the rights granted herein. */
+/* */
+/* - The TCG grants to the user of the other parts of the specification */
+/* (other than the Source Code) the rights to reproduce, distribute, */
+/* display, and perform the specification solely for the purpose of */
+/* developing products based on such documents. */
+/* */
+/* 2. Source Code Distribution Conditions: */
+/* */
+/* - Redistributions of Source Code must retain the above copyright licenses, */
+/* this list of conditions and the following disclaimers. */
+/* */
+/* - Redistributions in binary form must reproduce the above copyright */
+/* licenses, this list of conditions and the following disclaimers in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* 3. Disclaimers: */
+/* */
+/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
+/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
+/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
+/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
+/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
+/* information on specification licensing rights available through TCG */
+/* membership agreements. */
+/* */
+/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
+/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
+/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
+/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
+/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
+/* */
+/* - Without limitation, TCG and its members and licensors disclaim all */
+/* liability, including liability for infringement of any proprietary */
+/* rights, relating to use of information in this specification and to the */
+/* implementation of this specification, and TCG disclaims all liability for */
+/* cost of procurement of substitute goods or services, lost profits, loss */
+/* of use, loss of data or any incidental, consequential, direct, indirect, */
+/* or special damages, whether under contract, tort, warranty or otherwise, */
+/* arising in any way out of use or reliance upon this specification or any */
+/* information herein. */
+/* */
+/* (c) Copyright IBM Corp. and others, 2016 - 2018 */
+/* */
+/********************************************************************************/
+
+//
+// Hash Test Vectors
+//
+
+#define TEST_KDF_KEY_SIZE 20
+TPM2B_TYPE(KDF_TEST_KEY, TEST_KDF_KEY_SIZE);
+TPM2B_KDF_TEST_KEY c_kdfTestKeyIn = {{TEST_KDF_KEY_SIZE, {
+ 0x27, 0x1F, 0xA0, 0x8B, 0xBD, 0xC5, 0x06, 0x0E, 0xC3, 0xDF,
+ 0xA9, 0x28, 0xFF, 0x9B, 0x73, 0x12, 0x3A, 0x12, 0xDA, 0x0C }}};
+TPM2B_TYPE(KDF_TEST_LABEL, 17);
+TPM2B_KDF_TEST_LABEL c_kdfTestLabel = {{17, {
+ 0x4B, 0x44, 0x46, 0x53, 0x45, 0x4C, 0x46, 0x54,
+ 0x45, 0x53, 0x54, 0x4C, 0x41, 0x42, 0x45, 0x4C, 0x00 }}};
+TPM2B_TYPE(KDF_TEST_CONTEXT, 8);
+TPM2B_KDF_TEST_CONTEXT c_kdfTestContextU = {{8, {
+ 0xCE, 0x24, 0x4F, 0x39, 0x5D, 0xCA, 0x73, 0x91 }}};
+TPM2B_KDF_TEST_CONTEXT c_kdfTestContextV = {{8, {
+ 0xDA, 0x50, 0x40, 0x31, 0xDD, 0xF1, 0x2E, 0x83 }}};
+#if ALG_SHA512 == ALG_YES
+TPM2B_KDF_TEST_KEY c_kdfTestKeyOut = {{20, {
+ 0x8b, 0xe2, 0xc1, 0xb8, 0x5b, 0x78, 0x56, 0x9b, 0x9f, 0xa7,
+ 0x59, 0xf5, 0x85, 0x7c, 0x56, 0xd6, 0x84, 0x81, 0x0f, 0xd3 }}};
+#define KDF_TEST_ALG TPM_ALG_SHA512
+#elif ALG_SHA384 == ALG_YES
+TPM2B_KDF_TEST_KEY c_kdfTestKeyOut = {{20, {
+ 0x1d, 0xce, 0x70, 0xc9, 0x11, 0x3e, 0xb2, 0xdb, 0xa4, 0x7b,
+ 0xd9, 0xcf, 0xc7, 0x2b, 0xf4, 0x6f, 0x45, 0xb0, 0x93, 0x12 }}};
+#define KDF_TEST_ALG TPM_ALG_SHA384
+#elif ALG_SHA256 == ALG_YES
+TPM2B_KDF_TEST_KEY c_kdfTestKeyOut = {{20, {
+ 0xbb, 0x02, 0x59, 0xe1, 0xc8, 0xba, 0x60, 0x7e, 0x6a, 0x2c,
+ 0xd7, 0x04, 0xb6, 0x9a, 0x90, 0x2e, 0x9a, 0xde, 0x84, 0xc4 }}};
+#define KDF_TEST_ALG TPM_ALG_SHA256
+#elif ALG_SHA1 == ALG_YES
+TPM2B_KDF_TEST_KEY c_kdfTestKeyOut = {{20, {
+ 0x55, 0xb5, 0xa7, 0x18, 0x4a, 0xa0, 0x74, 0x23, 0xc4, 0x7d,
+ 0xae, 0x76, 0x6c, 0x26, 0xa2, 0x37, 0x7d, 0x7c, 0xf8, 0x51 }}};
+#define KDF_TEST_ALG TPM_ALG_SHA1
+#endif
diff --git a/src/tpm2/LibtpmsCallbacks.c b/src/tpm2/LibtpmsCallbacks.c
new file mode 100644
index 0000000..5d22147
--- /dev/null
+++ b/src/tpm2/LibtpmsCallbacks.c
@@ -0,0 +1,178 @@
+/********************************************************************************/
+/* */
+/* Libtpms Callbacks */
+/* Written by Stefan Berger */
+/* IBM Thomas J. Watson Research Center */
+/* */
+/* (c) Copyright IBM Corporation 2018. */
+/* */
+/* All rights reserved. */
+/* */
+/* Redistribution and use in source and binary forms, with or without */
+/* modification, are permitted provided that the following conditions are */
+/* met: */
+/* */
+/* Redistributions of source code must retain the above copyright notice, */
+/* this list of conditions and the following disclaimer. */
+/* */
+/* Redistributions in binary form must reproduce the above copyright */
+/* notice, this list of conditions and the following disclaimer in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* Neither the names of the IBM Corporation nor the names of its */
+/* contributors may be used to endorse or promote products derived from */
+/* this software without specific prior written permission. */
+/* */
+/* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS */
+/* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT */
+/* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR */
+/* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT */
+/* HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, */
+/* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT */
+/* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, */
+/* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY */
+/* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT */
+/* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE */
+/* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */
+/********************************************************************************/
+
+#include <stdint.h>
+#include <string.h>
+
+#include "Platform.h"
+#include "LibtpmsCallbacks.h"
+#include "NVMarshal.h"
+
+#define TPM_HAVE_TPM2_DECLARATIONS
+#include "tpm_library_intern.h"
+#include "tpm_error.h"
+#include "tpm_nvfilename.h"
+
+int
+libtpms_plat__NVEnable(void)
+{
+ unsigned char *data = NULL;
+ uint32_t length = 0;
+ struct libtpms_callbacks *cbs = TPMLIB_GetCallbacks();
+ TPM_RC rc;
+ bool is_empty_state;
+
+ /* try to get state blob set via TPMLIB_SetState() */
+ GetCachedState(TPMLIB_STATE_PERMANENT, &data, &length, &is_empty_state);
+ if (is_empty_state) {
+ memset(s_NV, 0, NV_MEMORY_SIZE);
+ return 0;
+ }
+
+ if (data == NULL && cbs->tpm_nvram_loaddata) {
+ uint32_t tpm_number = 0;
+ const char *name = TPM_PERMANENT_ALL_NAME;
+ TPM_RESULT ret;
+
+ ret = cbs->tpm_nvram_loaddata(&data, &length, tpm_number, name);
+ switch (ret) {
+ case TPM_RETRY:
+ if (!cbs->tpm_nvram_storedata) {
+ return -1;
+ }
+ memset(s_NV, 0, NV_MEMORY_SIZE);
+ return 0;
+
+ case TPM_SUCCESS:
+ /* got the data -- unmarshal them... */
+ break;
+
+ case TPM_FAIL:
+ default:
+ return -1;
+ }
+ }
+
+ if (data) {
+ unsigned char *buffer = data;
+ INT32 size = length;
+
+ rc = PERSISTENT_ALL_Unmarshal(&buffer, &size);
+ free(data);
+ if (rc != TPM_RC_SUCCESS)
+ return -1;
+ return 0;
+ }
+ return LIBTPMS_CALLBACK_FALLTHROUGH; /* -2 */
+}
+
+int
+libtpms_plat__NVDisable(
+ void
+ )
+{
+ struct libtpms_callbacks *cbs = TPMLIB_GetCallbacks();
+
+ if (cbs->tpm_nvram_loaddata)
+ return 0;
+ return LIBTPMS_CALLBACK_FALLTHROUGH; /* -2 */
+}
+
+int
+libtpms_plat__IsNvAvailable(
+ void
+ )
+{
+ struct libtpms_callbacks *cbs = TPMLIB_GetCallbacks();
+
+ if (cbs->tpm_nvram_loaddata &&
+ cbs->tpm_nvram_storedata) {
+ return 1;
+ }
+ return LIBTPMS_CALLBACK_FALLTHROUGH; /* -2 */
+}
+
+int
+libtpms_plat__NvCommit(
+ void
+ )
+{
+ struct libtpms_callbacks *cbs = TPMLIB_GetCallbacks();
+
+ if (cbs->tpm_nvram_storedata) {
+ uint32_t tpm_number = 0;
+ const char *name = TPM_PERMANENT_ALL_NAME;
+ TPM_RESULT ret;
+ BYTE *buf;
+ uint32_t buflen;
+
+ ret = TPM2_PersistentAllStore(&buf, &buflen);
+ if (ret != TPM_SUCCESS)
+ return ret;
+
+ ret = cbs->tpm_nvram_storedata(buf, buflen,
+ tpm_number, name);
+ free(buf);
+ if (ret == TPM_SUCCESS)
+ return 0;
+
+ return -1;
+ }
+ return LIBTPMS_CALLBACK_FALLTHROUGH; /* -2 */
+}
+
+int
+libtpms_plat__PhysicalPresenceAsserted(
+ BOOL *pp
+ )
+{
+ struct libtpms_callbacks *cbs = TPMLIB_GetCallbacks();
+
+ if (cbs->tpm_io_getphysicalpresence) {
+ uint32_t tpm_number = 0;
+ TPM_RESULT res;
+ unsigned char mypp;
+
+ res = cbs->tpm_io_getphysicalpresence(&mypp, tpm_number);
+ if (res == TPM_SUCCESS) {
+ *pp = mypp;
+ return 0;
+ }
+ }
+ return LIBTPMS_CALLBACK_FALLTHROUGH;
+}
diff --git a/src/tpm2/LibtpmsCallbacks.h b/src/tpm2/LibtpmsCallbacks.h
new file mode 100644
index 0000000..e262b9d
--- /dev/null
+++ b/src/tpm2/LibtpmsCallbacks.h
@@ -0,0 +1,50 @@
+/********************************************************************************/
+/* */
+/* Libtpms Callbacks */
+/* Written by Stefan Berger */
+/* IBM Thomas J. Watson Research Center */
+/* */
+/* (c) Copyright IBM Corporation 2018. */
+/* */
+/* All rights reserved. */
+/* */
+/* Redistribution and use in source and binary forms, with or without */
+/* modification, are permitted provided that the following conditions are */
+/* met: */
+/* */
+/* Redistributions of source code must retain the above copyright notice, */
+/* this list of conditions and the following disclaimer. */
+/* */
+/* Redistributions in binary form must reproduce the above copyright */
+/* notice, this list of conditions and the following disclaimer in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* Neither the names of the IBM Corporation nor the names of its */
+/* contributors may be used to endorse or promote products derived from */
+/* this software without specific prior written permission. */
+/* */
+/* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS */
+/* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT */
+/* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR */
+/* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT */
+/* HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, */
+/* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT */
+/* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, */
+/* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY */
+/* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT */
+/* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE */
+/* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */
+/********************************************************************************/
+
+#ifndef LIBTPMS_CALLBACKS_H
+#define LIBTPMS_CALLBACKS_H
+
+#define LIBTPMS_CALLBACK_FALLTHROUGH -2
+
+int libtpms_plat__NVEnable(void);
+int libtpms_plat__NVDisable(void);
+int libtpms_plat__IsNvAvailable(void);
+int libtpms_plat__NvCommit(void);
+int libtpms_plat__PhysicalPresenceAsserted(BOOL *pp);
+
+#endif /* LIBTPMS_CALLBACKS_H */
diff --git a/src/tpm2/LoadExternal_fp.h b/src/tpm2/LoadExternal_fp.h
new file mode 100644
index 0000000..f57f942
--- /dev/null
+++ b/src/tpm2/LoadExternal_fp.h
@@ -0,0 +1,87 @@
+/********************************************************************************/
+/* */
+/* */
+/* Written by Ken Goldman */
+/* IBM Thomas J. Watson Research Center */
+/* $Id: LoadExternal_fp.h 1521 2019-11-15 21:00:47Z kgoldman $ */
+/* */
+/* Licenses and Notices */
+/* */
+/* 1. Copyright Licenses: */
+/* */
+/* - Trusted Computing Group (TCG) grants to the user of the source code in */
+/* this specification (the "Source Code") a worldwide, irrevocable, */
+/* nonexclusive, royalty free, copyright license to reproduce, create */
+/* derivative works, distribute, display and perform the Source Code and */
+/* derivative works thereof, and to grant others the rights granted herein. */
+/* */
+/* - The TCG grants to the user of the other parts of the specification */
+/* (other than the Source Code) the rights to reproduce, distribute, */
+/* display, and perform the specification solely for the purpose of */
+/* developing products based on such documents. */
+/* */
+/* 2. Source Code Distribution Conditions: */
+/* */
+/* - Redistributions of Source Code must retain the above copyright licenses, */
+/* this list of conditions and the following disclaimers. */
+/* */
+/* - Redistributions in binary form must reproduce the above copyright */
+/* licenses, this list of conditions and the following disclaimers in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* 3. Disclaimers: */
+/* */
+/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
+/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
+/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
+/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
+/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
+/* information on specification licensing rights available through TCG */
+/* membership agreements. */
+/* */
+/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
+/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
+/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
+/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
+/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
+/* */
+/* - Without limitation, TCG and its members and licensors disclaim all */
+/* liability, including liability for infringement of any proprietary */
+/* rights, relating to use of information in this specification and to the */
+/* implementation of this specification, and TCG disclaims all liability for */
+/* cost of procurement of substitute goods or services, lost profits, loss */
+/* of use, loss of data or any incidental, consequential, direct, indirect, */
+/* or special damages, whether under contract, tort, warranty or otherwise, */
+/* arising in any way out of use or reliance upon this specification or any */
+/* information herein. */
+/* */
+/* (c) Copyright IBM Corp. and others, 2012-2015 */
+/* */
+/********************************************************************************/
+
+/* rev 119 */
+
+#ifndef LOADEXTERNAL_FP_H
+#define LOADEXTERNAL_FP_H
+
+typedef struct {
+ TPM2B_SENSITIVE inPrivate;
+ TPM2B_PUBLIC inPublic;
+ TPMI_RH_HIERARCHY hierarchy;
+} LoadExternal_In;
+
+#define RC_LoadExternal_inPrivate (TPM_RC_P + TPM_RC_1)
+#define RC_LoadExternal_inPublic (TPM_RC_P + TPM_RC_2)
+#define RC_LoadExternal_hierarchy (TPM_RC_P + TPM_RC_3)
+
+typedef struct {
+ TPM_HANDLE objectHandle;
+ TPM2B_NAME name;
+} LoadExternal_Out;
+
+TPM_RC
+TPM2_LoadExternal(
+ LoadExternal_In *in, // IN: input parameter list
+ LoadExternal_Out *out // OUT: output parameter list
+ );
+#endif
diff --git a/src/tpm2/Load_fp.h b/src/tpm2/Load_fp.h
new file mode 100644
index 0000000..7d5c2a5
--- /dev/null
+++ b/src/tpm2/Load_fp.h
@@ -0,0 +1,88 @@
+/********************************************************************************/
+/* */
+/* */
+/* Written by Ken Goldman */
+/* IBM Thomas J. Watson Research Center */
+/* $Id: Load_fp.h 1521 2019-11-15 21:00:47Z kgoldman $ */
+/* */
+/* Licenses and Notices */
+/* */
+/* 1. Copyright Licenses: */
+/* */
+/* - Trusted Computing Group (TCG) grants to the user of the source code in */
+/* this specification (the "Source Code") a worldwide, irrevocable, */
+/* nonexclusive, royalty free, copyright license to reproduce, create */
+/* derivative works, distribute, display and perform the Source Code and */
+/* derivative works thereof, and to grant others the rights granted herein. */
+/* */
+/* - The TCG grants to the user of the other parts of the specification */
+/* (other than the Source Code) the rights to reproduce, distribute, */
+/* display, and perform the specification solely for the purpose of */
+/* developing products based on such documents. */
+/* */
+/* 2. Source Code Distribution Conditions: */
+/* */
+/* - Redistributions of Source Code must retain the above copyright licenses, */
+/* this list of conditions and the following disclaimers. */
+/* */
+/* - Redistributions in binary form must reproduce the above copyright */
+/* licenses, this list of conditions and the following disclaimers in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* 3. Disclaimers: */
+/* */
+/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
+/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
+/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
+/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
+/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
+/* information on specification licensing rights available through TCG */
+/* membership agreements. */
+/* */
+/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
+/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
+/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
+/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
+/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
+/* */
+/* - Without limitation, TCG and its members and licensors disclaim all */
+/* liability, including liability for infringement of any proprietary */
+/* rights, relating to use of information in this specification and to the */
+/* implementation of this specification, and TCG disclaims all liability for */
+/* cost of procurement of substitute goods or services, lost profits, loss */
+/* of use, loss of data or any incidental, consequential, direct, indirect, */
+/* or special damages, whether under contract, tort, warranty or otherwise, */
+/* arising in any way out of use or reliance upon this specification or any */
+/* information herein. */
+/* */
+/* (c) Copyright IBM Corp. and others, 2012-2015 */
+/* */
+/********************************************************************************/
+
+/* rev 119 */
+
+#ifndef LOAD_FP_H
+#define LOAD_FP_H
+
+typedef struct {
+ TPMI_DH_OBJECT parentHandle;
+ TPM2B_PRIVATE inPrivate;
+ TPM2B_PUBLIC inPublic;
+} Load_In;
+
+#define RC_Load_parentHandle (TPM_RC_H + TPM_RC_1)
+#define RC_Load_inPrivate (TPM_RC_P + TPM_RC_1)
+#define RC_Load_inPublic (TPM_RC_P + TPM_RC_2)
+
+typedef struct {
+ TPM_HANDLE objectHandle;
+ TPM2B_NAME name;
+} Load_Out;
+
+TPM_RC
+TPM2_Load(
+ Load_In *in, // IN: input parameter list
+ Load_Out *out // OUT: output parameter list
+ );
+
+#endif
diff --git a/src/tpm2/Locality.c b/src/tpm2/Locality.c
new file mode 100644
index 0000000..d3f08c9
--- /dev/null
+++ b/src/tpm2/Locality.c
@@ -0,0 +1,99 @@
+/********************************************************************************/
+/* */
+/* */
+/* Written by Ken Goldman */
+/* IBM Thomas J. Watson Research Center */
+/* $Id: Locality.c 1490 2019-07-26 21:13:22Z kgoldman $ */
+/* */
+/* Licenses and Notices */
+/* */
+/* 1. Copyright Licenses: */
+/* */
+/* - Trusted Computing Group (TCG) grants to the user of the source code in */
+/* this specification (the "Source Code") a worldwide, irrevocable, */
+/* nonexclusive, royalty free, copyright license to reproduce, create */
+/* derivative works, distribute, display and perform the Source Code and */
+/* derivative works thereof, and to grant others the rights granted herein. */
+/* */
+/* - The TCG grants to the user of the other parts of the specification */
+/* (other than the Source Code) the rights to reproduce, distribute, */
+/* display, and perform the specification solely for the purpose of */
+/* developing products based on such documents. */
+/* */
+/* 2. Source Code Distribution Conditions: */
+/* */
+/* - Redistributions of Source Code must retain the above copyright licenses, */
+/* this list of conditions and the following disclaimers. */
+/* */
+/* - Redistributions in binary form must reproduce the above copyright */
+/* licenses, this list of conditions and the following disclaimers in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* 3. Disclaimers: */
+/* */
+/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
+/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
+/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
+/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
+/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
+/* information on specification licensing rights available through TCG */
+/* membership agreements. */
+/* */
+/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
+/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
+/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
+/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
+/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
+/* */
+/* - Without limitation, TCG and its members and licensors disclaim all */
+/* liability, including liability for infringement of any proprietary */
+/* rights, relating to use of information in this specification and to the */
+/* implementation of this specification, and TCG disclaims all liability for */
+/* cost of procurement of substitute goods or services, lost profits, loss */
+/* of use, loss of data or any incidental, consequential, direct, indirect, */
+/* or special damages, whether under contract, tort, warranty or otherwise, */
+/* arising in any way out of use or reliance upon this specification or any */
+/* information herein. */
+/* */
+/* (c) Copyright IBM Corp. and others, 2016, 2017 */
+/* */
+/********************************************************************************/
+
+/* 9.8 Locality.c */
+/* 9.8.1 Includes */
+#include "Tpm.h"
+/* 9.8.2 LocalityGetAttributes() */
+/* This function will convert a locality expressed as an integer into TPMA_LOCALITY form. */
+/* The function returns the locality attribute. */
+TPMA_LOCALITY
+LocalityGetAttributes(
+ UINT8 locality // IN: locality value
+ )
+{
+ TPMA_LOCALITY locality_attributes;
+ BYTE *localityAsByte = (BYTE *)&locality_attributes;
+ MemorySet(&locality_attributes, 0, sizeof(TPMA_LOCALITY));
+ switch(locality)
+ {
+ case 0:
+ SET_ATTRIBUTE(locality_attributes, TPMA_LOCALITY, TPM_LOC_ZERO);
+ break;
+ case 1:
+ SET_ATTRIBUTE(locality_attributes, TPMA_LOCALITY, TPM_LOC_ONE);
+ break;
+ case 2:
+ SET_ATTRIBUTE(locality_attributes, TPMA_LOCALITY, TPM_LOC_TWO);
+ break;
+ case 3:
+ SET_ATTRIBUTE(locality_attributes, TPMA_LOCALITY, TPM_LOC_THREE);
+ break;
+ case 4:
+ SET_ATTRIBUTE(locality_attributes, TPMA_LOCALITY, TPM_LOC_FOUR);
+ break;
+ default:
+ pAssert(locality > 31);
+ *localityAsByte = locality;
+ break;
+ }
+ return locality_attributes;
+}
diff --git a/src/tpm2/LocalityPlat.c b/src/tpm2/LocalityPlat.c
new file mode 100644
index 0000000..c3dc7de
--- /dev/null
+++ b/src/tpm2/LocalityPlat.c
@@ -0,0 +1,87 @@
+/********************************************************************************/
+/* */
+/* Platform Locality Support */
+/* Written by Ken Goldman */
+/* IBM Thomas J. Watson Research Center */
+/* $Id: LocalityPlat.c 1490 2019-07-26 21:13:22Z kgoldman $ */
+/* */
+/* Licenses and Notices */
+/* */
+/* 1. Copyright Licenses: */
+/* */
+/* - Trusted Computing Group (TCG) grants to the user of the source code in */
+/* this specification (the "Source Code") a worldwide, irrevocable, */
+/* nonexclusive, royalty free, copyright license to reproduce, create */
+/* derivative works, distribute, display and perform the Source Code and */
+/* derivative works thereof, and to grant others the rights granted herein. */
+/* */
+/* - The TCG grants to the user of the other parts of the specification */
+/* (other than the Source Code) the rights to reproduce, distribute, */
+/* display, and perform the specification solely for the purpose of */
+/* developing products based on such documents. */
+/* */
+/* 2. Source Code Distribution Conditions: */
+/* */
+/* - Redistributions of Source Code must retain the above copyright licenses, */
+/* this list of conditions and the following disclaimers. */
+/* */
+/* - Redistributions in binary form must reproduce the above copyright */
+/* licenses, this list of conditions and the following disclaimers in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* 3. Disclaimers: */
+/* */
+/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
+/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
+/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
+/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
+/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
+/* information on specification licensing rights available through TCG */
+/* membership agreements. */
+/* */
+/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
+/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
+/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
+/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
+/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
+/* */
+/* - Without limitation, TCG and its members and licensors disclaim all */
+/* liability, including liability for infringement of any proprietary */
+/* rights, relating to use of information in this specification and to the */
+/* implementation of this specification, and TCG disclaims all liability for */
+/* cost of procurement of substitute goods or services, lost profits, loss */
+/* of use, loss of data or any incidental, consequential, direct, indirect, */
+/* or special damages, whether under contract, tort, warranty or otherwise, */
+/* arising in any way out of use or reliance upon this specification or any */
+/* information herein. */
+/* */
+/* (c) Copyright IBM Corp. and others, 2016 - 2019 */
+/* */
+/********************************************************************************/
+
+/* C.5 LocalityPlat.c */
+/* C.5.1. Includes */
+#include "Platform.h"
+/* C.5.2. Functions */
+/* C.5.2.1. _plat__LocalityGet() */
+/* Get the most recent command locality in locality value form. This is an integer value for
+ locality and not a locality structure The locality can be 0-4 or 32-255. 5-31 is not allowed. */
+LIB_EXPORT unsigned char
+_plat__LocalityGet(
+ void
+ )
+{
+ return s_locality;
+}
+/* C.5.2.2. _plat__LocalitySet() */
+/* Set the most recent command locality in locality value form */
+LIB_EXPORT void
+_plat__LocalitySet(
+ unsigned char locality
+ )
+{
+ if(locality > 4 && locality < 32)
+ locality = 0;
+ s_locality = locality;
+ return;
+}
diff --git a/src/tpm2/Locality_fp.h b/src/tpm2/Locality_fp.h
new file mode 100644
index 0000000..3592126
--- /dev/null
+++ b/src/tpm2/Locality_fp.h
@@ -0,0 +1,71 @@
+/********************************************************************************/
+/* */
+/* */
+/* Written by Ken Goldman */
+/* IBM Thomas J. Watson Research Center */
+/* $Id: Locality_fp.h 1490 2019-07-26 21:13:22Z kgoldman $ */
+/* */
+/* Licenses and Notices */
+/* */
+/* 1. Copyright Licenses: */
+/* */
+/* - Trusted Computing Group (TCG) grants to the user of the source code in */
+/* this specification (the "Source Code") a worldwide, irrevocable, */
+/* nonexclusive, royalty free, copyright license to reproduce, create */
+/* derivative works, distribute, display and perform the Source Code and */
+/* derivative works thereof, and to grant others the rights granted herein. */
+/* */
+/* - The TCG grants to the user of the other parts of the specification */
+/* (other than the Source Code) the rights to reproduce, distribute, */
+/* display, and perform the specification solely for the purpose of */
+/* developing products based on such documents. */
+/* */
+/* 2. Source Code Distribution Conditions: */
+/* */
+/* - Redistributions of Source Code must retain the above copyright licenses, */
+/* this list of conditions and the following disclaimers. */
+/* */
+/* - Redistributions in binary form must reproduce the above copyright */
+/* licenses, this list of conditions and the following disclaimers in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* 3. Disclaimers: */
+/* */
+/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
+/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
+/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
+/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
+/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
+/* information on specification licensing rights available through TCG */
+/* membership agreements. */
+/* */
+/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
+/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
+/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
+/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
+/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
+/* */
+/* - Without limitation, TCG and its members and licensors disclaim all */
+/* liability, including liability for infringement of any proprietary */
+/* rights, relating to use of information in this specification and to the */
+/* implementation of this specification, and TCG disclaims all liability for */
+/* cost of procurement of substitute goods or services, lost profits, loss */
+/* of use, loss of data or any incidental, consequential, direct, indirect, */
+/* or special damages, whether under contract, tort, warranty or otherwise, */
+/* arising in any way out of use or reliance upon this specification or any */
+/* information herein. */
+/* */
+/* (c) Copyright IBM Corp. and others, 2016 */
+/* */
+/********************************************************************************/
+
+#ifndef LOCALITY_FP_H
+#define LOCALITY_FP_H
+
+TPMA_LOCALITY
+LocalityGetAttributes(
+ UINT8 locality // IN: locality value
+ );
+
+
+#endif
diff --git a/src/tpm2/MAC_Start_fp.h b/src/tpm2/MAC_Start_fp.h
new file mode 100644
index 0000000..6d73ad1
--- /dev/null
+++ b/src/tpm2/MAC_Start_fp.h
@@ -0,0 +1,88 @@
+/********************************************************************************/
+/* */
+/* */
+/* Written by Ken Goldman */
+/* IBM Thomas J. Watson Research Center */
+/* $Id: MAC_Start_fp.h 1047 2017-07-20 18:27:34Z kgoldman $ */
+/* */
+/* Licenses and Notices */
+/* */
+/* 1. Copyright Licenses: */
+/* */
+/* - Trusted Computing Group (TCG) grants to the user of the source code in */
+/* this specification (the "Source Code") a worldwide, irrevocable, */
+/* nonexclusive, royalty free, copyright license to reproduce, create */
+/* derivative works, distribute, display and perform the Source Code and */
+/* derivative works thereof, and to grant others the rights granted herein. */
+/* */
+/* - The TCG grants to the user of the other parts of the specification */
+/* (other than the Source Code) the rights to reproduce, distribute, */
+/* display, and perform the specification solely for the purpose of */
+/* developing products based on such documents. */
+/* */
+/* 2. Source Code Distribution Conditions: */
+/* */
+/* - Redistributions of Source Code must retain the above copyright licenses, */
+/* this list of conditions and the following disclaimers. */
+/* */
+/* - Redistributions in binary form must reproduce the above copyright */
+/* licenses, this list of conditions and the following disclaimers in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* 3. Disclaimers: */
+/* */
+/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
+/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
+/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
+/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
+/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
+/* information on specification licensing rights available through TCG */
+/* membership agreements. */
+/* */
+/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
+/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
+/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
+/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
+/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
+/* */
+/* - Without limitation, TCG and its members and licensors disclaim all */
+/* liability, including liability for infringement of any proprietary */
+/* rights, relating to use of information in this specification and to the */
+/* implementation of this specification, and TCG disclaims all liability for */
+/* cost of procurement of substitute goods or services, lost profits, loss */
+/* of use, loss of data or any incidental, consequential, direct, indirect, */
+/* or special damages, whether under contract, tort, warranty or otherwise, */
+/* arising in any way out of use or reliance upon this specification or any */
+/* information herein. */
+/* */
+/* (c) Copyright IBM Corp. and others, 2017 */
+/* */
+/********************************************************************************/
+
+/* rev 146 */
+
+#ifndef MAC_START_FP_H
+#define MAC_START_FP_H
+
+typedef struct {
+ TPMI_DH_OBJECT handle;
+ TPM2B_AUTH auth;
+ TPMI_ALG_MAC_SCHEME inScheme;
+} MAC_Start_In;
+
+typedef struct {
+ TPMI_DH_OBJECT sequenceHandle;
+} MAC_Start_Out;
+
+#define RC_MAC_Start_handle (TPM_RC_H + TPM_RC_1)
+#define RC_MAC_Start_auth (TPM_RC_P + TPM_RC_1)
+#define RC_MAC_Start_inScheme (TPM_RC_P + TPM_RC_2)
+
+TPM_RC
+TPM2_MAC_Start(
+ MAC_Start_In *in, // IN: input parameter list
+ MAC_Start_Out *out // OUT: output parameter list
+ );
+
+
+#endif
diff --git a/src/tpm2/MAC_fp.h b/src/tpm2/MAC_fp.h
new file mode 100644
index 0000000..0dc9679
--- /dev/null
+++ b/src/tpm2/MAC_fp.h
@@ -0,0 +1,88 @@
+/********************************************************************************/
+/* */
+/* */
+/* Written by Ken Goldman */
+/* IBM Thomas J. Watson Research Center */
+/* $Id: MAC_fp.h 1259 2018-07-10 19:11:09Z kgoldman $ */
+/* */
+/* Licenses and Notices */
+/* */
+/* 1. Copyright Licenses: */
+/* */
+/* - Trusted Computing Group (TCG) grants to the user of the source code in */
+/* this specification (the "Source Code") a worldwide, irrevocable, */
+/* nonexclusive, royalty free, copyright license to reproduce, create */
+/* derivative works, distribute, display and perform the Source Code and */
+/* derivative works thereof, and to grant others the rights granted herein. */
+/* */
+/* - The TCG grants to the user of the other parts of the specification */
+/* (other than the Source Code) the rights to reproduce, distribute, */
+/* display, and perform the specification solely for the purpose of */
+/* developing products based on such documents. */
+/* */
+/* 2. Source Code Distribution Conditions: */
+/* */
+/* - Redistributions of Source Code must retain the above copyright licenses, */
+/* this list of conditions and the following disclaimers. */
+/* */
+/* - Redistributions in binary form must reproduce the above copyright */
+/* licenses, this list of conditions and the following disclaimers in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* 3. Disclaimers: */
+/* */
+/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
+/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
+/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
+/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
+/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
+/* information on specification licensing rights available through TCG */
+/* membership agreements. */
+/* */
+/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
+/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
+/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
+/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
+/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
+/* */
+/* - Without limitation, TCG and its members and licensors disclaim all */
+/* liability, including liability for infringement of any proprietary */
+/* rights, relating to use of information in this specification and to the */
+/* implementation of this specification, and TCG disclaims all liability for */
+/* cost of procurement of substitute goods or services, lost profits, loss */
+/* of use, loss of data or any incidental, consequential, direct, indirect, */
+/* or special damages, whether under contract, tort, warranty or otherwise, */
+/* arising in any way out of use or reliance upon this specification or any */
+/* information herein. */
+/* */
+/* (c) Copyright IBM Corp. and others, 2012-2018 */
+/* */
+/********************************************************************************/
+
+/* rev 119 */
+
+#ifndef MAC_FP_H
+#define MAC_FP_H
+
+typedef struct {
+ TPMI_DH_OBJECT handle;
+ TPM2B_MAX_BUFFER buffer;
+ TPMI_ALG_MAC_SCHEME inScheme;
+} MAC_In;
+
+#define RC_MAC_handle (TPM_RC_H + TPM_RC_1)
+#define RC_MAC_buffer (TPM_RC_P + TPM_RC_1)
+#define RC_MAC_inScheme (TPM_RC_P + TPM_RC_2)
+
+typedef struct {
+ TPM2B_MAX_BUFFER outMAC;
+} MAC_Out;
+
+TPM_RC
+TPM2_MAC(
+ MAC_In *in, // IN: input parameter list
+ MAC_Out *out // OUT: output parameter list
+ );
+
+
+#endif
diff --git a/src/tpm2/MakeCredential_fp.h b/src/tpm2/MakeCredential_fp.h
new file mode 100644
index 0000000..e824a51
--- /dev/null
+++ b/src/tpm2/MakeCredential_fp.h
@@ -0,0 +1,89 @@
+/********************************************************************************/
+/* */
+/* */
+/* Written by Ken Goldman */
+/* IBM Thomas J. Watson Research Center */
+/* $Id: MakeCredential_fp.h 809 2016-11-16 18:31:54Z kgoldman $ */
+/* */
+/* Licenses and Notices */
+/* */
+/* 1. Copyright Licenses: */
+/* */
+/* - Trusted Computing Group (TCG) grants to the user of the source code in */
+/* this specification (the "Source Code") a worldwide, irrevocable, */
+/* nonexclusive, royalty free, copyright license to reproduce, create */
+/* derivative works, distribute, display and perform the Source Code and */
+/* derivative works thereof, and to grant others the rights granted herein. */
+/* */
+/* - The TCG grants to the user of the other parts of the specification */
+/* (other than the Source Code) the rights to reproduce, distribute, */
+/* display, and perform the specification solely for the purpose of */
+/* developing products based on such documents. */
+/* */
+/* 2. Source Code Distribution Conditions: */
+/* */
+/* - Redistributions of Source Code must retain the above copyright licenses, */
+/* this list of conditions and the following disclaimers. */
+/* */
+/* - Redistributions in binary form must reproduce the above copyright */
+/* licenses, this list of conditions and the following disclaimers in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* 3. Disclaimers: */
+/* */
+/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
+/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
+/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
+/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
+/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
+/* information on specification licensing rights available through TCG */
+/* membership agreements. */
+/* */
+/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
+/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
+/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
+/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
+/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
+/* */
+/* - Without limitation, TCG and its members and licensors disclaim all */
+/* liability, including liability for infringement of any proprietary */
+/* rights, relating to use of information in this specification and to the */
+/* implementation of this specification, and TCG disclaims all liability for */
+/* cost of procurement of substitute goods or services, lost profits, loss */
+/* of use, loss of data or any incidental, consequential, direct, indirect, */
+/* or special damages, whether under contract, tort, warranty or otherwise, */
+/* arising in any way out of use or reliance upon this specification or any */
+/* information herein. */
+/* */
+/* (c) Copyright IBM Corp. and others, 2012-2015 */
+/* */
+/********************************************************************************/
+
+/* rev 119 */
+
+#ifndef MAKECREDENTIAL_FP_H
+#define MAKECREDENTIAL_FP_H
+
+typedef struct {
+ TPMI_DH_OBJECT handle;
+ TPM2B_DIGEST credential;
+ TPM2B_NAME objectName;
+} MakeCredential_In;
+
+#define RC_MakeCredential_handle (TPM_RC_H + TPM_RC_1)
+#define RC_MakeCredential_credential (TPM_RC_P + TPM_RC_1)
+#define RC_MakeCredential_objectName (TPM_RC_P + TPM_RC_2)
+
+
+typedef struct {
+ TPM2B_ID_OBJECT credentialBlob;
+ TPM2B_ENCRYPTED_SECRET secret;
+} MakeCredential_Out;
+
+TPM_RC
+TPM2_MakeCredential(
+ MakeCredential_In *in, // IN: input parameter list
+ MakeCredential_Out *out // OUT: output parameter list
+ );
+
+#endif
diff --git a/src/tpm2/ManagementCommands.c b/src/tpm2/ManagementCommands.c
new file mode 100644
index 0000000..4ba70df
--- /dev/null
+++ b/src/tpm2/ManagementCommands.c
@@ -0,0 +1,113 @@
+/********************************************************************************/
+/* */
+/* Miscellaneous Management Functions */
+/* Written by Ken Goldman */
+/* IBM Thomas J. Watson Research Center */
+/* $Id: ManagementCommands.c 1490 2019-07-26 21:13:22Z kgoldman $ */
+/* */
+/* Licenses and Notices */
+/* */
+/* 1. Copyright Licenses: */
+/* */
+/* - Trusted Computing Group (TCG) grants to the user of the source code in */
+/* this specification (the "Source Code") a worldwide, irrevocable, */
+/* nonexclusive, royalty free, copyright license to reproduce, create */
+/* derivative works, distribute, display and perform the Source Code and */
+/* derivative works thereof, and to grant others the rights granted herein. */
+/* */
+/* - The TCG grants to the user of the other parts of the specification */
+/* (other than the Source Code) the rights to reproduce, distribute, */
+/* display, and perform the specification solely for the purpose of */
+/* developing products based on such documents. */
+/* */
+/* 2. Source Code Distribution Conditions: */
+/* */
+/* - Redistributions of Source Code must retain the above copyright licenses, */
+/* this list of conditions and the following disclaimers. */
+/* */
+/* - Redistributions in binary form must reproduce the above copyright */
+/* licenses, this list of conditions and the following disclaimers in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* 3. Disclaimers: */
+/* */
+/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
+/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
+/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
+/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
+/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
+/* information on specification licensing rights available through TCG */
+/* membership agreements. */
+/* */
+/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
+/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
+/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
+/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
+/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
+/* */
+/* - Without limitation, TCG and its members and licensors disclaim all */
+/* liability, including liability for infringement of any proprietary */
+/* rights, relating to use of information in this specification and to the */
+/* implementation of this specification, and TCG disclaims all liability for */
+/* cost of procurement of substitute goods or services, lost profits, loss */
+/* of use, loss of data or any incidental, consequential, direct, indirect, */
+/* or special damages, whether under contract, tort, warranty or otherwise, */
+/* arising in any way out of use or reliance upon this specification or any */
+/* information herein. */
+/* */
+/* (c) Copyright IBM Corp. and others, 2016 - 2018 */
+/* */
+/********************************************************************************/
+
+#include "Tpm.h"
+#include "PP_Commands_fp.h"
+#if CC_PP_Commands // Conditional expansion of this file
+TPM_RC
+TPM2_PP_Commands(
+ PP_Commands_In *in // IN: input parameter list
+ )
+{
+ UINT32 i;
+ // The command needs NV update. Check if NV is available.
+ // A TPM_RC_NV_UNAVAILABLE or TPM_RC_NV_RATE error may be returned at
+ // this point
+ RETURN_IF_NV_IS_NOT_AVAILABLE;
+ // Internal Data Update
+ // Process set list
+ for(i = 0; i < in->setList.count; i++)
+ // If command is implemented, set it as PP required. If the input
+ // command is not a PP command, it will be ignored at
+ // PhysicalPresenceCommandSet().
+ // Note: PhysicalPresenceCommandSet() checks if the command is implemented.
+ PhysicalPresenceCommandSet(in->setList.commandCodes[i]);
+ // Process clear list
+ for(i = 0; i < in->clearList.count; i++)
+ // If command is implemented, clear it as PP required. If the input
+ // command is not a PP command, it will be ignored at
+ // PhysicalPresenceCommandClear(). If the input command is
+ // TPM2_PP_Commands, it will be ignored as well
+ PhysicalPresenceCommandClear(in->clearList.commandCodes[i]);
+ // Save the change of PP list
+ NV_SYNC_PERSISTENT(ppList);
+ return TPM_RC_SUCCESS;
+}
+#endif // CC_PP_Commands
+#include "Tpm.h"
+#include "SetAlgorithmSet_fp.h"
+#if CC_SetAlgorithmSet // Conditional expansion of this file
+TPM_RC
+TPM2_SetAlgorithmSet(
+ SetAlgorithmSet_In *in // IN: input parameter list
+ )
+{
+ // The command needs NV update. Check if NV is available.
+ // A TPM_RC_NV_UNAVAILABLE or TPM_RC_NV_RATE error may be returned at
+ // this point
+ RETURN_IF_NV_IS_NOT_AVAILABLE;
+ // Internal Data Update
+ gp.algorithmSet = in->algorithmSet;
+ // Write the algorithm set changes to NV
+ NV_SYNC_PERSISTENT(algorithmSet);
+ return TPM_RC_SUCCESS;
+}
+#endif // CC_SetAlgorithmSet
diff --git a/src/tpm2/Manufacture.c b/src/tpm2/Manufacture.c
new file mode 100644
index 0000000..032bc76
--- /dev/null
+++ b/src/tpm2/Manufacture.c
@@ -0,0 +1,206 @@
+/********************************************************************************/
+/* */
+/* Performs the manufacturing of the TPM */
+/* Written by Ken Goldman */
+/* IBM Thomas J. Watson Research Center */
+/* $Id: Manufacture.c 1519 2019-11-15 20:43:51Z kgoldman $ */
+/* */
+/* Licenses and Notices */
+/* */
+/* 1. Copyright Licenses: */
+/* */
+/* - Trusted Computing Group (TCG) grants to the user of the source code in */
+/* this specification (the "Source Code") a worldwide, irrevocable, */
+/* nonexclusive, royalty free, copyright license to reproduce, create */
+/* derivative works, distribute, display and perform the Source Code and */
+/* derivative works thereof, and to grant others the rights granted herein. */
+/* */
+/* - The TCG grants to the user of the other parts of the specification */
+/* (other than the Source Code) the rights to reproduce, distribute, */
+/* display, and perform the specification solely for the purpose of */
+/* developing products based on such documents. */
+/* */
+/* 2. Source Code Distribution Conditions: */
+/* */
+/* - Redistributions of Source Code must retain the above copyright licenses, */
+/* this list of conditions and the following disclaimers. */
+/* */
+/* - Redistributions in binary form must reproduce the above copyright */
+/* licenses, this list of conditions and the following disclaimers in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* 3. Disclaimers: */
+/* */
+/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
+/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
+/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
+/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
+/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
+/* information on specification licensing rights available through TCG */
+/* membership agreements. */
+/* */
+/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
+/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
+/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
+/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
+/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
+/* */
+/* - Without limitation, TCG and its members and licensors disclaim all */
+/* liability, including liability for infringement of any proprietary */
+/* rights, relating to use of information in this specification and to the */
+/* implementation of this specification, and TCG disclaims all liability for */
+/* cost of procurement of substitute goods or services, lost profits, loss */
+/* of use, loss of data or any incidental, consequential, direct, indirect, */
+/* or special damages, whether under contract, tort, warranty or otherwise, */
+/* arising in any way out of use or reliance upon this specification or any */
+/* information herein. */
+/* */
+/* (c) Copyright IBM Corp. and others, 2016 - 2019 */
+/* */
+/********************************************************************************/
+
+/* 9.9 Manufacture.c */
+/* 9.9.1 Description */
+/* This file contains the function that performs the manufacturing of the TPM in a simulated
+ environment. These functions should not be used outside of a manufacturing or simulation
+ environment. */
+/* 9.9.2 Includes and Data Definitions */
+#define MANUFACTURE_C
+#include "Tpm.h"
+#include "TpmSizeChecks_fp.h"
+#define TPM_HAVE_TPM2_DECLARATIONS
+#include "tpm_library_intern.h" // libtpms added
+/* 9.9.3 Functions */
+/* 9.9.3.1 TPM_Manufacture() */
+/* This function initializes the TPM values in preparation for the TPMs first use. This function
+ will fail if previously called. The TPM can be re-manufactured by calling TPM_Teardown() first
+ and then calling this function again. */
+/* Return Values Meaning */
+/* -1 failure */
+/* 0 success */
+/* 1 manufacturing process previously performed */
+LIB_EXPORT int
+TPM_Manufacture(
+ int firstTime // IN: indicates if this is the first call from
+ // main()
+ )
+{
+ TPM_SU orderlyShutdown;
+
+ // Initialize the context slot mask for UINT16
+ s_ContextSlotMask = 0xffff; // libtpms added
+#if RUNTIME_SIZE_CHECKS
+ // Call the function to verify the sizes of values that result from different
+ // compile options.
+ if(!TpmSizeChecks())
+ return -1;
+#endif
+#if LIBRARY_COMPATIBILITY_CHECK
+ // Make sure that the attached library performs as expected.
+ if(!MathLibraryCompatibilityCheck())
+ return -1;
+#endif
+ // If TPM has been manufactured, return indication.
+ if(!firstTime && g_manufactured)
+ return 1;
+ // Do power on initializations of the cryptographic libraries.
+ CryptInit();
+ s_DAPendingOnNV = FALSE;
+ // initialize NV
+ NvManufacture();
+ // Clear the magic value in the DRBG state
+ go.drbgState.magic = 0;
+ if (CryptStartup(SU_RESET) == FALSE) { // libtpms added begin
+ TPMLIB_LogTPM2Error(
+ "CryptStartup failed:\n"
+ "IsEntropyBad : %d\n"
+ "IsTestStateSet(TESTING) : %d\n"
+ "IsTestStateSet(TESTED) : %d\n"
+ "IsTestStateSet(ENTROPY) : %d\n"
+ "IsDrbgTested : %d\n",
+ IsEntropyBad(),
+ IsTestStateSet(TESTING),
+ IsTestStateSet(TESTED),
+ IsTestStateSet(ENTROPY),
+ IsDrbgTested());
+ return -1;
+ } // libtpms added end
+ // default configuration for PCR
+ PCRSimStart();
+ // initialize pre-installed hierarchy data
+ // This should happen after NV is initialized because hierarchy data is
+ // stored in NV.
+ HierarchyPreInstall_Init();
+ // initialize dictionary attack parameters
+ DAPreInstall_Init();
+ // initialize PP list
+ PhysicalPresencePreInstall_Init();
+ // initialize command audit list
+ CommandAuditPreInstall_Init();
+ // first start up is required to be Startup(CLEAR)
+ orderlyShutdown = TPM_SU_CLEAR;
+ NV_WRITE_PERSISTENT(orderlyState, orderlyShutdown);
+ // initialize the firmware version
+ gp.firmwareV1 = FIRMWARE_V1;
+#ifdef FIRMWARE_V2
+ gp.firmwareV2 = FIRMWARE_V2;
+#else
+ gp.firmwareV2 = 0;
+#endif
+ NV_SYNC_PERSISTENT(firmwareV1);
+ NV_SYNC_PERSISTENT(firmwareV2);
+ // initialize the total reset counter to 0
+ gp.totalResetCount = 0;
+ NV_SYNC_PERSISTENT(totalResetCount);
+ // initialize the clock stuff
+ go.clock = 0;
+ go.clockSafe = YES;
+ NvWrite(NV_ORDERLY_DATA, sizeof(ORDERLY_DATA), &go);
+ // Commit NV writes. Manufacture process is an artificial process existing
+ // only in simulator environment and it is not defined in the specification
+ // that what should be the expected behavior if the NV write fails at this
+ // point. Therefore, it is assumed the NV write here is always success and
+ // no return code of this function is checked.
+ NvCommit();
+ g_manufactured = TRUE;
+ return 0;
+}
+/* 9.9.3.2 TPM_TearDown() */
+/* This function prepares the TPM for re-manufacture. It should not be implemented in anything other
+ than a simulated TPM. */
+/* In this implementation, all that is needs is to stop the cryptographic units and set a flag to
+ indicate that the TPM can be re-manufactured. This should be all that is necessary to start the
+ manufacturing process again. */
+/* Return Values Meaning */
+/* 0 success */
+/* 1 TPM not previously manufactured */
+LIB_EXPORT int
+TPM_TearDown(
+ void
+ )
+{
+ g_manufactured = FALSE;
+ return 0;
+}
+#if 0 /* libtpms added */
+/* 9.9.3.3 TpmEndSimulation() */
+/* This function is called at the end of the simulation run. It is used to provoke printing of any
+ statistics that might be needed. */
+LIB_EXPORT void
+TpmEndSimulation(
+ void
+ )
+{
+#if SIMULATION
+ HashLibSimulationEnd();
+ SymLibSimulationEnd();
+ MathLibSimulationEnd();
+#if ALG_RSA
+ RsaSimulationEnd();
+#endif
+#if ALG_ECC
+ EccSimulationEnd();
+#endif
+#endif // SIMULATION
+}
+#endif /* libtpms added */
diff --git a/src/tpm2/Manufacture_fp.h b/src/tpm2/Manufacture_fp.h
new file mode 100644
index 0000000..2ba2e36
--- /dev/null
+++ b/src/tpm2/Manufacture_fp.h
@@ -0,0 +1,81 @@
+/********************************************************************************/
+/* */
+/* Performs the manufacturing of the TPM */
+/* Written by Ken Goldman */
+/* IBM Thomas J. Watson Research Center */
+/* $Id: Manufacture_fp.h 1490 2019-07-26 21:13:22Z kgoldman $ */
+/* */
+/* Licenses and Notices */
+/* */
+/* 1. Copyright Licenses: */
+/* */
+/* - Trusted Computing Group (TCG) grants to the user of the source code in */
+/* this specification (the "Source Code") a worldwide, irrevocable, */
+/* nonexclusive, royalty free, copyright license to reproduce, create */
+/* derivative works, distribute, display and perform the Source Code and */
+/* derivative works thereof, and to grant others the rights granted herein. */
+/* */
+/* - The TCG grants to the user of the other parts of the specification */
+/* (other than the Source Code) the rights to reproduce, distribute, */
+/* display, and perform the specification solely for the purpose of */
+/* developing products based on such documents. */
+/* */
+/* 2. Source Code Distribution Conditions: */
+/* */
+/* - Redistributions of Source Code must retain the above copyright licenses, */
+/* this list of conditions and the following disclaimers. */
+/* */
+/* - Redistributions in binary form must reproduce the above copyright */
+/* licenses, this list of conditions and the following disclaimers in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* 3. Disclaimers: */
+/* */
+/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
+/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
+/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
+/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
+/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
+/* information on specification licensing rights available through TCG */
+/* membership agreements. */
+/* */
+/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
+/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
+/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
+/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
+/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
+/* */
+/* - Without limitation, TCG and its members and licensors disclaim all */
+/* liability, including liability for infringement of any proprietary */
+/* rights, relating to use of information in this specification and to the */
+/* implementation of this specification, and TCG disclaims all liability for */
+/* cost of procurement of substitute goods or services, lost profits, loss */
+/* of use, loss of data or any incidental, consequential, direct, indirect, */
+/* or special damages, whether under contract, tort, warranty or otherwise, */
+/* arising in any way out of use or reliance upon this specification or any */
+/* information herein. */
+/* */
+/* (c) Copyright IBM Corp. and others, 2016 - 2019 */
+/* */
+/********************************************************************************/
+
+#ifndef MANUFACTURE_FP_H
+#define MANUFACTURE_FP_H
+
+#include "CompilerDependencies.h" /* kgold */
+
+LIB_EXPORT int
+TPM_Manufacture(
+ int firstTime
+ );
+LIB_EXPORT int
+TPM_TearDown(
+ void
+ );
+LIB_EXPORT void
+TpmEndSimulation(
+ void
+ );
+
+
+#endif
diff --git a/src/tpm2/Marshal.c b/src/tpm2/Marshal.c
new file mode 100644
index 0000000..a3fa08a
--- /dev/null
+++ b/src/tpm2/Marshal.c
@@ -0,0 +1,2313 @@
+/********************************************************************************/
+/* */
+/* Parameter Marshaling */
+/* Written by Ken Goldman */
+/* IBM Thomas J. Watson Research Center */
+/* $Id: Marshal.c 1642 2020-08-18 19:42:24Z kgoldman $ */
+/* */
+/* Licenses and Notices */
+/* */
+/* 1. Copyright Licenses: */
+/* */
+/* - Trusted Computing Group (TCG) grants to the user of the source code in */
+/* this specification (the "Source Code") a worldwide, irrevocable, */
+/* nonexclusive, royalty free, copyright license to reproduce, create */
+/* derivative works, distribute, display and perform the Source Code and */
+/* derivative works thereof, and to grant others the rights granted herein. */
+/* */
+/* - The TCG grants to the user of the other parts of the specification */
+/* (other than the Source Code) the rights to reproduce, distribute, */
+/* display, and perform the specification solely for the purpose of */
+/* developing products based on such documents. */
+/* */
+/* 2. Source Code Distribution Conditions: */
+/* */
+/* - Redistributions of Source Code must retain the above copyright licenses, */
+/* this list of conditions and the following disclaimers. */
+/* */
+/* - Redistributions in binary form must reproduce the above copyright */
+/* licenses, this list of conditions and the following disclaimers in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* 3. Disclaimers: */
+/* */
+/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
+/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
+/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
+/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
+/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
+/* information on specification licensing rights available through TCG */
+/* membership agreements. */
+/* */
+/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
+/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
+/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
+/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
+/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
+/* */
+/* - Without limitation, TCG and its members and licensors disclaim all */
+/* liability, including liability for infringement of any proprietary */
+/* rights, relating to use of information in this specification and to the */
+/* implementation of this specification, and TCG disclaims all liability for */
+/* cost of procurement of substitute goods or services, lost profits, loss */
+/* of use, loss of data or any incidental, consequential, direct, indirect, */
+/* or special damages, whether under contract, tort, warranty or otherwise, */
+/* arising in any way out of use or reliance upon this specification or any */
+/* information herein. */
+/* */
+/* (c) Copyright IBM Corp. and others, 2016 - 2020 */
+/* */
+/********************************************************************************/
+
+#include <assert.h> // libtpms added
+#include <string.h>
+
+#include "Tpm.h"
+#include "Marshal_fp.h"
+
+UINT16
+UINT8_Marshal(UINT8 *source, BYTE **buffer, INT32 *size)
+{
+ if (buffer != NULL) {
+ if ((size == NULL) || ((UINT32)*size >= sizeof(UINT8))) {
+
+ (*buffer)[0] = *source;
+ *buffer += sizeof(UINT8);
+
+ if (size != NULL) {
+ *size -= sizeof(UINT8);
+ }
+ }
+ else {
+ pAssert(FALSE);
+ }
+ }
+ return sizeof(UINT8);
+}
+
+UINT16
+UINT16_Marshal(UINT16 *source, BYTE **buffer, INT32 *size)
+{
+ if (buffer != NULL) {
+ if ((size == NULL) || ((UINT32)*size >= sizeof(UINT16))) {
+
+ (*buffer)[0] = (BYTE)((*source >> 8) & 0xff);
+ (*buffer)[1] = (BYTE)((*source >> 0) & 0xff);
+ *buffer += sizeof(UINT16);
+
+ if (size != NULL) {
+ *size -= sizeof(UINT16);
+ }
+ }
+ else {
+ pAssert(FALSE);
+ }
+ }
+ return sizeof(UINT16);
+}
+
+UINT16
+UINT32_Marshal(UINT32 *source, BYTE **buffer, INT32 *size)
+{
+ if (buffer != NULL) {
+ if ((size == NULL) || ((UINT32)*size >= sizeof(UINT32))) {
+
+ (*buffer)[0] = (BYTE)((*source >> 24) & 0xff);
+ (*buffer)[1] = (BYTE)((*source >> 16) & 0xff);
+ (*buffer)[2] = (BYTE)((*source >> 8) & 0xff);
+ (*buffer)[3] = (BYTE)((*source >> 0) & 0xff);
+ *buffer += sizeof(UINT32);
+
+ if (size != NULL) {
+ *size -= sizeof(UINT32);
+ }
+ }
+ else {
+ pAssert(FALSE);
+ }
+ }
+ return sizeof(UINT32);
+}
+
+UINT16
+UINT64_Marshal(UINT64 *source, BYTE **buffer, INT32 *size)
+{
+ if (buffer != NULL) {
+ if ((size == NULL) || ((UINT32)*size >= sizeof(UINT64))) {
+
+ (*buffer)[0] = (BYTE)((*source >> 56) & 0xff);
+ (*buffer)[1] = (BYTE)((*source >> 48) & 0xff);
+ (*buffer)[2] = (BYTE)((*source >> 40) & 0xff);
+ (*buffer)[3] = (BYTE)((*source >> 32) & 0xff);
+ (*buffer)[4] = (BYTE)((*source >> 24) & 0xff);
+ (*buffer)[5] = (BYTE)((*source >> 16) & 0xff);
+ (*buffer)[6] = (BYTE)((*source >> 8) & 0xff);
+ (*buffer)[7] = (BYTE)((*source >> 0) & 0xff);
+ *buffer += sizeof(UINT64);
+
+ if (size != NULL) {
+ *size -= sizeof(UINT64);
+ }
+ }
+ else {
+ pAssert(FALSE);
+ }
+ }
+ return sizeof(UINT64);
+}
+
+UINT16
+Array_Marshal(BYTE *sourceBuffer, UINT16 sourceSize, BYTE **buffer, INT32 *size)
+{
+ if (buffer != NULL) {
+ if ((size == NULL) || (*size >= sourceSize)) {
+ memcpy(*buffer, sourceBuffer, sourceSize);
+
+ *buffer += sourceSize;
+
+ if (size != NULL) {
+ *size -= sourceSize;
+ }
+ }
+ else {
+ pAssert(FALSE);
+ }
+ }
+ return sourceSize;
+}
+
+UINT16
+TPM2B_Marshal(TPM2B *source, UINT32 maxSize, BYTE **buffer, INT32 *size)
+{
+ UINT16 written = 0;
+ assert(source->size <= maxSize); // libtpms added
+ written += UINT16_Marshal(&(source->size), buffer, size);
+ written += Array_Marshal(source->buffer, source->size, buffer, size);
+ return written;
+}
+
+/* Table 2:5 - Definition of Types for Documentation Clarity (TypedefTable()) */
+
+UINT16
+TPM_KEY_BITS_Marshal(TPM_KEY_BITS *source, BYTE **buffer, INT32 *size)
+{
+ UINT16 written = 0;
+ written += UINT16_Marshal(source, buffer, size);
+ return written;
+}
+
+/* Table 2:7 - Definition of TPM_CONSTANTS32 Constants (EnumTable()) */
+UINT16
+TPM_CONSTANTS32_Marshal(TPM_CONSTANTS32 *source, BYTE **buffer, INT32 *size)
+{
+ UINT16 written = 0;
+ written += UINT32_Marshal(source, buffer, size);
+ return written;
+}
+
+/* Table 9 - Definition of (UINT16) TPM_ALG_ID Constants <IN/OUT, S> */
+
+UINT16
+TPM_ALG_ID_Marshal(TPM_ALG_ID *source, BYTE **buffer, INT32 *size)
+{
+ UINT16 written = 0;
+ written += UINT16_Marshal(source, buffer, size);
+ return written;
+}
+
+/* Table 10 - Definition of (UINT16) {ECC} TPM_ECC_CURVE Constants <IN/OUT, S> */
+
+#if ALG_ECC
+UINT16
+TPM_ECC_CURVE_Marshal(TPM_ECC_CURVE *source, BYTE **buffer, INT32 *size)
+{
+ UINT16 written = 0;
+ written += UINT16_Marshal(source, buffer, size);
+ return written;
+}
+#endif
+
+/* Table 12 - Definition of TPM_CC Constants */
+
+UINT16
+TPM_CC_Marshal(TPM_CC *source, BYTE **buffer, INT32 *size)
+{
+ UINT16 written = 0;
+ written += UINT32_Marshal(source, buffer, size);
+ return written;
+}
+
+/* Table 2:16 - Definition of TPM_RC Constants (EnumTable()) */
+
+UINT16
+TPM_RC_Marshal(TPM_RC *source, BYTE **buffer, INT32 *size)
+{
+ UINT16 written = 0;
+ written += UINT32_Marshal(source, buffer, size);
+ return written;
+}
+
+/* Table 2:19 - Definition of TPM_ST Constants (EnumTable()) */
+
+UINT16
+TPM_ST_Marshal(TPM_ST *source, BYTE **buffer, INT32 *size)
+{
+ UINT16 written = 0;
+ written += UINT16_Marshal(source, buffer, size);
+ return written;
+}
+
+/* Table 2:22 - Definition of TPM_CAP Constants (EnumTable()) */
+
+INT16
+TPM_CAP_Marshal(TPM_CAP *source, BYTE **buffer, INT32 *size)
+{
+ UINT16 written = 0;
+ written += UINT32_Marshal(source, buffer, size);
+ return written;
+}
+
+/* Table 2:23 - Definition of TPM_PT Constants (EnumTable()) */
+
+UINT16
+TPM_PT_Marshal(TPM_PT *source, BYTE **buffer, INT32 *size)
+{
+ UINT16 written = 0;
+ written += UINT32_Marshal(source, buffer, size);
+ return written;
+}
+
+/* Table 2:24 - Definition of TPM_PT_PCR Constants (EnumTable()) */
+
+UINT16
+TPM_PT_PCR_Marshal(TPM_PT_PCR *source, BYTE **buffer, INT32 *size)
+{
+ UINT16 written = 0;
+ written += UINT32_Marshal(source, buffer, size);
+ return written;
+}
+
+/* Table 2:26 - Definition of Types for Handles (TypedefTable()) */
+
+UINT16
+TPM_HANDLE_Marshal(TPM_HANDLE *source, BYTE **buffer, INT32 *size)
+{
+ UINT16 written = 0;
+ written += UINT32_Marshal(source, buffer, size);
+ return written;
+}
+
+/* Table 2:30 - Definition of TPMA_ALGORITHM Bits (BitsTable()) */
+
+UINT16
+TPMA_ALGORITHM_Marshal(TPMA_ALGORITHM *source, BYTE **buffer, INT32 *size)
+{
+ UINT16 written = 0;
+ written += UINT32_Marshal((UINT32 *)source, buffer, size);
+ return written;
+}
+
+/* Table 2:31 - Definition of TPMA_OBJECT Bits (BitsTable()) */
+
+UINT16
+TPMA_OBJECT_Marshal(TPMA_OBJECT *source, BYTE **buffer, INT32 *size)
+{
+ UINT16 written = 0;
+ written += UINT32_Marshal((UINT32 *)source, buffer, size);
+ return written;
+}
+
+/* Table 2:32 - Definition of TPMA_SESSION Bits (BitsTable()) */
+
+UINT16
+TPMA_SESSION_Marshal(TPMA_SESSION *source, BYTE **buffer, INT32 *size)
+{
+ UINT16 written = 0;
+ written += UINT8_Marshal((UINT8 *)source, buffer, size); /* libtpms changed */
+ return written;
+}
+
+/* Table 2:33 - Definition of TPMA_LOCALITY Bits (BitsTable()) */
+
+UINT16
+TPMA_LOCALITY_Marshal(TPMA_LOCALITY *source, BYTE **buffer, INT32 *size)
+{
+ UINT16 written = 0;
+ written += UINT8_Marshal((UINT8 *)source, buffer, size); /* libtpms changed */
+ return written;
+}
+
+/* Table 2:37 - Definition of TPMA_CC Bits (BitsTable()) */
+
+UINT16
+TPMA_CC_Marshal(TPMA_CC *source, BYTE **buffer, INT32 *size)
+{
+ UINT16 written = 0;
+ written += UINT32_Marshal((UINT32 *)source, buffer, size);
+ return written;
+}
+
+/* Table 2:39 - Definition of TPMI_YES_NO Type (InterfaceTable()) */
+
+UINT16
+TPMI_YES_NO_Marshal(TPMI_YES_NO *source, BYTE **buffer, INT32 *size)
+{
+ UINT16 written = 0;
+ written += UINT8_Marshal(source, buffer, size);
+ return written;
+}
+
+/* Table 40 - Definition of (UINT32) TPMA_ACT Bits */
+
+UINT16
+TPMA_ACT_Marshal(TPMA_ACT *source, BYTE **buffer, INT32 *size)
+{
+ UINT16 written = 0;
+ written += UINT32_Marshal((UINT32 *)source, buffer, size);
+ return written;
+}
+
+/* Table 2:49 - Definition of TPMI_DH_SAVED Type (InterfaceTable()) */
+
+UINT16
+TPMI_DH_SAVED_Marshal(TPMI_DH_CONTEXT *source, BYTE **buffer, INT32 *size)
+{
+ UINT16 written = 0;
+ written += TPM_HANDLE_Marshal(source, buffer, size);
+ return written;
+}
+
+//* Table 2:49 - Definition of TPMI_RH_HIERARCHY Type (InterfaceTable()) */
+
+UINT16
+TPMI_RH_HIERARCHY_Marshal(TPMI_RH_HIERARCHY *source, BYTE **buffer, INT32 *size)
+{
+ UINT16 written = 0;
+ written += TPM_HANDLE_Marshal(source, buffer, size);
+ return written;
+}
+
+/* Table 2:59 - Definition of TPMI_RH_NV_INDEX Type (InterfaceTable()) */
+
+UINT16
+TPMI_RH_NV_INDEX_Marshal(TPMI_RH_NV_INDEX *source, BYTE **buffer, INT32 *size)
+{
+ UINT16 written = 0;
+ written += TPM_HANDLE_Marshal(source, buffer, size);
+ return written;
+}
+
+/* Table 2:60 - Definition of TPMI_ALG_HASH Type (InterfaceTable()) */
+
+UINT16
+TPMI_ALG_HASH_Marshal(TPMI_ALG_HASH *source, BYTE **buffer, INT32 *size)
+{
+ UINT16 written = 0;
+ written += TPM_ALG_ID_Marshal(source, buffer, size);
+ return written;
+}
+
+/* Table 2:63 - Definition of TPMI_ALG_SYM_OBJECT Type (InterfaceTable()) */
+
+UINT16
+TPMI_ALG_SYM_OBJECT_Marshal(TPMI_ALG_SYM_OBJECT *source, BYTE **buffer, INT32 *size)
+{
+ UINT16 written = 0;
+ written += TPM_ALG_ID_Marshal(source, buffer, size);
+ return written;
+}
+
+/* Table 2:64 - Definition of TPMI_ALG_SYM_MODE Type (InterfaceTable()) */
+
+UINT16
+TPMI_ALG_SYM_MODE_Marshal(TPMI_ALG_SYM_MODE *source, BYTE **buffer, INT32 *size)
+{
+ UINT16 written = 0;
+ written += TPM_ALG_ID_Marshal(source, buffer, size);
+ return written;
+}
+
+/* Table 2:65 - Definition of TPMI_ALG_KDF Type (InterfaceTable()) */
+
+UINT16
+TPMI_ALG_KDF_Marshal(TPMI_ALG_KDF *source, BYTE **buffer, INT32 *size)
+{
+ UINT16 written = 0;
+ written += TPM_ALG_ID_Marshal(source, buffer, size);
+ return written;
+}
+
+/* Table 2:66 - Definition of TPMI_ALG_SIG_SCHEME Type (InterfaceTable()) */
+
+UINT16
+TPMI_ALG_SIG_SCHEME_Marshal(TPMI_ALG_SIG_SCHEME *source, BYTE **buffer, INT32 *size)
+{
+ UINT16 written = 0;
+ written += TPM_ALG_ID_Marshal(source, buffer, size);
+ return written;
+}
+
+/* Table 2:71 - Definition of TPMU_HA Union (StructuresTable()) */
+
+UINT16
+TPMU_HA_Marshal(TPMU_HA *source, BYTE **buffer, INT32 *size, UINT32 selector)
+{
+ UINT16 written = 0;
+
+ switch (selector) {
+#if ALG_SHA1
+ case TPM_ALG_SHA1:
+ written += Array_Marshal(&source->sha1[0], SHA1_DIGEST_SIZE, buffer, size);
+ break;
+#endif
+#if ALG_SHA256
+ case TPM_ALG_SHA256:
+ written += Array_Marshal(&source->sha256[0], SHA256_DIGEST_SIZE, buffer, size);
+ break;
+#endif
+#if ALG_SHA384
+ case TPM_ALG_SHA384:
+ written += Array_Marshal(&source->sha384[0], SHA384_DIGEST_SIZE, buffer, size);
+ break;
+#endif
+#if ALG_SHA512
+ case TPM_ALG_SHA512:
+ written += Array_Marshal(&source->sha512[0], SHA512_DIGEST_SIZE, buffer, size);
+ break;
+#endif
+#if ALG_SM3_256
+ case TPM_ALG_SM3_256:
+ written += Array_Marshal(&source->sm3_256[0], SM3_256_DIGEST_SIZE, buffer, size);
+ break;
+#endif
+ case TPM_ALG_NULL:
+ break;
+ default:
+ pAssert(FALSE);
+ }
+ return written;
+}
+
+/* Table 2:72 - Definition of TPMT_HA Structure (StructuresTable()) */
+
+UINT16
+TPMT_HA_Marshal(TPMT_HA *source, BYTE **buffer, INT32 *size)
+{
+ UINT16 written = 0;
+ written += TPMI_ALG_HASH_Marshal(&source->hashAlg, buffer, size);
+ written += TPMU_HA_Marshal(&source->digest, buffer, size, source->hashAlg);
+ return written;
+}
+
+/* Table 2:73 - Definition of TPM2B_DIGEST Structure (StructuresTable()) */
+
+UINT16
+TPM2B_DIGEST_Marshal(TPM2B_DIGEST *source, BYTE **buffer, INT32 *size)
+{
+UINT16 written = 0;
+written += TPM2B_Marshal(&source->b, sizeof(source->t.buffer), buffer, size); // libtpms changed
+return written;
+}
+
+/* Table 2:74 - Definition of TPM2B_DATA Structure (StructuresTable()) */
+
+UINT16
+TPM2B_DATA_Marshal(TPM2B_DATA *source, BYTE **buffer, INT32 *size)
+{
+UINT16 written = 0;
+written += TPM2B_Marshal(&source->b, sizeof(source->t.buffer), buffer, size); // libtpms changed
+return written;
+}
+
+/* Table 2:75 - Definition of Types for TPM2B_NONCE (TypedefTable()) */
+
+UINT16
+TPM2B_NONCE_Marshal(TPM2B_NONCE *source, BYTE **buffer, INT32 *size)
+{
+UINT16 written = 0;
+written += TPM2B_DIGEST_Marshal(source, buffer, size);
+return written;
+}
+
+/* Table 2:76 - Definition of Types for TPM2B_AUTH (TypedefTable()) */
+
+UINT16
+TPM2B_AUTH_Marshal(TPM2B_AUTH *source, BYTE **buffer, INT32 *size)
+{
+ UINT16 written = 0;
+ written += TPM2B_DIGEST_Marshal(source, buffer, size);
+ return written;
+}
+
+/* Table 2:79 - Definition of TPM2B_MAX_BUFFER Structure (StructuresTable()) */
+
+UINT16
+TPM2B_MAX_BUFFER_Marshal(TPM2B_MAX_BUFFER *source, BYTE **buffer, INT32 *size)
+{
+ UINT16 written = 0;
+ written += TPM2B_Marshal(&source->b, sizeof(source->t.buffer), buffer, size); // libtpms changed
+ return written;
+}
+
+/* Table 2:80 - Definition of TPM2B_MAX_NV_BUFFER Structure (StructuresTable()) */
+
+UINT16
+TPM2B_MAX_NV_BUFFER_Marshal(TPM2B_MAX_NV_BUFFER *source, BYTE **buffer, INT32 *size)
+{
+ UINT16 written = 0;
+ written += TPM2B_Marshal(&source->b, sizeof(source->t.buffer), buffer, size); // libtpms changed
+ return written;
+}
+
+/* Table 80 - Definition of TPM2B_TIMEOUT Structure <IN/OUT> */
+UINT16
+TPM2B_TIMEOUT_Marshal(TPM2B_TIMEOUT *source, BYTE **buffer, INT32 *size)
+{
+ UINT16 written = 0;
+ written += TPM2B_Marshal(&source->b, sizeof(source->t.buffer), buffer, size); // libtpms changed
+ return written;
+}
+
+/* Table 2:82 - Definition of TPM2B_IV Structure (StructuresTable()) */
+
+UINT16
+TPM2B_IV_Marshal(TPM2B_IV *source, BYTE **buffer, INT32 *size)
+{
+ UINT16 written = 0;
+ written += TPM2B_Marshal(&source->b, sizeof(source->t.buffer), buffer, size); // libtpms changed
+ return written;
+}
+
+/* Table 2:84 - Definition of TPM2B_NAME Structure (StructuresTable()) */
+
+UINT16
+TPM2B_NAME_Marshal(TPM2B_NAME *source, BYTE **buffer, INT32 *size)
+{
+ UINT16 written = 0;
+ written += TPM2B_Marshal(&source->b, sizeof(source->t.name), buffer, size); // libtpms changed
+ return written;
+}
+
+/* Table 2:86 - Definition of TPMS_PCR_SELECTION Structure (StructuresTable()) */
+
+UINT16
+TPMS_PCR_SELECTION_Marshal(TPMS_PCR_SELECTION *source, BYTE **buffer, INT32 *size)
+{
+ UINT16 written = 0;
+
+ written += TPMI_ALG_HASH_Marshal(&source->hash, buffer, size);
+ written += UINT8_Marshal(&source->sizeofSelect, buffer, size);
+ written += Array_Marshal(&source->pcrSelect[0], source->sizeofSelect, buffer, size);
+ return written;
+}
+
+/* Table 2:89 - Definition of TPMT_TK_CREATION Structure (StructuresTable()) */
+
+UINT16
+TPMT_TK_CREATION_Marshal(TPMT_TK_CREATION *source, BYTE **buffer, INT32 *size)
+{
+ UINT16 written = 0;
+
+ written += TPM_ST_Marshal(&source->tag, buffer, size);
+ written += TPMI_RH_HIERARCHY_Marshal(&source->hierarchy, buffer, size);
+ written += TPM2B_DIGEST_Marshal(&source->digest, buffer, size);
+ return written;
+}
+
+/* Table 2:90 - Definition of TPMT_TK_VERIFIED Structure (StructuresTable()) */
+
+UINT16
+TPMT_TK_VERIFIED_Marshal(TPMT_TK_VERIFIED *source, BYTE **buffer, INT32 *size)
+{
+ UINT16 written = 0;
+
+ written += TPM_ST_Marshal(&source->tag, buffer, size);
+ written += TPMI_RH_HIERARCHY_Marshal(&source->hierarchy, buffer, size);
+ written += TPM2B_DIGEST_Marshal(&source->digest, buffer, size);
+ return written;
+}
+
+/* Table 2:91 - Definition of TPMT_TK_AUTH Structure (StructuresTable()) */
+
+UINT16
+TPMT_TK_AUTH_Marshal(TPMT_TK_AUTH *source, BYTE **buffer, INT32 *size)
+{
+ UINT16 written = 0;
+
+ written += TPM_ST_Marshal(&source->tag, buffer, size);
+ written += TPMI_RH_HIERARCHY_Marshal(&source->hierarchy, buffer, size);
+ written += TPM2B_DIGEST_Marshal(&source->digest, buffer, size);
+ return written;
+}
+
+/* Table 2:92 - Definition of TPMT_TK_HASHCHECK Structure (StructuresTable()) */
+
+UINT16
+TPMT_TK_HASHCHECK_Marshal(TPMT_TK_HASHCHECK *source, BYTE **buffer, INT32 *size)
+{
+ UINT16 written = 0;
+
+ written += TPM_ST_Marshal(&source->tag, buffer, size);
+ written += TPMI_RH_HIERARCHY_Marshal(&source->hierarchy, buffer, size);
+ written += TPM2B_DIGEST_Marshal(&source->digest, buffer, size);
+ return written;
+}
+
+/* Table 2:93 - Definition of TPMS_ALG_PROPERTY Structure (StructuresTable()) */
+
+UINT16
+TPMS_ALG_PROPERTY_Marshal(TPMS_ALG_PROPERTY *source, BYTE **buffer, INT32 *size)
+{
+ UINT16 written = 0;
+
+ written += TPM_ALG_ID_Marshal(&source->alg, buffer, size);
+ written += TPMA_ALGORITHM_Marshal(&source->algProperties, buffer, size);
+ return written;
+}
+
+/* Table 2:95 - Definition of TPMS_TAGGED_PCR_SELECT Structure (StructuresTable()) */
+
+UINT16
+TPMS_TAGGED_PCR_SELECT_Marshal(TPMS_TAGGED_PCR_SELECT *source, BYTE **buffer, INT32 *size)
+{
+ UINT16 written = 0;
+
+ written += TPM_PT_PCR_Marshal(&source->tag, buffer, size);
+ written += UINT8_Marshal(&source->sizeofSelect, buffer, size);
+ written += Array_Marshal(&source->pcrSelect[0], source->sizeofSelect, buffer, size);
+ return written;
+}
+
+/* Table 2:96 - Definition of TPMS_TAGGED_POLICY Structure (StructuresTable()) */
+
+UINT16
+TPMS_TAGGED_POLICY_Marshal(TPMS_TAGGED_POLICY *source, BYTE **buffer, INT32 *size)
+{
+ UINT16 written = 0;
+
+ written += TPM_HANDLE_Marshal(&source->handle, buffer, size);
+ written += TPMT_HA_Marshal(&source->policyHash, buffer, size);
+ return written;
+}
+
+/* Table 105 - Definition of TPMS_ACT_DATA Structure <OUT> */
+
+UINT16
+TPMS_ACT_DATA_Marshal(TPMS_ACT_DATA *source, BYTE **buffer, INT32 *size)
+{
+ UINT16 written = 0;
+
+ written += TPM_HANDLE_Marshal(&source->handle, buffer, size);
+ written += UINT32_Marshal(&source->timeout, buffer, size);
+ written += TPMA_ACT_Marshal(&source->attributes, buffer, size);
+ return written;
+}
+
+/* Table 2:94 - Definition of TPMS_TAGGED_PROPERTY Structure (StructuresTable()) */
+
+UINT16
+TPMS_TAGGED_PROPERTY_Marshal(TPMS_TAGGED_PROPERTY *source, BYTE **buffer, INT32 *size)
+{
+ UINT16 written = 0;
+
+ written += TPM_PT_Marshal(&source->property, buffer, size);
+ written += UINT32_Marshal(&source->value, buffer, size);
+ return written;
+}
+
+/* Table 2:97 - Definition of TPML_CC Structure (StructuresTable()) */
+
+UINT16
+TPML_CC_Marshal(TPML_CC *source, BYTE **buffer, INT32 *size)
+{
+ UINT16 written = 0;
+ UINT32 i;
+
+ written += UINT32_Marshal(&source->count, buffer, size);
+ for (i = 0 ; i < source->count ; i++) {
+ written += TPM_CC_Marshal(&source->commandCodes[i], buffer, size);
+ }
+ return written;
+}
+
+/* Table 2:98 - Definition of TPML_CCA Structure (StructuresTable()) */
+
+UINT16
+TPML_CCA_Marshal(TPML_CCA *source, BYTE **buffer, INT32 *size)
+{
+ UINT16 written = 0;
+ UINT32 i;
+
+ written += UINT32_Marshal(&source->count, buffer, size);
+ for (i = 0 ; i < source->count ; i++) {
+ written += TPMA_CC_Marshal(&source->commandAttributes[i], buffer, size);
+ }
+ return written;
+}
+
+/* Table 2:99 - Definition of TPML_ALG Structure (StructuresTable()) */
+
+UINT16
+TPML_ALG_Marshal(TPML_ALG *source, BYTE **buffer, INT32 *size)
+{
+ UINT16 written = 0;
+ UINT32 i;
+
+ written += UINT32_Marshal(&source->count, buffer, size);
+ for (i = 0 ; i < source->count ; i++) {
+ written += TPM_ALG_ID_Marshal(&source->algorithms[i], buffer, size);
+ }
+ return written;
+}
+
+/* Table 2:100 - Definition of TPML_HANDLE Structure (StructuresTable()) */
+
+UINT16
+TPML_HANDLE_Marshal(TPML_HANDLE *source, BYTE **buffer, INT32 *size)
+{
+ UINT16 written = 0;
+ UINT32 i;
+
+ written += UINT32_Marshal(&source->count, buffer, size);
+ for (i = 0 ; i < source->count ; i++) {
+ written += TPM_HANDLE_Marshal(&source->handle[i], buffer, size);
+ }
+ return written;
+}
+
+/* Table 2:101 - Definition of TPML_DIGEST Structure (StructuresTable()) */
+
+UINT16
+TPML_DIGEST_Marshal(TPML_DIGEST *source, BYTE **buffer, INT32 *size)
+{
+ UINT16 written = 0;
+ UINT32 i;
+
+ written += UINT32_Marshal(&source->count, buffer, size);
+ for (i = 0 ; i < source->count ; i++) {
+ written += TPM2B_DIGEST_Marshal(&source->digests[i], buffer, size);
+ }
+ return written;
+}
+
+/* Table 2:102 - Definition of TPML_DIGEST_VALUES Structure (StructuresTable()) */
+
+UINT16
+TPML_DIGEST_VALUES_Marshal(TPML_DIGEST_VALUES *source, BYTE **buffer, INT32 *size)
+{
+ UINT16 written = 0;
+ UINT32 i;
+
+ written += UINT32_Marshal(&source->count, buffer, size);
+ for (i = 0 ; i < source->count ; i++) {
+ written += TPMT_HA_Marshal(&source->digests[i], buffer, size);
+ }
+ return written;
+}
+
+/* Table 2:104 - Definition of TPML_PCR_SELECTION Structure (StructuresTable()) */
+
+UINT16
+TPML_PCR_SELECTION_Marshal(TPML_PCR_SELECTION *source, BYTE **buffer, INT32 *size)
+{
+ UINT16 written = 0;
+ UINT32 i;
+
+ written += UINT32_Marshal(&source->count, buffer, size);
+ for (i = 0 ; i < source->count ; i++) {
+ written += TPMS_PCR_SELECTION_Marshal(&source->pcrSelections[i], buffer, size);
+ }
+ return written;
+}
+
+/* Table 2:105 - Definition of TPML_ALG_PROPERTY Structure (StructuresTable()) */
+
+
+UINT16
+TPML_ALG_PROPERTY_Marshal(TPML_ALG_PROPERTY *source, BYTE **buffer, INT32 *size)
+{
+ UINT16 written = 0;
+ UINT32 i;
+
+ written += UINT32_Marshal(&source->count, buffer, size);
+ for (i = 0 ; i < source->count ; i++) {
+ written += TPMS_ALG_PROPERTY_Marshal(&source->algProperties[i], buffer, size);
+ }
+ return written;
+}
+
+//* Table 2:106 - Definition of TPML_TAGGED_TPM_PROPERTY Structure (StructuresTable()) */
+
+UINT16
+TPML_TAGGED_TPM_PROPERTY_Marshal(TPML_TAGGED_TPM_PROPERTY *source, BYTE **buffer, INT32 *size)
+{
+ UINT16 written = 0;
+ UINT32 i;
+
+ written += UINT32_Marshal(&source->count, buffer, size);
+ for (i = 0 ; i < source->count ; i++) {
+ written += TPMS_TAGGED_PROPERTY_Marshal(&source->tpmProperty[i], buffer, size);
+ }
+ return written;
+}
+
+/* Table 2:107 - Definition of TPML_TAGGED_PCR_PROPERTY Structure (StructuresTable()) */
+
+UINT16
+TPML_TAGGED_PCR_PROPERTY_Marshal(TPML_TAGGED_PCR_PROPERTY *source, BYTE **buffer, INT32 *size)
+{
+ UINT16 written = 0;
+ UINT32 i;
+
+ written += UINT32_Marshal(&source->count, buffer, size);
+ for (i = 0 ; i < source->count ; i++) {
+ written += TPMS_TAGGED_PCR_SELECT_Marshal(&source->pcrProperty[i], buffer, size);
+ }
+ return written;
+}
+
+/* Table 2:108 - Definition of TPML_ECC_CURVE Structure (StructuresTable()) */
+
+UINT16
+TPML_ECC_CURVE_Marshal(TPML_ECC_CURVE *source, BYTE **buffer, INT32 *size)
+{
+ UINT16 written = 0;
+
+ UINT32 i;
+
+ written += UINT32_Marshal(&source->count, buffer, size);
+ for (i = 0 ; i < source->count ; i++) {
+ written += TPM_ECC_CURVE_Marshal(&source->eccCurves[i], buffer, size);
+ }
+ return written;
+}
+
+/* Table 2:109 - Definition of TPML_TAGGED_POLICY Structure (StructuresTable()) */
+
+UINT16
+TPML_TAGGED_POLICY_Marshal(TPML_TAGGED_POLICY *source, BYTE **buffer, INT32 *size)
+{
+ UINT16 written = 0;
+ UINT32 i;
+
+ written += UINT32_Marshal(&source->count, buffer, size);
+ for (i = 0 ; i < source->count ; i++) {
+ written += TPMS_TAGGED_POLICY_Marshal(&source->policies[i], buffer, size);
+ }
+ return written;
+}
+
+/* Table 2:118 - Definition of TPML_ACT_DATA Structure (StructuresTable()) */
+
+UINT16
+TPML_ACT_DATA_Marshal(TPML_ACT_DATA *source, BYTE **buffer, INT32 *size)
+{
+ UINT16 written = 0;
+ UINT32 i;
+
+ written += UINT32_Marshal(&source->count, buffer, size);
+ for (i = 0 ; i < source->count ; i++) {
+ written += TPMS_ACT_DATA_Marshal(&source->actData[i], buffer, size);
+ }
+ return written;
+}
+
+/* Table 2:110 - Definition of TPMU_CAPABILITIES Union (StructuresTable()) */
+
+UINT16
+TPMU_CAPABILITIES_Marshal(TPMU_CAPABILITIES *source, BYTE **buffer, INT32 *size, UINT32 selector)
+{
+ UINT16 written = 0;
+
+ switch (selector) {
+ case TPM_CAP_ALGS:
+ written += TPML_ALG_PROPERTY_Marshal(&source->algorithms, buffer, size);
+ break;
+ case TPM_CAP_HANDLES:
+ written += TPML_HANDLE_Marshal(&source->handles, buffer, size);
+ break;
+ case TPM_CAP_COMMANDS:
+ written += TPML_CCA_Marshal(&source->command, buffer, size);
+ break;
+ case TPM_CAP_PP_COMMANDS:
+ written += TPML_CC_Marshal(&source->ppCommands, buffer, size);
+ break;
+ case TPM_CAP_AUDIT_COMMANDS:
+ written += TPML_CC_Marshal(&source->auditCommands, buffer, size);
+ break;
+ case TPM_CAP_PCRS:
+ written += TPML_PCR_SELECTION_Marshal(&source->assignedPCR, buffer, size);
+ break;
+ case TPM_CAP_TPM_PROPERTIES:
+ written += TPML_TAGGED_TPM_PROPERTY_Marshal(&source->tpmProperties, buffer, size);
+ break;
+ case TPM_CAP_PCR_PROPERTIES:
+ written += TPML_TAGGED_PCR_PROPERTY_Marshal(&source->pcrProperties, buffer, size);
+ break;
+ case TPM_CAP_ECC_CURVES:
+ written += TPML_ECC_CURVE_Marshal(&source->eccCurves, buffer, size);
+ break;
+ case TPM_CAP_AUTH_POLICIES:
+ written += TPML_TAGGED_POLICY_Marshal(&source->authPolicies, buffer, size);
+ break;
+ case TPM_CAP_ACT:
+ written += TPML_ACT_DATA_Marshal(&source->actData, buffer, size);
+ break;
+ default:
+ pAssert(FALSE);
+ }
+ return written;
+}
+
+/* Table 2:111 - Definition of TPMS_CAPABILITY_DATA Structure (StructuresTable()) */
+
+UINT16
+TPMS_CAPABILITY_DATA_Marshal(TPMS_CAPABILITY_DATA *source, BYTE **buffer, INT32 *size)
+{
+ UINT16 written = 0;
+
+ written += TPM_CAP_Marshal(&source->capability, buffer, size);
+ written += TPMU_CAPABILITIES_Marshal(&source->data, buffer, size, source->capability);
+ return written;
+}
+
+/* Table 2:112 - Definition of TPMS_CLOCK_INFO Structure (StructuresTable()) */
+
+UINT16
+TPMS_CLOCK_INFO_Marshal(TPMS_CLOCK_INFO *source, BYTE **buffer, INT32 *size)
+{
+ UINT16 written = 0;
+
+ written += UINT64_Marshal(&source->clock, buffer, size);
+ written += UINT32_Marshal(&source->resetCount, buffer, size);
+ written += UINT32_Marshal(&source->restartCount, buffer, size);
+ written += TPMI_YES_NO_Marshal(&source->safe, buffer, size);
+ return written;
+}
+
+/* Table 2:113 - Definition of TPMS_TIME_INFO Structure (StructuresTable()) */
+
+UINT16
+TPMS_TIME_INFO_Marshal(TPMS_TIME_INFO *source, BYTE **buffer, INT32 *size)
+{
+ UINT16 written = 0;
+
+ written += UINT64_Marshal(&source->time, buffer, size);
+ written += TPMS_CLOCK_INFO_Marshal(&source->clockInfo, buffer, size);
+ return written;
+}
+
+/* Table 2:114 - Definition of TPMS_TIME_ATTEST_INFO Structure (StructuresTable()) */
+
+UINT16
+TPMS_TIME_ATTEST_INFO_Marshal(TPMS_TIME_ATTEST_INFO *source, BYTE **buffer, INT32 *size)
+{
+ UINT16 written = 0;
+
+ written += TPMS_TIME_INFO_Marshal(&source->time, buffer, size);
+ written += UINT64_Marshal(&source->firmwareVersion, buffer, size);
+ return written;
+}
+
+/* Table 2:115 - Definition of TPMS_CERTIFY_INFO Structure (StructuresTable()) */
+
+UINT16
+TPMS_CERTIFY_INFO_Marshal(TPMS_CERTIFY_INFO *source, BYTE **buffer, INT32 *size)
+{
+ UINT16 written = 0;
+
+ written += TPM2B_NAME_Marshal(&source->name, buffer, size);
+ written += TPM2B_NAME_Marshal(&source->qualifiedName, buffer, size);
+ return written;
+}
+
+/* Table 2:116 - Definition of TPMS_QUOTE_INFO Structure (StructuresTable()) */
+
+UINT16
+TPMS_QUOTE_INFO_Marshal(TPMS_QUOTE_INFO *source, BYTE **buffer, INT32 *size)
+{
+ UINT16 written = 0;
+
+ written += TPML_PCR_SELECTION_Marshal(&source->pcrSelect, buffer, size);
+ written += TPM2B_DIGEST_Marshal(&source->pcrDigest, buffer, size);
+ return written;
+}
+
+/* Table 2:117 - Definition of TPMS_COMMAND_AUDIT_INFO Structure (StructuresTable()) */
+
+UINT16
+TPMS_COMMAND_AUDIT_INFO_Marshal(TPMS_COMMAND_AUDIT_INFO *source, BYTE **buffer, INT32 *size)
+{
+ UINT16 written = 0;
+
+ written += UINT64_Marshal(&source->auditCounter, buffer, size);
+ written += TPM_ALG_ID_Marshal(&source->digestAlg, buffer, size);
+ written += TPM2B_DIGEST_Marshal(&source->auditDigest, buffer, size);
+ written += TPM2B_DIGEST_Marshal(&source->commandDigest, buffer, size);
+ return written;
+}
+
+/* Table 2:118 - Definition of TPMS_SESSION_AUDIT_INFO Structure (StructuresTable()) */
+
+UINT16
+TPMS_SESSION_AUDIT_INFO_Marshal(TPMS_SESSION_AUDIT_INFO *source, BYTE **buffer, INT32 *size)
+{
+ UINT16 written = 0;
+
+ written += TPMI_YES_NO_Marshal(&source->exclusiveSession, buffer, size);
+ written += TPM2B_DIGEST_Marshal(&source->sessionDigest, buffer, size);
+ return written;
+}
+
+/* Table 2:119 - Definition of TPMS_CREATION_INFO Structure (StructuresTable()) */
+
+UINT16
+TPMS_CREATION_INFO_Marshal(TPMS_CREATION_INFO *source, BYTE **buffer, INT32 *size)
+{
+ UINT16 written = 0;
+
+ written += TPM2B_NAME_Marshal(&source->objectName, buffer, size);
+ written += TPM2B_DIGEST_Marshal(&source->creationHash, buffer, size);
+ return written;
+}
+
+/* Table 2:120 - Definition of TPMS_NV_CERTIFY_INFO Structure (StructuresTable()) */
+
+UINT16
+TPMS_NV_CERTIFY_INFO_Marshal(TPMS_NV_CERTIFY_INFO *source, BYTE **buffer, INT32 *size)
+{
+ UINT16 written = 0;
+
+ written += TPM2B_NAME_Marshal(&source->indexName, buffer, size);
+ written += UINT16_Marshal(&source->offset, buffer, size);
+ written += TPM2B_MAX_NV_BUFFER_Marshal(&source->nvContents, buffer, size);
+ return written;
+}
+
+/* Table 125 - Definition of TPMS_NV_DIGEST_CERTIFY_INFO Structure <OUT> */
+UINT16
+TPMS_NV_DIGEST_CERTIFY_INFO_Marshal(TPMS_NV_DIGEST_CERTIFY_INFO *source, BYTE **buffer, INT32 *size)
+{
+ UINT16 written = 0;
+ written += TPM2B_NAME_Marshal(&source->indexName, buffer, size);
+ written += TPM2B_DIGEST_Marshal(&source->nvDigest, buffer, size);
+ return written;
+}
+
+/* Table 2:121 - Definition of TPMI_ST_ATTEST Type (InterfaceTable()) */
+
+UINT16
+TPMI_ST_ATTEST_Marshal(TPMI_ST_ATTEST *source, BYTE **buffer, INT32 *size)
+{
+ UINT16 written = 0;
+ written += TPM_ST_Marshal(source, buffer, size);
+ return written;
+}
+
+/* Table 2:122 - Definition of TPMU_ATTEST Union (StructuresTable()) */
+
+UINT16
+TPMU_ATTEST_Marshal(TPMU_ATTEST *source, BYTE **buffer, INT32 *size, UINT32 selector)
+{
+ UINT16 written = 0;
+
+ switch (selector) {
+ case TPM_ST_ATTEST_CERTIFY:
+ written += TPMS_CERTIFY_INFO_Marshal(&source->certify, buffer, size);
+ break;
+ case TPM_ST_ATTEST_CREATION:
+ written += TPMS_CREATION_INFO_Marshal(&source->creation, buffer, size);
+ break;
+ case TPM_ST_ATTEST_QUOTE:
+ written += TPMS_QUOTE_INFO_Marshal(&source->quote, buffer, size);
+ break;
+ case TPM_ST_ATTEST_COMMAND_AUDIT:
+ written += TPMS_COMMAND_AUDIT_INFO_Marshal(&source->commandAudit, buffer, size);
+ break;
+ case TPM_ST_ATTEST_SESSION_AUDIT:
+ written += TPMS_SESSION_AUDIT_INFO_Marshal(&source->sessionAudit, buffer, size);
+ break;
+ case TPM_ST_ATTEST_TIME:
+ written += TPMS_TIME_ATTEST_INFO_Marshal(&source->time, buffer, size);
+ break;
+ case TPM_ST_ATTEST_NV:
+ written += TPMS_NV_CERTIFY_INFO_Marshal(&source->nv, buffer, size);
+ break;
+ case TPM_ST_ATTEST_NV_DIGEST:
+ written += TPMS_NV_DIGEST_CERTIFY_INFO_Marshal(&source->nvDigest, buffer, size);
+ break;
+ default:
+ pAssert(FALSE);
+ }
+ return written;
+}
+
+/* Table 2:123 - Definition of TPMS_ATTEST Structure (StructuresTable()) */
+
+UINT16
+TPMS_ATTEST_Marshal(TPMS_ATTEST *source, BYTE **buffer, INT32 *size)
+{
+ UINT16 written = 0;
+
+ written += TPM_CONSTANTS32_Marshal(&source->magic, buffer, size);
+ written += TPMI_ST_ATTEST_Marshal(&source->type, buffer, size);
+ written += TPM2B_NAME_Marshal(&source->qualifiedSigner, buffer, size);
+ written += TPM2B_DATA_Marshal(&source->extraData, buffer, size);
+ written += TPMS_CLOCK_INFO_Marshal(&source->clockInfo, buffer, size);
+ written += UINT64_Marshal(&source->firmwareVersion, buffer, size);
+ written += TPMU_ATTEST_Marshal(&source->attested, buffer, size,source->type);
+ return written;
+}
+
+/* Table 2:124 - Definition of TPM2B_ATTEST Structure (StructuresTable()) */
+
+UINT16
+TPM2B_ATTEST_Marshal(TPM2B_ATTEST *source, BYTE **buffer, INT32 *size)
+{
+ UINT16 written = 0;
+ written += TPM2B_Marshal(&source->b, sizeof(source->t.attestationData), buffer, size); // libtpms changed
+ return written;
+}
+
+/* Table 2:127 - Definition of TPMI_AES_KEY_BITS Type (InterfaceTable()) */
+
+UINT16
+TPMI_AES_KEY_BITS_Marshal(TPMI_AES_KEY_BITS *source, BYTE **buffer, INT32 *size)
+{
+ UINT16 written = 0;
+ written += TPM_KEY_BITS_Marshal(source, buffer, size);
+ return written;
+}
+
+UINT16 // libtpms added begin
+TPMI_TDES_KEY_BITS_Marshal(TPMI_TDES_KEY_BITS *source, BYTE **buffer, INT32 *size)
+{
+ UINT16 written = 0;
+ written += TPM_KEY_BITS_Marshal(source, buffer, size);
+ return written;
+}
+
+#if ALG_CAMELLIA
+UINT16
+TPMI_CAMELLIA_KEY_BITS_Marshal(TPMI_CAMELLIA_KEY_BITS *source, BYTE **buffer, INT32 *size)
+{
+ UINT16 written = 0;
+ written += TPM_KEY_BITS_Marshal(source, buffer, size);
+ return written;
+}
+#endif // libtpms added end
+
+/* Table 2:128 - Definition of TPMU_SYM_KEY_BITS Union (StructuresTable()) */
+
+UINT16
+TPMU_SYM_KEY_BITS_Marshal(TPMU_SYM_KEY_BITS *source, BYTE **buffer, INT32 *size, UINT32 selector)
+{
+ UINT16 written = 0;
+
+ switch(selector) {
+#if ALG_AES
+ case TPM_ALG_AES:
+ written += TPMI_AES_KEY_BITS_Marshal(&source->aes, buffer, size);
+ break;
+#endif
+#if ALG_SM4
+ case TPM_ALG_SM4:
+ written += TPMI_SM4_KEY_BITS_Marshal(&source->sm4, buffer, size);
+ break;
+#endif
+#if ALG_CAMELLIA
+ case TPM_ALG_CAMELLIA:
+ written += TPMI_CAMELLIA_KEY_BITS_Marshal(&source->camellia, buffer, size);
+ break;
+#endif
+#if ALG_TDES // libtpms added begin
+ case TPM_ALG_TDES:
+ written += TPMI_TDES_KEY_BITS_Marshal(&source->tdes, buffer, size);
+ break;
+#endif // libtpms added end
+#if ALG_XOR
+ case TPM_ALG_XOR:
+ written += TPMI_ALG_HASH_Marshal(&source->xorr, buffer, size);
+ break;
+#endif
+ case TPM_ALG_NULL:
+ break;
+ default:
+ pAssert(FALSE);
+ }
+ return written;
+}
+
+/* Table 2:129 - Definition of TPMU_SYM_MODE Union (StructuresTable()) */
+
+UINT16
+TPMU_SYM_MODE_Marshal(TPMU_SYM_MODE *source, BYTE **buffer, INT32 *size, UINT32 selector)
+{
+ UINT16 written = 0;
+
+ switch (selector) {
+#if ALG_AES
+ case TPM_ALG_AES:
+ written += TPMI_ALG_SYM_MODE_Marshal(&source->aes, buffer, size);
+ break;
+#endif
+#if ALG_SM4
+ case TPM_ALG_SM4:
+ written += TPMI_ALG_SYM_MODE_Marshal(&source->sm4, buffer, size);
+ break;
+#endif
+#if ALG_CAMELLIA
+ case TPM_ALG_CAMELLIA:
+ written += TPMI_ALG_SYM_MODE_Marshal(&source->camellia, buffer, size);
+ break;
+#endif
+#if ALG_TDES // libtpms added begin
+ case TPM_ALG_TDES:
+ written += TPMI_ALG_SYM_MODE_Marshal(&source->tdes, buffer, size);
+ break;
+#endif // libtpms added end
+#if ALG_XOR
+ case TPM_ALG_XOR:
+#endif
+ case TPM_ALG_NULL:
+ break;
+ default:
+ pAssert(FALSE);
+ }
+ return written;
+}
+
+/* Table 2:132 - Definition of TPMT_SYM_DEF_OBJECT Structure (StructuresTable()) */
+
+UINT16
+TPMT_SYM_DEF_OBJECT_Marshal(TPMT_SYM_DEF_OBJECT *source, BYTE **buffer, INT32 *size)
+{
+ UINT16 written = 0;
+
+ written += TPMI_ALG_SYM_OBJECT_Marshal(&source->algorithm, buffer, size);
+ written += TPMU_SYM_KEY_BITS_Marshal(&source->keyBits, buffer, size, source->algorithm);
+ written += TPMU_SYM_MODE_Marshal(&source->mode, buffer, size, source->algorithm);
+ return written;
+}
+
+/* Table 2:133 - Definition of TPM2B_SYM_KEY Structure (StructuresTable()) */
+
+UINT16
+TPM2B_SYM_KEY_Marshal(TPM2B_SYM_KEY *source, BYTE **buffer, INT32 *size)
+{
+ UINT16 written = 0;
+ written += TPM2B_Marshal(&source->b, sizeof(source->t.buffer), buffer, size); // libtpms changed
+ return written;
+}
+
+/* Table 2:134 - Definition of TPMS_SYMCIPHER_PARMS Structure (StructuresTable()) */
+
+UINT16
+TPMS_SYMCIPHER_PARMS_Marshal(TPMS_SYMCIPHER_PARMS *source, BYTE **buffer, INT32 *size)
+{
+ UINT16 written = 0;
+
+ written += TPMT_SYM_DEF_OBJECT_Marshal(&source->sym, buffer, size);
+ return written;
+}
+
+/* Table 2:139 - Definition of TPM2B_SENSITIVE_DATA Structure (StructuresTable()) */
+
+UINT16
+TPM2B_SENSITIVE_DATA_Marshal(TPM2B_SENSITIVE_DATA *source, BYTE **buffer, INT32 *size)
+{
+ UINT16 written = 0;
+ written += TPM2B_Marshal(&source->b, sizeof(source->t.buffer), buffer, size); // libtpms changed
+ return written;
+}
+
+/* Table 2:142 - Definition of TPMS_SCHEME_HASH Structure (StructuresTable()) */
+
+UINT16
+TPMS_SCHEME_HASH_Marshal(TPMS_SCHEME_HASH *source, BYTE **buffer, INT32 *size)
+{
+ UINT16 written = 0;
+
+ written += TPMI_ALG_HASH_Marshal(&source->hashAlg, buffer, size);
+ return written;
+}
+
+/* Table 2:143 - Definition of TPMS_SCHEME_ECDAA Structure (StructuresTable()) */
+
+UINT16
+TPMS_SCHEME_ECDAA_Marshal(TPMS_SCHEME_ECDAA *source, BYTE **buffer, INT32 *size)
+{
+ UINT16 written = 0;
+
+ written += TPMI_ALG_HASH_Marshal(&source->hashAlg, buffer, size);
+ written += UINT16_Marshal(&source->count, buffer, size);
+ return written;
+}
+
+/* Table 2:144 - Definition of TPMI_ALG_KEYEDHASH_SCHEME Type (InterfaceTable()) */
+
+UINT16
+TPMI_ALG_KEYEDHASH_SCHEME_Marshal(TPMI_ALG_KEYEDHASH_SCHEME *source, BYTE **buffer, INT32 *size)
+{
+ UINT16 written = 0;
+ written += TPM_ALG_ID_Marshal(source, buffer, size);
+ return written;
+}
+
+/* Table 2:145 - Definition of Types for HMAC_SIG_SCHEME (TypedefTable()) */
+
+UINT16
+TPMS_SCHEME_HMAC_Marshal(TPMS_SCHEME_HMAC *source, BYTE **buffer, INT32 *size)
+{
+ UINT16 written = 0;
+ written += TPMS_SCHEME_HASH_Marshal(source, buffer, size);
+ return written;
+}
+
+/* Table 2:146 - Definition of TPMS_SCHEME_XOR Structure (StructuresTable()) */
+
+UINT16
+TPMS_SCHEME_XOR_Marshal(TPMS_SCHEME_XOR *source, BYTE **buffer, INT32 *size)
+{
+ UINT16 written = 0;
+
+ written += TPMI_ALG_HASH_Marshal(&source->hashAlg, buffer, size);
+ written += TPMI_ALG_KDF_Marshal(&source->kdf, buffer, size);
+ return written;
+}
+
+/* Table 2:148 - Definition of TPMT_KEYEDHASH_SCHEME Structure (StructuresTable()) */
+
+UINT16
+TPMT_KEYEDHASH_SCHEME_Marshal(TPMT_KEYEDHASH_SCHEME *source, BYTE **buffer, INT32 *size)
+{
+ UINT16 written = 0;
+
+ written += TPMI_ALG_KEYEDHASH_SCHEME_Marshal(&source->scheme, buffer, size);
+ written += TPMU_SCHEME_KEYEDHASH_Marshal(&source->details, buffer, size, source->scheme);
+ return written;
+}
+
+/* Table 2:149 - Definition of Types for RSA Signature Schemes (TypedefTable()) */
+
+UINT16
+TPMS_SIG_SCHEME_RSASSA_Marshal(TPMS_SIG_SCHEME_RSASSA *source, BYTE **buffer, INT32 *size)
+{
+ UINT16 written = 0;
+ written += TPMS_SCHEME_HASH_Marshal(source, buffer, size);
+ return written;
+}
+
+UINT16
+TPMS_SIG_SCHEME_RSAPSS_Marshal(TPMS_SIG_SCHEME_RSAPSS *source, BYTE **buffer, INT32 *size)
+{
+ UINT16 written = 0;
+ written += TPMS_SCHEME_HASH_Marshal(source, buffer, size);
+ return written;
+}
+
+/* Table 2:150 - Definition of Types for ECC Signature Schemes (TypedefTable()) */
+
+UINT16
+TPMS_SIG_SCHEME_ECDSA_Marshal(TPMS_SIG_SCHEME_ECDSA *source, BYTE **buffer, INT32 *size)
+{
+ UINT16 written = 0;
+ written += TPMS_SCHEME_HASH_Marshal(source, buffer, size);
+ return written;
+}
+UINT16
+TPMS_SIG_SCHEME_SM2_Marshal(TPMS_SIG_SCHEME_SM2 *source, BYTE **buffer, INT32 *size)
+{
+ UINT16 written = 0;
+ written += TPMS_SCHEME_HASH_Marshal(source, buffer, size);
+ return written;
+}
+UINT16
+TPMS_SIG_SCHEME_ECSCHNORR_Marshal(TPMS_SIG_SCHEME_ECSCHNORR *source, BYTE **buffer, INT32 *size)
+{
+ UINT16 written = 0;
+ written += TPMS_SCHEME_HASH_Marshal(source, buffer, size);
+ return written;
+}
+UINT16
+TPMS_SIG_SCHEME_ECDAA_Marshal(TPMS_SIG_SCHEME_ECDAA *source, BYTE **buffer, INT32 *size)
+{
+ UINT16 written = 0;
+ written += TPMS_SCHEME_ECDAA_Marshal(source, buffer, size);
+ return written;
+}
+
+/* Table 2:153 - Definition of Types for Encryption Schemes (TypedefTable()) */
+
+UINT16
+TPMS_ENC_SCHEME_OAEP_Marshal(TPMS_ENC_SCHEME_OAEP *source, BYTE **buffer, INT32 *size)
+{
+ UINT16 written = 0;
+ written += TPMS_SCHEME_HASH_Marshal(source, buffer, size);
+ return written;
+}
+
+/* Table 146 - Definition of Types for {RSA} Encryption Schemes */
+
+UINT16
+TPMS_ENC_SCHEME_RSAES_Marshal(TPMS_ENC_SCHEME_RSAES *source, BYTE **buffer, INT32 *size)
+{
+ source = source;
+ buffer = buffer;
+ size = size;
+ return 0;
+}
+
+/* Table 2:147 - Definition of TPMU_SCHEME_KEYEDHASH Union (StructuresTable()) */
+
+UINT16
+TPMU_SCHEME_KEYEDHASH_Marshal(TPMU_SCHEME_KEYEDHASH *source, BYTE **buffer, INT32 *size, UINT32 selector)
+{
+ UINT16 written = 0;
+
+ switch (selector) {
+#if ALG_HMAC
+ case TPM_ALG_HMAC:
+ written += TPMS_SCHEME_HMAC_Marshal(&source->hmac, buffer, size);
+ break;
+#endif
+#if ALG_XOR
+ case TPM_ALG_XOR:
+ written += TPMS_SCHEME_XOR_Marshal(&source->xorr, buffer, size);
+ break;
+#endif
+ case TPM_ALG_NULL:
+ break;
+ default:
+ pAssert(FALSE);
+ }
+ return written;
+}
+
+/* Table 2:154 - Definition of Types for ECC Key Exchange (TypedefTable()) */
+
+UINT16
+TPMS_KEY_SCHEME_ECDH_Marshal(TPMS_KEY_SCHEME_ECDH *source, BYTE **buffer, INT32 *size)
+{
+ UINT16 written = 0;
+ written += TPMS_SCHEME_HASH_Marshal(source, buffer, size);
+ return written;
+}
+
+UINT16
+TPMS_KEY_SCHEME_ECMQV_Marshal(TPMS_KEY_SCHEME_ECMQV*source, BYTE **buffer, INT32 *size)
+{
+ UINT16 written = 0;
+ written += TPMS_SCHEME_HASH_Marshal(source, buffer, size);
+ return written;
+}
+
+/* Table 2:155 - Definition of Types for KDF Schemes (TypedefTable()) */
+UINT16
+TPMS_KDF_SCHEME_MGF1_Marshal(TPMS_KDF_SCHEME_MGF1 *source, BYTE **buffer, INT32 *size)
+{
+ UINT16 written = 0;
+ written += TPMS_SCHEME_HASH_Marshal(source, buffer, size);
+ return written;
+}
+UINT16
+TPMS_KDF_SCHEME_KDF1_SP800_56A_Marshal(TPMS_KDF_SCHEME_KDF1_SP800_56A *source, BYTE **buffer, INT32 *size)
+{
+ UINT16 written = 0;
+ written += TPMS_SCHEME_HASH_Marshal(source, buffer, size);
+ return written;
+}
+UINT16
+TPMS_KDF_SCHEME_KDF2_Marshal(TPMS_KDF_SCHEME_KDF2 *source, BYTE **buffer, INT32 *size)
+{
+ UINT16 written = 0;
+ written += TPMS_SCHEME_HASH_Marshal(source, buffer, size);
+ return written;
+}
+UINT16
+TPMS_KDF_SCHEME_KDF1_SP800_108_Marshal(TPMS_KDF_SCHEME_KDF1_SP800_108 *source, BYTE **buffer, INT32 *size)
+{
+ UINT16 written = 0;
+ written += TPMS_SCHEME_HASH_Marshal(source, buffer, size);
+ return written;
+}
+
+/* Table 2:156 - Definition of TPMU_KDF_SCHEME Union (StructuresTable()) */
+
+UINT16
+TPMU_KDF_SCHEME_Marshal(TPMU_KDF_SCHEME *source, BYTE **buffer, INT32 *size, UINT32 selector)
+{
+ UINT16 written = 0;
+
+
+ switch (selector) {
+#if ALG_MGF1
+ case TPM_ALG_MGF1:
+ written += TPMS_KDF_SCHEME_MGF1_Marshal(&source->mgf1, buffer, size);
+ break;
+#endif
+#if ALG_KDF1_SP800_56A
+ case TPM_ALG_KDF1_SP800_56A:
+ written += TPMS_KDF_SCHEME_KDF1_SP800_56A_Marshal(&source->kdf1_sp800_56a, buffer, size);
+ break;
+#endif
+#if ALG_KDF2
+ case TPM_ALG_KDF2:
+ written += TPMS_KDF_SCHEME_KDF2_Marshal(&source->kdf2, buffer, size);
+ break;
+#endif
+#if ALG_KDF1_SP800_108
+ case TPM_ALG_KDF1_SP800_108:
+ written += TPMS_KDF_SCHEME_KDF1_SP800_108_Marshal(&source->kdf1_sp800_108, buffer, size);
+ break;
+#endif
+ case TPM_ALG_NULL:
+ break;
+ default:
+ pAssert(FALSE);
+ }
+ return written;
+}
+
+/* Table 2:157 - Definition of TPMT_KDF_SCHEME Structure (StructuresTable()) */
+
+UINT16
+TPMT_KDF_SCHEME_Marshal(TPMT_KDF_SCHEME *source, BYTE **buffer, INT32 *size)
+{
+ UINT16 written = 0;
+
+ written += TPMI_ALG_KDF_Marshal(&source->scheme, buffer, size);
+ written += TPMU_KDF_SCHEME_Marshal(&source->details, buffer, size, source->scheme);
+ return written;
+}
+
+/* Table 2:159 - Definition of TPMU_ASYM_SCHEME Union (StructuresTable()) */
+
+UINT16
+TPMU_ASYM_SCHEME_Marshal(TPMU_ASYM_SCHEME *source, BYTE **buffer, INT32 *size, UINT32 selector)
+{
+ UINT16 written = 0;
+
+ switch (selector) {
+#if ALG_ECDH
+ case TPM_ALG_ECDH:
+ written += TPMS_KEY_SCHEME_ECDH_Marshal(&source->ecdh, buffer, size);
+ break;
+#endif
+#if ALG_ECMQV
+ case TPM_ALG_ECMQV:
+ written += TPMS_KEY_SCHEME_ECMQV_Marshal(&source->ecmqv, buffer, size);
+ break;
+#endif
+#if ALG_RSASSA
+ case TPM_ALG_RSASSA:
+ written += TPMS_SIG_SCHEME_RSASSA_Marshal(&source->rsassa, buffer, size);
+ break;
+#endif
+#if ALG_RSAPSS
+ case TPM_ALG_RSAPSS:
+ written += TPMS_SIG_SCHEME_RSAPSS_Marshal(&source->rsapss, buffer, size);
+ break;
+#endif
+#if ALG_ECDSA
+ case TPM_ALG_ECDSA:
+ written += TPMS_SIG_SCHEME_ECDSA_Marshal(&source->ecdsa, buffer, size);
+ break;
+#endif
+#if ALG_ECDAA
+ case TPM_ALG_ECDAA:
+ written += TPMS_SIG_SCHEME_ECDAA_Marshal(&source->ecdaa, buffer, size);
+ break;
+#endif
+#if ALG_SM2
+ case TPM_ALG_SM2:
+ written += TPMS_SIG_SCHEME_SM2_Marshal(&source->sm2, buffer, size);
+ break;
+#endif
+#if ALG_ECSCHNORR
+ case TPM_ALG_ECSCHNORR:
+ written += TPMS_SIG_SCHEME_ECSCHNORR_Marshal(&source->ecschnorr, buffer, size);
+ break;
+#endif
+#if ALG_RSAES
+ case TPM_ALG_RSAES:
+ written += TPMS_ENC_SCHEME_RSAES_Marshal(&source->rsaes, buffer, size);
+ break;
+#endif
+#if ALG_OAEP
+ case TPM_ALG_OAEP:
+ written += TPMS_ENC_SCHEME_OAEP_Marshal(&source->oaep, buffer, size);
+ break;
+#endif
+ case TPM_ALG_NULL:
+ break;
+ default:
+ pAssert(FALSE);
+ }
+ return written;
+}
+
+/* Table 2:161 - Definition of TPMI_ALG_RSA_SCHEME Type (InterfaceTable()) */
+
+UINT16
+TPMI_ALG_RSA_SCHEME_Marshal(TPMI_ALG_RSA_SCHEME *source, BYTE **buffer, INT32 *size)
+{
+ UINT16 written = 0;
+ written += TPM_ALG_ID_Marshal(source, buffer, size);
+ return written;
+}
+
+/* Table 2:162 - Definition of TPMT_RSA_SCHEME Structure (StructuresTable()) */
+
+UINT16
+TPMT_RSA_SCHEME_Marshal(TPMT_RSA_SCHEME *source, BYTE **buffer, INT32 *size)
+{
+ UINT16 written = 0;
+
+ written += TPMI_ALG_RSA_SCHEME_Marshal(&source->scheme, buffer, size);
+ written += TPMU_ASYM_SCHEME_Marshal(&source->details, buffer, size, source->scheme);
+ return written;
+}
+
+/* Table 2:165 - Definition of TPM2B_PUBLIC_KEY_RSA Structure (StructuresTable()) */
+
+UINT16
+TPM2B_PUBLIC_KEY_RSA_Marshal(TPM2B_PUBLIC_KEY_RSA *source, BYTE **buffer, INT32 *size)
+{
+ UINT16 written = 0;
+ written += TPM2B_Marshal(&source->b, sizeof(source->t.buffer), buffer, size); // libtpms changed
+ return written;
+}
+
+/* Table 2:166 - Definition of TPMI_RSA_KEY_BITS Type (InterfaceTable()) */
+
+UINT16
+TPMI_RSA_KEY_BITS_Marshal(TPMI_RSA_KEY_BITS *source, BYTE **buffer, INT32 *size)
+{
+ UINT16 written = 0;
+ written += TPM_KEY_BITS_Marshal(source, buffer, size);
+ return written;
+}
+
+/* Table 2:167 - Definition of TPM2B_PRIVATE_KEY_RSA Structure (StructuresTable()) */
+
+UINT16
+TPM2B_PRIVATE_KEY_RSA_Marshal(TPM2B_PRIVATE_KEY_RSA *source, BYTE **buffer, INT32 *size)
+{
+ UINT16 written = 0;
+ written += TPM2B_Marshal(&source->b, sizeof(source->t.buffer), buffer, size); // libtpms changed
+ return written;
+}
+
+/* Table 2:168 - Definition of TPM2B_ECC_PARAMETER Structure (StructuresTable()) */
+
+UINT16
+TPM2B_ECC_PARAMETER_Marshal(TPM2B_ECC_PARAMETER *source, BYTE **buffer, INT32 *size)
+{
+ UINT16 written = 0;
+ written += TPM2B_Marshal(&source->b, sizeof(source->t.buffer), buffer, size); // libtpms changed
+ return written;
+}
+
+/* Table 2:169 - Definition of TPMS_ECC_POINT Structure (StructuresTable()) */
+
+UINT16
+TPMS_ECC_POINT_Marshal(TPMS_ECC_POINT *source, BYTE **buffer, INT32 *size)
+{
+ UINT16 written = 0;
+
+ written += TPM2B_ECC_PARAMETER_Marshal(&source->x, buffer, size);
+ written += TPM2B_ECC_PARAMETER_Marshal(&source->y, buffer, size);
+ return written;
+}
+
+/* Table 2:170 - Definition of TPM2B_ECC_POINT Structure (StructuresTable()) */
+
+UINT16
+TPM2B_ECC_POINT_Marshal(TPM2B_ECC_POINT *source, BYTE **buffer, INT32 *size)
+{
+ UINT16 written = 0;
+ BYTE *sizePtr;
+
+ if (buffer != NULL) {
+ sizePtr = *buffer;
+ *buffer += sizeof(UINT16);
+ }
+ written += TPMS_ECC_POINT_Marshal(&source->point, buffer, size);
+ if (buffer != NULL) {
+ written += UINT16_Marshal(&written, &sizePtr, size);
+ }
+ else {
+ written += sizeof(UINT16);
+ }
+ return written;
+}
+
+/* Table 2:171 - Definition of TPMI_ALG_ECC_SCHEME Type (InterfaceTable()) */
+
+UINT16
+TPMI_ALG_ECC_SCHEME_Marshal(TPMI_ALG_ECC_SCHEME *source, BYTE **buffer, INT32 *size)
+{
+ UINT16 written = 0;
+ written += TPM_ALG_ID_Marshal(source, buffer, size);
+ return written;
+}
+
+/* Table 2:172 - Definition of TPMI_ECC_CURVE Type (InterfaceTable()) */
+
+UINT16
+TPMI_ECC_CURVE_Marshal(TPMI_ECC_CURVE *source, BYTE **buffer, INT32 *size)
+{
+ UINT16 written = 0;
+ written += TPM_ECC_CURVE_Marshal(source, buffer, size);
+ return written;
+}
+
+/* Table 2:173 - Definition of TPMT_ECC_SCHEME Structure (StructuresTable()) */
+
+UINT16
+TPMT_ECC_SCHEME_Marshal(TPMT_ECC_SCHEME *source, BYTE **buffer, INT32 *size)
+{
+ UINT16 written = 0;
+
+ written += TPMI_ALG_ECC_SCHEME_Marshal(&source->scheme, buffer, size);
+ written += TPMU_ASYM_SCHEME_Marshal(&source->details, buffer, size, source->scheme);
+ return written;
+}
+
+/* Table 2:174 - Definition of TPMS_ALGORITHM_DETAIL_ECC Structure (StructuresTable()) */
+
+UINT16
+TPMS_ALGORITHM_DETAIL_ECC_Marshal(TPMS_ALGORITHM_DETAIL_ECC *source, BYTE **buffer, INT32 *size)
+{
+ UINT16 written = 0;
+
+ written += TPM_ECC_CURVE_Marshal(&source->curveID, buffer, size);
+ written += UINT16_Marshal(&source->keySize, buffer, size);
+ written += TPMT_KDF_SCHEME_Marshal(&source->kdf, buffer, size);
+ written += TPMT_ECC_SCHEME_Marshal(&source->sign, buffer, size);
+ written += TPM2B_ECC_PARAMETER_Marshal(&source->p, buffer, size);
+ written += TPM2B_ECC_PARAMETER_Marshal(&source->a, buffer, size);
+ written += TPM2B_ECC_PARAMETER_Marshal(&source->b, buffer, size);
+ written += TPM2B_ECC_PARAMETER_Marshal(&source->gX, buffer, size);
+ written += TPM2B_ECC_PARAMETER_Marshal(&source->gY, buffer, size);
+ written += TPM2B_ECC_PARAMETER_Marshal(&source->n, buffer, size);
+ written += TPM2B_ECC_PARAMETER_Marshal(&source->h, buffer, size);
+ return written;
+}
+
+/* Table 2:175 - Definition of TPMS_SIGNATURE_RSA Structure (StructuresTable()) */
+
+UINT16
+TPMS_SIGNATURE_RSA_Marshal(TPMS_SIGNATURE_RSA *source, BYTE **buffer, INT32 *size)
+{
+ UINT16 written = 0;
+
+ written += TPMI_ALG_HASH_Marshal(&source->hash, buffer, size);
+ written += TPM2B_PUBLIC_KEY_RSA_Marshal(&source->sig, buffer, size);
+ return written;
+}
+
+/* Table 2:176 - Definition of Types for Signature (TypedefTable()) */
+UINT16
+TPMS_SIGNATURE_RSASSA_Marshal(TPMS_SIGNATURE_RSASSA *source, BYTE **buffer, INT32 *size)
+{
+ UINT16 written = 0;
+ written += TPMS_SIGNATURE_RSA_Marshal(source, buffer, size);
+ return written;
+}
+UINT16
+TPMS_SIGNATURE_RSAPSS_Marshal(TPMS_SIGNATURE_RSAPSS *source, BYTE **buffer, INT32 *size)
+{
+ UINT16 written = 0;
+ written += TPMS_SIGNATURE_RSA_Marshal(source, buffer, size);
+ return written;
+}
+
+/* Table 2:177 - Definition of TPMS_SIGNATURE_ECC Structure (StructuresTable()) */
+
+UINT16
+TPMS_SIGNATURE_ECC_Marshal(TPMS_SIGNATURE_ECC *source, BYTE **buffer, INT32 *size)
+{
+ UINT16 written = 0;
+
+ written += TPMI_ALG_HASH_Marshal(&source->hash, buffer, size);
+ written += TPM2B_ECC_PARAMETER_Marshal(&source->signatureR, buffer, size);
+ written += TPM2B_ECC_PARAMETER_Marshal(&source->signatureS, buffer, size);
+ return written;
+}
+
+/* Table 2:178 - Definition of Types for TPMS_SIGNATURE_ECC (TypedefTable()) */
+
+UINT16
+TPMS_SIGNATURE_ECDSA_Marshal(TPMS_SIGNATURE_ECDSA *source, BYTE **buffer, INT32 *size)
+{
+ UINT16 written = 0;
+ written += TPMS_SIGNATURE_ECC_Marshal(source, buffer, size);
+ return written;
+}
+
+UINT16
+TPMS_SIGNATURE_ECDAA_Marshal(TPMS_SIGNATURE_ECDAA *source, BYTE **buffer, INT32 *size)
+{
+ UINT16 written = 0;
+ written += TPMS_SIGNATURE_ECC_Marshal(source, buffer, size);
+ return written;
+}
+
+UINT16
+TPMS_SIGNATURE_SM2_Marshal(TPMS_SIGNATURE_SM2 *source, BYTE **buffer, INT32 *size)
+{
+ UINT16 written = 0;
+ written += TPMS_SIGNATURE_ECC_Marshal(source, buffer, size);
+ return written;
+}
+
+UINT16
+TPMS_SIGNATURE_ECSCHNORR_Marshal(TPMS_SIGNATURE_ECSCHNORR *source, BYTE **buffer, INT32 *size)
+{
+ UINT16 written = 0;
+ written += TPMS_SIGNATURE_ECC_Marshal(source, buffer, size);
+ return written;
+}
+
+/* Table 2:179 - Definition of TPMU_SIGNATURE Union (StructuresTable()) */
+UINT16
+TPMU_SIGNATURE_Marshal(TPMU_SIGNATURE *source, BYTE **buffer, INT32 *size, UINT32 selector)
+{
+ UINT16 written = 0;
+
+ switch (selector) {
+#if ALG_RSASSA
+ case TPM_ALG_RSASSA:
+ written += TPMS_SIGNATURE_RSASSA_Marshal(&source->rsassa, buffer, size);
+ break;
+#endif
+#if ALG_RSAPSS
+ case TPM_ALG_RSAPSS:
+ written += TPMS_SIGNATURE_RSAPSS_Marshal(&source->rsapss, buffer, size);
+ break;
+#endif
+#if ALG_ECDSA
+ case TPM_ALG_ECDSA:
+ written += TPMS_SIGNATURE_ECDSA_Marshal(&source->ecdsa, buffer, size);
+ break;
+#endif
+#if ALG_ECDAA
+ case TPM_ALG_ECDAA:
+ written += TPMS_SIGNATURE_ECDAA_Marshal(&source->ecdaa, buffer, size);
+ break;
+#endif
+#if ALG_SM2
+ case TPM_ALG_SM2:
+ written += TPMS_SIGNATURE_SM2_Marshal(&source->sm2, buffer, size);
+ break;
+#endif
+#if ALG_ECSCHNORR
+ case TPM_ALG_ECSCHNORR:
+ written += TPMS_SIGNATURE_ECSCHNORR_Marshal(&source->ecschnorr, buffer, size);
+ break;
+#endif
+#if ALG_HMAC
+ case TPM_ALG_HMAC:
+ written += TPMT_HA_Marshal(&source->hmac, buffer, size);
+ break;
+#endif
+ case TPM_ALG_NULL:
+ break;
+ default:
+ pAssert(FALSE);
+ }
+ return written;
+}
+
+/* Table 2:180 - Definition of TPMT_SIGNATURE Structure (StructuresTable()) */
+
+UINT16
+TPMT_SIGNATURE_Marshal(TPMT_SIGNATURE *source, BYTE **buffer, INT32 *size)
+{
+ UINT16 written = 0;
+
+ written += TPMI_ALG_SIG_SCHEME_Marshal(&source->sigAlg, buffer, size);
+ written += TPMU_SIGNATURE_Marshal(&source->signature, buffer, size, source->sigAlg);
+ return written;
+}
+
+/* Table 2:182 - Definition of TPM2B_ENCRYPTED_SECRET Structure (StructuresTable()) */
+
+UINT16
+TPM2B_ENCRYPTED_SECRET_Marshal(TPM2B_ENCRYPTED_SECRET *source, BYTE **buffer, INT32 *size)
+{
+ UINT16 written = 0;
+ written += TPM2B_Marshal(&source->b, sizeof(source->t.secret), buffer, size); // libtpms changed
+ return written;
+}
+
+/* Table 2:183 - Definition of TPMI_ALG_PUBLIC Type (InterfaceTable()) */
+
+
+UINT16
+TPMI_ALG_PUBLIC_Marshal(TPMI_ALG_PUBLIC *source, BYTE **buffer, INT32 *size)
+{
+ UINT16 written = 0;
+ written += TPM_ALG_ID_Marshal(source, buffer, size);
+ return written;
+}
+
+/* Table 2:184 - Definition of TPMU_PUBLIC_ID Union (StructuresTable()) */
+UINT16
+TPMU_PUBLIC_ID_Marshal(TPMU_PUBLIC_ID *source, BYTE **buffer, INT32 *size, UINT32 selector)
+{
+ UINT16 written = 0;
+
+ switch (selector) {
+#if ALG_KEYEDHASH
+ case TPM_ALG_KEYEDHASH:
+ written += TPM2B_DIGEST_Marshal(&source->keyedHash, buffer, size);
+ break;
+#endif
+#if ALG_SYMCIPHER
+ case TPM_ALG_SYMCIPHER:
+ written += TPM2B_DIGEST_Marshal(&source->sym, buffer, size);
+ break;
+#endif
+#if ALG_RSA
+ case TPM_ALG_RSA:
+ written += TPM2B_PUBLIC_KEY_RSA_Marshal(&source->rsa, buffer, size);
+ break;
+#endif
+#if ALG_ECC
+ case TPM_ALG_ECC:
+ written += TPMS_ECC_POINT_Marshal(&source->ecc, buffer, size);
+ break;
+#endif
+ default:
+ pAssert(FALSE);
+ }
+ return written;
+}
+
+/* Table 2:185 - Definition of TPMS_KEYEDHASH_PARMS Structure (StructuresTable()) */
+
+UINT16
+TPMS_KEYEDHASH_PARMS_Marshal(TPMS_KEYEDHASH_PARMS *source, BYTE **buffer, INT32 *size)
+{
+ UINT16 written = 0;
+ written += TPMT_KEYEDHASH_SCHEME_Marshal(&source->scheme, buffer, size);
+ return written;
+}
+
+/* Table 2:187 - Definition of TPMS_RSA_PARMS Structure (StructuresTable()) */
+
+UINT16
+TPMS_RSA_PARMS_Marshal(TPMS_RSA_PARMS *source, BYTE **buffer, INT32 *size)
+{
+ UINT16 written = 0;
+
+ written += TPMT_SYM_DEF_OBJECT_Marshal(&source->symmetric, buffer, size);
+ written += TPMT_RSA_SCHEME_Marshal(&source->scheme, buffer, size);
+ written += TPMI_RSA_KEY_BITS_Marshal(&source->keyBits, buffer, size);
+ written += UINT32_Marshal(&source->exponent, buffer, size);
+ return written;
+}
+
+/* Table 2:188 - Definition of TPMS_ECC_PARMS Structure (StructuresTable()) */
+
+UINT16
+TPMS_ECC_PARMS_Marshal(TPMS_ECC_PARMS *source, BYTE **buffer, INT32 *size)
+{
+ UINT16 written = 0;
+
+ written += TPMT_SYM_DEF_OBJECT_Marshal(&source->symmetric, buffer, size);
+ written += TPMT_ECC_SCHEME_Marshal(&source->scheme, buffer, size);
+ written += TPMI_ECC_CURVE_Marshal(&source->curveID, buffer, size);
+ written += TPMT_KDF_SCHEME_Marshal(&source->kdf, buffer, size);
+ return written;
+}
+
+/* Table 2:189 - Definition of TPMU_PUBLIC_PARMS Union (StructuresTable()) */
+
+UINT16
+TPMU_PUBLIC_PARMS_Marshal(TPMU_PUBLIC_PARMS *source, BYTE **buffer, INT32 *size, UINT32 selector)
+{
+ UINT16 written = 0;
+
+ switch (selector) {
+#if ALG_KEYEDHASH
+ case TPM_ALG_KEYEDHASH:
+ written += TPMS_KEYEDHASH_PARMS_Marshal(&source->keyedHashDetail, buffer, size);
+ break;
+#endif
+#if ALG_SYMCIPHER
+ case TPM_ALG_SYMCIPHER:
+ written += TPMS_SYMCIPHER_PARMS_Marshal(&source->symDetail, buffer, size);
+ break;
+#endif
+#if ALG_RSA
+ case TPM_ALG_RSA:
+ written += TPMS_RSA_PARMS_Marshal(&source->rsaDetail, buffer, size);
+ break;
+#endif
+#if ALG_ECC
+ case TPM_ALG_ECC:
+ written += TPMS_ECC_PARMS_Marshal(&source->eccDetail, buffer, size);
+ break;
+#endif
+ default:
+ pAssert(FALSE);
+ }
+ return written;
+}
+
+/* Table 2:191 - Definition of TPMT_PUBLIC Structure (StructuresTable()) */
+
+UINT16
+TPMT_PUBLIC_Marshal(TPMT_PUBLIC *source, BYTE **buffer, INT32 *size)
+{
+ UINT16 written = 0;
+ written += TPMI_ALG_PUBLIC_Marshal(&source->type, buffer, size);
+ written += TPMI_ALG_HASH_Marshal(&source->nameAlg, buffer, size);
+ written += TPMA_OBJECT_Marshal(&source->objectAttributes, buffer, size);
+ written += TPM2B_DIGEST_Marshal(&source->authPolicy, buffer, size);
+ written += TPMU_PUBLIC_PARMS_Marshal(&source->parameters, buffer, size, source->type);
+ written += TPMU_PUBLIC_ID_Marshal(&source->unique, buffer, size, source->type);
+ return written;
+}
+
+/* Table 2:192 - Definition of TPM2B_PUBLIC Structure (StructuresTable()) */
+
+UINT16
+TPM2B_PUBLIC_Marshal(TPM2B_PUBLIC *source, BYTE **buffer, INT32 *size)
+{
+ UINT16 written = 0;
+ BYTE *sizePtr = NULL; // libtpms changes for ppc64el gcc-5 -O3
+
+ if (buffer != NULL) {
+ sizePtr = *buffer;
+ *buffer += sizeof(UINT16);
+ }
+ written += TPMT_PUBLIC_Marshal(&source->publicArea, buffer, size);
+ if (buffer != NULL) {
+ written += UINT16_Marshal(&written, &sizePtr, size);
+ }
+ else {
+ written += sizeof(UINT16);
+ }
+ return written;
+}
+
+/* Table 2:195 - Definition of TPMU_SENSITIVE_COMPOSITE Union (StructuresTable()) */
+
+UINT16
+TPMU_SENSITIVE_COMPOSITE_Marshal(TPMU_SENSITIVE_COMPOSITE *source, BYTE **buffer, INT32 *size, UINT32 selector)
+{
+ UINT16 written = 0;
+
+ switch (selector) {
+#if ALG_RSA
+ case TPM_ALG_RSA:
+ written += TPM2B_PRIVATE_KEY_RSA_Marshal(&source->rsa, buffer, size);
+ break;
+#endif
+#if ALG_ECC
+ case TPM_ALG_ECC:
+ written += TPM2B_ECC_PARAMETER_Marshal(&source->ecc, buffer, size);
+ break;
+#endif
+#if ALG_KEYEDHASH
+ case TPM_ALG_KEYEDHASH:
+ written += TPM2B_SENSITIVE_DATA_Marshal(&source->bits, buffer, size);
+ break;
+#endif
+#if ALG_SYMCIPHER
+ case TPM_ALG_SYMCIPHER:
+ written += TPM2B_SYM_KEY_Marshal(&source->sym, buffer, size);
+ break;
+#endif
+ default:
+ pAssert(FALSE);
+ }
+ return written;
+}
+
+/* Table 2:196 - Definition of TPMT_SENSITIVE Structure (StructuresTable()) */
+
+UINT16
+TPMT_SENSITIVE_Marshal(TPMT_SENSITIVE *source, BYTE **buffer, INT32 *size)
+{
+ UINT16 written = 0;
+
+ written += TPMI_ALG_PUBLIC_Marshal(&source->sensitiveType, buffer, size);
+ written += TPM2B_AUTH_Marshal(&source->authValue, buffer, size);
+ written += TPM2B_DIGEST_Marshal(&source->seedValue, buffer, size);
+ written += TPMU_SENSITIVE_COMPOSITE_Marshal(&source->sensitive, buffer, size, source->sensitiveType);
+ return written;
+}
+
+/* Table 2:199 - Definition of TPM2B_PRIVATE Structure (StructuresTable()) */
+
+UINT16
+TPM2B_PRIVATE_Marshal(TPM2B_PRIVATE *source, BYTE **buffer, INT32 *size)
+{
+ UINT16 written = 0;
+ written += TPM2B_Marshal(&source->b, sizeof(source->t.buffer), buffer, size); // libtpms changed
+ return written;
+}
+
+/* Table 2:201 - Definition of TPM2B_ID_OBJECT Structure (StructuresTable()) */
+
+UINT16
+TPM2B_ID_OBJECT_Marshal(TPM2B_ID_OBJECT *source, BYTE **buffer, INT32 *size)
+{
+ UINT16 written = 0;
+ written += TPM2B_Marshal(&source->b, sizeof(source->t.credential), buffer, size); // libtpms changed
+ return written;
+}
+
+/* Table 2:205 - Definition of TPMA_NV Bits (BitsTable()) */
+
+UINT16
+TPMA_NV_Marshal(TPMA_NV *source, BYTE **buffer, INT32 *size)
+{
+ UINT16 written = 0;
+ written += UINT32_Marshal((UINT32 *)source, buffer, size); /* libtpms changed */
+ return written;
+}
+
+/* Table 2:206 - Definition of TPMS_NV_PUBLIC Structure (StructuresTable()) */
+
+UINT16
+TPMS_NV_PUBLIC_Marshal(TPMS_NV_PUBLIC *source, BYTE **buffer, INT32 *size)
+{
+ UINT16 written = 0;
+
+ written += TPMI_RH_NV_INDEX_Marshal(&source->nvIndex, buffer, size);
+ written += TPMI_ALG_HASH_Marshal(&source->nameAlg, buffer, size);
+ written += TPMA_NV_Marshal(&source->attributes, buffer, size);
+ written += TPM2B_DIGEST_Marshal(&source->authPolicy, buffer, size);
+ written += UINT16_Marshal(&source->dataSize, buffer, size);
+ return written;
+}
+
+/* Table 2:207 - Definition of TPM2B_NV_PUBLIC Structure (StructuresTable()) */
+
+UINT16
+TPM2B_NV_PUBLIC_Marshal(TPM2B_NV_PUBLIC *source, BYTE **buffer, INT32 *size)
+{
+ UINT16 written = 0;
+ BYTE *sizePtr;
+
+ if (buffer != NULL) {
+ sizePtr = *buffer;
+ *buffer += sizeof(UINT16);
+ }
+ written += TPMS_NV_PUBLIC_Marshal(&source->nvPublic, buffer, size);
+ if (buffer != NULL) {
+ written += UINT16_Marshal(&written, &sizePtr, size);
+ }
+ else {
+ written += sizeof(UINT16);
+ }
+ return written;
+}
+
+/* Table 2:210 - Definition of TPM2B_CONTEXT_DATA Structure (StructuresTable()) */
+
+UINT16
+TPM2B_CONTEXT_DATA_Marshal(TPM2B_CONTEXT_DATA *source, BYTE **buffer, INT32 *size)
+{
+ UINT16 written = 0;
+ written += TPM2B_Marshal(&source->b, sizeof(source->t.buffer), buffer, size); // libtpms changed
+ return written;
+}
+
+/* Table 2:211 - Definition of TPMS_CONTEXT Structure (StructuresTable()) */
+
+UINT16
+TPMS_CONTEXT_Marshal(TPMS_CONTEXT *source, BYTE **buffer, INT32 *size)
+{
+ UINT16 written = 0;
+
+ written += UINT64_Marshal(&source->sequence, buffer, size);
+ written += TPMI_DH_SAVED_Marshal(&source->savedHandle, buffer, size);
+ written += TPMI_RH_HIERARCHY_Marshal(&source->hierarchy, buffer, size);
+ written += TPM2B_CONTEXT_DATA_Marshal(&source->contextBlob, buffer, size);
+ return written;
+}
+
+/* Table 2:213 - Definition of TPMS_CREATION_DATA Structure (StructuresTable()) */
+
+UINT16
+TPMS_CREATION_DATA_Marshal(TPMS_CREATION_DATA *source, BYTE **buffer, INT32 *size)
+{
+ UINT16 written = 0;
+
+ written += TPML_PCR_SELECTION_Marshal(&source->pcrSelect, buffer, size);
+ written += TPM2B_DIGEST_Marshal(&source->pcrDigest, buffer, size);
+ written += TPMA_LOCALITY_Marshal(&source->locality, buffer, size);
+ written += TPM_ALG_ID_Marshal(&source->parentNameAlg, buffer, size);
+ written += TPM2B_NAME_Marshal(&source->parentName, buffer, size);
+ written += TPM2B_NAME_Marshal(&source->parentQualifiedName, buffer, size);
+ written += TPM2B_DATA_Marshal(&source->outsideInfo, buffer, size);
+ return written;
+}
+
+/* Table 2:214 - Definition of TPM2B_CREATION_DATA Structure (StructuresTable()) */
+
+UINT16
+TPM2B_CREATION_DATA_Marshal(TPM2B_CREATION_DATA *source, BYTE **buffer, INT32 *size)
+{
+ UINT16 written = 0;
+ BYTE *sizePtr = NULL; // libtpms added for s390x on Fedora 32
+
+ if (buffer != NULL) {
+ sizePtr = *buffer;
+ *buffer += sizeof(UINT16);
+ }
+ written += TPMS_CREATION_DATA_Marshal(&source->creationData, buffer, size);
+ if (buffer != NULL) {
+ written += UINT16_Marshal(&written, &sizePtr, size);
+ }
+ else {
+ written += sizeof(UINT16);
+ }
+ return written;
+}
+
+/* Table 225 - Definition of (UINT32) TPM_AT Constants */
+
+UINT16
+TPM_AT_Marshal(TPM_AT *source, BYTE **buffer, INT32 *size)
+{
+ UINT16 written = 0;
+ written += UINT32_Marshal(source, buffer, size);
+ return written;
+}
+
+/* Table 227 - Definition of TPMS_AC_OUTPUT Structure <OUT> */
+
+UINT16
+TPMS_AC_OUTPUT_Marshal(TPMS_AC_OUTPUT *source, BYTE **buffer, INT32 *size)
+{
+ UINT16 written = 0;
+
+ written += TPM_AT_Marshal(&source->tag, buffer, size);
+ written += UINT32_Marshal(&source->data, buffer, size);
+ return written;
+}
+
+/* Table 228 - Definition of TPML_AC_CAPABILITIES Structure <OUT> */
+
+UINT16
+TPML_AC_CAPABILITIES_Marshal(TPML_AC_CAPABILITIES *source, BYTE **buffer, INT32 *size)
+{
+ UINT16 written = 0;
+ UINT32 i;
+
+ written += UINT32_Marshal(&source->count, buffer, size);
+ for (i = 0 ; i < source->count ; i++) {
+ written += TPMS_AC_OUTPUT_Marshal(&source->acCapabilities[i], buffer, size);
+ }
+ return written;
+}
+
diff --git a/src/tpm2/Marshal_fp.h b/src/tpm2/Marshal_fp.h
new file mode 100644
index 0000000..d52f497
--- /dev/null
+++ b/src/tpm2/Marshal_fp.h
@@ -0,0 +1,400 @@
+/********************************************************************************/
+/* */
+/* Parameter Marshaling */
+/* Written by Ken Goldman */
+/* IBM Thomas J. Watson Research Center */
+/* $Id: Marshal_fp.h 1635 2020-06-12 21:48:27Z kgoldman $ */
+/* */
+/* Licenses and Notices */
+/* */
+/* 1. Copyright Licenses: */
+/* */
+/* - Trusted Computing Group (TCG) grants to the user of the source code in */
+/* this specification (the "Source Code") a worldwide, irrevocable, */
+/* nonexclusive, royalty free, copyright license to reproduce, create */
+/* derivative works, distribute, display and perform the Source Code and */
+/* derivative works thereof, and to grant others the rights granted herein. */
+/* */
+/* - The TCG grants to the user of the other parts of the specification */
+/* (other than the Source Code) the rights to reproduce, distribute, */
+/* display, and perform the specification solely for the purpose of */
+/* developing products based on such documents. */
+/* */
+/* 2. Source Code Distribution Conditions: */
+/* */
+/* - Redistributions of Source Code must retain the above copyright licenses, */
+/* this list of conditions and the following disclaimers. */
+/* */
+/* - Redistributions in binary form must reproduce the above copyright */
+/* licenses, this list of conditions and the following disclaimers in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* 3. Disclaimers: */
+/* */
+/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
+/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
+/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
+/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
+/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
+/* information on specification licensing rights available through TCG */
+/* membership agreements. */
+/* */
+/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
+/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
+/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
+/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
+/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
+/* */
+/* - Without limitation, TCG and its members and licensors disclaim all */
+/* liability, including liability for infringement of any proprietary */
+/* rights, relating to use of information in this specification and to the */
+/* implementation of this specification, and TCG disclaims all liability for */
+/* cost of procurement of substitute goods or services, lost profits, loss */
+/* of use, loss of data or any incidental, consequential, direct, indirect, */
+/* or special damages, whether under contract, tort, warranty or otherwise, */
+/* arising in any way out of use or reliance upon this specification or any */
+/* information herein. */
+/* */
+/* (c) Copyright IBM Corp. and others, 2016 - 2020 */
+/* */
+/********************************************************************************/
+
+#ifndef MARSHAL_FP_H
+#define MARSHAL_FP_H
+
+#include "TpmTypes.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+ UINT16
+ UINT8_Marshal(UINT8 *source, BYTE **buffer, INT32 *size);
+ UINT16
+ UINT16_Marshal(UINT16 *source, BYTE **buffer, INT32 *size);
+ UINT16
+ UINT32_Marshal(UINT32 *source, BYTE **buffer, INT32 *size);
+ UINT16
+ UINT64_Marshal(UINT64 *source, BYTE **buffer, INT32 *size);
+ UINT16
+ Array_Marshal(BYTE *sourceBuffer, UINT16 sourceSize, BYTE **buffer, INT32 *size);
+ UINT16
+ TPM2B_Marshal(TPM2B *source, UINT32 maxSize, BYTE **buffer, INT32 *size); // libtpms changed
+ UINT16
+ TPM_KEY_BITS_Marshal(TPM_KEY_BITS *source, BYTE **buffer, INT32 *size);
+ UINT16
+ TPM_CONSTANTS32_Marshal(TPM_CONSTANTS32 *source, BYTE **buffer, INT32 *size);
+ UINT16
+ TPM_ALG_ID_Marshal(TPM_ALG_ID *source, BYTE **buffer, INT32 *size);
+ UINT16
+ TPM_ECC_CURVE_Marshal(TPM_ECC_CURVE *source, BYTE **buffer, INT32 *size);
+ UINT16
+ TPM_CC_Marshal(TPM_CC *source, BYTE **buffer, INT32 *size);
+ UINT16
+ TPM_RC_Marshal(TPM_RC *source, BYTE **buffer, INT32 *size);
+ UINT16
+ TPM_ST_Marshal(TPM_ST *source, BYTE **buffer, INT32 *size);
+ INT16
+ TPM_CAP_Marshal(TPM_CAP *source, BYTE **buffer, INT32 *size);
+ UINT16
+ TPM_PT_Marshal(TPM_PT *source, BYTE **buffer, INT32 *size);
+ UINT16
+ TPM_PT_PCR_Marshal(TPM_PT_PCR *source, BYTE **buffer, INT32 *size);
+ UINT16
+ TPM_HANDLE_Marshal(TPM_HANDLE *source, BYTE **buffer, INT32 *size);
+ UINT16
+ TPMA_ALGORITHM_Marshal(TPMA_ALGORITHM *source, BYTE **buffer, INT32 *size);
+ UINT16
+ TPMA_OBJECT_Marshal(TPMA_OBJECT *source, BYTE **buffer, INT32 *size);
+ UINT16
+ TPMA_SESSION_Marshal(TPMA_SESSION *source, BYTE **buffer, INT32 *size);
+ UINT16
+ TPMA_LOCALITY_Marshal(TPMA_LOCALITY *source, BYTE **buffer, INT32 *size);
+ UINT16
+ TPMA_CC_Marshal(TPMA_CC *source, BYTE **buffer, INT32 *size);
+ UINT16
+ TPMI_YES_NO_Marshal(TPMI_YES_NO *source, BYTE **buffer, INT32 *size);
+ UINT16
+ TPMA_ACT_Marshal(TPMA_ACT *source, BYTE **buffer, INT32 *size);
+ UINT16
+ TPMI_DH_SAVED_Marshal(TPMI_DH_CONTEXT *source, BYTE **buffer, INT32 *size);
+ UINT16
+ TPMI_RH_HIERARCHY_Marshal(TPMI_RH_HIERARCHY *source, BYTE **buffer, INT32 *size);
+ UINT16
+ TPMI_RH_NV_INDEX_Marshal(TPMI_RH_NV_INDEX *source, BYTE **buffer, INT32 *size);
+ UINT16
+ TPMI_ALG_HASH_Marshal(TPMI_ALG_HASH *source, BYTE **buffer, INT32 *size);
+ UINT16
+ TPMI_ALG_SYM_OBJECT_Marshal(TPMI_ALG_SYM_OBJECT *source, BYTE **buffer, INT32 *size);
+ UINT16
+ TPMU_SYM_KEY_BITS_Marshal(TPMU_SYM_KEY_BITS *source, BYTE **buffer, INT32 *size, UINT32 selector);
+ UINT16
+ TPMI_ALG_SYM_MODE_Marshal(TPMI_ALG_SYM_MODE *source, BYTE **buffer, INT32 *size);
+ UINT16
+ TPMI_ALG_KDF_Marshal(TPMI_ALG_KDF *source, BYTE **buffer, INT32 *size);
+ UINT16
+ TPMI_ALG_SIG_SCHEME_Marshal(TPMI_ALG_SIG_SCHEME *source, BYTE **buffer, INT32 *size);
+ UINT16
+ TPMU_HA_Marshal(TPMU_HA *source, BYTE **buffer, INT32 *size, UINT32 selector);
+ UINT16
+ TPMT_HA_Marshal(TPMT_HA *source, BYTE **buffer, INT32 *size);
+ UINT16
+ TPM2B_DIGEST_Marshal(TPM2B_DIGEST *source, BYTE **buffer, INT32 *size);
+ UINT16
+ TPM2B_DATA_Marshal(TPM2B_DATA *source, BYTE **buffer, INT32 *size);
+ UINT16
+ TPM2B_NONCE_Marshal(TPM2B_NONCE *source, BYTE **buffer, INT32 *size);
+ UINT16
+ TPM2B_AUTH_Marshal(TPM2B_AUTH *source, BYTE **buffer, INT32 *size);
+ UINT16
+ TPM2B_MAX_BUFFER_Marshal(TPM2B_MAX_BUFFER *source, BYTE **buffer, INT32 *size);
+ UINT16
+ TPM2B_MAX_NV_BUFFER_Marshal(TPM2B_MAX_NV_BUFFER *source, BYTE **buffer, INT32 *size);
+ UINT16
+ TPM2B_TIMEOUT_Marshal(TPM2B_TIMEOUT *source, BYTE **buffer, INT32 *size);
+ UINT16
+ TPM2B_IV_Marshal(TPM2B_IV *source, BYTE **buffer, INT32 *size);
+ UINT16
+ TPM2B_NAME_Marshal(TPM2B_NAME *source, BYTE **buffer, INT32 *size);
+ UINT16
+ TPMS_PCR_SELECTION_Marshal(TPMS_PCR_SELECTION *source, BYTE **buffer, INT32 *size);
+ UINT16
+ TPMT_TK_CREATION_Marshal(TPMT_TK_CREATION *source, BYTE **buffer, INT32 *size);
+ UINT16
+ TPMT_TK_VERIFIED_Marshal(TPMT_TK_VERIFIED *source, BYTE **buffer, INT32 *size);
+ UINT16
+ TPMT_TK_AUTH_Marshal(TPMT_TK_AUTH *source, BYTE **buffer, INT32 *size);
+ UINT16
+ TPMT_TK_HASHCHECK_Marshal(TPMT_TK_HASHCHECK *source, BYTE **buffer, INT32 *size);
+ UINT16
+ TPMS_ALG_PROPERTY_Marshal(TPMS_ALG_PROPERTY *source, BYTE **buffer, INT32 *size);
+ UINT16
+ TPMS_TAGGED_PCR_SELECT_Marshal(TPMS_TAGGED_PCR_SELECT *source, BYTE **buffer, INT32 *size);
+ UINT16
+ TPMS_TAGGED_POLICY_Marshal(TPMS_TAGGED_POLICY *source, BYTE **buffer, INT32 *size);
+ UINT16
+ TPMS_ACT_DATA_Marshal(TPMS_ACT_DATA *source, BYTE **buffer, INT32 *size);
+ UINT16
+ TPMS_TAGGED_PROPERTY_Marshal(TPMS_TAGGED_PROPERTY *source, BYTE **buffer, INT32 *size);
+ UINT16
+ TPML_CC_Marshal(TPML_CC *source, BYTE **buffer, INT32 *size);
+ UINT16
+ TPML_CCA_Marshal(TPML_CCA *source, BYTE **buffer, INT32 *size);
+ UINT16
+ TPML_ALG_Marshal(TPML_ALG *source, BYTE **buffer, INT32 *size);
+ UINT16
+ TPML_DIGEST_Marshal(TPML_DIGEST *source, BYTE **buffer, INT32 *size);
+ UINT16
+ TPML_HANDLE_Marshal(TPML_HANDLE *source, BYTE **buffer, INT32 *size);
+ UINT16
+ TPML_DIGEST_VALUES_Marshal(TPML_DIGEST_VALUES *source, BYTE **buffer, INT32 *size);
+ UINT16
+ TPML_PCR_SELECTION_Marshal(TPML_PCR_SELECTION *source, BYTE **buffer, INT32 *size);
+ UINT16
+ TPML_ALG_PROPERTY_Marshal(TPML_ALG_PROPERTY *source, BYTE **buffer, INT32 *size);
+ UINT16
+ TPML_TAGGED_TPM_PROPERTY_Marshal(TPML_TAGGED_TPM_PROPERTY *source, BYTE **buffer, INT32 *size);
+ UINT16
+ TPML_TAGGED_PCR_PROPERTY_Marshal(TPML_TAGGED_PCR_PROPERTY *source, BYTE **buffer, INT32 *size);
+ UINT16
+ TPML_ECC_CURVE_Marshal(TPML_ECC_CURVE *source, BYTE **buffer, INT32 *size);
+ UINT16
+ TPML_TAGGED_POLICY_Marshal(TPML_TAGGED_POLICY *source, BYTE **buffer, INT32 *size);
+ UINT16
+ TPML_ACT_DATA_Marshal(TPML_ACT_DATA *source, BYTE **buffer, INT32 *size);
+ UINT16
+ TPMU_CAPABILITIES_Marshal(TPMU_CAPABILITIES *source, BYTE **buffer, INT32 *size, UINT32 selector);
+ UINT16
+ TPMS_CAPABILITY_DATA_Marshal(TPMS_CAPABILITY_DATA *source, BYTE **buffer, INT32 *size);
+ UINT16
+ TPMS_CLOCK_INFO_Marshal(TPMS_CLOCK_INFO *source, BYTE **buffer, INT32 *size);
+ UINT16
+ TPMS_TIME_INFO_Marshal(TPMS_TIME_INFO *source, BYTE **buffer, INT32 *size);
+ UINT16
+ TPMS_TIME_ATTEST_INFO_Marshal(TPMS_TIME_ATTEST_INFO *source, BYTE **buffer, INT32 *size);
+ UINT16
+ TPMS_CERTIFY_INFO_Marshal(TPMS_CERTIFY_INFO *source, BYTE **buffer, INT32 *size);
+ UINT16
+ TPMS_QUOTE_INFO_Marshal(TPMS_QUOTE_INFO *source, BYTE **buffer, INT32 *size);
+ UINT16
+ TPMS_COMMAND_AUDIT_INFO_Marshal(TPMS_COMMAND_AUDIT_INFO *source, BYTE **buffer, INT32 *size);
+ UINT16
+ TPMS_SESSION_AUDIT_INFO_Marshal(TPMS_SESSION_AUDIT_INFO *source, BYTE **buffer, INT32 *size);
+ UINT16
+ TPMS_CREATION_INFO_Marshal(TPMS_CREATION_INFO *source, BYTE **buffer, INT32 *size);
+ UINT16
+ TPMS_NV_CERTIFY_INFO_Marshal(TPMS_NV_CERTIFY_INFO *source, BYTE **buffer, INT32 *size);
+ UINT16
+ TPMS_NV_DIGEST_CERTIFY_INFO_Marshal(TPMS_NV_DIGEST_CERTIFY_INFO *source, BYTE **buffer, INT32 *size);
+ UINT16
+ TPM_ST_ATTEST_NV_DIGEST_Marshal(TPMS_NV_DIGEST_CERTIFY_INFO *source, BYTE **buffer, INT32 *size);
+ UINT16
+ TPMI_ST_ATTEST_Marshal(TPMI_ST_ATTEST *source, BYTE **buffer, INT32 *size);
+ UINT16
+ TPMU_ATTEST_Marshal(TPMU_ATTEST *source, BYTE **buffer, INT32 *size, UINT32 selector);
+ UINT16
+ TPMS_ATTEST_Marshal(TPMS_ATTEST *source, BYTE **buffer, INT32 *size);
+ UINT16
+ TPM2B_ATTEST_Marshal(TPM2B_ATTEST *source, BYTE **buffer, INT32 *size);
+ UINT16
+ TPMI_AES_KEY_BITS_Marshal(TPMI_AES_KEY_BITS *source, BYTE **buffer, INT32 *size);
+ UINT16 // libtpms added
+ TPMI_TDES_KEY_BITS_Marshal(TPMI_TDES_KEY_BITS *source, BYTE **buffer, INT32 *size);
+ UINT16
+ TPMI_CAMELLIA_KEY_BITS_Marshal(TPMI_CAMELLIA_KEY_BITS *source, BYTE **buffer, INT32 *size);
+ UINT16
+ TPMU_SYM_KEY_BITS_Marshal(TPMU_SYM_KEY_BITS *source, BYTE **buffer, INT32 *size, UINT32 selector);
+ UINT16
+ TPMU_SYM_MODE_Marshal(TPMU_SYM_MODE *source, BYTE **buffer, INT32 *size, UINT32 selector);
+ UINT16
+ TPMT_SYM_DEF_OBJECT_Marshal(TPMT_SYM_DEF_OBJECT *source, BYTE **buffer, INT32 *size);
+ UINT16
+ TPM2B_SYM_KEY_Marshal(TPM2B_SYM_KEY *source, BYTE **buffer, INT32 *size);
+ UINT16
+ TPMS_SYMCIPHER_PARMS_Marshal(TPMS_SYMCIPHER_PARMS *source, BYTE **buffer, INT32 *size);
+ UINT16
+ TPM2B_SENSITIVE_DATA_Marshal(TPM2B_SENSITIVE_DATA *source, BYTE **buffer, INT32 *size);
+ UINT16
+ TPMS_SCHEME_HASH_Marshal(TPMS_SCHEME_HASH *source, BYTE **buffer, INT32 *size);
+ UINT16
+ TPMS_SCHEME_ECDAA_Marshal(TPMS_SCHEME_ECDAA *source, BYTE **buffer, INT32 *size);
+ UINT16
+ TPMI_ALG_KEYEDHASH_SCHEME_Marshal(TPMI_ALG_KEYEDHASH_SCHEME *source, BYTE **buffer, INT32 *size);
+ UINT16
+ TPMS_SCHEME_HMAC_Marshal(TPMS_SCHEME_HMAC *source, BYTE **buffer, INT32 *size);
+ UINT16
+ TPMS_SCHEME_XOR_Marshal(TPMS_SCHEME_XOR *source, BYTE **buffer, INT32 *size);
+ UINT16
+ TPMT_KEYEDHASH_SCHEME_Marshal(TPMT_KEYEDHASH_SCHEME *source, BYTE **buffer, INT32 *size);
+ UINT16
+ TPMS_SIG_SCHEME_RSASSA_Marshal(TPMS_SIG_SCHEME_RSASSA *source, BYTE **buffer, INT32 *size);
+ UINT16
+ TPMS_SIG_SCHEME_RSAPSS_Marshal(TPMS_SIG_SCHEME_RSAPSS *source, BYTE **buffer, INT32 *size);
+ UINT16
+ TPMS_SIG_SCHEME_ECDSA_Marshal(TPMS_SIG_SCHEME_ECDSA *source, BYTE **buffer, INT32 *size);
+ UINT16
+ TPMS_SIG_SCHEME_SM2_Marshal(TPMS_SIG_SCHEME_SM2 *source, BYTE **buffer, INT32 *size);
+ UINT16
+ TPMS_SIG_SCHEME_ECSCHNORR_Marshal(TPMS_SIG_SCHEME_ECSCHNORR *source, BYTE **buffer, INT32 *size);
+ UINT16
+ TPMS_SIG_SCHEME_ECDAA_Marshal(TPMS_SIG_SCHEME_ECDAA *source, BYTE **buffer, INT32 *size);
+ UINT16
+ TPMS_ENC_SCHEME_OAEP_Marshal(TPMS_ENC_SCHEME_OAEP *source, BYTE **buffer, INT32 *size);
+ UINT16
+ TPMS_ENC_SCHEME_RSAES_Marshal(TPMS_ENC_SCHEME_RSAES *source, BYTE **buffer, INT32 *size);
+ UINT16
+ TPMU_SCHEME_KEYEDHASH_Marshal(TPMU_SCHEME_KEYEDHASH *source, BYTE **buffer, INT32 *size, UINT32 selector);
+ UINT16
+ TPMS_KEY_SCHEME_ECDH_Marshal(TPMS_KEY_SCHEME_ECDH *source, BYTE **buffer, INT32 *size);
+ UINT16
+ TPMS_KEY_SCHEME_ECMQV_Marshal(TPMS_KEY_SCHEME_ECMQV*source, BYTE **buffer, INT32 *size);
+ UINT16
+ TPMS_KDF_SCHEME_MGF1_Marshal(TPMS_KDF_SCHEME_MGF1 *source, BYTE **buffer, INT32 *size);
+ UINT16
+ TPMS_KDF_SCHEME_KDF1_SP800_56A_Marshal(TPMS_KDF_SCHEME_KDF1_SP800_56A *source, BYTE **buffer, INT32 *size);
+ UINT16
+ TPMS_KDF_SCHEME_KDF2_Marshal(TPMS_KDF_SCHEME_KDF2 *source, BYTE **buffer, INT32 *size);
+ UINT16
+ TPMS_KDF_SCHEME_KDF1_SP800_108_Marshal(TPMS_KDF_SCHEME_KDF1_SP800_108 *source, BYTE **buffer, INT32 *size);
+ UINT16
+ TPMU_KDF_SCHEME_Marshal(TPMU_KDF_SCHEME *source, BYTE **buffer, INT32 *size, UINT32 selector);
+ UINT16
+ TPMT_KDF_SCHEME_Marshal(TPMT_KDF_SCHEME *source, BYTE **buffer, INT32 *size);
+ UINT16
+ TPMU_ASYM_SCHEME_Marshal(TPMU_ASYM_SCHEME *source, BYTE **buffer, INT32 *size, UINT32 selector);
+ UINT16
+ TPMI_ALG_RSA_SCHEME_Marshal(TPMI_ALG_RSA_SCHEME *source, BYTE **buffer, INT32 *size);
+ UINT16
+ TPMT_RSA_SCHEME_Marshal(TPMT_RSA_SCHEME *source, BYTE **buffer, INT32 *size);
+ UINT16
+ TPM2B_PUBLIC_KEY_RSA_Marshal(TPM2B_PUBLIC_KEY_RSA *source, BYTE **buffer, INT32 *size);
+ UINT16
+ TPMI_RSA_KEY_BITS_Marshal(TPMI_RSA_KEY_BITS *source, BYTE **buffer, INT32 *size);
+ UINT16
+ TPM2B_PRIVATE_KEY_RSA_Marshal(TPM2B_PRIVATE_KEY_RSA *source, BYTE **buffer, INT32 *size);
+ UINT16
+ TPM2B_ECC_PARAMETER_Marshal(TPM2B_ECC_PARAMETER *source, BYTE **buffer, INT32 *size);
+ UINT16
+ TPMS_ECC_POINT_Marshal(TPMS_ECC_POINT *source, BYTE **buffer, INT32 *size);
+ UINT16
+ TPM2B_ECC_POINT_Marshal(TPM2B_ECC_POINT *source, BYTE **buffer, INT32 *size);
+ UINT16
+ TPMI_ALG_ECC_SCHEME_Marshal(TPMI_ALG_ECC_SCHEME *source, BYTE **buffer, INT32 *size);
+ UINT16
+ TPMI_ECC_CURVE_Marshal(TPMI_ECC_CURVE *source, BYTE **buffer, INT32 *size);
+ UINT16
+ TPMT_ECC_SCHEME_Marshal(TPMT_ECC_SCHEME *source, BYTE **buffer, INT32 *size);
+ UINT16
+ TPMS_ALGORITHM_DETAIL_ECC_Marshal(TPMS_ALGORITHM_DETAIL_ECC *source, BYTE **buffer, INT32 *size);
+ UINT16
+ TPMS_SIGNATURE_RSA_Marshal(TPMS_SIGNATURE_RSA *source, BYTE **buffer, INT32 *size);
+ UINT16
+ TPMS_SIGNATURE_RSASSA_Marshal(TPMS_SIGNATURE_RSASSA *source, BYTE **buffer, INT32 *size);
+ UINT16
+ TPMS_SIGNATURE_RSAPSS_Marshal(TPMS_SIGNATURE_RSAPSS *source, BYTE **buffer, INT32 *size);
+ UINT16
+ TPMS_SIGNATURE_ECC_Marshal(TPMS_SIGNATURE_ECC *source, BYTE **buffer, INT32 *size);
+ UINT16
+ TPMS_SIGNATURE_ECDSA_Marshal(TPMS_SIGNATURE_ECDSA *source, BYTE **buffer, INT32 *size);
+ UINT16
+ TPMS_SIGNATURE_ECDAA_Marshal(TPMS_SIGNATURE_ECDAA *source, BYTE **buffer, INT32 *size);
+ UINT16
+ TPMS_SIGNATURE_SM2_Marshal(TPMS_SIGNATURE_SM2 *source, BYTE **buffer, INT32 *size);
+ UINT16
+ TPMS_SIGNATURE_ECSCHNORR_Marshal(TPMS_SIGNATURE_ECSCHNORR *source, BYTE **buffer, INT32 *size);
+ UINT16
+ TPMU_SIGNATURE_Marshal(TPMU_SIGNATURE *source, BYTE **buffer, INT32 *size, UINT32 selector);
+ UINT16
+ TPMT_SIGNATURE_Marshal(TPMT_SIGNATURE *source, BYTE **buffer, INT32 *size);
+ UINT16
+ TPM2B_ENCRYPTED_SECRET_Marshal(TPM2B_ENCRYPTED_SECRET *source, BYTE **buffer, INT32 *size);
+ UINT16
+ TPMI_ALG_PUBLIC_Marshal(TPMI_ALG_PUBLIC *source, BYTE **buffer, INT32 *size);
+ UINT16
+ TPMU_PUBLIC_ID_Marshal(TPMU_PUBLIC_ID *source, BYTE **buffer, INT32 *size, UINT32 selector);
+ UINT16
+ TPMS_KEYEDHASH_PARMS_Marshal(TPMS_KEYEDHASH_PARMS *source, BYTE **buffer, INT32 *size);
+ UINT16
+ TPMS_RSA_PARMS_Marshal(TPMS_RSA_PARMS *source, BYTE **buffer, INT32 *size);
+ UINT16
+ TPMS_ECC_PARMS_Marshal(TPMS_ECC_PARMS *source, BYTE **buffer, INT32 *size);
+ UINT16
+ TPMU_PUBLIC_PARMS_Marshal(TPMU_PUBLIC_PARMS *source, BYTE **buffer, INT32 *size, UINT32 selector);
+ UINT16
+ TPMT_PUBLIC_Marshal(TPMT_PUBLIC *source, BYTE **buffer, INT32 *size);
+ UINT16
+ TPM2B_PUBLIC_Marshal(TPM2B_PUBLIC *source, BYTE **buffer, INT32 *size);
+ UINT16
+ TPMU_SENSITIVE_COMPOSITE_Marshal(TPMU_SENSITIVE_COMPOSITE *source, BYTE **buffer, INT32 *size, UINT32 selector);
+ UINT16
+ TPMT_SENSITIVE_Marshal(TPMT_SENSITIVE *source, BYTE **buffer, INT32 *size);
+ UINT16
+ TPM2B_PRIVATE_Marshal(TPM2B_PRIVATE *source, BYTE **buffer, INT32 *size);
+ UINT16
+ TPM2B_ID_OBJECT_Marshal(TPM2B_ID_OBJECT *source, BYTE **buffer, INT32 *size);
+ UINT16
+ TPMA_NV_Marshal(TPMA_NV *source, BYTE **buffer, INT32 *size);
+ UINT16
+ TPMS_NV_PUBLIC_Marshal(TPMS_NV_PUBLIC *source, BYTE **buffer, INT32 *size);
+ UINT16
+ TPM2B_NV_PUBLIC_Marshal(TPM2B_NV_PUBLIC *source, BYTE **buffer, INT32 *size);
+ UINT16
+ TPM2B_CONTEXT_DATA_Marshal(TPM2B_CONTEXT_DATA *source, BYTE **buffer, INT32 *size);
+ UINT16
+ TPMS_CONTEXT_Marshal(TPMS_CONTEXT *source, BYTE **buffer, INT32 *size);
+ UINT16
+ TPMS_CREATION_DATA_Marshal(TPMS_CREATION_DATA *source, BYTE **buffer, INT32 *size);
+ UINT16
+ TPM2B_CREATION_DATA_Marshal(TPM2B_CREATION_DATA *source, BYTE **buffer, INT32 *size);
+ UINT16
+ TPM_AT_Marshal(TPM_AT *source, BYTE **buffer, INT32 *size);
+ UINT16
+ TPMS_AC_OUTPUT_Marshal(TPMS_AC_OUTPUT *source, BYTE **buffer, INT32 *size);
+ UINT16
+ TPML_AC_CAPABILITIES_Marshal(TPML_AC_CAPABILITIES *source, BYTE **buffer, INT32 *size);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/src/tpm2/MathOnByteBuffers.c b/src/tpm2/MathOnByteBuffers.c
new file mode 100644
index 0000000..7a0b9da
--- /dev/null
+++ b/src/tpm2/MathOnByteBuffers.c
@@ -0,0 +1,266 @@
+/********************************************************************************/
+/* */
+/* Math functions performed with canonical integers in byte buffers */
+/* Written by Ken Goldman */
+/* IBM Thomas J. Watson Research Center */
+/* $Id: MathOnByteBuffers.c 1519 2019-11-15 20:43:51Z kgoldman $ */
+/* */
+/* Licenses and Notices */
+/* */
+/* 1. Copyright Licenses: */
+/* */
+/* - Trusted Computing Group (TCG) grants to the user of the source code in */
+/* this specification (the "Source Code") a worldwide, irrevocable, */
+/* nonexclusive, royalty free, copyright license to reproduce, create */
+/* derivative works, distribute, display and perform the Source Code and */
+/* derivative works thereof, and to grant others the rights granted herein. */
+/* */
+/* - The TCG grants to the user of the other parts of the specification */
+/* (other than the Source Code) the rights to reproduce, distribute, */
+/* display, and perform the specification solely for the purpose of */
+/* developing products based on such documents. */
+/* */
+/* 2. Source Code Distribution Conditions: */
+/* */
+/* - Redistributions of Source Code must retain the above copyright licenses, */
+/* this list of conditions and the following disclaimers. */
+/* */
+/* - Redistributions in binary form must reproduce the above copyright */
+/* licenses, this list of conditions and the following disclaimers in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* 3. Disclaimers: */
+/* */
+/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
+/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
+/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
+/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
+/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
+/* information on specification licensing rights available through TCG */
+/* membership agreements. */
+/* */
+/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
+/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
+/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
+/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
+/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
+/* */
+/* - Without limitation, TCG and its members and licensors disclaim all */
+/* liability, including liability for infringement of any proprietary */
+/* rights, relating to use of information in this specification and to the */
+/* implementation of this specification, and TCG disclaims all liability for */
+/* cost of procurement of substitute goods or services, lost profits, loss */
+/* of use, loss of data or any incidental, consequential, direct, indirect, */
+/* or special damages, whether under contract, tort, warranty or otherwise, */
+/* arising in any way out of use or reliance upon this specification or any */
+/* information herein. */
+/* */
+/* (c) Copyright IBM Corp. and others, 2016 - 2019 */
+/* */
+/********************************************************************************/
+
+/* 9.11 MathOnByteBuffers.c */
+/* 9.11.1 Introduction */
+/* This file contains implementation of the math functions that are performed with canonical
+ integers in byte buffers. The canonical integer is big-endian bytes. */
+#include "Tpm.h"
+/* 9.11.2.1 UnsignedCmpB */
+/* This function compare two unsigned values. The values are byte-aligned, big-endian numbers (e.g,
+ a hash). */
+/* Return Values Meaning */
+/* 1 if (a > b) */
+/* 0 if (a = b) */
+/* -1 if (a < b) */
+LIB_EXPORT int
+UnsignedCompareB(
+ UINT32 aSize, // IN: size of a
+ const BYTE *a, // IN: a
+ UINT32 bSize, // IN: size of b
+ const BYTE *b // IN: b
+ )
+{
+ UINT32 i;
+ if(aSize > bSize)
+ return 1;
+ else if(aSize < bSize)
+ return -1;
+ else
+ {
+ for(i = 0; i < aSize; i++)
+ {
+ if(a[i] != b[i])
+ return (a[i] > b[i]) ? 1 : -1;
+ }
+ }
+ return 0;
+}
+/* 9.11.2.2 SignedCompareB() */
+/* Compare two signed integers: */
+/* Return Values Meaning */
+/* 1 if a > b */
+/* 0 if a = b */
+/* -1 if a < b */
+int
+SignedCompareB(
+ const UINT32 aSize, // IN: size of a
+ const BYTE *a, // IN: a buffer
+ const UINT32 bSize, // IN: size of b
+ const BYTE *b // IN: b buffer
+ )
+{
+ int signA, signB; // sign of a and b
+ // For positive or 0, sign_a is 1
+ // for negative, sign_a is 0
+ signA = ((a[0] & 0x80) == 0) ? 1 : 0;
+ // For positive or 0, sign_b is 1
+ // for negative, sign_b is 0
+ signB = ((b[0] & 0x80) == 0) ? 1 : 0;
+ if(signA != signB)
+ {
+ return signA - signB;
+ }
+ if(signA == 1)
+ // do unsigned compare function
+ return UnsignedCompareB(aSize, a, bSize, b);
+ else
+ // do unsigned compare the other way
+ return 0 - UnsignedCompareB(aSize, a, bSize, b);
+}
+/* 9.11.3.3 ModExpB */
+/* This function is used to do modular exponentiation in support of RSA. The most typical uses are:
+ c = m^e mod n (RSA encrypt) and m = c^d mod n (RSA decrypt). When doing decryption, the e
+ parameter of the function will contain the private exponent d instead of the public exponent
+ e. */
+/* If the results will not fit in the provided buffer, an error is returned
+ (CRYPT_ERROR_UNDERFLOW). If the results is smaller than the buffer, the results is
+ de-normalized. */
+/* This version is intended for use with RSA and requires that m be less than n. */
+/* Error Returns Meaning */
+/* TPM_RC_SIZE number to exponentiate is larger than the modulus */
+/* TPM_RC_NO_RESULT result will not fit into the provided buffer */
+TPM_RC
+ModExpB(
+ UINT32 cSize, // IN: the size of the output buffer. It will
+ // need to be the same size as the modulus
+ BYTE *c, // OUT: the buffer to receive the results
+ // (c->size must be set to the maximum size
+ // for the returned value)
+ const UINT32 mSize,
+ const BYTE *m, // IN: number to exponentiate
+ const UINT32 eSize,
+ const BYTE *e, // IN: power
+ const UINT32 nSize,
+ const BYTE *n // IN: modulus
+ )
+{
+ BN_MAX(bnC);
+ BN_MAX(bnM);
+ BN_MAX(bnE);
+ BN_MAX(bnN);
+ NUMBYTES tSize = (NUMBYTES)nSize;
+ TPM_RC retVal = TPM_RC_SUCCESS;
+ // Convert input parameters
+ BnFromBytes(bnM, m, (NUMBYTES)mSize);
+ BnFromBytes(bnE, e, (NUMBYTES)eSize);
+ BnFromBytes(bnN, n, (NUMBYTES)nSize);
+ // Make sure that the output is big enough to hold the result
+ // and that 'm' is less than 'n' (the modulus)
+ if(cSize < nSize)
+ ERROR_RETURN(TPM_RC_NO_RESULT);
+ if(BnUnsignedCmp(bnM, bnN) >= 0)
+ ERROR_RETURN(TPM_RC_SIZE);
+ BnModExp(bnC, bnM, bnE, bnN);
+ BnToBytes(bnC, c, &tSize);
+ Exit:
+ return retVal;
+}
+/* 9.11.2.4 DivideB() */
+/* Divide an integer (n) by an integer (d) producing a quotient (q) and a remainder (r). If q or r
+ is not needed, then the pointer to them may be set to NULL. */
+/* Error Returns Meaning */
+/* TPM_RC_NO_RESULT q or r is too small to receive the result */
+LIB_EXPORT TPM_RC
+DivideB(
+ const TPM2B *n, // IN: numerator
+ const TPM2B *d, // IN: denominator
+ TPM2B *q, // OUT: quotient
+ TPM2B *r // OUT: remainder
+ )
+{
+ BN_MAX_INITIALIZED(bnN, n);
+ BN_MAX_INITIALIZED(bnD, d);
+ BN_MAX(bnQ);
+ BN_MAX(bnR);
+ //
+ // Do divide with converted values
+ BnDiv(bnQ, bnR, bnN, bnD);
+ // Convert the BIGNUM result back to 2B format using the size of the original
+ // number
+ if(q != NULL)
+ if(!BnTo2B(bnQ, q, q->size))
+ return TPM_RC_NO_RESULT;
+ if(r != NULL)
+ if(!BnTo2B(bnR, r, r->size))
+ return TPM_RC_NO_RESULT;
+ return TPM_RC_SUCCESS;
+}
+/* 9.11.2.5 AdjustNumberB() */
+/* Remove/add leading zeros from a number in a TPM2B. Will try to make the number by adding or
+ removing leading zeros. If the number is larger than the requested size, it will make the number
+ as small as possible. Setting requestedSize to zero is equivalent to requesting that the number
+ be normalized. */
+UINT16
+AdjustNumberB(
+ TPM2B *num,
+ UINT16 requestedSize
+ )
+{
+ BYTE *from;
+ UINT16 i;
+ // See if number is already the requested size
+ if(num->size == requestedSize)
+ return requestedSize;
+ from = num->buffer;
+ if (num->size > requestedSize)
+ {
+ // This is a request to shift the number to the left (remove leading zeros)
+ // Find the first non-zero byte. Don't look past the point where removing
+ // more zeros would make the number smaller than requested, and don't throw
+ // away any significant digits.
+ for(i = num->size; *from == 0 && i > requestedSize; from++, i--);
+ if(i < num->size)
+ {
+ num->size = i;
+ MemoryCopy(num->buffer, from, i);
+ }
+ }
+ // This is a request to shift the number to the right (add leading zeros)
+ else
+ {
+ MemoryCopy(&num->buffer[requestedSize - num->size], num->buffer, num->size);
+ MemorySet(num->buffer, 0, requestedSize- num->size);
+ num->size = requestedSize;
+ }
+ return num->size;
+}
+
+/* 9.11.2.6 ShiftLeft() */
+/* This function shifts a byte buffer (a TPM2B) one byte to the left. That is, the most significant
+ bit of the most significant byte is lost. */
+TPM2B *
+ShiftLeft(
+ TPM2B *value // IN/OUT: value to shift and shifted value out
+ )
+{
+ UINT16 count = value->size;
+ BYTE *buffer = value->buffer;
+ if(count > 0)
+ {
+ for(count -= 1; count > 0; buffer++, count--)
+ {
+ buffer[0] = (buffer[0] << 1) + ((buffer[1] & 0x80) ? 1 : 0);
+ }
+ *buffer <<= 1;
+ }
+ return value;
+}
diff --git a/src/tpm2/MathOnByteBuffers_fp.h b/src/tpm2/MathOnByteBuffers_fp.h
new file mode 100644
index 0000000..42f6112
--- /dev/null
+++ b/src/tpm2/MathOnByteBuffers_fp.h
@@ -0,0 +1,110 @@
+/********************************************************************************/
+/* */
+/* Math functions performed with canonical integers in byte buffers */
+/* Written by Ken Goldman */
+/* IBM Thomas J. Watson Research Center */
+/* $Id: MathOnByteBuffers_fp.h 1519 2019-11-15 20:43:51Z kgoldman $ */
+/* */
+/* Licenses and Notices */
+/* */
+/* 1. Copyright Licenses: */
+/* */
+/* - Trusted Computing Group (TCG) grants to the user of the source code in */
+/* this specification (the "Source Code") a worldwide, irrevocable, */
+/* nonexclusive, royalty free, copyright license to reproduce, create */
+/* derivative works, distribute, display and perform the Source Code and */
+/* derivative works thereof, and to grant others the rights granted herein. */
+/* */
+/* - The TCG grants to the user of the other parts of the specification */
+/* (other than the Source Code) the rights to reproduce, distribute, */
+/* display, and perform the specification solely for the purpose of */
+/* developing products based on such documents. */
+/* */
+/* 2. Source Code Distribution Conditions: */
+/* */
+/* - Redistributions of Source Code must retain the above copyright licenses, */
+/* this list of conditions and the following disclaimers. */
+/* */
+/* - Redistributions in binary form must reproduce the above copyright */
+/* licenses, this list of conditions and the following disclaimers in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* 3. Disclaimers: */
+/* */
+/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
+/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
+/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
+/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
+/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
+/* information on specification licensing rights available through TCG */
+/* membership agreements. */
+/* */
+/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
+/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
+/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
+/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
+/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
+/* */
+/* - Without limitation, TCG and its members and licensors disclaim all */
+/* liability, including liability for infringement of any proprietary */
+/* rights, relating to use of information in this specification and to the */
+/* implementation of this specification, and TCG disclaims all liability for */
+/* cost of procurement of substitute goods or services, lost profits, loss */
+/* of use, loss of data or any incidental, consequential, direct, indirect, */
+/* or special damages, whether under contract, tort, warranty or otherwise, */
+/* arising in any way out of use or reliance upon this specification or any */
+/* information herein. */
+/* */
+/* (c) Copyright IBM Corp. and others, 2016 - 2019 */
+/* */
+/********************************************************************************/
+
+#ifndef MATHONBYTEBUFFERS_FP_H
+#define MATHONBYTEBUFFERS_FP_H
+
+LIB_EXPORT int
+UnsignedCompareB(
+ UINT32 aSize, // IN: size of a
+ const BYTE *a, // IN: a
+ UINT32 bSize, // IN: size of b
+ const BYTE *b // IN: b
+ );
+int
+SignedCompareB(
+ const UINT32 aSize, // IN: size of a
+ const BYTE *a, // IN: a buffer
+ const UINT32 bSize, // IN: size of b
+ const BYTE *b // IN: b buffer
+ );
+TPM_RC
+ModExpB(
+ UINT32 cSize, // IN: the size of the output buffer. It will
+ // need to be the same size as the modulus
+ BYTE *c, // OUT: the buffer to receive the results
+ // (c->size must be set to the maximum size
+ // for the returned value)
+ const UINT32 mSize,
+ const BYTE *m, // IN: number to exponentiate
+ const UINT32 eSize,
+ const BYTE *e, // IN: power
+ const UINT32 nSize,
+ const BYTE *n // IN: modulus
+ );
+LIB_EXPORT TPM_RC
+DivideB(
+ const TPM2B *n, // IN: numerator
+ const TPM2B *d, // IN: denominator
+ TPM2B *q, // OUT: quotient
+ TPM2B *r // OUT: remainder
+ );
+UINT16
+AdjustNumberB(
+ TPM2B *num,
+ UINT16 requestedSize
+ );
+TPM2B *
+ShiftLeft(
+ TPM2B *value // IN/OUT: value to shift and shifted value out
+ );
+
+#endif
diff --git a/src/tpm2/Memory.c b/src/tpm2/Memory.c
new file mode 100644
index 0000000..e9472dd
--- /dev/null
+++ b/src/tpm2/Memory.c
@@ -0,0 +1,287 @@
+/********************************************************************************/
+/* */
+/* Miscellaneous Memory Manipulation Routines */
+/* Written by Ken Goldman */
+/* IBM Thomas J. Watson Research Center */
+/* $Id: Memory.c 1658 2021-01-22 23:14:01Z kgoldman $ */
+/* */
+/* Licenses and Notices */
+/* */
+/* 1. Copyright Licenses: */
+/* */
+/* - Trusted Computing Group (TCG) grants to the user of the source code in */
+/* this specification (the "Source Code") a worldwide, irrevocable, */
+/* nonexclusive, royalty free, copyright license to reproduce, create */
+/* derivative works, distribute, display and perform the Source Code and */
+/* derivative works thereof, and to grant others the rights granted herein. */
+/* */
+/* - The TCG grants to the user of the other parts of the specification */
+/* (other than the Source Code) the rights to reproduce, distribute, */
+/* display, and perform the specification solely for the purpose of */
+/* developing products based on such documents. */
+/* */
+/* 2. Source Code Distribution Conditions: */
+/* */
+/* - Redistributions of Source Code must retain the above copyright licenses, */
+/* this list of conditions and the following disclaimers. */
+/* */
+/* - Redistributions in binary form must reproduce the above copyright */
+/* licenses, this list of conditions and the following disclaimers in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* 3. Disclaimers: */
+/* */
+/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
+/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
+/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
+/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
+/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
+/* information on specification licensing rights available through TCG */
+/* membership agreements. */
+/* */
+/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
+/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
+/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
+/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
+/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
+/* */
+/* - Without limitation, TCG and its members and licensors disclaim all */
+/* liability, including liability for infringement of any proprietary */
+/* rights, relating to use of information in this specification and to the */
+/* implementation of this specification, and TCG disclaims all liability for */
+/* cost of procurement of substitute goods or services, lost profits, loss */
+/* of use, loss of data or any incidental, consequential, direct, indirect, */
+/* or special damages, whether under contract, tort, warranty or otherwise, */
+/* arising in any way out of use or reliance upon this specification or any */
+/* information herein. */
+/* */
+/* (c) Copyright IBM Corp. and others, 2016 - 2021 */
+/* */
+/********************************************************************************/
+
+/* 9.12 Memory.c */
+/* 9.12.1 Description */
+/* This file contains a set of miscellaneous memory manipulation routines. Many of the functions
+ have the same semantics as functions defined in string.h. Those functions are not used directly
+ in the TPM because they are not safe */
+/* This version uses string.h after adding guards. This is because the math libraries invariably
+ use those functions so it is not practical to prevent those library functions from being pulled
+ into the build. */
+/* 9.12.2 Includes and Data Definitions */
+#include "Tpm.h"
+#include "Memory_fp.h"
+/* 9.12.3 Functions */
+/* 9.12.3.1 MemoryCopy() */
+/* This is an alias for memmove. This is used in place of memcpy because some of the moves may
+ overlap and rather than try to make sure that memmove is used when necessary, it is always
+ used. */
+
+void
+MemoryCopy(
+ void *dest,
+ const void *src,
+ int sSize
+ )
+{
+ if (dest != src)
+ memmove(dest, src, sSize);
+}
+
+/* 9.12.3.2 MemoryEqual() */
+/* This function indicates if two buffers have the same values in the indicated number of bytes. */
+/* Return Values Meaning */
+/* TRUE all octets are the same */
+/* FALSE all octets are not the same */
+BOOL
+MemoryEqual(
+ const void *buffer1, // IN: compare buffer1
+ const void *buffer2, // IN: compare buffer2
+ unsigned int size // IN: size of bytes being compared
+ )
+{
+ BYTE equal = 0;
+ const BYTE *b1 = (BYTE *)buffer1;
+ const BYTE *b2 = (BYTE *)buffer2;
+ //
+ // Compare all bytes so that there is no leakage of information
+ // due to timing differences.
+ for(; size > 0; size--)
+ equal |= (*b1++ ^ *b2++);
+ return (equal == 0);
+}
+/* 9.12.3.3 MemoryCopy2B() */
+/* This function copies a TPM2B. This can be used when the TPM2B types are the same or different. */
+/* This function returns the number of octets in the data buffer of the TPM2B. */
+LIB_EXPORT INT16
+MemoryCopy2B(
+ TPM2B *dest, // OUT: receiving TPM2B
+ const TPM2B *source, // IN: source TPM2B
+ unsigned int dSize // IN: size of the receiving buffer
+ )
+{
+ pAssert(dest != NULL);
+ if(source == NULL)
+ dest->size = 0;
+ else
+ {
+ pAssert(source->size <= dSize);
+ MemoryCopy(dest->buffer, source->buffer, source->size);
+ dest->size = source->size;
+ }
+ return dest->size;
+}
+/* 9.12.3.4 MemoryConcat2B() */
+/* This function will concatenate the buffer contents of a TPM2B to the buffer contents of
+ another TPM2B and adjust the size accordingly (a := (a | b)). */
+void
+MemoryConcat2B(
+ TPM2B *aInOut, // IN/OUT: destination 2B
+ TPM2B *bIn, // IN: second 2B
+ unsigned int aMaxSize // IN: The size of aInOut.buffer (max values for
+ // aInOut.size)
+ )
+{
+ pAssert(bIn->size <= aMaxSize - aInOut->size);
+ MemoryCopy(&aInOut->buffer[aInOut->size], &bIn->buffer, bIn->size);
+ aInOut->size = aInOut->size + bIn->size;
+ return;
+}
+/* 9.12.3.5 MemoryEqual2B() */
+/* This function will compare two TPM2B structures. To be equal, they need to be the same size and
+ the buffer contexts need to be the same in all octets. */
+/* Return Values Meaning */
+/* TRUE size and buffer contents are the same */
+/* FALSE size or buffer contents are not the same */
+BOOL
+MemoryEqual2B(
+ const TPM2B *aIn, // IN: compare value
+ const TPM2B *bIn // IN: compare value
+ )
+{
+ if(aIn->size != bIn->size)
+ return FALSE;
+ return MemoryEqual(aIn->buffer, bIn->buffer, aIn->size);
+}
+/* 9.12.3.6 MemorySet() */
+/* This function will set all the octets in the specified memory range to the specified octet
+ value. */
+/* NOTE: A previous version had an additional parameter (dSize) that was intended to make sure that
+ the destination would not be overrun. The problem is that, in use, all that was happening was
+ that the value of size was used for dSize so there was no benefit in the extra parameter. */
+
+void
+MemorySet(
+ void *dest,
+ int value,
+ size_t size
+ )
+{
+ memset(dest, value, size);
+}
+
+/* 9.12.3.7 MemoryPad2B() */
+/* Function to pad a TPM2B with zeros and adjust the size. */
+
+void
+MemoryPad2B(
+ TPM2B *b,
+ UINT16 newSize
+ )
+{
+ MemorySet(&b->buffer[b->size], 0, newSize - b->size);
+ b->size = newSize;
+}
+
+/* 9.12.3.8 Uint16ToByteArray() */
+/* Function to write an integer to a byte array */
+
+void
+Uint16ToByteArray(
+ UINT16 i,
+ BYTE *a
+ )
+{
+ a[1] = (BYTE)(i); i >>= 8;
+ a[0] = (BYTE)(i);
+}
+
+/* 9.12.3.9 Uint32ToByteArray() */
+/* Function to write an integer to a byte array */
+
+void
+Uint32ToByteArray(
+ UINT32 i,
+ BYTE *a
+ )
+{
+ a[3] = (BYTE)(i); i >>= 8;
+ a[2] = (BYTE)(i); i >>= 8;
+ a[1] = (BYTE)(i); i >>= 8;
+ a[0] = (BYTE)(i);
+}
+
+/* 9.12.3.10 Uint64ToByteArray() */
+/* Function to write an integer to a byte array */
+
+void
+Uint64ToByteArray(
+ UINT64 i,
+ BYTE *a
+ )
+{
+ a[7] = (BYTE)(i); i >>= 8;
+ a[6] = (BYTE)(i); i >>= 8;
+ a[5] = (BYTE)(i); i >>= 8;
+ a[4] = (BYTE)(i); i >>= 8;
+ a[3] = (BYTE)(i); i >>= 8;
+ a[2] = (BYTE)(i); i >>= 8;
+ a[1] = (BYTE)(i); i >>= 8;
+ a[0] = (BYTE)(i);
+}
+
+/* 9.12.3.11 ByteArrayToUint8() */
+/* Function to write a UINT8 to a byte array. This is included for completeness and to allow certain
+ macro expansions */
+#if 0 // libtpms added
+UINT8
+ByteArrayToUint8(
+ BYTE *a
+ )
+{
+ return *a;
+}
+#endif // libtpms added
+
+/* 9.12.3.12 ByteArrayToUint16() */
+/* Function to write an integer to a byte array */
+
+UINT16
+ByteArrayToUint16(
+ BYTE *a
+ )
+{
+ return ((UINT16)a[0] << 8) + a[1];
+}
+
+/* 9.12.3.13 ByteArrayToUint32() */
+/* Function to write an integer to a byte array */
+
+UINT32
+ByteArrayToUint32(
+ BYTE *a
+ )
+{
+ return (UINT32)((((((UINT32)a[0] << 8) + a[1]) << 8) + (UINT32)a[2]) << 8) + a[3];
+}
+
+/* 9.12.3.14 ByteArrayToUint64() */
+/* Function to write an integer to a byte array */
+
+UINT64
+ByteArrayToUint64(
+ BYTE *a
+ )
+{
+ return (((UINT64)BYTE_ARRAY_TO_UINT32(a)) << 32) + BYTE_ARRAY_TO_UINT32(&a[4]);
+}
+
diff --git a/src/tpm2/Memory_fp.h b/src/tpm2/Memory_fp.h
new file mode 100644
index 0000000..082e8db
--- /dev/null
+++ b/src/tpm2/Memory_fp.h
@@ -0,0 +1,139 @@
+/********************************************************************************/
+/* */
+/* Miscellaneous Memory Manipulation Routines */
+/* Written by Ken Goldman */
+/* IBM Thomas J. Watson Research Center */
+/* $Id: Memory_fp.h 1476 2019-06-10 19:32:03Z kgoldman $ */
+/* */
+/* Licenses and Notices */
+/* */
+/* 1. Copyright Licenses: */
+/* */
+/* - Trusted Computing Group (TCG) grants to the user of the source code in */
+/* this specification (the "Source Code") a worldwide, irrevocable, */
+/* nonexclusive, royalty free, copyright license to reproduce, create */
+/* derivative works, distribute, display and perform the Source Code and */
+/* derivative works thereof, and to grant others the rights granted herein. */
+/* */
+/* - The TCG grants to the user of the other parts of the specification */
+/* (other than the Source Code) the rights to reproduce, distribute, */
+/* display, and perform the specification solely for the purpose of */
+/* developing products based on such documents. */
+/* */
+/* 2. Source Code Distribution Conditions: */
+/* */
+/* - Redistributions of Source Code must retain the above copyright licenses, */
+/* this list of conditions and the following disclaimers. */
+/* */
+/* - Redistributions in binary form must reproduce the above copyright */
+/* licenses, this list of conditions and the following disclaimers in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* 3. Disclaimers: */
+/* */
+/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
+/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
+/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
+/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
+/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
+/* information on specification licensing rights available through TCG */
+/* membership agreements. */
+/* */
+/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
+/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
+/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
+/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
+/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
+/* */
+/* - Without limitation, TCG and its members and licensors disclaim all */
+/* liability, including liability for infringement of any proprietary */
+/* rights, relating to use of information in this specification and to the */
+/* implementation of this specification, and TCG disclaims all liability for */
+/* cost of procurement of substitute goods or services, lost profits, loss */
+/* of use, loss of data or any incidental, consequential, direct, indirect, */
+/* or special damages, whether under contract, tort, warranty or otherwise, */
+/* arising in any way out of use or reliance upon this specification or any */
+/* information herein. */
+/* */
+/* (c) Copyright IBM Corp. and others, 2016 - 2019 */
+/* */
+/********************************************************************************/
+
+#ifndef MEMORY_FP_H
+#define MEMORY_FP_H
+
+void
+MemoryCopy(
+ void *dest,
+ const void *src,
+ int sSize
+ );
+BOOL
+MemoryEqual(
+ const void *buffer1, // IN: compare buffer1
+ const void *buffer2, // IN: compare buffer2
+ unsigned int size // IN: size of bytes being compared
+ );
+LIB_EXPORT INT16
+MemoryCopy2B(
+ TPM2B *dest, // OUT: receiving TPM2B
+ const TPM2B *source, // IN: source TPM2B
+ unsigned int dSize // IN: size of the receiving buffer
+ );
+void
+MemoryConcat2B(
+ TPM2B *aInOut, // IN/OUT: destination 2B
+ TPM2B *bIn, // IN: second 2B
+ unsigned int aMaxSize // IN: The size of aInOut.buffer (max values for
+ // aInOut.size)
+ );
+BOOL
+MemoryEqual2B(
+ const TPM2B *aIn, // IN: compare value
+ const TPM2B *bIn // IN: compare value
+ );
+void
+MemorySet(
+ void *dest,
+ int value,
+ size_t size
+ );
+void
+MemoryPad2B(
+ TPM2B *b,
+ UINT16 newSize
+ );
+void
+Uint16ToByteArray(
+ UINT16 i,
+ BYTE *a
+ );
+void
+Uint32ToByteArray(
+ UINT32 i,
+ BYTE *a
+ );
+void
+Uint64ToByteArray(
+ UINT64 i,
+ BYTE *a
+ );
+UINT8
+ByteArrayToUint8(
+ BYTE *a
+ );
+UINT16
+ByteArrayToUint16(
+ BYTE *a
+ );
+UINT32
+ByteArrayToUint32(
+ BYTE *a
+ );
+UINT64
+ByteArrayToUint64(
+ BYTE *a
+ );
+
+
+#endif
diff --git a/src/tpm2/MinMax.h b/src/tpm2/MinMax.h
new file mode 100644
index 0000000..db008a8
--- /dev/null
+++ b/src/tpm2/MinMax.h
@@ -0,0 +1,73 @@
+/********************************************************************************/
+/* */
+/* Min Max Macros */
+/* Written by Ken Goldman */
+/* IBM Thomas J. Watson Research Center */
+/* $Id: MinMax.h 1529 2019-11-21 23:29:01Z kgoldman $ */
+/* */
+/* Licenses and Notices */
+/* */
+/* 1. Copyright Licenses: */
+/* */
+/* - Trusted Computing Group (TCG) grants to the user of the source code in */
+/* this specification (the "Source Code") a worldwide, irrevocable, */
+/* nonexclusive, royalty free, copyright license to reproduce, create */
+/* derivative works, distribute, display and perform the Source Code and */
+/* derivative works thereof, and to grant others the rights granted herein. */
+/* */
+/* - The TCG grants to the user of the other parts of the specification */
+/* (other than the Source Code) the rights to reproduce, distribute, */
+/* display, and perform the specification solely for the purpose of */
+/* developing products based on such documents. */
+/* */
+/* 2. Source Code Distribution Conditions: */
+/* */
+/* - Redistributions of Source Code must retain the above copyright licenses, */
+/* this list of conditions and the following disclaimers. */
+/* */
+/* - Redistributions in binary form must reproduce the above copyright */
+/* licenses, this list of conditions and the following disclaimers in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* 3. Disclaimers: */
+/* */
+/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
+/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
+/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
+/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
+/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
+/* information on specification licensing rights available through TCG */
+/* membership agreements. */
+/* */
+/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
+/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
+/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
+/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
+/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
+/* */
+/* - Without limitation, TCG and its members and licensors disclaim all */
+/* liability, including liability for infringement of any proprietary */
+/* rights, relating to use of information in this specification and to the */
+/* implementation of this specification, and TCG disclaims all liability for */
+/* cost of procurement of substitute goods or services, lost profits, loss */
+/* of use, loss of data or any incidental, consequential, direct, indirect, */
+/* or special damages, whether under contract, tort, warranty or otherwise, */
+/* arising in any way out of use or reliance upon this specification or any */
+/* information herein. */
+/* */
+/* (c) Copyright IBM Corp. and others, 2019 */
+/* */
+/********************************************************************************/
+
+// 5.13 MinMax.h
+
+#ifndef _MIN_MAX_H_
+#define _MIN_MAX_H_
+#ifndef MAX
+#define MAX(a, b) ((a) > (b) ? (a) : (b))
+#endif
+#ifndef MIN
+#define MIN(a, b) ((a) < (b) ? (a) : (b))
+#endif
+#endif // _MIN_MAX_H_
+
diff --git a/src/tpm2/NV.h b/src/tpm2/NV.h
new file mode 100644
index 0000000..26218c0
--- /dev/null
+++ b/src/tpm2/NV.h
@@ -0,0 +1,162 @@
+/********************************************************************************/
+/* */
+/* */
+/* Written by Ken Goldman */
+/* IBM Thomas J. Watson Research Center */
+/* $Id: NV.h 1490 2019-07-26 21:13:22Z kgoldman $ */
+/* */
+/* Licenses and Notices */
+/* */
+/* 1. Copyright Licenses: */
+/* */
+/* - Trusted Computing Group (TCG) grants to the user of the source code in */
+/* this specification (the "Source Code") a worldwide, irrevocable, */
+/* nonexclusive, royalty free, copyright license to reproduce, create */
+/* derivative works, distribute, display and perform the Source Code and */
+/* derivative works thereof, and to grant others the rights granted herein. */
+/* */
+/* - The TCG grants to the user of the other parts of the specification */
+/* (other than the Source Code) the rights to reproduce, distribute, */
+/* display, and perform the specification solely for the purpose of */
+/* developing products based on such documents. */
+/* */
+/* 2. Source Code Distribution Conditions: */
+/* */
+/* - Redistributions of Source Code must retain the above copyright licenses, */
+/* this list of conditions and the following disclaimers. */
+/* */
+/* - Redistributions in binary form must reproduce the above copyright */
+/* licenses, this list of conditions and the following disclaimers in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* 3. Disclaimers: */
+/* */
+/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
+/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
+/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
+/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
+/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
+/* information on specification licensing rights available through TCG */
+/* membership agreements. */
+/* */
+/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
+/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
+/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
+/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
+/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
+/* */
+/* - Without limitation, TCG and its members and licensors disclaim all */
+/* liability, including liability for infringement of any proprietary */
+/* rights, relating to use of information in this specification and to the */
+/* implementation of this specification, and TCG disclaims all liability for */
+/* cost of procurement of substitute goods or services, lost profits, loss */
+/* of use, loss of data or any incidental, consequential, direct, indirect, */
+/* or special damages, whether under contract, tort, warranty or otherwise, */
+/* arising in any way out of use or reliance upon this specification or any */
+/* information herein. */
+/* */
+/* (c) Copyright IBM Corp. and others, 2016 - 2019 */
+/* */
+/********************************************************************************/
+
+#ifndef NV_H
+#define NV_H
+
+/* 5.14.1 Index Type Definitions */
+/* These definitions allow the same code to be used pre and post 1.21. The main action is to
+ redefine the index type values from the bit values. Use TPM_NT_ORDINARY to indicate if the TPM_NT
+ type is defined */
+#ifdef TPM_NT_ORDINARY
+/* If TPM_NT_ORDINARY is defined, then the TPM_NT field is present in a TPMA_NV */
+# define GET_TPM_NT(attributes) GET_ATTRIBUTE(attributes, TPMA_NV, TPM_NT)
+#else
+/* If TPM_NT_ORDINARY is not defined, then need to synthesize it from the attributes */
+# define GetNv_TPM_NV(attributes) \
+ ( IS_ATTRIBUTE(attributes, TPMA_NV, COUNTER) \
+ + (IS_ATTRIBUTE(attributes, TPMA_NV, BITS) << 1) \
+ + (IS_ATTRIBUTE(attributes, TPMA_NV, EXTEND) << 2) \
+ )
+# define TPM_NT_ORDINARY (0)
+# define TPM_NT_COUNTER (1)
+# define TPM_NT_BITS (2)
+# define TPM_NT_EXTEND (4)
+#endif
+/* 5.14.2 Attribute Macros */
+/* These macros are used to isolate the differences in the way that the index type changed in
+ version 1.21 of the specification */
+# define IsNvOrdinaryIndex(attributes) \
+ (GET_TPM_NT(attributes) == TPM_NT_ORDINARY)
+# define IsNvCounterIndex(attributes) \
+ (GET_TPM_NT(attributes) == TPM_NT_COUNTER)
+# define IsNvBitsIndex(attributes) \
+ (GET_TPM_NT(attributes) == TPM_NT_BITS)
+# define IsNvExtendIndex(attributes) \
+ (GET_TPM_NT(attributes) == TPM_NT_EXTEND)
+#ifdef TPM_NT_PIN_PASS
+# define IsNvPinPassIndex(attributes) \
+ (GET_TPM_NT(attributes) == TPM_NT_PIN_PASS)
+#endif
+#ifdef TPM_NT_PIN_FAIL
+# define IsNvPinFailIndex(attributes) \
+ (GET_TPM_NT(attributes) == TPM_NT_PIN_FAIL)
+#endif
+typedef struct {
+ UINT32 size;
+ TPM_HANDLE handle;
+} NV_ENTRY_HEADER;
+#define NV_EVICT_OBJECT_SIZE \
+ (sizeof(UINT32) + sizeof(TPM_HANDLE) + sizeof(OBJECT))
+#define NV_INDEX_COUNTER_SIZE \
+ (sizeof(UINT32) + sizeof(NV_INDEX) + sizeof(UINT64))
+#define NV_RAM_INDEX_COUNTER_SIZE \
+ (sizeof(NV_RAM_HEADER) + sizeof(UINT64))
+typedef struct {
+ UINT32 size;
+ TPM_HANDLE handle;
+ TPMA_NV attributes;
+} NV_RAM_HEADER;
+/* Defines the end-of-list marker for NV. The list terminator is a UINT32 of zero, followed by the
+ current value of s_maxCounter which is a 64-bit value. The structure is defined as an array of 3
+ UINT32 values so that there is no padding between the UINT32 list end marker and the UINT64
+ maxCounter value. */
+typedef UINT32 NV_LIST_TERMINATOR[3];
+/* 5.14.3 Orderly RAM Values */
+/* The following defines are for accessing orderly RAM values. This is the initialize for the RAM
+ reference iterator. */
+#define NV_RAM_REF_INIT 0
+/* This is the starting address of the RAM space used for orderly data */
+#define RAM_ORDERLY_START \
+ (&s_indexOrderlyRam[0])
+/* This is the offset within NV that is used to save the orderly data on an orderly shutdown. */
+#define NV_ORDERLY_START \
+ (NV_INDEX_RAM_DATA)
+/* This is the end of the orderly RAM space. It is actually the first byte after the last byte of
+ orderly RAM data */
+#define RAM_ORDERLY_END \
+ (RAM_ORDERLY_START + sizeof(s_indexOrderlyRam))
+/* This is the end of the orderly space in NV memory. As with RAM_ORDERLY_END, it is actually the
+ offset of the first byte after the end of the NV orderly data. */
+#define NV_ORDERLY_END \
+ (NV_ORDERLY_START + sizeof(s_indexOrderlyRam))
+/* Macro to check that an orderly RAM address is with range. */
+#define ORDERLY_RAM_ADDRESS_OK(start, offset) \
+ ((start >= RAM_ORDERLY_START) && ((start + offset - 1) < RAM_ORDERLY_END))
+#define RETURN_IF_NV_IS_NOT_AVAILABLE \
+ { \
+ if(g_NvStatus != TPM_RC_SUCCESS) \
+ return g_NvStatus; \
+ }
+/* Routinely have to clear the orderly flag and fail if the NV is not available so that it can be
+ cleared. */
+#define RETURN_IF_ORDERLY \
+ { \
+ if(NvClearOrderly() != TPM_RC_SUCCESS) \
+ return g_NvStatus; \
+ }
+#define NV_IS_AVAILABLE (g_NvStatus == TPM_RC_SUCCESS)
+#define IS_ORDERLY(value) (value < SU_DA_USED_VALUE)
+#define NV_IS_ORDERLY (IS_ORDERLY(gp.orderlyState))
+/* Macro to set the NV UPDATE_TYPE. This deals with the fact that the update is possibly a
+ combination of UT_NV and UT_ORDERLY. */
+#define SET_NV_UPDATE(type) g_updateNV |= (type)
+#endif // _NV_H_
diff --git a/src/tpm2/NVCommands.c b/src/tpm2/NVCommands.c
new file mode 100644
index 0000000..6908a14
--- /dev/null
+++ b/src/tpm2/NVCommands.c
@@ -0,0 +1,707 @@
+/********************************************************************************/
+/* */
+/* Non-Volatile Storage */
+/* Written by Ken Goldman */
+/* IBM Thomas J. Watson Research Center */
+/* $Id: NVCommands.c 1490 2019-07-26 21:13:22Z kgoldman $ */
+/* */
+/* Licenses and Notices */
+/* */
+/* 1. Copyright Licenses: */
+/* */
+/* - Trusted Computing Group (TCG) grants to the user of the source code in */
+/* this specification (the "Source Code") a worldwide, irrevocable, */
+/* nonexclusive, royalty free, copyright license to reproduce, create */
+/* derivative works, distribute, display and perform the Source Code and */
+/* derivative works thereof, and to grant others the rights granted herein. */
+/* */
+/* - The TCG grants to the user of the other parts of the specification */
+/* (other than the Source Code) the rights to reproduce, distribute, */
+/* display, and perform the specification solely for the purpose of */
+/* developing products based on such documents. */
+/* */
+/* 2. Source Code Distribution Conditions: */
+/* */
+/* - Redistributions of Source Code must retain the above copyright licenses, */
+/* this list of conditions and the following disclaimers. */
+/* */
+/* - Redistributions in binary form must reproduce the above copyright */
+/* licenses, this list of conditions and the following disclaimers in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* 3. Disclaimers: */
+/* */
+/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
+/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
+/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
+/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
+/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
+/* information on specification licensing rights available through TCG */
+/* membership agreements. */
+/* */
+/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
+/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
+/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
+/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
+/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
+/* */
+/* - Without limitation, TCG and its members and licensors disclaim all */
+/* liability, including liability for infringement of any proprietary */
+/* rights, relating to use of information in this specification and to the */
+/* implementation of this specification, and TCG disclaims all liability for */
+/* cost of procurement of substitute goods or services, lost profits, loss */
+/* of use, loss of data or any incidental, consequential, direct, indirect, */
+/* or special damages, whether under contract, tort, warranty or otherwise, */
+/* arising in any way out of use or reliance upon this specification or any */
+/* information herein. */
+/* */
+/* (c) Copyright IBM Corp. and others, 2016 - 2019 */
+/* */
+/********************************************************************************/
+
+#include "Tpm.h"
+#include "NV_DefineSpace_fp.h"
+#if CC_NV_DefineSpace // Conditional expansion of this file
+TPM_RC
+TPM2_NV_DefineSpace(
+ NV_DefineSpace_In *in // IN: input parameter list
+ )
+{
+ TPMA_NV attributes = in->publicInfo.nvPublic.attributes;
+ UINT16 nameSize;
+ nameSize = CryptHashGetDigestSize(in->publicInfo.nvPublic.nameAlg);
+ // Input Validation
+ // Checks not specific to type
+ // If the UndefineSpaceSpecial command is not implemented, then can't have
+ // an index that can only be deleted with policy
+#if CC_NV_UndefineSpaceSpecial == NO
+ if(IS_ATTRIBUTE(attributes, TPMA_NV, POLICY_DELETE))
+ return TPM_RCS_ATTRIBUTES + RC_NV_DefineSpace_publicInfo;
+#endif
+ // check that the authPolicy consistent with hash algorithm
+ if(in->publicInfo.nvPublic.authPolicy.t.size != 0
+ && in->publicInfo.nvPublic.authPolicy.t.size != nameSize)
+ return TPM_RCS_SIZE + RC_NV_DefineSpace_publicInfo;
+ // make sure that the authValue is not too large
+ if(MemoryRemoveTrailingZeros(&in->auth)
+ > CryptHashGetDigestSize(in->publicInfo.nvPublic.nameAlg))
+ return TPM_RCS_SIZE + RC_NV_DefineSpace_auth;
+ // If an index is being created by the owner and shEnable is
+ // clear, then we would not reach this point because ownerAuth
+ // can't be given when shEnable is CLEAR. However, if phEnable
+ // is SET but phEnableNV is CLEAR, we have to check here
+ if(in->authHandle == TPM_RH_PLATFORM && gc.phEnableNV == CLEAR)
+ return TPM_RCS_HIERARCHY + RC_NV_DefineSpace_authHandle;
+ // Attribute checks
+ // Eliminate the unsupported types
+ switch(GET_TPM_NT(attributes))
+ {
+#if CC_NV_Increment == YES
+ case TPM_NT_COUNTER:
+#endif
+#if CC_NV_SetBits == YES
+ case TPM_NT_BITS:
+#endif
+#if CC_NV_Extend == YES
+ case TPM_NT_EXTEND:
+#endif
+#if CC_PolicySecret == YES && defined TPM_NT_PIN_PASS
+ case TPM_NT_PIN_PASS:
+ case TPM_NT_PIN_FAIL:
+#endif
+ case TPM_NT_ORDINARY:
+ break;
+ default:
+ return TPM_RCS_ATTRIBUTES + RC_NV_DefineSpace_publicInfo;
+ break;
+ }
+ // Check that the sizes are OK based on the type
+ switch(GET_TPM_NT(attributes))
+ {
+ case TPM_NT_ORDINARY:
+ // Can't exceed the allowed size for the implementation
+ if(in->publicInfo.nvPublic.dataSize > MAX_NV_INDEX_SIZE)
+ return TPM_RCS_SIZE + RC_NV_DefineSpace_publicInfo;
+ break;
+ case TPM_NT_EXTEND:
+ if(in->publicInfo.nvPublic.dataSize != nameSize)
+ return TPM_RCS_SIZE + RC_NV_DefineSpace_publicInfo;
+ break;
+ default:
+ // Everything else needs a size of 8
+ if(in->publicInfo.nvPublic.dataSize != 8)
+ return TPM_RCS_SIZE + RC_NV_DefineSpace_publicInfo;
+ break;
+ }
+ // Handle other specifics
+ switch(GET_TPM_NT(attributes))
+ {
+ case TPM_NT_COUNTER:
+ // Counter can't have TPMA_NV_CLEAR_STCLEAR SET (don't clear counters)
+ if(IS_ATTRIBUTE(attributes, TPMA_NV, CLEAR_STCLEAR))
+ return TPM_RCS_ATTRIBUTES + RC_NV_DefineSpace_publicInfo;
+ break;
+#ifdef TPM_NT_PIN_FAIL
+ case TPM_NT_PIN_FAIL:
+ // NV_NO_DA must be SET and AUTHWRITE must be CLEAR
+ // NOTE: As with a PIN_PASS index, the authValue of the index is not
+ // available until the index is written. If AUTHWRITE is the only way to
+ // write then index, it could never be written. Rather than go through
+ // all of the other possible ways to write the Index, it is simply
+ // prohibited to write the index with the authValue. Other checks
+ // below will insure that there seems to be a way to write the index
+ // (i.e., with platform authorization , owner authorization,
+ // or with policyAuth.)
+ // It is not allowed to create a PIN Index that can't be modified.
+ if(!IS_ATTRIBUTE(attributes, TPMA_NV, NO_DA))
+ return TPM_RCS_ATTRIBUTES + RC_NV_DefineSpace_publicInfo;
+ /* fall through */
+#endif
+#ifdef TPM_NT_PIN_PASS
+ case TPM_NT_PIN_PASS:
+ // AUTHWRITE must be CLEAR (see note above to TPM_NT_PIN_FAIL)
+ if(IS_ATTRIBUTE(attributes, TPMA_NV, AUTHWRITE)
+ || IS_ATTRIBUTE(attributes, TPMA_NV, GLOBALLOCK)
+ || IS_ATTRIBUTE(attributes, TPMA_NV, WRITEDEFINE))
+ return TPM_RCS_ATTRIBUTES + RC_NV_DefineSpace_publicInfo;
+#endif // this comes before break because PIN_FAIL falls through
+ break;
+ default:
+ break;
+ }
+ // Locks may not be SET and written cannot be SET
+ if(IS_ATTRIBUTE(attributes, TPMA_NV, WRITTEN)
+ || IS_ATTRIBUTE(attributes, TPMA_NV, WRITELOCKED)
+ || IS_ATTRIBUTE(attributes, TPMA_NV, READLOCKED))
+ return TPM_RCS_ATTRIBUTES + RC_NV_DefineSpace_publicInfo;
+ // There must be a way to read the index.
+ if(!IS_ATTRIBUTE(attributes, TPMA_NV, OWNERREAD)
+ && !IS_ATTRIBUTE(attributes, TPMA_NV, PPREAD)
+ && !IS_ATTRIBUTE(attributes, TPMA_NV, AUTHREAD)
+ && !IS_ATTRIBUTE(attributes, TPMA_NV, POLICYREAD))
+ return TPM_RCS_ATTRIBUTES + RC_NV_DefineSpace_publicInfo;
+ // There must be a way to write the index
+ if(!IS_ATTRIBUTE(attributes, TPMA_NV, OWNERWRITE)
+ && !IS_ATTRIBUTE(attributes, TPMA_NV, PPWRITE)
+ && !IS_ATTRIBUTE(attributes, TPMA_NV, AUTHWRITE)
+ && !IS_ATTRIBUTE(attributes, TPMA_NV, POLICYWRITE))
+ return TPM_RCS_ATTRIBUTES + RC_NV_DefineSpace_publicInfo;
+ // An index with TPMA_NV_CLEAR_STCLEAR can't have TPMA_NV_WRITEDEFINE SET
+ if(IS_ATTRIBUTE(attributes, TPMA_NV, CLEAR_STCLEAR)
+ && IS_ATTRIBUTE(attributes, TPMA_NV, WRITEDEFINE))
+ return TPM_RCS_ATTRIBUTES + RC_NV_DefineSpace_publicInfo;
+ // Make sure that the creator of the index can delete the index
+ if((IS_ATTRIBUTE(attributes, TPMA_NV, PLATFORMCREATE)
+ && in->authHandle == TPM_RH_OWNER)
+ || (!IS_ATTRIBUTE(attributes, TPMA_NV, PLATFORMCREATE)
+ && in->authHandle == TPM_RH_PLATFORM))
+ return TPM_RCS_ATTRIBUTES + RC_NV_DefineSpace_authHandle;
+ // If TPMA_NV_POLICY_DELETE is SET, then the index must be defined by
+ // the platform
+ if(IS_ATTRIBUTE(attributes, TPMA_NV, POLICY_DELETE)
+ && TPM_RH_PLATFORM != in->authHandle)
+ return TPM_RCS_ATTRIBUTES + RC_NV_DefineSpace_publicInfo;
+ // Make sure that the TPMA_NV_WRITEALL is not set if the index size is larger
+ // than the allowed NV buffer size.
+ if(in->publicInfo.nvPublic.dataSize > MAX_NV_BUFFER_SIZE
+ && IS_ATTRIBUTE(attributes, TPMA_NV, WRITEALL))
+ return TPM_RCS_SIZE + RC_NV_DefineSpace_publicInfo;
+ // And finally, see if the index is already defined.
+ if(NvIndexIsDefined(in->publicInfo.nvPublic.nvIndex))
+ return TPM_RC_NV_DEFINED;
+ // Internal Data Update
+ // define the space. A TPM_RC_NV_SPACE error may be returned at this point
+ return NvDefineIndex(&in->publicInfo.nvPublic, &in->auth);
+}
+#endif // CC_NV_DefineSpace
+#include "Tpm.h"
+#include "NV_UndefineSpace_fp.h"
+#if CC_NV_UndefineSpace // Conditional expansion of this file
+TPM_RC
+TPM2_NV_UndefineSpace(
+ NV_UndefineSpace_In *in // IN: input parameter list
+ )
+{
+ NV_REF locator;
+ NV_INDEX *nvIndex = NvGetIndexInfo(in->nvIndex, &locator);
+ // Input Validation
+ // This command can't be used to delete an index with TPMA_NV_POLICY_DELETE SET
+ if(IS_ATTRIBUTE(nvIndex->publicArea.attributes, TPMA_NV, POLICY_DELETE))
+ return TPM_RCS_ATTRIBUTES + RC_NV_UndefineSpace_nvIndex;
+ // The owner may only delete an index that was defined with ownerAuth. The
+ // platform may delete an index that was created with either authorization.
+ if(in->authHandle == TPM_RH_OWNER
+ && IS_ATTRIBUTE(nvIndex->publicArea.attributes, TPMA_NV, PLATFORMCREATE))
+ return TPM_RC_NV_AUTHORIZATION;
+ // Internal Data Update
+ // Call implementation dependent internal routine to delete NV index
+ return NvDeleteIndex(nvIndex, locator);
+}
+#endif // CC_NV_UndefineSpace
+#include "Tpm.h"
+#include "NV_UndefineSpaceSpecial_fp.h"
+#include "SessionProcess_fp.h"
+#if CC_NV_UndefineSpaceSpecial // Conditional expansion of this file
+TPM_RC
+TPM2_NV_UndefineSpaceSpecial(
+ NV_UndefineSpaceSpecial_In *in // IN: input parameter list
+ )
+{
+ TPM_RC result;
+ NV_REF locator;
+ NV_INDEX *nvIndex = NvGetIndexInfo(in->nvIndex, &locator);
+ // Input Validation
+ // This operation only applies when the TPMA_NV_POLICY_DELETE attribute is SET
+ if(!IS_ATTRIBUTE(nvIndex->publicArea.attributes, TPMA_NV, POLICY_DELETE))
+ return TPM_RCS_ATTRIBUTES + RC_NV_UndefineSpaceSpecial_nvIndex;
+ // Internal Data Update
+ // Call implementation dependent internal routine to delete NV index
+ result = NvDeleteIndex(nvIndex, locator);
+ // If we just removed the index providing the authorization, make sure that the
+ // authorization session computation is modified so that it doesn't try to
+ // access the authValue of the just deleted index
+ if(result == TPM_RC_SUCCESS)
+ SessionRemoveAssociationToHandle(in->nvIndex);
+ return result;
+}
+#endif // CC_NV_UndefineSpaceSpecial
+#include "Tpm.h"
+#include "NV_ReadPublic_fp.h"
+#if CC_NV_ReadPublic // Conditional expansion of this file
+TPM_RC
+TPM2_NV_ReadPublic(
+ NV_ReadPublic_In *in, // IN: input parameter list
+ NV_ReadPublic_Out *out // OUT: output parameter list
+ )
+{
+ NV_INDEX *nvIndex = NvGetIndexInfo(in->nvIndex, NULL);
+ // Command Output
+ // Copy index public data to output
+ out->nvPublic.nvPublic = nvIndex->publicArea;
+ // Compute NV name
+ NvGetIndexName(nvIndex, &out->nvName);
+ return TPM_RC_SUCCESS;
+}
+#endif // CC_NV_ReadPublic
+#include "Tpm.h"
+#include "NV_Write_fp.h"
+#if CC_NV_Write // Conditional expansion of this file
+TPM_RC
+TPM2_NV_Write(
+ NV_Write_In *in // IN: input parameter list
+ )
+{
+ NV_INDEX *nvIndex = NvGetIndexInfo(in->nvIndex, NULL);
+ TPMA_NV attributes = nvIndex->publicArea.attributes;
+ TPM_RC result;
+ // Input Validation
+ // Common access checks, NvWriteAccessCheck() may return TPM_RC_NV_AUTHORIZATION
+ // or TPM_RC_NV_LOCKED
+ result = NvWriteAccessChecks(in->authHandle,
+ in->nvIndex,
+ attributes);
+ if(result != TPM_RC_SUCCESS)
+ return result;
+ // Bits index, extend index or counter index may not be updated by
+ // TPM2_NV_Write
+ if(IsNvCounterIndex(attributes)
+ || IsNvBitsIndex(attributes)
+ || IsNvExtendIndex(attributes))
+ return TPM_RC_ATTRIBUTES;
+ // Make sure that the offset is not too large
+ if(in->offset > nvIndex->publicArea.dataSize)
+ return TPM_RCS_VALUE + RC_NV_Write_offset;
+ // Make sure that the selection is within the range of the Index
+ if(in->data.t.size > (nvIndex->publicArea.dataSize - in->offset))
+ return TPM_RC_NV_RANGE;
+ // If this index requires a full sized write, make sure that input range is
+ // full sized.
+ // Note: if the requested size is the same as the Index data size, then offset
+ // will have to be zero. Otherwise, the range check above would have failed.
+ if(IS_ATTRIBUTE(attributes, TPMA_NV, WRITEALL)
+ && in->data.t.size < nvIndex->publicArea.dataSize)
+ return TPM_RC_NV_RANGE;
+ // Internal Data Update
+ // Perform the write. This called routine will SET the TPMA_NV_WRITTEN
+ // attribute if it has not already been SET. If NV isn't available, an error
+ // will be returned.
+ return NvWriteIndexData(nvIndex, in->offset, in->data.t.size,
+ in->data.t.buffer);
+}
+#endif // CC_NV_Write
+#include "Tpm.h"
+#include "NV_Increment_fp.h"
+#if CC_NV_Increment // Conditional expansion of this file
+TPM_RC
+TPM2_NV_Increment(
+ NV_Increment_In *in // IN: input parameter list
+ )
+{
+ TPM_RC result;
+ NV_REF locator;
+ NV_INDEX *nvIndex = NvGetIndexInfo(in->nvIndex, &locator);
+ UINT64 countValue;
+ // Input Validation
+ // Common access checks, NvWriteAccessCheck() may return TPM_RC_NV_AUTHORIZATION
+ // or TPM_RC_NV_LOCKED
+ result = NvWriteAccessChecks(in->authHandle,
+ in->nvIndex,
+ nvIndex->publicArea.attributes);
+ if(result != TPM_RC_SUCCESS)
+ return result;
+ // Make sure that this is a counter
+ if(!IsNvCounterIndex(nvIndex->publicArea.attributes))
+ return TPM_RCS_ATTRIBUTES + RC_NV_Increment_nvIndex;
+ // Internal Data Update
+ // If counter index is not been written, initialize it
+ if(!IS_ATTRIBUTE(nvIndex->publicArea.attributes, TPMA_NV, WRITTEN))
+ countValue = NvReadMaxCount();
+ else
+ // Read NV data in native format for TPM CPU.
+ countValue = NvGetUINT64Data(nvIndex, locator);
+ // Do the increment
+ countValue++;
+ // Write NV data back. A TPM_RC_NV_UNAVAILABLE or TPM_RC_NV_RATE error may
+ // be returned at this point. If necessary, this function will set the
+ // TPMA_NV_WRITTEN attribute
+ result = NvWriteUINT64Data(nvIndex, countValue);
+ if(result == TPM_RC_SUCCESS)
+ {
+ // If a counter just rolled over, then force the NV update.
+ // Note, if this is an orderly counter, then the write-back needs to be
+ // forced, for other counters, the write-back will happen anyway
+ if(IS_ATTRIBUTE(nvIndex->publicArea.attributes, TPMA_NV, ORDERLY)
+ && (countValue & MAX_ORDERLY_COUNT) == 0 )
+ {
+ // Need to force an NV update of orderly data
+ SET_NV_UPDATE(UT_ORDERLY);
+ }
+ }
+ return result;
+}
+#endif // CC_NV_Increment
+#include "Tpm.h"
+#include "NV_Extend_fp.h"
+#if CC_NV_Extend // Conditional expansion of this file
+TPM_RC
+TPM2_NV_Extend(
+ NV_Extend_In *in // IN: input parameter list
+ )
+{
+ TPM_RC result;
+ NV_REF locator;
+ NV_INDEX *nvIndex = NvGetIndexInfo(in->nvIndex, &locator);
+ TPM2B_DIGEST oldDigest;
+ TPM2B_DIGEST newDigest;
+ HASH_STATE hashState;
+ // Input Validation
+ // Common access checks, NvWriteAccessCheck() may return TPM_RC_NV_AUTHORIZATION
+ // or TPM_RC_NV_LOCKED
+ result = NvWriteAccessChecks(in->authHandle,
+ in->nvIndex,
+ nvIndex->publicArea.attributes);
+ if(result != TPM_RC_SUCCESS)
+ return result;
+ // Make sure that this is an extend index
+ if(!IsNvExtendIndex(nvIndex->publicArea.attributes))
+ return TPM_RCS_ATTRIBUTES + RC_NV_Extend_nvIndex;
+ // Internal Data Update
+ // Perform the write.
+ oldDigest.t.size = CryptHashGetDigestSize(nvIndex->publicArea.nameAlg);
+ pAssert(oldDigest.t.size <= sizeof(oldDigest.t.buffer));
+ if(IS_ATTRIBUTE(nvIndex->publicArea.attributes, TPMA_NV, WRITTEN))
+ {
+ NvGetIndexData(nvIndex, locator, 0, oldDigest.t.size, oldDigest.t.buffer);
+ }
+ else
+ {
+ MemorySet(oldDigest.t.buffer, 0, oldDigest.t.size);
+ }
+ // Start hash
+ newDigest.t.size = CryptHashStart(&hashState, nvIndex->publicArea.nameAlg);
+ // Adding old digest
+ CryptDigestUpdate2B(&hashState, &oldDigest.b);
+ // Adding new data
+ CryptDigestUpdate2B(&hashState, &in->data.b);
+ // Complete hash
+ CryptHashEnd2B(&hashState, &newDigest.b);
+ // Write extended hash back.
+ // Note, this routine will SET the TPMA_NV_WRITTEN attribute if necessary
+ return NvWriteIndexData(nvIndex, 0, newDigest.t.size, newDigest.t.buffer);
+}
+#endif // CC_NV_Extend
+#include "Tpm.h"
+#include "NV_SetBits_fp.h"
+#if CC_NV_SetBits // Conditional expansion of this file
+TPM_RC
+TPM2_NV_SetBits(
+ NV_SetBits_In *in // IN: input parameter list
+ )
+{
+ TPM_RC result;
+ NV_REF locator;
+ NV_INDEX *nvIndex = NvGetIndexInfo(in->nvIndex, &locator);
+ UINT64 oldValue;
+ UINT64 newValue;
+ // Input Validation
+ // Common access checks, NvWriteAccessCheck() may return TPM_RC_NV_AUTHORIZATION
+ // or TPM_RC_NV_LOCKED
+ result = NvWriteAccessChecks(in->authHandle,
+ in->nvIndex,
+ nvIndex->publicArea.attributes);
+ if(result != TPM_RC_SUCCESS)
+ return result;
+ // Make sure that this is a bit field
+ if(!IsNvBitsIndex(nvIndex->publicArea.attributes))
+ return TPM_RCS_ATTRIBUTES + RC_NV_SetBits_nvIndex;
+ // If index is not been written, initialize it
+ if(!IS_ATTRIBUTE(nvIndex->publicArea.attributes, TPMA_NV, WRITTEN))
+ oldValue = 0;
+ else
+ // Read index data
+ oldValue = NvGetUINT64Data(nvIndex, locator);
+ // Figure out what the new value is going to be
+ newValue = oldValue | in->bits;
+ // Internal Data Update
+ return NvWriteUINT64Data(nvIndex, newValue);
+}
+#endif // CC_NV_SetBits
+#include "Tpm.h"
+#include "NV_WriteLock_fp.h"
+#if CC_NV_WriteLock // Conditional expansion of this file
+TPM_RC
+TPM2_NV_WriteLock(
+ NV_WriteLock_In *in // IN: input parameter list
+ )
+{
+ TPM_RC result;
+ NV_REF locator;
+ NV_INDEX *nvIndex = NvGetIndexInfo(in->nvIndex, &locator);
+ TPMA_NV nvAttributes = nvIndex->publicArea.attributes;
+ // Input Validation:
+ // Common access checks, NvWriteAccessCheck() may return TPM_RC_NV_AUTHORIZATION
+ // or TPM_RC_NV_LOCKED
+ result = NvWriteAccessChecks(in->authHandle, in->nvIndex, nvAttributes);
+ if(result != TPM_RC_SUCCESS)
+ {
+ if(result == TPM_RC_NV_AUTHORIZATION)
+ return result;
+ // If write access failed because the index is already locked, then it is
+ // no error.
+ return TPM_RC_SUCCESS;
+ }
+ // if neither TPMA_NV_WRITEDEFINE nor TPMA_NV_WRITE_STCLEAR is set, the index
+ // can not be write-locked
+ if(!IS_ATTRIBUTE(nvAttributes, TPMA_NV, WRITEDEFINE)
+ && !IS_ATTRIBUTE(nvAttributes, TPMA_NV, WRITE_STCLEAR))
+ return TPM_RCS_ATTRIBUTES + RC_NV_WriteLock_nvIndex;
+ // Internal Data Update
+ // Set the WRITELOCK attribute.
+ // Note: if TPMA_NV_WRITELOCKED were already SET, then the write access check
+ // above would have failed and this code isn't executed.
+ SET_ATTRIBUTE(nvAttributes, TPMA_NV, WRITELOCKED);
+ // Write index info back
+ return NvWriteIndexAttributes(nvIndex->publicArea.nvIndex, locator,
+ nvAttributes);
+}
+#endif // CC_NV_WriteLock
+#include "Tpm.h"
+#include "NV_GlobalWriteLock_fp.h"
+#if CC_NV_GlobalWriteLock // Conditional expansion of this file
+TPM_RC
+TPM2_NV_GlobalWriteLock(
+ NV_GlobalWriteLock_In *in // IN: input parameter list
+ )
+{
+ // Input parameter (the authorization handle) is not reference in command action.
+ NOT_REFERENCED(in);
+ // Internal Data Update
+ // Implementation dependent method of setting the global lock
+ return NvSetGlobalLock();
+}
+#endif // CC_NV_GlobalWriteLock
+#include "Tpm.h"
+#include "NV_Read_fp.h"
+#if CC_NV_Read // Conditional expansion of this file
+/* TPM_RC_NV_AUTHORIZATION the authorization was valid but the authorizing entity (authHandle) is
+ not allowed to read from the Index referenced by nvIndex */
+/* TPM_RC_NV_LOCKED the Index referenced by nvIndex is read locked */
+/* TPM_RC_NV_RANGE read range defined by size and offset is outside the range of the Index
+ referenced by nvIndex */
+/* TPM_RC_NV_UNINITIALIZED the Index referenced by nvIndex has not been initialized (written) */
+/* TPM_RC_VALUE the read size is larger than the MAX_NV_BUFFER_SIZE */
+TPM_RC
+TPM2_NV_Read(
+ NV_Read_In *in, // IN: input parameter list
+ NV_Read_Out *out // OUT: output parameter list
+ )
+{
+ NV_REF locator;
+ NV_INDEX *nvIndex = NvGetIndexInfo(in->nvIndex, &locator);
+ TPM_RC result;
+ // Input Validation
+ // Common read access checks. NvReadAccessChecks() may return
+ // TPM_RC_NV_AUTHORIZATION, TPM_RC_NV_LOCKED, or TPM_RC_NV_UNINITIALIZED
+ result = NvReadAccessChecks(in->authHandle, in->nvIndex,
+ nvIndex->publicArea.attributes);
+ if(result != TPM_RC_SUCCESS)
+ return result;
+ // Make sure the data will fit the return buffer
+ if(in->size > MAX_NV_BUFFER_SIZE)
+ return TPM_RCS_VALUE + RC_NV_Read_size;
+ // Verify that the offset is not too large
+ if(in->offset > nvIndex->publicArea.dataSize)
+ return TPM_RCS_VALUE + RC_NV_Read_offset;
+ // Make sure that the selection is within the range of the Index
+ if(in->size > (nvIndex->publicArea.dataSize - in->offset))
+ return TPM_RC_NV_RANGE;
+ // Command Output
+ // Set the return size
+ out->data.t.size = in->size;
+ // Perform the read
+ NvGetIndexData(nvIndex, locator, in->offset, in->size, out->data.t.buffer);
+ return TPM_RC_SUCCESS;
+}
+#endif // CC_NV_Read
+#include "Tpm.h"
+#include "NV_ReadLock_fp.h"
+#if CC_NV_ReadLock // Conditional expansion of this file
+TPM_RC
+TPM2_NV_ReadLock(
+ NV_ReadLock_In *in // IN: input parameter list
+ )
+{
+ TPM_RC result;
+ NV_REF locator;
+ // The referenced index has been checked multiple times before this is called
+ // so it must be present and will be loaded into cache
+ NV_INDEX *nvIndex = NvGetIndexInfo(in->nvIndex, &locator);
+ TPMA_NV nvAttributes = nvIndex->publicArea.attributes;
+ // Input Validation
+ // Common read access checks. NvReadAccessChecks() may return
+ // TPM_RC_NV_AUTHORIZATION, TPM_RC_NV_LOCKED, or TPM_RC_NV_UNINITIALIZED
+ result = NvReadAccessChecks(in->authHandle,
+ in->nvIndex,
+ nvAttributes);
+ if(result == TPM_RC_NV_AUTHORIZATION)
+ return TPM_RC_NV_AUTHORIZATION;
+ // Index is already locked for write
+ else if(result == TPM_RC_NV_LOCKED)
+ return TPM_RC_SUCCESS;
+ // If NvReadAccessChecks return TPM_RC_NV_UNINITALIZED, then continue.
+ // It is not an error to read lock an uninitialized Index.
+ // if TPMA_NV_READ_STCLEAR is not set, the index can not be read-locked
+ if(!IS_ATTRIBUTE(nvAttributes, TPMA_NV, READ_STCLEAR))
+ return TPM_RCS_ATTRIBUTES + RC_NV_ReadLock_nvIndex;
+ // Internal Data Update
+ // Set the READLOCK attribute
+ SET_ATTRIBUTE(nvAttributes, TPMA_NV, READLOCKED);
+ // Write NV info back
+ return NvWriteIndexAttributes(nvIndex->publicArea.nvIndex,
+ locator,
+ nvAttributes);
+}
+#endif // CC_NV_ReadLock
+#include "Tpm.h"
+#include "NV_ChangeAuth_fp.h"
+#if CC_NV_ChangeAuth // Conditional expansion of this file
+TPM_RC
+TPM2_NV_ChangeAuth(
+ NV_ChangeAuth_In *in // IN: input parameter list
+ )
+{
+ NV_REF locator;
+ NV_INDEX *nvIndex = NvGetIndexInfo(in->nvIndex, &locator);
+ // Input Validation
+ // Remove trailing zeros and make sure that the result is not larger than the
+ // digest of the nameAlg.
+ if(MemoryRemoveTrailingZeros(&in->newAuth)
+ > CryptHashGetDigestSize(nvIndex->publicArea.nameAlg))
+ return TPM_RCS_SIZE + RC_NV_ChangeAuth_newAuth;
+ // Internal Data Update
+ // Change authValue
+ return NvWriteIndexAuth(locator, &in->newAuth);
+}
+#endif // CC_NV_ChangeAuth
+#include "Tpm.h"
+#include "Attest_spt_fp.h"
+#include "NV_Certify_fp.h"
+#if CC_NV_Certify // Conditional expansion of this file
+TPM_RC
+TPM2_NV_Certify(
+ NV_Certify_In *in, // IN: input parameter list
+ NV_Certify_Out *out // OUT: output parameter list
+ )
+{
+ TPM_RC result;
+ NV_REF locator;
+ NV_INDEX *nvIndex = NvGetIndexInfo(in->nvIndex, &locator);
+ TPMS_ATTEST certifyInfo;
+ OBJECT *signObject = HandleToObject(in->signHandle);
+ // Input Validation
+ if(!IsSigningObject(signObject))
+ return TPM_RCS_KEY + RC_NV_Certify_signHandle;
+ if(!CryptSelectSignScheme(signObject, &in->inScheme))
+ return TPM_RCS_SCHEME + RC_NV_Certify_inScheme;
+ // Common access checks, NvWriteAccessCheck() may return TPM_RC_NV_AUTHORIZATION
+ // or TPM_RC_NV_LOCKED
+ result = NvReadAccessChecks(in->authHandle, in->nvIndex,
+ nvIndex->publicArea.attributes);
+ if(result != TPM_RC_SUCCESS)
+ return result;
+ // make sure that the selection is within the range of the Index (cast to avoid
+ // any wrap issues with addition)
+ if((UINT32)in->size + (UINT32)in->offset > (UINT32)nvIndex->publicArea.dataSize)
+ return TPM_RC_NV_RANGE;
+ // Make sure the data will fit the return buffer
+ // NOTE: This check may be modified if the output buffer will not hold the
+ // maximum sized NV buffer as part of the certified data. The difference in
+ // size could be substantial if the signature scheme was produced a large
+ // signature (e.g., RSA 4096).
+ if(in->size > MAX_NV_BUFFER_SIZE)
+ return TPM_RCS_VALUE + RC_NV_Certify_size;
+ // Command Output
+
+ // Fill in attest information common fields
+ FillInAttestInfo(in->signHandle, &in->inScheme, &in->qualifyingData,
+ &certifyInfo);
+
+ // Get the name of the index
+ NvGetIndexName(nvIndex, &certifyInfo.attested.nv.indexName);
+
+ // See if this is old format or new format
+ if ((in->size != 0) || (in->offset != 0))
+ {
+ // NV certify specific fields
+ // Attestation type
+ certifyInfo.type = TPM_ST_ATTEST_NV;
+
+ // Set the return size
+ certifyInfo.attested.nv.nvContents.t.size = in->size;
+
+ // Set the offset
+ certifyInfo.attested.nv.offset = in->offset;
+
+ // Perform the read
+ NvGetIndexData(nvIndex, locator, in->offset, in->size,
+ certifyInfo.attested.nv.nvContents.t.buffer);
+ }
+ else
+ {
+ HASH_STATE hashState;
+ // This is to sign a digest of the data
+ certifyInfo.type = TPM_ST_ATTEST_NV_DIGEST;
+ // Initialize the hash before calling the function to add the Index data to
+ // the hash.
+ certifyInfo.attested.nvDigest.nvDigest.t.size =
+ CryptHashStart(&hashState, in->inScheme.details.any.hashAlg);
+ NvHashIndexData(&hashState, nvIndex, locator, 0,
+ nvIndex->publicArea.dataSize);
+ CryptHashEnd2B(&hashState, &certifyInfo.attested.nvDigest.nvDigest.b);
+ }
+ // Sign attestation structure. A NULL signature will be returned if
+ // signObject is NULL.
+ return SignAttestInfo(signObject, &in->inScheme, &certifyInfo,
+ &in->qualifyingData, &out->certifyInfo, &out->signature);
+}
+#endif // CC_NV_Certify
diff --git a/src/tpm2/NVDynamic.c b/src/tpm2/NVDynamic.c
new file mode 100644
index 0000000..c7c6a3b
--- /dev/null
+++ b/src/tpm2/NVDynamic.c
@@ -0,0 +1,1679 @@
+/********************************************************************************/
+/* */
+/* Dynamic space for user defined NV */
+/* Written by Ken Goldman */
+/* IBM Thomas J. Watson Research Center */
+/* $Id: NVDynamic.c 1658 2021-01-22 23:14:01Z kgoldman $ */
+/* */
+/* Licenses and Notices */
+/* */
+/* 1. Copyright Licenses: */
+/* */
+/* - Trusted Computing Group (TCG) grants to the user of the source code in */
+/* this specification (the "Source Code") a worldwide, irrevocable, */
+/* nonexclusive, royalty free, copyright license to reproduce, create */
+/* derivative works, distribute, display and perform the Source Code and */
+/* derivative works thereof, and to grant others the rights granted herein. */
+/* */
+/* - The TCG grants to the user of the other parts of the specification */
+/* (other than the Source Code) the rights to reproduce, distribute, */
+/* display, and perform the specification solely for the purpose of */
+/* developing products based on such documents. */
+/* */
+/* 2. Source Code Distribution Conditions: */
+/* */
+/* - Redistributions of Source Code must retain the above copyright licenses, */
+/* this list of conditions and the following disclaimers. */
+/* */
+/* - Redistributions in binary form must reproduce the above copyright */
+/* licenses, this list of conditions and the following disclaimers in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* 3. Disclaimers: */
+/* */
+/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
+/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
+/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
+/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
+/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
+/* information on specification licensing rights available through TCG */
+/* membership agreements. */
+/* */
+/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
+/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
+/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
+/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
+/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
+/* */
+/* - Without limitation, TCG and its members and licensors disclaim all */
+/* liability, including liability for infringement of any proprietary */
+/* rights, relating to use of information in this specification and to the */
+/* implementation of this specification, and TCG disclaims all liability for */
+/* cost of procurement of substitute goods or services, lost profits, loss */
+/* of use, loss of data or any incidental, consequential, direct, indirect, */
+/* or special damages, whether under contract, tort, warranty or otherwise, */
+/* arising in any way out of use or reliance upon this specification or any */
+/* information herein. */
+/* */
+/* (c) Copyright IBM Corp. and others, 2016 - 2021 */
+/* */
+/********************************************************************************/
+
+/* 8.4 NVDynamic.c */
+/* 8.4.2 Includes, Defines and Data Definitions */
+#define NV_C
+#include "Tpm.h"
+
+/* 8.4.3 Local Functions */
+/* 8.4.3.1 NvNext() */
+/* This function provides a method to traverse every data entry in NV dynamic area. */
+/* To begin with, parameter iter should be initialized to NV_REF_INIT indicating the first element.
+ Every time this function is called, the value in iter would be adjusted pointing to the next
+ element in traversal. If there is no next element, iter value would be 0. This function returns
+ the address of the 'data entry' pointed by the iter. If there is no more elements in the set, a 0
+ value is returned indicating the end of traversal. */
+static NV_REF
+NvNext(
+ NV_REF *iter, // IN/OUT: the list iterator
+ TPM_HANDLE *handle // OUT: the handle of the next item.
+ )
+{
+ NV_REF currentAddr;
+ NV_ENTRY_HEADER header;
+ //
+ // If iterator is at the beginning of list
+ if(*iter == NV_REF_INIT)
+ {
+ // Initialize iterator
+ *iter = NV_USER_DYNAMIC;
+ }
+ // Step over the size field and point to the handle
+ currentAddr = *iter + sizeof(UINT32);
+ // read the header of the next entry
+ NvRead(&header, *iter, sizeof(NV_ENTRY_HEADER));
+ // if the size field is zero, then we have hit the end of the list
+ if(header.size == 0)
+ // leave the *iter pointing at the end of the list
+ return 0;
+ // advance the header by the size of the entry
+ *iter += header.size;
+ if(handle != NULL)
+ *handle = header.handle;
+ return currentAddr;
+}
+/* 8.4.3.2 NvNextByType() */
+/* This function returns a reference to the next NV entry of the desired type */
+/* Return Values Meaning */
+/* 0 end of list */
+/* != 0 the next entry of the indicated type */
+static NV_REF
+NvNextByType(
+ TPM_HANDLE *handle, // OUT: the handle of the found type or 0
+ NV_REF *iter, // IN: the iterator
+ TPM_HT type // IN: the handle type to look for
+ )
+{
+ NV_REF addr;
+ TPM_HANDLE nvHandle = 0;
+ while((addr = NvNext(iter, &nvHandle)) != 0)
+ {
+ // addr: the address of the location containing the handle of the value
+ // iter: the next location.
+ if(HandleGetType(nvHandle) == type)
+ break;
+ }
+ if(handle != NULL)
+ *handle = nvHandle;
+ return addr;
+}
+/* 8.4.3.3 NvNextIndex() */
+/* This function returns the reference to the next NV Index entry. A value of 0 indicates the end
+ of the list. */
+/* Return Values Meaning */
+/* 0 end of list */
+/* != 0 the next */
+#define NvNextIndex(handle, iter) \
+ NvNextByType(handle, iter, TPM_HT_NV_INDEX)
+/* 8.4.3.4 NvNextEvict() */
+/* This function returns the offset in NV of the next evict object entry. A value of 0 indicates
+ the end of the list. */
+#define NvNextEvict(handle, iter) \
+ NvNextByType(handle, iter, TPM_HT_PERSISTENT)
+/* 8.4.3.5 NvGetEnd() */
+/* Function to find the end of the NV dynamic data list */
+static NV_REF
+NvGetEnd(
+ void
+ )
+{
+ NV_REF iter = NV_REF_INIT;
+ NV_REF currentAddr;
+ // Scan until the next address is 0
+ while((currentAddr = NvNext(&iter, NULL)) != 0);
+ return iter;
+}
+/* 8.4.3.6 NvGetFreeBytes */
+/* This function returns the number of free octets in NV space. */
+static UINT32
+NvGetFreeBytes(
+ void
+ )
+{
+ // This does not have an overflow issue because NvGetEnd() cannot return a value
+ // that is larger than s_evictNvEnd. This is because there is always a 'stop'
+ // word in the NV memory that terminates the search for the end before the
+ // value can go past s_evictNvEnd.
+ return s_evictNvEnd - NvGetEnd();
+}
+/* 8.4.3.7 NvTestSpace() */
+/* This function will test if there is enough space to add a new entity. */
+/* Return Values Meaning */
+/* TRUE space available */
+/* FALSE no enough space */
+static BOOL
+NvTestSpace(
+ UINT32 size, // IN: size of the entity to be added
+ BOOL isIndex, // IN: TRUE if the entity is an index
+ BOOL isCounter // IN: TRUE if the index is a counter
+ )
+{
+ UINT32 remainBytes = NvGetFreeBytes();
+ UINT32 reserved = sizeof(UINT32) // size of the forward pointer
+ + sizeof(NV_LIST_TERMINATOR);
+ // Do a compile time sanity check on the setting for NV_MEMORY_SIZE
+#if NV_MEMORY_SIZE < 1024
+#error "NV_MEMORY_SIZE probably isn't large enough"
+#endif
+ // For NV Index, need to make sure that we do not allocate an Index if this
+ // would mean that the TPM cannot allocate the minimum number of evict
+ // objects.
+ if(isIndex)
+ {
+ // Get the number of persistent objects allocated
+ UINT32 persistentNum = NvCapGetPersistentNumber();
+ // If we have not allocated the requisite number of evict objects, then we
+ // need to reserve space for them.
+ // NOTE: some of this is not written as simply as it might seem because
+ // the values are all unsigned and subtracting needs to be done carefully
+ // so that an underflow doesn't cause problems.
+ if(persistentNum < MIN_EVICT_OBJECTS)
+ reserved += (MIN_EVICT_OBJECTS - persistentNum) * NV_EVICT_OBJECT_SIZE;
+ }
+ // If this is not an index or is not a counter, reserve space for the
+ // required number of counter indexes
+ if(!isIndex || !isCounter)
+ {
+ // Get the number of counters
+ UINT32 counterNum = NvCapGetCounterNumber();
+ // If the required number of counters have not been allocated, reserved
+ // space for the extra needed counters
+ if(counterNum < MIN_COUNTER_INDICES)
+ reserved += (MIN_COUNTER_INDICES - counterNum) * NV_INDEX_COUNTER_SIZE;
+ }
+ // Check that the requested allocation will fit after making sure that there
+ // will be no chance of overflow
+ return ((reserved < remainBytes)
+ && (size <= remainBytes)
+ && (size + reserved <= remainBytes));
+}
+/* 8.4.3.8 NvWriteNvListEnd() */
+/* Function to write the list terminator. */
+NV_REF
+NvWriteNvListEnd(
+ NV_REF end
+ )
+{
+ // Marker is initialized with zeros
+ BYTE listEndMarker[sizeof(NV_LIST_TERMINATOR)] = {0};
+ UINT64 maxCount = NvReadMaxCount();
+ //
+ // This is a constant check that can be resolved at compile time.
+ cAssert(sizeof(UINT64) <= sizeof(NV_LIST_TERMINATOR) - sizeof(UINT32));
+ // Copy the maxCount value to the marker buffer
+ MemoryCopy(&listEndMarker[sizeof(UINT32)], &maxCount, sizeof(UINT64));
+ pAssert(end + sizeof(NV_LIST_TERMINATOR) <= s_evictNvEnd);
+ // Write it to memory
+ NvWrite(end, sizeof(NV_LIST_TERMINATOR), &listEndMarker);
+ return end + sizeof(NV_LIST_TERMINATOR);
+}
+/* 8.4.3.9 NvAdd() */
+/* This function adds a new entity to NV. */
+/* This function requires that there is enough space to add a new entity (i.e., that NvTestSpace()
+ has been called and the available space is at least as large as the required space). */
+/* The totalSize will be the size of entity. If a handle is added, this function will increase the
+ size accordingly. */
+static TPM_RC
+NvAdd(
+ UINT32 totalSize, // IN: total size needed for this entity For
+ // evict object, totalSize is the same as
+ // bufferSize. For NV Index, totalSize is
+ // bufferSize plus index data size
+ UINT32 bufferSize, // IN: size of initial buffer
+ TPM_HANDLE handle, // IN: optional handle
+ BYTE *entity // IN: initial buffer
+ )
+{
+ NV_REF newAddr; // IN: where the new entity will start
+ NV_REF nextAddr;
+ RETURN_IF_NV_IS_NOT_AVAILABLE;
+ // Get the end of data list
+ newAddr = NvGetEnd();
+ // Step over the forward pointer
+ nextAddr = newAddr + sizeof(UINT32);
+ // Optionally write the handle. For indexes, the handle is TPM_RH_UNASSIGNED
+ // so that the handle in the nvIndex is used instead of writing this value
+ if(handle != TPM_RH_UNASSIGNED)
+ {
+ NvWrite((UINT32)nextAddr, sizeof(TPM_HANDLE), &handle);
+ nextAddr += sizeof(TPM_HANDLE);
+ }
+ // Write entity data
+ NvWrite((UINT32)nextAddr, bufferSize, entity);
+ // Advance the pointer by the amount of the total
+ nextAddr += totalSize;
+ // Finish by writing the link value
+ // Write the next offset (relative addressing)
+ totalSize = nextAddr - newAddr;
+ // Write link value
+ NvWrite((UINT32)newAddr, sizeof(UINT32), &totalSize);
+ // Write the list terminator
+ NvWriteNvListEnd(nextAddr);
+ return TPM_RC_SUCCESS;
+}
+/* 8.4.3.10 NvDelete() */
+/* This function is used to delete an NV Index or persistent object from NV memory. */
+static TPM_RC
+NvDelete(
+ NV_REF entityRef // IN: reference to entity to be deleted
+ )
+{
+ UINT32 entrySize;
+ // adjust entityAddr to back up and point to the forward pointer
+ NV_REF entryRef = entityRef - sizeof(UINT32);
+ NV_REF endRef = NvGetEnd();
+ NV_REF nextAddr; // address of the next entry
+ RETURN_IF_NV_IS_NOT_AVAILABLE;
+ // Get the offset of the next entry. That is, back up and point to the size
+ // field of the entry
+ NvRead(&entrySize, entryRef, sizeof(UINT32));
+ // The next entry after the one being deleted is at a relative offset
+ // from the current entry
+ nextAddr = entryRef + entrySize;
+ // If this is not the last entry, move everything up
+ if(nextAddr < endRef)
+ {
+ pAssert(nextAddr > entryRef);
+ _plat__NvMemoryMove(nextAddr,
+ entryRef,
+ (endRef - nextAddr));
+ }
+ // The end of the used space is now moved up by the amount of space we just
+ // reclaimed
+ endRef -= entrySize;
+ // Write the end marker, and make the new end equal to the first byte after
+ // the just added end value. This will automatically update the NV value for
+ // maxCounter
+ // NOTE: This is the call that sets flag to cause NV to be updated
+ endRef = NvWriteNvListEnd(endRef);
+ // Clear the reclaimed memory
+ _plat__NvMemoryClear(endRef, entrySize);
+ return TPM_RC_SUCCESS;
+}
+/* 8.4.4 RAM-based NV Index Data Access Functions */
+/* 8.4.4.1 Introduction */
+/* The data layout in ram buffer is {size of(NV_handle() + attributes + data NV_handle(),
+ attributes, data} for each NV Index data stored in RAM. */
+/* NV storage associated with orderly data is updated when a NV Index is added but NOT when the data
+ or attributes are changed. Orderly data is only updated to NV on an orderly shutdown
+ (TPM2_Shutdown()) */
+/* 8.4.4.2 NvRamNext() */
+/* This function is used to iterate trough the list of Ram Index values. *iter needs to be
+ initialized by calling */
+static NV_RAM_REF
+NvRamNext(
+ NV_RAM_REF *iter, // IN/OUT: the list iterator
+ TPM_HANDLE *handle // OUT: the handle of the next item.
+ )
+{
+ NV_RAM_REF currentAddr;
+ NV_RAM_HEADER header;
+ //
+ // If iterator is at the beginning of list
+ if(*iter == NV_RAM_REF_INIT)
+ {
+ // Initialize iterator
+ *iter = &s_indexOrderlyRam[0];
+ }
+ // if we are going to return what the iter is currently pointing to...
+ currentAddr = *iter;
+ // If iterator reaches the end of NV space, then don't advance and return
+ // that we are at the end of the list. The end of the list occurs when
+ // we don't have space for a size and a handle
+ if(currentAddr + sizeof(NV_RAM_HEADER) > RAM_ORDERLY_END)
+ return NULL;
+ // read the header of the next entry
+ memcpy(&header, currentAddr, sizeof(NV_RAM_HEADER)); // libtpms: do not use MemoryCopy to avoid gcc warning
+ // if the size field is zero, then we have hit the end of the list
+ if(header.size == 0)
+ // leave the *iter pointing at the end of the list
+ return NULL;
+ // advance the header by the size of the entry
+ *iter = currentAddr + header.size;
+ // pAssert(*iter <= RAM_ORDERLY_END);
+ if(handle != NULL)
+ *handle = header.handle;
+ return currentAddr;
+}
+/* 8.4.4.2 NvRamGetEnd() */
+/* This routine performs the same function as NvGetEnd() but for the RAM data. */
+static NV_RAM_REF
+NvRamGetEnd(
+ void
+ )
+{
+ NV_RAM_REF iter = NV_RAM_REF_INIT;
+ NV_RAM_REF currentAddr;
+ // Scan until the next address is 0
+ while((currentAddr = NvRamNext(&iter, NULL)) != 0);
+ return iter;
+}
+/* 8.4.4.3 NvRamTestSpaceIndex() */
+/* This function indicates if there is enough RAM space to add a data for a new NV Index. */
+/* Return Values Meaning */
+/* TRUE space available */
+/* FALSE no enough space */
+static BOOL
+NvRamTestSpaceIndex(
+ UINT32 size // IN: size of the data to be added to RAM
+ )
+{
+ UINT32 remaining = (UINT32)(RAM_ORDERLY_END - NvRamGetEnd());
+ UINT32 needed = sizeof(NV_RAM_HEADER) + size;
+ // NvRamGetEnd points to the next available byte.
+ return remaining >= needed;
+}
+/* 8.4.4.4 NvRamGetIndex() */
+/* This function returns the offset of NV data in the RAM buffer */
+/* This function requires that NV Index is in RAM. That is, the index must be known to exist. */
+static NV_RAM_REF
+NvRamGetIndex(
+ TPMI_RH_NV_INDEX handle // IN: NV handle
+ )
+{
+ NV_RAM_REF iter = NV_RAM_REF_INIT;
+ NV_RAM_REF currentAddr;
+ TPM_HANDLE foundHandle;
+ while((currentAddr = NvRamNext(&iter, &foundHandle)) != 0)
+ {
+ if(handle == foundHandle)
+ break;
+ }
+ return currentAddr;
+}
+/* 8.4.4.5 NvUpdateIndexOrderlyData() */
+/* This function is used to cause an update of the orderly data to the NV backing store. */
+void
+NvUpdateIndexOrderlyData(
+ void
+ )
+{
+ // Write reserved RAM space to NV
+ NvWrite(NV_INDEX_RAM_DATA, sizeof(s_indexOrderlyRam), s_indexOrderlyRam);
+}
+/* 8.4.4.6 NvAddRAM() */
+/* This function adds a new data area to RAM. */
+/* This function requires that enough free RAM space is available to add the new data. */
+/* This function should be called after the NV Index space has been updated and the index
+ removed. This insures that NV is available so that checking for NV availability is not required
+ during this function. */
+static void
+NvAddRAM(
+ TPMS_NV_PUBLIC *index // IN: the index descriptor
+ )
+{
+ NV_RAM_HEADER header;
+ NV_RAM_REF end = NvRamGetEnd();
+ header.size = sizeof(NV_RAM_HEADER) + index->dataSize;
+ header.handle = index->nvIndex;
+ MemoryCopy(&header.attributes, &index->attributes, sizeof(TPMA_NV));
+ pAssert(ORDERLY_RAM_ADDRESS_OK(end, header.size));
+ // Copy the header to the memory
+ MemoryCopy(end, &header, sizeof(NV_RAM_HEADER));
+ // Clear the data area (just in case)
+ MemorySet(end + sizeof(NV_RAM_HEADER), 0, index->dataSize);
+ // Step over this new entry
+ end += header.size;
+ // If the end marker will fit, add it
+ if(end + sizeof(UINT32) < RAM_ORDERLY_END)
+ MemorySet(end, 0, sizeof(UINT32));
+ // Write reserved RAM space to NV to reflect the newly added NV Index
+ SET_NV_UPDATE(UT_ORDERLY);
+ return;
+}
+/* 8.4.4.7 NvDeleteRAM() */
+/* This function is used to delete a RAM-backed NV Index data area. The space used by the entry are
+ overwritten by the contents of the Index data that comes after (the data is moved up to fill the
+ hole left by removing this index. The reclaimed space is cleared to zeros. This function assumes
+ the data of NV Index exists in RAM. */
+/* This function should be called after the NV Index space has been updated and the index
+ removed. This insures that NV is available so that checking for NV availability is not required
+ during this function. */
+static void
+NvDeleteRAM(
+ TPMI_RH_NV_INDEX handle // IN: NV handle
+ )
+{
+ NV_RAM_REF nodeAddress;
+ NV_RAM_REF nextNode;
+ UINT32 size;
+ NV_RAM_REF lastUsed = NvRamGetEnd();
+ nodeAddress = NvRamGetIndex(handle);
+ pAssert(nodeAddress != 0);
+ // Get node size
+ MemoryCopy(&size, nodeAddress, sizeof(size));
+ // Get the offset of next node
+ nextNode = nodeAddress + size;
+ // Copy the data
+ MemoryCopy(nodeAddress, nextNode, (int)(lastUsed - nextNode));
+ // Clear out the reclaimed space
+ MemorySet(lastUsed - size, 0, size);
+ // Write reserved RAM space to NV to reflect the newly delete NV Index
+ SET_NV_UPDATE(UT_ORDERLY);
+ return;
+}
+/* 8.4.4.9 NvReadIndex() */
+/* This function is used to read the NV Index NV_INDEX. This is used so that the index information
+ can be compressed and only this function would be needed to decompress it. Mostly, compression
+ would only be able to save the space needed by the policy. */
+void
+NvReadNvIndexInfo(
+ NV_REF ref, // IN: points to NV where index is located
+ NV_INDEX *nvIndex // OUT: place to receive index data
+ )
+{
+ pAssert(nvIndex != NULL);
+ NvRead(nvIndex, ref, sizeof(NV_INDEX));
+ return;
+}
+/* 8.4.4.9 NvReadObject() */
+/* This function is used to read a persistent object. This is used so that the object information
+ can be compressed and only this function would be needed to uncompress it. */
+void
+NvReadObject(
+ NV_REF ref, // IN: points to NV where index is located
+ OBJECT *object // OUT: place to receive the object data
+ )
+{
+ NvRead(object, (ref + sizeof(TPM_HANDLE)), sizeof(OBJECT));
+ return;
+}
+/* 8.4.4.10 NvFindEvict() */
+/* This function will return the NV offset of an evict object */
+/* Return Values Meaning */
+/* 0 evict object not found */
+/* != 0 offset of evict object */
+static NV_REF
+NvFindEvict(
+ TPM_HANDLE nvHandle,
+ OBJECT *object
+ )
+{
+ NV_REF found = NvFindHandle(nvHandle);
+ // If we found the handle and the request included an object pointer, fill it in
+ if(found != 0 && object != NULL)
+ NvReadObject(found, object);
+ return found;
+}
+/* 8.4.4.11 NvIndexIsDefined() */
+/* See if an index is already defined */
+BOOL
+NvIndexIsDefined(
+ TPM_HANDLE nvHandle // IN: Index to look for
+ )
+{
+ return (NvFindHandle(nvHandle) != 0);
+}
+/* 8.4.4.12 NvConditionallyWrite() */
+/* Function to check if the data to be written has changed and write it if it has */
+/* Error Returns Meaning */
+/* TPM_RC_NV_RATE NV is unavailable because of rate limit */
+/* TPM_RC_NV_UNAVAILABLE NV is inaccessible */
+static TPM_RC
+NvConditionallyWrite(
+ NV_REF entryAddr, // IN: stating address
+ UINT32 size, // IN: size of the data to write
+ void *data // IN: the data to write
+ )
+{
+ // If the index data is actually changed, then a write to NV is required
+ if(_plat__NvIsDifferent(entryAddr, size, data))
+ {
+ // Write the data if NV is available
+ if(g_NvStatus == TPM_RC_SUCCESS)
+ {
+ NvWrite(entryAddr, size, data);
+ }
+ return g_NvStatus;
+ }
+ return TPM_RC_SUCCESS;
+}
+/* 8.4.4.13 NvReadNvIndexAttributes() */
+/* This function returns the attributes of an NV Index. */
+static TPMA_NV
+NvReadNvIndexAttributes(
+ NV_REF locator // IN: reference to an NV index
+ )
+{
+ TPMA_NV attributes;
+ NvRead(&attributes,
+ locator + offsetof(NV_INDEX, publicArea.attributes),
+ sizeof(TPMA_NV));
+ return attributes;
+}
+/* 8.4.4.14 NvReadRamIndexAttributes() */
+/* This function returns the attributes from the RAM header structure. This function is used to deal
+ with the fact that the header structure is only byte aligned. */
+static TPMA_NV
+NvReadRamIndexAttributes(
+ NV_RAM_REF ref // IN: pointer to a NV_RAM_HEADER
+ )
+{
+ TPMA_NV attributes;
+ MemoryCopy(&attributes, ref + offsetof(NV_RAM_HEADER, attributes),
+ sizeof(TPMA_NV));
+ return attributes;
+}
+/* 8.4.4.15 NvWriteNvIndexAttributes() */
+/* This function is used to write just the attributes of an index to NV. */
+/* Error Returns Meaning */
+/* TPM_RC_NV_RATE NV is rate limiting so retry */
+/* TPM_RC_NV_UNAVAILABLE NV is not available */
+static TPM_RC
+NvWriteNvIndexAttributes(
+ NV_REF locator, // IN: location of the index
+ TPMA_NV attributes // IN: attributes to write
+ )
+{
+ return NvConditionallyWrite(
+ locator + offsetof(NV_INDEX, publicArea.attributes),
+ sizeof(TPMA_NV),
+ &attributes);
+}
+/* 8.4.4.16 NvWriteRamIndexAttributes() */
+/* This function is used to write the index attributes into an unaligned structure */
+static void
+NvWriteRamIndexAttributes(
+ NV_RAM_REF ref, // IN: address of the header
+ TPMA_NV attributes // IN: the attributes to write
+ )
+{
+ MemoryCopy(ref + offsetof(NV_RAM_HEADER, attributes), &attributes,
+ sizeof(TPMA_NV));
+ return;
+}
+/* 8.4.5 Externally Accessible Functions */
+/* 8.4.5.1 NvIsPlatformPersistentHandle() */
+/* This function indicates if a handle references a persistent object in the range belonging to the
+ platform. */
+/* Return Values Meaning */
+/* TRUE handle references a platform persistent object */
+/* FALSE handle does not reference platform persistent object */
+BOOL
+NvIsPlatformPersistentHandle(
+ TPM_HANDLE handle // IN: handle
+ )
+{
+ return (handle >= PLATFORM_PERSISTENT && handle <= PERSISTENT_LAST);
+}
+/* 8.4.5.2 NvIsOwnerPersistentHandle() */
+/* This function indicates if a handle references a persistent object in the range belonging to the
+ owner. */
+/* Return Values Meaning */
+/* TRUE handle is owner persistent handle */
+/* FALSE handle is not owner persistent handle and may not be a persistent handle at all */
+BOOL
+NvIsOwnerPersistentHandle(
+ TPM_HANDLE handle // IN: handle
+ )
+{
+ return (handle >= PERSISTENT_FIRST && handle < PLATFORM_PERSISTENT);
+}
+/* 8.4.5.3 NvIndexIsAccessible() */
+/* This function validates that a handle references a defined NV Index and that the Index is
+ currently accessible. */
+/* Error Returns Meaning */
+/* TPM_RC_HANDLE the handle points to an undefined NV Index If shEnable is CLEAR, this would include
+ an index created using ownerAuth. If phEnableNV is CLEAR, this would include and index created
+ using platformAuth */
+/* TPM_RC_NV_READLOCKED Index is present but locked for reading and command does not write to the
+ index */
+/* TPM_RC_NV_WRITELOCKED Index is present but locked for writing and command writes to the index */
+TPM_RC
+NvIndexIsAccessible(
+ TPMI_RH_NV_INDEX handle // IN: handle
+ )
+{
+ NV_INDEX *nvIndex = NvGetIndexInfo(handle, NULL);
+ //
+ if(nvIndex == NULL)
+ // If index is not found, return TPM_RC_HANDLE
+ return TPM_RC_HANDLE;
+ if(gc.shEnable == FALSE || gc.phEnableNV == FALSE)
+ {
+ // if shEnable is CLEAR, an ownerCreate NV Index should not be
+ // indicated as present
+ if(!IS_ATTRIBUTE(nvIndex->publicArea.attributes, TPMA_NV, PLATFORMCREATE))
+ {
+ if(gc.shEnable == FALSE)
+ return TPM_RC_HANDLE;
+ }
+ // if phEnableNV is CLEAR, a platform created Index should not
+ // be visible
+ else if(gc.phEnableNV == FALSE)
+ return TPM_RC_HANDLE;
+ }
+#if 0 // Writelock test for debug
+ // If the Index is write locked and this is an NV Write operation...
+ if(IS_ATTRIBUTE(nvIndex->publicArea.attributes, TPMA_NV, WRITELOCKED)
+ && IsWriteOperation(commandIndex))
+ {
+ // then return a locked indication unless the command is TPM2_NV_WriteLock
+ if(GetCommandCode(commandIndex) != TPM_CC_NV_WriteLock)
+ return TPM_RC_NV_LOCKED;
+ return TPM_RC_SUCCESS;
+ }
+#endif
+#if 0 // Readlock Test for debug
+ // If the Index is read locked and this is an NV Read operation...
+ if(IS_ATTRIBUTE(nvIndex->publicArea.attributes, TPMA_NV, READLOCKED)
+ && IsReadOperation(commandIndex))
+ {
+ // then return a locked indication unless the command is TPM2_NV_ReadLock
+ if(GetCommandCode(commandIndex) != TPM_CC_NV_ReadLock)
+ return TPM_RC_NV_LOCKED;
+ }
+#endif
+ // NV Index is accessible
+ return TPM_RC_SUCCESS;
+}
+/* 8.4.5.4 NvGetEvictObject() */
+/* This function is used to dereference an evict object handle and get a pointer to the object. */
+/* Error Returns Meaning */
+/* TPM_RC_HANDLE the handle does not point to an existing persistent object */
+TPM_RC
+NvGetEvictObject(
+ TPM_HANDLE handle, // IN: handle
+ OBJECT *object // OUT: object data
+ )
+{
+ NV_REF entityAddr; // offset points to the entity
+ // Find the address of evict object and copy to object
+ entityAddr = NvFindEvict(handle, object);
+ // whether there is an error or not, make sure that the evict
+ // status of the object is set so that the slot will get freed on exit
+ // Must do this after NvFindEvict loads the object
+ object->attributes.evict = SET;
+ // If handle is not found, return an error
+ if(entityAddr == 0)
+ return TPM_RC_HANDLE;
+ return TPM_RC_SUCCESS;
+}
+/* 8.4.5.5 NvIndexCacheInit() */
+/* Function to initialize the Index cache */
+void
+NvIndexCacheInit(
+ void
+ )
+{
+ s_cachedNvRef = NV_REF_INIT;
+ s_cachedNvRamRef = NV_RAM_REF_INIT;
+ s_cachedNvIndex.publicArea.nvIndex = TPM_RH_UNASSIGNED;
+ return;
+}
+/* 8.4.5.6 NvGetIndexData() */
+/* This function is used to access the data in an NV Index. The data is returned as a byte
+ sequence. */
+/* This function requires that the NV Index be defined, and that the required data is within the
+ data range. It also requires that TPMA_NV_WRITTEN of the Index is SET. */
+void
+NvGetIndexData(
+ NV_INDEX *nvIndex, // IN: the in RAM index descriptor
+ NV_REF locator, // IN: where the data is located
+ UINT32 offset, // IN: offset of NV data
+ UINT16 size, // IN: size of NV data
+ void *data // OUT: data buffer
+ )
+{
+ TPMA_NV nvAttributes;
+ //
+ pAssert(nvIndex != NULL);
+ nvAttributes = nvIndex->publicArea.attributes;
+ pAssert(IS_ATTRIBUTE(nvAttributes, TPMA_NV, WRITTEN));
+ if(IS_ATTRIBUTE(nvAttributes, TPMA_NV, ORDERLY))
+ {
+ // Get data from RAM buffer
+ NV_RAM_REF ramAddr = NvRamGetIndex(nvIndex->publicArea.nvIndex);
+ pAssert(ramAddr != 0 && (size <=
+ ((NV_RAM_HEADER *)ramAddr)->size -
+ sizeof(NV_RAM_HEADER) - offset));
+ MemoryCopy(data, ramAddr + sizeof(NV_RAM_HEADER) + offset, size);
+ }
+ else
+ {
+ // Validate that read falls within range of the index
+ pAssert(offset <= nvIndex->publicArea.dataSize
+ && size <= (nvIndex->publicArea.dataSize - offset));
+ NvRead(data, locator + sizeof(NV_INDEX) + offset, size);
+ }
+ return;
+}
+/* 8.4.5.7 NvHashIndexData() */
+/* This function adds Index data to a hash. It does this in parts to avoid large stack buffers. */
+void
+NvHashIndexData(
+ HASH_STATE *hashState, // IN: Initialized hash state
+ NV_INDEX *nvIndex, // IN: Index
+ NV_REF locator, // IN: where the data is located
+ UINT32 offset, // IN: starting offset
+ UINT16 size // IN: amount to hash
+ )
+{
+#define BUFFER_SIZE 64
+ BYTE buffer[BUFFER_SIZE];
+ if (offset > nvIndex->publicArea.dataSize)
+ return;
+ // Make sure that we don't try to read off the end.
+ if ((offset + size) > nvIndex->publicArea.dataSize)
+ size = nvIndex->publicArea.dataSize - (UINT16)offset;
+#if BUFFER_SIZE >= MAX_NV_INDEX_SIZE
+ NvGetIndexData(nvIndex, locator, offset, size, buffer);
+ CryptDigestUpdate(hashState, size, buffer);
+#else
+ {
+ INT16 i;
+ UINT16 readSize;
+ //
+ for (i = size; i > 0; offset += readSize, i -= readSize)
+ {
+ readSize = (i < BUFFER_SIZE) ? i : BUFFER_SIZE;
+ NvGetIndexData(nvIndex, locator, offset, readSize, buffer);
+ CryptDigestUpdate(hashState, readSize, buffer);
+ }
+ }
+#endif // BUFFER_SIZE >= MAX_NV_INDEX_SIZE
+#undef BUFFER_SIZE
+}
+/* 8.4.5.7 NvGetUINT64Data() */
+/* Get data in integer format of a bit or counter NV Index. */
+/* This function requires that the NV Index is defined and that the NV Index previously has been
+ written. */
+UINT64
+NvGetUINT64Data(
+ NV_INDEX *nvIndex, // IN: the in RAM index descriptor
+ NV_REF locator // IN: where index exists in NV
+ )
+{
+ UINT64 intVal;
+ // Read the value and convert it to internal format
+ NvGetIndexData(nvIndex, locator, 0, 8, &intVal);
+ return BYTE_ARRAY_TO_UINT64(((BYTE *)&intVal));
+}
+/* 8.4.5.8 NvWriteIndexAttributes() */
+/* This function is used to write just the attributes of an index. */
+/* Error Returns Meaning */
+/* TPM_RC_NV_RATE NV is rate limiting so retry */
+/* TPM_RC_NV_UNAVAILABLE NV is not available */
+TPM_RC
+NvWriteIndexAttributes(
+ TPM_HANDLE handle,
+ NV_REF locator, // IN: location of the index
+ TPMA_NV attributes // IN: attributes to write
+ )
+{
+ TPM_RC result;
+ //
+ if(IS_ATTRIBUTE(attributes, TPMA_NV, ORDERLY))
+ {
+ NV_RAM_REF ram = NvRamGetIndex(handle);
+ NvWriteRamIndexAttributes(ram, attributes);
+ result = TPM_RC_SUCCESS;
+ }
+ else
+ {
+ result = NvWriteNvIndexAttributes(locator, attributes);
+ }
+ return result;
+}
+/* 8.4.5.9 NvWriteIndexAuth() */
+/* This function is used to write the authValue of an index. It is used by TPM2_NV_ChangeAuth() */
+/* Error Returns Meaning */
+/* TPM_RC_NV_RATE NV is rate limiting so retry */
+/* TPM_RC_NV_UNAVAILABLE NV is not available */
+TPM_RC
+NvWriteIndexAuth(
+ NV_REF locator, // IN: location of the index
+ TPM2B_AUTH *authValue // IN: the authValue to write
+ )
+{
+ {
+ TPM_RC result;
+ //
+ // If the locator is pointing to the cached index value...
+ if(locator == s_cachedNvRef)
+ {
+ // copy the authValue to the cached index so it will be there if we
+ // look for it. This is a safety thing.
+ MemoryCopy2B(&s_cachedNvIndex.authValue.b, &authValue->b,
+ sizeof(s_cachedNvIndex.authValue.t.buffer));
+ }
+ result = NvConditionallyWrite(
+ locator + offsetof(NV_INDEX, authValue),
+ sizeof(UINT16) + authValue->t.size,
+ authValue);
+ return result;
+ }
+}
+/* 8.4.5.10 NvGetIndexInfo() */
+/* This function loads the nvIndex Info into the NV cache and returns a pointer to the NV_INDEX. If
+ the returned value is zero, the index was not found. The locator parameter, if not NULL, will be
+ set to the offset in NV of the Index (the location of the handle of the Index). */
+/* This function will set the index cache. If the index is orderly, the attributes from RAM are
+ substituted for the attributes in the cached index */
+NV_INDEX *
+NvGetIndexInfo(
+ TPM_HANDLE nvHandle, // IN: the index handle
+ NV_REF *locator // OUT: location of the index
+ )
+{
+ if(s_cachedNvIndex.publicArea.nvIndex != nvHandle)
+ {
+ s_cachedNvIndex.publicArea.nvIndex = TPM_RH_UNASSIGNED;
+ s_cachedNvRamRef = 0;
+ s_cachedNvRef = NvFindHandle(nvHandle);
+ if(s_cachedNvRef == 0)
+ return NULL;
+ NvReadNvIndexInfo(s_cachedNvRef, &s_cachedNvIndex);
+ if(IS_ATTRIBUTE(s_cachedNvIndex.publicArea.attributes, TPMA_NV, ORDERLY))
+ {
+ s_cachedNvRamRef = NvRamGetIndex(nvHandle);
+ s_cachedNvIndex.publicArea.attributes =
+ NvReadRamIndexAttributes(s_cachedNvRamRef);
+ }
+ }
+ if(locator != NULL)
+ *locator = s_cachedNvRef;
+ return &s_cachedNvIndex;
+}
+/* 8.4.5.11 NvWriteIndexData() */
+/* This function is used to write NV index data. It is intended to be used to update the data
+ associated with the default index. */
+/* This function requires that the NV Index is defined, and the data is within the defined data
+ range for the index. */
+/* Index data is only written due to a command that modifies the data in a single index. There is no
+ case where changes are made to multiple indexes data at the same time. Multiple attributes may be
+ change but not multiple index data. This is important because we will normally be handling the
+ index for which we have the cached pointer values. */
+/* Error Returns Meaning */
+/* TPM_RC_NV_RATE NV is rate limiting so retry */
+/* TPM_RC_NV_UNAVAILABLE NV is not available */
+TPM_RC
+NvWriteIndexData(
+ NV_INDEX *nvIndex, // IN: the description of the index
+ UINT32 offset, // IN: offset of NV data
+ UINT32 size, // IN: size of NV data
+ void *data // IN: data buffer
+ )
+{
+ TPM_RC result = TPM_RC_SUCCESS;
+ //
+ pAssert(nvIndex != NULL);
+ // Make sure that this is dealing with the 'default' index.
+ // Note: it is tempting to change the calling sequence so that the 'default' is
+ // presumed.
+ pAssert(nvIndex->publicArea.nvIndex == s_cachedNvIndex.publicArea.nvIndex);
+ // Validate that write falls within range of the index
+ pAssert(offset <= nvIndex->publicArea.dataSize
+ && size <= (nvIndex->publicArea.dataSize - offset));
+ // Update TPMA_NV_WRITTEN bit if necessary
+ if(!IS_ATTRIBUTE(nvIndex->publicArea.attributes, TPMA_NV, WRITTEN))
+ {
+ // Update the in memory version of the attributes
+ SET_ATTRIBUTE(nvIndex->publicArea.attributes, TPMA_NV, WRITTEN);
+ // If this is not orderly, then update the NV version of
+ // the attributes
+ if(!IS_ATTRIBUTE(nvIndex->publicArea.attributes, TPMA_NV, ORDERLY))
+ {
+ result = NvWriteNvIndexAttributes(s_cachedNvRef,
+ nvIndex->publicArea.attributes);
+ if(result != TPM_RC_SUCCESS)
+ return result;
+ // If this is a partial write of an ordinary index, clear the whole
+ // index.
+ if(IsNvOrdinaryIndex(nvIndex->publicArea.attributes)
+ && (nvIndex->publicArea.dataSize > size))
+ _plat__NvMemoryClear(s_cachedNvRef + sizeof(NV_INDEX),
+ nvIndex->publicArea.dataSize);
+ }
+ else
+ {
+ // This is orderly so update the RAM version
+ MemoryCopy(s_cachedNvRamRef + offsetof(NV_RAM_HEADER, attributes),
+ &nvIndex->publicArea.attributes, sizeof(TPMA_NV));
+ // If setting WRITTEN for an orderly counter, make sure that the
+ // state saved version of the counter is saved
+ if(IsNvCounterIndex(nvIndex->publicArea.attributes))
+ SET_NV_UPDATE(UT_ORDERLY);
+ // If setting the written attribute on an ordinary index, make sure that
+ // the data is all cleared out in case there is a partial write. This
+ // is only necessary for ordinary indexes because all of the other types
+ // are always written in total.
+ else if(IsNvOrdinaryIndex(nvIndex->publicArea.attributes))
+ MemorySet(s_cachedNvRamRef + sizeof(NV_RAM_HEADER),
+ 0, nvIndex->publicArea.dataSize);
+ }
+ }
+ // If this is orderly data, write it to RAM
+ if(IS_ATTRIBUTE(nvIndex->publicArea.attributes, TPMA_NV, ORDERLY))
+ {
+ // Note: if this is the first write to a counter, the code above will queue
+ // the write to NV of the RAM data in order to update TPMA_NV_WRITTEN. In
+ // process of doing that write, it will also write the initial counter value
+ // Update RAM
+ MemoryCopy(s_cachedNvRamRef + sizeof(NV_RAM_HEADER) + offset, data, size);
+ // And indicate that the TPM is no longer orderly
+ g_clearOrderly = TRUE;
+ }
+ else
+ {
+ // Offset into the index to the first byte of the data to be written to NV
+ result = NvConditionallyWrite(s_cachedNvRef + sizeof(NV_INDEX) + offset,
+ size, data);
+ }
+ return result;
+}
+/* 8.4.5.12 NvWriteUINT64Data() */
+/* This function to write back a UINT64 value. The various UINT64 values (bits, counters, and
+ PINs()) are kept in canonical format but manipulate in native format. This takes a native format
+ value converts it and saves it back as in canonical format. */
+/* This function will return the value from NV or RAM depending on the type of the index (orderly or
+ not) */
+TPM_RC
+NvWriteUINT64Data(
+ NV_INDEX *nvIndex, // IN: the description of the index
+ UINT64 intValue // IN: the value to write
+ )
+{
+ BYTE bytes[8];
+ UINT64_TO_BYTE_ARRAY(intValue, bytes);
+ return NvWriteIndexData(nvIndex, 0, 8, &bytes);
+}
+/* 8.4.5.13 NvGetIndexName() */
+/* This function computes the Name of an index The name buffer receives the bytes of the Name and
+ the return value is the number of octets in the Name. */
+/* This function requires that the NV Index is defined. */
+TPM2B_NAME *
+NvGetIndexName(
+ NV_INDEX *nvIndex, // IN: the index over which the name is to be
+ // computed
+ TPM2B_NAME *name // OUT: name of the index
+ )
+{
+ UINT16 dataSize, digestSize;
+ BYTE marshalBuffer[sizeof(TPMS_NV_PUBLIC)];
+ BYTE *buffer;
+ HASH_STATE hashState;
+ // Marshal public area
+ buffer = marshalBuffer;
+ dataSize = TPMS_NV_PUBLIC_Marshal(&nvIndex->publicArea, &buffer, NULL);
+ // hash public area
+ digestSize = CryptHashStart(&hashState, nvIndex->publicArea.nameAlg);
+ CryptDigestUpdate(&hashState, dataSize, marshalBuffer);
+ // Complete digest leaving room for the nameAlg
+ CryptHashEnd(&hashState, digestSize, &name->b.buffer[2]);
+ // Include the nameAlg
+ UINT16_TO_BYTE_ARRAY(nvIndex->publicArea.nameAlg, name->b.buffer);
+ name->t.size = digestSize + 2;
+ return name;
+}
+/* 8.4.5.14 NvGetNameByIndexHandle() */
+/* This function is used to compute the Name of an NV Index referenced by handle. */
+/* The name buffer receives the bytes of the Name and the return value is the number of octets in
+ the Name. */
+/* This function requires that the NV Index is defined. */
+TPM2B_NAME *
+NvGetNameByIndexHandle(
+ TPMI_RH_NV_INDEX handle, // IN: handle of the index
+ TPM2B_NAME *name // OUT: name of the index
+ )
+{
+ NV_INDEX *nvIndex = NvGetIndexInfo(handle, NULL);
+ return NvGetIndexName(nvIndex, name);
+}
+/* 8.4.5.15 NvDefineIndex() */
+/* This function is used to assign NV memory to an NV Index. */
+/* Error Returns Meaning */
+/* TPM_RC_NV_SPACE insufficient NV space */
+TPM_RC
+NvDefineIndex(
+ TPMS_NV_PUBLIC *publicArea, // IN: A template for an area to create.
+ TPM2B_AUTH *authValue // IN: The initial authorization value
+ )
+{
+
+ // The buffer to be written to NV memory
+ NV_INDEX nvIndex; // the index data
+ UINT16 entrySize; // size of entry
+ TPM_RC result;
+ //
+ entrySize = sizeof(NV_INDEX);
+ // only allocate data space for indexes that are going to be written to NV.
+ // Orderly indexes don't need space.
+ if(!IS_ATTRIBUTE(publicArea->attributes, TPMA_NV, ORDERLY))
+ entrySize += publicArea->dataSize;
+ // Check if we have enough space to create the NV Index
+ // In this implementation, the only resource limitation is the available NV
+ // space (and possibly RAM space.) Other implementation may have other
+ // limitation on counter or on NV slots
+ if(!NvTestSpace(entrySize, TRUE, IsNvCounterIndex(publicArea->attributes)))
+ return TPM_RC_NV_SPACE;
+ // if the index to be defined is RAM backed, check RAM space availability
+ // as well
+ if(IS_ATTRIBUTE(publicArea->attributes, TPMA_NV, ORDERLY)
+ && !NvRamTestSpaceIndex(publicArea->dataSize))
+ return TPM_RC_NV_SPACE;
+ // Copy input value to nvBuffer
+ nvIndex.publicArea = *publicArea;
+ // Copy the authValue
+ nvIndex.authValue = *authValue;
+ // Add index to NV memory
+ result = NvAdd(entrySize, sizeof(NV_INDEX), TPM_RH_UNASSIGNED,
+ (BYTE *)&nvIndex);
+ if(result == TPM_RC_SUCCESS)
+ {
+ // If the data of NV Index is RAM backed, add the data area in RAM as well
+ if(IS_ATTRIBUTE(publicArea->attributes, TPMA_NV, ORDERLY))
+ NvAddRAM(publicArea);
+ }
+ return result;
+}
+/* 8.4.5.16 NvAddEvictObject() */
+/* This function is used to assign NV memory to a persistent object. */
+/* Error Returns Meaning */
+/* TPM_RC_NV_HANDLE the requested handle is already in use */
+/* TPM_RC_NV_SPACE insufficient NV space */
+TPM_RC
+NvAddEvictObject(
+ TPMI_DH_OBJECT evictHandle, // IN: new evict handle
+ OBJECT *object // IN: object to be added
+ )
+{
+ TPM_HANDLE temp = object->evictHandle;
+ TPM_RC result;
+ // Check if we have enough space to add the evict object
+ // An evict object needs 8 bytes in index table + sizeof OBJECT
+ // In this implementation, the only resource limitation is the available NV
+ // space. Other implementation may have other limitation on evict object
+ // handle space
+ if(!NvTestSpace(sizeof(OBJECT) + sizeof(TPM_HANDLE), FALSE, FALSE))
+ return TPM_RC_NV_SPACE;
+ // Set evict attribute and handle
+ object->attributes.evict = SET;
+ object->evictHandle = evictHandle;
+ // Now put this in NV
+ result = NvAdd(sizeof(OBJECT), sizeof(OBJECT), evictHandle, (BYTE *)object);
+ // Put things back the way they were
+ object->attributes.evict = CLEAR;
+ object->evictHandle = temp;
+ return result;
+}
+/* 8.4.5.17 NvDeleteIndex() */
+/* This function is used to delete an NV Index. */
+/* Error Returns Meaning */
+/* TPM_RC_NV_UNAVAILABLE NV is not accessible */
+/* TPM_RC_NV_RATE NV is rate limiting */
+TPM_RC
+NvDeleteIndex(
+ NV_INDEX *nvIndex, // IN: an in RAM index descriptor
+ NV_REF entityAddr // IN: location in NV
+ )
+{
+ TPM_RC result;
+ //
+ if(nvIndex != NULL)
+ {
+ // Whenever a counter is deleted, make sure that the MaxCounter value is
+ // updated to reflect the value
+ if(IsNvCounterIndex(nvIndex->publicArea.attributes)
+ && IS_ATTRIBUTE(nvIndex->publicArea.attributes, TPMA_NV, WRITTEN))
+ NvUpdateMaxCount(NvGetUINT64Data(nvIndex, entityAddr));
+ result = NvDelete(entityAddr);
+ if(result != TPM_RC_SUCCESS)
+ return result;
+ // If the NV Index is RAM backed, delete the RAM data as well
+ if(IS_ATTRIBUTE(nvIndex->publicArea.attributes, TPMA_NV, ORDERLY))
+ NvDeleteRAM(nvIndex->publicArea.nvIndex);
+ NvIndexCacheInit();
+ }
+ return TPM_RC_SUCCESS;
+}
+/* 8.4.5.18 NvDeleteEvict() */
+/* This function will delete a NV evict object. Will return success if object deleted or if it does
+ not exist */
+TPM_RC
+NvDeleteEvict(
+ TPM_HANDLE handle // IN: handle of entity to be deleted
+ )
+{
+ NV_REF entityAddr = NvFindEvict(handle, NULL); // pointer to entity
+ TPM_RC result = TPM_RC_SUCCESS;
+ if(entityAddr != 0)
+ result = NvDelete(entityAddr);
+ return result;
+}
+/* 8.4.5.19 NvFlushHierarchy() */
+/* This function will delete persistent objects belonging to the indicated hierarchy. If the
+ storage hierarchy is selected, the function will also delete any NV Index defined using
+ ownerAuth. */
+/* Error Returns Meaning */
+/* TPM_RC_NV_RATE NV is unavailable because of rate limit */
+/* TPM_RC_NV_UNAVAILABLE NV is inaccessible */
+TPM_RC
+NvFlushHierarchy(
+ TPMI_RH_HIERARCHY hierarchy // IN: hierarchy to be flushed.
+ )
+{
+ NV_REF iter = NV_REF_INIT;
+ NV_REF currentAddr;
+ TPM_HANDLE entityHandle;
+ TPM_RC result = TPM_RC_SUCCESS;
+ //
+ while((currentAddr = NvNext(&iter, &entityHandle)) != 0)
+ {
+ if(HandleGetType(entityHandle) == TPM_HT_NV_INDEX)
+ {
+ NV_INDEX nvIndex;
+ //
+ // If flush endorsement or platform hierarchy, no NV Index would be
+ // flushed
+ if(hierarchy == TPM_RH_ENDORSEMENT || hierarchy == TPM_RH_PLATFORM)
+ continue;
+ // Get the index information
+ NvReadNvIndexInfo(currentAddr, &nvIndex);
+ // For storage hierarchy, flush OwnerCreated index
+ if(!IS_ATTRIBUTE(nvIndex.publicArea.attributes, TPMA_NV,
+ PLATFORMCREATE))
+ {
+ // Delete the index (including RAM for orderly)
+ result = NvDeleteIndex(&nvIndex, currentAddr);
+ if(result != TPM_RC_SUCCESS)
+ break;
+ // Re-iterate from beginning after a delete
+ iter = NV_REF_INIT;
+ }
+ }
+ else if(HandleGetType(entityHandle) == TPM_HT_PERSISTENT)
+ {
+ OBJECT_ATTRIBUTES attributes;
+ //
+ NvRead(&attributes,
+ (UINT32)(currentAddr
+ + sizeof(TPM_HANDLE)
+ + offsetof(OBJECT, attributes)),
+ sizeof(OBJECT_ATTRIBUTES));
+ // If the evict object belongs to the hierarchy to be flushed...
+ if((hierarchy == TPM_RH_PLATFORM && attributes.ppsHierarchy == SET)
+ || (hierarchy == TPM_RH_OWNER && attributes.spsHierarchy == SET)
+ || (hierarchy == TPM_RH_ENDORSEMENT
+ && attributes.epsHierarchy == SET))
+ {
+ // ...then delete the evict object
+ result = NvDelete(currentAddr);
+ if(result != TPM_RC_SUCCESS)
+ break;
+ // Re-iterate from beginning after a delete
+ iter = NV_REF_INIT;
+ }
+ }
+ else
+ {
+ FAIL(FATAL_ERROR_INTERNAL);
+ }
+ }
+ return result;
+}
+/* 8.4.5.20 NvSetGlobalLock() */
+/* This function is used to SET the TPMA_NV_WRITELOCKED attribute for all NV Indexes that have
+ TPMA_NV_GLOBALLOCK SET. This function is use by TPM2_NV_GlobalWriteLock(). */
+/* Error Returns Meaning */
+/* TPM_RC_NV_RATE NV is unavailable because of rate limit */
+/* TPM_RC_NV_UNAVAILABLE NV is inaccessible */
+TPM_RC
+NvSetGlobalLock(
+ void
+ )
+{
+ NV_REF iter = NV_REF_INIT;
+ NV_RAM_REF ramIter = NV_RAM_REF_INIT;
+ NV_REF currentAddr;
+ NV_RAM_REF currentRamAddr;
+ TPM_RC result = TPM_RC_SUCCESS;
+ //
+ // Check all normal indexes
+ while((currentAddr = NvNextIndex(NULL, &iter)) != 0)
+ {
+ TPMA_NV attributes = NvReadNvIndexAttributes(currentAddr);
+ //
+ // See if it should be locked
+ if(!IS_ATTRIBUTE(attributes, TPMA_NV, ORDERLY)
+ && IS_ATTRIBUTE(attributes, TPMA_NV, GLOBALLOCK))
+ {
+ SET_ATTRIBUTE(attributes, TPMA_NV, WRITELOCKED);
+ result = NvWriteNvIndexAttributes(currentAddr, attributes);
+ if(result != TPM_RC_SUCCESS)
+ return result;
+ }
+ }
+ // Now search all the orderly attributes
+ while((currentRamAddr = NvRamNext(&ramIter, NULL)) != 0)
+ {
+ // See if it should be locked
+ TPMA_NV attributes = NvReadRamIndexAttributes(currentRamAddr);
+ if(IS_ATTRIBUTE(attributes, TPMA_NV, GLOBALLOCK))
+ {
+ SET_ATTRIBUTE(attributes, TPMA_NV, WRITELOCKED);
+ NvWriteRamIndexAttributes(currentRamAddr, attributes);
+ }
+ }
+ return result;
+}
+/* 8.4.5.21 InsertSort() */
+/* Sort a handle into handle list in ascending order. The total handle number in the list should
+ not exceed MAX_CAP_HANDLES */
+static void
+InsertSort(
+ TPML_HANDLE *handleList, // IN/OUT: sorted handle list
+ UINT32 count, // IN: maximum count in the handle list
+ TPM_HANDLE entityHandle // IN: handle to be inserted
+ )
+{
+ UINT32 i, j;
+ UINT32 originalCount;
+ // For a corner case that the maximum count is 0, do nothing
+ if(count == 0)
+ return;
+ // For empty list, add the handle at the beginning and return
+ if(handleList->count == 0)
+ {
+ handleList->handle[0] = entityHandle;
+ handleList->count++;
+ return;
+ }
+ // Check if the maximum of the list has been reached
+ originalCount = handleList->count;
+ if(originalCount < count)
+ handleList->count++;
+ // Insert the handle to the list
+ for(i = 0; i < originalCount; i++)
+ {
+ if(handleList->handle[i] > entityHandle)
+ {
+ for(j = handleList->count - 1; j > i; j--)
+ {
+ handleList->handle[j] = handleList->handle[j - 1];
+ }
+ break;
+ }
+ }
+ // If a slot was found, insert the handle in this position
+ if(i < originalCount || handleList->count > originalCount)
+ handleList->handle[i] = entityHandle;
+ return;
+}
+/* 8.4.5.22 NvCapGetPersistent() */
+/* This function is used to get a list of handles of the persistent objects, starting at handle. */
+/* Handle must be in valid persistent object handle range, but does not have to reference an
+ existing persistent object. */
+/* Return Values Meaning */
+/* YES if there are more handles available */
+/* NO all the available handles has been returned */
+TPMI_YES_NO
+NvCapGetPersistent(
+ TPMI_DH_OBJECT handle, // IN: start handle
+ UINT32 count, // IN: maximum number of returned handles
+ TPML_HANDLE *handleList // OUT: list of handle
+ )
+{
+ TPMI_YES_NO more = NO;
+ NV_REF iter = NV_REF_INIT;
+ NV_REF currentAddr;
+ TPM_HANDLE entityHandle;
+ pAssert(HandleGetType(handle) == TPM_HT_PERSISTENT);
+ // Initialize output handle list
+ handleList->count = 0;
+ // The maximum count of handles we may return is MAX_CAP_HANDLES
+ if(count > MAX_CAP_HANDLES) count = MAX_CAP_HANDLES;
+ while((currentAddr = NvNextEvict(&entityHandle, &iter)) != 0)
+ {
+ // Ignore persistent handles that have values less than the input handle
+ if(entityHandle < handle)
+ continue;
+ // if the handles in the list have reached the requested count, and there
+ // are still handles need to be inserted, indicate that there are more.
+ if(handleList->count == count)
+ more = YES;
+ // A handle with a value larger than start handle is a candidate
+ // for return. Insert sort it to the return list. Insert sort algorithm
+ // is chosen here for simplicity based on the assumption that the total
+ // number of NV Indexes is small. For an implementation that may allow
+ // large number of NV Indexes, a more efficient sorting algorithm may be
+ // used here.
+ InsertSort(handleList, count, entityHandle);
+ }
+ return more;
+}
+/* 8.4.5.23 NvCapGetIndex() */
+/* This function returns a list of handles of NV Indexes, starting from handle. Handle must be in
+ the range of NV Indexes, but does not have to reference an existing NV Index. */
+/* Return Values Meaning */
+/* YES if there are more handles to report */
+/* NO all the available handles has been reported */
+TPMI_YES_NO
+NvCapGetIndex(
+ TPMI_DH_OBJECT handle, // IN: start handle
+ UINT32 count, // IN: max number of returned handles
+ TPML_HANDLE *handleList // OUT: list of handle
+ )
+{
+ TPMI_YES_NO more = NO;
+ NV_REF iter = NV_REF_INIT;
+ NV_REF currentAddr;
+ TPM_HANDLE nvHandle;
+ pAssert(HandleGetType(handle) == TPM_HT_NV_INDEX);
+ // Initialize output handle list
+ handleList->count = 0;
+ // The maximum count of handles we may return is MAX_CAP_HANDLES
+ if(count > MAX_CAP_HANDLES) count = MAX_CAP_HANDLES;
+ while((currentAddr = NvNextIndex(&nvHandle, &iter)) != 0)
+ {
+ // Ignore index handles that have values less than the 'handle'
+ if(nvHandle < handle)
+ continue;
+ // if the count of handles in the list has reached the requested count,
+ // and there are still handles to report, set more.
+ if(handleList->count == count)
+ more = YES;
+ // A handle with a value larger than start handle is a candidate
+ // for return. Insert sort it to the return list. Insert sort algorithm
+ // is chosen here for simplicity based on the assumption that the total
+ // number of NV Indexes is small. For an implementation that may allow
+ // large number of NV Indexes, a more efficient sorting algorithm may be
+ // used here.
+ InsertSort(handleList, count, nvHandle);
+ }
+ return more;
+}
+/* 8.4.5.24 NvCapGetIndexNumber() */
+/* This function returns the count of NV Indexes currently defined. */
+UINT32
+NvCapGetIndexNumber(
+ void
+ )
+{
+ UINT32 num = 0;
+ NV_REF iter = NV_REF_INIT;
+ while(NvNextIndex(NULL, &iter) != 0)
+ num++;
+ return num;
+}
+/* 8.4.5.25 NvCapGetPersistentNumber() */
+/* Function returns the count of persistent objects currently in NV memory. */
+UINT32
+NvCapGetPersistentNumber(
+ void
+ )
+{
+ UINT32 num = 0;
+ NV_REF iter = NV_REF_INIT;
+ TPM_HANDLE handle;
+ while(NvNextEvict(&handle, &iter) != 0)
+ num++;
+ return num;
+}
+/* 8.4.5.26 NvCapGetPersistentAvail() */
+/* This function returns an estimate of the number of additional persistent objects that could be
+ loaded into NV memory. */
+UINT32
+NvCapGetPersistentAvail(
+ void
+ )
+{
+ UINT32 availNVSpace;
+ UINT32 counterNum = NvCapGetCounterNumber();
+ UINT32 reserved = sizeof(NV_LIST_TERMINATOR);
+ // Get the available space in NV storage
+ availNVSpace = NvGetFreeBytes();
+ if(counterNum < MIN_COUNTER_INDICES)
+ {
+ // Some space has to be reserved for counter objects.
+ reserved += (MIN_COUNTER_INDICES - counterNum) * NV_INDEX_COUNTER_SIZE;
+ if(reserved > availNVSpace)
+ availNVSpace = 0;
+ else
+ availNVSpace -= reserved;
+ }
+ return availNVSpace / NV_EVICT_OBJECT_SIZE;
+}
+/* 8.4.5.27 NvCapGetCounterNumber() */
+/* Get the number of defined NV Indexes that are counter indexes. */
+UINT32
+NvCapGetCounterNumber(
+ void
+ )
+{
+ NV_REF iter = NV_REF_INIT;
+ NV_REF currentAddr;
+ UINT32 num = 0;
+ while((currentAddr = NvNextIndex(NULL, &iter)) != 0)
+ {
+ TPMA_NV attributes = NvReadNvIndexAttributes(currentAddr);
+ if(IsNvCounterIndex(attributes))
+ num++;
+ }
+ return num;
+}
+/* 8.4.5.28 NvSetStartupAttributes() */
+/* Local function to set the attributes of an Index at TPM Reset and TPM Restart. */
+static TPMA_NV
+NvSetStartupAttributes(
+ TPMA_NV attributes, // IN: attributes to change
+ STARTUP_TYPE type // IN: start up type
+ )
+{
+ // Clear read lock
+ CLEAR_ATTRIBUTE(attributes, TPMA_NV, READLOCKED);
+ // Will change a non counter index to the unwritten state if:
+ // a) TPMA_NV_CLEAR_STCLEAR is SET
+ // b) orderly and TPM Reset
+ if(!IsNvCounterIndex(attributes))
+ {
+ if(IS_ATTRIBUTE(attributes, TPMA_NV, CLEAR_STCLEAR)
+ || (IS_ATTRIBUTE(attributes, TPMA_NV, ORDERLY)
+ && (type == SU_RESET)))
+ CLEAR_ATTRIBUTE(attributes, TPMA_NV, WRITTEN);
+ }
+ // Unlock any index that is not written or that does not have
+ // TPMA_NV_WRITEDEFINE SET.
+ if(!IS_ATTRIBUTE(attributes, TPMA_NV, WRITTEN)
+ || !IS_ATTRIBUTE(attributes, TPMA_NV, WRITEDEFINE))
+ CLEAR_ATTRIBUTE(attributes, TPMA_NV, WRITELOCKED);
+ return attributes;
+}
+/* 8.4.5.29 NvEntityStartup() */
+/* This function is called at TPM_Startup(). If the startup completes a TPM Resume cycle, no action
+ is taken. If the startup is a TPM Reset or a TPM Restart, then this function will: */
+/* a) clear read/write lock; */
+/* b) reset NV Index data that has TPMA_NV_CLEAR_STCLEAR SET; and */
+/* c) set the lower bits in orderly counters to 1 for a non-orderly startup */
+/* It is a prerequisite that NV be available for writing before this function is called. */
+BOOL
+NvEntityStartup(
+ STARTUP_TYPE type // IN: start up type
+ )
+{
+ NV_REF iter = NV_REF_INIT;
+ NV_RAM_REF ramIter = NV_RAM_REF_INIT;
+ NV_REF currentAddr; // offset points to the current entity
+ NV_RAM_REF currentRamAddr;
+ TPM_HANDLE nvHandle;
+ TPMA_NV attributes;
+ // Restore RAM index data
+ NvRead(s_indexOrderlyRam, NV_INDEX_RAM_DATA, sizeof(s_indexOrderlyRam));
+ // Initialize the max NV counter value
+ NvSetMaxCount(NvGetMaxCount());
+ // If recovering from state save, do nothing else
+ if(type == SU_RESUME)
+ return TRUE;
+ // Iterate all the NV Index to clear the locks
+ while((currentAddr = NvNextIndex(&nvHandle, &iter)) != 0)
+ {
+ attributes = NvReadNvIndexAttributes(currentAddr);
+ // If this is an orderly index, defer processing until loop below
+ if(IS_ATTRIBUTE(attributes, TPMA_NV, ORDERLY))
+ continue;
+ // Set the attributes appropriate for this startup type
+ attributes = NvSetStartupAttributes(attributes, type);
+ NvWriteNvIndexAttributes(currentAddr, attributes);
+ }
+ // Iterate all the orderly indexes to clear the locks and initialize counters
+ while((currentRamAddr = NvRamNext(&ramIter, NULL)) != 0)
+ {
+ attributes = NvReadRamIndexAttributes(currentRamAddr);
+ attributes = NvSetStartupAttributes(attributes, type);
+ // update attributes in RAM
+ NvWriteRamIndexAttributes(currentRamAddr, attributes);
+ // Set the lower bits in an orderly counter to 1 for a non-orderly startup
+ if(IsNvCounterIndex(attributes)
+ && (g_prevOrderlyState == SU_NONE_VALUE))
+ {
+ UINT64 counter;
+ // Read the counter value last saved to NV.
+ counter = BYTE_ARRAY_TO_UINT64(currentRamAddr + sizeof(NV_RAM_HEADER));
+ // Set the lower bits of counter to 1's
+ counter |= MAX_ORDERLY_COUNT;
+ // Write back to RAM
+ // NOTE: Do not want to force a write to NV here. The counter value will
+ // stay in RAM until the next shutdown or rollover.
+ UINT64_TO_BYTE_ARRAY(counter, currentRamAddr + sizeof(NV_RAM_HEADER));
+ }
+ }
+ return TRUE;
+}
+/* 8.4.5.30 NvCapGetCounterAvail() */
+/* This function returns an estimate of the number of additional counter type NV Indexes that can be
+ defined. */
+UINT32
+NvCapGetCounterAvail(
+ void
+ )
+{
+ UINT32 availNVSpace;
+ UINT32 availRAMSpace;
+ UINT32 persistentNum = NvCapGetPersistentNumber();
+ UINT32 reserved = sizeof(NV_LIST_TERMINATOR);
+ // Get the available space in NV storage
+ availNVSpace = NvGetFreeBytes();
+ if(persistentNum < MIN_EVICT_OBJECTS)
+ {
+ // Some space has to be reserved for evict object. Adjust availNVSpace.
+ reserved += (MIN_EVICT_OBJECTS - persistentNum) * NV_EVICT_OBJECT_SIZE;
+ if(reserved > availNVSpace)
+ availNVSpace = 0;
+ else
+ availNVSpace -= reserved;
+ }
+ // Compute the available space in RAM
+ availRAMSpace = (RAM_ORDERLY_END - NvRamGetEnd()); /* kgold - removed cast */
+ // Return the min of counter number in NV and in RAM
+ if(availNVSpace / NV_INDEX_COUNTER_SIZE
+ > availRAMSpace / NV_RAM_INDEX_COUNTER_SIZE)
+ return availRAMSpace / NV_RAM_INDEX_COUNTER_SIZE;
+ else
+ return availNVSpace / NV_INDEX_COUNTER_SIZE;
+}
+/* 8.4.5.31 NvFindHandle() */
+/* this function returns the offset in NV memory of the entity associated with the input handle. A
+ value of zero indicates that handle does not exist reference an existing persistent object or
+ defined NV Index. */
+NV_REF
+NvFindHandle(
+ TPM_HANDLE handle
+ )
+{
+ NV_REF addr;
+ NV_REF iter = NV_REF_INIT;
+ TPM_HANDLE nextHandle;
+ while((addr = NvNext(&iter, &nextHandle)) != 0)
+ {
+ if(nextHandle == handle)
+ break;
+ }
+ return addr;
+}
+/* 8.4.6 NV Max Counter */
+/* 8.4.6.1 Introduction */
+/* The TPM keeps track of the highest value of a deleted counter index. When an index is deleted,
+ this value is updated if the deleted counter index is greater than the previous value. When a new
+ index is created and first incremented, it will get a value that is at least one greater than any
+ other index than any previously deleted index. This ensures that it is not possible to roll back
+ an index. */
+/* The highest counter value is kept in NV in a special end-of-list marker. This marker is only
+ updated when an index is deleted. Otherwise it just moves. */
+/* When the TPM starts up, it searches NV for the end of list marker and initializes an in memory
+ value (s_maxCounter). */
+/* 8.4.6.2 NvReadMaxCount() */
+/* This function returns the max NV counter value. */
+UINT64
+NvReadMaxCount(
+ void
+ )
+{
+ return s_maxCounter;
+}
+/* 8.4.6.3 NvUpdateMaxCount() */
+/* This function updates the max counter value to NV memory. This is just staging for the actual
+ write that will occur when the NV index memory is modified. */
+void
+NvUpdateMaxCount(
+ UINT64 count
+ )
+{
+ if(count > s_maxCounter)
+ s_maxCounter = count;
+}
+/* 8.4.6.4 NvSetMaxCount() */
+/* This function is used at NV initialization time to set the initial value of the maximum
+ counter. */
+void
+NvSetMaxCount(
+ UINT64 value
+ )
+{
+ s_maxCounter = value;
+}
+/* 8.4.6.5 NvGetMaxCount() */
+/* Function to get the NV max counter value from the end-of-list marker */
+UINT64
+NvGetMaxCount(
+ void
+ )
+{
+ NV_REF iter = NV_REF_INIT;
+ NV_REF currentAddr;
+ UINT64 maxCount;
+ // Find the end of list marker and initialize the NV Max Counter value.
+ while((currentAddr = NvNext(&iter, NULL )) != 0);
+ // 'iter' should be pointing at the end of list marker so read in the current
+ // value of the s_maxCounter.
+ NvRead(&maxCount, iter + sizeof(UINT32), sizeof(maxCount));
+ return maxCount;
+}
diff --git a/src/tpm2/NVDynamic_fp.h b/src/tpm2/NVDynamic_fp.h
new file mode 100644
index 0000000..376f1aa
--- /dev/null
+++ b/src/tpm2/NVDynamic_fp.h
@@ -0,0 +1,253 @@
+/********************************************************************************/
+/* */
+/* Dynamic space for user defined NV */
+/* Written by Ken Goldman */
+/* IBM Thomas J. Watson Research Center */
+/* $Id: NVDynamic_fp.h 1476 2019-06-10 19:32:03Z kgoldman $ */
+/* */
+/* Licenses and Notices */
+/* */
+/* 1. Copyright Licenses: */
+/* */
+/* - Trusted Computing Group (TCG) grants to the user of the source code in */
+/* this specification (the "Source Code") a worldwide, irrevocable, */
+/* nonexclusive, royalty free, copyright license to reproduce, create */
+/* derivative works, distribute, display and perform the Source Code and */
+/* derivative works thereof, and to grant others the rights granted herein. */
+/* */
+/* - The TCG grants to the user of the other parts of the specification */
+/* (other than the Source Code) the rights to reproduce, distribute, */
+/* display, and perform the specification solely for the purpose of */
+/* developing products based on such documents. */
+/* */
+/* 2. Source Code Distribution Conditions: */
+/* */
+/* - Redistributions of Source Code must retain the above copyright licenses, */
+/* this list of conditions and the following disclaimers. */
+/* */
+/* - Redistributions in binary form must reproduce the above copyright */
+/* licenses, this list of conditions and the following disclaimers in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* 3. Disclaimers: */
+/* */
+/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
+/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
+/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
+/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
+/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
+/* information on specification licensing rights available through TCG */
+/* membership agreements. */
+/* */
+/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
+/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
+/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
+/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
+/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
+/* */
+/* - Without limitation, TCG and its members and licensors disclaim all */
+/* liability, including liability for infringement of any proprietary */
+/* rights, relating to use of information in this specification and to the */
+/* implementation of this specification, and TCG disclaims all liability for */
+/* cost of procurement of substitute goods or services, lost profits, loss */
+/* of use, loss of data or any incidental, consequential, direct, indirect, */
+/* or special damages, whether under contract, tort, warranty or otherwise, */
+/* arising in any way out of use or reliance upon this specification or any */
+/* information herein. */
+/* */
+/* (c) Copyright IBM Corp. and others, 2016 - 2019 */
+/* */
+/********************************************************************************/
+
+#ifndef NVDYNAMIC_FP_H
+#define NVDYNAMIC_FP_H
+
+NV_REF
+NvWriteNvListEnd(
+ NV_REF end
+ );
+void
+NvUpdateIndexOrderlyData(
+ void
+ );
+void
+NvReadNvIndexInfo(
+ NV_REF ref, // IN: points to NV where index is located
+ NV_INDEX *nvIndex // OUT: place to receive index data
+ );
+void
+NvReadObject(
+ NV_REF ref, // IN: points to NV where index is located
+ OBJECT *object // OUT: place to receive the object data
+ );
+BOOL
+NvIndexIsDefined(
+ TPM_HANDLE nvHandle // IN: Index to look for
+ );
+BOOL
+NvIsPlatformPersistentHandle(
+ TPM_HANDLE handle // IN: handle
+ );
+BOOL
+NvIsOwnerPersistentHandle(
+ TPM_HANDLE handle // IN: handle
+ );
+TPM_RC
+NvIndexIsAccessible(
+ TPMI_RH_NV_INDEX handle // IN: handle
+ );
+TPM_RC
+NvGetEvictObject(
+ TPM_HANDLE handle, // IN: handle
+ OBJECT *object // OUT: object data
+ );
+void
+NvIndexCacheInit(
+ void
+ );
+void
+NvGetIndexData(
+ NV_INDEX *nvIndex, // IN: the in RAM index descriptor
+ NV_REF locator, // IN: where the data is located
+ UINT32 offset, // IN: offset of NV data
+ UINT16 size, // IN: size of NV data
+ void *data // OUT: data buffer
+ );
+void
+NvHashIndexData(
+ HASH_STATE *hashState, // IN: Initialized hash state
+ NV_INDEX *nvIndex, // IN: Index
+ NV_REF locator, // IN: where the data is located
+ UINT32 offset, // IN: starting offset
+ UINT16 size // IN: amount to hash
+ );
+UINT64
+NvGetUINT64Data(
+ NV_INDEX *nvIndex, // IN: the in RAM index descriptor
+ NV_REF locator // IN: where index exists in NV
+ );
+TPM_RC
+NvWriteIndexAttributes(
+ TPM_HANDLE handle,
+ NV_REF locator, // IN: location of the index
+ TPMA_NV attributes // IN: attributes to write
+ );
+TPM_RC
+NvWriteIndexAuth(
+ NV_REF locator, // IN: location of the index
+ TPM2B_AUTH *authValue // IN: the authValue to write
+ );
+NV_INDEX *
+NvGetIndexInfo(
+ TPM_HANDLE nvHandle, // IN: the index handle
+ NV_REF *locator // OUT: location of the index
+ );
+TPM_RC
+NvWriteIndexData(
+ NV_INDEX *nvIndex, // IN: the description of the index
+ UINT32 offset, // IN: offset of NV data
+ UINT32 size, // IN: size of NV data
+ void *data // IN: data buffer
+ );
+TPM_RC
+NvWriteUINT64Data(
+ NV_INDEX *nvIndex, // IN: the description of the index
+ UINT64 intValue // IN: the value to write
+ );
+TPM2B_NAME *
+NvGetIndexName(
+ NV_INDEX *nvIndex, // IN: the index over which the name is to be
+ // computed
+ TPM2B_NAME *name // OUT: name of the index
+ );
+TPM2B_NAME *
+NvGetNameByIndexHandle(
+ TPMI_RH_NV_INDEX handle, // IN: handle of the index
+ TPM2B_NAME *name // OUT: name of the index
+ );
+TPM_RC
+NvDefineIndex(
+ TPMS_NV_PUBLIC *publicArea, // IN: A template for an area to create.
+ TPM2B_AUTH *authValue // IN: The initial authorization value
+ );
+TPM_RC
+NvAddEvictObject(
+ TPMI_DH_OBJECT evictHandle, // IN: new evict handle
+ OBJECT *object // IN: object to be added
+ );
+TPM_RC
+NvDeleteIndex(
+ NV_INDEX *nvIndex, // IN: an in RAM index descriptor
+ NV_REF entityAddr // IN: location in NV
+ );
+TPM_RC
+NvDeleteEvict(
+ TPM_HANDLE handle // IN: handle of entity to be deleted
+ );
+TPM_RC
+NvFlushHierarchy(
+ TPMI_RH_HIERARCHY hierarchy // IN: hierarchy to be flushed.
+ );
+TPM_RC
+NvSetGlobalLock(
+ void
+ );
+TPMI_YES_NO
+NvCapGetPersistent(
+ TPMI_DH_OBJECT handle, // IN: start handle
+ UINT32 count, // IN: maximum number of returned handles
+ TPML_HANDLE *handleList // OUT: list of handle
+ );
+TPMI_YES_NO
+NvCapGetIndex(
+ TPMI_DH_OBJECT handle, // IN: start handle
+ UINT32 count, // IN: max number of returned handles
+ TPML_HANDLE *handleList // OUT: list of handle
+ );
+UINT32
+NvCapGetIndexNumber(
+ void
+ );
+UINT32
+NvCapGetPersistentNumber(
+ void
+ );
+UINT32
+NvCapGetPersistentAvail(
+ void
+ );
+UINT32
+NvCapGetCounterNumber(
+ void
+ );
+BOOL
+NvEntityStartup(
+ STARTUP_TYPE type // IN: start up type
+ );
+UINT32
+NvCapGetCounterAvail(
+ void
+ );
+NV_REF
+NvFindHandle(
+ TPM_HANDLE handle
+ );
+UINT64
+NvReadMaxCount(
+ void
+ );
+void
+NvUpdateMaxCount(
+ UINT64 count
+ );
+void
+NvSetMaxCount(
+ UINT64 value
+ );
+UINT64
+NvGetMaxCount(
+ void
+ );
+
+
+#endif
diff --git a/src/tpm2/NVMarshal.c b/src/tpm2/NVMarshal.c
new file mode 100644
index 0000000..c7cd1e0
--- /dev/null
+++ b/src/tpm2/NVMarshal.c
@@ -0,0 +1,4916 @@
+/********************************************************************************/
+/* */
+/* Marshalling and unmarshalling of state */
+/* Written by Stefan Berger */
+/* IBM Thomas J. Watson Research Center */
+/* */
+/* (c) Copyright IBM Corporation 2017,2018. */
+/* */
+/* All rights reserved. */
+/* */
+/* Redistribution and use in source and binary forms, with or without */
+/* modification, are permitted provided that the following conditions are */
+/* met: */
+/* */
+/* Redistributions of source code must retain the above copyright notice, */
+/* this list of conditions and the following disclaimer. */
+/* */
+/* Redistributions in binary form must reproduce the above copyright */
+/* notice, this list of conditions and the following disclaimer in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* Neither the names of the IBM Corporation nor the names of its */
+/* contributors may be used to endorse or promote products derived from */
+/* this software without specific prior written permission. */
+/* */
+/* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS */
+/* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT */
+/* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR */
+/* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT */
+/* HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, */
+/* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT */
+/* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, */
+/* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY */
+/* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT */
+/* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE */
+/* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */
+/********************************************************************************/
+
+#include <string.h>
+#include <inttypes.h>
+
+#include "assert.h"
+
+#define _CRYPT_HASH_C_
+#define SESSION_PROCESS_C
+#define NV_C
+#define OBJECT_C
+#define PCR_C
+#define SESSION_C
+#include "Platform.h"
+#include "NVMarshal.h"
+#include "Marshal_fp.h"
+#include "Unmarshal_fp.h"
+#include "Global.h"
+#include "TpmTcpProtocol.h"
+#include "Simulator_fp.h"
+
+#define TPM_HAVE_TPM2_DECLARATIONS
+#include "tpm_library_intern.h"
+
+/*
+ * The TPM2 maintains a pcrAllocated shadow variable; the current active one is
+ * in gp.pcrAllocated and the one to be active after reboot is in NVRAM. So,
+ * this means we have to restore two of these variables when we resume. The
+ * tricky part is that the global gp will be restored by reading from NVRAM.
+ * Once that has been done the gp.pcrAllocated needs to be restored with the
+ * one that is supposed to be active. All of this is only supposed to happen
+ * when we resume a VM's volatile state.
+ */
+static struct shadow {
+ TPML_PCR_SELECTION pcrAllocated;
+ BOOL pcrAllocatedIsNew;
+} shadow;
+
+/* prevent misconfiguration: */
+typedef char assertion_failed_nvram[
+ (NV_USER_DYNAMIC_END < NV_USER_DYNAMIC) ? -1 : 0];
+
+typedef struct
+{
+ UINT16 version;
+ UINT32 magic;
+ UINT16 min_version; /* min. implementation version to accept the blob */
+} NV_HEADER;
+
+static UINT8 BOOL_Marshal(BOOL *boolean, BYTE **buffer, INT32 *size);
+static TPM_RC BOOL_Unmarshal(BOOL *boolean, BYTE **buffer, INT32 *size);
+
+/*
+ * There are compile-time optional variables that we marshal. To allow
+ * for some flexibility, we marshal them in such a way that these
+ * variables can be skipped if they are in the byte stream but are not
+ * needed by the implementation. The following block_skip data structure
+ * and related functions address this issue.
+ */
+typedef struct {
+ size_t idx;
+ size_t sz;
+ struct position {
+ BYTE *buffer;
+ INT32 size;
+ } pos[5]; /* more only needed for nested compile-time #ifdef's */
+} block_skip;
+
+/*
+ * This function is to be called when an optional block follows. It inserts
+ * a BOOL into the byte stream indicating whether the block is there or not.
+ * Then it leaves a 16bit zero in the byt stream and remembers the location
+ * of that zero. We will update the location with the number of optional
+ * bytes written when block_skip_write_pop() is called.
+ */
+static UINT16
+block_skip_write_push(block_skip *bs, BOOL has_block,
+ BYTE **buffer, INT32 *size) {
+ UINT16 written , w;
+ UINT16 zero = 0;
+ written = BOOL_Marshal(&has_block, buffer, size);
+ bs->pos[bs->idx].buffer = *buffer;
+ bs->pos[bs->idx].size = *size;
+ w = UINT16_Marshal(&zero, buffer, size);
+ if (w) {
+ bs->idx++;
+ pAssert(bs->idx < bs->sz);
+ written += w;
+ }
+ return written;
+}
+
+/*
+ * This function must be called for every block_skip_write_push() call.
+ * It has to be called once a compile-time optional block has been
+ * processed. It must be called after the #endif.
+ * In this function we updated the previously remembered location with
+ * the numbers of bytes to skip in case a block is there but it is not
+ * needed.
+ */
+static void
+block_skip_write_pop(block_skip *bs, INT32 *size) {
+ UINT16 skip;
+ unsigned i = --bs->idx;
+ pAssert((int)bs->idx >= 0);
+ skip = bs->pos[i].size - *size - sizeof(UINT16);
+ UINT16_Marshal(&skip, &bs->pos[i].buffer, &bs->pos[i].size);
+}
+
+/*
+ * This function must be called when unmarshalling a byte stream and
+ * a compile-time optional block follows. In case the compile-time
+ * optional block is there but not in the byte stream, we log an error.
+ * In case the bytes stream contains the block, but we don't need it
+ * we skip it. In the other cases we don't need to do anything since
+ * the code is 'in sync' with the byte stream.
+ */
+static TPM_RC
+block_skip_read(BOOL needs_block, BYTE **buffer, INT32 *size,
+ const char *name, const char *field,
+ BOOL *skip_code)
+{
+ TPM_RC rc = TPM_RC_SUCCESS;
+ BOOL has_block;
+ UINT16 blocksize;
+
+ if (rc == TPM_RC_SUCCESS) {
+ rc = BOOL_Unmarshal(&has_block, buffer, size);
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ rc = UINT16_Unmarshal(&blocksize, buffer, size);
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ if (!has_block && needs_block) {
+ TPMLIB_LogTPM2Error("%s needs missing %s\n", name, field);
+ rc = TPM_RC_BAD_PARAMETER;
+ } else if (has_block && !needs_block) {
+ /* byte stream has the data but we don't need them */
+ *buffer += blocksize;
+ *size -= blocksize;
+ *skip_code = TRUE;
+ }
+ }
+ return rc;
+}
+
+#define BLOCK_SKIP_INIT \
+ block_skip block_skip = { \
+ .idx = 0, \
+ .sz = ARRAY_SIZE(block_skip.pos), \
+ }
+
+#define BLOCK_SKIP_WRITE_PUSH(HAS_BLOCK, BUFFER, POS) \
+ block_skip_write_push(&block_skip, HAS_BLOCK, BUFFER, POS)
+
+#define BLOCK_SKIP_WRITE_POP(SIZE) \
+ block_skip_write_pop(&block_skip, SIZE)
+
+#define BLOCK_SKIP_WRITE_CHECK \
+ pAssert(block_skip.idx == 0)
+
+#define BLOCK_SKIP_READ(SKIP_MARK, NEEDS_BLOCK, BUFFER, SIZE, NAME, FIELD) \
+ { \
+ BOOL skip_code = FALSE; \
+ rc = block_skip_read(NEEDS_BLOCK, buffer, size, \
+ NAME, FIELD, &skip_code); \
+ if (rc == TPM_RC_SUCCESS && skip_code) \
+ goto SKIP_MARK; \
+ }
+
+static unsigned int _ffsll(long long bits)
+{
+ size_t i = 0;
+
+ for (i = 0; i < 8 * sizeof(bits); i++) {
+ if (bits & (1ULL << i))
+ return i + 1;
+ }
+ return 0;
+}
+
+/* BOOL is 'int' but we store a single byte */
+static UINT8
+BOOL_Marshal(BOOL *boolean, BYTE **buffer, INT32 *size)
+{
+ UINT8 _bool = (*boolean != 0);
+ UINT16 written = 0;
+ written += UINT8_Marshal(&_bool, buffer, size);
+ return written;
+}
+
+static TPM_RC
+BOOL_Unmarshal(BOOL *boolean, BYTE **buffer, INT32 *size)
+{
+ UINT8 _bool;
+ TPM_RC rc = TPM_RC_SUCCESS;
+
+ if (rc == TPM_RC_SUCCESS) {
+ rc = UINT8_Unmarshal(&_bool, buffer, size);
+ }
+
+ if (rc == TPM_RC_SUCCESS) {
+ *boolean = (_bool != 0);
+ }
+
+ return rc;
+}
+
+static UINT16
+SEED_COMPAT_LEVEL_Marshal(SEED_COMPAT_LEVEL *source,
+ BYTE **buffer, INT32 *size)
+{
+ return UINT8_Marshal((UINT8 *)source, buffer, size);
+}
+
+static TPM_RC
+SEED_COMPAT_LEVEL_Unmarshal(SEED_COMPAT_LEVEL *source,
+ BYTE **buffer, INT32 *size,
+ const char *name)
+{
+ TPM_RC rc;
+
+ rc = UINT8_Unmarshal((UINT8 *)source, buffer, size);
+ if (rc == TPM_RC_SUCCESS && *source > SEED_COMPAT_LEVEL_LAST) {
+ TPMLIB_LogTPM2Error("%s compatLevel '%u' higher than supported '%u'\n",
+ name, *source, SEED_COMPAT_LEVEL_LAST);
+ rc = TPM_RC_BAD_VERSION;
+ }
+ return rc;
+}
+
+static int
+TPM2B_Cmp(const TPM2B *t1, const TPM2B *t2)
+{
+ if (t1->size != t2->size)
+ return 1;
+
+ return memcmp(t1->buffer, t2->buffer, t1->size);
+}
+
+static UINT16
+TPM2B_PROOF_Marshal(TPM2B_PROOF *source, BYTE **buffer, INT32 *size)
+{
+ UINT16 written = 0;
+ written += TPM2B_Marshal(&source->b, sizeof(source->t.buffer), buffer, size);
+ return written;
+}
+
+static TPM_RC
+TPM2B_PROOF_Unmarshal(TPM2B_PROOF *target, BYTE **buffer, INT32 *size)
+{
+ TPM_RC rc = TPM_RC_SUCCESS;
+
+ if (rc == TPM_RC_SUCCESS) {
+ rc = TPM2B_Unmarshal(&target->b, sizeof(target->t.buffer), buffer, size);
+ }
+ return rc;
+}
+
+static TPM_RC
+UINT32_Unmarshal_Check(UINT32 *data, UINT32 exp, BYTE **buffer, INT32 *size,
+ const char *msg)
+{
+ TPM_RC rc = TPM_RC_SUCCESS;
+
+ if (rc == TPM_RC_SUCCESS) {
+ rc = UINT32_Unmarshal(data, buffer, size);
+ }
+ if (rc == TPM_RC_SUCCESS && exp != *data) {
+ TPMLIB_LogTPM2Error("%s: Expected value: 0x%08x, found: 0x%08x\n",
+ __func__, exp, *data);
+ rc = TPM_RC_BAD_TAG;
+ }
+ return rc;
+}
+
+static void
+NV_HEADER_INIT(NV_HEADER *t, UINT16 version, UINT32 magic, UINT16 min_version)
+{
+ t->version = version;
+ t->magic = magic;
+ t->min_version = min_version;
+}
+
+static UINT16
+NV_HEADER_Marshal(BYTE **buffer, INT32 *size, UINT16 version, UINT32 magic,
+ UINT16 min_version)
+{
+ UINT16 written;
+ NV_HEADER hdr;
+
+ NV_HEADER_INIT(&hdr, version, magic, min_version);
+
+ written = UINT16_Marshal(&hdr.version, buffer, size);
+ written += UINT32_Marshal(&hdr.magic, buffer, size);
+ if (version >= 2)
+ written += UINT16_Marshal(&hdr.min_version, buffer, size);
+
+ return written;
+}
+
+static TPM_RC
+NV_HEADER_UnmarshalVerbose(NV_HEADER *data, BYTE **buffer, INT32 *size,
+ UINT16 cur_version, UINT32 exp_magic, BOOL verbose)
+{
+ TPM_RC rc = TPM_RC_SUCCESS;
+
+ if (rc == TPM_RC_SUCCESS) {
+ rc = UINT16_Unmarshal(&data->version, buffer, size);
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ rc = UINT32_Unmarshal(&data->magic, buffer, size);
+ }
+ if (rc == TPM_RC_SUCCESS && exp_magic != data->magic) {
+ if (verbose)
+ TPMLIB_LogTPM2Error("%s: Invalid magic. Expected 0x%08x, got 0x%08x\n",
+ __func__, exp_magic, data->magic);
+ rc = TPM_RC_BAD_TAG;
+ }
+
+ data->min_version = 0;
+ if (rc == TPM_RC_SUCCESS && data->version >= 2) {
+
+ rc = UINT16_Unmarshal(&data->min_version, buffer, size);
+
+ if (rc == TPM_RC_SUCCESS && data->min_version > cur_version) {
+ if (verbose)
+ TPMLIB_LogTPM2Error("%s: Minimum version %u higher than "
+ "implementation version %u for type 0x%08x\n",
+ __func__, data->min_version, cur_version,
+ exp_magic);
+ rc = TPM_RC_BAD_VERSION;
+ }
+ }
+
+ return rc;
+}
+
+static TPM_RC
+NV_HEADER_Unmarshal(NV_HEADER *data, BYTE **buffer, INT32 *size,
+ UINT16 cur_version, UINT32 exp_magic)
+{
+ return NV_HEADER_UnmarshalVerbose(data, buffer, size, cur_version,
+ exp_magic, true);
+}
+
+#define NV_INDEX_MAGIC 0x2547265a
+#define NV_INDEX_VERSION 2
+static UINT16
+NV_INDEX_Marshal(NV_INDEX *data, BYTE **buffer, INT32 *size)
+{
+ UINT16 written;
+ BLOCK_SKIP_INIT;
+
+ written = NV_HEADER_Marshal(buffer, size,
+ NV_INDEX_VERSION,
+ NV_INDEX_MAGIC, 1);
+
+ written += TPMS_NV_PUBLIC_Marshal(&data->publicArea, buffer, size);
+ written += TPM2B_AUTH_Marshal(&data->authValue, buffer, size);
+
+ written += BLOCK_SKIP_WRITE_PUSH(TRUE, buffer, size);
+ /* future versions append below this line */
+
+ BLOCK_SKIP_WRITE_POP(size);
+
+ BLOCK_SKIP_WRITE_CHECK;
+
+ return written;
+}
+
+static TPM_RC
+NV_INDEX_Unmarshal(NV_INDEX *data, BYTE **buffer, INT32 *size)
+{
+ TPM_RC rc = TPM_RC_SUCCESS;
+ NV_HEADER hdr;
+
+ if (rc == TPM_RC_SUCCESS) {
+ rc = NV_HEADER_Unmarshal(&hdr, buffer, size,
+ NV_INDEX_VERSION, NV_INDEX_MAGIC);
+ }
+
+ if (rc == TPM_RC_SUCCESS) {
+ rc = TPMS_NV_PUBLIC_Unmarshal(&data->publicArea, buffer, size);
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ rc = TPM2B_AUTH_Unmarshal(&data->authValue, buffer, size);
+ }
+
+ /* version 2 starts having indicator for next versions that we can skip;
+ this allows us to downgrade state */
+ if (rc == TPM_RC_SUCCESS && hdr.version >= 2) {
+ BLOCK_SKIP_READ(skip_future_versions, FALSE, buffer, size,
+ "NV_INDEX", "version 3 or later");
+ /* future versions nest-append here */
+ }
+skip_future_versions:
+ return rc;
+}
+
+#define DRBG_STATE_MAGIC 0x6fe83ea1
+#define DRBG_STATE_VERSION 2
+static UINT16
+DRBG_STATE_Marshal(DRBG_STATE *data, BYTE **buffer, INT32 *size)
+{
+ UINT16 written;
+ size_t i;
+ UINT16 array_size;
+ BLOCK_SKIP_INIT;
+
+ written = NV_HEADER_Marshal(buffer, size,
+ DRBG_STATE_VERSION, DRBG_STATE_MAGIC, 1);
+ written += UINT64_Marshal(&data->reseedCounter, buffer, size);
+ written += UINT32_Marshal(&data->magic, buffer, size);
+
+ array_size = sizeof(data->seed.bytes);
+ written += UINT16_Marshal(&array_size, buffer, size);
+ written += Array_Marshal(&data->seed.bytes[0], array_size, buffer, size);
+
+ array_size = ARRAY_SIZE(data->lastValue);
+ written += UINT16_Marshal(&array_size, buffer, size);
+ for (i = 0; i < array_size; i++) {
+ written += UINT32_Marshal(&data->lastValue[i], buffer, size);
+ }
+
+ written += BLOCK_SKIP_WRITE_PUSH(TRUE, buffer, size);
+ /* future versions append below this line */
+
+ BLOCK_SKIP_WRITE_POP(size);
+
+ BLOCK_SKIP_WRITE_CHECK;
+
+ return written;
+}
+
+static TPM_RC
+DRBG_STATE_Unmarshal(DRBG_STATE *data, BYTE **buffer, INT32 *size)
+{
+ TPM_RC rc= TPM_RC_SUCCESS;
+ size_t i;
+ NV_HEADER hdr;
+ UINT16 array_size = 0;
+
+ if (rc == TPM_RC_SUCCESS) {
+ rc = NV_HEADER_Unmarshal(&hdr, buffer, size,
+ DRBG_STATE_VERSION, DRBG_STATE_MAGIC);
+ }
+
+ if (rc == TPM_RC_SUCCESS) {
+ rc = UINT64_Unmarshal(&data->reseedCounter, buffer, size);
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ rc = UINT32_Unmarshal(&data->magic, buffer, size);
+ }
+
+ if (rc == TPM_RC_SUCCESS) {
+ rc = UINT16_Unmarshal(&array_size, buffer, size);
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ if (array_size != ARRAY_SIZE(data->seed.bytes)) {
+ TPMLIB_LogTPM2Error("Non-matching DRBG_STATE seed array size. "
+ "Expected %zu, got %u\n",
+ ARRAY_SIZE(data->seed.bytes), array_size);
+ rc = TPM_RC_SIZE;
+ }
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ rc = Array_Unmarshal(&data->seed.bytes[0], array_size, buffer, size);
+ }
+
+ if (rc == TPM_RC_SUCCESS) {
+ rc = UINT16_Unmarshal(&array_size, buffer, size);
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ if (array_size != ARRAY_SIZE(data->lastValue)) {
+ TPMLIB_LogTPM2Error("Non-matching DRBG_STATE lastValue array size. "
+ "Expected %zu, got %u\n",
+ ARRAY_SIZE(data->lastValue), array_size);
+ rc = TPM_RC_SIZE;
+ }
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ for (i = 0; i < ARRAY_SIZE(data->lastValue) && rc == TPM_RC_SUCCESS; i++) {
+ rc = UINT32_Unmarshal(&data->lastValue[i], buffer, size);
+ }
+ }
+
+ /* version 2 starts having indicator for next versions that we can skip;
+ this allows us to downgrade state */
+ if (rc == TPM_RC_SUCCESS && hdr.version >= 2) {
+ BLOCK_SKIP_READ(skip_future_versions, FALSE, buffer, size,
+ "DRBG_STATE", "version 3 or later");
+ /* future versions nest-append here */
+ }
+skip_future_versions:
+
+ return rc;
+}
+
+#define PCR_POLICY_MAGIC 0x176be626
+#define PCR_POLICY_VERSION 2
+static UINT16
+PCR_POLICY_Marshal(PCR_POLICY *data, BYTE **buffer, INT32 *size)
+{
+ UINT16 written;
+ unsigned i;
+ UINT16 array_size = ARRAY_SIZE(data->hashAlg);
+ BLOCK_SKIP_INIT;
+
+ written = NV_HEADER_Marshal(buffer, size,
+ PCR_POLICY_VERSION,
+ PCR_POLICY_MAGIC, 1);
+
+ written += UINT16_Marshal(&array_size, buffer, size);
+
+ for (i = 0; i < array_size; i++) {
+ /* TPMI_ALG_HASH_Unmarshal errors on algid 0 */
+ written += TPM_ALG_ID_Marshal(&data->hashAlg[i], buffer, size);
+ written += TPM2B_DIGEST_Marshal(&data->policy[i], buffer, size);
+ }
+
+ written += BLOCK_SKIP_WRITE_PUSH(TRUE, buffer, size);
+ /* future versions append below this line */
+
+ BLOCK_SKIP_WRITE_POP(size);
+
+ BLOCK_SKIP_WRITE_CHECK;
+
+ return written;
+}
+
+static TPM_RC
+PCR_POLICY_Unmarshal(PCR_POLICY *data, BYTE **buffer, INT32 *size)
+{
+ TPM_RC rc= TPM_RC_SUCCESS;
+ unsigned i;
+ UINT16 array_size;
+ NV_HEADER hdr;
+
+ if (rc == TPM_RC_SUCCESS) {
+ rc = NV_HEADER_Unmarshal(&hdr, buffer, size,
+ PCR_POLICY_VERSION, PCR_POLICY_MAGIC);
+ }
+
+ if (rc == TPM_RC_SUCCESS) {
+ rc = UINT16_Unmarshal(&array_size, buffer, size);
+ }
+
+ if (rc == TPM_RC_SUCCESS) {
+ if (array_size != ARRAY_SIZE(data->hashAlg)) {
+ TPMLIB_LogTPM2Error("Non-matching PCR_POLICY array size. "
+ "Expected %zu, got %u\n",
+ ARRAY_SIZE(data->hashAlg), array_size);
+ rc = TPM_RC_SIZE;
+ }
+ }
+
+ for (i = 0;
+ rc == TPM_RC_SUCCESS &&
+ i < ARRAY_SIZE(data->hashAlg);
+ i++) {
+ /* TPMI_ALG_HASH_Unmarshal errors on algid 0 */
+ if (rc == TPM_RC_SUCCESS) {
+ rc = TPM_ALG_ID_Unmarshal(&data->hashAlg[i], buffer, size);
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ rc = TPM2B_DIGEST_Unmarshal(&data->policy[i], buffer, size);
+ }
+ }
+
+ /* version 2 starts having indicator for next versions that we can skip;
+ this allows us to downgrade state */
+ if (rc == TPM_RC_SUCCESS && hdr.version >= 2) {
+ BLOCK_SKIP_READ(skip_future_versions, FALSE, buffer, size,
+ "PCR_POLICY", "version 3 or later");
+ /* future versions nest-append here */
+ }
+skip_future_versions:
+ return rc;
+}
+
+#define ORDERLY_DATA_MAGIC 0x56657887
+#define ORDERLY_DATA_VERSION 2
+
+static UINT16
+ORDERLY_DATA_Marshal(ORDERLY_DATA *data, BYTE **buffer, INT32 *size)
+{
+ UINT16 written;
+ BOOL has_block;
+ BLOCK_SKIP_INIT;
+
+ written = NV_HEADER_Marshal(buffer, size,
+ ORDERLY_DATA_VERSION, ORDERLY_DATA_MAGIC, 1);
+ written += UINT64_Marshal(&data->clock, buffer, size);
+ written += UINT8_Marshal(&data->clockSafe, buffer, size);
+
+ written += DRBG_STATE_Marshal(&data->drbgState, buffer, size);
+
+#if ACCUMULATE_SELF_HEAL_TIMER
+ has_block = TRUE;
+#else
+ has_block = FALSE;
+#endif
+ written += BLOCK_SKIP_WRITE_PUSH(has_block, buffer, size);
+
+#if ACCUMULATE_SELF_HEAL_TIMER
+ written += UINT64_Marshal(&data->selfHealTimer, buffer, size);
+ written += UINT64_Marshal(&data->lockoutTimer, buffer, size);
+ written += UINT64_Marshal(&data->time, buffer, size);
+#endif // ACCUMULATE_SELF_HEAL_TIMER
+
+ BLOCK_SKIP_WRITE_POP(size);
+
+ written += BLOCK_SKIP_WRITE_PUSH(TRUE, buffer, size);
+ /* future versions append below this line */
+
+ BLOCK_SKIP_WRITE_POP(size);
+
+ BLOCK_SKIP_WRITE_CHECK;
+
+ return written;
+}
+
+static TPM_RC
+ORDERLY_DATA_Unmarshal(ORDERLY_DATA *data, BYTE **buffer, INT32 *size)
+{
+ TPM_RC rc = TPM_RC_SUCCESS;
+ BOOL needs_block;
+ NV_HEADER hdr;
+
+ if (rc == TPM_RC_SUCCESS) {
+ rc = NV_HEADER_Unmarshal(&hdr, buffer, size,
+ ORDERLY_DATA_VERSION, ORDERLY_DATA_MAGIC);
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ rc = UINT64_Unmarshal(&data->clock, buffer, size);
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ rc = UINT8_Unmarshal(&data->clockSafe, buffer, size);
+ }
+
+ if (rc == TPM_RC_SUCCESS) {
+ rc = DRBG_STATE_Unmarshal(&data->drbgState, buffer, size);
+ }
+
+#if ACCUMULATE_SELF_HEAL_TIMER
+ needs_block = TRUE;
+#else
+ needs_block = FALSE;
+#endif
+ if (rc == TPM_RC_SUCCESS) {
+ BLOCK_SKIP_READ(skip_self_heal_timer, needs_block, buffer, size,
+ "ORDERLY_DATA", "selfHealTimer");
+ }
+#if ACCUMULATE_SELF_HEAL_TIMER
+ if (rc == TPM_RC_SUCCESS) {
+ rc = UINT64_Unmarshal(&data->selfHealTimer, buffer, size);
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ rc = UINT64_Unmarshal(&data->lockoutTimer, buffer, size);
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ rc = UINT64_Unmarshal(&data->time, buffer, size);
+ }
+#endif // ACCUMULATE_SELF_HEAL_TIMER
+skip_self_heal_timer:
+
+ /* version 2 starts having indicator for next versions that we can skip;
+ this allows us to downgrade state */
+ if (rc == TPM_RC_SUCCESS && hdr.version >= 2) {
+ BLOCK_SKIP_READ(skip_future_versions, FALSE, buffer, size,
+ "ORDERLY_DATA", "version 3 or later");
+ /* future versions nest-append here */
+ }
+skip_future_versions:
+
+ return rc;
+}
+
+#define PCR_SAVE_MAGIC 0x7372eabc
+#define PCR_SAVE_VERSION 2
+static UINT16
+PCR_SAVE_Marshal(PCR_SAVE *data, BYTE **buffer, INT32 *size)
+{
+ UINT16 written = 0;
+ TPM_ALG_ID algid;
+ UINT16 array_size;
+ BLOCK_SKIP_INIT;
+
+ written = NV_HEADER_Marshal(buffer, size,
+ PCR_SAVE_VERSION, PCR_SAVE_MAGIC, 1);
+
+ array_size = NUM_STATIC_PCR;
+ written += UINT16_Marshal(&array_size, buffer, size);
+
+#if ALG_SHA1
+ algid = TPM_ALG_SHA1;
+ written += TPM_ALG_ID_Marshal(&algid, buffer, size);
+
+ array_size = sizeof(data->Sha1);
+ written += UINT16_Marshal(&array_size, buffer, size);
+ written += Array_Marshal((BYTE *)&data->Sha1, array_size,
+ buffer, size);
+#endif
+#if ALG_SHA256
+ algid = TPM_ALG_SHA256;
+ written += TPM_ALG_ID_Marshal(&algid, buffer, size);
+
+ array_size = sizeof(data->Sha256);
+ written += UINT16_Marshal(&array_size, buffer, size);
+ written += Array_Marshal((BYTE *)&data->Sha256, array_size,
+ buffer, size);
+#endif
+#if ALG_SHA384
+ algid = TPM_ALG_SHA384;
+ written += TPM_ALG_ID_Marshal(&algid, buffer, size);
+
+ array_size = sizeof(data->Sha384);
+ written += UINT16_Marshal(&array_size, buffer, size);
+ written += Array_Marshal((BYTE *)&data->Sha384, array_size,
+ buffer, size);
+#endif
+#if ALG_SHA512
+ algid = TPM_ALG_SHA512;
+ written += TPM_ALG_ID_Marshal(&algid, buffer, size);
+
+ array_size = sizeof(data->Sha512);
+ written += UINT16_Marshal(&array_size, buffer, size);
+ written += Array_Marshal((BYTE *)&data->Sha512, array_size,
+ buffer, size);
+#endif
+#if ALG_SM3_256
+ algid = TPM_ALG_SM3_256;
+ written += TPM_ALG_ID_Marshal(&algid, buffer, size);
+
+ array_size = sizeof(data->Sm3_256);
+ written += UINT16_Marshal(&array_size, buffer, size);
+ written += Array_Marshal((BYTE *)&data->Sm3_256, array_size,
+ buffer, size);
+#endif
+#if ALG_SHA3_256 || ALG_SHA3_384 || ALG_SHA3_512 || ALG_SM3_256
+#error SHA3 and SM3 are not supported
+#endif
+
+ /* end marker */
+ algid = TPM_ALG_NULL;
+ written += TPM_ALG_ID_Marshal(&algid, buffer, size);
+
+ written += BLOCK_SKIP_WRITE_PUSH(TRUE, buffer, size);
+ /* future versions append below this line */
+
+ BLOCK_SKIP_WRITE_POP(size);
+
+ BLOCK_SKIP_WRITE_CHECK;
+
+ return written;
+}
+
+/*
+ * Get the PCR banks that are active so that we know what PCRs need to be
+ * restored. Only data for active PCR banks needs to restored, inactive PCR
+ * banks need no data restored.
+ */
+static UINT64
+pcrbanks_algs_active(const TPML_PCR_SELECTION *pcrAllocated)
+{
+ UINT64 algs_active = 0;
+ unsigned i, j;
+
+ for(i = 0; i < pcrAllocated->count; i++) {
+ for (j = 0; j < pcrAllocated->pcrSelections[i].sizeofSelect; j++) {
+ if (pcrAllocated->pcrSelections[i].pcrSelect[j]) {
+ algs_active |= 1 << pcrAllocated->pcrSelections[i].hash;
+ break;
+ }
+ }
+ }
+
+ return algs_active;
+}
+
+static TPM_RC
+PCR_SAVE_Unmarshal(PCR_SAVE *data, BYTE **buffer, INT32 *size,
+ const TPML_PCR_SELECTION *pcrAllocated)
+{
+ TPM_RC rc = TPM_RC_SUCCESS;
+ UINT16 array_size, needed_size = 0;
+ NV_HEADER hdr;
+ TPM_ALG_ID algid;
+ BOOL end = FALSE;
+ BYTE *t = NULL;
+ UINT64 algs_needed = pcrbanks_algs_active(pcrAllocated);
+
+ if (rc == TPM_RC_SUCCESS) {
+ rc = NV_HEADER_Unmarshal(&hdr, buffer, size,
+ PCR_SAVE_VERSION, PCR_SAVE_MAGIC);
+ }
+
+ if (rc == TPM_RC_SUCCESS) {
+ rc = UINT16_Unmarshal(&array_size, buffer, size);
+ }
+ if (rc == TPM_RC_SUCCESS &&
+ array_size != NUM_STATIC_PCR) {
+ TPMLIB_LogTPM2Error("Non-matching PCR_SAVE NUM_STATIC_PCR. "
+ "Expected %zu, got %u\n",
+ sizeof(NUM_STATIC_PCR), array_size);
+ rc = TPM_RC_SIZE;
+ }
+
+ while (rc == TPM_RC_SUCCESS && !end) {
+ if (rc == TPM_RC_SUCCESS) {
+ rc = TPM_ALG_ID_Unmarshal(&algid, buffer, size);
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ switch (algid) {
+#if ALG_SHA1
+ case TPM_ALG_SHA1:
+ needed_size = sizeof(data->Sha1);
+ t = (BYTE *)&data->Sha1;
+ break;
+#endif
+#if ALG_SHA256
+ case TPM_ALG_SHA256:
+ needed_size = sizeof(data->Sha256);
+ t = (BYTE *)&data->Sha256;
+ break;
+#endif
+#if ALG_SHA384
+ case TPM_ALG_SHA384:
+ needed_size = sizeof(data->Sha384);
+ t = (BYTE *)&data->Sha384;
+ break;
+#endif
+#if ALG_SHA512
+ case TPM_ALG_SHA512:
+ needed_size = sizeof(data->Sha512);
+ t = (BYTE *)&data->Sha512;
+ break;
+#endif
+#if ALG_SM3_256
+ case TPM_ALG_SM3_256:
+ needed_size = sizeof(data->Sm3_256);
+ t = (BYTE *)&data->Sm3_256;
+ break;
+#endif
+#if ALG_SHA3_256 || ALG_SHA3_384 || ALG_SHA3_512 || ALG_SM3_256
+#error SHA3 and SM3 are not supported
+#endif
+ case TPM_ALG_NULL:
+ /* end marker */
+ end = TRUE;
+ t = NULL;
+ break;
+ default:
+ TPMLIB_LogTPM2Error("PCR_SAVE: Unsupported algid %d.",
+ algid);
+ rc = TPM_RC_BAD_PARAMETER;
+ t = NULL;
+ }
+ }
+ if (t) {
+ if (rc == TPM_RC_SUCCESS) {
+ algs_needed &= ~(1 << algid);
+ rc = UINT16_Unmarshal(&array_size, buffer, size);
+ }
+ if (rc == TPM_RC_SUCCESS && array_size != needed_size) {
+ TPMLIB_LogTPM2Error("PCR_SAVE: Bad size for PCRs for hash 0x%x; "
+ "Expected %u, got %d\n",
+ algid, needed_size, array_size);
+ rc = TPM_RC_BAD_PARAMETER;
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ rc = Array_Unmarshal(t, array_size, buffer, size);
+ }
+ }
+ }
+
+ if (rc == TPM_RC_SUCCESS && algs_needed) {
+ TPMLIB_LogTPM2Error("PCR_SAVE: Missing data for hash algorithm %d.\n",
+ _ffsll(algs_needed) - 1);
+ rc = TPM_RC_BAD_PARAMETER;
+ }
+
+ /* version 2 starts having indicator for next versions that we can skip;
+ this allows us to downgrade state */
+ if (rc == TPM_RC_SUCCESS && hdr.version >= 2) {
+ BLOCK_SKIP_READ(skip_future_versions, FALSE, buffer, size,
+ "PCR_SAVE", "version 3 or later");
+ /* future versions nest-append here */
+ }
+skip_future_versions:
+
+ return rc;
+}
+
+
+#ifdef PCR_C
+
+#define PCR_MAGIC 0xe95f0387
+#define PCR_VERSION 2
+static UINT16
+PCR_Marshal(PCR *data, BYTE **buffer, INT32 *size)
+{
+ UINT16 written;
+ TPM_ALG_ID algid;
+ UINT16 array_size;
+ BLOCK_SKIP_INIT;
+
+ written = NV_HEADER_Marshal(buffer, size,
+ PCR_VERSION, PCR_MAGIC, 1);
+
+#if ALG_SHA1
+ algid = TPM_ALG_SHA1;
+ written += TPM_ALG_ID_Marshal(&algid, buffer, size);
+
+ array_size = sizeof(data->Sha1Pcr);
+ written += UINT16_Marshal(&array_size, buffer, size);
+ written += Array_Marshal((BYTE *)&data->Sha1Pcr, array_size,
+ buffer, size);
+#endif
+#if ALG_SHA256
+ algid = TPM_ALG_SHA256;
+ written += TPM_ALG_ID_Marshal(&algid, buffer, size);
+
+ array_size = sizeof(data->Sha256Pcr);
+ written += UINT16_Marshal(&array_size, buffer, size);
+ written += Array_Marshal((BYTE *)&data->Sha256Pcr, array_size,
+ buffer, size);
+#endif
+#if ALG_SHA384
+ algid = TPM_ALG_SHA384;
+ written += TPM_ALG_ID_Marshal(&algid, buffer, size);
+
+ array_size = sizeof(data->Sha384Pcr);
+ written += UINT16_Marshal(&array_size, buffer, size);
+ written += Array_Marshal((BYTE *)&data->Sha384Pcr, array_size,
+ buffer, size);
+#endif
+#if ALG_SHA512
+ algid = TPM_ALG_SHA512;
+ written += TPM_ALG_ID_Marshal(&algid, buffer, size);
+
+ array_size = sizeof(data->Sha512Pcr);
+ written += UINT16_Marshal(&array_size, buffer, size);
+ written += Array_Marshal((BYTE *)&data->Sha512Pcr, array_size,
+ buffer, size);
+#endif
+#if ALG_SM3_256
+ algid = TPM_ALG_SM3_256;
+ written += TPM_ALG_ID_Marshal(&algid, buffer, size);
+
+ array_size = sizeof(data->Sm3_256Pcr);
+ written += UINT16_Marshal(&array_size, buffer, size);
+ written += Array_Marshal((BYTE *)&data->Sm3_256Pcr, array_size,
+ buffer, size);
+#endif
+#if ALG_SHA3_256 || ALG_SHA3_384 || ALG_SHA3_512 || ALG_SM3_256
+#error SHA3 and SM3 are not supported
+#endif
+
+ /* end marker */
+ algid = TPM_ALG_NULL;
+ written += TPM_ALG_ID_Marshal(&algid, buffer, size);
+
+ written += BLOCK_SKIP_WRITE_PUSH(TRUE, buffer, size);
+ /* future versions append below this line */
+
+ BLOCK_SKIP_WRITE_POP(size);
+
+ BLOCK_SKIP_WRITE_CHECK;
+
+ return written;
+}
+
+static TPM_RC
+PCR_Unmarshal(PCR *data, BYTE **buffer, INT32 *size,
+ const TPML_PCR_SELECTION *pcrAllocated)
+{
+ TPM_RC rc = TPM_RC_SUCCESS;
+ NV_HEADER hdr;
+ BOOL end = FALSE;
+ BYTE *t = NULL;
+ UINT16 needed_size = 0, array_size;
+ TPM_ALG_ID algid;
+ UINT64 algs_needed = pcrbanks_algs_active(pcrAllocated);
+
+ if (rc == TPM_RC_SUCCESS) {
+ rc = NV_HEADER_Unmarshal(&hdr, buffer, size,
+ PCR_VERSION, PCR_MAGIC);
+ }
+
+ while (rc == TPM_RC_SUCCESS && !end) {
+ if (rc == TPM_RC_SUCCESS) {
+ rc = TPM_ALG_ID_Unmarshal(&algid, buffer, size);
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ switch (algid) {
+#if ALG_SHA1
+ case TPM_ALG_SHA1:
+ needed_size = sizeof(data->Sha1Pcr);
+ t = (BYTE *)&data->Sha1Pcr;
+ break;
+#endif
+#if ALG_SHA256
+ case TPM_ALG_SHA256:
+ needed_size = sizeof(data->Sha256Pcr);
+ t = (BYTE *)&data->Sha256Pcr;
+ break;
+#endif
+#if ALG_SHA384
+ case TPM_ALG_SHA384:
+ needed_size = sizeof(data->Sha384Pcr);
+ t = (BYTE *)&data->Sha384Pcr;
+ break;
+#endif
+#if ALG_SHA512
+ case TPM_ALG_SHA512:
+ needed_size = sizeof(data->Sha512Pcr);
+ t = (BYTE *)&data->Sha512Pcr;
+ break;
+#endif
+#if ALG_SM3_256
+ case TPM_ALG_SM3_256:
+ needed_size = sizeof(data->Sm3_256Pcr);
+ t = (BYTE *)&data->Sm3_256Pcr;
+ break;
+#endif
+#if ALG_SHA3_256 || ALG_SHA3_384 || ALG_SHA3_512 || ALG_SM3_256
+#error SHA3 and SM3 are not supported
+#endif
+ case TPM_ALG_NULL:
+ /* end marker */
+ end = TRUE;
+ t = NULL;
+ break;
+ default:
+ TPMLIB_LogTPM2Error("PCR: Unsupported algid %d.",
+ algid);
+ rc = TPM_RC_BAD_PARAMETER;
+ t = NULL;
+ }
+ }
+ if (t) {
+ if (rc == TPM_RC_SUCCESS) {
+ algs_needed &= ~(1 << algid);
+ rc = UINT16_Unmarshal(&array_size, buffer, size);
+ }
+ if (rc == TPM_RC_SUCCESS && array_size != needed_size) {
+ TPMLIB_LogTPM2Error("PCR: Bad size for PCR for hash 0x%x; "
+ "Expected %u, got %d\n",
+ algid, needed_size, array_size);
+ rc = TPM_RC_BAD_PARAMETER;
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ rc = Array_Unmarshal(t, array_size, buffer, size);
+ }
+ }
+ }
+
+ if (rc == TPM_RC_SUCCESS && algs_needed) {
+ TPMLIB_LogTPM2Error("PCR: Missing data for hash algorithm %d.\n",
+ _ffsll(algs_needed) - 1);
+ rc = TPM_RC_BAD_PARAMETER;
+ }
+
+ /* version 2 starts having indicator for next versions that we can skip;
+ this allows us to downgrade state */
+ if (rc == TPM_RC_SUCCESS && hdr.version >= 2) {
+ BLOCK_SKIP_READ(skip_future_versions, FALSE, buffer, size,
+ "PCR", "version 3 or later");
+ /* future versions nest-append here */
+ }
+skip_future_versions:
+
+ return rc;
+}
+#endif
+
+#define PCR_AUTHVALUE_MAGIC 0x6be82eaf
+#define PCR_AUTHVALUE_VERSION 2
+static UINT16
+PCR_AUTHVALUE_Marshal(PCR_AUTHVALUE *data, BYTE **buffer, INT32 *size)
+{
+ UINT16 written;
+ size_t i;
+ UINT16 array_size;
+ BLOCK_SKIP_INIT;
+
+ written = NV_HEADER_Marshal(buffer, size,
+ PCR_AUTHVALUE_VERSION, PCR_AUTHVALUE_MAGIC, 1);
+
+ array_size = ARRAY_SIZE(data->auth);
+ written += UINT16_Marshal(&array_size, buffer, size);
+ for (i = 0; i < array_size; i++) {
+ written += TPM2B_DIGEST_Marshal(&data->auth[i], buffer, size);
+ }
+
+ written += BLOCK_SKIP_WRITE_PUSH(TRUE, buffer, size);
+ /* future versions append below this line */
+
+ BLOCK_SKIP_WRITE_POP(size);
+
+ BLOCK_SKIP_WRITE_CHECK;
+
+ return written;
+}
+
+static TPM_RC
+PCR_AUTHVALUE_Unmarshal(PCR_AUTHVALUE *data, BYTE **buffer, INT32 *size)
+{
+ TPM_RC rc = TPM_RC_SUCCESS;
+ size_t i;
+ NV_HEADER hdr;
+ UINT16 array_size = 0;
+
+ if (rc == TPM_RC_SUCCESS) {
+ rc = NV_HEADER_Unmarshal(&hdr, buffer, size,
+ PCR_AUTHVALUE_VERSION, PCR_AUTHVALUE_MAGIC);
+ }
+
+ if (rc == TPM_RC_SUCCESS) {
+ rc = UINT16_Unmarshal(&array_size, buffer, size);
+ }
+ if (rc == TPM_RC_SUCCESS &&
+ array_size != ARRAY_SIZE(data->auth)) {
+ TPMLIB_LogTPM2Error("PCR_AUTHVALUE: Bad array size for auth; "
+ "expected %zu, got %u\n",
+ ARRAY_SIZE(data->auth), array_size);
+ rc = TPM_RC_BAD_PARAMETER;
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ for (i = 0; i < ARRAY_SIZE(data->auth) && rc == TPM_RC_SUCCESS; i++) {
+ rc = TPM2B_DIGEST_Unmarshal(&data->auth[i], buffer, size);
+ }
+ }
+
+ /* version 2 starts having indicator for next versions that we can skip;
+ this allows us to downgrade state */
+ if (rc == TPM_RC_SUCCESS && hdr.version >= 2) {
+ BLOCK_SKIP_READ(skip_future_versions, FALSE, buffer, size,
+ "PCR_AUTHVALUE", "version 3 or later");
+ /* future versions nest-append here */
+ }
+skip_future_versions:
+
+ return rc;
+}
+
+#define STATE_CLEAR_DATA_MAGIC 0x98897667
+#define STATE_CLEAR_DATA_VERSION 2
+
+static UINT16
+STATE_CLEAR_DATA_Marshal(STATE_CLEAR_DATA *data, BYTE **buffer, INT32 *size)
+{
+ UINT16 written;
+ BLOCK_SKIP_INIT;
+
+ written = NV_HEADER_Marshal(buffer, size,
+ STATE_CLEAR_DATA_VERSION,
+ STATE_CLEAR_DATA_MAGIC, 1);
+ written += BOOL_Marshal(&data->shEnable, buffer, size);
+ written += BOOL_Marshal(&data->ehEnable, buffer, size);
+ written += BOOL_Marshal(&data->phEnableNV, buffer, size);
+ written += UINT16_Marshal(&data->platformAlg, buffer, size);
+ written += TPM2B_DIGEST_Marshal(&data->platformPolicy, buffer, size);
+ written += TPM2B_AUTH_Marshal(&data->platformAuth, buffer, size);
+ written += PCR_SAVE_Marshal(&data->pcrSave, buffer, size);
+ written += PCR_AUTHVALUE_Marshal(&data->pcrAuthValues, buffer, size);
+
+ written += BLOCK_SKIP_WRITE_PUSH(TRUE, buffer, size);
+ /* future versions append below this line */
+
+ BLOCK_SKIP_WRITE_POP(size);
+
+ BLOCK_SKIP_WRITE_CHECK;
+
+ return written;
+}
+
+static TPM_RC
+STATE_CLEAR_DATA_Unmarshal(STATE_CLEAR_DATA *data, BYTE **buffer, INT32 *size)
+{
+ TPM_RC rc = TPM_RC_SUCCESS;
+ NV_HEADER hdr;
+
+ if (rc == TPM_RC_SUCCESS) {
+ rc = NV_HEADER_Unmarshal(&hdr, buffer, size,
+ STATE_CLEAR_DATA_VERSION,
+ STATE_CLEAR_DATA_MAGIC);
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ rc = BOOL_Unmarshal(&data->shEnable, buffer, size);
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ rc = BOOL_Unmarshal(&data->ehEnable, buffer, size);
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ rc = BOOL_Unmarshal(&data->phEnableNV, buffer, size);
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ rc = UINT16_Unmarshal(&data->platformAlg, buffer, size);
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ rc = TPM2B_DIGEST_Unmarshal(&data->platformPolicy, buffer, size);
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ rc = TPM2B_AUTH_Unmarshal(&data->platformAuth, buffer, size);
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ rc = PCR_SAVE_Unmarshal(&data->pcrSave, buffer, size, &shadow.pcrAllocated);
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ rc = PCR_AUTHVALUE_Unmarshal(&data->pcrAuthValues, buffer, size);
+ }
+
+ /* version 2 starts having indicator for next versions that we can skip;
+ this allows us to downgrade state */
+ if (rc == TPM_RC_SUCCESS && hdr.version >= 2) {
+ BLOCK_SKIP_READ(skip_future_versions, FALSE, buffer, size,
+ "STATE_CLEAR_DATA", "version 3 or later");
+ /* future versions nest-append here */
+ }
+skip_future_versions:
+
+ return rc;
+}
+
+#define STATE_RESET_DATA_MAGIC 0x01102332
+#define STATE_RESET_DATA_VERSION 4
+
+static TPM_RC
+STATE_RESET_DATA_Unmarshal(STATE_RESET_DATA *data, BYTE **buffer, INT32 *size)
+{
+ TPM_RC rc = TPM_RC_SUCCESS;
+ BOOL needs_block;
+ UINT16 array_size;
+ NV_HEADER hdr;
+
+ if (rc == TPM_RC_SUCCESS) {
+ rc = NV_HEADER_Unmarshal(&hdr, buffer, size,
+ STATE_RESET_DATA_VERSION,
+ STATE_RESET_DATA_MAGIC);
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ rc = TPM2B_PROOF_Unmarshal(&data->nullProof, buffer, size);
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ rc = TPM2B_Unmarshal(&data->nullSeed.b, PRIMARY_SEED_SIZE, buffer, size);
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ rc = UINT32_Unmarshal(&data->clearCount, buffer, size);
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ rc = UINT64_Unmarshal(&data->objectContextID, buffer, size);
+ }
+
+
+ if (rc == TPM_RC_SUCCESS) {
+ rc = UINT16_Unmarshal(&array_size, buffer, size);
+ }
+ if (rc == TPM_RC_SUCCESS &&
+ array_size != ARRAY_SIZE(data->contextArray)) {
+ TPMLIB_LogTPM2Error("STATE_RESET_DATA: Bad array size for contextArray; "
+ "expected %zu, got %u\n",
+ ARRAY_SIZE(data->contextArray), array_size);
+ rc = TPM_RC_BAD_PARAMETER;
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ size_t i;
+ if (hdr.version <= 3) {
+ /* version <= 3 was writing an array of UINT8 */
+ UINT8 element;
+ for (i = 0; i < array_size && rc == TPM_RC_SUCCESS; i++) {
+ rc = UINT8_Unmarshal(&element, buffer, size);
+ data->contextArray[i] = element;
+ }
+ s_ContextSlotMask = 0xff;
+ } else {
+ /* version 4 and later an array of UINT16 */
+ for (i = 0; i < array_size && rc == TPM_RC_SUCCESS; i++) {
+ rc = UINT16_Unmarshal(&data->contextArray[i], buffer, size);
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ rc = UINT16_Unmarshal(&s_ContextSlotMask, buffer, size);
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ if (s_ContextSlotMask != 0xffff && s_ContextSlotMask != 0x00ff) {
+ TPMLIB_LogTPM2Error("STATE_RESET_DATA: s_ContextSlotMask has bad value: 0x%04x\n",
+ s_ContextSlotMask);
+ rc = TPM_RC_BAD_PARAMETER;
+ }
+ }
+ }
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ rc = UINT64_Unmarshal(&data->contextCounter, buffer, size);
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ rc = TPM2B_DIGEST_Unmarshal(&data->commandAuditDigest,
+ buffer, size);
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ rc = UINT32_Unmarshal(&data->restartCount, buffer, size);
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ rc = UINT32_Unmarshal(&data->pcrCounter, buffer, size);
+ }
+
+#if ALG_ECC
+ needs_block = TRUE;
+#else
+ needs_block = FALSE;
+#endif
+ if (rc == TPM_RC_SUCCESS) {
+ BLOCK_SKIP_READ(skip_alg_ecc, needs_block, buffer, size,
+ "STATE_RESET_DATA", "commitCounter");
+ }
+#if ALG_ECC
+ if (rc == TPM_RC_SUCCESS) {
+ rc = UINT64_Unmarshal(&data->commitCounter, buffer, size);
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ rc = TPM2B_AUTH_Unmarshal(&data->commitNonce, buffer, size);
+ }
+
+ if (rc == TPM_RC_SUCCESS) {
+ rc = UINT16_Unmarshal(&array_size, buffer, size);
+ }
+ if (rc == TPM_RC_SUCCESS &&
+ array_size != sizeof(data->commitArray)) {
+ TPMLIB_LogTPM2Error("STATE_RESET_DATA: Bad array size for commitArray; "
+ "expected %zu, got %u\n",
+ sizeof(data->commitArray), array_size);
+ rc = TPM_RC_BAD_PARAMETER;
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ rc = Array_Unmarshal((BYTE *)&data->commitArray, array_size,
+ buffer, size);
+ }
+#endif
+skip_alg_ecc:
+
+ /* default values before conditional block */
+ data->nullSeedCompatLevel = SEED_COMPAT_LEVEL_ORIGINAL;
+
+ /* version 2 starts having indicator for next versions that we can skip;
+ this allows us to downgrade state */
+ if (rc == TPM_RC_SUCCESS && hdr.version >= 2) {
+ BLOCK_SKIP_READ(skip_future_versions, hdr.version >= 3, buffer, size,
+ "STATE_RESET_DATA", "version 3 or later");
+ if (rc == TPM_RC_SUCCESS) {
+ rc = SEED_COMPAT_LEVEL_Unmarshal(&gr.nullSeedCompatLevel,
+ buffer, size, "nullSeed");
+ }
+
+ if (rc == TPM_RC_SUCCESS) {
+ BLOCK_SKIP_READ(skip_future_versions, FALSE, buffer, size,
+ "STATE_RESET_DATA", "version 4 or later");
+ }
+ /* future versions nest-append here */
+ }
+
+skip_future_versions:
+
+ return rc;
+}
+
+static UINT16
+STATE_RESET_DATA_Marshal(STATE_RESET_DATA *data, BYTE **buffer, INT32 *size)
+{
+ UINT16 written;
+ BOOL has_block;
+ UINT16 array_size;
+ BLOCK_SKIP_INIT;
+ size_t i;
+
+ written = NV_HEADER_Marshal(buffer, size,
+ STATE_RESET_DATA_VERSION,
+ STATE_RESET_DATA_MAGIC, 4);
+ written += TPM2B_PROOF_Marshal(&data->nullProof, buffer, size);
+ written += TPM2B_Marshal(&data->nullSeed.b, sizeof(data->nullSeed.t.buffer), buffer, size);
+ written += UINT32_Marshal(&data->clearCount, buffer, size);
+ written += UINT64_Marshal(&data->objectContextID, buffer, size);
+
+ array_size = ARRAY_SIZE(data->contextArray);
+ written += UINT16_Marshal(&array_size, buffer, size);
+ for (i = 0; i < array_size; i++)
+ written += UINT16_Marshal(&data->contextArray[i], buffer, size);
+
+ if (s_ContextSlotMask != 0x00ff && s_ContextSlotMask != 0xffff) {
+ /* TPM wasn't initialized, so s_ContextSlotMask wasn't set */
+ s_ContextSlotMask = 0xffff;
+ }
+ written += UINT16_Marshal(&s_ContextSlotMask, buffer, size);
+
+ written += UINT64_Marshal(&data->contextCounter, buffer, size);
+ written += TPM2B_DIGEST_Marshal(&data->commandAuditDigest,
+ buffer, size);
+ written += UINT32_Marshal(&data->restartCount, buffer, size);
+ written += UINT32_Marshal(&data->pcrCounter, buffer, size);
+#if ALG_ECC
+ has_block = TRUE;
+#else
+ has_block = FALSE;
+#endif
+ written += BLOCK_SKIP_WRITE_PUSH(has_block, buffer, size);
+
+#if ALG_ECC
+ written += UINT64_Marshal(&data->commitCounter, buffer, size);
+ written += TPM2B_AUTH_Marshal(&data->commitNonce, buffer, size);
+
+ array_size = sizeof(data->commitArray);
+ written += UINT16_Marshal(&array_size, buffer, size);
+ written += Array_Marshal((BYTE *)&data->commitArray, array_size,
+ buffer, size);
+#endif
+ BLOCK_SKIP_WRITE_POP(size);
+
+ written += BLOCK_SKIP_WRITE_PUSH(TRUE, buffer, size);
+ written += SEED_COMPAT_LEVEL_Marshal(&data->nullSeedCompatLevel,
+ buffer, size);
+
+ written += BLOCK_SKIP_WRITE_PUSH(TRUE, buffer, size);
+ /* future versions append below this line */
+
+ BLOCK_SKIP_WRITE_POP(size);
+ BLOCK_SKIP_WRITE_POP(size);
+
+ BLOCK_SKIP_WRITE_CHECK;
+
+ return written;
+}
+
+#define BN_PRIME_T_MAGIC 0x2fe736ab
+#define BN_PRIME_T_VERSION 2
+static UINT16
+bn_prime_t_Marshal(bn_prime_t *data, BYTE **buffer, INT32 *size)
+{
+ UINT16 written, numbytes;
+ size_t i, idx;
+ BLOCK_SKIP_INIT;
+
+ written = NV_HEADER_Marshal(buffer, size,
+ BN_PRIME_T_VERSION, BN_PRIME_T_MAGIC, 1);
+
+ /* we do not write 'allocated' */
+ numbytes = data->size * sizeof(crypt_uword_t);
+ written += UINT16_Marshal(&numbytes, buffer, size);
+
+ for (i = 0, idx = 0;
+ i < numbytes;
+ i += sizeof(crypt_uword_t), idx += 1) {
+#if RADIX_BITS == 64
+ written += UINT64_Marshal(&data->d[idx], buffer, size);
+#elif RADIX_BITS == 32
+ written += UINT32_Marshal(&data->d[idx], buffer, size);
+#else
+#error RADIX_BYTES it no defined
+#endif
+ }
+
+ written += BLOCK_SKIP_WRITE_PUSH(TRUE, buffer, size);
+ /* future versions append below this line */
+
+ BLOCK_SKIP_WRITE_POP(size);
+
+ BLOCK_SKIP_WRITE_CHECK;
+
+ return written;
+}
+
+static TPM_RC
+bn_prime_t_Unmarshal(bn_prime_t *data, BYTE **buffer, INT32 *size)
+{
+ TPM_RC rc = TPM_RC_SUCCESS;
+ size_t i, idx;
+ UINT16 numbytes = 0;
+ UINT32 word;
+ NV_HEADER hdr;
+
+ if (rc == TPM_RC_SUCCESS) {
+ rc = NV_HEADER_Unmarshal(&hdr, buffer, size,
+ BN_PRIME_T_VERSION,
+ BN_PRIME_T_MAGIC);
+ }
+
+ data->allocated = ARRAY_SIZE(data->d);
+
+ if (rc == TPM_RC_SUCCESS) {
+ rc = UINT16_Unmarshal(&numbytes, buffer, size);
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ /* coverity: num_bytes is sanitized here! */
+ data->size = (numbytes + sizeof(crypt_uword_t) - 1) / sizeof(crypt_word_t);
+ if (data->size > data->allocated) {
+ TPMLIB_LogTPM2Error("bn_prime_t: Require size larger %zu than "
+ "allocated %zu\n",
+ (size_t)data->size, (size_t)data->allocated);
+ rc = TPM_RC_SIZE;
+ data->size = 0;
+ }
+ }
+
+ if (rc == TPM_RC_SUCCESS) {
+ for (i = 0, idx = 0;
+ i < numbytes && rc == TPM_RC_SUCCESS;
+ i += sizeof(UINT32), idx += 1) {
+ rc = UINT32_Unmarshal(&word, buffer, size);
+#if RADIX_BITS == 64
+ data->d[idx / 2] <<= 32;
+ data->d[idx / 2] |= word;
+#elif RADIX_BITS == 32
+ data->d[idx] = word;
+#endif
+ }
+ }
+
+#if RADIX_BITS == 64
+ if (rc == TPM_RC_SUCCESS) {
+ if (idx & 1)
+ data->d[idx / 2] <<= 32;
+ }
+#endif
+
+ /* version 2 starts having indicator for next versions that we can skip;
+ this allows us to downgrade state */
+ if (rc == TPM_RC_SUCCESS && hdr.version >= 2) {
+ BLOCK_SKIP_READ(skip_future_versions, FALSE, buffer, size,
+ "BN_PRIME_T", "version 3 or later");
+ /* future versions nest-append here */
+ }
+
+skip_future_versions:
+
+ return rc;
+}
+
+#define PRIVATE_EXPONENT_T_MAGIC 0x854eab2
+#define PRIVATE_EXPONENT_T_VERSION 2
+static UINT16
+privateExponent_t_Marshal(privateExponent_t *data, BYTE **buffer, INT32 *size)
+{
+ UINT16 written;
+ BLOCK_SKIP_INIT;
+
+ written = NV_HEADER_Marshal(buffer, size,
+ PRIVATE_EXPONENT_T_VERSION,
+ PRIVATE_EXPONENT_T_MAGIC, 1);
+#if CRT_FORMAT_RSA == NO
+#error Missing code
+#else
+ written += bn_prime_t_Marshal(&data->Q, buffer, size);
+ written += bn_prime_t_Marshal(&data->dP, buffer, size);
+ written += bn_prime_t_Marshal(&data->dQ, buffer, size);
+ written += bn_prime_t_Marshal(&data->qInv, buffer, size);
+#endif
+
+ written += BLOCK_SKIP_WRITE_PUSH(TRUE, buffer, size);
+ /* future versions append below this line */
+
+ BLOCK_SKIP_WRITE_POP(size);
+
+ BLOCK_SKIP_WRITE_CHECK;
+
+ return written;
+}
+
+static TPM_RC
+privateExponent_t_Unmarshal(privateExponent_t *data, BYTE **buffer, INT32 *size)
+{
+ TPM_RC rc = TPM_RC_SUCCESS;
+ NV_HEADER hdr;
+
+ if (rc == TPM_RC_SUCCESS) {
+ rc = NV_HEADER_Unmarshal(&hdr, buffer, size,
+ PRIVATE_EXPONENT_T_VERSION,
+ PRIVATE_EXPONENT_T_MAGIC);
+ }
+
+#if CRT_FORMAT_RSA == NO
+#error Missing code
+#else
+ if (rc == TPM_RC_SUCCESS) {
+ rc = bn_prime_t_Unmarshal(&data->Q, buffer, size);
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ rc = bn_prime_t_Unmarshal(&data->dP, buffer, size);
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ rc = bn_prime_t_Unmarshal(&data->dQ, buffer, size);
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ rc = bn_prime_t_Unmarshal(&data->qInv, buffer, size);
+ }
+#endif
+
+ /* version 2 starts having indicator for next versions that we can skip;
+ this allows us to downgrade state */
+ if (rc == TPM_RC_SUCCESS && hdr.version >= 2) {
+ BLOCK_SKIP_READ(skip_future_versions, FALSE, buffer, size,
+ "PRIVATE_EXPONENT_T", "version 3 or later");
+ /* future versions nest-append here */
+ }
+
+skip_future_versions:
+
+ return rc;
+}
+
+static UINT16
+HASH_STATE_TYPE_Marshal(HASH_STATE_TYPE *data, BYTE **buffer, INT32 *size)
+{
+ UINT16 written;
+
+ written = UINT8_Marshal(data, buffer, size);
+
+ return written;
+}
+
+static UINT16
+HASH_STATE_TYPE_Unmarshal(HASH_STATE_TYPE *data, BYTE **buffer, INT32 *size)
+{
+ return UINT8_Unmarshal(data, buffer, size);
+}
+
+static inline UINT16
+SHA_LONG_Marshal(SHA_LONG *data, BYTE **buffer, INT32 *size)
+{
+ return UINT32_Marshal(data, buffer, size);
+}
+
+static inline UINT16
+SHA_LONG_Unmarshal(SHA_LONG *data, BYTE **buffer, INT32 *size)
+{
+ return UINT32_Unmarshal(data, buffer, size);
+}
+
+static inline UINT16
+SHA_LONG64_Marshal(SHA_LONG64 *data, BYTE **buffer, INT32 *size)
+{
+ assert(sizeof(*data) == 8);
+ return UINT64_Marshal((UINT64 *)data, buffer, size);
+}
+
+static inline UINT16
+SHA_LONG64_Unmarshal(SHA_LONG64 *data, BYTE **buffer, INT32 *size)
+{
+ assert(sizeof(*data) == 8);
+ return UINT64_Unmarshal((UINT64 *)data, buffer, size);
+}
+
+#if ALG_SHA1
+
+#define HASH_STATE_SHA1_MAGIC 0x19d46f50
+#define HASH_STATE_SHA1_VERSION 2
+
+static UINT16
+tpmHashStateSHA1_Marshal(tpmHashStateSHA1_t *data, BYTE **buffer, INT32 *size)
+{
+ UINT16 written;
+ UINT16 array_size;
+ BLOCK_SKIP_INIT;
+
+ written = NV_HEADER_Marshal(buffer, size,
+ HASH_STATE_SHA1_VERSION,
+ HASH_STATE_SHA1_MAGIC,1);
+ written += SHA_LONG_Marshal(&data->h0, buffer, size);
+ written += SHA_LONG_Marshal(&data->h1, buffer, size);
+ written += SHA_LONG_Marshal(&data->h2, buffer, size);
+ written += SHA_LONG_Marshal(&data->h3, buffer, size);
+ written += SHA_LONG_Marshal(&data->h4, buffer, size);
+ written += SHA_LONG_Marshal(&data->Nl, buffer, size);
+ written += SHA_LONG_Marshal(&data->Nh, buffer, size);
+
+ /* data must be written as array */
+ array_size = sizeof(data->data);
+ written += UINT16_Marshal(&array_size, buffer, size);
+ written += Array_Marshal((BYTE *)&data->data[0], array_size,
+ buffer, size);
+
+ written += UINT32_Marshal(&data->num, buffer, size);
+
+ written += BLOCK_SKIP_WRITE_PUSH(TRUE, buffer, size);
+ /* future versions append below this line */
+
+ BLOCK_SKIP_WRITE_POP(size);
+
+ BLOCK_SKIP_WRITE_CHECK;
+
+ return written;
+}
+
+static UINT16
+tpmHashStateSHA1_Unmarshal(tpmHashStateSHA1_t *data, BYTE **buffer, INT32 *size)
+{
+ UINT16 rc = TPM_RC_SUCCESS;
+ NV_HEADER hdr;
+ UINT16 array_size;
+
+ if (rc == TPM_RC_SUCCESS) {
+ rc = NV_HEADER_Unmarshal(&hdr, buffer, size,
+ HASH_STATE_SHA1_VERSION,
+ HASH_STATE_SHA1_MAGIC);
+ }
+
+ if (rc == TPM_RC_SUCCESS) {
+ rc = SHA_LONG_Unmarshal(&data->h0, buffer, size);
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ rc = SHA_LONG_Unmarshal(&data->h1, buffer, size);
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ rc = SHA_LONG_Unmarshal(&data->h2, buffer, size);
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ rc = SHA_LONG_Unmarshal(&data->h3, buffer, size);
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ rc = SHA_LONG_Unmarshal(&data->h4, buffer, size);
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ rc = SHA_LONG_Unmarshal(&data->Nl, buffer, size);
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ rc = SHA_LONG_Unmarshal(&data->Nh, buffer, size);
+ }
+
+ if (rc == TPM_RC_SUCCESS) {
+ rc = UINT16_Unmarshal(&array_size, buffer, size);
+ }
+ if (rc == TPM_RC_SUCCESS &&
+ array_size != sizeof(data->data)) {
+ TPMLIB_LogTPM2Error("HASH_STATE_SHA1: Bad array size for data; "
+ "expected %zu, got %u\n",
+ sizeof(data->data), array_size);
+ rc = TPM_RC_BAD_PARAMETER;
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ rc = Array_Unmarshal((BYTE *)&data->data[0], array_size,
+ buffer, size);
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ rc = UINT32_Unmarshal(&data->num, buffer, size);
+ }
+
+ /* version 2 starts having indicator for next versions that we can skip;
+ this allows us to downgrade state */
+ if (rc == TPM_RC_SUCCESS && hdr.version >= 2) {
+ BLOCK_SKIP_READ(skip_future_versions, FALSE, buffer, size,
+ "HASH_STATE_SHA1", "version 3 or later");
+ /* future versions nest-append here */
+ }
+
+skip_future_versions:
+
+ return rc;
+}
+#endif
+
+#if ALG_SHA256
+#define HASH_STATE_SHA256_MAGIC 0x6ea059d0
+#define HASH_STATE_SHA256_VERSION 2
+
+static UINT16
+tpmHashStateSHA256_Marshal(tpmHashStateSHA256_t *data, BYTE **buffer, INT32 *size)
+{
+ UINT16 written = 0;
+ UINT16 array_size;
+ size_t i;
+ BLOCK_SKIP_INIT;
+
+ written = NV_HEADER_Marshal(buffer, size,
+ HASH_STATE_SHA256_VERSION,
+ HASH_STATE_SHA256_MAGIC, 1);
+
+ array_size = ARRAY_SIZE(data->h);
+ written += UINT16_Marshal(&array_size, buffer, size);
+ for (i = 0; i < array_size; i++) {
+ written += SHA_LONG_Marshal(&data->h[i], buffer, size);
+ }
+ written += SHA_LONG_Marshal(&data->Nl, buffer, size);
+ written += SHA_LONG_Marshal(&data->Nh, buffer, size);
+
+ /* data must be written as array */
+ array_size = sizeof(data->data);
+ written += UINT16_Marshal(&array_size, buffer, size);
+ written += Array_Marshal((BYTE *)&data->data[0], array_size,
+ buffer, size);
+
+ written += UINT32_Marshal(&data->num, buffer, size);
+ written += UINT32_Marshal(&data->md_len, buffer, size);
+
+ written += BLOCK_SKIP_WRITE_PUSH(TRUE, buffer, size);
+ /* future versions append below this line */
+
+ BLOCK_SKIP_WRITE_POP(size);
+
+ BLOCK_SKIP_WRITE_CHECK;
+
+ return written;
+}
+
+static UINT16
+tpmHashStateSHA256_Unmarshal(tpmHashStateSHA256_t *data, BYTE **buffer, INT32 *size)
+{
+ UINT16 rc = TPM_RC_SUCCESS;
+ size_t i;
+ UINT16 array_size;
+ NV_HEADER hdr;
+
+ if (rc == TPM_RC_SUCCESS) {
+ rc = NV_HEADER_Unmarshal(&hdr, buffer, size,
+ HASH_STATE_SHA256_VERSION,
+ HASH_STATE_SHA256_MAGIC);
+ }
+
+ if (rc == TPM_RC_SUCCESS) {
+ rc = UINT16_Unmarshal(&array_size, buffer, size);
+ }
+ if (rc == TPM_RC_SUCCESS &&
+ array_size != ARRAY_SIZE(data->h)) {
+ TPMLIB_LogTPM2Error("HASH_STATE_SHA256: Bad array size for h; "
+ "expected %zu, got %u\n",
+ ARRAY_SIZE(data->h), array_size);
+ rc = TPM_RC_BAD_PARAMETER;
+ }
+ for (i = 0; rc == TPM_RC_SUCCESS && i < array_size; i++) {
+ rc = SHA_LONG_Unmarshal(&data->h[i], buffer, size);
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ rc = SHA_LONG_Unmarshal(&data->Nl, buffer, size);
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ rc = SHA_LONG_Unmarshal(&data->Nh, buffer, size);
+ }
+
+ if (rc == TPM_RC_SUCCESS) {
+ rc = UINT16_Unmarshal(&array_size, buffer, size);
+ }
+ if (rc == TPM_RC_SUCCESS &&
+ array_size != sizeof(data->data)) {
+ TPMLIB_LogTPM2Error("HASH_STATE_SHA256: Bad array size for data; "
+ "expected %zu, got %u\n",
+ sizeof(data->data), array_size);
+ rc = TPM_RC_BAD_PARAMETER;
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ rc = Array_Unmarshal((BYTE *)&data->data[0], array_size,
+ buffer, size);
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ rc = UINT32_Unmarshal(&data->num, buffer, size);
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ rc = UINT32_Unmarshal(&data->md_len, buffer, size);
+ }
+
+ /* version 2 starts having indicator for next versions that we can skip;
+ this allows us to downgrade state */
+ if (rc == TPM_RC_SUCCESS && hdr.version >= 2) {
+ BLOCK_SKIP_READ(skip_future_versions, FALSE, buffer, size,
+ "HASH_STATE_SHA256", "version 3 or later");
+ /* future versions nest-append here */
+ }
+
+skip_future_versions:
+
+ return rc;
+}
+#endif
+
+#if ALG_SHA384 || ALG_SHA512
+
+#define HASH_STATE_SHA384_MAGIC 0x14814b08
+#define HASH_STATE_SHA384_VERSION 2
+
+#define HASH_STATE_SHA512_MAGIC 0x269e8ae0
+#define HASH_STATE_SHA512_VERSION 2
+
+static UINT16
+tpmHashStateSHA512_Marshal(SHA512_CTX *data, BYTE **buffer, INT32 *size,
+ UINT16 hashAlg)
+{
+ UINT16 written = 0;
+ UINT16 array_size;
+ size_t i;
+ BLOCK_SKIP_INIT;
+ UINT16 version = HASH_STATE_SHA512_VERSION;
+ UINT32 magic = HASH_STATE_SHA512_MAGIC;
+
+ if (hashAlg == ALG_SHA384_VALUE) {
+ version = HASH_STATE_SHA384_VERSION;
+ magic = HASH_STATE_SHA384_MAGIC;
+ }
+
+ written = NV_HEADER_Marshal(buffer, size,
+ version, magic, 1);
+
+ array_size = ARRAY_SIZE(data->h);
+ written += UINT16_Marshal(&array_size, buffer, size);
+ for (i = 0; i < array_size; i++) {
+ written += SHA_LONG64_Marshal(&data->h[i], buffer, size);
+ }
+ written += SHA_LONG64_Marshal(&data->Nl, buffer, size);
+ written += SHA_LONG64_Marshal(&data->Nh, buffer, size);
+
+ array_size = sizeof(data->u.p);
+ written += UINT16_Marshal(&array_size, buffer, size);
+ written += Array_Marshal(&data->u.p[0], array_size, buffer, size);
+
+ written += UINT32_Marshal(&data->num, buffer, size);
+ written += UINT32_Marshal(&data->md_len, buffer, size);
+
+ written += BLOCK_SKIP_WRITE_PUSH(TRUE, buffer, size);
+ /* future versions append below this line */
+
+ BLOCK_SKIP_WRITE_POP(size);
+
+ BLOCK_SKIP_WRITE_CHECK;
+
+ return written;
+}
+
+static UINT16
+tpmHashStateSHA512_Unmarshal(SHA512_CTX *data, BYTE **buffer, INT32 *size,
+ UINT16 hashAlg)
+{
+ UINT16 rc = TPM_RC_SUCCESS;
+ size_t i;
+ UINT16 array_size;
+ NV_HEADER hdr;
+ UINT16 version = HASH_STATE_SHA512_VERSION;
+ UINT32 magic = HASH_STATE_SHA512_MAGIC;
+
+ if (hashAlg == ALG_SHA384_VALUE) {
+ version = HASH_STATE_SHA384_VERSION;
+ magic = HASH_STATE_SHA384_MAGIC;
+ }
+
+ if (rc == TPM_RC_SUCCESS) {
+ rc = NV_HEADER_Unmarshal(&hdr, buffer, size,
+ version, magic);
+ }
+
+ if (rc == TPM_RC_SUCCESS) {
+ rc = UINT16_Unmarshal(&array_size, buffer, size);
+ }
+ if (rc == TPM_RC_SUCCESS &&
+ array_size != ARRAY_SIZE(data->h)) {
+ TPMLIB_LogTPM2Error("HASH_STATE_SHA512: Bad array size for h; "
+ "expected %zu, got %u\n",
+ ARRAY_SIZE(data->h), array_size);
+ rc = TPM_RC_BAD_PARAMETER;
+ }
+ for (i = 0; rc == TPM_RC_SUCCESS && i < array_size; i++) {
+ rc = SHA_LONG64_Unmarshal(&data->h[i], buffer, size);
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ rc = SHA_LONG64_Unmarshal(&data->Nl, buffer, size);
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ rc = SHA_LONG64_Unmarshal(&data->Nh, buffer, size);
+ }
+
+ if (rc == TPM_RC_SUCCESS) {
+ rc = UINT16_Unmarshal(&array_size, buffer, size);
+ }
+ if (rc == TPM_RC_SUCCESS &&
+ array_size != sizeof(data->u.p)) {
+ TPMLIB_LogTPM2Error("HASH_STATE_SHA512: Bad array size for u.p; "
+ "expected %zu, got %u\n",
+ sizeof(data->u.p), array_size);
+ rc = TPM_RC_BAD_PARAMETER;
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ rc = Array_Unmarshal(&data->u.p[0], array_size, buffer, size);
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ rc = UINT32_Unmarshal(&data->num, buffer, size);
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ rc = UINT32_Unmarshal(&data->md_len, buffer, size);
+ }
+
+ /* version 2 starts having indicator for next versions that we can skip;
+ this allows us to downgrade state */
+ if (rc == TPM_RC_SUCCESS && hdr.version >= 2) {
+ BLOCK_SKIP_READ(skip_future_versions, FALSE, buffer, size,
+ "HASH_STATE_SHA512", "version 3 or later");
+ /* future versions nest-append here */
+ }
+
+skip_future_versions:
+
+ return rc;
+}
+#endif
+
+#define ANY_HASH_STATE_MAGIC 0x349d494b
+#define ANY_HASH_STATE_VERSION 2
+
+static UINT16
+ANY_HASH_STATE_Marshal(ANY_HASH_STATE *data, BYTE **buffer, INT32 *size,
+ UINT16 hashAlg)
+{
+ UINT16 written;
+ BLOCK_SKIP_INIT;
+
+ written = NV_HEADER_Marshal(buffer, size,
+ ANY_HASH_STATE_VERSION,
+ ANY_HASH_STATE_MAGIC, 1);
+
+ switch (hashAlg) {
+#if ALG_SHA1
+ case ALG_SHA1_VALUE:
+ written += tpmHashStateSHA1_Marshal(&data->Sha1, buffer, size);
+ break;
+#endif
+#if ALG_SHA256
+ case ALG_SHA256_VALUE:
+ written += tpmHashStateSHA256_Marshal(&data->Sha256, buffer, size);
+ break;
+#endif
+#if ALG_SHA384
+ case ALG_SHA384_VALUE:
+ written += tpmHashStateSHA512_Marshal(&data->Sha384, buffer, size,
+ ALG_SHA384_VALUE);
+ break;
+#endif
+#if ALG_SHA512
+ case ALG_SHA512_VALUE:
+ written += tpmHashStateSHA512_Marshal(&data->Sha512, buffer, size,
+ ALG_SHA512_VALUE);
+ break;
+#endif
+ default:
+ break;
+ }
+
+ written += BLOCK_SKIP_WRITE_PUSH(TRUE, buffer, size);
+ /* future versions append below this line */
+
+ BLOCK_SKIP_WRITE_POP(size);
+
+ BLOCK_SKIP_WRITE_CHECK;
+
+ return written;
+}
+
+static UINT16
+ANY_HASH_STATE_Unmarshal(ANY_HASH_STATE *data, BYTE **buffer, INT32 *size,
+ UINT16 hashAlg)
+{
+ UINT16 rc = TPM_RC_SUCCESS;
+ NV_HEADER hdr;
+
+ if (rc == TPM_RC_SUCCESS) {
+ rc = NV_HEADER_Unmarshal(&hdr, buffer, size,
+ ANY_HASH_STATE_VERSION,
+ ANY_HASH_STATE_MAGIC);
+ }
+
+ switch (hashAlg) {
+#if ALG_SHA1
+ case ALG_SHA1_VALUE:
+ rc = tpmHashStateSHA1_Unmarshal(&data->Sha1, buffer, size);
+ break;
+#endif
+#if ALG_SHA256
+ case ALG_SHA256_VALUE:
+ rc = tpmHashStateSHA256_Unmarshal(&data->Sha256, buffer, size);
+ break;
+#endif
+#if ALG_SHA384
+ case ALG_SHA384_VALUE:
+ rc = tpmHashStateSHA512_Unmarshal(&data->Sha384, buffer, size,
+ ALG_SHA384_VALUE);
+ break;
+#endif
+#if ALG_SHA512
+ case ALG_SHA512_VALUE:
+ rc = tpmHashStateSHA512_Unmarshal(&data->Sha512, buffer, size,
+ ALG_SHA512_VALUE);
+ break;
+#endif
+ }
+
+ /* version 2 starts having indicator for next versions that we can skip;
+ this allows us to downgrade state */
+ if (rc == TPM_RC_SUCCESS && hdr.version >= 2) {
+ BLOCK_SKIP_READ(skip_future_versions, FALSE, buffer, size,
+ "ANY_HASH_STATE", "version 3 or later");
+ /* future versions nest-append here */
+ }
+
+skip_future_versions:
+
+ return rc;
+}
+
+#define HASH_STATE_MAGIC 0x562878a2
+#define HASH_STATE_VERSION 2
+
+static UINT16
+HASH_STATE_Marshal(HASH_STATE *data, BYTE **buffer, INT32 *size)
+{
+ UINT16 written;
+ BLOCK_SKIP_INIT;
+
+ written = NV_HEADER_Marshal(buffer, size,
+ HASH_STATE_VERSION,
+ HASH_STATE_MAGIC, 1);
+
+ written += HASH_STATE_TYPE_Marshal(&data->type, buffer, size);
+ written += TPM_ALG_ID_Marshal(&data->hashAlg, buffer, size);
+ /* def does not need to be written */
+ written += ANY_HASH_STATE_Marshal(&data->state, buffer, size, data->hashAlg);
+
+ written += BLOCK_SKIP_WRITE_PUSH(TRUE, buffer, size);
+ /* future versions append below this line */
+
+ BLOCK_SKIP_WRITE_POP(size);
+
+ BLOCK_SKIP_WRITE_CHECK;
+
+ return written;
+}
+
+static UINT16
+HASH_STATE_Unmarshal(HASH_STATE *data, BYTE **buffer, INT32 *size)
+{
+ UINT16 rc = TPM_RC_SUCCESS;
+ NV_HEADER hdr;
+
+ if (rc == TPM_RC_SUCCESS) {
+ rc = NV_HEADER_Unmarshal(&hdr, buffer, size,
+ HASH_STATE_VERSION, HASH_STATE_MAGIC);
+ }
+
+ if (rc == TPM_RC_SUCCESS) {
+ rc = HASH_STATE_TYPE_Unmarshal(&data->type, buffer, size);
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ rc = TPM_ALG_ID_Unmarshal(&data->hashAlg, buffer, size);
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ data->def = CryptGetHashDef(data->hashAlg);
+ if (!data->def) {
+ TPMLIB_LogTPM2Error("Could not get hash function interface for "
+ "hashAlg 0x%02x\n", data->hashAlg);
+ rc = TPM_RC_BAD_PARAMETER;
+ }
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ rc = ANY_HASH_STATE_Unmarshal(&data->state, buffer, size, data->hashAlg);
+ }
+
+ /* version 2 starts having indicator for next versions that we can skip;
+ this allows us to downgrade state */
+ if (rc == TPM_RC_SUCCESS && hdr.version >= 2) {
+ BLOCK_SKIP_READ(skip_future_versions, FALSE, buffer, size,
+ "HASH_STATE", "version 3 or later");
+ /* future versions nest-append here */
+ }
+
+skip_future_versions:
+ return rc;
+}
+
+static inline UINT16
+TPM2B_HASH_BLOCK_Marshal(TPM2B_HASH_BLOCK *data, BYTE **buffer, INT32 *size)
+{
+ UINT16 written;
+
+ written = TPM2B_Marshal(&data->b, sizeof(data->t.buffer), buffer, size);
+
+ return written;
+}
+
+static inline UINT16
+TPM2B_HASH_BLOCK_Unmarshal(TPM2B_HASH_BLOCK *data, BYTE **buffer, INT32 *size)
+{
+ UINT16 rc;
+
+ rc = TPM2B_Unmarshal(&data->b, sizeof(data->t.buffer), buffer, size);
+
+ return rc;
+}
+
+static UINT16
+HMAC_STATE_Marshal(HMAC_STATE *data, BYTE **buffer, INT32 *size)
+{
+ UINT16 written;
+
+ written = HASH_STATE_Marshal(&data->hashState, buffer, size);
+ written += TPM2B_HASH_BLOCK_Marshal(&data->hmacKey, buffer, size);
+
+ return written;
+}
+
+static UINT16
+HMAC_STATE_Unmarshal(HMAC_STATE *data, BYTE **buffer, INT32 *size)
+{
+ UINT16 rc = TPM_RC_SUCCESS;
+
+ if (rc == TPM_RC_SUCCESS) {
+ rc = HASH_STATE_Unmarshal(&data->hashState, buffer, size);
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ rc = TPM2B_HASH_BLOCK_Unmarshal(&data->hmacKey, buffer, size);
+ }
+
+ return rc;
+}
+
+#define HASH_OBJECT_MAGIC 0xb874fe38
+#define HASH_OBJECT_VERSION 3
+
+static UINT16
+HASH_OBJECT_Marshal(HASH_OBJECT *data, BYTE **buffer, INT32 *size)
+{
+ UINT16 written;
+ size_t i;
+ UINT16 array_size;
+ BLOCK_SKIP_INIT;
+
+ written = NV_HEADER_Marshal(buffer, size,
+ HASH_OBJECT_VERSION, HASH_OBJECT_MAGIC, 1);
+ written += TPMI_ALG_PUBLIC_Marshal(&data->type, buffer, size);
+ written += TPMI_ALG_HASH_Marshal(&data->nameAlg, buffer, size);
+ written += TPMA_OBJECT_Marshal(&data->objectAttributes, buffer, size);
+ written += TPM2B_AUTH_Marshal(&data->auth, buffer, size);
+ if (data->attributes.hashSeq == SET ||
+ data->attributes.eventSeq == SET /* since v3 */) {
+ array_size = ARRAY_SIZE(data->state.hashState);
+ written += UINT16_Marshal(&array_size, buffer, size);
+ for (i = 0; i < array_size; i++) {
+ written += HASH_STATE_Marshal(&data->state.hashState[i], buffer,
+ size);
+ }
+ } else if (data->attributes.hmacSeq == SET) {
+ written += HMAC_STATE_Marshal(&data->state.hmacState, buffer, size);
+ }
+
+ written += BLOCK_SKIP_WRITE_PUSH(TRUE, buffer, size);
+ /* future versions append below this line */
+
+ BLOCK_SKIP_WRITE_POP(size);
+
+ BLOCK_SKIP_WRITE_CHECK;
+
+ return written;
+}
+
+static UINT16
+HASH_OBJECT_Unmarshal(HASH_OBJECT *data, BYTE **buffer, INT32 *size)
+{
+ TPM_RC rc = TPM_RC_SUCCESS;
+ size_t i;
+ UINT16 array_size;
+ NV_HEADER hdr;
+
+ if (rc == TPM_RC_SUCCESS) {
+ rc = NV_HEADER_Unmarshal(&hdr, buffer, size,
+ HASH_OBJECT_VERSION, HASH_OBJECT_MAGIC);
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ rc = TPMI_ALG_PUBLIC_Unmarshal(&data->type, buffer, size);
+ if (rc == TPM_RC_TYPE)
+ rc = TPM_RC_SUCCESS;
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ rc = TPMI_ALG_HASH_Unmarshal(&data->nameAlg, buffer, size, TRUE);
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ rc = TPMA_OBJECT_Unmarshal(&data->objectAttributes, buffer, size);
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ rc = TPM2B_AUTH_Unmarshal(&data->auth, buffer, size);
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ /* hashSeq was always written correctly; eventSeq only appeared in v3 */
+ if (data->attributes.hashSeq == SET ||
+ (data->attributes.eventSeq == SET && hdr.version >= 3)) {
+ if (rc == TPM_RC_SUCCESS) {
+ rc = UINT16_Unmarshal(&array_size, buffer, size);
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ if (array_size != ARRAY_SIZE(data->state.hashState)) {
+ TPMLIB_LogTPM2Error("HASH_OBJECT: Bad array size for state.hashState; "
+ "expected %zu, got %u\n",
+ ARRAY_SIZE(data->state.hashState),
+ array_size);
+ rc = TPM_RC_SIZE;
+ }
+ }
+ for (i = 0; rc == TPM_RC_SUCCESS && i < array_size; i++) {
+ rc = HASH_STATE_Unmarshal(&data->state.hashState[i],
+ buffer, size);
+ }
+ } else if (data->attributes.hmacSeq == SET) {
+ rc = HMAC_STATE_Unmarshal(&data->state.hmacState, buffer, size);
+ }
+ }
+
+ /* version 2 starts having indicator for next versions that we can skip;
+ this allows us to downgrade state */
+ if (rc == TPM_RC_SUCCESS && hdr.version >= 2) {
+ BLOCK_SKIP_READ(skip_future_versions, FALSE, buffer, size,
+ "HASH_OBJECT", "version 3 or later");
+ /* future versions nest-append here */
+ }
+
+skip_future_versions:
+
+ return rc;
+}
+
+/* Local version of TPMT_SENSITIVE_Marshal handling public keys that don't have much in TPM_SENSITIVE */
+static UINT16
+NV_TPMT_SENSITIVE_Marshal(TPMT_SENSITIVE *source, BYTE **buffer, INT32 *size)
+{
+ UINT16 written = 0;
+
+ written += TPM_ALG_ID_Marshal(&source->sensitiveType, buffer, size);
+ written += TPM2B_AUTH_Marshal(&source->authValue, buffer, size);
+ written += TPM2B_DIGEST_Marshal(&source->seedValue, buffer, size);
+
+ switch (source->sensitiveType) {
+ case TPM_ALG_RSA:
+ case TPM_ALG_ECC:
+ case TPM_ALG_KEYEDHASH:
+ case TPM_ALG_SYMCIPHER:
+ written += TPMU_SENSITIVE_COMPOSITE_Marshal(&source->sensitive, buffer, size, source->sensitiveType);
+ break;
+ default:
+ /* we wrote these but they must have been 0 in this case */
+ pAssert(source->authValue.t.size == 0);
+ pAssert(source->seedValue.t.size == 0);
+ pAssert(source->sensitiveType == TPM_ALG_ERROR)
+ /* public keys */
+ }
+ return written;
+}
+
+/* local version of TPM_SENSITIVE_Unmarshal handling public keys that don't have much in TPMT_SENSITVE */
+static TPM_RC
+NV_TPMT_SENSITIVE_Unmarshal(TPMT_SENSITIVE *target, BYTE **buffer, INT32 *size)
+{
+ TPM_RC rc = TPM_RC_SUCCESS;
+
+ if (rc == TPM_RC_SUCCESS) {
+ /* TPMI_ALG_PUBLIC_Unmarshal would test the sensitiveType; we don't want this */
+ rc = TPM_ALG_ID_Unmarshal(&target->sensitiveType, buffer, size);
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ rc = TPM2B_AUTH_Unmarshal(&target->authValue, buffer, size);
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ rc = TPM2B_DIGEST_Unmarshal(&target->seedValue, buffer, size);
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ switch (target->sensitiveType) {
+ case TPM_ALG_RSA:
+ case TPM_ALG_ECC:
+ case TPM_ALG_KEYEDHASH:
+ case TPM_ALG_SYMCIPHER:
+ rc = TPMU_SENSITIVE_COMPOSITE_Unmarshal(&target->sensitive, buffer, size, target->sensitiveType);
+ break;
+ default:
+ pAssert(target->authValue.t.size == 0);
+ pAssert(target->seedValue.t.size == 0);
+ pAssert(target->sensitiveType == TPM_ALG_ERROR)
+ /* nothing do to do */
+ }
+ }
+ return rc;
+}
+
+#define OBJECT_MAGIC 0x75be73af
+#define OBJECT_VERSION 3
+
+static UINT16
+OBJECT_Marshal(OBJECT *data, BYTE **buffer, INT32 *size)
+{
+ UINT16 written;
+ BOOL has_block;
+ BLOCK_SKIP_INIT;
+
+ written = NV_HEADER_Marshal(buffer, size,
+ OBJECT_VERSION, OBJECT_MAGIC, 3);
+
+ /*
+ * attributes are written in ANY_OBJECT_Marshal
+ */
+ written += TPMT_PUBLIC_Marshal(&data->publicArea, buffer, size);
+ written += NV_TPMT_SENSITIVE_Marshal(&data->sensitive, buffer, size);
+
+#if ALG_RSA
+ has_block = TRUE;
+#else
+ has_block = FALSE;
+#endif
+ written += BLOCK_SKIP_WRITE_PUSH(has_block, buffer, size);
+#if ALG_RSA
+ written += privateExponent_t_Marshal(&data->privateExponent,
+ buffer, size);
+#endif
+ BLOCK_SKIP_WRITE_POP(size);
+
+ written += TPM2B_NAME_Marshal(&data->qualifiedName, buffer, size);
+ written += TPM_HANDLE_Marshal(&data->evictHandle, buffer, size);
+ written += TPM2B_NAME_Marshal(&data->name, buffer, size);
+
+ written += BLOCK_SKIP_WRITE_PUSH(TRUE, buffer, size);
+ written += SEED_COMPAT_LEVEL_Marshal(&data->seedCompatLevel,
+ buffer, size);
+
+ written += BLOCK_SKIP_WRITE_PUSH(TRUE, buffer, size);
+ /* future versions append below this line */
+
+ BLOCK_SKIP_WRITE_POP(size);
+ BLOCK_SKIP_WRITE_POP(size);
+
+ BLOCK_SKIP_WRITE_CHECK;
+
+ return written;
+}
+
+static TPM_RC
+OBJECT_Unmarshal(OBJECT *data, BYTE **buffer, INT32 *size)
+{
+ TPM_RC rc = TPM_RC_SUCCESS;
+ NV_HEADER hdr;
+ BOOL needs_block;
+
+ /*
+ * attributes are read in ANY_OBJECT_Unmarshal
+ */
+ if (rc == TPM_RC_SUCCESS) {
+ rc = NV_HEADER_Unmarshal(&hdr, buffer, size,
+ OBJECT_VERSION, OBJECT_MAGIC);
+ }
+
+ if (rc == TPM_RC_SUCCESS) {
+ rc = TPMT_PUBLIC_Unmarshal(&data->publicArea, buffer, size, TRUE);
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ rc = NV_TPMT_SENSITIVE_Unmarshal(&data->sensitive, buffer, size);
+ }
+
+#if ALG_RSA
+ needs_block = TRUE;
+#else
+ needs_block = FALSE;
+#endif
+ if (rc == TPM_RC_SUCCESS) {
+ BLOCK_SKIP_READ(skip_alg_rsa, needs_block, buffer, size,
+ "OBJECT", "privateExponent");
+ }
+#if ALG_RSA
+ if (rc == TPM_RC_SUCCESS) {
+ rc = privateExponent_t_Unmarshal(&data->privateExponent,
+ buffer, size);
+ }
+#endif
+skip_alg_rsa:
+
+ if (rc == TPM_RC_SUCCESS) {
+ rc = TPM2B_NAME_Unmarshal(&data->qualifiedName, buffer, size);
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ rc = TPM_HANDLE_Unmarshal(&data->evictHandle, buffer, size);
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ rc = TPM2B_NAME_Unmarshal(&data->name, buffer, size);
+ }
+
+ /* default values before conditional block */
+ data->seedCompatLevel = SEED_COMPAT_LEVEL_ORIGINAL;
+
+ /* version 2 starts having indicator for next versions that we can skip;
+ this allows us to downgrade state */
+ if (rc == TPM_RC_SUCCESS && hdr.version >= 2) {
+ BLOCK_SKIP_READ(skip_future_versions, hdr.version >= 3, buffer, size,
+ "OBJECT", "version 3 or later");
+ if (rc == TPM_RC_SUCCESS) {
+ rc = SEED_COMPAT_LEVEL_Unmarshal(&data->seedCompatLevel,
+ buffer, size,
+ "OBJECT seedCompatLevel");
+ }
+
+ if (rc == TPM_RC_SUCCESS) {
+ BLOCK_SKIP_READ(skip_future_versions, FALSE, buffer, size,
+ "OBJECT", "version 4 or later");
+ }
+ /* future versions nest-append here */
+ }
+
+skip_future_versions:
+ return rc;
+}
+
+#define ANY_OBJECT_MAGIC 0xfe9a3974
+#define ANY_OBJECT_VERSION 2
+
+UINT16
+ANY_OBJECT_Marshal(OBJECT *data, BYTE **buffer, INT32 *size)
+{
+ UINT16 written;
+ UINT32 *ptr = (UINT32 *)&data->attributes;
+ BLOCK_SKIP_INIT;
+
+ written = NV_HEADER_Marshal(buffer, size,
+ ANY_OBJECT_VERSION, ANY_OBJECT_MAGIC, 1);
+
+ written += UINT32_Marshal(ptr, buffer, size);
+ /* the slot must be occupied, otherwise the rest may not be initialized */
+ if (data->attributes.occupied) {
+ if (ObjectIsSequence(data))
+ written += HASH_OBJECT_Marshal((HASH_OBJECT *)data, buffer, size);
+ else
+ written += OBJECT_Marshal(data, buffer, size);
+ }
+
+ written += BLOCK_SKIP_WRITE_PUSH(TRUE, buffer, size);
+ /* future versions append below this line */
+
+ BLOCK_SKIP_WRITE_POP(size);
+
+ BLOCK_SKIP_WRITE_CHECK;
+
+ return written;
+}
+
+TPM_RC
+ANY_OBJECT_Unmarshal(OBJECT *data, BYTE **buffer, INT32 *size, BOOL verbose)
+{
+ TPM_RC rc = TPM_RC_SUCCESS;
+ UINT32 *ptr = (UINT32 *)&data->attributes;
+ NV_HEADER hdr;
+
+ if (rc == TPM_RC_SUCCESS) {
+ rc = NV_HEADER_UnmarshalVerbose(&hdr, buffer, size,
+ ANY_OBJECT_VERSION, ANY_OBJECT_MAGIC,
+ verbose);
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ rc = UINT32_Unmarshal(ptr, buffer, size);
+ }
+
+ if (rc == TPM_RC_SUCCESS && data->attributes.occupied) {
+ if (ObjectIsSequence(data))
+ rc = HASH_OBJECT_Unmarshal((HASH_OBJECT *)data, buffer, size);
+ else
+ rc = OBJECT_Unmarshal(data, buffer, size);
+ }
+
+ /* version 2 starts having indicator for next versions that we can skip;
+ this allows us to downgrade state */
+ if (rc == TPM_RC_SUCCESS && hdr.version >= 2) {
+ BLOCK_SKIP_READ(skip_future_versions, FALSE, buffer, size,
+ "ANY_OBJECT", "version 3 or later");
+ /* future versions nest-append here */
+ }
+
+skip_future_versions:
+
+ return rc;
+}
+
+static UINT16
+TPMT_SYM_DEF_Marshal(TPMT_SYM_DEF *data, BYTE **buffer, INT32 *size)
+{
+ UINT16 written;
+
+ written = UINT16_Marshal(&data->algorithm, buffer, size);
+ written += TPMU_SYM_KEY_BITS_Marshal(&data->keyBits, buffer, size, data->algorithm);
+ written += TPMU_SYM_MODE_Marshal(&data->mode, buffer, size, data->algorithm);
+
+ return written;
+}
+
+#define SESSION_MAGIC 0x44be9f45
+#define SESSION_VERSION 2
+
+static UINT16
+SESSION_Marshal(SESSION *data, BYTE **buffer, INT32 *size)
+{
+ UINT16 written;
+ UINT8 clocksize;
+ BLOCK_SKIP_INIT;
+
+ written = NV_HEADER_Marshal(buffer, size,
+ SESSION_VERSION, SESSION_MAGIC, 1);
+ written += UINT32_Marshal((UINT32 *)&data->attributes, buffer, size);
+ written += UINT32_Marshal(&data->pcrCounter, buffer, size);
+ written += UINT64_Marshal(&data->startTime, buffer, size);
+ written += UINT64_Marshal(&data->timeout, buffer, size);
+
+#if CLOCK_STOPS
+ clocksize = sizeof(UINT64);
+ written += UINT8_Marshal(&clocksize, buffer, size);
+ written += UINT64_Marshal(&data->epoch, buffer, size);
+#else
+ clocksize = sizeof(UINT32);
+ written += UINT8_Marshal(&clocksize, buffer, size);
+ written += UINT32_Marshal(&data->epoch, buffer, size);
+#endif
+
+ written += UINT32_Marshal(&data->commandCode, buffer, size);
+ written += UINT16_Marshal(&data->authHashAlg, buffer, size);
+ written += UINT8_Marshal(&data->commandLocality, buffer, size);
+ written += TPMT_SYM_DEF_Marshal(&data->symmetric, buffer, size);
+ written += TPM2B_AUTH_Marshal(&data->sessionKey, buffer, size);
+ written += TPM2B_NONCE_Marshal(&data->nonceTPM, buffer, size);
+ // TPM2B_NAME or TPM2B_DIGEST could be used for marshalling
+ written += TPM2B_NAME_Marshal(&data->u1.boundEntity, buffer, size);
+ written += TPM2B_DIGEST_Marshal(&data->u2.auditDigest, buffer, size);
+
+ written += BLOCK_SKIP_WRITE_PUSH(TRUE, buffer, size);
+ /* future versions append below this line */
+
+ BLOCK_SKIP_WRITE_POP(size);
+
+ BLOCK_SKIP_WRITE_CHECK;
+
+ return written;
+}
+
+static TPM_RC
+SESSION_Unmarshal(SESSION *data, BYTE **buffer, INT32 *size)
+{
+ TPM_RC rc = TPM_RC_SUCCESS;
+ NV_HEADER hdr;
+ UINT8 clocksize;
+
+ if (rc == TPM_RC_SUCCESS) {
+ rc = NV_HEADER_Unmarshal(&hdr, buffer, size,
+ SESSION_VERSION, SESSION_MAGIC);
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ rc = UINT32_Unmarshal((UINT32 *)&data->attributes, buffer, size);
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ rc = UINT32_Unmarshal(&data->pcrCounter, buffer, size);
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ rc = UINT64_Unmarshal(&data->startTime, buffer, size);
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ rc = UINT64_Unmarshal(&data->timeout, buffer, size);
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ rc = UINT8_Unmarshal(&clocksize, buffer, size);
+ }
+ if (rc == TPM_RC_SUCCESS) {
+#if CLOCK_STOPS
+ if (clocksize != sizeof(UINT64)) {
+ TPMLIB_LogTPM2Error("Unexpected clocksize for epoch; "
+ "Expected %zu, got %u\n",
+ sizeof(UINT64), clocksize);
+ rc = TPM_RC_BAD_PARAMETER;
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ rc = UINT64_Unmarshal(&data->epoch, buffer, size);
+ }
+#else
+ if (clocksize != sizeof(UINT32)) {
+ TPMLIB_LogTPM2Error("Unexpected clocksize for epoch; "
+ "Expected %zu, got %u\n",
+ sizeof(UINT32), clocksize);
+ rc = TPM_RC_BAD_PARAMETER;
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ rc = UINT32_Unmarshal(&data->epoch, buffer, size);
+ }
+#endif
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ rc = UINT32_Unmarshal(&data->commandCode, buffer, size);
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ rc = UINT16_Unmarshal(&data->authHashAlg, buffer, size);
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ rc = UINT8_Unmarshal(&data->commandLocality, buffer, size);
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ rc = TPMT_SYM_DEF_Unmarshal(&data->symmetric, buffer, size, YES);
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ rc = TPM2B_AUTH_Unmarshal(&data->sessionKey, buffer, size);
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ rc = TPM2B_NONCE_Unmarshal(&data->nonceTPM, buffer, size);
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ rc = TPM2B_NAME_Unmarshal(&data->u1.boundEntity, buffer, size);
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ rc = TPM2B_DIGEST_Unmarshal(&data->u2.auditDigest, buffer, size);
+ }
+
+ /* version 2 starts having indicator for next versions that we can skip;
+ this allows us to downgrade state */
+ if (rc == TPM_RC_SUCCESS && hdr.version >= 2) {
+ BLOCK_SKIP_READ(skip_future_versions, FALSE, buffer, size,
+ "SESSION", "version 3 or later");
+ /* future versions nest-append here */
+ }
+
+skip_future_versions:
+ return rc;
+}
+
+#define SESSION_SLOT_MAGIC 0x3664aebc
+#define SESSION_SLOT_VERSION 2
+
+static UINT16
+SESSION_SLOT_Marshal(SESSION_SLOT *data, BYTE **buffer, INT32* size)
+{
+ UINT16 written;
+ BLOCK_SKIP_INIT;
+
+ written = NV_HEADER_Marshal(buffer, size,
+ SESSION_SLOT_VERSION,
+ SESSION_SLOT_MAGIC, 1);
+
+ written += BOOL_Marshal(&data->occupied, buffer, size);
+ if (!data->occupied)
+ return written;
+
+ written += SESSION_Marshal(&data->session, buffer, size);
+
+ written += BLOCK_SKIP_WRITE_PUSH(TRUE, buffer, size);
+ /* future versions append below this line */
+
+ BLOCK_SKIP_WRITE_POP(size);
+
+ BLOCK_SKIP_WRITE_CHECK;
+
+ return written;
+}
+
+static TPM_RC
+SESSION_SLOT_Unmarshal(SESSION_SLOT *data, BYTE **buffer, INT32 *size)
+{
+ TPM_RC rc = TPM_RC_SUCCESS;
+ NV_HEADER hdr;
+
+ if (rc == TPM_RC_SUCCESS) {
+ rc = NV_HEADER_Unmarshal(&hdr, buffer, size,
+ SESSION_SLOT_VERSION, SESSION_SLOT_MAGIC);
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ rc = BOOL_Unmarshal(&data->occupied, buffer, size);
+ }
+ if (!data->occupied)
+ return rc;
+
+ if (rc == TPM_RC_SUCCESS) {
+ rc = SESSION_Unmarshal(&data->session, buffer, size);
+ }
+
+ /* version 2 starts having indicator for next versions that we can skip;
+ this allows us to downgrade state */
+ if (rc == TPM_RC_SUCCESS && hdr.version >= 2) {
+ BLOCK_SKIP_READ(skip_future_versions, FALSE, buffer, size,
+ "SESSION_SLOT", "version 3 or later");
+ /* future versions nest-append here */
+ }
+
+skip_future_versions:
+ return rc;
+}
+
+#define VOLATILE_STATE_VERSION 4
+#define VOLATILE_STATE_MAGIC 0x45637889
+
+UINT16
+VolatileState_Marshal(BYTE **buffer, INT32 *size)
+{
+ UINT16 written;
+ size_t i;
+ BOOL tpmEst;
+ UINT64 tmp_uint64;
+ UINT32 tmp_uint32;
+ BOOL has_block;
+ UINT16 array_size;
+ BLOCK_SKIP_INIT;
+ PERSISTENT_DATA pd;
+
+ written = NV_HEADER_Marshal(buffer, size,
+ VOLATILE_STATE_VERSION, VOLATILE_STATE_MAGIC,
+ 1);
+
+ /* skip g_rcIndex: these are 'constants' */
+ written += TPM_HANDLE_Marshal(&g_exclusiveAuditSession, buffer, size); /* line 423 */
+ /* g_time: may not be necessary */
+ written += UINT64_Marshal(&g_time, buffer, size); /* line 426 */
+ /* g_timeEpoch: skipped so far -- needs investigation */
+ /* g_phEnable: since we won't call TPM2_Starup, we need to write it */
+ written += BOOL_Marshal(&g_phEnable, buffer, size); /* line 439 */
+ /* g_pcrReconfig: must write */
+ written += BOOL_Marshal(&g_pcrReConfig, buffer, size); /* line 443 */
+ /* g_DRTMHandle: must write */
+ written += TPM_HANDLE_Marshal(&g_DRTMHandle, buffer, size); /* line 448 */
+ /* g_DrtmPreStartup: must write */
+ written += BOOL_Marshal(&g_DrtmPreStartup, buffer, size); /* line 453 */
+ /* g_StartupLocality3: must write */
+ written += BOOL_Marshal(&g_StartupLocality3, buffer, size); /* line 458 */
+
+#if USE_DA_USED
+ has_block = TRUE;
+#else
+ has_block = FALSE;
+#endif
+ written += BLOCK_SKIP_WRITE_PUSH(has_block, buffer, size);
+
+#if USE_DA_USED
+ /* g_daUsed: must write */
+ written += BOOL_Marshal(&g_daUsed, buffer, size); /* line 484 */
+#endif
+ BLOCK_SKIP_WRITE_POP(size);
+
+ /* g_updateNV: can skip since it seems to only be valid during execution of a command*/
+ /* g_powerWasLost: must write */
+ written += BOOL_Marshal(&g_powerWasLost, buffer, size); /* line 504 */
+ /* g_clearOrderly: can skip since it seems to only be valid during execution of a command */
+ /* g_prevOrderlyState: must write */
+ written += UINT16_Marshal(&g_prevOrderlyState, buffer, size); /* line 516 */
+ /* g_nvOk: must write */
+ written += BOOL_Marshal(&g_nvOk, buffer, size); /* line 522 */
+ /* g_NvStatus: can skip since it seems to only be valid during execution of a command */
+
+#if 0 /* does not exist */
+ written += TPM2B_AUTH_Marshal(&g_platformUniqueAuthorities, buffer, size); /* line 535 */
+#endif
+ written += TPM2B_AUTH_Marshal(&g_platformUniqueDetails, buffer, size); /* line 536 */
+
+ /* gp (persistent_data): skip; we assume its latest states in the persistent data file */
+
+ /* we store the next 3 because they may not have been written to NVRAM */
+ written += ORDERLY_DATA_Marshal(&go, buffer, size); /* line 707 */
+ written += STATE_CLEAR_DATA_Marshal(&gc, buffer, size); /* line 738 */
+ written += STATE_RESET_DATA_Marshal(&gr, buffer, size); /* line 826 */
+
+ /* g_manufactured: must write */
+ written += BOOL_Marshal(&g_manufactured, buffer, size); /* line 928 */
+ /* g_initialized: must write */
+ written += BOOL_Marshal(&g_initialized, buffer, size); /* line 932 */
+
+#if defined SESSION_PROCESS_C || defined GLOBAL_C || defined MANUFACTURE_C
+ has_block = TRUE;
+#else
+ has_block = FALSE;
+#endif
+ written += BLOCK_SKIP_WRITE_PUSH(has_block, buffer, size);
+
+#if defined SESSION_PROCESS_C || defined GLOBAL_C || defined MANUFACTURE_C
+ /*
+ * The session related variables may only be valid during the execution
+ * of a single command; safer to store
+ */
+ array_size = ARRAY_SIZE(s_sessionHandles);
+ written += UINT16_Marshal(&array_size, buffer, size);
+
+ for (i = 0; i < array_size; i++) {
+ written += TPM_HANDLE_Marshal(&s_sessionHandles[i], buffer, size);
+ written += TPMA_SESSION_Marshal(&s_attributes[i], buffer, size);
+ written += TPM_HANDLE_Marshal(&s_associatedHandles[i], buffer, size);
+ written += TPM2B_NONCE_Marshal(&s_nonceCaller[i], buffer, size);
+ written += TPM2B_AUTH_Marshal(&s_inputAuthValues[i], buffer, size);
+ /* s_usedSessions: cannot serialize this since it is a pointer; also, isn't used */
+ }
+ written += TPM_HANDLE_Marshal(&s_encryptSessionIndex, buffer, size);
+ written += TPM_HANDLE_Marshal(&s_decryptSessionIndex, buffer, size);
+ written += TPM_HANDLE_Marshal(&s_auditSessionIndex, buffer, size);
+
+#if CC_GetCommandAuditDigest
+ has_block = TRUE;
+#else
+ has_block = FALSE;
+#endif
+ written += BLOCK_SKIP_WRITE_PUSH(has_block, buffer, size);
+
+#if CC_GetCommandAuditDigest
+ /* s_cpHashForCommandAudit: seems not used; better to write it */
+ written += TPM2B_DIGEST_Marshal(&s_cpHashForCommandAudit, buffer, size);
+#endif
+ BLOCK_SKIP_WRITE_POP(size);
+
+ /* s_DAPendingOnNV: needs investigation ... */
+ written += BOOL_Marshal(&s_DAPendingOnNV, buffer, size);
+#endif // SESSION_PROCESS_C
+ BLOCK_SKIP_WRITE_POP(size);
+
+#if defined DA_C || defined GLOBAL_C || defined MANUFACTURE_C
+ has_block = TRUE;
+#else
+ has_block = FALSE;
+#endif
+ written += BLOCK_SKIP_WRITE_PUSH(has_block, buffer, size);
+
+#if defined DA_C || defined GLOBAL_C || defined MANUFACTURE_C
+
+#if !ACCUMULATE_SELF_HEAL_TIMER
+ has_block = TRUE;
+#else
+ has_block = FALSE;
+#endif
+ written += BLOCK_SKIP_WRITE_PUSH(has_block, buffer, size);
+
+#if !ACCUMULATE_SELF_HEAL_TIMER
+ written += UINT64_Marshal(&s_selfHealTimer, buffer, size); /* line 975 */
+ written += UINT64_Marshal(&s_lockoutTimer, buffer, size); /* line 977 */
+#endif // ACCUMULATE_SELF_HEAL_TIMER
+ BLOCK_SKIP_WRITE_POP(size);
+#endif // DA_C
+ BLOCK_SKIP_WRITE_POP(size);
+
+#if defined NV_C || defined GLOBAL_C
+ has_block = TRUE;
+#else
+ has_block = FALSE;
+#endif
+ written += BLOCK_SKIP_WRITE_PUSH(has_block, buffer, size);
+ /* s_evictNvEnd set in NvInitStatic called by NvPowerOn in case g_powerWasLost
+ * Unless we set g_powerWasLost=TRUE and call NvPowerOn, we have to include it.
+ */
+#if defined NV_C || defined GLOBAL_C
+ written += UINT32_Marshal(&s_evictNvEnd, buffer, size); /* line 984 */
+ /* s_indexOrderlyRam read from NVRAM in NvEntityStartup and written to it
+ * in NvUpdateIndexOrderlyData called by TPM2_Shutdown and initialized
+ * in NvManufacture -- since we don't call TPM2_Shutdown we serialize it here
+ */
+ array_size = sizeof(s_indexOrderlyRam);
+ written += UINT16_Marshal(&array_size, buffer, size);
+ written += Array_Marshal(s_indexOrderlyRam, array_size, buffer, size);
+
+ written += UINT64_Marshal(&s_maxCounter, buffer, size); /* line 992 */
+ /* the following need not be written; NvIndexCacheInit initializes them partly
+ * and NvIndexCacheInit() is called during ExecuteCommand()
+ * - s_cachedNvIndex
+ * - s_cachedNvRef
+ * - s_cachedNvRamRef
+ */
+#endif
+ BLOCK_SKIP_WRITE_POP(size);
+
+#if defined OBJECT_C || defined GLOBAL_C
+ has_block = TRUE;
+#else
+ has_block = FALSE;
+#endif
+ written += BLOCK_SKIP_WRITE_PUSH(has_block, buffer, size);
+
+#if defined OBJECT_C || defined GLOBAL_C
+ /* used in many places; it doesn't look like TPM2_Shutdown writes this into
+ * persistent memory, so what is lost upon TPM2_Shutdown?
+ */
+ array_size = ARRAY_SIZE(s_objects);
+ written += UINT16_Marshal(&array_size, buffer, size);
+
+ for (i = 0; i < array_size; i++) {
+ written += ANY_OBJECT_Marshal(&s_objects[i], buffer, size);
+ }
+#endif
+ BLOCK_SKIP_WRITE_POP(size);
+
+#if defined PCR_C || defined GLOBAL_C
+ has_block = TRUE;
+#else
+ has_block = FALSE;
+#endif
+ written += BLOCK_SKIP_WRITE_PUSH(has_block, buffer, size);
+
+#if defined PCR_C || defined GLOBAL_C
+ /* s_pcrs: Marshal *all* PCRs, even those for which stateSave bit is not set */
+ array_size = ARRAY_SIZE(s_pcrs);
+ written += UINT16_Marshal(&array_size, buffer, size);
+
+ for (i = 0; i < array_size; i++) {
+ written += PCR_Marshal(&s_pcrs[i], buffer, size);
+ }
+#endif
+ BLOCK_SKIP_WRITE_POP(size);
+
+#if defined SESSION_C || defined GLOBAL_C
+ has_block = TRUE;
+#else
+ has_block = FALSE;
+#endif
+ written += BLOCK_SKIP_WRITE_PUSH(has_block, buffer, size);
+
+#if defined SESSION_C || defined GLOBAL_C
+ /* s_sessions: */
+ array_size = ARRAY_SIZE(s_sessions);
+ written += UINT16_Marshal(&array_size, buffer, size);
+
+ for (i = 0; i < array_size; i++) {
+ written += SESSION_SLOT_Marshal(&s_sessions[i], buffer, size);
+ }
+ /* s_oldestSavedSession: */
+ written += UINT32_Marshal(&s_oldestSavedSession, buffer, size);
+ /* s_freeSessionSlots: */
+ written += UINT32_Marshal((UINT32 *)&s_freeSessionSlots, buffer, size);
+#endif
+ BLOCK_SKIP_WRITE_POP(size);
+
+#if defined IO_BUFFER_C || defined GLOBAL_C
+ /* s_actionInputBuffer: skip; only used during a single command */
+ /* s_actionOutputBuffer: skip; only used during a single command */
+#endif
+ written += BOOL_Marshal(&g_inFailureMode, buffer, size); /* line 1078 */
+
+ /* TPM established bit */
+ tpmEst = _rpc__Signal_GetTPMEstablished();
+ written += BOOL_Marshal(&tpmEst, buffer, size);
+
+#if defined TPM_FAIL_C || defined GLOBAL_C || 1
+ has_block = TRUE;
+#else
+ has_block = FALSE;
+#endif
+ written += BLOCK_SKIP_WRITE_PUSH(has_block, buffer, size);
+
+#if defined TPM_FAIL_C || defined GLOBAL_C || 1
+ written += UINT32_Marshal(&s_failFunction, buffer, size);
+ written += UINT32_Marshal(&s_failLine, buffer, size);
+ written += UINT32_Marshal(&s_failCode, buffer, size);
+#endif // TPM_FAIL_C
+ BLOCK_SKIP_WRITE_POP(size);
+
+#ifndef HARDWARE_CLOCK
+ has_block = TRUE;
+#else
+ has_block = FALSE;
+#endif
+ written += BLOCK_SKIP_WRITE_PUSH(has_block, buffer, size);
+
+#ifndef HARDWARE_CLOCK
+ tmp_uint64 = s_realTimePrevious;
+ written += UINT64_Marshal(&tmp_uint64, buffer, size);
+ tmp_uint64 = s_tpmTime;
+ written += UINT64_Marshal(&tmp_uint64, buffer, size);
+#endif
+ BLOCK_SKIP_WRITE_POP(size);
+
+ written += BOOL_Marshal(&s_timerReset, buffer, size);
+ written += BOOL_Marshal(&s_timerStopped, buffer, size);
+ written += UINT32_Marshal(&s_adjustRate, buffer, size);
+
+ tmp_uint64 = ClockGetTime(CLOCK_REALTIME);
+ written += UINT64_Marshal(&tmp_uint64, buffer, size);
+
+ written += BLOCK_SKIP_WRITE_PUSH(TRUE, buffer, size); /* v3 */
+
+ /* tie the volatile state to the EP,SP, and PPSeed */
+ NvRead(&pd, NV_PERSISTENT_DATA, sizeof(pd));
+ written += TPM2B_Marshal(&pd.EPSeed.b, sizeof(pd.EPSeed.t.buffer), buffer, size);
+ written += TPM2B_Marshal(&pd.SPSeed.b, sizeof(pd.SPSeed.t.buffer), buffer, size);
+ written += TPM2B_Marshal(&pd.PPSeed.b, sizeof(pd.PPSeed.t.buffer), buffer, size);
+
+ written += BLOCK_SKIP_WRITE_PUSH(TRUE, buffer, size); /* v4 */
+
+ tmp_uint64 = ClockGetTime(CLOCK_MONOTONIC) + s_hostMonotonicAdjustTime;
+ written += UINT64_Marshal(&tmp_uint64, buffer, size);
+
+ written += UINT64_Marshal(&s_suspendedElapsedTime, buffer, size);
+ written += UINT64_Marshal(&s_lastSystemTime, buffer, size);
+ written += UINT64_Marshal(&s_lastReportedTime, buffer, size);
+
+ written += BLOCK_SKIP_WRITE_PUSH(TRUE, buffer, size); /* v5 */
+ /* future versions append below this line */
+
+ BLOCK_SKIP_WRITE_POP(size); /* v5 */
+ BLOCK_SKIP_WRITE_POP(size); /* v4 */
+ BLOCK_SKIP_WRITE_POP(size); /* v3 */
+
+ /* keep marker at end */
+ tmp_uint32 = VOLATILE_STATE_MAGIC;
+ written += UINT32_Marshal(&tmp_uint32, buffer, size);
+
+ BLOCK_SKIP_WRITE_CHECK;
+
+ return written;
+}
+
+static TPM_RC
+VolatileState_TailV4_Unmarshal(BYTE **buffer, INT32 *size)
+{
+ TPM_RC rc = TPM_RC_SUCCESS;
+ UINT64 tmp_uint64;
+
+ if (rc == TPM_RC_SUCCESS) {
+ rc = UINT64_Unmarshal(&tmp_uint64, buffer, size);
+ s_hostMonotonicAdjustTime = tmp_uint64 - ClockGetTime(CLOCK_MONOTONIC);
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ rc = UINT64_Unmarshal(&s_suspendedElapsedTime, buffer, size);
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ rc = UINT64_Unmarshal(&s_lastSystemTime, buffer, size);
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ rc = UINT64_Unmarshal(&s_lastReportedTime, buffer, size);
+ }
+
+ return rc;
+}
+
+static TPM_RC
+VolatileState_TailV3_Unmarshal(BYTE **buffer, INT32 *size)
+{
+ TPM_RC rc = TPM_RC_SUCCESS;
+ PERSISTENT_DATA pd;
+ TPM2B_SEED seed = {
+ .b.size = 0,
+ };
+
+ NvRead(&pd, NV_PERSISTENT_DATA, sizeof(pd));
+
+ if (rc == TPM_RC_SUCCESS) {
+ rc = TPM2B_Unmarshal(&seed.b, PRIMARY_SEED_SIZE, buffer, size);
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ if (seed.b.size > PRIMARY_SEED_SIZE) /* coverity */
+ rc = TPM_RC_SIZE;
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ if (TPM2B_Cmp(&seed.b, &pd.EPSeed.b)) {
+ TPMLIB_LogTPM2Error("%s: EPSeed does not match\n",
+ __func__);
+ rc = TPM_RC_VALUE;
+ }
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ rc = TPM2B_Unmarshal(&seed.b, PRIMARY_SEED_SIZE, buffer, size);
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ if (seed.b.size > PRIMARY_SEED_SIZE) /* coverity */
+ rc = TPM_RC_SIZE;
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ if (TPM2B_Cmp(&seed.b, &pd.SPSeed.b)) {
+ TPMLIB_LogTPM2Error("%s: SPSeed does not match\n",
+ __func__);
+ rc = TPM_RC_VALUE;
+ }
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ rc = TPM2B_Unmarshal(&seed.b, PRIMARY_SEED_SIZE, buffer, size);
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ if (seed.b.size > PRIMARY_SEED_SIZE) /* coverity */
+ rc = TPM_RC_SIZE;
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ if (TPM2B_Cmp(&seed.b, &pd.PPSeed.b)) {
+ TPMLIB_LogTPM2Error("%s: PPSeed does not match\n",
+ __func__);
+ rc = TPM_RC_VALUE;
+ }
+ }
+
+ return rc;
+}
+
+TPM_RC
+VolatileState_Unmarshal(BYTE **buffer, INT32 *size)
+{
+ TPM_RC rc = TPM_RC_SUCCESS;
+ size_t i;
+ UINT64 tmp_uint64;
+ UINT32 tmp_uint32;
+ NV_HEADER hdr;
+ BOOL needs_block;
+ UINT16 array_size = 0;
+ UINT64 backthen;
+
+ if (rc == TPM_RC_SUCCESS) {
+ rc = NV_HEADER_Unmarshal(&hdr, buffer, size,
+ VOLATILE_STATE_VERSION, VOLATILE_STATE_MAGIC);
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ rc = TPM_HANDLE_Unmarshal(&g_exclusiveAuditSession, buffer, size); /* line 423 */
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ rc = UINT64_Unmarshal(&g_time, buffer, size); /* line 426 */
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ rc = BOOL_Unmarshal(&g_phEnable, buffer, size); /* line 439 */
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ rc = BOOL_Unmarshal(&g_pcrReConfig, buffer, size); /* line 443 */
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ rc = TPM_HANDLE_Unmarshal(&g_DRTMHandle, buffer, size); /* line 448 */
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ rc = BOOL_Unmarshal(&g_DrtmPreStartup, buffer, size); /* line 453 */
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ rc = BOOL_Unmarshal(&g_StartupLocality3, buffer, size); /* line 458 */
+ }
+
+#if USE_DA_USED
+ needs_block = TRUE;
+#else
+ needs_block = FALSE;
+#endif
+ if (rc == TPM_RC_SUCCESS) {
+ BLOCK_SKIP_READ(skip_da, needs_block, buffer, size,
+ "Volatile state", "g_daUsed");
+ }
+#if USE_DA_USED
+ if (rc == TPM_RC_SUCCESS) {
+ rc = BOOL_Unmarshal(&g_daUsed, buffer, size); /* line 484 */
+ }
+#endif
+skip_da:
+
+ if (rc == TPM_RC_SUCCESS) {
+ rc = BOOL_Unmarshal(&g_powerWasLost, buffer, size); /* line 504 */
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ rc = UINT16_Unmarshal(&g_prevOrderlyState, buffer, size); /* line 516 */
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ rc = BOOL_Unmarshal(&g_nvOk, buffer, size); /* line 522 */
+ }
+#if 0 /* does not exist */
+ if (rc == TPM_RC_SUCCESS) {
+ rc = TPM2B_AUTH_Unmarshal(&g_platformUniqueAuthorities, buffer, size); /* line 535 */
+ }
+#endif
+ if (rc == TPM_RC_SUCCESS) {
+ rc = TPM2B_AUTH_Unmarshal(&g_platformUniqueDetails, buffer, size); /* line 536 */
+ }
+
+ if (rc == TPM_RC_SUCCESS) {
+ rc = ORDERLY_DATA_Unmarshal(&go, buffer, size);
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ rc = STATE_CLEAR_DATA_Unmarshal(&gc, buffer, size);
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ rc = STATE_RESET_DATA_Unmarshal(&gr, buffer, size);
+ }
+
+ if (rc == TPM_RC_SUCCESS) {
+ rc = BOOL_Unmarshal(&g_manufactured, buffer, size); /* line 928 */
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ rc = BOOL_Unmarshal(&g_initialized, buffer, size); /* line 932 */
+ }
+
+#if defined SESSION_PROCESS_C || defined GLOBAL_C || defined MANUFACTURE_C
+ needs_block = TRUE;
+#else
+ needs_block = FALSE;
+#endif
+ if (rc == TPM_RC_SUCCESS) {
+ BLOCK_SKIP_READ(skip_session_process, needs_block, buffer, size,
+ "Volatile state", "s_sessionHandles");
+ }
+#if defined SESSION_PROCESS_C || defined GLOBAL_C || defined MANUFACTURE_C
+ if (rc == TPM_RC_SUCCESS) {
+ rc = UINT16_Unmarshal(&array_size, buffer, size);
+ }
+ if (rc == TPM_RC_SUCCESS &&
+ array_size != ARRAY_SIZE(s_sessionHandles)) {
+ TPMLIB_LogTPM2Error("Volatile state: Bad array size for s_sessionHandles; "
+ "expected %zu, got %u\n",
+ ARRAY_SIZE(s_sessionHandles), array_size);
+ rc = TPM_RC_BAD_PARAMETER;
+ }
+ for (i = 0; i < array_size && rc == TPM_RC_SUCCESS; i++) {
+ if (rc == TPM_RC_SUCCESS) {
+ rc = TPM_HANDLE_Unmarshal(&s_sessionHandles[i], buffer, size);
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ rc = TPMA_SESSION_Unmarshal(&s_attributes[i], buffer, size);
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ rc = TPM_HANDLE_Unmarshal(&s_associatedHandles[i], buffer, size);
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ rc = TPM2B_NONCE_Unmarshal(&s_nonceCaller[i], buffer, size);
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ rc = TPM2B_AUTH_Unmarshal(&s_inputAuthValues[i], buffer, size);
+ }
+ }
+
+ if (rc == TPM_RC_SUCCESS) {
+ rc = TPM_HANDLE_Unmarshal(&s_encryptSessionIndex, buffer, size);
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ rc = TPM_HANDLE_Unmarshal(&s_decryptSessionIndex, buffer, size);
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ rc = TPM_HANDLE_Unmarshal(&s_auditSessionIndex, buffer, size);
+ }
+
+#if CC_GetCommandAuditDigest
+ needs_block = TRUE;
+#else
+ needs_block = FALSE;
+#endif
+ if (rc == TPM_RC_SUCCESS) {
+ BLOCK_SKIP_READ(skip_cc_getcommandauditdigest, needs_block, buffer, size,
+ "Volatile state", "s_cpHashForCommandAudit");
+ }
+#if CC_GetCommandAuditDigest
+ if (rc == TPM_RC_SUCCESS) {
+ rc = TPM2B_DIGEST_Unmarshal(&s_cpHashForCommandAudit, buffer, size);
+ }
+#endif
+skip_cc_getcommandauditdigest:
+
+ if (rc == TPM_RC_SUCCESS) {
+ rc = BOOL_Unmarshal(&s_DAPendingOnNV, buffer, size);
+ }
+#endif /* SESSION_PROCESS_C */
+skip_session_process:
+
+#if defined DA_C || defined GLOBAL_C || defined MANUFACTURE_C
+ needs_block = TRUE;
+#else
+ needs_block = FALSE;
+#endif
+ if (rc == TPM_RC_SUCCESS) {
+ BLOCK_SKIP_READ(skip_accumulate_self_heal_timer_1, needs_block, buffer, size,
+ "Volatile state", "s_selfHealTimer.1");
+ }
+
+#if defined DA_C || defined GLOBAL_C || defined MANUFACTURE_C
+#if !ACCUMULATE_SELF_HEAL_TIMER
+ needs_block = TRUE;
+#else
+ needs_block = FALSE;
+#endif
+ if (rc == TPM_RC_SUCCESS) {
+ BLOCK_SKIP_READ(skip_accumulate_self_heal_timer_2, needs_block, buffer, size,
+ "Volatile state", "s_selfHealTimer.2");
+ }
+#if !ACCUMULATE_SELF_HEAL_TIMER
+ if (rc == TPM_RC_SUCCESS) {
+ rc = UINT64_Unmarshal(&s_selfHealTimer, buffer, size); /* line 975 */
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ rc = UINT64_Unmarshal(&s_lockoutTimer, buffer, size); /* line 977 */
+ }
+#endif
+skip_accumulate_self_heal_timer_2:
+#endif
+skip_accumulate_self_heal_timer_1:
+
+#if defined NV_C || defined GLOBAL_C
+ needs_block = TRUE;
+#else
+ needs_block = FALSE;
+#endif
+ if (rc == TPM_RC_SUCCESS) {
+ BLOCK_SKIP_READ(skip_nv, needs_block, buffer, size,
+ "Volatile state", "s_evictNvEnd");
+ }
+
+#if defined NV_C || defined GLOBAL_C
+ if (rc == TPM_RC_SUCCESS) {
+ rc = UINT32_Unmarshal(&s_evictNvEnd, buffer, size); /* line 984 */
+ }
+
+ if (rc == TPM_RC_SUCCESS) {
+ rc = UINT16_Unmarshal(&array_size, buffer, size);
+ }
+ if (rc == TPM_RC_SUCCESS &&
+ array_size != ARRAY_SIZE(s_indexOrderlyRam)) {
+ TPMLIB_LogTPM2Error("Volatile state: Bad array size for s_indexOrderlyRam; "
+ "expected %zu, got %u\n",
+ ARRAY_SIZE(s_indexOrderlyRam), array_size);
+ rc = TPM_RC_BAD_PARAMETER;
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ rc = Array_Unmarshal(s_indexOrderlyRam, array_size, buffer, size);
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ rc = UINT64_Unmarshal(&s_maxCounter, buffer, size); /* line 992 */
+ }
+ /* The following are not included:
+ * - s_cachedNvIndex
+ * - s_cachedNvRef
+ * - s_cachedNvRamRef
+ */
+#endif
+skip_nv:
+
+#if defined OBJECT_C || defined GLOBAL_C
+ needs_block = TRUE;
+#else
+ needs_block = FALSE;
+#endif
+ if (rc == TPM_RC_SUCCESS) {
+ BLOCK_SKIP_READ(skip_object, needs_block, buffer, size,
+ "Volatile state", "s_objects");
+ }
+#if defined OBJECT_C || defined GLOBAL_C
+ if (rc == TPM_RC_SUCCESS) {
+ rc = UINT16_Unmarshal(&array_size, buffer, size);
+ }
+ if (rc == TPM_RC_SUCCESS &&
+ array_size != ARRAY_SIZE(s_objects)) {
+ TPMLIB_LogTPM2Error("Volatile state: Bad array size for s_objects; "
+ "expected %zu, got %u\n",
+ ARRAY_SIZE(s_objects), array_size);
+ rc = TPM_RC_BAD_PARAMETER;
+ }
+ for (i = 0; i < array_size && rc == TPM_RC_SUCCESS; i++) {
+ rc = ANY_OBJECT_Unmarshal(&s_objects[i], buffer, size, true);
+ }
+#endif
+skip_object:
+
+#if defined PCR_C || defined GLOBAL_C
+ needs_block = TRUE;
+#else
+ needs_block = FALSE;
+#endif
+ if (rc == TPM_RC_SUCCESS) {
+ BLOCK_SKIP_READ(skip_pcr, needs_block, buffer, size,
+ "Volatile state", "s_pcrs");
+ }
+#if defined PCR_C || defined GLOBAL_C
+ if (rc == TPM_RC_SUCCESS) {
+ rc = UINT16_Unmarshal(&array_size, buffer, size);
+ }
+ if (rc == TPM_RC_SUCCESS &&
+ array_size != ARRAY_SIZE(s_pcrs)) {
+ TPMLIB_LogTPM2Error("Volatile state: Bad array size for s_pcrs; "
+ "expected %zu, got %u\n",
+ ARRAY_SIZE(s_pcrs), array_size);
+ rc = TPM_RC_BAD_PARAMETER;
+ }
+ for (i = 0; i < array_size && rc == TPM_RC_SUCCESS; i++) {
+ rc = PCR_Unmarshal(&s_pcrs[i], buffer, size, &shadow.pcrAllocated);
+ }
+#endif
+skip_pcr:
+
+#if defined SESSION_C || defined GLOBAL_C
+ needs_block = TRUE;
+#else
+ needs_block = FALSE;
+#endif
+ if (rc == TPM_RC_SUCCESS) {
+ BLOCK_SKIP_READ(skip_session, needs_block, buffer, size,
+ "Volatile state", "s_sessions");
+ }
+#if defined SESSION_C || defined GLOBAL_C
+ if (rc == TPM_RC_SUCCESS) {
+ rc = UINT16_Unmarshal(&array_size, buffer, size);
+ }
+ if (rc == TPM_RC_SUCCESS &&
+ array_size != ARRAY_SIZE(s_sessions)) {
+ TPMLIB_LogTPM2Error("Volatile state: Bad array size for s_sessions; "
+ "expected %zu, got %u\n",
+ ARRAY_SIZE(s_sessions), array_size);
+ rc = TPM_RC_BAD_PARAMETER;
+ }
+ /* s_sessions: */
+ for (i = 0; i < array_size && rc == TPM_RC_SUCCESS; i++) {
+ rc = SESSION_SLOT_Unmarshal(&s_sessions[i], buffer, size);
+ }
+ /* s_oldestSavedSession: */
+ if (rc == TPM_RC_SUCCESS) {
+ rc = UINT32_Unmarshal(&s_oldestSavedSession, buffer, size);
+ }
+ /* s_freeSessionSlots: */
+ if (rc == TPM_RC_SUCCESS) {
+ rc = UINT32_Unmarshal((UINT32 *)&s_freeSessionSlots, buffer, size);
+ }
+#endif
+skip_session:
+
+ if (rc == TPM_RC_SUCCESS) {
+ rc = BOOL_Unmarshal(&g_inFailureMode, buffer, size); /* line 1078 */
+ }
+
+ /* TPM established bit */
+ if (rc == TPM_RC_SUCCESS) {
+ BOOL tpmEst;
+ rc = BOOL_Unmarshal(&tpmEst, buffer, size);
+ if (rc == TPM_RC_SUCCESS) {
+ if (tpmEst)
+ _rpc__Signal_SetTPMEstablished();
+ else
+ _rpc__Signal_ResetTPMEstablished();
+ }
+ }
+
+#if defined TPM_FAIL_C || defined GLOBAL_C || 1
+ needs_block = TRUE;
+#else
+ needs_block = FALSE;
+#endif
+ if (rc == TPM_RC_SUCCESS) {
+ BLOCK_SKIP_READ(skip_fail, needs_block, buffer, size,
+ "Volatile state", "s_failFunction");
+ }
+
+#if defined TPM_FAIL_C || defined GLOBAL_C || 1
+ /* appended in v2 */
+ if (rc == TPM_RC_SUCCESS) {
+ rc = UINT32_Unmarshal(&s_failFunction, buffer, size);
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ rc = UINT32_Unmarshal(&s_failLine, buffer, size);
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ rc = UINT32_Unmarshal(&s_failCode, buffer, size);
+ }
+#endif
+skip_fail:
+
+#ifndef HARDWARE_CLOCK
+ needs_block = TRUE;
+#else
+ needs_block = FALSE;
+#endif
+ if (rc == TPM_RC_SUCCESS) {
+ BLOCK_SKIP_READ(skip_hardware_clock, needs_block, buffer, size,
+ "Volatile state", "s_realTimePrevious");
+ }
+
+#ifndef HARDWARE_CLOCK
+ if (rc == TPM_RC_SUCCESS) {
+ rc = UINT64_Unmarshal(&tmp_uint64, buffer, size);
+ s_realTimePrevious = tmp_uint64;
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ rc = UINT64_Unmarshal(&tmp_uint64, buffer, size);
+ s_tpmTime = tmp_uint64;
+ }
+#endif
+skip_hardware_clock:
+
+ if (rc == TPM_RC_SUCCESS) {
+ rc = BOOL_Unmarshal(&s_timerReset, buffer, size);
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ rc = BOOL_Unmarshal(&s_timerStopped, buffer, size);
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ rc = UINT32_Unmarshal(&s_adjustRate, buffer, size);
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ rc = UINT64_Unmarshal(&backthen, buffer, size);
+ }
+
+ /* version 2 starts having indicator for next versions that we can skip;
+ this allows us to downgrade state */
+ if (rc == TPM_RC_SUCCESS && hdr.version >= 2) {
+ BLOCK_SKIP_READ(skip_future_versions, hdr.version >= 3, buffer, size,
+ "Volatile State", "version 3 or later");
+ if (rc == TPM_RC_SUCCESS) {
+ rc = VolatileState_TailV3_Unmarshal(buffer, size);
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ BLOCK_SKIP_READ(skip_future_versions, hdr.version >= 4, buffer, size,
+ "Volatile State", "version 4 or later");
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ rc = VolatileState_TailV4_Unmarshal(buffer, size);
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ BLOCK_SKIP_READ(skip_future_versions, FALSE, buffer, size,
+ "Volatile State", "version 5 or later");
+ }
+ /* future versions append here */
+ }
+
+skip_future_versions:
+
+ /* keep marker at end: */
+ if (rc == TPM_RC_SUCCESS) {
+ rc = UINT32_Unmarshal(&tmp_uint32, buffer, size);
+ if (rc == TPM_RC_SUCCESS) {
+ if (tmp_uint32 != VOLATILE_STATE_MAGIC) {
+ TPMLIB_LogTPM2Error("Invalid volatile state magic. "
+ "Expected 0x%08x, got 0x%08x\n",
+ VOLATILE_STATE_MAGIC, tmp_uint32);
+ rc = TPM_RC_BAD_TAG;
+ }
+ }
+ }
+
+ if (rc == TPM_RC_SUCCESS) {
+ BOOL timesAreRealtime = hdr.version <= 3;
+ /* Before Rev148 (header version <= 3), times were reported in
+ realtime; we need to account for this now */
+ ClockAdjustPostResume(backthen, timesAreRealtime);
+ }
+ return rc;
+}
+
+/********************************************************************
+ * The following is a list of compile-time constants that we verify against
+ * when state is presented to us. Comparison operators allow us to verify
+ * compile time constants' values against what we would accept when reading
+ * state. So for example a value of 1024 for a buffer size that is read can
+ * be compared against the value that this implementation has been compiled
+ * with. In some case a 'less or equal' [LE] (1024 < 2048) may be acceptable
+ * but that depends on the purpose of the compile time constant. The most
+ * conservative approach is to force that the unmarshalled values are equal
+ * [EQ] to the ones of this implementation.
+ *
+ * Meanings of comparison operators:
+ * EQ: The read state must match the state the implementation would produce
+ * The algorithm must have been enabled at the previously implementation
+ * and at the current implementation; or it must have been disabled at
+ * both
+ *
+ * LE: The read state may have been written by a version that did not
+ * implement an algorithm ('0') but the current implementation does
+ * implement it ('1'); this does NOT allow an implementation to accept
+ * the state anymore if the state was written by an implementation that
+ * implemented it ('1') but the current implementation does not im-
+ * plement it
+ *
+ * DONTCARE: Implementation that wrote the state can either have implemented
+ * an algorithm or not and implementation reading the state may
+ * also either implement it or not
+ */
+static const struct _entry {
+ UINT32 constant;
+ char *name;
+ enum CompareOp { EQ, LE, GE, DONTCARE } cmp;
+} pa_compile_constants[] = {
+#define COMPILE_CONSTANT(CONST, CMP) \
+ .constant = CONST, .name = #CONST, .cmp = CMP
+ { COMPILE_CONSTANT(ALG_RSA, EQ) },
+ { COMPILE_CONSTANT(ALG_SHA1, EQ) },
+ { COMPILE_CONSTANT(ALG_HMAC, EQ) },
+ { COMPILE_CONSTANT(ALG_TDES, LE) },
+ { COMPILE_CONSTANT(ALG_AES, EQ) },
+ { COMPILE_CONSTANT(ALG_MGF1, EQ) },
+ { COMPILE_CONSTANT(ALG_XOR, EQ) },
+ { COMPILE_CONSTANT(ALG_KEYEDHASH, EQ) },
+ { COMPILE_CONSTANT(ALG_SHA256, EQ) },
+ { COMPILE_CONSTANT(ALG_SHA384, EQ) },
+ { COMPILE_CONSTANT(ALG_SHA512, EQ) },
+ { COMPILE_CONSTANT(ALG_SM3_256, EQ) },
+ { COMPILE_CONSTANT(ALG_SM4, EQ) },
+ { COMPILE_CONSTANT(ALG_RSASSA, EQ) },
+ { COMPILE_CONSTANT(ALG_RSAES, EQ) },
+ { COMPILE_CONSTANT(ALG_RSAPSS, EQ) },
+ { COMPILE_CONSTANT(ALG_OAEP, EQ) },
+ { COMPILE_CONSTANT(ALG_ECC, EQ) },
+ { COMPILE_CONSTANT(ALG_ECDH, EQ) },
+ { COMPILE_CONSTANT(ALG_ECDSA, EQ) },
+ { COMPILE_CONSTANT(ALG_ECDAA, EQ) },
+ { COMPILE_CONSTANT(ALG_SM2, LE) },
+ { COMPILE_CONSTANT(ALG_ECSCHNORR, EQ) },
+ { COMPILE_CONSTANT(ALG_ECMQV, LE) },
+ { COMPILE_CONSTANT(ALG_SYMCIPHER, EQ) },
+ { COMPILE_CONSTANT(ALG_KDF1_SP800_56A, EQ) },
+ { COMPILE_CONSTANT(ALG_KDF2, LE) },
+ { COMPILE_CONSTANT(ALG_KDF1_SP800_108, EQ) },
+ { COMPILE_CONSTANT(ALG_CMAC, LE) },
+ { COMPILE_CONSTANT(ALG_CTR, EQ) },
+ { COMPILE_CONSTANT(ALG_OFB, EQ) },
+ { COMPILE_CONSTANT(ALG_CBC, EQ) },
+ { COMPILE_CONSTANT(ALG_CFB, EQ) },
+ { COMPILE_CONSTANT(ALG_ECB, EQ) },
+ { COMPILE_CONSTANT(MAX_RSA_KEY_BITS, LE) }, /* old: 2048 */
+ { COMPILE_CONSTANT(MAX_TDES_KEY_BITS, EQ) },
+ { COMPILE_CONSTANT(MAX_AES_KEY_BITS, EQ) },
+ { COMPILE_CONSTANT(128, EQ) }, /* MAX_SM4_KEY_BITS in older code was 128 also with SM4 not active */
+ { COMPILE_CONSTANT(128, EQ) }, /* MAX_CAMELLIA_KEY_BITS in older code was 128 also with CAMELLIA not active */
+ { COMPILE_CONSTANT(ECC_NIST_P192, LE) },
+ { COMPILE_CONSTANT(ECC_NIST_P224, LE) },
+ { COMPILE_CONSTANT(ECC_NIST_P256, LE) },
+ { COMPILE_CONSTANT(ECC_NIST_P384, LE) },
+ { COMPILE_CONSTANT(ECC_NIST_P521, LE) },
+ { COMPILE_CONSTANT(ECC_BN_P256, LE) },
+ { COMPILE_CONSTANT(ECC_BN_P638, LE) },
+ { COMPILE_CONSTANT(ECC_SM2_P256, LE) },
+ { COMPILE_CONSTANT(MAX_ECC_KEY_BITS, LE) },
+ { COMPILE_CONSTANT(4, EQ) }, /* was: HASH_ALIGNMENT, which is not relevant */
+ { COMPILE_CONSTANT(SYM_ALIGNMENT, EQ) },
+ { COMPILE_CONSTANT(IMPLEMENTATION_PCR, EQ) },
+ { COMPILE_CONSTANT(PLATFORM_PCR, EQ) },
+ { COMPILE_CONSTANT(DRTM_PCR, EQ) },
+ { COMPILE_CONSTANT(HCRTM_PCR, EQ) },
+ { COMPILE_CONSTANT(NUM_LOCALITIES, EQ) },
+ { COMPILE_CONSTANT(MAX_HANDLE_NUM, EQ) },
+ { COMPILE_CONSTANT(MAX_ACTIVE_SESSIONS, EQ) },
+ { COMPILE_CONSTANT(MAX_LOADED_SESSIONS, EQ) },
+ { COMPILE_CONSTANT(MAX_SESSION_NUM, EQ) },
+ { COMPILE_CONSTANT(MAX_LOADED_OBJECTS, EQ) },
+ { COMPILE_CONSTANT(MIN_EVICT_OBJECTS, LE) },
+ { COMPILE_CONSTANT(NUM_POLICY_PCR_GROUP, EQ) },
+ { COMPILE_CONSTANT(NUM_AUTHVALUE_PCR_GROUP, EQ) },
+ { COMPILE_CONSTANT(MAX_CONTEXT_SIZE, LE) }, /* old: 2474 */
+ { COMPILE_CONSTANT(MAX_DIGEST_BUFFER, EQ) },
+ { COMPILE_CONSTANT(MAX_NV_INDEX_SIZE, EQ) },
+ { COMPILE_CONSTANT(MAX_NV_BUFFER_SIZE, EQ) },
+ { COMPILE_CONSTANT(MAX_CAP_BUFFER, EQ) },
+ { COMPILE_CONSTANT(NV_MEMORY_SIZE, LE) },
+ { COMPILE_CONSTANT(MIN_COUNTER_INDICES, EQ) },
+ { COMPILE_CONSTANT(NUM_STATIC_PCR, EQ) },
+ { COMPILE_CONSTANT(MAX_ALG_LIST_SIZE, EQ) },
+ { COMPILE_CONSTANT(PRIMARY_SEED_SIZE, EQ) },
+#if CONTEXT_ENCRYPT_ALGORITHM == AES
+#define CONTEXT_ENCRYPT_ALGORITHM_ TPM_ALG_AES
+#endif
+ { COMPILE_CONSTANT(CONTEXT_ENCRYPT_ALGORITHM_, EQ) },
+ { COMPILE_CONSTANT(NV_CLOCK_UPDATE_INTERVAL, EQ) },
+ { COMPILE_CONSTANT(NUM_POLICY_PCR, EQ) },
+ { COMPILE_CONSTANT(ORDERLY_BITS, EQ) },
+ { COMPILE_CONSTANT(MAX_SYM_DATA, EQ) },
+ { COMPILE_CONSTANT(MAX_RNG_ENTROPY_SIZE, EQ) },
+ { COMPILE_CONSTANT(RAM_INDEX_SPACE, EQ) },
+ { COMPILE_CONSTANT(RSA_DEFAULT_PUBLIC_EXPONENT, EQ) },
+ { COMPILE_CONSTANT(ENABLE_PCR_NO_INCREMENT, EQ) },
+ { COMPILE_CONSTANT(CRT_FORMAT_RSA, EQ) },
+ { COMPILE_CONSTANT(VENDOR_COMMAND_COUNT, EQ) },
+ { COMPILE_CONSTANT(MAX_VENDOR_BUFFER_SIZE, EQ) },
+ { COMPILE_CONSTANT(TPM_MAX_DERIVATION_BITS, EQ) },
+ { COMPILE_CONSTANT(PROOF_SIZE, EQ) },
+ { COMPILE_CONSTANT(HASH_COUNT, EQ) },
+
+ /* added for PA_COMPILE_CONSTANTS_VERSION == 3 */
+ { COMPILE_CONSTANT(AES_128, LE) },
+ { COMPILE_CONSTANT(AES_192, LE) },
+ { COMPILE_CONSTANT(AES_256, LE) },
+ { COMPILE_CONSTANT(SM4_128, LE) },
+ { COMPILE_CONSTANT(ALG_CAMELLIA, LE) },
+ { COMPILE_CONSTANT(CAMELLIA_128, LE) },
+ { COMPILE_CONSTANT(CAMELLIA_192, LE) },
+ { COMPILE_CONSTANT(CAMELLIA_256, LE) },
+ { COMPILE_CONSTANT(ALG_SHA3_256, LE) },
+ { COMPILE_CONSTANT(ALG_SHA3_384, LE) },
+ { COMPILE_CONSTANT(ALG_SHA3_512, LE) },
+ { COMPILE_CONSTANT(RSA_1024, LE) },
+ { COMPILE_CONSTANT(RSA_2048, LE) },
+ { COMPILE_CONSTANT(RSA_3072, LE) },
+ { COMPILE_CONSTANT(RSA_4096, LE) },
+ { COMPILE_CONSTANT(RSA_16384, LE) },
+ { COMPILE_CONSTANT(RH_ACT_0, LE) },
+ { COMPILE_CONSTANT(RH_ACT_1, LE) },
+ { COMPILE_CONSTANT(RH_ACT_2, LE) },
+ { COMPILE_CONSTANT(RH_ACT_3, LE) },
+ { COMPILE_CONSTANT(RH_ACT_4, LE) },
+ { COMPILE_CONSTANT(RH_ACT_5, LE) },
+ { COMPILE_CONSTANT(RH_ACT_6, LE) },
+ { COMPILE_CONSTANT(RH_ACT_7, LE) },
+ { COMPILE_CONSTANT(RH_ACT_8, LE) },
+ { COMPILE_CONSTANT(RH_ACT_9, LE) },
+ { COMPILE_CONSTANT(RH_ACT_A, LE) },
+ { COMPILE_CONSTANT(RH_ACT_B, LE) },
+ { COMPILE_CONSTANT(RH_ACT_C, LE) },
+ { COMPILE_CONSTANT(RH_ACT_D, LE) },
+ { COMPILE_CONSTANT(RH_ACT_E, LE) },
+ { COMPILE_CONSTANT(RH_ACT_F, LE) },
+};
+
+static TPM_RC
+UINT32_Unmarshal_CheckConstant(BYTE **buffer, INT32 *size, UINT32 constant,
+ const char *name,
+ enum CompareOp cmp, UINT16 struct_version)
+{
+ TPM_RC rc = TPM_RC_SUCCESS;
+ UINT32 value;
+ const char *op = NULL;
+
+ if (rc == TPM_RC_SUCCESS) {
+ rc = UINT32_Unmarshal(&value, buffer, size);
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ switch (cmp) {
+ case EQ:
+ if (!(constant == value))
+ op = "=";
+ break;
+ case LE:
+ if (!(value <= constant))
+ op = "<=";
+ break;
+ case GE:
+ if (!(value >= constant))
+ op = ">=";
+ break;
+ case DONTCARE:
+ break;
+ }
+ if (op) {
+ TPMLIB_LogTPM2Error("Unexpected value for %s; "
+ "its value %d is not %s %d; "
+ "(version: %u)\n",
+ name, value, op, constant,
+ struct_version);
+ rc = TPM_RC_BAD_PARAMETER;
+ }
+ }
+ return rc;
+}
+
+#define PA_COMPILE_CONSTANTS_MAGIC 0xc9ea6431
+#define PA_COMPILE_CONSTANTS_VERSION 3
+
+/* Marshal compile-time constants related to persistent-all state */
+static UINT32
+PACompileConstants_Marshal(BYTE **buffer, INT32 *size)
+{
+ unsigned i;
+ UINT32 written, tmp_uint32;
+ UINT32 array_size = ARRAY_SIZE(pa_compile_constants);
+ BLOCK_SKIP_INIT;
+
+ written = NV_HEADER_Marshal(buffer, size,
+ PA_COMPILE_CONSTANTS_VERSION,
+ PA_COMPILE_CONSTANTS_MAGIC, 1);
+
+ written += UINT32_Marshal(&array_size, buffer, size);
+
+ for (i = 0; i < array_size; i++) {
+ tmp_uint32 = pa_compile_constants[i].constant;
+ written += UINT32_Marshal(&tmp_uint32, buffer, size);
+ }
+
+ written += BLOCK_SKIP_WRITE_PUSH(TRUE, buffer, size);
+ /* future versions append below this line */
+
+ BLOCK_SKIP_WRITE_POP(size);
+
+ BLOCK_SKIP_WRITE_CHECK;
+
+ return written;
+}
+
+static TPM_RC
+PACompileConstants_Unmarshal(BYTE **buffer, INT32 *size)
+{
+ TPM_RC rc = TPM_RC_SUCCESS;
+ unsigned i;
+ NV_HEADER hdr;
+ UINT32 array_size;
+ UINT32 exp_array_size = 0;
+
+ if (rc == TPM_RC_SUCCESS) {
+ rc = NV_HEADER_Unmarshal(&hdr, buffer, size,
+ PA_COMPILE_CONSTANTS_VERSION,
+ PA_COMPILE_CONSTANTS_MAGIC);
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ switch (hdr.version) {
+ case 1:
+ case 2:
+ /* PA_COMPILE_CONSTANTS_VERSION 1 and 2 had 88 entries */
+ exp_array_size = 88;
+ break;
+ case 3:
+ /* PA_COMPILE_CONSTANTS_VERSION 3 had 104 entries */
+ exp_array_size = 120;
+ break;
+ default:
+ /* we don't suport anything newer - no downgrade */
+ TPMLIB_LogTPM2Error("Unsupported PA_COMPILE_CONSTANTS version %d. "
+ "Supporting up to version %d.\n",
+ hdr.version, PA_COMPILE_CONSTANTS_VERSION);
+ rc = TPM_RC_BAD_VERSION;
+ }
+ }
+
+ if (rc == TPM_RC_SUCCESS) {
+ rc = UINT32_Unmarshal(&array_size, buffer, size);
+ }
+
+ if (rc == TPM_RC_SUCCESS &&
+ array_size != exp_array_size) {
+ TPMLIB_LogTPM2Error("PA_COMPILE_CONSTANTS v%d has non-matching number of "
+ "elements; found %u, expected %u\n",
+ hdr.version, array_size, exp_array_size);
+ }
+
+ for (i = 0; rc == TPM_RC_SUCCESS && i < exp_array_size; i++)
+ rc = UINT32_Unmarshal_CheckConstant(
+ buffer, size, pa_compile_constants[i].constant,
+ pa_compile_constants[i].name,
+ pa_compile_constants[i].cmp, hdr.version);
+
+
+ /* version 2 starts having indicator for next versions that we can skip;
+ this allows us to downgrade state */
+ if (rc == TPM_RC_SUCCESS && hdr.version >= 2) {
+ BLOCK_SKIP_READ(skip_future_versions, FALSE, buffer, size,
+ "PA_COMPILE_CONSTANTS", "version 3 or later");
+ /* future versions nest-append here */
+ }
+
+skip_future_versions:
+
+ /* keep marker at end: */
+ return rc;
+}
+
+#define PERSISTENT_DATA_MAGIC 0x12213443
+#define PERSISTENT_DATA_VERSION 4
+
+static UINT16
+PERSISTENT_DATA_Marshal(PERSISTENT_DATA *data, BYTE **buffer, INT32 *size)
+{
+ UINT16 written;
+ UINT16 array_size;
+ UINT8 clocksize;
+ BOOL has_block;
+ BLOCK_SKIP_INIT;
+
+ written = NV_HEADER_Marshal(buffer, size,
+ PERSISTENT_DATA_VERSION,
+ PERSISTENT_DATA_MAGIC, 4);
+ written += BOOL_Marshal(&data->disableClear, buffer, size);
+ written += TPM_ALG_ID_Marshal(&data->ownerAlg, buffer, size);
+ written += TPM_ALG_ID_Marshal(&data->endorsementAlg, buffer, size);
+ written += TPM_ALG_ID_Marshal(&data->lockoutAlg, buffer, size);
+ written += TPM2B_DIGEST_Marshal(&data->ownerPolicy, buffer, size);
+ written += TPM2B_DIGEST_Marshal(&data->endorsementPolicy, buffer, size);
+ written += TPM2B_DIGEST_Marshal(&data->lockoutPolicy, buffer, size);
+ written += TPM2B_AUTH_Marshal(&data->ownerAuth, buffer, size);
+ written += TPM2B_AUTH_Marshal(&data->endorsementAuth, buffer, size);
+ written += TPM2B_AUTH_Marshal(&data->lockoutAuth, buffer, size);
+ written += TPM2B_Marshal(&data->EPSeed.b, sizeof(data->EPSeed.t.buffer), buffer, size);
+ written += TPM2B_Marshal(&data->SPSeed.b, sizeof(data->SPSeed.t.buffer), buffer, size);
+ written += TPM2B_Marshal(&data->PPSeed.b, sizeof(data->PPSeed.t.buffer), buffer, size);
+ written += TPM2B_PROOF_Marshal(&data->phProof, buffer, size);
+ written += TPM2B_PROOF_Marshal(&data->shProof, buffer, size);
+ written += TPM2B_PROOF_Marshal(&data->ehProof, buffer, size);
+ written += UINT64_Marshal(&data->totalResetCount, buffer, size);
+ written += UINT32_Marshal(&data->resetCount, buffer, size);
+
+#if defined NUM_POLICY_PCR_GROUP && NUM_POLICY_PCR_GROUP > 0
+ has_block = TRUE;
+#else
+ has_block = FALSE;
+#endif
+ written += BLOCK_SKIP_WRITE_PUSH(has_block, buffer, size);
+
+#if defined NUM_POLICY_PCR_GROUP && NUM_POLICY_PCR_GROUP > 0
+ written += PCR_POLICY_Marshal(&data->pcrPolicies, buffer, size);
+#endif
+ BLOCK_SKIP_WRITE_POP(size);
+
+ written += TPML_PCR_SELECTION_Marshal(&data->pcrAllocated, buffer, size);
+
+ /* ppList may grow */
+ array_size = sizeof(data->ppList);
+ written += UINT16_Marshal(&array_size, buffer, size);
+ written += Array_Marshal(&data->ppList[0], array_size, buffer, size);
+
+ written += UINT32_Marshal(&data->failedTries, buffer, size);
+ written += UINT32_Marshal(&data->maxTries, buffer, size);
+ written += UINT32_Marshal(&data->recoveryTime, buffer, size);
+ written += UINT32_Marshal(&data->lockoutRecovery, buffer, size);
+ written += BOOL_Marshal(&data->lockOutAuthEnabled, buffer, size);
+ written += UINT16_Marshal(&data->orderlyState, buffer, size);
+
+ /* auditCommands may grow */
+ array_size = sizeof(data->auditCommands);
+ written += UINT16_Marshal(&array_size, buffer, size);
+ written += Array_Marshal(&data->auditCommands[0], array_size,
+ buffer, size);
+
+ written += TPM_ALG_ID_Marshal(&data->auditHashAlg, buffer, size);
+ written += UINT64_Marshal(&data->auditCounter, buffer, size);
+ written += UINT32_Marshal(&data->algorithmSet, buffer, size);
+ written += UINT32_Marshal(&data->firmwareV1, buffer, size);
+ written += UINT32_Marshal(&data->firmwareV2, buffer, size);
+#if CLOCK_STOPS
+ clocksize = sizeof(UINT64);
+ written += UINT8_Marshal(&clocksize, buffer, size);
+ written += UINT64_Marshal(&data->timeEpoch, buffer, size);
+#else
+ clocksize = sizeof(UINT32);
+ written += UINT8_Marshal(&clocksize, buffer, size);
+ written += UINT32_Marshal(&data->timeEpoch, buffer, size);
+#endif
+
+ written += BLOCK_SKIP_WRITE_PUSH(TRUE, buffer, size);
+
+ /* there's a 'shadow' pcrAllocated as well */
+ written += TPML_PCR_SELECTION_Marshal(&gp.pcrAllocated, buffer, size);
+
+ written += BLOCK_SKIP_WRITE_PUSH(TRUE, buffer, size);
+ written += SEED_COMPAT_LEVEL_Marshal(&data->EPSeedCompatLevel,
+ buffer, size);
+ written += SEED_COMPAT_LEVEL_Marshal(&data->SPSeedCompatLevel,
+ buffer, size);
+ written += SEED_COMPAT_LEVEL_Marshal(&data->PPSeedCompatLevel,
+ buffer, size);
+
+ written += BLOCK_SKIP_WRITE_PUSH(TRUE, buffer, size);
+ /* future versions append below this line */
+
+ BLOCK_SKIP_WRITE_POP(size);
+ BLOCK_SKIP_WRITE_POP(size);
+ BLOCK_SKIP_WRITE_POP(size);
+
+ BLOCK_SKIP_WRITE_CHECK;
+
+ return written;
+}
+
+static TPM_RC
+PERSISTENT_DATA_Unmarshal(PERSISTENT_DATA *data, BYTE **buffer, INT32 *size)
+{
+ TPM_RC rc = TPM_RC_SUCCESS;
+ NV_HEADER hdr;
+ UINT16 array_size;
+ UINT8 clocksize;
+ BOOL needs_block;
+
+ if (rc == TPM_RC_SUCCESS) {
+ rc = NV_HEADER_Unmarshal(&hdr, buffer, size,
+ PERSISTENT_DATA_VERSION,
+ PERSISTENT_DATA_MAGIC);
+ }
+
+ if (rc == TPM_RC_SUCCESS) {
+ rc = BOOL_Unmarshal(&data->disableClear, buffer, size);
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ rc = TPM_ALG_ID_Unmarshal(&data->ownerAlg, buffer, size);
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ rc = TPM_ALG_ID_Unmarshal(&data->endorsementAlg, buffer, size);
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ rc = TPM_ALG_ID_Unmarshal(&data->lockoutAlg, buffer, size);
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ rc = TPM2B_DIGEST_Unmarshal(&data->ownerPolicy, buffer, size);
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ rc = TPM2B_DIGEST_Unmarshal(&data->endorsementPolicy, buffer, size);
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ rc = TPM2B_DIGEST_Unmarshal(&data->lockoutPolicy, buffer, size);
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ rc = TPM2B_AUTH_Unmarshal(&data->ownerAuth, buffer, size);
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ rc = TPM2B_AUTH_Unmarshal(&data->endorsementAuth, buffer, size);
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ rc = TPM2B_AUTH_Unmarshal(&data->lockoutAuth, buffer, size);
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ rc = TPM2B_Unmarshal(&data->EPSeed.b, PRIMARY_SEED_SIZE, buffer, size);
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ rc = TPM2B_Unmarshal(&data->SPSeed.b, PRIMARY_SEED_SIZE, buffer, size);
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ rc = TPM2B_Unmarshal(&data->PPSeed.b, PRIMARY_SEED_SIZE, buffer, size);
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ rc = TPM2B_PROOF_Unmarshal(&data->phProof, buffer, size);
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ rc = TPM2B_PROOF_Unmarshal(&data->shProof, buffer, size);
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ rc = TPM2B_PROOF_Unmarshal(&data->ehProof, buffer, size);
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ rc = UINT64_Unmarshal(&data->totalResetCount, buffer, size);
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ rc = UINT32_Unmarshal(&data->resetCount, buffer, size);
+ }
+
+#if defined NUM_POLICY_PCR_GROUP && NUM_POLICY_PCR_GROUP > 0
+ needs_block = TRUE;
+#else
+ needs_block = FALSE;
+#endif
+ if (rc == TPM_RC_SUCCESS) {
+ BLOCK_SKIP_READ(skip_num_policy_pcr_group, needs_block, buffer, size,
+ "PERSISTENT_DATA", "pcrPolicies");
+ }
+#if defined NUM_POLICY_PCR_GROUP && NUM_POLICY_PCR_GROUP > 0
+ if (rc == TPM_RC_SUCCESS) {
+ rc = PCR_POLICY_Unmarshal(&data->pcrPolicies, buffer, size);
+ }
+#endif
+skip_num_policy_pcr_group:
+
+ if (rc == TPM_RC_SUCCESS) {
+ rc = TPML_PCR_SELECTION_Unmarshal(&data->pcrAllocated, buffer, size);
+
+ shadow.pcrAllocated = data->pcrAllocated;
+ shadow.pcrAllocatedIsNew = TRUE;
+ }
+
+ /* ppList array may not be our size */
+ if (rc == TPM_RC_SUCCESS) {
+ rc = UINT16_Unmarshal(&array_size, buffer, size);
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ BYTE buf[array_size];
+ rc = Array_Unmarshal(buf, array_size, buffer, size);
+ memcpy(data->ppList, buf, MIN(array_size, sizeof(data->ppList)));
+ }
+
+ if (rc == TPM_RC_SUCCESS) {
+ rc = UINT32_Unmarshal(&data->failedTries, buffer, size);
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ rc = UINT32_Unmarshal(&data->maxTries, buffer, size);
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ rc = UINT32_Unmarshal(&data->recoveryTime, buffer, size);
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ rc = UINT32_Unmarshal(&data->lockoutRecovery, buffer, size);
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ rc = BOOL_Unmarshal(&data->lockOutAuthEnabled, buffer, size);
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ /* TPM_SU_Unmarshal returns error if value is 0 */
+ rc = UINT16_Unmarshal(&data->orderlyState, buffer, size);
+ }
+
+ /* auditCommands array may not be our size */
+ if (rc == TPM_RC_SUCCESS) {
+ rc = UINT16_Unmarshal(&array_size, buffer, size);
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ BYTE buf[array_size];
+ rc = Array_Unmarshal(buf, array_size, buffer, size);
+ memcpy(data->auditCommands, buf,
+ MIN(array_size, sizeof(data->auditCommands)));
+ }
+
+ if (rc == TPM_RC_SUCCESS) {
+ rc = TPM_ALG_ID_Unmarshal(&data->auditHashAlg, buffer, size);
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ rc = UINT64_Unmarshal(&data->auditCounter, buffer, size);
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ rc = UINT32_Unmarshal(&data->algorithmSet, buffer, size);
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ rc = UINT32_Unmarshal(&data->firmwareV1, buffer, size);
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ rc = UINT32_Unmarshal(&data->firmwareV2, buffer, size);
+ }
+
+ if (rc == TPM_RC_SUCCESS) {
+ rc = UINT8_Unmarshal(&clocksize, buffer, size);
+ }
+ if (rc == TPM_RC_SUCCESS) {
+#if CLOCK_STOPS
+ if (clocksize != sizeof(UINT64)) {
+ TPMLIB_LogTPM2Error("Unexpected clocksize for epoch; "
+ "Expected %u, got %u\n",
+ sizeof(UINT64), clocksize);
+ rc = TPM_RC_BAD_PARAMETER;
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ rc = UINT64_Unmarshal(&data->timeEpoch, buffer, size);
+ }
+#else
+ if (clocksize != sizeof(UINT32)) {
+ TPMLIB_LogTPM2Error("Unexpected clocksize for epoch; "
+ "Expected %zu, got %u\n",
+ sizeof(UINT32), clocksize);
+ rc = TPM_RC_BAD_PARAMETER;
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ rc = UINT32_Unmarshal(&data->timeEpoch, buffer, size);
+ }
+#endif
+ }
+
+ /* default values before conditional block */
+ data->EPSeedCompatLevel = SEED_COMPAT_LEVEL_ORIGINAL;
+ data->SPSeedCompatLevel = SEED_COMPAT_LEVEL_ORIGINAL;
+ data->PPSeedCompatLevel = SEED_COMPAT_LEVEL_ORIGINAL;
+
+ /* version 2 starts having indicator for next versions that we can skip;
+ this allows us to downgrade state */
+ if (rc == TPM_RC_SUCCESS && hdr.version >= 2) {
+ BLOCK_SKIP_READ(skip_future_versions, hdr.version >= 3, buffer, size,
+ "PERSISTENT_DATA", "version 3 or later");
+ if (rc == TPM_RC_SUCCESS) {
+ rc = TPML_PCR_SELECTION_Unmarshal(&shadow.pcrAllocated, buffer, size);
+ }
+
+ if (rc == TPM_RC_SUCCESS) {
+ BLOCK_SKIP_READ(skip_future_versions, hdr.version >= 4, buffer, size,
+ "PERSISTENT_DATA", "version 4 or later");
+ }
+
+ if (rc == TPM_RC_SUCCESS) {
+ rc = SEED_COMPAT_LEVEL_Unmarshal(&data->EPSeedCompatLevel,
+ buffer, size, "EPSeed");
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ rc = SEED_COMPAT_LEVEL_Unmarshal(&data->SPSeedCompatLevel,
+ buffer, size, "SPSeed");
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ rc = SEED_COMPAT_LEVEL_Unmarshal(&data->PPSeedCompatLevel,
+ buffer, size, "PPSeed");
+ }
+
+ if (rc == TPM_RC_SUCCESS) {
+ BLOCK_SKIP_READ(skip_future_versions, FALSE, buffer, size,
+ "PERSISTENT_DATA", "version 5 or later");
+ }
+ /* future versions nest-append here */
+ }
+
+skip_future_versions:
+
+ if (rc != TPM_RC_SUCCESS) {
+ TPMLIB_LogTPM2Error("Failed to unmarshal PERSISTENT_DATA version %u\n",
+ hdr.version);
+ }
+ return rc;
+}
+
+#define INDEX_ORDERLY_RAM_VERSION 2
+#define INDEX_ORDERLY_RAM_MAGIC 0x5346feab
+static UINT32
+INDEX_ORDERLY_RAM_Marshal(void *array, size_t array_size,
+ BYTE **buffer, INT32 *size)
+{
+ UINT16 written;
+ NV_RAM_HEADER nrh, *nrhp;
+ UINT16 offset = 0;
+ UINT16 datasize;
+ UINT32 sourceside_size = array_size;
+ BLOCK_SKIP_INIT;
+
+ written = NV_HEADER_Marshal(buffer, size,
+ INDEX_ORDERLY_RAM_VERSION,
+ INDEX_ORDERLY_RAM_MAGIC, 1);
+
+ /* the size of the array we are using here */
+ written += UINT32_Marshal(&sourceside_size, buffer, size);
+
+ while (TRUE) {
+ nrhp = array + offset;
+ /* nrhp may point to misaligned address (ubsan), so use 'nrh'; first access only 'size' */
+ memcpy(&nrh, nrhp, sizeof(nrh.size));
+
+ /* write the NVRAM header;
+ nrh->size holds the complete size including data;
+ nrh->size = 0 indicates the end */
+ written += UINT32_Marshal(&nrh.size, buffer, size);
+ if (nrh.size == 0)
+ break;
+ /* copy the entire structure now; ubsan does not allow 'nrh = *nrhp' */
+ memcpy(&nrh, nrhp, sizeof(nrh));
+
+ written += TPM_HANDLE_Marshal(&nrh.handle, buffer, size);
+ written += TPMA_NV_Marshal(&nrh.attributes, buffer, size);
+
+ if (offset + nrh.size > array_size) {
+ TPMLIB_LogTPM2Error("INDEX_ORDERLY_RAM: nrh->size corrupted: %d\n",
+ nrh.size);
+ break;
+ }
+ /* write data size before array */
+ if (nrh.size < sizeof(NV_RAM_HEADER)) {
+ TPMLIB_LogTPM2Error(
+ "INDEX_ORDERLY_RAM: nrh->size < sizeof(NV_RAM_HEADER): %d < %zu\n",
+ (int)nrh.size, sizeof(NV_RAM_HEADER));
+ break;
+ }
+ datasize = nrh.size - sizeof(NV_RAM_HEADER);
+ written += UINT16_Marshal(&datasize, buffer, size);
+ if (datasize > 0) {
+ /* append the data */
+ written += Array_Marshal(array + offset + sizeof(NV_RAM_HEADER),
+ datasize, buffer, size);
+ }
+ offset += nrh.size;
+ if (offset + sizeof(NV_RAM_HEADER) > array_size) {
+ /* nothing will fit anymore and there won't be a 0-sized
+ * terminating node (@1).
+ */
+ break;
+ }
+ }
+
+ written += BLOCK_SKIP_WRITE_PUSH(TRUE, buffer, size);
+ /* future versions append below this line */
+
+ BLOCK_SKIP_WRITE_POP(size);
+
+ BLOCK_SKIP_WRITE_CHECK;
+
+ return written;
+}
+
+static TPM_RC
+INDEX_ORDERLY_RAM_Unmarshal(void *array, size_t array_size,
+ BYTE **buffer, INT32 *size)
+{
+ TPM_RC rc = TPM_RC_SUCCESS;
+ NV_HEADER hdr;
+ NV_RAM_HEADER nrh, *nrhp;
+ UINT16 offset = 0;
+ UINT16 datasize = 0;
+ UINT32 sourceside_size;
+
+ if (rc == TPM_RC_SUCCESS) {
+ rc = NV_HEADER_Unmarshal(&hdr, buffer, size,
+ INDEX_ORDERLY_RAM_VERSION,
+ INDEX_ORDERLY_RAM_MAGIC);
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ /* get the size of the array on the source side
+ we can accommodate different sizes when rebuilding
+ but if it doesn't fit we'll error out and report the sizes */
+ rc = UINT32_Unmarshal(&sourceside_size, buffer, size);
+ }
+
+ while (rc == TPM_RC_SUCCESS) {
+ memset(&nrh, 0, sizeof(nrh)); /* coverity */
+ /* nrhp may point to misaligned address (ubsan)
+ * we read 'into' nrh and copy to nrhp at end
+ */
+ nrhp = array + offset;
+
+ if (offset + sizeof(NV_RAM_HEADER) > sourceside_size) {
+ /* this case can occur with the previous entry filling up the
+ * space; in this case there will not be a 0-sized terminating
+ * node (see @1 above). We clear the rest of our space.
+ */
+ if (array_size > offset)
+ memset(nrhp, 0, array_size - offset);
+ break;
+ }
+
+ /* write the NVRAM header;
+ nrh->size holds the complete size including data;
+ nrh->size = 0 indicates the end */
+ if (offset + sizeof(nrh.size) > array_size) {
+ offset += sizeof(nrh.size);
+ goto exit_size;
+ }
+
+ if (rc == TPM_RC_SUCCESS) {
+ rc = UINT32_Unmarshal(&nrh.size, buffer, size);
+ if (rc == TPM_RC_SUCCESS && nrh.size == 0) {
+ memcpy(nrhp, &nrh, sizeof(nrh.size));
+ break;
+ }
+ }
+ if (offset + sizeof(NV_RAM_HEADER) > array_size) {
+ offset += sizeof(NV_RAM_HEADER);
+ goto exit_size;
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ rc = TPM_HANDLE_Unmarshal(&nrh.handle, buffer, size);
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ rc = TPMA_NV_Unmarshal(&nrh.attributes, buffer, size);
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ rc = UINT16_Unmarshal(&datasize, buffer, size);
+ }
+ if (offset + sizeof(NV_RAM_HEADER) + datasize > array_size) {
+ offset += sizeof(NV_RAM_HEADER) + datasize;
+ goto exit_size;
+ }
+ if (rc == TPM_RC_SUCCESS && datasize > 0) {
+ /* append the data */
+ rc = Array_Unmarshal(array + offset + sizeof(NV_RAM_HEADER),
+ datasize, buffer, size);
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ /* fix up size in case it is architecture-dependent */
+ nrh.size = sizeof(nrh) + datasize;
+ offset += nrh.size;
+ /* copy header into possibly misaligned address in NVRAM */
+ *nrhp = nrh;
+ }
+ }
+
+ /* version 2 starts having indicator for next versions that we can skip;
+ this allows us to downgrade state */
+ if (rc == TPM_RC_SUCCESS && hdr.version >= 2) {
+ BLOCK_SKIP_READ(skip_future_versions, FALSE, buffer, size,
+ "INDEX_ORDERLY_RAM", "version 3 or later");
+ /* future versions nest-append here */
+ }
+
+skip_future_versions:
+ return rc;
+
+exit_size:
+ TPMLIB_LogTPM2Error("INDEX_ORDERLY_RAM:"
+ "Insufficient space to write to offset %u;"
+ "Source had %u bytes, we have %zu bytes.\n",
+ offset, sourceside_size, array_size);
+ return TPM_RC_SIZE;
+}
+
+static void
+USER_NVRAM_Display(const char *msg)
+{
+ NV_REF entryRef = NV_USER_DYNAMIC;
+ UINT32 entrysize;
+ UINT64 offset = 0;
+ TPM_HANDLE handle;
+ UINT32 datasize;
+ NV_INDEX nvi;
+ OBJECT obj;
+ UINT64 maxCount;
+
+ fprintf(stderr, "USER_NVRAM contents %s:\n", msg);
+
+ while (TRUE) {
+ /* 1st: entrysize */
+ NvRead(&entrysize, entryRef, sizeof(entrysize));
+ fprintf(stderr, " offset: %5"PRIu32" entry size: %5u ",
+ (UINT32)(entryRef - NV_USER_DYNAMIC), entrysize);
+ offset = sizeof(UINT32);
+
+ if (entrysize == 0)
+ break;
+
+ /* 2nd: the handle -- it will tell us what datatype this is */
+ NvRead(&handle, entryRef + offset, sizeof(handle));
+ fprintf(stderr, "handle: 0x%08x ", handle);
+
+ switch (HandleGetType(handle)) {
+ case TPM_HT_NV_INDEX:
+ fprintf(stderr, " (NV_INDEX) ");
+ /* NV_INDEX has the index again at offset 0! */
+ NvReadNvIndexInfo(entryRef + offset, &nvi);
+ offset += sizeof(nvi);
+ datasize = entrysize - sizeof(UINT32) - sizeof(nvi);
+ fprintf(stderr, " datasize: %u\n",datasize);
+ break;
+ break;
+ case TPM_HT_PERSISTENT:
+ fprintf(stderr, " (PERSISTENT)");
+ offset += sizeof(handle);
+
+ NvRead(&obj, entryRef + offset, sizeof(obj));
+ offset += sizeof(obj);
+ fprintf(stderr, " sizeof(obj): %zu\n", sizeof(obj));
+ break;
+ default:
+ TPMLIB_LogTPM2Error("USER_NVRAM: Corrupted handle: %08x\n", handle);
+ }
+ /* advance to next entry */
+ entryRef += entrysize;
+ }
+ fprintf(stderr, "\n");
+
+ NvRead(&maxCount, entryRef + offset, sizeof(maxCount));
+ fprintf(stderr, " maxCount: %"PRIu64"\n", maxCount);
+ fprintf(stderr, "-----------------------------\n");
+}
+
+#define USER_NVRAM_VERSION 2
+#define USER_NVRAM_MAGIC 0x094f22c3
+static UINT32
+USER_NVRAM_Marshal(BYTE **buffer, INT32 *size)
+{
+ UINT32 written;
+ UINT32 entrysize;
+ UINT64 offset;
+ NV_REF entryRef = NV_USER_DYNAMIC;
+ NV_INDEX nvi;
+ UINT64 maxCount;
+ TPM_HANDLE handle;
+ OBJECT obj;
+ UINT32 datasize;
+ UINT64 sourceside_size = NV_USER_DYNAMIC_END - NV_USER_DYNAMIC;
+ BLOCK_SKIP_INIT;
+
+ if (FALSE)
+ USER_NVRAM_Display("before marshalling");
+
+ written = NV_HEADER_Marshal(buffer, size,
+ USER_NVRAM_VERSION, USER_NVRAM_MAGIC,
+ 1);
+
+ written += UINT64_Marshal(&sourceside_size, buffer, size);
+
+ while (TRUE) {
+ /* 1st: entrysize */
+ NvRead(&entrysize, entryRef, sizeof(entrysize));
+ offset = sizeof(UINT32);
+
+ /* entrysize is in native format now */
+ written += UINT32_Marshal(&entrysize, buffer, size);
+ if (entrysize == 0)
+ break;
+
+ /* 2nd: the handle -- it will tell us what datatype this is */
+ NvRead(&handle, entryRef + offset, sizeof(handle));
+ written += TPM_HANDLE_Marshal(&handle, buffer, size);
+
+ switch (HandleGetType(handle)) {
+ case TPM_HT_NV_INDEX:
+ /* NV_INDEX has the index again at offset 0! */
+ NvReadNvIndexInfo(entryRef + offset, &nvi);
+ offset += sizeof(nvi);
+
+ written += NV_INDEX_Marshal(&nvi, buffer, size);
+ /* after that: bulk data */
+ datasize = entrysize - sizeof(UINT32) - sizeof(nvi);
+ written += UINT32_Marshal(&datasize, buffer, size);
+ if (datasize > 0) {
+ BYTE buf[datasize];
+ NvRead(buf, entryRef + offset, datasize);
+ written += Array_Marshal(buf, datasize, buffer, size);
+ }
+ break;
+ case TPM_HT_PERSISTENT:
+ offset += sizeof(handle);
+
+ NvRead(&obj, entryRef + offset, sizeof(obj));
+ offset += sizeof(obj);
+ written += ANY_OBJECT_Marshal(&obj, buffer, size);
+ break;
+ default:
+ TPMLIB_LogTPM2Error("USER_NVRAM: Corrupted handle: %08x\n", handle);
+ }
+ /* advance to next entry */
+ entryRef += entrysize;
+ }
+ NvRead(&maxCount, entryRef + offset, sizeof(maxCount));
+ written += UINT64_Marshal(&maxCount, buffer, size);
+
+ written += BLOCK_SKIP_WRITE_PUSH(TRUE, buffer, size);
+ /* future versions append below this line */
+
+ BLOCK_SKIP_WRITE_POP(size);
+
+ BLOCK_SKIP_WRITE_CHECK;
+
+ return written;
+}
+
+/*
+ * USER_NVRAM_Unmarshal:
+ *
+ * Unmarshal the byte stream directly into the NVRAM. Ensure that the
+ * the data fit into the user NVRAM before writing them.
+ *
+ * This function fails if there's not enough NVRAM to write the data into
+ * or if an unknown handle type was encountered.
+ */
+static TPM_RC
+USER_NVRAM_Unmarshal(BYTE **buffer, INT32 *size)
+{
+ TPM_RC rc = TPM_RC_SUCCESS;
+ NV_HEADER hdr;
+ NV_REF entryRef = NV_USER_DYNAMIC;
+ UINT32 entrysize;
+ UINT64 offset, o = 0;
+ NV_INDEX nvi;
+ UINT64 maxCount;
+ TPM_HANDLE handle;
+ OBJECT obj;
+ UINT32 datasize = 0;
+ UINT64 sourceside_size;
+ UINT64 array_size = NV_USER_DYNAMIC_END - NV_USER_DYNAMIC;
+ UINT64 entrysize_offset;
+
+ if (rc == TPM_RC_SUCCESS) {
+ rc = NV_HEADER_Unmarshal(&hdr, buffer, size,
+ USER_NVRAM_VERSION,
+ USER_NVRAM_MAGIC);
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ rc = UINT64_Unmarshal(&sourceside_size, buffer, size);
+ }
+
+ while (rc == TPM_RC_SUCCESS) {
+ /* 1st: entrysize */
+ if (o + sizeof(UINT32) > array_size) {
+ o += sizeof(UINT32);
+ goto exit_size;
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ rc = UINT32_Unmarshal(&entrysize, buffer, size);
+
+ /* the entrysize also depends on the sizeof(nvi); we may have to
+ update it if sizeof(nvi) changed between versions */
+ entrysize_offset = o;
+ NvWrite(entryRef + o, sizeof(entrysize), &entrysize);
+ offset = sizeof(UINT32);
+ if (entrysize == 0)
+ break;
+ }
+ /* 2nd: handle */
+ if (rc == TPM_RC_SUCCESS) {
+ rc = TPM_HANDLE_Unmarshal(&handle, buffer, size);
+ }
+
+ if (rc == TPM_RC_SUCCESS) {
+ switch (HandleGetType(handle)) {
+ case TPM_HT_NV_INDEX:
+ /* we need to read the handle again */
+ if (rc == TPM_RC_SUCCESS &&
+ o + offset + sizeof(nvi) > array_size) {
+ o += offset + sizeof(nvi);
+ goto exit_size;
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ rc = NV_INDEX_Unmarshal(&nvi, buffer, size);
+ NvWrite(entryRef + o + offset, sizeof(nvi), &nvi);
+ offset += sizeof(nvi);
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ rc = UINT32_Unmarshal(&datasize, buffer, size);
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ /* datasize cannot exceed 64k + a few bytes */
+ if (datasize > (0x10000 + 0x100)) {
+ TPMLIB_LogTPM2Error("datasize for NV_INDEX too "
+ "large: %u\n", datasize);
+ rc = TPM_RC_SIZE;
+ }
+ }
+ if (rc == TPM_RC_SUCCESS &&
+ o + offset + datasize > array_size) {
+ o += offset + datasize;
+ goto exit_size;
+ }
+ if (rc == TPM_RC_SUCCESS && datasize > 0) {
+ BYTE buf[datasize];
+ rc = Array_Unmarshal(buf, datasize, buffer, size);
+ NvWrite(entryRef + o + offset, datasize, buf);
+ offset += datasize;
+
+ /* update the entry size; account for expanding nvi */
+ entrysize = sizeof(UINT32) + sizeof(nvi) + datasize;
+ }
+ break;
+ case TPM_HT_PERSISTENT:
+ if (rc == TPM_RC_SUCCESS &&
+ o + offset + sizeof(TPM_HANDLE) + sizeof(obj) >
+ array_size) {
+ o += offset + sizeof(TPM_HANDLE) + sizeof(obj);
+ goto exit_size;
+ }
+
+ if (rc == TPM_RC_SUCCESS) {
+ NvWrite(entryRef + o + offset, sizeof(handle), &handle);
+ offset += sizeof(TPM_HANDLE);
+
+ memset(&obj, 0, sizeof(obj));
+ rc = ANY_OBJECT_Unmarshal(&obj, buffer, size, true);
+ NvWrite(entryRef + o + offset, sizeof(obj), &obj);
+ offset += sizeof(obj);
+ }
+ entrysize = sizeof(UINT32) + sizeof(TPM_HANDLE) + sizeof(obj);
+ break;
+ default:
+ TPMLIB_LogTPM2Error("USER_NVRAM: "
+ "Read handle 0x%08x of unknown type\n",
+ handle);
+ rc = TPM_RC_HANDLE;
+ }
+
+ if (rc == TPM_RC_SUCCESS) {
+ NvWrite(entryRef + entrysize_offset, sizeof(entrysize), &entrysize);
+ }
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ o += offset;
+ }
+ }
+ if (rc == TPM_RC_SUCCESS &&
+ o + offset + sizeof(UINT64) > array_size) {
+ o += offset + sizeof(UINT64);
+ goto exit_size;
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ rc = UINT64_Unmarshal(&maxCount, buffer, size);
+ NvWrite(entryRef + o + offset, sizeof(maxCount), &maxCount);
+ }
+
+ /* version 2 starts having indicator for next versions that we can skip;
+ this allows us to downgrade state */
+ if (rc == TPM_RC_SUCCESS && hdr.version >= 2) {
+ BLOCK_SKIP_READ(skip_future_versions, FALSE, buffer, size,
+ "USER_NVRAM", "version 3 or later");
+ /* future versions nest-append here */
+ }
+
+skip_future_versions:
+
+ if (FALSE)
+ USER_NVRAM_Display("after unmarshalling");
+
+ return rc;
+
+exit_size:
+ TPMLIB_LogTPM2Error("USER_NVRAM:"
+ "Insufficient space to write to offset %"PRIu64";"
+ "Source had %"PRIu64" bytes, we have %"PRIu64" "
+ "bytes.\n",
+ o, sourceside_size, array_size);
+ return TPM_RC_SIZE;
+}
+
+/*
+ * Write out all persistent data by reading them from the NVRAM
+ * and then writing them out.
+ *
+ * - PERSISTENT_DATA (NV_PERSISTENT_DATA)
+ * - ORDERLY_DATA (NV_STATE_RESET_DATA)
+ * - STATE_RESET_DATA (NV_STATE_RESET_DATA)
+ * - STATE_CLEAR_DATA (NV_STATE_CLEAR_DATA)
+ * - indexOrderlyRAM (NV_INDEX_RAM_DATA)
+ * - NVRAM locations (NV_USER_DYNAMIC)
+ */
+#define PERSISTENT_ALL_VERSION 3
+#define PERSISTENT_ALL_MAGIC 0xab364723
+UINT32
+PERSISTENT_ALL_Marshal(BYTE **buffer, INT32 *size)
+{
+ UINT32 magic;
+ PERSISTENT_DATA pd;
+ ORDERLY_DATA od;
+ STATE_RESET_DATA srd;
+ STATE_CLEAR_DATA scd;
+ UINT32 written = 0;
+ BYTE indexOrderlyRam[sizeof(s_indexOrderlyRam)];
+ BLOCK_SKIP_INIT;
+ BOOL writeSuState;
+
+ NvRead(&pd, NV_PERSISTENT_DATA, sizeof(pd));
+ NvRead(&od, NV_ORDERLY_DATA, sizeof(od));
+ NvRead(&srd, NV_STATE_RESET_DATA, sizeof(srd));
+ NvRead(&scd, NV_STATE_CLEAR_DATA, sizeof(scd));
+
+ /* indexOrderlyRam was never endianess-converted; so it's native */
+ NvRead(indexOrderlyRam, NV_INDEX_RAM_DATA, sizeof(indexOrderlyRam));
+
+ written = NV_HEADER_Marshal(buffer, size,
+ PERSISTENT_ALL_VERSION,
+ PERSISTENT_ALL_MAGIC, 3);
+ written += PACompileConstants_Marshal(buffer, size);
+ written += PERSISTENT_DATA_Marshal(&pd, buffer, size);
+ written += ORDERLY_DATA_Marshal(&od, buffer, size);
+ writeSuState = (pd.orderlyState & TPM_SU_STATE_MASK) == TPM_SU_STATE;
+ /* starting with v3 we only write STATE_RESET and STATE_CLEAR if needed */
+ if (writeSuState) {
+ written += STATE_RESET_DATA_Marshal(&srd, buffer, size);
+ written += STATE_CLEAR_DATA_Marshal(&scd, buffer, size);
+ }
+ written += INDEX_ORDERLY_RAM_Marshal(indexOrderlyRam, sizeof(indexOrderlyRam),
+ buffer, size);
+ written += USER_NVRAM_Marshal(buffer, size);
+
+ written += BLOCK_SKIP_WRITE_PUSH(TRUE, buffer, size);
+ /* future versions append below this line */
+
+ BLOCK_SKIP_WRITE_POP(size);
+
+ magic = PERSISTENT_ALL_MAGIC;
+ written += UINT32_Marshal(&magic, buffer, size);
+
+ BLOCK_SKIP_WRITE_CHECK;
+
+ return written;
+}
+
+TPM_RC
+PERSISTENT_ALL_Unmarshal(BYTE **buffer, INT32 *size)
+{
+ TPM_RC rc = TPM_RC_SUCCESS;
+ NV_HEADER hdr;
+ PERSISTENT_DATA pd;
+ ORDERLY_DATA od;
+ STATE_RESET_DATA srd;
+ STATE_CLEAR_DATA scd;
+ BYTE indexOrderlyRam[sizeof(s_indexOrderlyRam)];
+ BOOL readSuState = false;
+
+ memset(&pd, 0, sizeof(pd));
+ memset(&od, 0, sizeof(od));
+ memset(&srd, 0, sizeof(srd));
+ memset(&scd, 0, sizeof(scd));
+ memset(indexOrderlyRam, 0, sizeof(indexOrderlyRam));
+
+ if (rc == TPM_RC_SUCCESS) {
+ rc = NV_HEADER_Unmarshal(&hdr, buffer, size,
+ PERSISTENT_ALL_VERSION,
+ PERSISTENT_ALL_MAGIC);
+ }
+
+ if (rc == TPM_RC_SUCCESS) {
+ rc = PACompileConstants_Unmarshal(buffer, size);
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ rc = PERSISTENT_DATA_Unmarshal(&pd, buffer, size);
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ if (hdr.version < 3) {
+ /* STATE_RESET and STATE_CLEAR were always written before version 3 */
+ readSuState = true;
+ } else {
+ readSuState = (pd.orderlyState & TPM_SU_STATE_MASK) == TPM_SU_STATE;
+ }
+ rc = ORDERLY_DATA_Unmarshal(&od, buffer, size);
+ }
+ if (rc == TPM_RC_SUCCESS && readSuState) {
+ rc = STATE_RESET_DATA_Unmarshal(&srd, buffer, size);
+ }
+ if (rc == TPM_RC_SUCCESS && readSuState) {
+ rc = STATE_CLEAR_DATA_Unmarshal(&scd, buffer, size);
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ rc = INDEX_ORDERLY_RAM_Unmarshal(indexOrderlyRam, sizeof(indexOrderlyRam),
+ buffer, size);
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ /* this will write it into NVRAM right away */
+ rc = USER_NVRAM_Unmarshal(buffer, size);
+ /* if rc == TPM_RC_SUCCESS, we know that there is enough
+ NVRAM to fit everything. */
+ }
+
+ /* version 2 starts having indicator for next versions that we can skip;
+ this allows us to downgrade state */
+ if (rc == TPM_RC_SUCCESS && hdr.version >= 2) {
+ BLOCK_SKIP_READ(skip_future_versions, FALSE, buffer, size,
+ "USER NVRAM", "version 3 or later");
+ /* future versions nest-append here */
+ }
+
+skip_future_versions:
+ if (rc == TPM_RC_SUCCESS) {
+ rc = UINT32_Unmarshal_Check(&hdr.magic,
+ PERSISTENT_ALL_MAGIC, buffer, size,
+ "PERSISTENT_ALL_MAGIC after USER_NVRAM");
+ }
+
+ if (rc == TPM_RC_SUCCESS) {
+ NvWrite(NV_PERSISTENT_DATA, sizeof(pd), &pd);
+ NvWrite(NV_ORDERLY_DATA, sizeof(od), &od);
+ NvWrite(NV_STATE_RESET_DATA, sizeof(srd), &srd);
+ NvWrite(NV_STATE_CLEAR_DATA, sizeof(scd), &scd);
+ NvWrite(NV_INDEX_RAM_DATA, sizeof(indexOrderlyRam), indexOrderlyRam);
+ }
+
+ return rc;
+}
+
+void
+NVShadowRestore(void)
+{
+ if (shadow.pcrAllocatedIsNew) {
+ gp.pcrAllocated = shadow.pcrAllocated;
+ shadow.pcrAllocatedIsNew = FALSE;
+ }
+}
diff --git a/src/tpm2/NVMarshal.h b/src/tpm2/NVMarshal.h
new file mode 100644
index 0000000..92a74fb
--- /dev/null
+++ b/src/tpm2/NVMarshal.h
@@ -0,0 +1,61 @@
+/********************************************************************************/
+/* */
+/* Marshalling and unmarshalling of state */
+/* Written by Stefan Berger */
+/* IBM Thomas J. Watson Research Center */
+/* */
+/* (c) Copyright IBM Corporation 2017,2018. */
+/* */
+/* All rights reserved. */
+/* */
+/* Redistribution and use in source and binary forms, with or without */
+/* modification, are permitted provided that the following conditions are */
+/* met: */
+/* */
+/* Redistributions of source code must retain the above copyright notice, */
+/* this list of conditions and the following disclaimer. */
+/* */
+/* Redistributions in binary form must reproduce the above copyright */
+/* notice, this list of conditions and the following disclaimer in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* Neither the names of the IBM Corporation nor the names of its */
+/* contributors may be used to endorse or promote products derived from */
+/* this software without specific prior written permission. */
+/* */
+/* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS */
+/* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT */
+/* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR */
+/* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT */
+/* HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, */
+/* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT */
+/* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, */
+/* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY */
+/* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT */
+/* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE */
+/* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */
+/********************************************************************************/
+
+#ifndef NVMARSHAL_H
+#define NVMARSHAL_H
+
+#include <stdbool.h>
+
+#include "Tpm.h"
+#include "TpmTypes.h"
+
+#define ARRAY_SIZE(array) (sizeof(array) / sizeof((array)[0]))
+
+UINT16 VolatileState_Marshal(BYTE **buffer, INT32 *size);
+TPM_RC VolatileState_Unmarshal(BYTE **buffer, INT32 *size);
+
+UINT32 PERSISTENT_ALL_Marshal(BYTE **buffer, INT32 *size);
+TPM_RC PERSISTENT_ALL_Unmarshal(BYTE **buffer, INT32 *size);
+
+void NVShadowRestore(void);
+
+UINT16 ANY_OBJECT_Marshal(OBJECT *data, BYTE **buffer, INT32 *size);
+TPM_RC ANY_OBJECT_Unmarshal(OBJECT *data, BYTE **buffer, INT32 *size, BOOL verbose);
+
+#endif /* NVMARSHAL_H */
+
diff --git a/src/tpm2/NVMem.c b/src/tpm2/NVMem.c
new file mode 100644
index 0000000..3d27770
--- /dev/null
+++ b/src/tpm2/NVMem.c
@@ -0,0 +1,494 @@
+/********************************************************************************/
+/* */
+/* NV read and write access methods */
+/* Written by Ken Goldman */
+/* IBM Thomas J. Watson Research Center */
+/* $Id: NVMem.c 1658 2021-01-22 23:14:01Z kgoldman $ */
+/* */
+/* Licenses and Notices */
+/* */
+/* 1. Copyright Licenses: */
+/* */
+/* - Trusted Computing Group (TCG) grants to the user of the source code in */
+/* this specification (the "Source Code") a worldwide, irrevocable, */
+/* nonexclusive, royalty free, copyright license to reproduce, create */
+/* derivative works, distribute, display and perform the Source Code and */
+/* derivative works thereof, and to grant others the rights granted herein. */
+/* */
+/* - The TCG grants to the user of the other parts of the specification */
+/* (other than the Source Code) the rights to reproduce, distribute, */
+/* display, and perform the specification solely for the purpose of */
+/* developing products based on such documents. */
+/* */
+/* 2. Source Code Distribution Conditions: */
+/* */
+/* - Redistributions of Source Code must retain the above copyright licenses, */
+/* this list of conditions and the following disclaimers. */
+/* */
+/* - Redistributions in binary form must reproduce the above copyright */
+/* licenses, this list of conditions and the following disclaimers in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* 3. Disclaimers: */
+/* */
+/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
+/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
+/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
+/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
+/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
+/* information on specification licensing rights available through TCG */
+/* membership agreements. */
+/* */
+/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
+/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
+/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
+/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
+/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
+/* */
+/* - Without limitation, TCG and its members and licensors disclaim all */
+/* liability, including liability for infringement of any proprietary */
+/* rights, relating to use of information in this specification and to the */
+/* implementation of this specification, and TCG disclaims all liability for */
+/* cost of procurement of substitute goods or services, lost profits, loss */
+/* of use, loss of data or any incidental, consequential, direct, indirect, */
+/* or special damages, whether under contract, tort, warranty or otherwise, */
+/* arising in any way out of use or reliance upon this specification or any */
+/* information herein. */
+/* */
+/* (c) Copyright IBM Corp. and others, 2016 - 2021 */
+/* */
+/********************************************************************************/
+
+/* C.6 NVMem.c */
+/* C.6.1. Description */
+/* This file contains the NV read and write access methods. This implementation uses RAM/file and
+ does not manage the RAM/file as NV blocks. The implementation may become more sophisticated over
+ time. */
+/* C.6.2. Includes and Local */
+#include <memory.h>
+#include <string.h>
+#include <assert.h>
+#include "Platform.h"
+/* libtpms added begin */
+#include "NVMarshal.h"
+#include "LibtpmsCallbacks.h"
+#include <errno.h>
+#define TPM_HAVE_TPM2_DECLARATIONS
+#include "tpm_library_intern.h"
+/* libtpms added end */
+
+#if FILE_BACKED_NV
+# include <stdio.h>
+static FILE *s_NvFile = NULL; /* kgold made these static */
+static int s_NeedsManufacture = FALSE;
+#endif
+
+/* C.6.2. Functions */
+/* C.6.2.1. NvFileOpen() */
+
+#if FILE_BACKED_NV
+
+/* This function opens the file used to hold the NV image.
+ Return Type: int */
+/* Return Value Meaning */
+/* >=0 success */
+/* -1 error */
+static int
+NvFileOpen(
+ const char *mode
+ )
+{
+#if defined(NV_FILE_PATH)
+# define TO_STRING(s) TO_STRING_IMPL(s)
+# define TO_STRING_IMPL(s) #s
+ const char* s_NvFilePath = TO_STRING(NV_FILE_PATH);
+# undef TO_STRING
+# undef TO_STRING_IMPL
+#else
+ const char* s_NvFilePath = "NVChip";
+#endif
+
+ // Try to open an exist NVChip file for read/write
+# if defined _MSC_VER && 1
+ if(fopen_s(&s_NvFile, s_NvFilePath, mode) != 0)
+ s_NvFile = NULL;
+# else
+ s_NvFile = fopen(s_NvFilePath, mode);
+# endif
+ return (s_NvFile == NULL) ? -1 : 0;
+}
+
+/* C.6.2.2. NvFileCommit() */
+/* Write all of the contents of the NV image to a file. */
+/* Return Value Meaning */
+/* TRUE success */
+/* FALSE failure */
+static int
+NvFileCommit(
+ void
+ )
+{
+ int OK;
+ // If NV file is not available, return failure
+ if(s_NvFile == NULL)
+ return 1;
+ // Write RAM data to NV
+ fseek(s_NvFile, 0, SEEK_SET);
+ OK = (NV_MEMORY_SIZE == fwrite(s_NV, 1, NV_MEMORY_SIZE, s_NvFile));
+ OK = OK && (0 == fflush(s_NvFile));
+ assert(OK);
+ return OK;
+}
+/* C.6.2.3. NvFileSize() */
+/* This function gets the size of the NV file and puts the file pointer where desired using the seek
+ method values. SEEK_SET => beginning; SEEK_CUR => current position and SEEK_END => to the end of
+ the file. */
+static long
+NvFileSize(
+ int leaveAt
+ )
+{
+ int irc; /* kgold, added return code checks */
+ long fileSize;
+ long filePos;
+ //
+ assert(NULL != s_NvFile);
+
+ filePos = ftell(s_NvFile); // libtpms changed begin
+ if (filePos < 0)
+ return -1; // libtpms changed end
+
+ int fseek_result = fseek(s_NvFile, 0, SEEK_END);
+ NOT_REFERENCED(fseek_result); // Fix compiler warning for NDEBUG
+ assert(fseek_result == 0);
+ fileSize = ftell(s_NvFile);
+ assert(fileSize >= 0);
+ switch(leaveAt)
+ {
+ case SEEK_SET:
+ filePos = 0;
+ /* fall through */
+ case SEEK_CUR:
+ irc = fseek(s_NvFile, filePos, SEEK_SET);
+ assert(irc == 0);
+ break;
+ case SEEK_END:
+ break;
+ default:
+ assert(FALSE);
+ break;
+ }
+ return fileSize;
+}
+#endif
+
+#if 0 /* libtpms added */
+/* C.6.2.4. _plat__NvErrors() */
+/* This function is used by the simulator to set the error flags in the NV subsystem to simulate an
+ error in the NV loading process */
+LIB_EXPORT void
+_plat__NvErrors(
+ int recoverable,
+ int unrecoverable
+ )
+{
+ s_NV_unrecoverable = unrecoverable;
+ s_NV_recoverable = recoverable;
+}
+#endif /* libtpms added */
+/* C.6.2.5. _plat__NVEnable() */
+/* Enable NV memory. */
+/* This version just pulls in data from a file. In a real TPM, with NV on chip, this function would
+ verify the integrity of the saved context. If the NV memory was not on chip but was in something
+ like RPMB, the NV state would be read in, decrypted and integrity checked. */
+/* The recovery from an integrity failure depends on where the error occurred. It it was in the
+ state that is discarded by TPM Reset, then the error is recoverable if the TPM is
+ reset. Otherwise, the TPM must go into failure mode. */
+/* Return Values Meaning */
+/* 0 if success */
+/* > 0 if receive recoverable error */
+/* <0 if unrecoverable error */
+LIB_EXPORT int
+_plat__NVEnable(
+ void *platParameter // IN: platform specific parameters
+ )
+{
+#ifdef TPM_LIBTPMS_CALLBACKS
+ int ret;
+#endif
+ //
+ // Start assuming everything is OK
+ s_NV_unrecoverable = FALSE;
+ s_NV_recoverable = FALSE;
+
+#ifdef TPM_LIBTPMS_CALLBACKS
+ ret = libtpms_plat__NVEnable();
+ if (ret != LIBTPMS_CALLBACK_FALLTHROUGH)
+ return ret;
+#endif /* TPM_LIBTPMS_CALLBACKS */
+ return _plat__NVEnable_NVChipFile(platParameter);
+}
+
+int
+_plat__NVEnable_NVChipFile(
+ void *platParameter // IN: platform specific parameters
+ )
+{
+ NOT_REFERENCED(platParameter); // to keep compiler quiet
+ //
+ // Start assuming everything is OK
+ s_NV_unrecoverable = FALSE;
+ s_NV_recoverable = FALSE;
+#if FILE_BACKED_NV
+ if(s_NvFile != NULL)
+ return 0;
+ // Initialize all the bytes in the ram copy of the NV
+ _plat__NvMemoryClear(0, NV_MEMORY_SIZE);
+
+ // If the file exists
+ if(NvFileOpen("r+b") >= 0)
+ {
+ long fileSize = NvFileSize(SEEK_SET); // get the file size and leave the
+ // file pointer at the start
+ //
+ // If the size is right, read the data
+ if(NV_MEMORY_SIZE == fileSize)
+ {
+ s_NeedsManufacture =
+ fread(s_NV, 1, NV_MEMORY_SIZE, s_NvFile) != NV_MEMORY_SIZE;
+ if (s_NeedsManufacture) { // libtpms changes start: set s_NV_unrecoverable on error
+ s_NV_unrecoverable = TRUE;
+ TPMLIB_LogTPM2Error("Could not read NVChip file: %s\n",
+ strerror(errno)); // libtpms changes end
+ }
+ }
+ else
+ {
+ NvFileCommit(); // for any other size, initialize it
+ s_NeedsManufacture = TRUE;
+ }
+ }
+ // If NVChip file does not exist, try to create it for read/write.
+ else if(NvFileOpen("w+b") >= 0)
+ {
+ NvFileCommit(); // Initialize the file
+ s_NeedsManufacture = TRUE;
+ }
+ assert(NULL != s_NvFile); // Just in case we are broken for some reason.
+#endif
+ // NV contents have been initialized and the error checks have been performed. For
+ // simulation purposes, use the signaling interface to indicate if an error is
+ // to be simulated and the type of the error.
+ if(s_NV_unrecoverable)
+ return -1;
+ return s_NV_recoverable;
+}
+
+/* C.6.2.6. _plat__NVDisable() */
+/* Disable NV memory */
+LIB_EXPORT void
+_plat__NVDisable(
+ int delete // IN: If TRUE, delete the NV contents.
+ )
+{
+#ifdef TPM_LIBTPMS_CALLBACKS
+ int ret = libtpms_plat__NVDisable();
+ if (ret != LIBTPMS_CALLBACK_FALLTHROUGH)
+ return;
+#endif /* TPM_LIBTPMS_CALLBACKS */
+
+#if FILE_BACKED_NV
+ if(NULL != s_NvFile)
+ {
+ fclose(s_NvFile); // Close NV file
+ // Alternative to deleting the file is to set its size to 0. This will not
+ // match the NV size so the TPM will need to be remanufactured.
+ if(delete)
+ {
+ // Open for writing at the start. Sets the size to zero.
+ if(NvFileOpen("w") >= 0)
+ {
+ fflush(s_NvFile);
+ fclose(s_NvFile);
+ }
+ }
+ }
+ s_NvFile = NULL; // Set file handle to NULL
+#endif
+ return;
+}
+
+/* C.6.2.7. _plat__IsNvAvailable() */
+/* Check if NV is available */
+/* Return Values Meaning */
+/* 0 NV is available */
+/* 1 NV is not available due to write failure */
+/* 2 NV is not available due to rate limit */
+LIB_EXPORT int
+_plat__IsNvAvailable(
+ void
+ )
+{
+ int retVal = 0;
+
+#ifdef TPM_LIBTPMS_CALLBACKS
+ if (libtpms_plat__IsNvAvailable() == 1)
+ return 0;
+#endif /* TPM_LIBTPMS_CALLBACKS */
+
+ // NV is not available if the TPM is in failure mode
+ if(!s_NvIsAvailable)
+ retVal = 1;
+#if FILE_BACKED_NV
+ else
+ retVal = (s_NvFile == NULL);
+#endif
+ return retVal;
+}
+
+/* C.6.2.8. _plat__NvMemoryRead() */
+/* Function: Read a chunk of NV memory */
+LIB_EXPORT void
+_plat__NvMemoryRead(
+ unsigned int startOffset, // IN: read start
+ unsigned int size, // IN: size of bytes to read
+ void *data // OUT: data buffer
+ )
+{
+ assert(startOffset + size <= NV_MEMORY_SIZE);
+ memcpy(data, &s_NV[startOffset], size); // Copy data from RAM
+ return;
+}
+/* C.6.2.9. _plat__NvIsDifferent() */
+/* This function checks to see if the NV is different from the test value. This is so that NV will
+ not be written if it has not changed. */
+/* Return Values Meaning */
+/* TRUE(1) the NV location is different from the test value */
+/* FALSE(0) the NV location is the same as the test value */
+LIB_EXPORT int
+_plat__NvIsDifferent(
+ unsigned int startOffset, // IN: read start
+ unsigned int size, // IN: size of bytes to read
+ void *data // IN: data buffer
+ )
+{
+ return (memcmp(&s_NV[startOffset], data, size) != 0);
+}
+/* C.6.2.10. _plat__NvMemoryWrite() */
+/* This function is used to update NV memory. The write is to a memory copy of NV. At the end of the
+ current command, any changes are written to the actual NV memory. */
+/* NOTE: A useful optimization would be for this code to compare the current contents of NV with the
+ local copy and note the blocks that have changed. Then only write those blocks when
+ _plat__NvCommit() is called. */
+
+LIB_EXPORT int
+_plat__NvMemoryWrite(
+ unsigned int startOffset, // IN: write start
+ unsigned int size, // IN: size of bytes to write
+ void *data // OUT: data buffer
+ )
+{
+ if(startOffset + size <= NV_MEMORY_SIZE)
+ {
+ memcpy(&s_NV[startOffset], data, size); // Copy the data to the NV image
+ return TRUE;
+ }
+ return FALSE;
+}
+/* C.6.2.11. _plat__NvMemoryClear() */
+/* Function is used to set a range of NV memory bytes to an implementation-dependent value. The
+ value represents the erase state of the memory. */
+LIB_EXPORT void
+_plat__NvMemoryClear(
+ unsigned int start, // IN: clear start
+ unsigned int size // IN: number of bytes to clear
+ )
+{
+ assert(start + size <= NV_MEMORY_SIZE);
+ // In this implementation, assume that the erase value for NV is all 1s
+ memset(&s_NV[start], 0xff, size);
+}
+/* C.6.2.12. _plat__NvMemoryMove() */
+/* Function: Move a chunk of NV memory from source to destination This function should ensure that
+ if there overlap, the original data is copied before it is written */
+LIB_EXPORT void
+_plat__NvMemoryMove(
+ unsigned int sourceOffset, // IN: source offset
+ unsigned int destOffset, // IN: destination offset
+ unsigned int size // IN: size of data being moved
+ )
+{
+ assert(sourceOffset + size <= NV_MEMORY_SIZE);
+ assert(destOffset + size <= NV_MEMORY_SIZE);
+ memmove(&s_NV[destOffset], &s_NV[sourceOffset], size); // Move data in RAM
+#if 1 /* libtpms added begin */
+ if (destOffset > sourceOffset)
+ memset(&s_NV[sourceOffset], 0, destOffset-sourceOffset);
+ else
+ memset(&s_NV[destOffset+size], 0, sourceOffset-destOffset);
+#endif /* libtpms added end */
+ return;
+}
+/* C.6.2.13. _plat__NvCommit() */
+/* This function writes the local copy of NV to NV for permanent store. It will write NV_MEMORY_SIZE
+ bytes to NV. If a file is use, the entire file is written. */
+/* Return Values Meaning */
+/* 0 NV write success */
+/* non-0 NV write fail */
+LIB_EXPORT int
+_plat__NvCommit(
+ void
+ )
+{
+#ifdef TPM_LIBTPMS_CALLBACKS
+ int ret = libtpms_plat__NvCommit();
+ if (ret != LIBTPMS_CALLBACK_FALLTHROUGH)
+ return ret;
+#endif /* TPM_LIBTPMS_CALLBACKS */
+
+#if FILE_BACKED_NV
+ return (NvFileCommit() ? 0 : 1);
+#else
+ return 0;
+#endif
+}
+
+/* C.6.2.14. _plat__SetNvAvail() */
+/* Set the current NV state to available. This function is for testing purpose only. It is not
+ part of the platform NV logic */
+LIB_EXPORT void
+_plat__SetNvAvail(
+ void
+ )
+{
+ s_NvIsAvailable = TRUE;
+ return;
+}
+#if 0 /* libtpms added */
+/* C.6.2.15. _plat__ClearNvAvail() */
+/* Set the current NV state to unavailable. This function is for testing purpose only. It is not
+ part of the platform NV logic */
+LIB_EXPORT void
+_plat__ClearNvAvail(
+ void
+ )
+{
+ s_NvIsAvailable = FALSE;
+ return;
+}
+
+/* C.6.2.15. _plat__NVNeedsManufacture() */
+/* This function is used by the simulator to determine when the TPM's NV state needs to be manufactured. */
+
+LIB_EXPORT int
+_plat__NVNeedsManufacture(
+ void
+ )
+{
+#if FILE_BACKED_NV
+ return s_NeedsManufacture;
+#else
+ return FALSE;
+#endif
+}
+#endif /* libtpms added */
diff --git a/src/tpm2/NVReserved.c b/src/tpm2/NVReserved.c
new file mode 100644
index 0000000..fa1053c
--- /dev/null
+++ b/src/tpm2/NVReserved.c
@@ -0,0 +1,230 @@
+/********************************************************************************/
+/* */
+/* NV TPM persistent and state save data */
+/* Written by Ken Goldman */
+/* IBM Thomas J. Watson Research Center */
+/* $Id: NVReserved.c 1476 2019-06-10 19:32:03Z kgoldman $ */
+/* */
+/* Licenses and Notices */
+/* */
+/* 1. Copyright Licenses: */
+/* */
+/* - Trusted Computing Group (TCG) grants to the user of the source code in */
+/* this specification (the "Source Code") a worldwide, irrevocable, */
+/* nonexclusive, royalty free, copyright license to reproduce, create */
+/* derivative works, distribute, display and perform the Source Code and */
+/* derivative works thereof, and to grant others the rights granted herein. */
+/* */
+/* - The TCG grants to the user of the other parts of the specification */
+/* (other than the Source Code) the rights to reproduce, distribute, */
+/* display, and perform the specification solely for the purpose of */
+/* developing products based on such documents. */
+/* */
+/* 2. Source Code Distribution Conditions: */
+/* */
+/* - Redistributions of Source Code must retain the above copyright licenses, */
+/* this list of conditions and the following disclaimers. */
+/* */
+/* - Redistributions in binary form must reproduce the above copyright */
+/* licenses, this list of conditions and the following disclaimers in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* 3. Disclaimers: */
+/* */
+/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
+/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
+/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
+/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
+/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
+/* information on specification licensing rights available through TCG */
+/* membership agreements. */
+/* */
+/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
+/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
+/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
+/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
+/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
+/* */
+/* - Without limitation, TCG and its members and licensors disclaim all */
+/* liability, including liability for infringement of any proprietary */
+/* rights, relating to use of information in this specification and to the */
+/* implementation of this specification, and TCG disclaims all liability for */
+/* cost of procurement of substitute goods or services, lost profits, loss */
+/* of use, loss of data or any incidental, consequential, direct, indirect, */
+/* or special damages, whether under contract, tort, warranty or otherwise, */
+/* arising in any way out of use or reliance upon this specification or any */
+/* information herein. */
+/* */
+/* (c) Copyright IBM Corp. and others, 2016 - 2019 */
+/* */
+/********************************************************************************/
+
+// 8.5 NVReserved.c
+/* 8.5.2 Includes, Defines and Data Definitions */
+#define NV_C
+#include "Tpm.h"
+/* 8.5.3 Functions */
+/* 8.5.3.1 NvInitStatic() */
+/* This function initializes the static variables used in the NV subsystem. */
+static void
+NvInitStatic(
+ void
+ )
+{
+ // In some implementations, the end of NV is variable and is set at boot time.
+ // This value will be the same for each boot, but is not necessarily known
+ // at compile time.
+ s_evictNvEnd = (NV_REF)NV_MEMORY_SIZE;
+ return;
+}
+/* 8.5.3.2 NvCheckState() */
+/* Function to check the NV state by accessing the platform-specific function to get the NV state.
+ The result state is registered in s_NvIsAvailable that will be reported by NvIsAvailable(). */
+/* This function is called at the beginning of ExecuteCommand() before any potential check of
+ g_NvStatus. */
+void
+NvCheckState(
+ void
+ )
+{
+ int func_return;
+ //
+ func_return = _plat__IsNvAvailable();
+ if(func_return == 0)
+ g_NvStatus = TPM_RC_SUCCESS;
+ else if(func_return == 1)
+ g_NvStatus = TPM_RC_NV_UNAVAILABLE;
+ else
+ g_NvStatus = TPM_RC_NV_RATE;
+ return;
+}
+/* 8.5.3.3 NvCommit */
+/* This is a wrapper for the platform function to commit pending NV writes. */
+BOOL
+NvCommit(
+ void
+ )
+{
+ return (_plat__NvCommit() == 0);
+}
+/* 8.5.3.4 NvPowerOn() */
+/* This function is called at _TPM_Init() to initialize the NV environment. */
+/* Return Values Meaning */
+/* TRUE all NV was initialized */
+/* FALSE the NV containing saved state had an error and TPM2_Startup(CLEAR) is required */
+BOOL
+NvPowerOn(
+ void
+ )
+{
+ int nvError = 0;
+ // If power was lost, need to re-establish the RAM data that is loaded from
+ // NV and initialize the static variables
+ if(g_powerWasLost)
+ {
+ if((nvError = _plat__NVEnable(0)) < 0)
+ LOG_FAILURE(FATAL_ERROR_NV_UNRECOVERABLE); /* libtpms changed */
+ NvInitStatic();
+ }
+ return nvError == 0;
+}
+/* 8.5.3.5 NvManufacture() */
+/* This function initializes the NV system at pre-install time. */
+/* This function should only be called in a manufacturing environment or in a simulation. */
+/* The layout of NV memory space is an implementation choice. */
+void
+NvManufacture(
+ void
+ )
+{
+#if SIMULATION
+ // Simulate the NV memory being in the erased state.
+ _plat__NvMemoryClear(0, NV_MEMORY_SIZE);
+#endif
+ // Initialize static variables
+ NvInitStatic();
+ // Clear the RAM used for Orderly Index data
+ MemorySet(s_indexOrderlyRam, 0, RAM_INDEX_SPACE);
+ // Write that Orderly Index data to NV
+ NvUpdateIndexOrderlyData();
+ // Initialize the next offset of the first entry in evict/index list to 0 (the
+ // end of list marker) and the initial s_maxCounterValue;
+ NvSetMaxCount(0);
+ // Put the end of list marker at the end of memory. This contains the MaxCount
+ // value as well as the end marker.
+ NvWriteNvListEnd(NV_USER_DYNAMIC);
+ return;
+}
+/* 8.5.3.6 NvRead() */
+/* This function is used to move reserved data from NV memory to RAM. */
+void
+NvRead(
+ void *outBuffer, // OUT: buffer to receive data
+ UINT32 nvOffset, // IN: offset in NV of value
+ UINT32 size // IN: size of the value to read
+ )
+{
+ // Input type should be valid
+ pAssert(nvOffset + size < NV_MEMORY_SIZE);
+ _plat__NvMemoryRead(nvOffset, size, outBuffer);
+ return;
+}
+/* 8.5.3.7 NvWrite() */
+/* This function is used to post reserved data for writing to NV memory. Before the TPM completes
+ the operation, the value will be written. */
+BOOL
+NvWrite(
+ UINT32 nvOffset, // IN: location in NV to receive data
+ UINT32 size, // IN: size of the data to move
+ void *inBuffer // IN: location containing data to write
+ )
+{
+ // Input type should be valid
+ if(nvOffset + size <= NV_MEMORY_SIZE)
+ {
+ // Set the flag that a NV write happened
+ SET_NV_UPDATE(UT_NV);
+ return _plat__NvMemoryWrite(nvOffset, size, inBuffer);
+ }
+ return FALSE;
+}
+
+#if 0 // libtpms added being (for Coverity)
+/* 8.5.3.8 NvUpdatePersistent() */
+/* This function is used to update a value in the PERSISTENT_DATA structure and commits the value to
+ NV. */
+void
+NvUpdatePersistent(
+ UINT32 offset, // IN: location in PERMANENT_DATA to be updated
+ UINT32 size, // IN: size of the value
+ void *buffer // IN: the new data
+ )
+{
+ pAssert(offset + size <= sizeof(gp));
+ MemoryCopy(&gp + offset, buffer, size);
+ NvWrite(offset, size, buffer);
+}
+/* 8.5.3.9 NvClearPersistent() */
+/* This function is used to clear a persistent data entry and commit it to NV */
+void
+NvClearPersistent(
+ UINT32 offset, // IN: the offset in the PERMANENT_DATA
+ // structure to be cleared (zeroed)
+ UINT32 size // IN: number of bytes to clear
+ )
+{
+ pAssert(offset + size <= sizeof(gp));
+ MemorySet((&gp) + offset, 0, size);
+ NvWrite(offset, size, (&gp) + offset);
+}
+#endif // libtpms added end
+/* 8.5.3.10 NvReadPersistent() */
+/* This function reads persistent data to the RAM copy of the gp structure. */
+void
+NvReadPersistent(
+ void
+ )
+{
+ NvRead(&gp, NV_PERSISTENT_DATA, sizeof(gp));
+ return;
+}
diff --git a/src/tpm2/NVReserved_fp.h b/src/tpm2/NVReserved_fp.h
new file mode 100644
index 0000000..16bfb20
--- /dev/null
+++ b/src/tpm2/NVReserved_fp.h
@@ -0,0 +1,113 @@
+/********************************************************************************/
+/* */
+/* */
+/* Written by Ken Goldman */
+/* IBM Thomas J. Watson Research Center */
+/* $Id: NVReserved_fp.h 1476 2019-06-10 19:32:03Z kgoldman $ */
+/* */
+/* Licenses and Notices */
+/* */
+/* 1. Copyright Licenses: */
+/* */
+/* - Trusted Computing Group (TCG) grants to the user of the source code in */
+/* this specification (the "Source Code") a worldwide, irrevocable, */
+/* nonexclusive, royalty free, copyright license to reproduce, create */
+/* derivative works, distribute, display and perform the Source Code and */
+/* derivative works thereof, and to grant others the rights granted herein. */
+/* */
+/* - The TCG grants to the user of the other parts of the specification */
+/* (other than the Source Code) the rights to reproduce, distribute, */
+/* display, and perform the specification solely for the purpose of */
+/* developing products based on such documents. */
+/* */
+/* 2. Source Code Distribution Conditions: */
+/* */
+/* - Redistributions of Source Code must retain the above copyright licenses, */
+/* this list of conditions and the following disclaimers. */
+/* */
+/* - Redistributions in binary form must reproduce the above copyright */
+/* licenses, this list of conditions and the following disclaimers in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* 3. Disclaimers: */
+/* */
+/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
+/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
+/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
+/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
+/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
+/* information on specification licensing rights available through TCG */
+/* membership agreements. */
+/* */
+/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
+/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
+/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
+/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
+/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
+/* */
+/* - Without limitation, TCG and its members and licensors disclaim all */
+/* liability, including liability for infringement of any proprietary */
+/* rights, relating to use of information in this specification and to the */
+/* implementation of this specification, and TCG disclaims all liability for */
+/* cost of procurement of substitute goods or services, lost profits, loss */
+/* of use, loss of data or any incidental, consequential, direct, indirect, */
+/* or special damages, whether under contract, tort, warranty or otherwise, */
+/* arising in any way out of use or reliance upon this specification or any */
+/* information herein. */
+/* */
+/* (c) Copyright IBM Corp. and others, 2016 - 2019 */
+/* */
+/********************************************************************************/
+
+#ifndef NVRESERVED_FP_H
+#define NVRESERVED_FP_H
+
+#include "NVMarshal.h" /* libtpms added */
+
+void
+NvCheckState(
+ void
+ );
+BOOL
+NvCommit(
+ void
+ );
+BOOL
+NvPowerOn(
+ void
+ );
+void
+NvManufacture(
+ void
+ );
+void
+NvRead(
+ void *outBuffer, // OUT: buffer to receive data
+ UINT32 nvOffset, // IN: offset in NV of value
+ UINT32 size // IN: size of the value to read
+ );
+BOOL
+NvWrite(
+ UINT32 nvOffset, // IN: location in NV to receive data
+ UINT32 size, // IN: size of the data to move
+ void *inBuffer // IN: location containing data to write
+ );
+void
+NvUpdatePersistent(
+ UINT32 offset, // IN: location in PERMANENT_DATA to be updated
+ UINT32 size, // IN: size of the value
+ void *buffer // IN: the new data
+ );
+void
+NvClearPersistent(
+ UINT32 offset, // IN: the offset in the PERMANENT_DATA
+ // structure to be cleared (zeroed)
+ UINT32 size // IN: number of bytes to clear
+ );
+void
+NvReadPersistent(
+ void
+ );
+
+
+#endif
diff --git a/src/tpm2/NV_Certify_fp.h b/src/tpm2/NV_Certify_fp.h
new file mode 100644
index 0000000..a58af30
--- /dev/null
+++ b/src/tpm2/NV_Certify_fp.h
@@ -0,0 +1,98 @@
+/********************************************************************************/
+/* */
+/* */
+/* Written by Ken Goldman */
+/* IBM Thomas J. Watson Research Center */
+/* $Id: NV_Certify_fp.h 809 2016-11-16 18:31:54Z kgoldman $ */
+/* */
+/* Licenses and Notices */
+/* */
+/* 1. Copyright Licenses: */
+/* */
+/* - Trusted Computing Group (TCG) grants to the user of the source code in */
+/* this specification (the "Source Code") a worldwide, irrevocable, */
+/* nonexclusive, royalty free, copyright license to reproduce, create */
+/* derivative works, distribute, display and perform the Source Code and */
+/* derivative works thereof, and to grant others the rights granted herein. */
+/* */
+/* - The TCG grants to the user of the other parts of the specification */
+/* (other than the Source Code) the rights to reproduce, distribute, */
+/* display, and perform the specification solely for the purpose of */
+/* developing products based on such documents. */
+/* */
+/* 2. Source Code Distribution Conditions: */
+/* */
+/* - Redistributions of Source Code must retain the above copyright licenses, */
+/* this list of conditions and the following disclaimers. */
+/* */
+/* - Redistributions in binary form must reproduce the above copyright */
+/* licenses, this list of conditions and the following disclaimers in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* 3. Disclaimers: */
+/* */
+/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
+/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
+/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
+/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
+/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
+/* information on specification licensing rights available through TCG */
+/* membership agreements. */
+/* */
+/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
+/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
+/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
+/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
+/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
+/* */
+/* - Without limitation, TCG and its members and licensors disclaim all */
+/* liability, including liability for infringement of any proprietary */
+/* rights, relating to use of information in this specification and to the */
+/* implementation of this specification, and TCG disclaims all liability for */
+/* cost of procurement of substitute goods or services, lost profits, loss */
+/* of use, loss of data or any incidental, consequential, direct, indirect, */
+/* or special damages, whether under contract, tort, warranty or otherwise, */
+/* arising in any way out of use or reliance upon this specification or any */
+/* information herein. */
+/* */
+/* (c) Copyright IBM Corp. and others, 2012-2015 */
+/* */
+/********************************************************************************/
+
+/* rev 119 */
+
+#ifndef NV_CERTIFY_FP_H
+#define NV_CERTIFY_FP_H
+
+typedef struct {
+ TPMI_DH_OBJECT signHandle;
+ TPMI_RH_NV_AUTH authHandle;
+ TPMI_RH_NV_INDEX nvIndex;
+ TPM2B_DATA qualifyingData;
+ TPMT_SIG_SCHEME inScheme;
+ UINT16 size;
+ UINT16 offset;
+} NV_Certify_In;
+
+#define RC_NV_Certify_signHandle (TPM_RC_H + TPM_RC_1)
+#define RC_NV_Certify_authHandle (TPM_RC_H + TPM_RC_2)
+#define RC_NV_Certify_nvIndex (TPM_RC_H + TPM_RC_3)
+#define RC_NV_Certify_qualifyingData (TPM_RC_P + TPM_RC_1)
+#define RC_NV_Certify_inScheme (TPM_RC_P + TPM_RC_2)
+#define RC_NV_Certify_size (TPM_RC_P + TPM_RC_3)
+#define RC_NV_Certify_offset (TPM_RC_P + TPM_RC_4)
+
+
+typedef struct {
+ TPM2B_ATTEST certifyInfo;
+ TPMT_SIGNATURE signature;
+} NV_Certify_Out;
+
+TPM_RC
+TPM2_NV_Certify(
+ NV_Certify_In *in, // IN: input parameter list
+ NV_Certify_Out *out // OUT: output parameter list
+ );
+
+
+#endif
diff --git a/src/tpm2/NV_ChangeAuth_fp.h b/src/tpm2/NV_ChangeAuth_fp.h
new file mode 100644
index 0000000..fb26a73
--- /dev/null
+++ b/src/tpm2/NV_ChangeAuth_fp.h
@@ -0,0 +1,81 @@
+/********************************************************************************/
+/* */
+/* */
+/* Written by Ken Goldman */
+/* IBM Thomas J. Watson Research Center */
+/* $Id: NV_ChangeAuth_fp.h 809 2016-11-16 18:31:54Z kgoldman $ */
+/* */
+/* Licenses and Notices */
+/* */
+/* 1. Copyright Licenses: */
+/* */
+/* - Trusted Computing Group (TCG) grants to the user of the source code in */
+/* this specification (the "Source Code") a worldwide, irrevocable, */
+/* nonexclusive, royalty free, copyright license to reproduce, create */
+/* derivative works, distribute, display and perform the Source Code and */
+/* derivative works thereof, and to grant others the rights granted herein. */
+/* */
+/* - The TCG grants to the user of the other parts of the specification */
+/* (other than the Source Code) the rights to reproduce, distribute, */
+/* display, and perform the specification solely for the purpose of */
+/* developing products based on such documents. */
+/* */
+/* 2. Source Code Distribution Conditions: */
+/* */
+/* - Redistributions of Source Code must retain the above copyright licenses, */
+/* this list of conditions and the following disclaimers. */
+/* */
+/* - Redistributions in binary form must reproduce the above copyright */
+/* licenses, this list of conditions and the following disclaimers in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* 3. Disclaimers: */
+/* */
+/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
+/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
+/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
+/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
+/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
+/* information on specification licensing rights available through TCG */
+/* membership agreements. */
+/* */
+/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
+/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
+/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
+/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
+/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
+/* */
+/* - Without limitation, TCG and its members and licensors disclaim all */
+/* liability, including liability for infringement of any proprietary */
+/* rights, relating to use of information in this specification and to the */
+/* implementation of this specification, and TCG disclaims all liability for */
+/* cost of procurement of substitute goods or services, lost profits, loss */
+/* of use, loss of data or any incidental, consequential, direct, indirect, */
+/* or special damages, whether under contract, tort, warranty or otherwise, */
+/* arising in any way out of use or reliance upon this specification or any */
+/* information herein. */
+/* */
+/* (c) Copyright IBM Corp. and others, 2012-2015 */
+/* */
+/********************************************************************************/
+
+/* rev 119 */
+
+#ifndef NV_CHANGEAUTH_FP_H
+#define NV_CHANGEAUTH_FP_H
+
+typedef struct {
+ TPMI_RH_NV_INDEX nvIndex;
+ TPM2B_AUTH newAuth;
+} NV_ChangeAuth_In;
+
+#define RC_NV_ChangeAuth_nvIndex (TPM_RC_H + TPM_RC_1)
+#define RC_NV_ChangeAuth_newAuth (TPM_RC_P + TPM_RC_1)
+
+TPM_RC
+TPM2_NV_ChangeAuth(
+ NV_ChangeAuth_In *in // IN: input parameter list
+ );
+
+
+#endif
diff --git a/src/tpm2/NV_DefineSpace_fp.h b/src/tpm2/NV_DefineSpace_fp.h
new file mode 100644
index 0000000..03d81c3
--- /dev/null
+++ b/src/tpm2/NV_DefineSpace_fp.h
@@ -0,0 +1,83 @@
+/********************************************************************************/
+/* */
+/* */
+/* Written by Ken Goldman */
+/* IBM Thomas J. Watson Research Center */
+/* $Id: NV_DefineSpace_fp.h 809 2016-11-16 18:31:54Z kgoldman $ */
+/* */
+/* Licenses and Notices */
+/* */
+/* 1. Copyright Licenses: */
+/* */
+/* - Trusted Computing Group (TCG) grants to the user of the source code in */
+/* this specification (the "Source Code") a worldwide, irrevocable, */
+/* nonexclusive, royalty free, copyright license to reproduce, create */
+/* derivative works, distribute, display and perform the Source Code and */
+/* derivative works thereof, and to grant others the rights granted herein. */
+/* */
+/* - The TCG grants to the user of the other parts of the specification */
+/* (other than the Source Code) the rights to reproduce, distribute, */
+/* display, and perform the specification solely for the purpose of */
+/* developing products based on such documents. */
+/* */
+/* 2. Source Code Distribution Conditions: */
+/* */
+/* - Redistributions of Source Code must retain the above copyright licenses, */
+/* this list of conditions and the following disclaimers. */
+/* */
+/* - Redistributions in binary form must reproduce the above copyright */
+/* licenses, this list of conditions and the following disclaimers in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* 3. Disclaimers: */
+/* */
+/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
+/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
+/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
+/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
+/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
+/* information on specification licensing rights available through TCG */
+/* membership agreements. */
+/* */
+/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
+/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
+/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
+/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
+/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
+/* */
+/* - Without limitation, TCG and its members and licensors disclaim all */
+/* liability, including liability for infringement of any proprietary */
+/* rights, relating to use of information in this specification and to the */
+/* implementation of this specification, and TCG disclaims all liability for */
+/* cost of procurement of substitute goods or services, lost profits, loss */
+/* of use, loss of data or any incidental, consequential, direct, indirect, */
+/* or special damages, whether under contract, tort, warranty or otherwise, */
+/* arising in any way out of use or reliance upon this specification or any */
+/* information herein. */
+/* */
+/* (c) Copyright IBM Corp. and others, 2012-2015 */
+/* */
+/********************************************************************************/
+
+/* rev 119 */
+
+#ifndef NV_DEFINESPACE_FP_H
+#define NV_DEFINESPACE_FP_H
+
+typedef struct {
+ TPMI_RH_PROVISION authHandle;
+ TPM2B_AUTH auth;
+ TPM2B_NV_PUBLIC publicInfo;
+} NV_DefineSpace_In;
+
+#define RC_NV_DefineSpace_authHandle (TPM_RC_H + TPM_RC_1)
+#define RC_NV_DefineSpace_auth (TPM_RC_P + TPM_RC_1)
+#define RC_NV_DefineSpace_publicInfo (TPM_RC_P + TPM_RC_2)
+
+TPM_RC
+TPM2_NV_DefineSpace(
+ NV_DefineSpace_In *in // IN: input parameter list
+ );
+
+
+#endif
diff --git a/src/tpm2/NV_Extend_fp.h b/src/tpm2/NV_Extend_fp.h
new file mode 100644
index 0000000..58d4c2f
--- /dev/null
+++ b/src/tpm2/NV_Extend_fp.h
@@ -0,0 +1,83 @@
+/********************************************************************************/
+/* */
+/* */
+/* Written by Ken Goldman */
+/* IBM Thomas J. Watson Research Center */
+/* $Id: NV_Extend_fp.h 809 2016-11-16 18:31:54Z kgoldman $ */
+/* */
+/* Licenses and Notices */
+/* */
+/* 1. Copyright Licenses: */
+/* */
+/* - Trusted Computing Group (TCG) grants to the user of the source code in */
+/* this specification (the "Source Code") a worldwide, irrevocable, */
+/* nonexclusive, royalty free, copyright license to reproduce, create */
+/* derivative works, distribute, display and perform the Source Code and */
+/* derivative works thereof, and to grant others the rights granted herein. */
+/* */
+/* - The TCG grants to the user of the other parts of the specification */
+/* (other than the Source Code) the rights to reproduce, distribute, */
+/* display, and perform the specification solely for the purpose of */
+/* developing products based on such documents. */
+/* */
+/* 2. Source Code Distribution Conditions: */
+/* */
+/* - Redistributions of Source Code must retain the above copyright licenses, */
+/* this list of conditions and the following disclaimers. */
+/* */
+/* - Redistributions in binary form must reproduce the above copyright */
+/* licenses, this list of conditions and the following disclaimers in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* 3. Disclaimers: */
+/* */
+/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
+/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
+/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
+/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
+/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
+/* information on specification licensing rights available through TCG */
+/* membership agreements. */
+/* */
+/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
+/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
+/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
+/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
+/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
+/* */
+/* - Without limitation, TCG and its members and licensors disclaim all */
+/* liability, including liability for infringement of any proprietary */
+/* rights, relating to use of information in this specification and to the */
+/* implementation of this specification, and TCG disclaims all liability for */
+/* cost of procurement of substitute goods or services, lost profits, loss */
+/* of use, loss of data or any incidental, consequential, direct, indirect, */
+/* or special damages, whether under contract, tort, warranty or otherwise, */
+/* arising in any way out of use or reliance upon this specification or any */
+/* information herein. */
+/* */
+/* (c) Copyright IBM Corp. and others, 2012-2015 */
+/* */
+/********************************************************************************/
+
+/* rev 119 */
+
+#ifndef NV_EXTEND_FP_H
+#define NV_EXTEND_FP_H
+
+typedef struct {
+ TPMI_RH_NV_AUTH authHandle;
+ TPMI_RH_NV_INDEX nvIndex;
+ TPM2B_MAX_NV_BUFFER data;
+} NV_Extend_In;
+
+#define RC_NV_Extend_authHandle (TPM_RC_H + TPM_RC_1)
+#define RC_NV_Extend_nvIndex (TPM_RC_H + TPM_RC_2)
+#define RC_NV_Extend_data (TPM_RC_P + TPM_RC_1)
+
+TPM_RC
+TPM2_NV_Extend(
+ NV_Extend_In *in // IN: input parameter list
+ );
+
+
+#endif
diff --git a/src/tpm2/NV_GlobalWriteLock_fp.h b/src/tpm2/NV_GlobalWriteLock_fp.h
new file mode 100644
index 0000000..4f6b26b
--- /dev/null
+++ b/src/tpm2/NV_GlobalWriteLock_fp.h
@@ -0,0 +1,79 @@
+/********************************************************************************/
+/* */
+/* */
+/* Written by Ken Goldman */
+/* IBM Thomas J. Watson Research Center */
+/* $Id: NV_GlobalWriteLock_fp.h 809 2016-11-16 18:31:54Z kgoldman $ */
+/* */
+/* Licenses and Notices */
+/* */
+/* 1. Copyright Licenses: */
+/* */
+/* - Trusted Computing Group (TCG) grants to the user of the source code in */
+/* this specification (the "Source Code") a worldwide, irrevocable, */
+/* nonexclusive, royalty free, copyright license to reproduce, create */
+/* derivative works, distribute, display and perform the Source Code and */
+/* derivative works thereof, and to grant others the rights granted herein. */
+/* */
+/* - The TCG grants to the user of the other parts of the specification */
+/* (other than the Source Code) the rights to reproduce, distribute, */
+/* display, and perform the specification solely for the purpose of */
+/* developing products based on such documents. */
+/* */
+/* 2. Source Code Distribution Conditions: */
+/* */
+/* - Redistributions of Source Code must retain the above copyright licenses, */
+/* this list of conditions and the following disclaimers. */
+/* */
+/* - Redistributions in binary form must reproduce the above copyright */
+/* licenses, this list of conditions and the following disclaimers in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* 3. Disclaimers: */
+/* */
+/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
+/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
+/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
+/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
+/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
+/* information on specification licensing rights available through TCG */
+/* membership agreements. */
+/* */
+/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
+/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
+/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
+/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
+/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
+/* */
+/* - Without limitation, TCG and its members and licensors disclaim all */
+/* liability, including liability for infringement of any proprietary */
+/* rights, relating to use of information in this specification and to the */
+/* implementation of this specification, and TCG disclaims all liability for */
+/* cost of procurement of substitute goods or services, lost profits, loss */
+/* of use, loss of data or any incidental, consequential, direct, indirect, */
+/* or special damages, whether under contract, tort, warranty or otherwise, */
+/* arising in any way out of use or reliance upon this specification or any */
+/* information herein. */
+/* */
+/* (c) Copyright IBM Corp. and others, 2012-2015 */
+/* */
+/********************************************************************************/
+
+/* rev 119 */
+
+#ifndef NV_GLOBALWRITELOCK_FP_H
+#define NV_GLOBALWRITELOCK_FP_H
+
+typedef struct {
+ TPMI_RH_PROVISION authHandle;
+} NV_GlobalWriteLock_In;
+
+#define RC_NV_GlobalWriteLock_authHandle (TPM_RC_H + TPM_RC_1)
+
+TPM_RC
+TPM2_NV_GlobalWriteLock(
+ NV_GlobalWriteLock_In *in // IN: input parameter list
+ );
+
+
+#endif
diff --git a/src/tpm2/NV_Increment_fp.h b/src/tpm2/NV_Increment_fp.h
new file mode 100644
index 0000000..260e0cb
--- /dev/null
+++ b/src/tpm2/NV_Increment_fp.h
@@ -0,0 +1,81 @@
+/********************************************************************************/
+/* */
+/* */
+/* Written by Ken Goldman */
+/* IBM Thomas J. Watson Research Center */
+/* $Id: NV_Increment_fp.h 1521 2019-11-15 21:00:47Z kgoldman $ */
+/* */
+/* Licenses and Notices */
+/* */
+/* 1. Copyright Licenses: */
+/* */
+/* - Trusted Computing Group (TCG) grants to the user of the source code in */
+/* this specification (the "Source Code") a worldwide, irrevocable, */
+/* nonexclusive, royalty free, copyright license to reproduce, create */
+/* derivative works, distribute, display and perform the Source Code and */
+/* derivative works thereof, and to grant others the rights granted herein. */
+/* */
+/* - The TCG grants to the user of the other parts of the specification */
+/* (other than the Source Code) the rights to reproduce, distribute, */
+/* display, and perform the specification solely for the purpose of */
+/* developing products based on such documents. */
+/* */
+/* 2. Source Code Distribution Conditions: */
+/* */
+/* - Redistributions of Source Code must retain the above copyright licenses, */
+/* this list of conditions and the following disclaimers. */
+/* */
+/* - Redistributions in binary form must reproduce the above copyright */
+/* licenses, this list of conditions and the following disclaimers in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* 3. Disclaimers: */
+/* */
+/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
+/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
+/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
+/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
+/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
+/* information on specification licensing rights available through TCG */
+/* membership agreements. */
+/* */
+/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
+/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
+/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
+/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
+/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
+/* */
+/* - Without limitation, TCG and its members and licensors disclaim all */
+/* liability, including liability for infringement of any proprietary */
+/* rights, relating to use of information in this specification and to the */
+/* implementation of this specification, and TCG disclaims all liability for */
+/* cost of procurement of substitute goods or services, lost profits, loss */
+/* of use, loss of data or any incidental, consequential, direct, indirect, */
+/* or special damages, whether under contract, tort, warranty or otherwise, */
+/* arising in any way out of use or reliance upon this specification or any */
+/* information herein. */
+/* */
+/* (c) Copyright IBM Corp. and others, 2012-2015 */
+/* */
+/********************************************************************************/
+
+/* rev 119 */
+
+#ifndef NV_INCREMENT_FP_H
+#define NV_INCREMENT_FP_H
+
+typedef struct {
+ TPMI_RH_NV_AUTH authHandle;
+ TPMI_RH_NV_INDEX nvIndex;
+} NV_Increment_In;;
+
+#define RC_NV_Increment_authHandle (TPM_RC_H + TPM_RC_1)
+#define RC_NV_Increment_nvIndex (TPM_RC_H + TPM_RC_2)
+
+TPM_RC
+TPM2_NV_Increment(
+ NV_Increment_In *in // IN: input parameter list
+ );
+
+
+#endif
diff --git a/src/tpm2/NV_ReadLock_fp.h b/src/tpm2/NV_ReadLock_fp.h
new file mode 100644
index 0000000..f50479b
--- /dev/null
+++ b/src/tpm2/NV_ReadLock_fp.h
@@ -0,0 +1,81 @@
+/********************************************************************************/
+/* */
+/* */
+/* Written by Ken Goldman */
+/* IBM Thomas J. Watson Research Center */
+/* $Id: NV_ReadLock_fp.h 809 2016-11-16 18:31:54Z kgoldman $ */
+/* */
+/* Licenses and Notices */
+/* */
+/* 1. Copyright Licenses: */
+/* */
+/* - Trusted Computing Group (TCG) grants to the user of the source code in */
+/* this specification (the "Source Code") a worldwide, irrevocable, */
+/* nonexclusive, royalty free, copyright license to reproduce, create */
+/* derivative works, distribute, display and perform the Source Code and */
+/* derivative works thereof, and to grant others the rights granted herein. */
+/* */
+/* - The TCG grants to the user of the other parts of the specification */
+/* (other than the Source Code) the rights to reproduce, distribute, */
+/* display, and perform the specification solely for the purpose of */
+/* developing products based on such documents. */
+/* */
+/* 2. Source Code Distribution Conditions: */
+/* */
+/* - Redistributions of Source Code must retain the above copyright licenses, */
+/* this list of conditions and the following disclaimers. */
+/* */
+/* - Redistributions in binary form must reproduce the above copyright */
+/* licenses, this list of conditions and the following disclaimers in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* 3. Disclaimers: */
+/* */
+/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
+/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
+/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
+/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
+/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
+/* information on specification licensing rights available through TCG */
+/* membership agreements. */
+/* */
+/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
+/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
+/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
+/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
+/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
+/* */
+/* - Without limitation, TCG and its members and licensors disclaim all */
+/* liability, including liability for infringement of any proprietary */
+/* rights, relating to use of information in this specification and to the */
+/* implementation of this specification, and TCG disclaims all liability for */
+/* cost of procurement of substitute goods or services, lost profits, loss */
+/* of use, loss of data or any incidental, consequential, direct, indirect, */
+/* or special damages, whether under contract, tort, warranty or otherwise, */
+/* arising in any way out of use or reliance upon this specification or any */
+/* information herein. */
+/* */
+/* (c) Copyright IBM Corp. and others, 2012-2015 */
+/* */
+/********************************************************************************/
+
+/* rev 119 */
+
+#ifndef NV_READLOCK_FP_H
+#define NV_READLOCK_FP_H
+
+typedef struct {
+ TPMI_RH_NV_AUTH authHandle;
+ TPMI_RH_NV_INDEX nvIndex;
+} NV_ReadLock_In;
+
+#define RC_NV_ReadLock_authHandle (TPM_RC_H + TPM_RC_1)
+#define RC_NV_ReadLock_nvIndex (TPM_RC_H + TPM_RC_2)
+
+TPM_RC
+TPM2_NV_ReadLock(
+ NV_ReadLock_In *in // IN: input parameter list
+ );
+
+
+#endif
diff --git a/src/tpm2/NV_ReadPublic_fp.h b/src/tpm2/NV_ReadPublic_fp.h
new file mode 100644
index 0000000..bcad306
--- /dev/null
+++ b/src/tpm2/NV_ReadPublic_fp.h
@@ -0,0 +1,85 @@
+/********************************************************************************/
+/* */
+/* */
+/* Written by Ken Goldman */
+/* IBM Thomas J. Watson Research Center */
+/* $Id: NV_ReadPublic_fp.h 809 2016-11-16 18:31:54Z kgoldman $ */
+/* */
+/* Licenses and Notices */
+/* */
+/* 1. Copyright Licenses: */
+/* */
+/* - Trusted Computing Group (TCG) grants to the user of the source code in */
+/* this specification (the "Source Code") a worldwide, irrevocable, */
+/* nonexclusive, royalty free, copyright license to reproduce, create */
+/* derivative works, distribute, display and perform the Source Code and */
+/* derivative works thereof, and to grant others the rights granted herein. */
+/* */
+/* - The TCG grants to the user of the other parts of the specification */
+/* (other than the Source Code) the rights to reproduce, distribute, */
+/* display, and perform the specification solely for the purpose of */
+/* developing products based on such documents. */
+/* */
+/* 2. Source Code Distribution Conditions: */
+/* */
+/* - Redistributions of Source Code must retain the above copyright licenses, */
+/* this list of conditions and the following disclaimers. */
+/* */
+/* - Redistributions in binary form must reproduce the above copyright */
+/* licenses, this list of conditions and the following disclaimers in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* 3. Disclaimers: */
+/* */
+/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
+/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
+/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
+/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
+/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
+/* information on specification licensing rights available through TCG */
+/* membership agreements. */
+/* */
+/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
+/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
+/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
+/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
+/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
+/* */
+/* - Without limitation, TCG and its members and licensors disclaim all */
+/* liability, including liability for infringement of any proprietary */
+/* rights, relating to use of information in this specification and to the */
+/* implementation of this specification, and TCG disclaims all liability for */
+/* cost of procurement of substitute goods or services, lost profits, loss */
+/* of use, loss of data or any incidental, consequential, direct, indirect, */
+/* or special damages, whether under contract, tort, warranty or otherwise, */
+/* arising in any way out of use or reliance upon this specification or any */
+/* information herein. */
+/* */
+/* (c) Copyright IBM Corp. and others, 2012-2015 */
+/* */
+/********************************************************************************/
+
+/* rev 119 */
+
+#ifndef NV_READPUBLIC_FP_H
+#define NV_READPUBLIC_FP_H
+
+typedef struct {
+ TPMI_RH_NV_INDEX nvIndex;
+} NV_ReadPublic_In;
+
+#define RC_NV_ReadPublic_nvIndex (TPM_RC_P + TPM_RC_1)
+
+typedef struct {
+ TPM2B_NV_PUBLIC nvPublic;
+ TPM2B_NAME nvName;
+} NV_ReadPublic_Out;
+
+TPM_RC
+TPM2_NV_ReadPublic(
+ NV_ReadPublic_In *in, // IN: input parameter list
+ NV_ReadPublic_Out *out // OUT: output parameter list
+ );
+
+
+#endif
diff --git a/src/tpm2/NV_Read_fp.h b/src/tpm2/NV_Read_fp.h
new file mode 100644
index 0000000..660fbd1
--- /dev/null
+++ b/src/tpm2/NV_Read_fp.h
@@ -0,0 +1,89 @@
+/********************************************************************************/
+/* */
+/* */
+/* Written by Ken Goldman */
+/* IBM Thomas J. Watson Research Center */
+/* $Id: NV_Read_fp.h 809 2016-11-16 18:31:54Z kgoldman $ */
+/* */
+/* Licenses and Notices */
+/* */
+/* 1. Copyright Licenses: */
+/* */
+/* - Trusted Computing Group (TCG) grants to the user of the source code in */
+/* this specification (the "Source Code") a worldwide, irrevocable, */
+/* nonexclusive, royalty free, copyright license to reproduce, create */
+/* derivative works, distribute, display and perform the Source Code and */
+/* derivative works thereof, and to grant others the rights granted herein. */
+/* */
+/* - The TCG grants to the user of the other parts of the specification */
+/* (other than the Source Code) the rights to reproduce, distribute, */
+/* display, and perform the specification solely for the purpose of */
+/* developing products based on such documents. */
+/* */
+/* 2. Source Code Distribution Conditions: */
+/* */
+/* - Redistributions of Source Code must retain the above copyright licenses, */
+/* this list of conditions and the following disclaimers. */
+/* */
+/* - Redistributions in binary form must reproduce the above copyright */
+/* licenses, this list of conditions and the following disclaimers in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* 3. Disclaimers: */
+/* */
+/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
+/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
+/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
+/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
+/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
+/* information on specification licensing rights available through TCG */
+/* membership agreements. */
+/* */
+/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
+/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
+/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
+/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
+/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
+/* */
+/* - Without limitation, TCG and its members and licensors disclaim all */
+/* liability, including liability for infringement of any proprietary */
+/* rights, relating to use of information in this specification and to the */
+/* implementation of this specification, and TCG disclaims all liability for */
+/* cost of procurement of substitute goods or services, lost profits, loss */
+/* of use, loss of data or any incidental, consequential, direct, indirect, */
+/* or special damages, whether under contract, tort, warranty or otherwise, */
+/* arising in any way out of use or reliance upon this specification or any */
+/* information herein. */
+/* */
+/* (c) Copyright IBM Corp. and others, 2012-2015 */
+/* */
+/********************************************************************************/
+
+/* rev 119 */
+
+#ifndef NV_READ_FP_H
+#define NV_READ_FP_H
+
+typedef struct {
+ TPMI_RH_NV_AUTH authHandle;
+ TPMI_RH_NV_INDEX nvIndex;
+ UINT16 size;
+ UINT16 offset;
+} NV_Read_In;
+
+#define RC_NV_Read_authHandle (TPM_RC_H + TPM_RC_1)
+#define RC_NV_Read_nvIndex (TPM_RC_H + TPM_RC_2)
+#define RC_NV_Read_size (TPM_RC_P + TPM_RC_1)
+#define RC_NV_Read_offset (TPM_RC_P + TPM_RC_2)
+
+typedef struct {
+ TPM2B_MAX_NV_BUFFER data;
+} NV_Read_Out;
+
+TPM_RC
+TPM2_NV_Read(
+ NV_Read_In *in, // IN: input parameter list
+ NV_Read_Out *out // OUT: output parameter list
+ );
+
+#endif
diff --git a/src/tpm2/NV_SetBits_fp.h b/src/tpm2/NV_SetBits_fp.h
new file mode 100644
index 0000000..b860d64
--- /dev/null
+++ b/src/tpm2/NV_SetBits_fp.h
@@ -0,0 +1,83 @@
+/********************************************************************************/
+/* */
+/* */
+/* Written by Ken Goldman */
+/* IBM Thomas J. Watson Research Center */
+/* $Id: NV_SetBits_fp.h 809 2016-11-16 18:31:54Z kgoldman $ */
+/* */
+/* Licenses and Notices */
+/* */
+/* 1. Copyright Licenses: */
+/* */
+/* - Trusted Computing Group (TCG) grants to the user of the source code in */
+/* this specification (the "Source Code") a worldwide, irrevocable, */
+/* nonexclusive, royalty free, copyright license to reproduce, create */
+/* derivative works, distribute, display and perform the Source Code and */
+/* derivative works thereof, and to grant others the rights granted herein. */
+/* */
+/* - The TCG grants to the user of the other parts of the specification */
+/* (other than the Source Code) the rights to reproduce, distribute, */
+/* display, and perform the specification solely for the purpose of */
+/* developing products based on such documents. */
+/* */
+/* 2. Source Code Distribution Conditions: */
+/* */
+/* - Redistributions of Source Code must retain the above copyright licenses, */
+/* this list of conditions and the following disclaimers. */
+/* */
+/* - Redistributions in binary form must reproduce the above copyright */
+/* licenses, this list of conditions and the following disclaimers in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* 3. Disclaimers: */
+/* */
+/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
+/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
+/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
+/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
+/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
+/* information on specification licensing rights available through TCG */
+/* membership agreements. */
+/* */
+/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
+/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
+/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
+/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
+/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
+/* */
+/* - Without limitation, TCG and its members and licensors disclaim all */
+/* liability, including liability for infringement of any proprietary */
+/* rights, relating to use of information in this specification and to the */
+/* implementation of this specification, and TCG disclaims all liability for */
+/* cost of procurement of substitute goods or services, lost profits, loss */
+/* of use, loss of data or any incidental, consequential, direct, indirect, */
+/* or special damages, whether under contract, tort, warranty or otherwise, */
+/* arising in any way out of use or reliance upon this specification or any */
+/* information herein. */
+/* */
+/* (c) Copyright IBM Corp. and others, 2012-2015 */
+/* */
+/********************************************************************************/
+
+/* rev 119 */
+
+#ifndef NV_SETBITS_FP_H
+#define NV_SETBITS_FP_H
+
+typedef struct {
+ TPMI_RH_NV_AUTH authHandle;
+ TPMI_RH_NV_INDEX nvIndex;
+ UINT64 bits;
+} NV_SetBits_In;
+
+#define RC_NV_SetBits_authHandle (TPM_RC_H + TPM_RC_1)
+#define RC_NV_SetBits_nvIndex (TPM_RC_H + TPM_RC_2)
+#define RC_NV_SetBits_bits (TPM_RC_P + TPM_RC_1)
+
+TPM_RC
+TPM2_NV_SetBits(
+ NV_SetBits_In *in // IN: input parameter list
+ );
+
+
+#endif
diff --git a/src/tpm2/NV_UndefineSpaceSpecial_fp.h b/src/tpm2/NV_UndefineSpaceSpecial_fp.h
new file mode 100644
index 0000000..d2016a4
--- /dev/null
+++ b/src/tpm2/NV_UndefineSpaceSpecial_fp.h
@@ -0,0 +1,81 @@
+/********************************************************************************/
+/* */
+/* */
+/* Written by Ken Goldman */
+/* IBM Thomas J. Watson Research Center */
+/* $Id: NV_UndefineSpaceSpecial_fp.h 809 2016-11-16 18:31:54Z kgoldman $ */
+/* */
+/* Licenses and Notices */
+/* */
+/* 1. Copyright Licenses: */
+/* */
+/* - Trusted Computing Group (TCG) grants to the user of the source code in */
+/* this specification (the "Source Code") a worldwide, irrevocable, */
+/* nonexclusive, royalty free, copyright license to reproduce, create */
+/* derivative works, distribute, display and perform the Source Code and */
+/* derivative works thereof, and to grant others the rights granted herein. */
+/* */
+/* - The TCG grants to the user of the other parts of the specification */
+/* (other than the Source Code) the rights to reproduce, distribute, */
+/* display, and perform the specification solely for the purpose of */
+/* developing products based on such documents. */
+/* */
+/* 2. Source Code Distribution Conditions: */
+/* */
+/* - Redistributions of Source Code must retain the above copyright licenses, */
+/* this list of conditions and the following disclaimers. */
+/* */
+/* - Redistributions in binary form must reproduce the above copyright */
+/* licenses, this list of conditions and the following disclaimers in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* 3. Disclaimers: */
+/* */
+/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
+/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
+/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
+/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
+/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
+/* information on specification licensing rights available through TCG */
+/* membership agreements. */
+/* */
+/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
+/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
+/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
+/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
+/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
+/* */
+/* - Without limitation, TCG and its members and licensors disclaim all */
+/* liability, including liability for infringement of any proprietary */
+/* rights, relating to use of information in this specification and to the */
+/* implementation of this specification, and TCG disclaims all liability for */
+/* cost of procurement of substitute goods or services, lost profits, loss */
+/* of use, loss of data or any incidental, consequential, direct, indirect, */
+/* or special damages, whether under contract, tort, warranty or otherwise, */
+/* arising in any way out of use or reliance upon this specification or any */
+/* information herein. */
+/* */
+/* (c) Copyright IBM Corp. and others, 2012-2015 */
+/* */
+/********************************************************************************/
+
+/* rev 119 */
+
+#ifndef NV_UNDEFINESPACESPECIAL_FP_H
+#define NV_UNDEFINESPACESPECIAL_FP_H
+
+typedef struct {
+ TPMI_RH_NV_INDEX nvIndex;
+ TPMI_RH_PLATFORM platform;
+} NV_UndefineSpaceSpecial_In;
+
+#define RC_NV_UndefineSpaceSpecial_nvIndex (TPM_RC_H + TPM_RC_1)
+#define RC_NV_UndefineSpaceSpecial_platform (TPM_RC_H + TPM_RC_2)
+
+TPM_RC
+TPM2_NV_UndefineSpaceSpecial(
+ NV_UndefineSpaceSpecial_In *in // IN: input parameter list
+ );
+
+
+#endif
diff --git a/src/tpm2/NV_UndefineSpace_fp.h b/src/tpm2/NV_UndefineSpace_fp.h
new file mode 100644
index 0000000..fc6897e
--- /dev/null
+++ b/src/tpm2/NV_UndefineSpace_fp.h
@@ -0,0 +1,81 @@
+/********************************************************************************/
+/* */
+/* */
+/* Written by Ken Goldman */
+/* IBM Thomas J. Watson Research Center */
+/* $Id: NV_UndefineSpace_fp.h 809 2016-11-16 18:31:54Z kgoldman $ */
+/* */
+/* Licenses and Notices */
+/* */
+/* 1. Copyright Licenses: */
+/* */
+/* - Trusted Computing Group (TCG) grants to the user of the source code in */
+/* this specification (the "Source Code") a worldwide, irrevocable, */
+/* nonexclusive, royalty free, copyright license to reproduce, create */
+/* derivative works, distribute, display and perform the Source Code and */
+/* derivative works thereof, and to grant others the rights granted herein. */
+/* */
+/* - The TCG grants to the user of the other parts of the specification */
+/* (other than the Source Code) the rights to reproduce, distribute, */
+/* display, and perform the specification solely for the purpose of */
+/* developing products based on such documents. */
+/* */
+/* 2. Source Code Distribution Conditions: */
+/* */
+/* - Redistributions of Source Code must retain the above copyright licenses, */
+/* this list of conditions and the following disclaimers. */
+/* */
+/* - Redistributions in binary form must reproduce the above copyright */
+/* licenses, this list of conditions and the following disclaimers in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* 3. Disclaimers: */
+/* */
+/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
+/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
+/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
+/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
+/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
+/* information on specification licensing rights available through TCG */
+/* membership agreements. */
+/* */
+/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
+/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
+/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
+/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
+/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
+/* */
+/* - Without limitation, TCG and its members and licensors disclaim all */
+/* liability, including liability for infringement of any proprietary */
+/* rights, relating to use of information in this specification and to the */
+/* implementation of this specification, and TCG disclaims all liability for */
+/* cost of procurement of substitute goods or services, lost profits, loss */
+/* of use, loss of data or any incidental, consequential, direct, indirect, */
+/* or special damages, whether under contract, tort, warranty or otherwise, */
+/* arising in any way out of use or reliance upon this specification or any */
+/* information herein. */
+/* */
+/* (c) Copyright IBM Corp. and others, 2012-2015 */
+/* */
+/********************************************************************************/
+
+/* rev 119 */
+
+#ifndef NV_UNDEFINESPACE_FP_H
+#define NV_UNDEFINESPACE_FP_H
+
+typedef struct {
+ TPMI_RH_PROVISION authHandle;
+ TPMI_RH_NV_INDEX nvIndex;
+} NV_UndefineSpace_In;
+
+#define RC_NV_UndefineSpace_authHandle (TPM_RC_H + TPM_RC_1)
+#define RC_NV_UndefineSpace_nvIndex (TPM_RC_H + TPM_RC_2)
+
+TPM_RC
+TPM2_NV_UndefineSpace(
+ NV_UndefineSpace_In *in // IN: input parameter list
+ );
+
+
+#endif
diff --git a/src/tpm2/NV_WriteLock_fp.h b/src/tpm2/NV_WriteLock_fp.h
new file mode 100644
index 0000000..7771343
--- /dev/null
+++ b/src/tpm2/NV_WriteLock_fp.h
@@ -0,0 +1,81 @@
+/********************************************************************************/
+/* */
+/* */
+/* Written by Ken Goldman */
+/* IBM Thomas J. Watson Research Center */
+/* $Id: NV_WriteLock_fp.h 1521 2019-11-15 21:00:47Z kgoldman $ */
+/* */
+/* Licenses and Notices */
+/* */
+/* 1. Copyright Licenses: */
+/* */
+/* - Trusted Computing Group (TCG) grants to the user of the source code in */
+/* this specification (the "Source Code") a worldwide, irrevocable, */
+/* nonexclusive, royalty free, copyright license to reproduce, create */
+/* derivative works, distribute, display and perform the Source Code and */
+/* derivative works thereof, and to grant others the rights granted herein. */
+/* */
+/* - The TCG grants to the user of the other parts of the specification */
+/* (other than the Source Code) the rights to reproduce, distribute, */
+/* display, and perform the specification solely for the purpose of */
+/* developing products based on such documents. */
+/* */
+/* 2. Source Code Distribution Conditions: */
+/* */
+/* - Redistributions of Source Code must retain the above copyright licenses, */
+/* this list of conditions and the following disclaimers. */
+/* */
+/* - Redistributions in binary form must reproduce the above copyright */
+/* licenses, this list of conditions and the following disclaimers in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* 3. Disclaimers: */
+/* */
+/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
+/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
+/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
+/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
+/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
+/* information on specification licensing rights available through TCG */
+/* membership agreements. */
+/* */
+/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
+/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
+/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
+/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
+/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
+/* */
+/* - Without limitation, TCG and its members and licensors disclaim all */
+/* liability, including liability for infringement of any proprietary */
+/* rights, relating to use of information in this specification and to the */
+/* implementation of this specification, and TCG disclaims all liability for */
+/* cost of procurement of substitute goods or services, lost profits, loss */
+/* of use, loss of data or any incidental, consequential, direct, indirect, */
+/* or special damages, whether under contract, tort, warranty or otherwise, */
+/* arising in any way out of use or reliance upon this specification or any */
+/* information herein. */
+/* */
+/* (c) Copyright IBM Corp. and others, 2012-2015 */
+/* */
+/********************************************************************************/
+
+/* rev 119 */
+
+#ifndef NV_WRITELOCK_FP_H
+#define NV_WRITELOCK_FP_H
+
+typedef struct {
+ TPMI_RH_NV_AUTH authHandle;
+ TPMI_RH_NV_INDEX nvIndex;
+} NV_WriteLock_In;
+
+#define RC_NV_WriteLock_authHandle (TPM_RC_H + TPM_RC_1)
+#define RC_NV_WriteLock_nvIndex (TPM_RC_H + TPM_RC_2)
+
+TPM_RC
+TPM2_NV_WriteLock(
+ NV_WriteLock_In *in // IN: input parameter list
+ );
+
+
+#endif
diff --git a/src/tpm2/NV_Write_fp.h b/src/tpm2/NV_Write_fp.h
new file mode 100644
index 0000000..2880c6e
--- /dev/null
+++ b/src/tpm2/NV_Write_fp.h
@@ -0,0 +1,85 @@
+/********************************************************************************/
+/* */
+/* */
+/* Written by Ken Goldman */
+/* IBM Thomas J. Watson Research Center */
+/* $Id: NV_Write_fp.h 809 2016-11-16 18:31:54Z kgoldman $ */
+/* */
+/* Licenses and Notices */
+/* */
+/* 1. Copyright Licenses: */
+/* */
+/* - Trusted Computing Group (TCG) grants to the user of the source code in */
+/* this specification (the "Source Code") a worldwide, irrevocable, */
+/* nonexclusive, royalty free, copyright license to reproduce, create */
+/* derivative works, distribute, display and perform the Source Code and */
+/* derivative works thereof, and to grant others the rights granted herein. */
+/* */
+/* - The TCG grants to the user of the other parts of the specification */
+/* (other than the Source Code) the rights to reproduce, distribute, */
+/* display, and perform the specification solely for the purpose of */
+/* developing products based on such documents. */
+/* */
+/* 2. Source Code Distribution Conditions: */
+/* */
+/* - Redistributions of Source Code must retain the above copyright licenses, */
+/* this list of conditions and the following disclaimers. */
+/* */
+/* - Redistributions in binary form must reproduce the above copyright */
+/* licenses, this list of conditions and the following disclaimers in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* 3. Disclaimers: */
+/* */
+/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
+/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
+/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
+/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
+/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
+/* information on specification licensing rights available through TCG */
+/* membership agreements. */
+/* */
+/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
+/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
+/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
+/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
+/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
+/* */
+/* - Without limitation, TCG and its members and licensors disclaim all */
+/* liability, including liability for infringement of any proprietary */
+/* rights, relating to use of information in this specification and to the */
+/* implementation of this specification, and TCG disclaims all liability for */
+/* cost of procurement of substitute goods or services, lost profits, loss */
+/* of use, loss of data or any incidental, consequential, direct, indirect, */
+/* or special damages, whether under contract, tort, warranty or otherwise, */
+/* arising in any way out of use or reliance upon this specification or any */
+/* information herein. */
+/* */
+/* (c) Copyright IBM Corp. and others, 2012-2015 */
+/* */
+/********************************************************************************/
+
+/* rev 119 */
+
+#ifndef NV_WRITE_FP_H
+#define NV_WRITE_FP_H
+
+typedef struct {
+ TPMI_RH_NV_AUTH authHandle;
+ TPMI_RH_NV_INDEX nvIndex;
+ TPM2B_MAX_NV_BUFFER data;
+ UINT16 offset;
+} NV_Write_In;
+
+#define RC_NV_Write_authHandle (TPM_RC_H + TPM_RC_1)
+#define RC_NV_Write_nvIndex (TPM_RC_H + TPM_RC_2)
+#define RC_NV_Write_data (TPM_RC_P + TPM_RC_1)
+#define RC_NV_Write_offset (TPM_RC_P + TPM_RC_2)
+
+TPM_RC
+TPM2_NV_Write(
+ NV_Write_In *in // IN: input parameter list
+ );
+
+
+#endif
diff --git a/src/tpm2/NV_spt.c b/src/tpm2/NV_spt.c
new file mode 100644
index 0000000..9e4351f
--- /dev/null
+++ b/src/tpm2/NV_spt.c
@@ -0,0 +1,179 @@
+/********************************************************************************/
+/* */
+/* */
+/* Written by Ken Goldman */
+/* IBM Thomas J. Watson Research Center */
+/* $Id: NV_spt.c 1490 2019-07-26 21:13:22Z kgoldman $ */
+/* */
+/* Licenses and Notices */
+/* */
+/* 1. Copyright Licenses: */
+/* */
+/* - Trusted Computing Group (TCG) grants to the user of the source code in */
+/* this specification (the "Source Code") a worldwide, irrevocable, */
+/* nonexclusive, royalty free, copyright license to reproduce, create */
+/* derivative works, distribute, display and perform the Source Code and */
+/* derivative works thereof, and to grant others the rights granted herein. */
+/* */
+/* - The TCG grants to the user of the other parts of the specification */
+/* (other than the Source Code) the rights to reproduce, distribute, */
+/* display, and perform the specification solely for the purpose of */
+/* developing products based on such documents. */
+/* */
+/* 2. Source Code Distribution Conditions: */
+/* */
+/* - Redistributions of Source Code must retain the above copyright licenses, */
+/* this list of conditions and the following disclaimers. */
+/* */
+/* - Redistributions in binary form must reproduce the above copyright */
+/* licenses, this list of conditions and the following disclaimers in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* 3. Disclaimers: */
+/* */
+/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
+/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
+/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
+/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
+/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
+/* information on specification licensing rights available through TCG */
+/* membership agreements. */
+/* */
+/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
+/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
+/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
+/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
+/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
+/* */
+/* - Without limitation, TCG and its members and licensors disclaim all */
+/* liability, including liability for infringement of any proprietary */
+/* rights, relating to use of information in this specification and to the */
+/* implementation of this specification, and TCG disclaims all liability for */
+/* cost of procurement of substitute goods or services, lost profits, loss */
+/* of use, loss of data or any incidental, consequential, direct, indirect, */
+/* or special damages, whether under contract, tort, warranty or otherwise, */
+/* arising in any way out of use or reliance upon this specification or any */
+/* information herein. */
+/* */
+/* (c) Copyright IBM Corp. and others, 2016, 2017 */
+/* */
+/********************************************************************************/
+
+/* 7.5 NV Command Support (NV_spt.c) */
+/* 7.5.1 Includes */
+#include "Tpm.h"
+#include "NV_spt_fp.h"
+/* 7.5.2 Functions */
+/* 7.5.2.1 NvReadAccessChecks() */
+/* Common routine for validating a read Used by TPM2_NV_Read(), TPM2_NV_ReadLock() and
+ TPM2_PolicyNV() */
+/* Error Returns Meaning */
+/* TPM_RC_NV_AUTHORIZATION autHandle is not allowed to authorize read of the index */
+/* TPM_RC_NV_LOCKED Read locked */
+/* TPM_RC_NV_UNINITIALIZED Try to read an uninitialized index */
+TPM_RC
+NvReadAccessChecks(
+ TPM_HANDLE authHandle, // IN: the handle that provided the
+ // authorization
+ TPM_HANDLE nvHandle, // IN: the handle of the NV index to be read
+ TPMA_NV attributes // IN: the attributes of 'nvHandle'
+ )
+{
+ // If data is read locked, returns an error
+ if(IS_ATTRIBUTE(attributes, TPMA_NV, READLOCKED))
+ return TPM_RC_NV_LOCKED;
+ // If the authorization was provided by the owner or platform, then check
+ // that the attributes allow the read. If the authorization handle
+ // is the same as the index, then the checks were made when the authorization
+ // was checked..
+ if(authHandle == TPM_RH_OWNER)
+ {
+ // If Owner provided authorization then ONWERWRITE must be SET
+ if(!IS_ATTRIBUTE(attributes, TPMA_NV, OWNERREAD))
+ return TPM_RC_NV_AUTHORIZATION;
+ }
+ else if(authHandle == TPM_RH_PLATFORM)
+ {
+ // If Platform provided authorization then PPWRITE must be SET
+ if(!IS_ATTRIBUTE(attributes, TPMA_NV, PPREAD))
+ return TPM_RC_NV_AUTHORIZATION;
+ }
+ // If neither Owner nor Platform provided authorization, make sure that it was
+ // provided by this index.
+ else if(authHandle != nvHandle)
+ return TPM_RC_NV_AUTHORIZATION;
+ // If the index has not been written, then the value cannot be read
+ // NOTE: This has to come after other access checks to make sure that
+ // the proper authorization is given to TPM2_NV_ReadLock()
+ if(!IS_ATTRIBUTE(attributes, TPMA_NV, WRITTEN))
+ return TPM_RC_NV_UNINITIALIZED;
+ return TPM_RC_SUCCESS;
+}
+/* 7.5.2.2 NvWriteAccessChecks() */
+/* Common routine for validating a write Used by TPM2_NV_Write(), TPM2_NV_Increment(),
+ TPM2_SetBits(), and TPM2_NV_WriteLock() */
+/* Error Returns Meaning */
+/* TPM_RC_NV_AUTHORIZATION Authorization fails */
+/* TPM_RC_NV_LOCKED Write locked */
+TPM_RC
+NvWriteAccessChecks(
+ TPM_HANDLE authHandle, // IN: the handle that provided the
+ // authorization
+ TPM_HANDLE nvHandle, // IN: the handle of the NV index to be written
+ TPMA_NV attributes // IN: the attributes of 'nvHandle'
+ )
+{
+ // If data is write locked, returns an error
+ if(IS_ATTRIBUTE(attributes, TPMA_NV, WRITELOCKED))
+ return TPM_RC_NV_LOCKED;
+ // If the authorization was provided by the owner or platform, then check
+ // that the attributes allow the write. If the authorization handle
+ // is the same as the index, then the checks were made when the authorization
+ // was checked..
+ if(authHandle == TPM_RH_OWNER)
+ {
+ // If Owner provided authorization then ONWERWRITE must be SET
+ if(!IS_ATTRIBUTE(attributes, TPMA_NV, OWNERWRITE))
+ return TPM_RC_NV_AUTHORIZATION;
+ }
+ else if(authHandle == TPM_RH_PLATFORM)
+ {
+ // If Platform provided authorization then PPWRITE must be SET
+ if(!IS_ATTRIBUTE(attributes, TPMA_NV, PPWRITE))
+ return TPM_RC_NV_AUTHORIZATION;
+ }
+ // If neither Owner nor Platform provided authorization, make sure that it was
+ // provided by this index.
+ else if(authHandle != nvHandle)
+ return TPM_RC_NV_AUTHORIZATION;
+ return TPM_RC_SUCCESS;
+}
+/* 7.5.2.3 NvClearOrderly() */
+/* This function is used to cause gp.orderlyState to be cleared to the non-orderly state. */
+TPM_RC
+NvClearOrderly(
+ void
+ )
+{
+ if(gp.orderlyState < SU_DA_USED_VALUE)
+ RETURN_IF_NV_IS_NOT_AVAILABLE;
+ g_clearOrderly = TRUE;
+ return TPM_RC_SUCCESS;
+}
+/* 7.5.2.4 NvIsPinPassIndex() */
+/* Function to check to see if an NV index is a PIN Pass Index */
+/* Return Value Meaning */
+/* TRUE is pin pass */
+/* FALSE is not pin pass */
+BOOL
+NvIsPinPassIndex(
+ TPM_HANDLE index // IN: Handle to check
+ )
+{
+ if(HandleGetType(index) == TPM_HT_NV_INDEX)
+ {
+ NV_INDEX *nvIndex = NvGetIndexInfo(index, NULL);
+ return IsNvPinPassIndex(nvIndex->publicArea.attributes);
+ }
+ return FALSE;
+}
diff --git a/src/tpm2/NV_spt_fp.h b/src/tpm2/NV_spt_fp.h
new file mode 100644
index 0000000..dc7906f
--- /dev/null
+++ b/src/tpm2/NV_spt_fp.h
@@ -0,0 +1,87 @@
+/********************************************************************************/
+/* */
+/* */
+/* Written by Ken Goldman */
+/* IBM Thomas J. Watson Research Center */
+/* $Id: NV_spt_fp.h 1490 2019-07-26 21:13:22Z kgoldman $ */
+/* */
+/* Licenses and Notices */
+/* */
+/* 1. Copyright Licenses: */
+/* */
+/* - Trusted Computing Group (TCG) grants to the user of the source code in */
+/* this specification (the "Source Code") a worldwide, irrevocable, */
+/* nonexclusive, royalty free, copyright license to reproduce, create */
+/* derivative works, distribute, display and perform the Source Code and */
+/* derivative works thereof, and to grant others the rights granted herein. */
+/* */
+/* - The TCG grants to the user of the other parts of the specification */
+/* (other than the Source Code) the rights to reproduce, distribute, */
+/* display, and perform the specification solely for the purpose of */
+/* developing products based on such documents. */
+/* */
+/* 2. Source Code Distribution Conditions: */
+/* */
+/* - Redistributions of Source Code must retain the above copyright licenses, */
+/* this list of conditions and the following disclaimers. */
+/* */
+/* - Redistributions in binary form must reproduce the above copyright */
+/* licenses, this list of conditions and the following disclaimers in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* 3. Disclaimers: */
+/* */
+/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
+/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
+/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
+/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
+/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
+/* information on specification licensing rights available through TCG */
+/* membership agreements. */
+/* */
+/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
+/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
+/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
+/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
+/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
+/* */
+/* - Without limitation, TCG and its members and licensors disclaim all */
+/* liability, including liability for infringement of any proprietary */
+/* rights, relating to use of information in this specification and to the */
+/* implementation of this specification, and TCG disclaims all liability for */
+/* cost of procurement of substitute goods or services, lost profits, loss */
+/* of use, loss of data or any incidental, consequential, direct, indirect, */
+/* or special damages, whether under contract, tort, warranty or otherwise, */
+/* arising in any way out of use or reliance upon this specification or any */
+/* information herein. */
+/* */
+/* (c) Copyright IBM Corp. and others, 2016 */
+/* */
+/********************************************************************************/
+
+#ifndef NV_SPT_FP_H
+#define NV_SPT_FP_H
+
+TPM_RC
+NvReadAccessChecks(
+ TPM_HANDLE authHandle, // IN: the handle that provided the
+ // authorization
+ TPM_HANDLE nvHandle, // IN: the handle of the NV index to be read
+ TPMA_NV attributes // IN: the attributes of 'nvHandle'
+ );
+TPM_RC
+NvWriteAccessChecks(
+ TPM_HANDLE authHandle, // IN: the handle that provided the
+ // authorization
+ TPM_HANDLE nvHandle, // IN: the handle of the NV index to be written
+ TPMA_NV attributes // IN: the attributes of 'nvHandle'
+ );
+TPM_RC
+NvClearOrderly(
+ void
+ );
+BOOL
+NvIsPinPassIndex(
+ TPM_HANDLE index // IN: Handle to check
+ );
+#endif
diff --git a/src/tpm2/OIDs.h b/src/tpm2/OIDs.h
new file mode 100644
index 0000000..7147518
--- /dev/null
+++ b/src/tpm2/OIDs.h
@@ -0,0 +1,280 @@
+/********************************************************************************/
+/* */
+/* OID values */
+/* Written by Ken Goldman */
+/* IBM Thomas J. Watson Research Center */
+/* $Id: OIDs.h 1628 2020-05-27 19:35:29Z kgoldman $ */
+/* */
+/* Licenses and Notices */
+/* */
+/* 1. Copyright Licenses: */
+/* */
+/* - Trusted Computing Group (TCG) grants to the user of the source code in */
+/* this specification (the "Source Code") a worldwide, irrevocable, */
+/* nonexclusive, royalty free, copyright license to reproduce, create */
+/* derivative works, distribute, display and perform the Source Code and */
+/* derivative works thereof, and to grant others the rights granted herein. */
+/* */
+/* - The TCG grants to the user of the other parts of the specification */
+/* (other than the Source Code) the rights to reproduce, distribute, */
+/* display, and perform the specification solely for the purpose of */
+/* developing products based on such documents. */
+/* */
+/* 2. Source Code Distribution Conditions: */
+/* */
+/* - Redistributions of Source Code must retain the above copyright licenses, */
+/* this list of conditions and the following disclaimers. */
+/* */
+/* - Redistributions in binary form must reproduce the above copyright */
+/* licenses, this list of conditions and the following disclaimers in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* 3. Disclaimers: */
+/* */
+/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
+/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
+/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
+/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
+/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
+/* information on specification licensing rights available through TCG */
+/* membership agreements. */
+/* */
+/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
+/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
+/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
+/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
+/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
+/* */
+/* - Without limitation, TCG and its members and licensors disclaim all */
+/* liability, including liability for infringement of any proprietary */
+/* rights, relating to use of information in this specification and to the */
+/* implementation of this specification, and TCG disclaims all liability for */
+/* cost of procurement of substitute goods or services, lost profits, loss */
+/* of use, loss of data or any incidental, consequential, direct, indirect, */
+/* or special damages, whether under contract, tort, warranty or otherwise, */
+/* arising in any way out of use or reliance upon this specification or any */
+/* information herein. */
+/* */
+/* (c) Copyright IBM Corp. and others, 2019 - 2020 */
+/* */
+/********************************************************************************/
+
+// 10.1.16 OIDs.h
+
+#include "Tpm.h"
+
+#ifndef _OIDS_H_
+#define _OIDS_H_
+
+// All the OIDs in this file are defined as DER-encoded values with a leading tag 0x06
+// (ASN1_OBJECT_IDENTIFIER), followed by a single length byte. This allows the OID size to be
+// determined by looking at octet[1] of the OID (total size is OID[1] + 2).
+
+// These macros allow OIDs to be defined (or not) depending on whether the associated hash
+// algorithm is implemented.
+
+// NOTE: When one of these macros is used, the NAME needs '_" on each side. The exception is when
+// the macro is used for the hash OID when only a single _ is used.
+
+#ifndef ALG_SHA1
+# define ALG_SHA1 NO
+#endif
+#if ALG_SHA1
+#define SHA1_OID(NAME) MAKE_OID(NAME##SHA1)
+#else
+#define SHA1_OID(NAME)
+#endif
+#ifndef ALG_SHA256
+# define ALG_SHA256 NO
+#endif
+#if ALG_SHA256
+#define SHA256_OID(NAME) MAKE_OID(NAME##SHA256)
+#else
+#define SHA256_OID(NAME)
+#endif
+#ifndef ALG_SHA384
+# define ALG_SHA384 NO
+#endif
+#if ALG_SHA384
+#define SHA384_OID(NAME) MAKE_OID(NAME##SHA384)
+#else
+#define SHA384_OID(NAME)
+#endif
+#ifndef ALG_SHA512
+# define ALG_SHA512 NO
+#endif
+#if ALG_SHA512
+#define SHA512_OID(NAME) MAKE_OID(NAME##SHA512)
+#else
+#define SHA512_OID(NAME)
+#endif
+#ifndef ALG_SM3_256
+# define ALG_SM3_256 NO
+#endif
+#if ALG_SM3_256
+#define SM3_256_OID(NAME) MAKE_OID(NAME##SM3_256)
+#else
+#define SM3_256_OID(NAME)
+#endif
+#ifndef ALG_SHA3_256
+# define ALG_SHA3_256 NO
+#endif
+#if ALG_SHA3_256
+#define SHA3_256_OID(NAME) MAKE_OID(NAME##SHA3_256)
+#else
+#define SHA3_256_OID(NAME)
+#endif
+#ifndef ALG_SHA3_384
+# define ALG_SHA3_384 NO
+#endif
+#if ALG_SHA3_384
+#define SHA3_384_OID(NAME) MAKE_OID(NAME##SHA3_384)
+#else
+#define SHA3_384_OID(NAME)
+#endif
+#ifndef ALG_SHA3_512
+# define ALG_SHA3_512 NO
+#endif
+#if ALG_SHA3_512
+#define SHA3_512_OID(NAME) MAKE_OID(NAME##SHA3_512)
+#else
+#define SHA3_512_OID(NAME)
+#endif
+// These are encoded to take one additional byte of algorithm selector
+#define NIST_HASH 0x06, 0x09, 0x60, 0x86, 0x48, 1, 101, 3, 4, 2
+#define NIST_SIG 0x06, 0x09, 0x60, 0x86, 0x48, 1, 101, 3, 4, 3
+
+// These hash OIDs used in a lot of places.
+#define OID_SHA1_VALUE 0x06, 0x05, 0x2B, 0x0E, 0x03, 0x02, 0x1A
+SHA1_OID(_); // Expands to:
+// MAKE_OID(_SHA1)
+// which expands to:
+// EXTERN const BYTE OID_SHA1[] INITIALIZER({OID_SHA1_VALUE})
+// which, depending on the setting of EXTERN and
+// INITIALIZER, expands to either:
+// extern const BYTE OID_SHA1[]
+// or
+// const BYTE OID_SHA1[] = {OID_SHA1_VALUE}
+// which is:
+// const BYTE OID_SHA1[] = {0x06, 0x05, 0x2B, 0x0E,
+// 0x03, 0x02, 0x1A}
+#define OID_SHA256_VALUE NIST_HASH, 1
+SHA256_OID(_);
+#define OID_SHA384_VALUE NIST_HASH, 2
+SHA384_OID(_);
+#define OID_SHA512_VALUE NIST_HASH, 3
+SHA512_OID(_);
+#define OID_SM3_256_VALUE 0x06, 0x08, 0x2A, 0x81, 0x1C, 0xCF, 0x55, 0x01, \
+ 0x83, 0x11
+SM3_256_OID(_); // (1.2.156.10197.1.401)
+#define OID_SHA3_256_VALUE NIST_HASH, 8
+SHA3_256_OID(_);
+#define OID_SHA3_384_VALUE NIST_HASH, 9
+SHA3_384_OID(_);
+#define OID_SHA3_512_VALUE NIST_HASH, 10
+SHA3_512_OID(_);
+// These are used for RSA-PSS
+#if ALG_RSA
+#define OID_MGF1_VALUE 0x06, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, \
+ 0x01, 0x01, 0x08
+MAKE_OID(_MGF1);
+#define OID_RSAPSS_VALUE 0x06, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, \
+ 0x01, 0x01, 0x0A
+MAKE_OID(_RSAPSS);
+// This is the OID to designate the public part of an RSA key.
+#define OID_PKCS1_PUB_VALUE 0x06, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, \
+ 0x01, 0x01, 0x01
+MAKE_OID(_PKCS1_PUB);
+// These are used for RSA PKCS1 signature Algorithms
+#define OID_PKCS1_SHA1_VALUE 0x06,0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, \
+ 0x0D, 0x01, 0x01, 0x05
+SHA1_OID(_PKCS1_); // (1.2.840.113549.1.1.5)
+#define OID_PKCS1_SHA256_VALUE 0x06,0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, \
+ 0x0D, 0x01, 0x01, 0x0B
+SHA256_OID(_PKCS1_); // (1.2.840.113549.1.1.11)
+#define OID_PKCS1_SHA384_VALUE 0x06,0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, \
+ 0x0D, 0x01, 0x01, 0x0C
+SHA384_OID(_PKCS1_); // (1.2.840.113549.1.1.12)
+#define OID_PKCS1_SHA512_VALUE 0x06,0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, \
+ 0x0D, 0x01, 0x01, 0x0D
+SHA512_OID(_PKCS1_); //(1.2.840.113549.1.1.13)
+#define OID_PKCS1_SM3_256_VALUE 0x06, 0x08, 0x2A, 0x81, 0x1C, 0xCF, 0x55, \
+ 0x01, 0x83, 0x78
+SM3_256_OID(_PKCS1_); // 1.2.156.10197.1.504
+#define OID_PKCS1_SHA3_256_VALUE NIST_SIG, 14
+SHA3_256_OID(_PKCS1_);
+#define OID_PKCS1_SHA3_384_VALUE NIST_SIG, 15
+SHA3_384_OID(_PKCS1_);
+#define OID_PKCS1_SHA3_512_VALUE NIST_SIG, 16
+SHA3_512_OID(_PKCS1_);
+#endif // ALG_RSA
+#if ALG_ECDSA
+#define OID_ECDSA_SHA1_VALUE 0x06, 0x07, 0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x04, \
+ 0x01
+SHA1_OID(_ECDSA_); // (1.2.840.10045.4.1) SHA1 digest signed by an ECDSA key.
+#define OID_ECDSA_SHA256_VALUE 0x06, 0x08, 0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x04, \
+ 0x03, 0x02
+SHA256_OID(_ECDSA_); // (1.2.840.10045.4.3.2) SHA256 digest signed by an ECDSA key.
+#define OID_ECDSA_SHA384_VALUE 0x06, 0x08, 0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x04, \
+ 0x03, 0x03
+SHA384_OID(_ECDSA_); // (1.2.840.10045.4.3.3) SHA384 digest signed by an ECDSA key.
+#define OID_ECDSA_SHA512_VALUE 0x06, 0x08, 0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x04, \
+ 0x03, 0x04
+SHA512_OID(_ECDSA_); // (1.2.840.10045.4.3.4) SHA512 digest signed by an ECDSA key.
+#define OID_ECDSA_SM3_256_VALUE 0x06, 0x08, 0x2A, 0x81, 0x1C, 0xCF, 0x55, 0x01, \
+ 0x83, 0x75
+SM3_256_OID(_ECDSA_); // 1.2.156.10197.1.501
+#define OID_ECDSA_SHA3_256_VALUE NIST_SIG, 10
+SHA3_256_OID(_ECDSA_);
+#define OID_ECDSA_SHA3_384_VALUE NIST_SIG, 11
+SHA3_384_OID(_ECDSA_);
+#define OID_ECDSA_SHA3_512_VALUE NIST_SIG, 12
+SHA3_512_OID(_ECDSA_);
+#endif // ALG_ECDSA
+#if ALG_ECC
+#define OID_ECC_PUBLIC_VALUE 0x06, 0x07, 0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x02, \
+ 0x01
+MAKE_OID(_ECC_PUBLIC);
+#define OID_ECC_NIST_P192_VALUE 0x06, 0x08, 0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x03, \
+ 0x01, 0x01
+#if ECC_NIST_P192
+MAKE_OID(_ECC_NIST_P192); // (1.2.840.10045.3.1.1) 'nistP192'
+#endif // ECC_NIST_P192
+#define OID_ECC_NIST_P224_VALUE 0x06, 0x05, 0x2B, 0x81, 0x04, 0x00, 0x21
+#if ECC_NIST_P224
+MAKE_OID(_ECC_NIST_P224); // (1.3.132.0.33) 'nistP224'
+#endif // ECC_NIST_P224
+#define OID_ECC_NIST_P256_VALUE 0x06, 0x08, 0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x03, \
+ 0x01, 0x07
+#if ECC_NIST_P256
+MAKE_OID(_ECC_NIST_P256); // (1.2.840.10045.3.1.7) 'nistP256'
+#endif // ECC_NIST_P256
+#define OID_ECC_NIST_P384_VALUE 0x06, 0x05, 0x2B, 0x81, 0x04, 0x00, 0x22
+#if ECC_NIST_P384
+MAKE_OID(_ECC_NIST_P384); // (1.3.132.0.34) 'nistP384'
+#endif // ECC_NIST_P384
+#define OID_ECC_NIST_P521_VALUE 0x06, 0x05, 0x2B, 0x81, 0x04, 0x00, 0x23
+#if ECC_NIST_P521
+MAKE_OID(_ECC_NIST_P521); // (1.3.132.0.35) 'nistP521'
+#endif // ECC_NIST_P521
+// No OIDs defined for these anonymous curves
+#define OID_ECC_BN_P256_VALUE 0x00
+#if ECC_BN_P256
+MAKE_OID(_ECC_BN_P256);
+#endif // ECC_BN_P256
+#define OID_ECC_BN_P638_VALUE 0x00
+#if ECC_BN_P638
+MAKE_OID(_ECC_BN_P638);
+#endif // ECC_BN_P638
+#define OID_ECC_SM2_P256_VALUE 0x06, 0x08, 0x2A, 0x81, 0x1C, 0xCF, 0x55, 0x01, \
+ 0x82, 0x2D
+#if ECC_SM2_P256
+MAKE_OID(_ECC_SM2_P256); // Don't know where I found this OID. It needs checking
+#endif // ECC_SM2_P256
+#if ECC_BN_P256
+#define OID_ECC_BN_P256 NULL
+#endif // ECC_BN_P256
+#endif // ALG_ECC
+// #undef MAKE_OID
+#define OID_SIZE(OID) (OID[1] + 2)
+#endif // !_OIDS_H_
diff --git a/src/tpm2/Object.c b/src/tpm2/Object.c
new file mode 100644
index 0000000..aa69a53
--- /dev/null
+++ b/src/tpm2/Object.c
@@ -0,0 +1,970 @@
+/********************************************************************************/
+/* */
+/* Manage the object store of the TPM. */
+/* Written by Ken Goldman */
+/* IBM Thomas J. Watson Research Center */
+/* $Id: Object.c 1658 2021-01-22 23:14:01Z kgoldman $ */
+/* */
+/* Licenses and Notices */
+/* */
+/* 1. Copyright Licenses: */
+/* */
+/* - Trusted Computing Group (TCG) grants to the user of the source code in */
+/* this specification (the "Source Code") a worldwide, irrevocable, */
+/* nonexclusive, royalty free, copyright license to reproduce, create */
+/* derivative works, distribute, display and perform the Source Code and */
+/* derivative works thereof, and to grant others the rights granted herein. */
+/* */
+/* - The TCG grants to the user of the other parts of the specification */
+/* (other than the Source Code) the rights to reproduce, distribute, */
+/* display, and perform the specification solely for the purpose of */
+/* developing products based on such documents. */
+/* */
+/* 2. Source Code Distribution Conditions: */
+/* */
+/* - Redistributions of Source Code must retain the above copyright licenses, */
+/* this list of conditions and the following disclaimers. */
+/* */
+/* - Redistributions in binary form must reproduce the above copyright */
+/* licenses, this list of conditions and the following disclaimers in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* 3. Disclaimers: */
+/* */
+/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
+/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
+/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
+/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
+/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
+/* information on specification licensing rights available through TCG */
+/* membership agreements. */
+/* */
+/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
+/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
+/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
+/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
+/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
+/* */
+/* - Without limitation, TCG and its members and licensors disclaim all */
+/* liability, including liability for infringement of any proprietary */
+/* rights, relating to use of information in this specification and to the */
+/* implementation of this specification, and TCG disclaims all liability for */
+/* cost of procurement of substitute goods or services, lost profits, loss */
+/* of use, loss of data or any incidental, consequential, direct, indirect, */
+/* or special damages, whether under contract, tort, warranty or otherwise, */
+/* arising in any way out of use or reliance upon this specification or any */
+/* information herein. */
+/* */
+/* (c) Copyright IBM Corp. and others, 2016 - 2021 */
+/* */
+/********************************************************************************/
+
+/* 8.6 Object.c */
+/* 8.6.1 Introduction */
+/* This file contains the functions that manage the object store of the TPM. */
+/* 8.6.2 Includes and Data Definitions */
+#define OBJECT_C
+#include "Tpm.h"
+#include "NVMarshal.h" // libtpms added
+#include "BackwardsCompatibilityObject.h" // libtpms added
+/* 8.6.3 Functions */
+/* 8.6.3.1 ObjectFlush() */
+/* This function marks an object slot as available. Since there is no checking of the input
+ parameters, it should be used judiciously. */
+/* NOTE: This could be converted to a macro. */
+void
+ObjectFlush(
+ OBJECT *object
+ )
+{
+ object->attributes.occupied = CLEAR;
+}
+/* 8.6.3.2 ObjectSetInUse() */
+/* This access function sets the occupied attribute of an object slot. */
+void
+ObjectSetInUse(
+ OBJECT *object
+ )
+{
+ object->attributes.occupied = SET;
+}
+/* 8.6.3.3 ObjectStartup() */
+/* This function is called at TPM2_Startup() to initialize the object subsystem. */
+BOOL
+ObjectStartup(
+ void
+ )
+{
+ UINT32 i;
+ // object slots initialization
+ for(i = 0; i < MAX_LOADED_OBJECTS; i++)
+ {
+ //Set the slot to not occupied
+ ObjectFlush(&s_objects[i]);
+ }
+ return TRUE;
+}
+/* 8.6.3.4 ObjectCleanupEvict() */
+/* In this implementation, a persistent object is moved from NV into an object slot for
+ processing. It is flushed after command execution. This function is called from
+ ExecuteCommand(). */
+void
+ObjectCleanupEvict(
+ void
+ )
+{
+ UINT32 i;
+ // This has to be iterated because a command may have two handles
+ // and they may both be persistent.
+ // This could be made to be more efficient so that a search is not needed.
+ for(i = 0; i < MAX_LOADED_OBJECTS; i++)
+ {
+ // If an object is a temporary evict object, flush it from slot
+ OBJECT *object = &s_objects[i];
+ if(object->attributes.evict == SET)
+ ObjectFlush(object);
+ }
+ return;
+}
+/* 8.6.3.5 IsObjectPresent() */
+/* This function checks to see if a transient handle references a loaded object. This routine
+ should not be called if the handle is not a transient handle. The function validates that the
+ handle is in the implementation-dependent allowed in range for loaded transient objects. */
+/* Return Values Meaning */
+/* TRUE if the handle references a loaded object */
+/* FALSE if the handle is not an object handle, or it does not reference to a loaded object */
+BOOL
+IsObjectPresent(
+ TPMI_DH_OBJECT handle // IN: handle to be checked
+ )
+{
+ UINT32 slotIndex = handle - TRANSIENT_FIRST;
+ // Since the handle is just an index into the array that is zero based, any
+ // handle value outsize of the range of:
+ // TRANSIENT_FIRST -- (TRANSIENT_FIRST + MAX_LOADED_OBJECT - 1)
+ // will now be greater than or equal to MAX_LOADED_OBJECTS
+ if(slotIndex >= MAX_LOADED_OBJECTS)
+ return FALSE;
+ // Indicate if the slot is occupied
+ return (s_objects[slotIndex].attributes.occupied == TRUE);
+}
+/* 8.6.3.6 ObjectIsSequence() */
+/* This function is used to check if the object is a sequence object. This function should not be
+ called if the handle does not reference a loaded object. */
+/* Return Values Meaning */
+/* TRUE object is an HMAC, hash, or event sequence object */
+/* FALSE object is not an HMAC, hash, or event sequence object */
+BOOL
+ObjectIsSequence(
+ OBJECT *object // IN: handle to be checked
+ )
+{
+ pAssert(object != NULL);
+ return (object->attributes.hmacSeq == SET
+ || object->attributes.hashSeq == SET
+ || object->attributes.eventSeq == SET);
+}
+/* 8.6.3.7 HandleToObject() */
+/* This function is used to find the object structure associated with a handle. */
+/* This function requires that handle references a loaded object or a permanent handle. */
+OBJECT*
+HandleToObject(
+ TPMI_DH_OBJECT handle // IN: handle of the object
+ )
+{
+ UINT32 index;
+ // Return NULL if the handle references a permanent handle because there is no
+ // associated OBJECT.
+ if(HandleGetType(handle) == TPM_HT_PERMANENT)
+ return NULL;
+ // In this implementation, the handle is determined by the slot occupied by the
+ // object.
+ index = handle - TRANSIENT_FIRST;
+ pAssert(index < MAX_LOADED_OBJECTS);
+ pAssert(s_objects[index].attributes.occupied);
+ return &s_objects[index];
+}
+/* 8.6.3.9 GetQualifiedName() */
+/* This function returns the Qualified Name of the object. In this implementation, the Qualified
+ Name is computed when the object is loaded and is saved in the internal representation of the
+ object. The alternative would be to retain the Name of the parent and compute the QN when
+ needed. This would take the same amount of space so it is not recommended that the alternate be
+ used. */
+/* This function requires that handle references a loaded object. */
+void
+GetQualifiedName(
+ TPMI_DH_OBJECT handle, // IN: handle of the object
+ TPM2B_NAME *qualifiedName // OUT: qualified name of the object
+ )
+{
+ OBJECT *object;
+ switch(HandleGetType(handle))
+ {
+ case TPM_HT_PERMANENT:
+ qualifiedName->t.size = sizeof(TPM_HANDLE);
+ UINT32_TO_BYTE_ARRAY(handle, qualifiedName->t.name);
+ break;
+ case TPM_HT_TRANSIENT:
+ object = HandleToObject(handle);
+ if(object == NULL || object->publicArea.nameAlg == TPM_ALG_NULL)
+ qualifiedName->t.size = 0;
+ else
+ // Copy the name
+ *qualifiedName = object->qualifiedName;
+ break;
+ default:
+ FAIL(FATAL_ERROR_INTERNAL);
+ }
+ return;
+}
+/* 8.6.3.10 ObjectGetHierarchy() */
+/* This function returns the handle for the hierarchy of an object. */
+TPMI_RH_HIERARCHY
+ObjectGetHierarchy(
+ OBJECT *object // IN :object
+ )
+{
+ if(object->attributes.spsHierarchy)
+ {
+ return TPM_RH_OWNER;
+ }
+ else if(object->attributes.epsHierarchy)
+ {
+ return TPM_RH_ENDORSEMENT;
+ }
+ else if(object->attributes.ppsHierarchy)
+ {
+ return TPM_RH_PLATFORM;
+ }
+ else
+ {
+ return TPM_RH_NULL;
+ }
+}
+/* 8.6.3.11 GetHierarchy() */
+/* This function returns the handle of the hierarchy to which a handle belongs. This function is
+ similar to ObjectGetHierarchy() but this routine takes a handle while ObjectGetHierarchy() takes
+ a pointer to an object. */
+/* This function requires that handle references a loaded object. */
+TPMI_RH_HIERARCHY
+GetHieriarchy(
+ TPMI_DH_OBJECT handle // IN :object handle
+ )
+{
+ OBJECT *object = HandleToObject(handle);
+ return ObjectGetHierarchy(object);
+}
+/* 8.6.3.12 FindEmptyObjectSlot() */
+/* This function finds an open object slot, if any. It will clear the attributes but will not set
+ the occupied attribute. This is so that a slot may be used and discarded if everything does not
+ go as planned. */
+/* Return Values Meaning */
+/* null no open slot found */
+/* !=null pointer to available slot */
+OBJECT *
+FindEmptyObjectSlot(
+ TPMI_DH_OBJECT *handle // OUT: (optional)
+ )
+{
+ UINT32 i;
+ OBJECT *object;
+ for(i = 0; i < MAX_LOADED_OBJECTS; i++)
+ {
+ object = &s_objects[i];
+ if(object->attributes.occupied == CLEAR)
+ {
+ if(handle)
+ *handle = i + TRANSIENT_FIRST;
+ // Initialize the object attributes
+ // MemorySet(&object->attributes, 0, sizeof(OBJECT_ATTRIBUTES));
+ MemorySet(object, 0, sizeof(*object)); // libtpms added: Initialize the whole object
+ return object;
+ }
+ }
+ return NULL;
+}
+/* 8.6.3.13 ObjectAllocateSlot() */
+/* This function is used to allocate a slot in internal object array. */
+/* Return Values Meaning */
+OBJECT *
+ObjectAllocateSlot(
+ TPMI_DH_OBJECT *handle // OUT: handle of allocated object
+ )
+{
+ OBJECT *object = FindEmptyObjectSlot(handle);
+ if(object != NULL)
+ {
+ // if found, mark as occupied
+ ObjectSetInUse(object);
+ }
+ return object;
+}
+/* 8.6.3.14 ObjectSetLoadedAttributes() */
+/* This function sets the internal attributes for a loaded object. It is called to finalize the
+ OBJECT attributes (not the TPMA_OBJECT attributes) for a loaded object. */
+void
+ObjectSetLoadedAttributes(
+ OBJECT *object, // IN: object attributes to finalize
+ TPM_HANDLE parentHandle, // IN: the parent handle
+ SEED_COMPAT_LEVEL seedCompatLevel // IN: seed compat level to use for children
+ )
+{
+ OBJECT *parent = HandleToObject(parentHandle);
+ TPMA_OBJECT objectAttributes = object->publicArea.objectAttributes;
+
+ object->seedCompatLevel = seedCompatLevel; // libtpms added
+ //
+ // Copy the stClear attribute from the public area. This could be overwritten
+ // if the parent has stClear SET
+ object->attributes.stClear =
+ IS_ATTRIBUTE(objectAttributes, TPMA_OBJECT, stClear);
+ // If parent handle is a permanent handle, it is a primary (unless it is NULL
+ if(parent == NULL)
+ {
+ object->attributes.primary = SET;
+ switch(parentHandle)
+ {
+ case TPM_RH_ENDORSEMENT:
+ object->attributes.epsHierarchy = SET;
+ break;
+ case TPM_RH_OWNER:
+ object->attributes.spsHierarchy = SET;
+ break;
+ case TPM_RH_PLATFORM:
+ object->attributes.ppsHierarchy = SET;
+ break;
+ default:
+ // Treat the temporary attribute as a hierarchy
+ object->attributes.temporary = SET;
+ object->attributes.primary = CLEAR;
+ break;
+ }
+ }
+ else
+ {
+ // is this a stClear object
+ object->attributes.stClear =
+ (IS_ATTRIBUTE(objectAttributes, TPMA_OBJECT, stClear)
+ || (parent->attributes.stClear == SET));
+ object->attributes.epsHierarchy = parent->attributes.epsHierarchy;
+ object->attributes.spsHierarchy = parent->attributes.spsHierarchy;
+ object->attributes.ppsHierarchy = parent->attributes.ppsHierarchy;
+ // An object is temporary if its parent is temporary or if the object
+ // is external
+ object->attributes.temporary = parent->attributes.temporary
+ || object->attributes.external;
+ }
+ // If this is an external object, set the QN == name but don't SET other
+ // key properties ('parent' or 'derived')
+ if(object->attributes.external)
+ object->qualifiedName = object->name;
+ else
+ {
+ // check attributes for different types of parents
+ if(IS_ATTRIBUTE(objectAttributes, TPMA_OBJECT, restricted)
+ && !object->attributes.publicOnly
+ && IS_ATTRIBUTE(objectAttributes, TPMA_OBJECT, decrypt)
+ && object->publicArea.nameAlg != TPM_ALG_NULL)
+ {
+ // This is a parent. If it is not a KEYEDHASH, it is an ordinary parent.
+ // Otherwise, it is a derivation parent.
+ if(object->publicArea.type == TPM_ALG_KEYEDHASH)
+ object->attributes.derivation = SET;
+ else
+ object->attributes.isParent = SET;
+ }
+ ComputeQualifiedName(parentHandle, object->publicArea.nameAlg,
+ &object->name, &object->qualifiedName);
+ }
+ // Set slot occupied
+ ObjectSetInUse(object);
+ return;
+}
+/* 8.6.3.15 ObjectLoad() */
+/* Common function to load an object. A loaded object has its public area validated (unless its
+ nameAlg is TPM_ALG_NULL). If a sensitive part is loaded, it is verified to be correct and if both
+ public and sensitive parts are loaded, then the cryptographic binding between the objects is
+ validated. This function does not cause the allocated slot to be marked as in use. */
+TPM_RC
+ObjectLoad(
+ OBJECT *object, // IN: pointer to object slot
+ // object
+ OBJECT *parent, // IN: (optional) the parent object
+ TPMT_PUBLIC *publicArea, // IN: public area to be installed in the object
+ TPMT_SENSITIVE *sensitive, // IN: (optional) sensitive area to be
+ // installed in the object
+ TPM_RC blamePublic, // IN: parameter number to associate with the
+ // publicArea errors
+ TPM_RC blameSensitive,// IN: parameter number to associate with the
+ // sensitive area errors
+ TPM2B_NAME *name // IN: (optional)
+ )
+{
+ TPM_RC result = TPM_RC_SUCCESS;
+ BOOL doCheck;
+ //
+ // Do validations of public area object descriptions
+ // Is this public only or a no-name object?
+ if(sensitive == NULL || publicArea->nameAlg == TPM_ALG_NULL)
+ {
+ // Need to have schemes checked so that we do the right thing with the
+ // public key.
+ result = SchemeChecks(NULL, publicArea);
+ }
+ else
+ {
+ // For any sensitive area, make sure that the seedSize is no larger than the
+ // digest size of nameAlg
+ if(sensitive->seedValue.t.size
+ > CryptHashGetDigestSize(publicArea->nameAlg))
+ return TPM_RCS_KEY_SIZE + blameSensitive;
+ // Check attributes and schemes for consistency
+ result = PublicAttributesValidation(parent, publicArea);
+ }
+ if(result != TPM_RC_SUCCESS)
+ return RcSafeAddToResult(result, blamePublic);
+ // If object == NULL, then this is am import. For import, load is not called
+ // unless the parent is fixedTPM.
+ if(object == NULL)
+ doCheck = TRUE;// //
+ // If the parent is not NULL, then this is an ordinary load and we only check
+ // if the parent is not fixedTPM
+ else if(parent != NULL)
+ doCheck = !IS_ATTRIBUTE(parent->publicArea.objectAttributes,
+ TPMA_OBJECT, fixedTPM);
+ else
+ // This is a loadExternal. Check everything.
+ // Note: the check functions will filter things based on the name algorithm
+ // and whether or not both parts are loaded.
+ doCheck = TRUE;
+ // Note: the parent will be NULL if this is a load external. CryptValidateKeys()
+ // will only check the parts that need to be checked based on the settings
+ // of publicOnly and nameAlg.
+ // Note: For an RSA key, the keys sizes are checked but the binding is not
+ // checked.
+ if(doCheck)
+ {
+ // Do the cryptographic key validation
+ result = CryptValidateKeys(publicArea, sensitive, blamePublic,
+ blameSensitive);
+ }
+ // If this is an import, we are done
+ if(object == NULL || result != TPM_RC_SUCCESS)
+ return result;
+ // Set the name, if one was provided
+ if(name != NULL)
+ object->name = *name;
+ else
+ object->name.t.size = 0;
+ // Initialize public
+ object->publicArea = *publicArea;
+ // If there is a sensitive area, load it
+ if(sensitive == NULL)
+ object->attributes.publicOnly = SET;
+ else
+ {
+ object->sensitive = *sensitive;
+#if ALG_RSA
+ // If this is an RSA key that is not a parent, complete the load by
+ // computing the private exponent.
+ if(publicArea->type == ALG_RSA_VALUE)
+ result = CryptRsaLoadPrivateExponent(object);
+#endif
+ }
+ return result;
+}
+/* 8.6.3.16 AllocateSequenceSlot() */
+/* This function allocates a sequence slot and initializes the parts that are used by the normal
+ objects so that a sequence object is not inadvertently used for an operation that is not
+ appropriate for a sequence. */
+static HASH_OBJECT *
+AllocateSequenceSlot(
+ TPM_HANDLE *newHandle, // OUT: receives the allocated handle
+ TPM2B_AUTH *auth // IN: the authValue for the slot
+ )
+{
+ HASH_OBJECT *object = (HASH_OBJECT *)ObjectAllocateSlot(newHandle);
+ //
+ // Validate that the proper location of the hash state data relative to the
+ // object state data. It would be good if this could have been done at compile
+ // time but it can't so do it in something that can be removed after debug.
+ cAssert(offsetof(HASH_OBJECT, auth) == offsetof(OBJECT, publicArea.authPolicy));
+ if(object != NULL)
+ {
+ // Set the common values that a sequence object shares with an ordinary object
+ // First, clear all attributes
+ MemorySet(&object->objectAttributes, 0, sizeof(TPMA_OBJECT));
+ // The type is TPM_ALG_NULL
+ object->type = TPM_ALG_NULL;
+ // This has no name algorithm and the name is the Empty Buffer
+ object->nameAlg = TPM_ALG_NULL;
+ // A sequence object is considered to be in the NULL hierarchy so it should
+ // be marked as temporary so that it can't be persisted
+ object->attributes.temporary = SET;
+ // A sequence object is DA exempt.
+ SET_ATTRIBUTE(object->objectAttributes, TPMA_OBJECT, noDA);
+ // Copy the authorization value
+ if(auth != NULL)
+ object->auth = *auth;
+ else
+ object->auth.t.size = 0;
+ }
+ return object;
+}
+/* 8.6.3.17 ObjectCreateHMACSequence() */
+/* This function creates an internal HMAC sequence object. */
+/* Error Returns Meaning */
+/* TPM_RC_OBJECT_MEMORY if there is no free slot for an object */
+#if CC_HMAC_Start || CC_MAC_Start
+TPM_RC
+ObjectCreateHMACSequence(
+ TPMI_ALG_HASH hashAlg, // IN: hash algorithm
+ OBJECT *keyObject, // IN: the object containing the HMAC key
+ TPM2B_AUTH *auth, // IN: authValue
+ TPMI_DH_OBJECT *newHandle // OUT: HMAC sequence object handle
+ )
+{
+ HASH_OBJECT *hmacObject;
+ //
+ // Try to allocate a slot for new object
+ hmacObject = AllocateSequenceSlot(newHandle, auth);
+ if(hmacObject == NULL)
+ return TPM_RC_OBJECT_MEMORY;
+ // Set HMAC sequence bit
+ hmacObject->attributes.hmacSeq = SET;
+#if !SMAC_IMPLEMENTED
+ if(CryptHmacStart(&hmacObject->state.hmacState, hashAlg,
+ keyObject->sensitive.sensitive.bits.b.size,
+ keyObject->sensitive.sensitive.bits.b.buffer) == 0)
+#else
+ if(CryptMacStart(&hmacObject->state.hmacState,
+ &keyObject->publicArea.parameters,
+ hashAlg, &keyObject->sensitive.sensitive.any.b) == 0)
+#endif // SMAC_IMPLEMENTED
+ return TPM_RC_FAILURE;
+ return TPM_RC_SUCCESS;
+}
+#endif
+
+/* 8.6.3.18 ObjectCreateHashSequence() */
+/* This function creates a hash sequence object. */
+/* Error Returns Meaning */
+/* TPM_RC_OBJECT_MEMORY if there is no free slot for an object */
+TPM_RC
+ObjectCreateHashSequence(
+ TPMI_ALG_HASH hashAlg, // IN: hash algorithm
+ TPM2B_AUTH *auth, // IN: authValue
+ TPMI_DH_OBJECT *newHandle // OUT: sequence object handle
+ )
+{
+ HASH_OBJECT *hashObject = AllocateSequenceSlot(newHandle, auth);
+ // See if slot allocated
+ if(hashObject == NULL)
+ return TPM_RC_OBJECT_MEMORY;
+ // Set hash sequence bit
+ hashObject->attributes.hashSeq = SET;
+ // Start hash for hash sequence
+ CryptHashStart(&hashObject->state.hashState[0], hashAlg);
+ return TPM_RC_SUCCESS;
+}
+/* 8.6.3.19 ObjectCreateEventSequence() */
+/* This function creates an event sequence object. */
+/* Error Returns Meaning */
+/* TPM_RC_OBJECT_MEMORY if there is no free slot for an object */
+TPM_RC
+ObjectCreateEventSequence(
+ TPM2B_AUTH *auth, // IN: authValue
+ TPMI_DH_OBJECT *newHandle // OUT: sequence object handle
+ )
+{
+ HASH_OBJECT *hashObject = AllocateSequenceSlot(newHandle, auth);
+ UINT32 count;
+ TPM_ALG_ID hash;
+ // See if slot allocated
+ if(hashObject == NULL)
+ return TPM_RC_OBJECT_MEMORY;
+ // Set the event sequence attribute
+ hashObject->attributes.eventSeq = SET;
+ // Initialize hash states for each implemented PCR algorithms
+ for(count = 0; (hash = CryptHashGetAlgByIndex(count)) != TPM_ALG_NULL; count++)
+ CryptHashStart(&hashObject->state.hashState[count], hash);
+ return TPM_RC_SUCCESS;
+}
+/* 8.6.3.20 ObjectTerminateEvent() */
+/* This function is called to close out the event sequence and clean up the hash context states. */
+void
+ObjectTerminateEvent(
+ void
+ )
+{
+ HASH_OBJECT *hashObject;
+ int count;
+ BYTE buffer[MAX_DIGEST_SIZE];
+ hashObject = (HASH_OBJECT *)HandleToObject(g_DRTMHandle);
+ // Don't assume that this is a proper sequence object
+ if(hashObject->attributes.eventSeq)
+ {
+ // If it is, close any open hash contexts. This is done in case
+ // the cryptographic implementation has some context values that need to be
+ // cleaned up (hygiene).
+ //
+ for(count = 0; CryptHashGetAlgByIndex(count) != TPM_ALG_NULL; count++)
+ {
+ CryptHashEnd(&hashObject->state.hashState[count], 0, buffer);
+ }
+ // Flush sequence object
+ FlushObject(g_DRTMHandle);
+ }
+ g_DRTMHandle = TPM_RH_UNASSIGNED;
+}
+/* 8.6.3.21 ObjectContextLoad() */
+/* This function loads an object from a saved object context. */
+/* Return Values Meaning */
+/* NULL if there is no free slot for an object */
+/* NON_NULL points to the loaded object */
+#if 0 // libtpms added
+OBJECT *
+ObjectContextLoad(
+ ANY_OBJECT_BUFFER *object, // IN: pointer to object structure in saved
+ // context
+ TPMI_DH_OBJECT *handle // OUT: object handle
+ )
+{
+ OBJECT *newObject = ObjectAllocateSlot(handle);
+ // Try to allocate a slot for new object
+ if(newObject != NULL)
+ {
+ // Copy the first part of the object
+ MemoryCopy(newObject, object, offsetof(HASH_OBJECT, state));
+ // See if this is a sequence object
+ if(ObjectIsSequence(newObject))
+ {
+ // If this is a sequence object, import the data
+ SequenceDataImport((HASH_OBJECT *)newObject,
+ (HASH_OBJECT_BUFFER *)object);
+ }
+ else
+ {
+ // Copy input object data to internal structure
+ MemoryCopy(newObject, object, sizeof(OBJECT));
+ }
+ }
+ return newObject;
+}
+#endif // libtpms added begin
+
+OBJECT *
+ObjectContextLoadLibtpms(BYTE *buffer,
+ INT32 size,
+ TPMI_DH_OBJECT *handle
+ )
+{
+ OBJECT *newObject = ObjectAllocateSlot(handle);
+ TPM_RC rc;
+ BYTE *mybuf = buffer;
+ INT32 mysize = size;
+
+ pAssert(handle);
+
+ // Try to allocate a slot for new object
+ if(newObject != NULL)
+ {
+ rc = ANY_OBJECT_Unmarshal(newObject, &mybuf, &mysize, false);
+ if (rc) {
+ /* Attempt to load an old OBJECT that was copied out directly from
+ * an older version of OBJECT.
+ */
+ rc = OLD_OBJECTToOBJECT(newObject, buffer, size);
+ if (rc) {
+ FlushObject(*handle);
+ newObject = NULL;
+ }
+ }
+ }
+ return newObject;
+} // libtpms added end
+
+/* 8.6.3.22 FlushObject() */
+/* This function frees an object slot. */
+/* This function requires that the object is loaded. */
+void
+FlushObject(
+ TPMI_DH_OBJECT handle // IN: handle to be freed
+ )
+{
+ UINT32 index = handle - TRANSIENT_FIRST;
+ pAssert(index < MAX_LOADED_OBJECTS);
+ // Clear all the object attributes
+ MemorySet((BYTE*)&(s_objects[index].attributes),
+ 0, sizeof(OBJECT_ATTRIBUTES));
+ return;
+}
+/* 8.6.3.23 ObjectFlushHierarchy() */
+/* This function is called to flush all the loaded transient objects associated with a hierarchy
+ when the hierarchy is disabled. */
+void
+ObjectFlushHierarchy(
+ TPMI_RH_HIERARCHY hierarchy // IN: hierarchy to be flush
+ )
+{
+ UINT16 i;
+ // iterate object slots
+ for(i = 0; i < MAX_LOADED_OBJECTS; i++)
+ {
+ if(s_objects[i].attributes.occupied) // If found an occupied slot
+ {
+ switch(hierarchy)
+ {
+ case TPM_RH_PLATFORM:
+ if(s_objects[i].attributes.ppsHierarchy == SET)
+ s_objects[i].attributes.occupied = FALSE;
+ break;
+ case TPM_RH_OWNER:
+ if(s_objects[i].attributes.spsHierarchy == SET)
+ s_objects[i].attributes.occupied = FALSE;
+ break;
+ case TPM_RH_ENDORSEMENT:
+ if(s_objects[i].attributes.epsHierarchy == SET)
+ s_objects[i].attributes.occupied = FALSE;
+ break;
+ default:
+ FAIL(FATAL_ERROR_INTERNAL);
+ break;
+ }
+ }
+ }
+ return;
+}
+/* 8.6.3.24 ObjectLoadEvict() */
+/* This function loads a persistent object into a transient object slot. */
+/* This function requires that handle is associated with a persistent object. */
+/* Error Returns Meaning */
+/* TPM_RC_HANDLE the persistent object does not exist or the associated hierarchy is disabled. */
+/* TPM_RC_OBJECT_MEMORY no object slot */
+TPM_RC
+ObjectLoadEvict(
+ TPM_HANDLE *handle, // IN:OUT: evict object handle. If success, it
+ // will be replace by the loaded object handle
+ COMMAND_INDEX commandIndex // IN: the command being processed
+ )
+{
+ TPM_RC result;
+ TPM_HANDLE evictHandle = *handle; // Save the evict handle
+ OBJECT *object;
+ // If this is an index that references a persistent object created by
+ // the platform, then return TPM_RH_HANDLE if the phEnable is FALSE
+ if(*handle >= PLATFORM_PERSISTENT)
+ {
+ // belongs to platform
+ if(g_phEnable == CLEAR)
+ return TPM_RC_HANDLE;
+ }
+ // belongs to owner
+ else if(gc.shEnable == CLEAR)
+ return TPM_RC_HANDLE;
+ // Try to allocate a slot for an object
+ object = ObjectAllocateSlot(handle);
+ if(object == NULL)
+ return TPM_RC_OBJECT_MEMORY;
+ // Copy persistent object to transient object slot. A TPM_RC_HANDLE
+ // may be returned at this point. This will mark the slot as containing
+ // a transient object so that it will be flushed at the end of the
+ // command
+ result = NvGetEvictObject(evictHandle, object);
+ // Bail out if this failed
+ if(result != TPM_RC_SUCCESS)
+ return result;
+ // check the object to see if it is in the endorsement hierarchy
+ // if it is and this is not a TPM2_EvictControl() command, indicate
+ // that the hierarchy is disabled.
+ // If the associated hierarchy is disabled, make it look like the
+ // handle is not defined
+ if(ObjectGetHierarchy(object) == TPM_RH_ENDORSEMENT
+ && gc.ehEnable == CLEAR
+ && GetCommandCode(commandIndex) != TPM_CC_EvictControl)
+ return TPM_RC_HANDLE;
+ return result;
+}
+/* 8.6.3.25 ObjectComputeName() */
+/* This does the name computation from a public area (can be marshaled or not). */
+TPM2B_NAME *
+ObjectComputeName(
+ UINT32 size, // IN: the size of the area to digest
+ BYTE *publicArea, // IN: the public area to digest
+ TPM_ALG_ID nameAlg, // IN: the hash algorithm to use
+ TPM2B_NAME *name // OUT: Computed name
+ )
+{
+ // Hash the publicArea into the name buffer leaving room for the nameAlg
+ name->t.size = CryptHashBlock(nameAlg, size, publicArea,
+ sizeof(name->t.name) - 2,
+ &name->t.name[2]);
+ // set the nameAlg
+ UINT16_TO_BYTE_ARRAY(nameAlg, name->t.name);
+ name->t.size += 2;
+ return name;
+}
+/* 8.6.3.26 PublicMarshalAndComputeName() */
+/* This function computes the Name of an object from its public area. */
+TPM2B_NAME *
+PublicMarshalAndComputeName(
+ TPMT_PUBLIC *publicArea, // IN: public area of an object
+ TPM2B_NAME *name // OUT: name of the object
+ )
+{
+ // Will marshal a public area into a template. This is because the internal
+ // format for a TPM2B_PUBLIC is a structure and not a simple BYTE buffer.
+ TPM2B_TEMPLATE marshaled; // this is big enough to hold a
+ // marshaled TPMT_PUBLIC
+ BYTE *buffer = (BYTE *)&marshaled.t.buffer;
+ // if the nameAlg is NULL then there is no name.
+ if(publicArea->nameAlg == TPM_ALG_NULL)
+ name->t.size = 0;
+ else
+ {
+ // Marshal the public area into its canonical form
+ marshaled.t.size = TPMT_PUBLIC_Marshal(publicArea, &buffer, NULL);
+ // and compute the name
+ ObjectComputeName(marshaled.t.size, marshaled.t.buffer,
+ publicArea->nameAlg, name);
+ }
+ return name;
+}
+/* 8.6.3.28 ComputeQualifiedName() */
+/* This function computes the qualified name of an object. */
+void
+ComputeQualifiedName(
+ TPM_HANDLE parentHandle, // IN: parent's handle
+ TPM_ALG_ID nameAlg, // IN: name hash
+ TPM2B_NAME *name, // IN: name of the object
+ TPM2B_NAME *qualifiedName // OUT: qualified name of the object
+ )
+{
+ HASH_STATE hashState; // hash state
+ TPM2B_NAME parentName;
+ if(parentHandle == TPM_RH_UNASSIGNED)
+ {
+ MemoryCopy2B(&qualifiedName->b, &name->b, sizeof(qualifiedName->t.name));
+ *qualifiedName = *name;
+ }
+ else
+ {
+ GetQualifiedName(parentHandle, &parentName);
+ // QN_A = hash_A (QN of parent || NAME_A)
+ // Start hash
+ qualifiedName->t.size = CryptHashStart(&hashState, nameAlg);
+ // Add parent's qualified name
+ CryptDigestUpdate2B(&hashState, &parentName.b);
+ // Add self name
+ CryptDigestUpdate2B(&hashState, &name->b);
+ // Complete hash leaving room for the name algorithm
+ CryptHashEnd(&hashState, qualifiedName->t.size,
+ &qualifiedName->t.name[2]);
+ UINT16_TO_BYTE_ARRAY(nameAlg, qualifiedName->t.name);
+ qualifiedName->t.size += 2;
+ }
+ return;
+}
+/* 8.6.3.29 ObjectIsStorage() */
+/* This function determines if an object has the attributes associated with a parent. A parent is an
+ asymmetric or symmetric block cipher key that has its restricted and decrypt attributes SET, and
+ sign CLEAR. */
+/* Return Values Meaning */
+/* TRUE if the object is a storage key */
+/* FALSE if the object is not a storage key */
+BOOL
+ObjectIsStorage(
+ TPMI_DH_OBJECT handle // IN: object handle
+ )
+{
+ OBJECT *object = HandleToObject(handle);
+ TPMT_PUBLIC *publicArea = ((object != NULL) ? &object->publicArea : NULL);
+ //
+ return (publicArea != NULL
+ && IS_ATTRIBUTE(publicArea->objectAttributes, TPMA_OBJECT, restricted)
+ && IS_ATTRIBUTE(publicArea->objectAttributes, TPMA_OBJECT, decrypt)
+ && !IS_ATTRIBUTE(publicArea->objectAttributes, TPMA_OBJECT, sign)
+ && (object->publicArea.type == ALG_RSA_VALUE
+ || object->publicArea.type == ALG_ECC_VALUE));
+}
+/* 8.6.3.30 ObjectCapGetLoaded() */
+/* This function returns a a list of handles of loaded object, starting from handle. Handle must be
+ in the range of valid transient object handles, but does not have to be the handle of a loaded
+ transient object. */
+/* Return Values Meaning */
+/* YES if there are more handles available */
+/* NO all the available handles has been returned */
+TPMI_YES_NO
+ObjectCapGetLoaded(
+ TPMI_DH_OBJECT handle, // IN: start handle
+ UINT32 count, // IN: count of returned handles
+ TPML_HANDLE *handleList // OUT: list of handle
+ )
+{
+ TPMI_YES_NO more = NO;
+ UINT32 i;
+ pAssert(HandleGetType(handle) == TPM_HT_TRANSIENT);
+ // Initialize output handle list
+ handleList->count = 0;
+ // The maximum count of handles we may return is MAX_CAP_HANDLES
+ if(count > MAX_CAP_HANDLES) count = MAX_CAP_HANDLES;
+ // Iterate object slots to get loaded object handles
+ for(i = handle - TRANSIENT_FIRST; i < MAX_LOADED_OBJECTS; i++)
+ {
+ if(s_objects[i].attributes.occupied == TRUE)
+ {
+ // A valid transient object can not be the copy of a persistent object
+ pAssert(s_objects[i].attributes.evict == CLEAR);
+ if(handleList->count < count)
+ {
+ // If we have not filled up the return list, add this object
+ // handle to it
+ handleList->handle[handleList->count] = i + TRANSIENT_FIRST;
+ handleList->count++;
+ }
+ else
+ {
+ // If the return list is full but we still have loaded object
+ // available, report this and stop iterating
+ more = YES;
+ break;
+ }
+ }
+ }
+ return more;
+}
+/* 8.6.3.31 ObjectCapGetTransientAvail() */
+/* This function returns an estimate of the number of additional transient objects that could be
+ loaded into the TPM. */
+UINT32
+ObjectCapGetTransientAvail(
+ void
+ )
+{
+ UINT32 i;
+ UINT32 num = 0;
+ // Iterate object slot to get the number of unoccupied slots
+ for(i = 0; i < MAX_LOADED_OBJECTS; i++)
+ {
+ if(s_objects[i].attributes.occupied == FALSE) num++;
+ }
+ return num;
+}
+/* 8.6.3.32 ObjectGetPublicAttributes() */
+/* Returns the attributes associated with an object handles. */
+TPMA_OBJECT
+ObjectGetPublicAttributes(
+ TPM_HANDLE handle
+ )
+{
+ return HandleToObject(handle)->publicArea.objectAttributes;
+}
+#if 0 /* libtpms added */
+OBJECT_ATTRIBUTES
+ObjectGetProperties(
+ TPM_HANDLE handle
+ )
+{
+ return HandleToObject(handle)->attributes;
+}
+#endif /* libtpms added */
diff --git a/src/tpm2/ObjectChangeAuth_fp.h b/src/tpm2/ObjectChangeAuth_fp.h
new file mode 100644
index 0000000..05a97c3
--- /dev/null
+++ b/src/tpm2/ObjectChangeAuth_fp.h
@@ -0,0 +1,89 @@
+/********************************************************************************/
+/* */
+/* */
+/* Written by Ken Goldman */
+/* IBM Thomas J. Watson Research Center */
+/* $Id: ObjectChangeAuth_fp.h 809 2016-11-16 18:31:54Z kgoldman $ */
+/* */
+/* Licenses and Notices */
+/* */
+/* 1. Copyright Licenses: */
+/* */
+/* - Trusted Computing Group (TCG) grants to the user of the source code in */
+/* this specification (the "Source Code") a worldwide, irrevocable, */
+/* nonexclusive, royalty free, copyright license to reproduce, create */
+/* derivative works, distribute, display and perform the Source Code and */
+/* derivative works thereof, and to grant others the rights granted herein. */
+/* */
+/* - The TCG grants to the user of the other parts of the specification */
+/* (other than the Source Code) the rights to reproduce, distribute, */
+/* display, and perform the specification solely for the purpose of */
+/* developing products based on such documents. */
+/* */
+/* 2. Source Code Distribution Conditions: */
+/* */
+/* - Redistributions of Source Code must retain the above copyright licenses, */
+/* this list of conditions and the following disclaimers. */
+/* */
+/* - Redistributions in binary form must reproduce the above copyright */
+/* licenses, this list of conditions and the following disclaimers in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* 3. Disclaimers: */
+/* */
+/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
+/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
+/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
+/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
+/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
+/* information on specification licensing rights available through TCG */
+/* membership agreements. */
+/* */
+/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
+/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
+/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
+/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
+/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
+/* */
+/* - Without limitation, TCG and its members and licensors disclaim all */
+/* liability, including liability for infringement of any proprietary */
+/* rights, relating to use of information in this specification and to the */
+/* implementation of this specification, and TCG disclaims all liability for */
+/* cost of procurement of substitute goods or services, lost profits, loss */
+/* of use, loss of data or any incidental, consequential, direct, indirect, */
+/* or special damages, whether under contract, tort, warranty or otherwise, */
+/* arising in any way out of use or reliance upon this specification or any */
+/* information herein. */
+/* */
+/* (c) Copyright IBM Corp. and others, 2012-2015 */
+/* */
+/********************************************************************************/
+
+/* rev 119 */
+
+#ifndef OBJECTCHANGEAUTH_FP_H
+#define OBJECTCHANGEAUTH_FP_H
+
+typedef struct {
+ TPMI_DH_OBJECT objectHandle;
+ TPMI_DH_OBJECT parentHandle;
+ TPM2B_AUTH newAuth;
+} ObjectChangeAuth_In;
+
+#define RC_ObjectChangeAuth_objectHandle (TPM_RC_H + TPM_RC_1)
+#define RC_ObjectChangeAuth_parentHandle (TPM_RC_H + TPM_RC_2)
+#define RC_ObjectChangeAuth_newAuth (TPM_RC_P + TPM_RC_1)
+
+typedef struct {
+ TPM2B_PRIVATE outPrivate;
+} ObjectChangeAuth_Out;
+
+
+TPM_RC
+TPM2_ObjectChangeAuth(
+ ObjectChangeAuth_In *in, // IN: input parameter list
+ ObjectChangeAuth_Out *out // OUT: output parameter list
+ );
+
+
+#endif
diff --git a/src/tpm2/ObjectCommands.c b/src/tpm2/ObjectCommands.c
new file mode 100644
index 0000000..27f6637
--- /dev/null
+++ b/src/tpm2/ObjectCommands.c
@@ -0,0 +1,549 @@
+/********************************************************************************/
+/* */
+/* Object Commands */
+/* Written by Ken Goldman */
+/* IBM Thomas J. Watson Research Center */
+/* $Id: ObjectCommands.c 1658 2021-01-22 23:14:01Z kgoldman $ */
+/* */
+/* Licenses and Notices */
+/* */
+/* 1. Copyright Licenses: */
+/* */
+/* - Trusted Computing Group (TCG) grants to the user of the source code in */
+/* this specification (the "Source Code") a worldwide, irrevocable, */
+/* nonexclusive, royalty free, copyright license to reproduce, create */
+/* derivative works, distribute, display and perform the Source Code and */
+/* derivative works thereof, and to grant others the rights granted herein. */
+/* */
+/* - The TCG grants to the user of the other parts of the specification */
+/* (other than the Source Code) the rights to reproduce, distribute, */
+/* display, and perform the specification solely for the purpose of */
+/* developing products based on such documents. */
+/* */
+/* 2. Source Code Distribution Conditions: */
+/* */
+/* - Redistributions of Source Code must retain the above copyright licenses, */
+/* this list of conditions and the following disclaimers. */
+/* */
+/* - Redistributions in binary form must reproduce the above copyright */
+/* licenses, this list of conditions and the following disclaimers in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* 3. Disclaimers: */
+/* */
+/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
+/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
+/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
+/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
+/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
+/* information on specification licensing rights available through TCG */
+/* membership agreements. */
+/* */
+/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
+/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
+/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
+/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
+/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
+/* */
+/* - Without limitation, TCG and its members and licensors disclaim all */
+/* liability, including liability for infringement of any proprietary */
+/* rights, relating to use of information in this specification and to the */
+/* implementation of this specification, and TCG disclaims all liability for */
+/* cost of procurement of substitute goods or services, lost profits, loss */
+/* of use, loss of data or any incidental, consequential, direct, indirect, */
+/* or special damages, whether under contract, tort, warranty or otherwise, */
+/* arising in any way out of use or reliance upon this specification or any */
+/* information herein. */
+/* */
+/* (c) Copyright IBM Corp. and others, 2016 - 2021 */
+/* */
+/********************************************************************************/
+
+#include "Tpm.h"
+#include "Object_spt_fp.h"
+#include "Create_fp.h"
+#if CC_Create // Conditional expansion of this file
+TPM_RC
+TPM2_Create(
+ Create_In *in, // IN: input parameter list
+ Create_Out *out // OUT: output parameter list
+ )
+{
+ TPM_RC result = TPM_RC_SUCCESS;
+ OBJECT *parentObject;
+ OBJECT *newObject;
+ TPMT_PUBLIC *publicArea;
+ // Input Validation
+ parentObject = HandleToObject(in->parentHandle);
+ pAssert(parentObject != NULL);
+ // Does parent have the proper attributes?
+ if(!ObjectIsParent(parentObject))
+ return TPM_RCS_TYPE + RC_Create_parentHandle;
+ // Get a slot for the creation
+ newObject = FindEmptyObjectSlot(NULL);
+ if(newObject == NULL)
+ return TPM_RC_OBJECT_MEMORY;
+ // If the TPM2B_PUBLIC was passed as a structure, marshal it into is canonical
+ // form for processing
+ // to save typing.
+ publicArea = &newObject->publicArea;
+ // Copy the input structure to the allocated structure
+ *publicArea = in->inPublic.publicArea;
+ // Check attributes in input public area. CreateChecks() checks the things that
+ // are unique to creation and then validates the attributes and values that are
+ // common to create and load.
+ result = CreateChecks(parentObject, publicArea,
+ in->inSensitive.sensitive.data.t.size);
+ if(result != TPM_RC_SUCCESS)
+ return RcSafeAddToResult(result, RC_Create_inPublic);
+ // Clean up the authValue if necessary
+ if(!AdjustAuthSize(&in->inSensitive.sensitive.userAuth, publicArea->nameAlg))
+ return TPM_RCS_SIZE + RC_Create_inSensitive;
+ // Command Output
+ // Create the object using the default TPM random-number generator
+ result = CryptCreateObject(newObject, &in->inSensitive.sensitive, NULL);
+ if(result != TPM_RC_SUCCESS)
+ return result;
+ // Fill in creation data
+ FillInCreationData(in->parentHandle, publicArea->nameAlg,
+ &in->creationPCR, &in->outsideInfo,
+ &out->creationData, &out->creationHash);
+ // Compute creation ticket
+ TicketComputeCreation(EntityGetHierarchy(in->parentHandle), &newObject->name,
+ &out->creationHash, &out->creationTicket);
+ // Prepare output private data from sensitive
+ SensitiveToPrivate(&newObject->sensitive, &newObject->name, parentObject,
+ publicArea->nameAlg,
+ &out->outPrivate);
+ // Finish by copying the remaining return values
+ out->outPublic.publicArea = newObject->publicArea;
+ return TPM_RC_SUCCESS;
+}
+#endif // CC_Create
+#include "Tpm.h"
+#include "Load_fp.h"
+#if CC_Load // Conditional expansion of this file
+#include "Object_spt_fp.h"
+TPM_RC
+TPM2_Load(
+ Load_In *in, // IN: input parameter list
+ Load_Out *out // OUT: output parameter list
+ )
+{
+ TPM_RC result = TPM_RC_SUCCESS;
+ TPMT_SENSITIVE sensitive = {0}; // libtpms changed (valgrind)
+ OBJECT *parentObject;
+ OBJECT *newObject;
+ // Input Validation
+ // Don't get invested in loading if there is no place to put it.
+ newObject = FindEmptyObjectSlot(&out->objectHandle);
+ if(newObject == NULL)
+ return TPM_RC_OBJECT_MEMORY;
+ if(in->inPrivate.t.size == 0)
+ return TPM_RCS_SIZE + RC_Load_inPrivate;
+ parentObject = HandleToObject(in->parentHandle);
+ pAssert(parentObject != NULL);
+ // Is the object that is being used as the parent actually a parent.
+ if(!ObjectIsParent(parentObject))
+ return TPM_RCS_TYPE + RC_Load_parentHandle;
+ // Compute the name of object. If there isn't one, it is because the nameAlg is
+ // not valid.
+ PublicMarshalAndComputeName(&in->inPublic.publicArea, &out->name);
+ if(out->name.t.size == 0)
+ return TPM_RCS_HASH + RC_Load_inPublic;
+ // Retrieve sensitive data.
+ result = PrivateToSensitive(&in->inPrivate.b, &out->name.b, parentObject,
+ in->inPublic.publicArea.nameAlg,
+ &sensitive);
+ if(result != TPM_RC_SUCCESS)
+ return RcSafeAddToResult(result, RC_Load_inPrivate);
+ // Internal Data Update
+ // Load and validate object
+ result = ObjectLoad(newObject, parentObject,
+ &in->inPublic.publicArea, &sensitive,
+ RC_Load_inPublic, RC_Load_inPrivate,
+ &out->name);
+ if(result == TPM_RC_SUCCESS)
+ {
+ // Set the common OBJECT attributes for a loaded object.
+ ObjectSetLoadedAttributes(newObject, in->parentHandle,
+ parentObject->seedCompatLevel); // libtpms added
+ }
+ return result;
+}
+#endif // CC_Load
+#include "Tpm.h"
+#include "LoadExternal_fp.h"
+#if CC_LoadExternal // Conditional expansion of this file
+#include "Object_spt_fp.h"
+TPM_RC
+TPM2_LoadExternal(
+ LoadExternal_In *in, // IN: input parameter list
+ LoadExternal_Out *out // OUT: output parameter list
+ )
+{
+ TPM_RC result;
+ OBJECT *object;
+ TPMT_SENSITIVE *sensitive = NULL;
+ // Input Validation
+ // Don't get invested in loading if there is no place to put it.
+ object = FindEmptyObjectSlot(&out->objectHandle);
+ if(object == NULL)
+ return TPM_RC_OBJECT_MEMORY;
+ // If the hierarchy to be associated with this object is turned off, the object
+ // cannot be loaded.
+ if(!HierarchyIsEnabled(in->hierarchy))
+ return TPM_RCS_HIERARCHY + RC_LoadExternal_hierarchy;
+ // For loading an object with both public and sensitive
+ if(in->inPrivate.size != 0)
+ {
+ // An external object with a sensitive area can only be loaded in the
+ // NULL hierarchy
+ if(in->hierarchy != TPM_RH_NULL)
+ return TPM_RCS_HIERARCHY + RC_LoadExternal_hierarchy;
+ // An external object with a sensitive area must have fixedTPM == CLEAR
+ // fixedParent == CLEAR so that it does not appear to be a key created by
+ // this TPM.
+ if(IS_ATTRIBUTE(in->inPublic.publicArea.objectAttributes, TPMA_OBJECT, fixedTPM)
+ || IS_ATTRIBUTE(in->inPublic.publicArea.objectAttributes, TPMA_OBJECT,
+ fixedParent)
+ || IS_ATTRIBUTE(in->inPublic.publicArea.objectAttributes, TPMA_OBJECT,
+ restricted))
+ return TPM_RCS_ATTRIBUTES + RC_LoadExternal_inPublic;
+ // Have sensitive point to something other than NULL so that object
+ // initialization will load the sensitive part too
+ sensitive = &in->inPrivate.sensitiveArea;
+ }
+ // Need the name to initialize the object structure
+ PublicMarshalAndComputeName(&in->inPublic.publicArea, &out->name);
+ // Load and validate key
+ result = ObjectLoad(object, NULL,
+ &in->inPublic.publicArea, sensitive,
+ RC_LoadExternal_inPublic, RC_LoadExternal_inPrivate,
+ &out->name);
+ if(result == TPM_RC_SUCCESS)
+ {
+ object->attributes.external = SET;
+ // Set the common OBJECT attributes for a loaded object.
+ ObjectSetLoadedAttributes(object, in->hierarchy,
+ // if anything can be derived from an external object,
+ // we make sure it always uses the old algorithm
+ SEED_COMPAT_LEVEL_ORIGINAL); // libtpms added
+ }
+ return result;
+}
+#endif // CC_LoadExternal
+#include "Tpm.h"
+#include "ReadPublic_fp.h"
+#if CC_ReadPublic // Conditional expansion of this file
+TPM_RC
+TPM2_ReadPublic(
+ ReadPublic_In *in, // IN: input parameter list
+ ReadPublic_Out *out // OUT: output parameter list
+ )
+{
+ OBJECT *object = HandleToObject(in->objectHandle);
+ // Input Validation
+ // Can not read public area of a sequence object
+ if(ObjectIsSequence(object))
+ return TPM_RC_SEQUENCE;
+ // Command Output
+ out->outPublic.publicArea = object->publicArea;
+ out->name = object->name;
+ out->qualifiedName = object->qualifiedName;
+ return TPM_RC_SUCCESS;
+}
+#endif // CC_ReadPublic
+#include "Tpm.h"
+#include "ActivateCredential_fp.h"
+#if CC_ActivateCredential // Conditional expansion of this file
+#include "Object_spt_fp.h"
+TPM_RC
+TPM2_ActivateCredential(
+ ActivateCredential_In *in, // IN: input parameter list
+ ActivateCredential_Out *out // OUT: output parameter list
+ )
+{
+ TPM_RC result = TPM_RC_SUCCESS;
+ OBJECT *object; // decrypt key
+ OBJECT *activateObject; // key associated with credential
+ TPM2B_DATA data; // credential data
+ // Input Validation
+ // Get decrypt key pointer
+ object = HandleToObject(in->keyHandle);
+ // Get certificated object pointer
+ activateObject = HandleToObject(in->activateHandle);
+ // input decrypt key must be an asymmetric, restricted decryption key
+ if(!CryptIsAsymAlgorithm(object->publicArea.type)
+ || !IS_ATTRIBUTE(object->publicArea.objectAttributes, TPMA_OBJECT, decrypt)
+ || !IS_ATTRIBUTE(object->publicArea.objectAttributes,
+ TPMA_OBJECT, restricted))
+ return TPM_RCS_TYPE + RC_ActivateCredential_keyHandle;
+ // Command output
+ // Decrypt input credential data via asymmetric decryption. A
+ // TPM_RC_VALUE, TPM_RC_KEY or unmarshal errors may be returned at this
+ // point
+ result = CryptSecretDecrypt(object, NULL, IDENTITY_STRING, &in->secret, &data);
+ if(result != TPM_RC_SUCCESS)
+ {
+ if(result == TPM_RC_KEY)
+ return TPM_RC_FAILURE;
+ return RcSafeAddToResult(result, RC_ActivateCredential_secret);
+ }
+ // Retrieve secret data. A TPM_RC_INTEGRITY error or unmarshal
+ // errors may be returned at this point
+ result = CredentialToSecret(&in->credentialBlob.b,
+ &activateObject->name.b,
+ &data.b,
+ object,
+ &out->certInfo);
+ if(result != TPM_RC_SUCCESS)
+ return RcSafeAddToResult(result, RC_ActivateCredential_credentialBlob);
+ return TPM_RC_SUCCESS;
+}
+#endif // CC_ActivateCredential
+#include "Tpm.h"
+#include "MakeCredential_fp.h"
+#if CC_MakeCredential // Conditional expansion of this file
+#include "Object_spt_fp.h"
+TPM_RC
+TPM2_MakeCredential(
+ MakeCredential_In *in, // IN: input parameter list
+ MakeCredential_Out *out // OUT: output parameter list
+ )
+{
+ TPM_RC result = TPM_RC_SUCCESS;
+ OBJECT *object;
+ TPM2B_DATA data;
+ // Input Validation
+ // Get object pointer
+ object = HandleToObject(in->handle);
+ // input key must be an asymmetric, restricted decryption key
+ // NOTE: Needs to be restricted to have a symmetric value.
+ if(!CryptIsAsymAlgorithm(object->publicArea.type)
+ || !IS_ATTRIBUTE(object->publicArea.objectAttributes, TPMA_OBJECT, decrypt)
+ || !IS_ATTRIBUTE(object->publicArea.objectAttributes, TPMA_OBJECT, restricted))
+ return TPM_RCS_TYPE + RC_MakeCredential_handle;
+ // The credential information may not be larger than the digest size used for
+ // the Name of the key associated with handle.
+ if(in->credential.t.size > CryptHashGetDigestSize(object->publicArea.nameAlg))
+ return TPM_RCS_SIZE + RC_MakeCredential_credential;
+ // Command Output
+ // Make encrypt key and its associated secret structure.
+ out->secret.t.size = sizeof(out->secret.t.secret);
+ result = CryptSecretEncrypt(object, IDENTITY_STRING, &data, &out->secret);
+ if(result != TPM_RC_SUCCESS)
+ return result;
+ // Prepare output credential data from secret
+ SecretToCredential(&in->credential, &in->objectName.b, &data.b,
+ object, &out->credentialBlob);
+ return TPM_RC_SUCCESS;
+}
+#endif // CC_MakeCredential
+#include "Tpm.h"
+#include "Unseal_fp.h"
+#if CC_Unseal // Conditional expansion of this file
+TPM_RC
+TPM2_Unseal(
+ Unseal_In *in,
+ Unseal_Out *out
+ )
+{
+ OBJECT *object;
+ // Input Validation
+ // Get pointer to loaded object
+ object = HandleToObject(in->itemHandle);
+ // Input handle must be a data object
+ if(object->publicArea.type != TPM_ALG_KEYEDHASH)
+ return TPM_RCS_TYPE + RC_Unseal_itemHandle;
+ if(IS_ATTRIBUTE(object->publicArea.objectAttributes, TPMA_OBJECT, decrypt)
+ || IS_ATTRIBUTE(object->publicArea.objectAttributes, TPMA_OBJECT, sign)
+ || IS_ATTRIBUTE(object->publicArea.objectAttributes, TPMA_OBJECT, restricted))
+ return TPM_RCS_ATTRIBUTES + RC_Unseal_itemHandle;
+ // Command Output
+ // Copy data
+ out->outData = object->sensitive.sensitive.bits;
+ return TPM_RC_SUCCESS;
+}
+#endif // CC_Unseal
+#include "Tpm.h"
+#include "ObjectChangeAuth_fp.h"
+#if CC_ObjectChangeAuth // Conditional expansion of this file
+#include "Object_spt_fp.h"
+TPM_RC
+TPM2_ObjectChangeAuth(
+ ObjectChangeAuth_In *in, // IN: input parameter list
+ ObjectChangeAuth_Out *out // OUT: output parameter list
+ )
+{
+ TPMT_SENSITIVE sensitive;
+ OBJECT *object = HandleToObject(in->objectHandle);
+ TPM2B_NAME QNCompare;
+ // Input Validation
+ // Can not change authorization on sequence object
+ if(ObjectIsSequence(object))
+ return TPM_RCS_TYPE + RC_ObjectChangeAuth_objectHandle;
+ // Make sure that the authorization value is consistent with the nameAlg
+ if(!AdjustAuthSize(&in->newAuth, object->publicArea.nameAlg))
+ return TPM_RCS_SIZE + RC_ObjectChangeAuth_newAuth;
+ // Parent handle should be the parent of object handle. In this
+ // implementation we verify this by checking the QN of object. Other
+ // implementation may choose different method to verify this attribute.
+ ComputeQualifiedName(in->parentHandle,
+ object->publicArea.nameAlg,
+ &object->name, &QNCompare);
+ if(!MemoryEqual2B(&object->qualifiedName.b, &QNCompare.b))
+ return TPM_RCS_TYPE + RC_ObjectChangeAuth_parentHandle;
+ // Command Output
+ // Prepare the sensitive area with the new authorization value
+ sensitive = object->sensitive;
+ sensitive.authValue = in->newAuth;
+ // Protect the sensitive area
+ SensitiveToPrivate(&sensitive, &object->name, HandleToObject(in->parentHandle),
+ object->publicArea.nameAlg,
+ &out->outPrivate);
+ return TPM_RC_SUCCESS;
+}
+#endif // CC_ObjectChangeAuth
+#include "Tpm.h"
+#include "CreateLoaded_fp.h"
+#if CC_CreateLoaded // Conditional expansion of this file
+TPM_RC
+TPM2_CreateLoaded(
+ CreateLoaded_In *in, // IN: input parameter list
+ CreateLoaded_Out *out // OUT: output parameter list
+ )
+{
+ TPM_RC result = TPM_RC_SUCCESS;
+ OBJECT *parent = HandleToObject(in->parentHandle);
+ OBJECT *newObject;
+ BOOL derivation;
+ TPMT_PUBLIC *publicArea;
+ RAND_STATE randState;
+ RAND_STATE *rand = &randState;
+ TPMS_DERIVE labelContext;
+ SEED_COMPAT_LEVEL seedCompatLevel = SEED_COMPAT_LEVEL_LAST; // libtpms added
+ // Input Validation
+ // How the public area is unmarshaled is determined by the parent, so
+ // see if parent is a derivation parent
+ derivation = (parent != NULL && parent->attributes.derivation);
+ // If the parent is an object, then make sure that it is either a parent or
+ // derivation parent
+ if(parent != NULL && !parent->attributes.isParent && !derivation)
+ return TPM_RCS_TYPE + RC_CreateLoaded_parentHandle;
+ // Get a spot in which to create the newObject
+ newObject = FindEmptyObjectSlot(&out->objectHandle);
+ if(newObject == NULL)
+ return TPM_RC_OBJECT_MEMORY;
+ // Do this to save typing
+ publicArea = &newObject->publicArea;
+ // Unmarshal the template into the object space. TPM2_Create() and
+ // TPM2_CreatePrimary() have the publicArea unmarshaled by CommandDispatcher.
+ // This command is different because of an unfortunate property of the
+ // unique field of an ECC key. It is a structure rather than a single TPM2B. If
+ // if had been a TPM2B, then the label and context could be within a TPM2B and
+ // unmarshaled like other public areas. Since it is not, this command needs its
+ // on template that is a TPM2B that is unmarshaled as a BYTE array with a
+ // its own unmarshal function.
+ result = UnmarshalToPublic(publicArea, &in->inPublic, derivation,
+ &labelContext);
+ if(result != TPM_RC_SUCCESS)
+ return result + RC_CreateLoaded_inPublic;
+ // Validate that the authorization size is appropriate
+ if(!AdjustAuthSize(&in->inSensitive.sensitive.userAuth, publicArea->nameAlg))
+ return TPM_RCS_SIZE + RC_CreateLoaded_inSensitive;
+ // Command output
+ if(derivation)
+ {
+ TPMT_KEYEDHASH_SCHEME *scheme;
+ scheme = &parent->publicArea.parameters.keyedHashDetail.scheme;
+ // SP800-108 is the only KDF supported by this implementation and there is
+ // no default hash algorithm.
+ pAssert(scheme->details.xorr.hashAlg != TPM_ALG_NULL
+ && scheme->details.xorr.kdf == TPM_ALG_KDF1_SP800_108);
+ // Don't derive RSA keys
+ if(publicArea->type == TPM_ALG_RSA)
+ return TPM_RCS_TYPE + RC_CreateLoaded_inPublic;
+ // sensitiveDataOrigin has to be CLEAR in a derived object. Since this
+ // is specific to a derived object, it is checked here.
+ if(IS_ATTRIBUTE(publicArea->objectAttributes, TPMA_OBJECT,
+ sensitiveDataOrigin))
+ return TPM_RCS_ATTRIBUTES;
+ // Check the reset of the attributes
+ result = PublicAttributesValidation(parent, publicArea);
+ if(result != TPM_RC_SUCCESS)
+ return RcSafeAddToResult(result, RC_CreateLoaded_inPublic);
+ // Process the template and sensitive areas to get the actual 'label' and
+ // 'context' values to be used for this derivation.
+ result = SetLabelAndContext(&labelContext, &in->inSensitive.sensitive.data);
+ if(result != TPM_RC_SUCCESS)
+ return result;
+ // Set up the KDF for object generation
+ DRBG_InstantiateSeededKdf((KDF_STATE *)rand,
+ scheme->details.xorr.hashAlg,
+ scheme->details.xorr.kdf,
+ &parent->sensitive.sensitive.bits.b,
+ &labelContext.label.b,
+ &labelContext.context.b,
+ TPM_MAX_DERIVATION_BITS);
+ // Clear the sensitive size so that the creation functions will not try
+ // to use this value.
+ in->inSensitive.sensitive.data.t.size = 0;
+ seedCompatLevel = parent->seedCompatLevel; // libtpms added
+ }
+ else
+ {
+ // Check attributes in input public area. CreateChecks() checks the things
+ // that are unique to creation and then validates the attributes and values
+ // that are common to create and load.
+ result = CreateChecks(parent, publicArea,
+ in->inSensitive.sensitive.data.t.size);
+ if(result != TPM_RC_SUCCESS)
+ return RcSafeAddToResult(result, RC_CreateLoaded_inPublic);
+ // Creating a primary object
+ if(parent == NULL)
+ {
+ TPM2B_NAME name;
+ newObject->attributes.primary = SET;
+ if(in->parentHandle == TPM_RH_ENDORSEMENT)
+ newObject->attributes.epsHierarchy = SET;
+ seedCompatLevel =
+ HierarchyGetPrimarySeedCompatLevel(in->parentHandle); // libtpms added
+ // If so, use the primary seed and the digest of the template
+ // to seed the DRBG
+ result = DRBG_InstantiateSeeded((DRBG_STATE *)rand,
+ &HierarchyGetPrimarySeed(in->parentHandle)->b,
+ PRIMARY_OBJECT_CREATION,
+ (TPM2B *)PublicMarshalAndComputeName(publicArea,&name),
+ &in->inSensitive.sensitive.data.b,
+ seedCompatLevel); // libtpms added
+ if (result != TPM_RC_SUCCESS)
+ return result;
+ }
+ else
+ // This is an ordinary object so use the normal random number generator
+ rand = NULL;
+ }
+ // Internal data update
+ // Create the object
+ result = CryptCreateObject(newObject, &in->inSensitive.sensitive, rand);
+ if(result != TPM_RC_SUCCESS)
+ return result;
+ // if this is not a Primary key and not a derived key, then return the sensitive
+ // area
+ if(parent != NULL && !derivation)
+ // Prepare output private data from sensitive
+ SensitiveToPrivate(&newObject->sensitive, &newObject->name,
+ parent, newObject->publicArea.nameAlg,
+ &out->outPrivate);
+ else
+ out->outPrivate.t.size = 0;
+ // Set the remaining return values
+ out->outPublic.publicArea = newObject->publicArea;
+ out->name = newObject->name;
+ // Set the remaining attributes for a loaded object
+ ObjectSetLoadedAttributes(newObject, in->parentHandle,
+ seedCompatLevel); // libtpms added
+ return result;
+}
+#endif // CC_CreateLoaded
diff --git a/src/tpm2/Object_fp.h b/src/tpm2/Object_fp.h
new file mode 100644
index 0000000..327fd82
--- /dev/null
+++ b/src/tpm2/Object_fp.h
@@ -0,0 +1,236 @@
+/********************************************************************************/
+/* */
+/* Functions That Manage the Object Store of the TPM */
+/* Written by Ken Goldman */
+/* IBM Thomas J. Watson Research Center */
+/* $Id: Object_fp.h 1658 2021-01-22 23:14:01Z kgoldman $ */
+/* */
+/* Licenses and Notices */
+/* */
+/* 1. Copyright Licenses: */
+/* */
+/* - Trusted Computing Group (TCG) grants to the user of the source code in */
+/* this specification (the "Source Code") a worldwide, irrevocable, */
+/* nonexclusive, royalty free, copyright license to reproduce, create */
+/* derivative works, distribute, display and perform the Source Code and */
+/* derivative works thereof, and to grant others the rights granted herein. */
+/* */
+/* - The TCG grants to the user of the other parts of the specification */
+/* (other than the Source Code) the rights to reproduce, distribute, */
+/* display, and perform the specification solely for the purpose of */
+/* developing products based on such documents. */
+/* */
+/* 2. Source Code Distribution Conditions: */
+/* */
+/* - Redistributions of Source Code must retain the above copyright licenses, */
+/* this list of conditions and the following disclaimers. */
+/* */
+/* - Redistributions in binary form must reproduce the above copyright */
+/* licenses, this list of conditions and the following disclaimers in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* 3. Disclaimers: */
+/* */
+/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
+/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
+/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
+/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
+/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
+/* information on specification licensing rights available through TCG */
+/* membership agreements. */
+/* */
+/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
+/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
+/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
+/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
+/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
+/* */
+/* - Without limitation, TCG and its members and licensors disclaim all */
+/* liability, including liability for infringement of any proprietary */
+/* rights, relating to use of information in this specification and to the */
+/* implementation of this specification, and TCG disclaims all liability for */
+/* cost of procurement of substitute goods or services, lost profits, loss */
+/* of use, loss of data or any incidental, consequential, direct, indirect, */
+/* or special damages, whether under contract, tort, warranty or otherwise, */
+/* arising in any way out of use or reliance upon this specification or any */
+/* information herein. */
+/* */
+/* (c) Copyright IBM Corp. and others, 2016 - 2021 */
+/* */
+/********************************************************************************/
+
+#ifndef OBJECT_FP_H
+#define OBJECT_FP_H
+
+void
+ObjectFlush(
+ OBJECT *object
+ );
+void
+ObjectSetInUse(
+ OBJECT *object
+ );
+BOOL
+ObjectStartup(
+ void
+ );
+void
+ObjectCleanupEvict(
+ void
+ );
+BOOL
+IsObjectPresent(
+ TPMI_DH_OBJECT handle // IN: handle to be checked
+ );
+BOOL
+ObjectIsSequence(
+ OBJECT *object // IN: handle to be checked
+ );
+OBJECT*
+HandleToObject(
+ TPMI_DH_OBJECT handle // IN: handle of the object
+ );
+UINT16
+GetName(
+ TPMI_DH_OBJECT handle, // IN: handle of the object
+ NAME *name // OUT: name of the object
+ );
+void
+GetQualifiedName(
+ TPMI_DH_OBJECT handle, // IN: handle of the object
+ TPM2B_NAME *qualifiedName // OUT: qualified name of the object
+ );
+TPMI_RH_HIERARCHY
+ObjectGetHierarchy(
+ OBJECT *object // IN :object
+ );
+TPMI_RH_HIERARCHY
+GetHieriarchy(
+ TPMI_DH_OBJECT handle // IN :object handle
+ );
+OBJECT *
+FindEmptyObjectSlot(
+ TPMI_DH_OBJECT *handle // OUT: (optional)
+ );
+OBJECT *
+ObjectAllocateSlot(
+ TPMI_DH_OBJECT *handle // OUT: handle of allocated object
+ );
+void
+ObjectSetLoadedAttributes(
+ OBJECT *object, // IN: object attributes to finalize
+ TPM_HANDLE parentHandle, // IN: the parent handle
+ SEED_COMPAT_LEVEL seedCompatLevel // IN: seedCompatLevel to use for children
+ );
+TPM_RC
+ObjectLoad(
+ OBJECT *object, // IN: pointer to object slot
+ // object
+ OBJECT *parent, // IN: (optional) the parent object
+ TPMT_PUBLIC *publicArea, // IN: public area to be installed in the object
+ TPMT_SENSITIVE *sensitive, // IN: (optional) sensitive area to be
+ // installed in the object
+ TPM_RC blamePublic, // IN: parameter number to associate with the
+ // publicArea errors
+ TPM_RC blameSensitive,// IN: parameter number to associate with the
+ // sensitive area errors
+ TPM2B_NAME *name // IN: (optional)
+ );
+TPM_RC
+ObjectCreateHMACSequence(
+ TPMI_ALG_HASH hashAlg, // IN: hash algorithm
+ OBJECT *keyObject, // IN: the object containing the HMAC key
+ TPM2B_AUTH *auth, // IN: authValue
+ TPMI_DH_OBJECT *newHandle // OUT: HMAC sequence object handle
+ );
+TPM_RC
+ObjectCreateHashSequence(
+ TPMI_ALG_HASH hashAlg, // IN: hash algorithm
+ TPM2B_AUTH *auth, // IN: authValue
+ TPMI_DH_OBJECT *newHandle // OUT: sequence object handle
+ );
+TPM_RC
+ObjectCreateEventSequence(
+ TPM2B_AUTH *auth, // IN: authValue
+ TPMI_DH_OBJECT *newHandle // OUT: sequence object handle
+ );
+void
+ObjectTerminateEvent(
+ void
+ );
+#if 0 // libtpms added
+OBJECT *
+ObjectContextLoad(
+ ANY_OBJECT_BUFFER *object, // IN: pointer to object structure in saved
+ // context
+ TPMI_DH_OBJECT *handle // OUT: object handle
+ );
+#endif // libtpms added begin
+OBJECT *
+ObjectContextLoadLibtpms(BYTE *buffer, // IN: buffer holding the marshaled object
+ INT32 size, // IN: size of buffer
+ TPMI_DH_OBJECT *handle // OUT: object handle
+ );
+ // libtpms added end
+void
+FlushObject(
+ TPMI_DH_OBJECT handle // IN: handle to be freed
+ );
+void
+ObjectFlushHierarchy(
+ TPMI_RH_HIERARCHY hierarchy // IN: hierarchy to be flush
+ );
+TPM_RC
+ObjectLoadEvict(
+ TPM_HANDLE *handle, // IN:OUT: evict object handle. If success, it
+ // will be replace by the loaded object handle
+ COMMAND_INDEX commandIndex // IN: the command being processed
+ );
+TPM2B_NAME *
+ObjectComputeName(
+ UINT32 size, // IN: the size of the area to digest
+ BYTE *publicArea, // IN: the public area to digest area
+ TPM_ALG_ID nameAlg, // IN: the hash algorithm to use
+ TPM2B_NAME *name // OUT: Computed name
+ );
+TPM2B_NAME *
+PublicMarshalAndComputeName(
+ TPMT_PUBLIC *publicArea, // IN: public area of an object
+ TPM2B_NAME *name // OUT: name of the object
+ );
+TPMI_ALG_HASH
+AlgOfName(
+ TPM2B_NAME *name
+ );
+void
+ComputeQualifiedName(
+ TPM_HANDLE parentHandle, // IN: parent's name
+ TPM_ALG_ID nameAlg, // IN: name hash
+ TPM2B_NAME *name, // IN: name of the object
+ TPM2B_NAME *qualifiedName // OUT: qualified name of the object
+ );
+BOOL
+ObjectIsStorage(
+ TPMI_DH_OBJECT handle // IN: object handle
+ );
+TPMI_YES_NO
+ObjectCapGetLoaded(
+ TPMI_DH_OBJECT handle, // IN: start handle
+ UINT32 count, // IN: count of returned handles
+ TPML_HANDLE *handleList // OUT: list of handle
+ );
+UINT32
+ObjectCapGetTransientAvail(
+ void
+ );
+TPMA_OBJECT
+ObjectGetPublicAttributes(
+ TPM_HANDLE handle
+ );
+OBJECT_ATTRIBUTES
+ObjectGetProperties(
+ TPM_HANDLE handle
+ );
+
+
+#endif
diff --git a/src/tpm2/Object_spt.c b/src/tpm2/Object_spt.c
new file mode 100644
index 0000000..3be6717
--- /dev/null
+++ b/src/tpm2/Object_spt.c
@@ -0,0 +1,1419 @@
+/********************************************************************************/
+/* */
+/* Object Command Support */
+/* Written by Ken Goldman */
+/* IBM Thomas J. Watson Research Center */
+/* $Id: Object_spt.c 1658 2021-01-22 23:14:01Z kgoldman $ */
+/* */
+/* Licenses and Notices */
+/* */
+/* 1. Copyright Licenses: */
+/* */
+/* - Trusted Computing Group (TCG) grants to the user of the source code in */
+/* this specification (the "Source Code") a worldwide, irrevocable, */
+/* nonexclusive, royalty free, copyright license to reproduce, create */
+/* derivative works, distribute, display and perform the Source Code and */
+/* derivative works thereof, and to grant others the rights granted herein. */
+/* */
+/* - The TCG grants to the user of the other parts of the specification */
+/* (other than the Source Code) the rights to reproduce, distribute, */
+/* display, and perform the specification solely for the purpose of */
+/* developing products based on such documents. */
+/* */
+/* 2. Source Code Distribution Conditions: */
+/* */
+/* - Redistributions of Source Code must retain the above copyright licenses, */
+/* this list of conditions and the following disclaimers. */
+/* */
+/* - Redistributions in binary form must reproduce the above copyright */
+/* licenses, this list of conditions and the following disclaimers in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* 3. Disclaimers: */
+/* */
+/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
+/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
+/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
+/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
+/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
+/* information on specification licensing rights available through TCG */
+/* membership agreements. */
+/* */
+/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
+/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
+/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
+/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
+/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
+/* */
+/* - Without limitation, TCG and its members and licensors disclaim all */
+/* liability, including liability for infringement of any proprietary */
+/* rights, relating to use of information in this specification and to the */
+/* implementation of this specification, and TCG disclaims all liability for */
+/* cost of procurement of substitute goods or services, lost profits, loss */
+/* of use, loss of data or any incidental, consequential, direct, indirect, */
+/* or special damages, whether under contract, tort, warranty or otherwise, */
+/* arising in any way out of use or reliance upon this specification or any */
+/* information herein. */
+/* */
+/* (c) Copyright IBM Corp. and others, 2016 - 2021 */
+/* */
+/********************************************************************************/
+
+/* 7.6 Object Command Support (Object_spt.c) */
+/* 7.6.1 Includes */
+#include "Tpm.h"
+#include "Object_spt_fp.h"
+/* 7.6.2 Local Functions */
+/* 7.6.2.1 GetIV2BSize() */
+/* Get the size of TPM2B_IV in canonical form that will be append to the start of the sensitive
+ data. It includes both size of size field and size of iv data */
+/* Return Values Meaning */
+static UINT16
+GetIV2BSize(
+ OBJECT *protector // IN: the protector handle
+ )
+{
+ TPM_ALG_ID symAlg;
+ UINT16 keyBits;
+ // Determine the symmetric algorithm and size of key
+ if(protector == NULL)
+ {
+ // Use the context encryption algorithm and key size
+ symAlg = CONTEXT_ENCRYPT_ALG;
+ keyBits = CONTEXT_ENCRYPT_KEY_BITS;
+ }
+ else
+ {
+ symAlg = protector->publicArea.parameters.asymDetail.symmetric.algorithm;
+ keyBits = protector->publicArea.parameters.asymDetail.symmetric.keyBits.sym;
+ }
+ // The IV size is a UINT16 size field plus the block size of the symmetric
+ // algorithm
+ return sizeof(UINT16) + CryptGetSymmetricBlockSize(symAlg, keyBits);
+}
+/* 7.6.2.2 ComputeProtectionKeyParms() */
+/* This function retrieves the symmetric protection key parameters for the sensitive data The
+ parameters retrieved from this function include encryption algorithm, key size in bit, and a
+ TPM2B_SYM_KEY containing the key material as well as the key size in bytes This function is used
+ for any action that requires encrypting or decrypting of the sensitive area of an object or a
+ credential blob */
+static void
+ComputeProtectionKeyParms(
+ OBJECT *protector, // IN: the protector object
+ TPM_ALG_ID hashAlg, // IN: hash algorithm for KDFa
+ TPM2B *name, // IN: name of the object
+ TPM2B *seedIn, /* IN: optional seed for duplication
+ blob. */
+ // For non duplication blob, this parameter should be NULL
+ TPM_ALG_ID *symAlg, // OUT: the symmetric algorithm
+ UINT16 *keyBits, // OUT: the symmetric key size in bits
+ TPM2B_SYM_KEY *symKey // OUT: the symmetric key
+ )
+{
+ const TPM2B *seed = seedIn;
+ // Determine the algorithms for the KDF and the encryption/decryption
+ // For TPM_RH_NULL, using context settings
+ if(protector == NULL)
+ {
+ // Use the context encryption algorithm and key size
+ *symAlg = CONTEXT_ENCRYPT_ALG;
+ symKey->t.size = CONTEXT_ENCRYPT_KEY_BYTES;
+ *keyBits = CONTEXT_ENCRYPT_KEY_BITS;
+ }
+ else
+ {
+ TPMT_SYM_DEF_OBJECT *symDef;
+ symDef = &protector->publicArea.parameters.asymDetail.symmetric;
+ *symAlg = symDef->algorithm;
+ *keyBits = symDef->keyBits.sym;
+ symKey->t.size = (*keyBits + 7) / 8;
+ }
+ // Get seed for KDF
+ if(seed == NULL)
+ seed = GetSeedForKDF(protector);
+ // KDFa to generate symmetric key and IV value
+ CryptKDFa(hashAlg, seed, STORAGE_KEY, name, NULL,
+ symKey->t.size * 8, symKey->t.buffer, NULL, FALSE);
+ return;
+}
+/* 7.6.2.3 ComputeOuterIntegrity() */
+/* The sensitive area parameter is a buffer that holds a space for the integrity value and the
+ marshaled sensitive area. The caller should skip over the area set aside for the integrity value
+ and compute the hash of the remainder of the object. The size field of sensitive is in
+ unmarshaled form and the sensitive area contents is an array of bytes. */
+static void
+ComputeOuterIntegrity(
+ TPM2B *name, // IN: the name of the object
+ OBJECT *protector, // IN: the object that
+ // provides protection. For an object,
+ // it is a parent. For a credential, it
+ // is the encrypt object. For
+ // a Temporary Object, it is NULL
+ TPMI_ALG_HASH hashAlg, // IN: algorithm to use for integrity
+ TPM2B *seedIn, // IN: an external seed may be provided for
+ // duplication blob. For non duplication
+ // blob, this parameter should be NULL
+ UINT32 sensitiveSize, // IN: size of the marshaled sensitive data
+ BYTE *sensitiveData, // IN: sensitive area
+ TPM2B_DIGEST *integrity // OUT: integrity
+ )
+{
+ HMAC_STATE hmacState;
+ TPM2B_DIGEST hmacKey;
+ const TPM2B *seed = seedIn;
+ //
+ // Get seed for KDF
+ if(seed == NULL)
+ seed = GetSeedForKDF(protector);
+ // Determine the HMAC key bits
+ hmacKey.t.size = CryptHashGetDigestSize(hashAlg);
+ // KDFa to generate HMAC key
+ CryptKDFa(hashAlg, seed, INTEGRITY_KEY, NULL, NULL,
+ hmacKey.t.size * 8, hmacKey.t.buffer, NULL, FALSE);
+ // Start HMAC and get the size of the digest which will become the integrity
+ integrity->t.size = CryptHmacStart2B(&hmacState, hashAlg, &hmacKey.b);
+ // Adding the marshaled sensitive area to the integrity value
+ CryptDigestUpdate(&hmacState.hashState, sensitiveSize, sensitiveData);
+ // Adding name
+ CryptDigestUpdate2B(&hmacState.hashState, name);
+ // Compute HMAC
+ CryptHmacEnd2B(&hmacState, &integrity->b);
+ return;
+}
+/* 7.6.2.4 ComputeInnerIntegrity() */
+/* This function computes the integrity of an inner wrap */
+static void
+ComputeInnerIntegrity(
+ TPM_ALG_ID hashAlg, // IN: hash algorithm for inner wrap
+ TPM2B *name, // IN: the name of the object
+ UINT16 dataSize, // IN: the size of sensitive data
+ BYTE *sensitiveData, // IN: sensitive data
+ TPM2B_DIGEST *integrity // OUT: inner integrity
+ )
+{
+ HASH_STATE hashState;
+ //
+ // Start hash and get the size of the digest which will become the integrity
+ integrity->t.size = CryptHashStart(&hashState, hashAlg);
+ // Adding the marshaled sensitive area to the integrity value
+ CryptDigestUpdate(&hashState, dataSize, sensitiveData);
+ // Adding name
+ CryptDigestUpdate2B(&hashState, name);
+ // Compute hash
+ CryptHashEnd2B(&hashState, &integrity->b);
+ return;
+}
+/* 7.6.2.5 ProduceInnerIntegrity() */
+/* This function produces an inner integrity for regular private, credential or duplication blob It
+ requires the sensitive data being marshaled to the innerBuffer, with the leading bytes reserved
+ for integrity hash. It assume the sensitive data starts at address (innerBuffer + integrity
+ size). This function integrity at the beginning of the inner buffer It returns the total size of
+ buffer with the inner wrap */
+static UINT16
+ProduceInnerIntegrity(
+ TPM2B *name, // IN: the name of the object
+ TPM_ALG_ID hashAlg, // IN: hash algorithm for inner wrap
+ UINT16 dataSize, /* IN: the size of sensitive data, excluding
+ the leading integrity buffer size */
+ BYTE *innerBuffer // IN/OUT: inner buffer with sensitive data in
+ // it. At input, the leading bytes of this
+ // buffer is reserved for integrity
+ )
+{
+ BYTE *sensitiveData; // pointer to the sensitive data
+ TPM2B_DIGEST integrity;
+ UINT16 integritySize;
+ BYTE *buffer; // Auxiliary buffer pointer
+ // sensitiveData points to the beginning of sensitive data in innerBuffer
+ integritySize = sizeof(UINT16) + CryptHashGetDigestSize(hashAlg);
+ sensitiveData = innerBuffer + integritySize;
+ ComputeInnerIntegrity(hashAlg, name, dataSize, sensitiveData, &integrity);
+ // Add integrity at the beginning of inner buffer
+ buffer = innerBuffer;
+ TPM2B_DIGEST_Marshal(&integrity, &buffer, NULL);
+ return dataSize + integritySize;
+}
+/* 7.6.2.6 CheckInnerIntegrity() */
+/* This function check integrity of inner blob */
+/* Error Returns Meaning */
+/* TPM_RC_INTEGRITY if the outer blob integrity is bad */
+/* unmarshal errors unmarshal errors while unmarshaling integrity */
+static TPM_RC
+CheckInnerIntegrity(
+ TPM2B *name, // IN: the name of the object
+ TPM_ALG_ID hashAlg, // IN: hash algorithm for inner wrap
+ UINT16 dataSize, // IN: the size of sensitive data, including the
+ // leading integrity buffer size
+ BYTE *innerBuffer // IN/OUT: inner buffer with sensitive data in
+ // it
+ )
+{
+ TPM_RC result;
+ TPM2B_DIGEST integrity;
+ TPM2B_DIGEST integrityToCompare;
+ BYTE *buffer; // Auxiliary buffer pointer
+ INT32 size;
+ // Unmarshal integrity
+ buffer = innerBuffer;
+ size = (INT32)dataSize;
+ result = TPM2B_DIGEST_Unmarshal(&integrity, &buffer, &size);
+ if(result == TPM_RC_SUCCESS)
+ {
+ // Compute integrity to compare
+ ComputeInnerIntegrity(hashAlg, name, (UINT16)size, buffer,
+ &integrityToCompare);
+ // Compare outer blob integrity
+ if(!MemoryEqual2B(&integrity.b, &integrityToCompare.b))
+ result = TPM_RC_INTEGRITY;
+ }
+ return result;
+}
+/* 7.6.3 Public Functions */
+/* 7.6.3.1 AdjustAuthSize() */
+/* This function will validate that the input authValue is no larger than the digestSize for the
+ nameAlg. It will then pad with zeros to the size of the digest. */
+BOOL
+AdjustAuthSize(
+ TPM2B_AUTH *auth, // IN/OUT: value to adjust
+ TPMI_ALG_HASH nameAlg // IN:
+ )
+{
+ UINT16 digestSize;
+ // If there is no nameAlg, then this is a LoadExternal and the authVale can
+ // be any size up to the maximum allowed by the implementation
+ digestSize = (nameAlg == TPM_ALG_NULL) ? sizeof(TPMU_HA)
+ : CryptHashGetDigestSize(nameAlg);
+ if(digestSize < MemoryRemoveTrailingZeros(auth))
+ return FALSE;
+ else if(digestSize > auth->t.size)
+ MemoryPad2B(&auth->b, digestSize);
+ auth->t.size = digestSize;
+ return TRUE;
+}
+/* 7.6.3.2 AreAttributesForParent() */
+/* This function is called by create, load, and import functions. */
+/* NOTE: The isParent attribute is SET when an object is loaded and it has attributes that are
+ suitable for a parent object. */
+/* Return Values Meaning */
+/* TRUE properties are those of a parent */
+/* FALSE properties are not those of a parent */
+BOOL
+ObjectIsParent(
+ OBJECT *parentObject // IN: parent handle
+ )
+{
+ return parentObject->attributes.isParent;
+}
+/* 7.6.3.3 CreateChecks() */
+/* Attribute checks that are unique to creation. */
+/* Error Returns Meaning */
+/* TPM_RC_ATTRIBUTES sensitiveDataOrigin is not consistent with the object type */
+/* other returns from PublicAttributesValidation() */
+TPM_RC
+CreateChecks(
+ OBJECT *parentObject,
+ TPMT_PUBLIC *publicArea,
+ UINT16 sensitiveDataSize
+ )
+{
+ TPMA_OBJECT attributes = publicArea->objectAttributes;
+ TPM_RC result = TPM_RC_SUCCESS;
+ //
+ // If the caller indicates that they have provided the data, then make sure that
+ // they have provided some data.
+ if((!IS_ATTRIBUTE(attributes, TPMA_OBJECT, sensitiveDataOrigin))
+ && (sensitiveDataSize == 0))
+ return TPM_RCS_ATTRIBUTES;
+ // For an ordinary object, data can only be provided when sensitiveDataOrigin
+ // is CLEAR
+ if((parentObject != NULL)
+ && (IS_ATTRIBUTE(attributes, TPMA_OBJECT, sensitiveDataOrigin))
+ && (sensitiveDataSize != 0))
+ return TPM_RCS_ATTRIBUTES;
+ switch(publicArea->type)
+ {
+ case TPM_ALG_KEYEDHASH:
+ // if this is a data object (sign == decrypt == CLEAR) then the
+ // TPM cannot be the data source.
+ if(!IS_ATTRIBUTE(attributes, TPMA_OBJECT, sign)
+ && !IS_ATTRIBUTE(attributes, TPMA_OBJECT, decrypt)
+ && IS_ATTRIBUTE(attributes, TPMA_OBJECT, sensitiveDataOrigin))
+ result = TPM_RC_ATTRIBUTES;
+ // comment out the next line in order to prevent a fixedTPM derivation
+ // parent
+ // break;
+ case TPM_ALG_SYMCIPHER:
+ // A restricted key symmetric key (SYMCIPHER and KEYEDHASH)
+ // must have sensitiveDataOrigin SET unless it has fixedParent and
+ // fixedTPM CLEAR.
+ if(IS_ATTRIBUTE(attributes, TPMA_OBJECT, restricted))
+ if(!IS_ATTRIBUTE(attributes, TPMA_OBJECT, sensitiveDataOrigin))
+ if(IS_ATTRIBUTE(attributes, TPMA_OBJECT, fixedParent)
+ || IS_ATTRIBUTE(attributes, TPMA_OBJECT, fixedTPM))
+ result = TPM_RCS_ATTRIBUTES;
+ break;
+ default: // Asymmetric keys cannot have the sensitive portion provided
+ if(!IS_ATTRIBUTE(attributes, TPMA_OBJECT, sensitiveDataOrigin))
+ result = TPM_RCS_ATTRIBUTES;
+ break;
+ }
+ if(TPM_RC_SUCCESS == result)
+ {
+ result = PublicAttributesValidation(parentObject, publicArea);
+ }
+ return result;
+}
+/* 7.6.3.4 SchemeChecks */
+/* This function is called by TPM2_LoadExternal() and PublicAttributesValidation(). This function
+ validates the schemes in the public area of an object. */
+/* Error Returns Meaning */
+/* TPM_RC_HASH non-duplicable storage key and its parent have different name algorithm */
+/* TPM_RC_KDF incorrect KDF specified for decrypting keyed hash object */
+/* TPM_RC_KEY invalid key size values in an asymmetric key public area */
+/* TPM_RCS_SCHEME inconsistent attributes decrypt, sign, restricted and key's scheme ID; or hash
+ algorithm is inconsistent with the scheme ID for keyed hash object */
+/* TPM_RC_SYMMETRIC a storage key with no symmetric algorithm specified; or non-storage key with
+ symmetric algorithm different from TPM_ALG_NULL */
+TPM_RC
+SchemeChecks(
+ OBJECT *parentObject, // IN: parent (null if primary seed)
+ TPMT_PUBLIC *publicArea // IN: public area of the object
+ )
+{
+ TPMT_SYM_DEF_OBJECT *symAlgs = NULL;
+ TPM_ALG_ID scheme = TPM_ALG_NULL;
+ TPMA_OBJECT attributes = publicArea->objectAttributes;
+ TPMU_PUBLIC_PARMS *parms = &publicArea->parameters;
+ //
+ switch(publicArea->type)
+ {
+ case TPM_ALG_SYMCIPHER:
+ symAlgs = &parms->symDetail.sym;
+ // If this is a decrypt key, then only the block cipher modes (not
+ // SMAC) are valid. TPM_ALG_NULL is OK too. If this is a 'sign' key,
+ // then any mode that got through the unmarshaling is OK.
+ if(IS_ATTRIBUTE(attributes, TPMA_OBJECT, decrypt)
+ && !CryptSymModeIsValid(symAlgs->mode.sym, TRUE))
+ return TPM_RCS_SCHEME;
+ break;
+ case TPM_ALG_KEYEDHASH:
+ scheme = parms->keyedHashDetail.scheme.scheme;
+ // if both sign and decrypt
+ if(IS_ATTRIBUTE(attributes, TPMA_OBJECT, sign)
+ == IS_ATTRIBUTE(attributes, TPMA_OBJECT, decrypt))
+ {
+ // if both sign and decrypt are set or clear, then need
+ // TPM_ALG_NULL as scheme
+ if(scheme != TPM_ALG_NULL)
+ return TPM_RCS_SCHEME;
+ }
+ else if(IS_ATTRIBUTE(attributes, TPMA_OBJECT, sign)
+ && scheme != TPM_ALG_HMAC)
+ return TPM_RCS_SCHEME;
+ else if(IS_ATTRIBUTE(attributes, TPMA_OBJECT, decrypt))
+ {
+ if(scheme != TPM_ALG_XOR)
+ return TPM_RCS_SCHEME;
+ // If this is a derivation parent, then the KDF needs to be
+ // SP800-108 for this implementation. This is the only derivation
+ // supported by this implementation. Other implementations could
+ // support additional schemes. There is no default.
+ if(IS_ATTRIBUTE(attributes, TPMA_OBJECT, restricted))
+ {
+ if(parms->keyedHashDetail.scheme.details.xorr.kdf
+ != TPM_ALG_KDF1_SP800_108)
+ return TPM_RCS_SCHEME;
+ // Must select a digest.
+ if(CryptHashGetDigestSize
+ (parms->keyedHashDetail.scheme.details.xorr.hashAlg) == 0)
+ return TPM_RCS_HASH;
+ }
+ }
+ break;
+ default: // handling for asymmetric
+ scheme = parms->asymDetail.scheme.scheme;
+ symAlgs = &parms->asymDetail.symmetric;
+ // if the key is both sign and decrypt, then the scheme must be
+ // TPM_ALG_NULL because there is no way to specify both a sign and a
+ // decrypt scheme in the key.
+ if(IS_ATTRIBUTE(attributes, TPMA_OBJECT, sign)
+ == IS_ATTRIBUTE(attributes, TPMA_OBJECT, decrypt))
+ {
+ // scheme must be TPM_ALG_NULL
+ if(scheme != TPM_ALG_NULL)
+ return TPM_RCS_SCHEME;
+ }
+ else if(IS_ATTRIBUTE(attributes, TPMA_OBJECT, sign))
+ {
+ // If this is a signing key, see if it has a signing scheme
+ if(CryptIsAsymSignScheme(publicArea->type, scheme))
+ {
+ // if proper signing scheme then it needs a proper hash
+ if(parms->asymDetail.scheme.details.anySig.hashAlg
+ == TPM_ALG_NULL)
+ return TPM_RCS_SCHEME;
+ }
+ else
+ {
+ // signing key that does not have a proper signing scheme.
+ // This is OK if the key is not restricted and its scheme
+ // is TPM_ALG_NULL
+ if(IS_ATTRIBUTE(attributes, TPMA_OBJECT, restricted)
+ || scheme != TPM_ALG_NULL)
+ return TPM_RCS_SCHEME;
+ }
+ }
+ else if(IS_ATTRIBUTE(attributes, TPMA_OBJECT, decrypt))
+ {
+ if(IS_ATTRIBUTE(attributes, TPMA_OBJECT, restricted))
+ {
+ // for a restricted decryption key (a parent), scheme
+ // is required to be TPM_ALG_NULL
+ if(scheme != TPM_ALG_NULL)
+ return TPM_RCS_SCHEME;
+ }
+ else
+ {
+ // For an unrestricted decryption key, the scheme has to
+ // be a valid scheme or TPM_ALG_NULL
+ if(scheme != TPM_ALG_NULL &&
+ !CryptIsAsymDecryptScheme(publicArea->type, scheme))
+ return TPM_RCS_SCHEME;
+ }
+ }
+ if(!IS_ATTRIBUTE(attributes, TPMA_OBJECT, restricted)
+ || !IS_ATTRIBUTE(attributes, TPMA_OBJECT, decrypt))
+ {
+ // For an asymmetric key that is not a parent, the symmetric
+ // algorithms must be TPM_ALG_NULL
+ if(symAlgs->algorithm != TPM_ALG_NULL)
+ return TPM_RCS_SYMMETRIC;
+ }
+ // Special checks for an ECC key
+#if ALG_ECC
+ if(publicArea->type == TPM_ALG_ECC)
+ {
+ TPM_ECC_CURVE curveID;
+ const TPMT_ECC_SCHEME *curveScheme;
+ curveID = publicArea->parameters.eccDetail.curveID;
+ curveScheme = CryptGetCurveSignScheme(curveID);
+ // The curveId must be valid or the unmarshaling is busted.
+ pAssert(curveScheme != NULL);
+ // If the curveID requires a specific scheme, then the key must
+ // select the same scheme
+ if(curveScheme->scheme != TPM_ALG_NULL)
+ {
+ TPMS_ECC_PARMS *ecc = &publicArea->parameters.eccDetail;
+ if(scheme != curveScheme->scheme)
+ return TPM_RCS_SCHEME;
+ // The scheme can allow any hash, or not...
+ if(curveScheme->details.anySig.hashAlg != TPM_ALG_NULL
+ && (ecc->scheme.details.anySig.hashAlg
+ != curveScheme->details.anySig.hashAlg))
+ return TPM_RCS_SCHEME;
+ }
+ // For now, the KDF must be TPM_ALG_NULL
+ if(publicArea->parameters.eccDetail.kdf.scheme != TPM_ALG_NULL)
+ return TPM_RCS_KDF;
+ }
+#endif
+ break;
+ }
+ // If this is a restricted decryption key with symmetric algorithms, then it
+ // is an ordinary parent (not a derivation parent). It needs to specific
+ // symmetric algorithms other than TPM_ALG_NULL
+ if(symAlgs != NULL
+ && IS_ATTRIBUTE(attributes, TPMA_OBJECT, restricted)
+ && IS_ATTRIBUTE(attributes, TPMA_OBJECT, decrypt))
+ {
+ if(symAlgs->algorithm == TPM_ALG_NULL)
+ return TPM_RCS_SYMMETRIC;
+#if 0 //??
+ // This next check is under investigation. Need to see if it will break Windows
+ // before it is enabled. If it does not, then it should be default because a
+ // the mode used with a parent is always CFB and Part 2 indicates as much.
+ if(symAlgs->mode.sym != TPM_ALG_CFB)
+ return TPM_RCS_MODE;
+#endif
+ // If this parent is not duplicable, then the symmetric algorithms
+ // (encryption and hash) must match those of its parent
+ if(IS_ATTRIBUTE(attributes, TPMA_OBJECT, fixedParent)
+ && (parentObject != NULL))
+ {
+ if(publicArea->nameAlg != parentObject->publicArea.nameAlg)
+ return TPM_RCS_HASH;
+ if(!MemoryEqual(symAlgs, &parentObject->publicArea.parameters,
+ sizeof(TPMT_SYM_DEF_OBJECT)))
+ return TPM_RCS_SYMMETRIC;
+ }
+ }
+ return TPM_RC_SUCCESS;
+}
+/* 7.6.3.5 PublicAttributesValidation() */
+/* This function validates the values in the public area of an object. This function is used in the
+ processing of TPM2_Create(), TPM2_CreatePrimary(), TPM2_CreateLoaded(), TPM2_Load(),
+ TPM2_Import(), and TPM2_LoadExternal(). For TPM2_Import() this is only used if the new parent has
+ fixedTPM SET. For TPM2_LoadExternal(), this is not used for a public-only key */
+/* Error Returns Meaning */
+/* TPM_RC_ATTRIBUTES fixedTPM, fixedParent, or encryptedDuplication attributes are inconsistent
+ between themselves or with those of the parent object; inconsistent restricted, decrypt and sign
+ attributes; attempt to inject sensitive data for an asymmetric key; attempt to create a symmetric
+ cipher key that is not a decryption key */
+/* TPM_RC_HASH nameAlg is TPM_ALG_NULL */
+/* TPM_RC_SIZE authPolicy size does not match digest size of the name algorithm in publicArea */
+/* other returns from SchemeChecks() */
+TPM_RC
+PublicAttributesValidation(
+ OBJECT *parentObject, // IN: input parent object
+ TPMT_PUBLIC *publicArea // IN: public area of the object
+ )
+{
+ TPMA_OBJECT attributes = publicArea->objectAttributes;
+ TPMA_OBJECT parentAttributes = TPMA_ZERO_INITIALIZER();
+ //
+ if(parentObject != NULL)
+ parentAttributes = parentObject->publicArea.objectAttributes;
+ if(publicArea->nameAlg == TPM_ALG_NULL)
+ return TPM_RCS_HASH;
+ // If there is an authPolicy, it needs to be the size of the digest produced
+ // by the nameAlg of the object
+ if((publicArea->authPolicy.t.size != 0
+ && (publicArea->authPolicy.t.size
+ != CryptHashGetDigestSize(publicArea->nameAlg))))
+ return TPM_RCS_SIZE;
+ // If the parent is fixedTPM (including a Primary Object) the object must have
+ // the same value for fixedTPM and fixedParent
+ if(parentObject == NULL
+ || IS_ATTRIBUTE(parentAttributes, TPMA_OBJECT, fixedTPM))
+ {
+ if(IS_ATTRIBUTE(attributes, TPMA_OBJECT, fixedParent)
+ != IS_ATTRIBUTE(attributes, TPMA_OBJECT, fixedTPM))
+ return TPM_RCS_ATTRIBUTES;
+ }
+ else
+ {
+ // The parent is not fixedTPM so the object can't be fixedTPM
+ if(IS_ATTRIBUTE(attributes, TPMA_OBJECT, fixedTPM))
+ return TPM_RCS_ATTRIBUTES;
+ }
+ // See if sign and decrypt are the same
+ if(IS_ATTRIBUTE(attributes, TPMA_OBJECT, sign)
+ == IS_ATTRIBUTE(attributes, TPMA_OBJECT, decrypt))
+ {
+ // a restricted key cannot have both SET or both CLEAR
+ if(IS_ATTRIBUTE(attributes, TPMA_OBJECT, restricted))
+ return TPM_RC_ATTRIBUTES;
+ // only a data object may have both sign and decrypt CLEAR
+ // BTW, since we know that decrypt==sign, no need to check both
+ if(publicArea->type != TPM_ALG_KEYEDHASH
+ && !IS_ATTRIBUTE(attributes, TPMA_OBJECT, sign))
+ return TPM_RC_ATTRIBUTES;
+ }
+ // If the object can't be duplicated (directly or indirectly) then there
+ // is no justification for having encryptedDuplication SET
+ if(IS_ATTRIBUTE(attributes, TPMA_OBJECT, fixedTPM)
+ && IS_ATTRIBUTE(attributes, TPMA_OBJECT, encryptedDuplication))
+ return TPM_RCS_ATTRIBUTES;
+ // If a parent object has fixedTPM CLEAR, the child must have the
+ // same encryptedDuplication value as its parent.
+ // Primary objects are considered to have a fixedTPM parent (the seeds).
+ if(parentObject != NULL
+ && !IS_ATTRIBUTE(parentAttributes, TPMA_OBJECT, fixedTPM))
+ {
+ if(IS_ATTRIBUTE(attributes, TPMA_OBJECT, encryptedDuplication)
+ != IS_ATTRIBUTE(parentAttributes, TPMA_OBJECT, encryptedDuplication))
+ return TPM_RCS_ATTRIBUTES;
+ }
+ // Special checks for derived objects
+ if((parentObject != NULL) && (parentObject->attributes.derivation == SET))
+ {
+ // A derived object has the same settings for fixedTPM as its parent
+ if(IS_ATTRIBUTE(attributes, TPMA_OBJECT, fixedTPM)
+ != IS_ATTRIBUTE(parentAttributes, TPMA_OBJECT, fixedTPM))
+ return TPM_RCS_ATTRIBUTES;
+ // A derived object is required to be fixedParent
+ if(!IS_ATTRIBUTE(attributes, TPMA_OBJECT, fixedParent))
+ return TPM_RCS_ATTRIBUTES;
+ }
+ return SchemeChecks(parentObject, publicArea);
+}
+/* 7.6.3.6 FillInCreationData() */
+/* Fill in creation data for an object. */
+void
+FillInCreationData(
+ TPMI_DH_OBJECT parentHandle, // IN: handle of parent
+ TPMI_ALG_HASH nameHashAlg, // IN: name hash algorithm
+ TPML_PCR_SELECTION *creationPCR, // IN: PCR selection
+ TPM2B_DATA *outsideData, // IN: outside data
+ TPM2B_CREATION_DATA *outCreation, // OUT: creation data for output
+ TPM2B_DIGEST *creationDigest // OUT: creation digest
+ )
+{
+ BYTE creationBuffer[sizeof(TPMS_CREATION_DATA)];
+ BYTE *buffer;
+ HASH_STATE hashState;
+ // Fill in TPMS_CREATION_DATA in outCreation
+ // Compute PCR digest
+ PCRComputeCurrentDigest(nameHashAlg, creationPCR,
+ &outCreation->creationData.pcrDigest);
+ // Put back PCR selection list
+ outCreation->creationData.pcrSelect = *creationPCR;
+ // Get locality
+ outCreation->creationData.locality
+ = LocalityGetAttributes(_plat__LocalityGet());
+ outCreation->creationData.parentNameAlg = TPM_ALG_NULL;
+ // If the parent is either a primary seed or TPM_ALG_NULL, then the Name
+ // and QN of the parent are the parent's handle.
+ if(HandleGetType(parentHandle) == TPM_HT_PERMANENT)
+ {
+ buffer = &outCreation->creationData.parentName.t.name[0];
+ outCreation->creationData.parentName.t.size =
+ TPM_HANDLE_Marshal(&parentHandle, &buffer, NULL);
+ // For a primary or temporary object, the parent name (a handle) and the
+ // parent's QN are the same
+ outCreation->creationData.parentQualifiedName
+ = outCreation->creationData.parentName;
+ }
+ else // Regular object
+ {
+ OBJECT *parentObject = HandleToObject(parentHandle);
+ // Set name algorithm
+ outCreation->creationData.parentNameAlg =
+ parentObject->publicArea.nameAlg;
+ // Copy parent name
+ outCreation->creationData.parentName = parentObject->name;
+ // Copy parent qualified name
+ outCreation->creationData.parentQualifiedName =
+ parentObject->qualifiedName;
+ }
+ // Copy outside information
+ outCreation->creationData.outsideInfo = *outsideData;
+ // Marshal creation data to canonical form
+ buffer = creationBuffer;
+ outCreation->size = TPMS_CREATION_DATA_Marshal(&outCreation->creationData,
+ &buffer, NULL);
+ // Compute hash for creation field in public template
+ creationDigest->t.size = CryptHashStart(&hashState, nameHashAlg);
+ CryptDigestUpdate(&hashState, outCreation->size, creationBuffer);
+ CryptHashEnd2B(&hashState, &creationDigest->b);
+ return;
+}
+/* 7.6.3.7 GetSeedForKDF() */
+/* Get a seed for KDF. The KDF for encryption and HMAC key use the same seed. */
+/* Return Values Meaning */
+const TPM2B *
+GetSeedForKDF(
+ OBJECT *protector // IN: the protector handle
+ )
+{
+ // Get seed for encryption key. Use input seed if provided.
+ // Otherwise, using protector object's seedValue. TPM_RH_NULL is the only
+ // exception that we may not have a loaded object as protector. In such a
+ // case, use nullProof as seed.
+ if(protector == NULL)
+ return &gr.nullProof.b;
+ else
+ return &protector->sensitive.seedValue.b;
+}
+/* 7.6.3.8 ProduceOuterWrap() */
+/* This function produce outer wrap for a buffer containing the sensitive data. It requires the
+ sensitive data being marshaled to the outerBuffer, with the leading bytes reserved for integrity
+ hash. If iv is used, iv space should be reserved at the beginning of the buffer. It assumes the
+ sensitive data starts at address (outerBuffer + integrity size {+ iv size}). This function: */
+/* a) adds IV before sensitive area if required */
+/* b) encrypts sensitive data with IV or a NULL IV as required */
+/* c) adds HMAC integrity at the beginning of the buffer */
+/* d) returns the total size of blob with outer wrap */
+
+UINT16
+ProduceOuterWrap(
+ OBJECT *protector, // IN: The handle of the object that provides
+ // protection. For object, it is parent
+ // handle. For credential, it is the handle
+ // of encrypt object.
+ TPM2B *name, // IN: the name of the object
+ TPM_ALG_ID hashAlg, // IN: hash algorithm for outer wrap
+ TPM2B *seed, // IN: an external seed may be provided for
+ // duplication blob. For non duplication
+ // blob, this parameter should be NULL
+ BOOL useIV, // IN: indicate if an IV is used
+ UINT16 dataSize, // IN: the size of sensitive data, excluding the
+ // leading integrity buffer size or the
+ // optional iv size
+ BYTE *outerBuffer // IN/OUT: outer buffer with sensitive data in
+ // it
+ )
+{
+ TPM_ALG_ID symAlg;
+ UINT16 keyBits;
+ TPM2B_SYM_KEY symKey;
+ TPM2B_IV ivRNG; // IV from RNG
+ TPM2B_IV *iv = NULL;
+ UINT16 ivSize = 0; // size of iv area, including the size field
+ BYTE *sensitiveData; // pointer to the sensitive data
+ TPM2B_DIGEST integrity;
+ UINT16 integritySize;
+ BYTE *buffer; // Auxiliary buffer pointer
+ // Compute the beginning of sensitive data. The outer integrity should
+ // always exist if this function is called to make an outer wrap
+ integritySize = sizeof(UINT16) + CryptHashGetDigestSize(hashAlg);
+ sensitiveData = outerBuffer + integritySize;
+ // If iv is used, adjust the pointer of sensitive data and add iv before it
+ if(useIV)
+ {
+ ivSize = GetIV2BSize(protector);
+ // Generate IV from RNG. The iv data size should be the total IV area
+ // size minus the size of size field
+ ivRNG.t.size = ivSize - sizeof(UINT16);
+ CryptRandomGenerate(ivRNG.t.size, ivRNG.t.buffer);
+ // Marshal IV to buffer
+ buffer = sensitiveData;
+ TPM2B_IV_Marshal(&ivRNG, &buffer, NULL);
+ // adjust sensitive data starting after IV area
+ sensitiveData += ivSize;
+ // Use iv for encryption
+ iv = &ivRNG;
+ }
+ // Compute symmetric key parameters for outer buffer encryption
+ ComputeProtectionKeyParms(protector, hashAlg, name, seed,
+ &symAlg, &keyBits, &symKey);
+ // Encrypt inner buffer in place
+ CryptSymmetricEncrypt(sensitiveData, symAlg, keyBits,
+ symKey.t.buffer, iv, TPM_ALG_CFB, dataSize,
+ sensitiveData);
+ // Compute outer integrity. Integrity computation includes the optional IV
+ // area
+ ComputeOuterIntegrity(name, protector, hashAlg, seed, dataSize + ivSize,
+ outerBuffer + integritySize, &integrity);
+ // Add integrity at the beginning of outer buffer
+ buffer = outerBuffer;
+ TPM2B_DIGEST_Marshal(&integrity, &buffer, NULL);
+ // return the total size in outer wrap
+ return dataSize + integritySize + ivSize;
+}
+/* 7.6.3.9 UnwrapOuter() */
+/* This function remove the outer wrap of a blob containing sensitive data This function
+ performs: */
+/* a) check integrity of outer blob */
+/* b) decrypt outer blob */
+/* Error Returns Meaning */
+/* TPM_RCS_INSUFFICIENT error during sensitive data unmarshaling */
+/* TPM_RCS_INTEGRITY sensitive data integrity is broken */
+/* TPM_RCS_SIZE error during sensitive data unmarshaling */
+/* TPM_RCS_VALUE IV size for CFB does not match the encryption algorithm block size */
+TPM_RC
+UnwrapOuter(
+ OBJECT *protector, // IN: The object that provides
+ // protection. For object, it is parent
+ // handle. For credential, it is the
+ // encrypt object.
+ TPM2B *name, // IN: the name of the object
+ TPM_ALG_ID hashAlg, // IN: hash algorithm for outer wrap
+ TPM2B *seed, // IN: an external seed may be provided for
+ // duplication blob. For non duplication
+ // blob, this parameter should be NULL.
+ BOOL useIV, // IN: indicates if an IV is used
+ UINT16 dataSize, // IN: size of sensitive data in outerBuffer,
+ // including the leading integrity buffer
+ // size, and an optional iv area
+ BYTE *outerBuffer // IN/OUT: sensitive data
+ )
+{
+ TPM_RC result;
+ TPM_ALG_ID symAlg = TPM_ALG_NULL;
+ TPM2B_SYM_KEY symKey;
+ UINT16 keyBits = 0;
+ TPM2B_IV ivIn; // input IV retrieved from input buffer
+ TPM2B_IV *iv = NULL;
+ BYTE *sensitiveData; // pointer to the sensitive data
+ TPM2B_DIGEST integrityToCompare;
+ TPM2B_DIGEST integrity;
+ INT32 size;
+ // Unmarshal integrity
+ sensitiveData = outerBuffer;
+ size = (INT32)dataSize;
+ result = TPM2B_DIGEST_Unmarshal(&integrity, &sensitiveData, &size);
+ if(result == TPM_RC_SUCCESS)
+ {
+ // Compute integrity to compare
+ ComputeOuterIntegrity(name, protector, hashAlg, seed,
+ (UINT16)size, sensitiveData,
+ &integrityToCompare);
+ // Compare outer blob integrity
+ if(!MemoryEqual2B(&integrity.b, &integrityToCompare.b))
+ return TPM_RCS_INTEGRITY;
+ // Get the symmetric algorithm parameters used for encryption
+ ComputeProtectionKeyParms(protector, hashAlg, name, seed,
+ &symAlg, &keyBits, &symKey);
+ // Retrieve IV if it is used
+ if(useIV)
+ {
+ result = TPM2B_IV_Unmarshal(&ivIn, &sensitiveData, &size);
+ if(result == TPM_RC_SUCCESS)
+ {
+ // The input iv size for CFB must match the encryption algorithm
+ // block size
+ if(ivIn.t.size != CryptGetSymmetricBlockSize(symAlg, keyBits))
+ result = TPM_RC_VALUE;
+ else
+ iv = &ivIn;
+ }
+ }
+ }
+ // If no errors, decrypt private in place. Since this function uses CFB,
+ // CryptSymmetricDecrypt() will not return any errors. It may fail but it will
+ // not return an error.
+ if(result == TPM_RC_SUCCESS)
+ CryptSymmetricDecrypt(sensitiveData, symAlg, keyBits,
+ symKey.t.buffer, iv, TPM_ALG_CFB,
+ (UINT16)size, sensitiveData);
+ return result;
+}
+/* 7.6.3.10 MarshalSensitive() */
+/* This function is used to marshal a sensitive area. Among other things, it adjusts the size of the
+ authValue to be no smaller than the digest of nameAlg.
+
+ Returns the size of the marshaled area. */
+static UINT16
+MarshalSensitive(
+ BYTE *buffer, // OUT: receiving buffer
+ TPMT_SENSITIVE *sensitive, // IN: the sensitive area to marshal
+ TPMI_ALG_HASH nameAlg // IN:
+ )
+{
+ BYTE *sizeField = buffer; // saved so that size can be
+ // marshaled after it is known
+ UINT16 retVal;
+ // Pad the authValue if needed
+ MemoryPad2B(&sensitive->authValue.b, CryptHashGetDigestSize(nameAlg));
+ buffer += 2;
+ // Marshal the structure
+ retVal = TPMT_SENSITIVE_Marshal(sensitive, &buffer, NULL);
+ // Marshal the size
+ retVal = (UINT16)(retVal + UINT16_Marshal(&retVal, &sizeField, NULL));
+ return retVal;
+}
+/* 7.6.3.11 SensitiveToPrivate() */
+/* This function prepare the private blob for off the chip storage The operations in this
+ function: */
+/* a) marshal TPM2B_SENSITIVE structure into the buffer of TPM2B_PRIVATE */
+/* b) apply encryption to the sensitive area. */
+/* c) apply outer integrity computation. */
+void
+SensitiveToPrivate(
+ TPMT_SENSITIVE *sensitive, // IN: sensitive structure
+ TPM2B_NAME *name, // IN: the name of the object
+ OBJECT *parent, // IN: The parent object
+ TPM_ALG_ID nameAlg, // IN: hash algorithm in public area. This
+ // parameter is used when parentHandle is
+ // NULL, in which case the object is
+ // temporary.
+ TPM2B_PRIVATE *outPrivate // OUT: output private structure
+ )
+{
+ BYTE *sensitiveData; // pointer to the sensitive data
+ UINT16 dataSize; // data blob size
+ TPMI_ALG_HASH hashAlg; // hash algorithm for integrity
+ UINT16 integritySize;
+ UINT16 ivSize;
+ //
+ pAssert(name != NULL && name->t.size != 0);
+ // Find the hash algorithm for integrity computation
+ if(parent == NULL)
+ {
+ // For Temporary Object, using self name algorithm
+ hashAlg = nameAlg;
+ }
+ else
+ {
+ // Otherwise, using parent's name algorithm
+ hashAlg = parent->publicArea.nameAlg;
+ }
+ // Starting of sensitive data without wrappers
+ sensitiveData = outPrivate->t.buffer;
+ // Compute the integrity size
+ integritySize = sizeof(UINT16) + CryptHashGetDigestSize(hashAlg);
+ // Reserve space for integrity
+ sensitiveData += integritySize;
+ // Get iv size
+ ivSize = GetIV2BSize(parent);
+ // Reserve space for iv
+ sensitiveData += ivSize;
+ // Marshal the sensitive area including authValue size adjustments.
+ dataSize = MarshalSensitive(sensitiveData, sensitive, nameAlg);
+ //Produce outer wrap, including encryption and HMAC
+ outPrivate->t.size = ProduceOuterWrap(parent, &name->b, hashAlg, NULL,
+ TRUE, dataSize, outPrivate->t.buffer);
+ return;
+}
+/* 7.6.3.12 PrivateToSensitive() */
+/* Unwrap an input private area. Check the integrity, decrypt and retrieve data to a sensitive
+ structure. The operations in this function: */
+/* a) check the integrity HMAC of the input private area */
+/* b) decrypt the private buffer */
+/* c) unmarshal TPMT_SENSITIVE structure into the buffer of TPMT_SENSITIVE */
+/* Error Returns Meaning */
+/* TPM_RCS_INTEGRITY if the private area integrity is bad */
+/* TPM_RC_SENSITIVE unmarshal errors while unmarshaling TPMS_ENCRYPT from input private */
+/* TPM_RCS_SIZE error during sensitive data unmarshaling */
+/* TPM_RCS_VALUE outer wrapper does not have an iV of the correct size */
+TPM_RC
+PrivateToSensitive(
+ TPM2B *inPrivate, // IN: input private structure
+ TPM2B *name, // IN: the name of the object
+ OBJECT *parent, // IN: parent object
+ TPM_ALG_ID nameAlg, // IN: hash algorithm in public area. It is
+ // passed separately because we only pass
+ // name, rather than the whole public area
+ // of the object. This parameter is used in
+ // the following two cases: 1. primary
+ // objects. 2. duplication blob with inner
+ // wrap. In other cases, this parameter
+ // will be ignored
+ TPMT_SENSITIVE *sensitive // OUT: sensitive structure
+ )
+{
+ TPM_RC result;
+ BYTE *buffer;
+ INT32 size;
+ BYTE *sensitiveData; // pointer to the sensitive data
+ UINT16 dataSize;
+ UINT16 dataSizeInput;
+ TPMI_ALG_HASH hashAlg; // hash algorithm for integrity
+ UINT16 integritySize;
+ UINT16 ivSize;
+ //
+ // Make sure that name is provided
+ pAssert(name != NULL && name->size != 0);
+ // Find the hash algorithm for integrity computation
+ if(parent == NULL)
+ {
+ // For Temporary Object, using self name algorithm
+ hashAlg = nameAlg;
+ }
+ else
+ {
+ // Otherwise, using parent's name algorithm
+ hashAlg = parent->publicArea.nameAlg;
+ }
+ // unwrap outer
+ result = UnwrapOuter(parent, name, hashAlg, NULL, TRUE,
+ inPrivate->size, inPrivate->buffer);
+ if(result != TPM_RC_SUCCESS)
+ return result;
+ // Compute the inner integrity size.
+ integritySize = sizeof(UINT16) + CryptHashGetDigestSize(hashAlg);
+ // Get iv size
+ ivSize = GetIV2BSize(parent);
+ // The starting of sensitive data and data size without outer wrapper
+ sensitiveData = inPrivate->buffer + integritySize + ivSize;
+ dataSize = inPrivate->size - integritySize - ivSize;
+ // Unmarshal input data size
+ buffer = sensitiveData;
+ size = (INT32)dataSize;
+ result = UINT16_Unmarshal(&dataSizeInput, &buffer, &size);
+ if(result == TPM_RC_SUCCESS)
+ {
+ if((dataSizeInput + sizeof(UINT16)) != dataSize)
+ result = TPM_RC_SENSITIVE;
+ else
+ {
+ // Unmarshal sensitive buffer to sensitive structure
+ result = TPMT_SENSITIVE_Unmarshal(sensitive, &buffer, &size);
+ if(result != TPM_RC_SUCCESS || size != 0)
+ {
+ result = TPM_RC_SENSITIVE;
+ }
+ }
+ }
+ return result;
+}
+/* 7.6.3.13 SensitiveToDuplicate() */
+/* This function prepare the duplication blob from the sensitive area. The operations in this
+ function: */
+/* a) marshal TPMT_SENSITIVE structure into the buffer of TPM2B_PRIVATE */
+/* b) apply inner wrap to the sensitive area if required */
+/* c) apply outer wrap if required */
+void
+SensitiveToDuplicate(
+ TPMT_SENSITIVE *sensitive, // IN: sensitive structure
+ TPM2B *name, // IN: the name of the object
+ OBJECT *parent, // IN: The new parent object
+ TPM_ALG_ID nameAlg, // IN: hash algorithm in public area. It
+ // is passed separately because we
+ // only pass name, rather than the
+ // whole public area of the object.
+ TPM2B *seed, // IN: the external seed. If external
+ // seed is provided with size of 0,
+ // no outer wrap should be applied
+ // to duplication blob.
+ TPMT_SYM_DEF_OBJECT *symDef, // IN: Symmetric key definition. If the
+ // symmetric key algorithm is NULL,
+ // no inner wrap should be applied.
+ TPM2B_DATA *innerSymKey, // IN/OUT: a symmetric key may be
+ // provided to encrypt the inner
+ // wrap of a duplication blob. May
+ // be generated here if needed.
+ TPM2B_PRIVATE *outPrivate // OUT: output private structure
+ )
+{
+ BYTE *sensitiveData; // pointer to the sensitive data
+ TPMI_ALG_HASH outerHash = TPM_ALG_NULL;// The hash algorithm for outer wrap
+ TPMI_ALG_HASH innerHash = TPM_ALG_NULL;// The hash algorithm for inner wrap
+ UINT16 dataSize; // data blob size
+ BOOL doInnerWrap = FALSE;
+ BOOL doOuterWrap = FALSE;
+ //
+ // Make sure that name is provided
+ pAssert(name != NULL && name->size != 0);
+ // Make sure symDef and innerSymKey are not NULL
+ pAssert(symDef != NULL && innerSymKey != NULL);
+ // Starting of sensitive data without wrappers
+ sensitiveData = outPrivate->t.buffer;
+ // Find out if inner wrap is required
+ if(symDef->algorithm != TPM_ALG_NULL)
+ {
+ doInnerWrap = TRUE;
+ // Use self nameAlg as inner hash algorithm
+ innerHash = nameAlg;
+ // Adjust sensitive data pointer
+ sensitiveData += sizeof(UINT16) + CryptHashGetDigestSize(innerHash);
+ }
+ // Find out if outer wrap is required
+ if(seed->size != 0)
+ {
+ doOuterWrap = TRUE;
+ // Use parent nameAlg as outer hash algorithm
+ outerHash = parent->publicArea.nameAlg;
+ // Adjust sensitive data pointer
+ sensitiveData += sizeof(UINT16) + CryptHashGetDigestSize(outerHash);
+ }
+ // Marshal sensitive area
+ dataSize = MarshalSensitive(sensitiveData, sensitive, nameAlg);
+ // Apply inner wrap for duplication blob. It includes both integrity and
+ // encryption
+ if(doInnerWrap)
+ {
+ BYTE *innerBuffer = NULL;
+ BOOL symKeyInput = TRUE;
+ innerBuffer = outPrivate->t.buffer;
+ // Skip outer integrity space
+ if(doOuterWrap)
+ innerBuffer += sizeof(UINT16) + CryptHashGetDigestSize(outerHash);
+ dataSize = ProduceInnerIntegrity(name, innerHash, dataSize,
+ innerBuffer);
+ // Generate inner encryption key if needed
+ if(innerSymKey->t.size == 0)
+ {
+ innerSymKey->t.size = (symDef->keyBits.sym + 7) / 8;
+ CryptRandomGenerate(innerSymKey->t.size, innerSymKey->t.buffer);
+ // TPM generates symmetric encryption. Set the flag to FALSE
+ symKeyInput = FALSE;
+ }
+ else
+ {
+ // assume the input key size should matches the symmetric definition
+ pAssert(innerSymKey->t.size == (symDef->keyBits.sym + 7) / 8);
+ }
+ // Encrypt inner buffer in place
+ CryptSymmetricEncrypt(innerBuffer, symDef->algorithm,
+ symDef->keyBits.sym, innerSymKey->t.buffer, NULL,
+ TPM_ALG_CFB, dataSize, innerBuffer);
+ // If the symmetric encryption key is imported, clear the buffer for
+ // output
+ if(symKeyInput)
+ innerSymKey->t.size = 0;
+ }
+ // Apply outer wrap for duplication blob. It includes both integrity and
+ // encryption
+ if(doOuterWrap)
+ {
+ dataSize = ProduceOuterWrap(parent, name, outerHash, seed, FALSE,
+ dataSize, outPrivate->t.buffer);
+ }
+ // Data size for output
+ outPrivate->t.size = dataSize;
+ return;
+}
+/* 7.6.3.14 DuplicateToSensitive() */
+/* Unwrap a duplication blob. Check the integrity, decrypt and retrieve data to a sensitive
+ structure. The operations in this function: */
+/* a) check the integrity HMAC of the input private area */
+/* b) decrypt the private buffer */
+/* c) unmarshal TPMT_SENSITIVE structure into the buffer of TPMT_SENSITIVE */
+/* Error Returns Meaning */
+/* TPM_RC_INSUFFICIENT unmarshaling sensitive data from inPrivate failed */
+/* TPM_RC_INTEGRITY inPrivate data integrity is broken */
+/* TPM_RC_SIZE unmarshaling sensitive data from inPrivate failed */
+TPM_RC
+DuplicateToSensitive(
+ TPM2B *inPrivate, // IN: input private structure
+ TPM2B *name, // IN: the name of the object
+ OBJECT *parent, // IN: the parent
+ TPM_ALG_ID nameAlg, // IN: hash algorithm in public area.
+ TPM2B *seed, // IN: an external seed may be provided.
+ // If external seed is provided with
+ // size of 0, no outer wrap is
+ // applied
+ TPMT_SYM_DEF_OBJECT *symDef, // IN: Symmetric key definition. If the
+ // symmetric key algorithm is NULL,
+ // no inner wrap is applied
+ TPM2B *innerSymKey, // IN: a symmetric key may be provided
+ // to decrypt the inner wrap of a
+ // duplication blob.
+ TPMT_SENSITIVE *sensitive // OUT: sensitive structure
+ )
+{
+ TPM_RC result;
+ BYTE *buffer;
+ INT32 size;
+ BYTE *sensitiveData; // pointer to the sensitive data
+ UINT16 dataSize;
+ UINT16 dataSizeInput;
+ // Make sure that name is provided
+ pAssert(name != NULL && name->size != 0);
+ // Make sure symDef and innerSymKey are not NULL
+ pAssert(symDef != NULL && innerSymKey != NULL);
+ // Starting of sensitive data
+ sensitiveData = inPrivate->buffer;
+ dataSize = inPrivate->size;
+ // Find out if outer wrap is applied
+ if(seed->size != 0)
+ {
+ // Use parent nameAlg as outer hash algorithm
+ TPMI_ALG_HASH outerHash = parent->publicArea.nameAlg;
+ result = UnwrapOuter(parent, name, outerHash, seed, FALSE,
+ dataSize, sensitiveData);
+ if(result != TPM_RC_SUCCESS)
+ return result;
+ // Adjust sensitive data pointer and size
+ sensitiveData += sizeof(UINT16) + CryptHashGetDigestSize(outerHash);
+ dataSize -= sizeof(UINT16) + CryptHashGetDigestSize(outerHash);
+ }
+ // Find out if inner wrap is applied
+ if(symDef->algorithm != TPM_ALG_NULL)
+ {
+ // assume the input key size matches the symmetric definition
+ pAssert(innerSymKey->size == (symDef->keyBits.sym + 7) / 8);
+ // Decrypt inner buffer in place
+ CryptSymmetricDecrypt(sensitiveData, symDef->algorithm,
+ symDef->keyBits.sym, innerSymKey->buffer, NULL,
+ TPM_ALG_CFB, dataSize, sensitiveData);
+ // Check inner integrity
+ result = CheckInnerIntegrity(name, nameAlg, dataSize, sensitiveData);
+ if(result != TPM_RC_SUCCESS)
+ return result;
+ // Adjust sensitive data pointer and size
+ sensitiveData += sizeof(UINT16) + CryptHashGetDigestSize(nameAlg);
+ dataSize -= sizeof(UINT16) + CryptHashGetDigestSize(nameAlg);
+ }
+ // Unmarshal input data size
+ buffer = sensitiveData;
+ size = (INT32)dataSize;
+ result = UINT16_Unmarshal(&dataSizeInput, &buffer, &size);
+ if(result == TPM_RC_SUCCESS)
+ {
+ if((dataSizeInput + sizeof(UINT16)) != dataSize)
+ result = TPM_RC_SIZE;
+ else
+ {
+ // Unmarshal sensitive buffer to sensitive structure
+ result = TPMT_SENSITIVE_Unmarshal(sensitive, &buffer, &size);
+ // if the results is OK make sure that all the data was unmarshaled
+ if(result == TPM_RC_SUCCESS && size != 0)
+ result = TPM_RC_SIZE;
+ }
+ }
+ return result;
+}
+/* 7.6.3.15 SecretToCredential() */
+/* This function prepare the credential blob from a secret (a TPM2B_DIGEST) The operations in this
+ function: */
+/* a) marshal TPM2B_DIGEST structure into the buffer of TPM2B_ID_OBJECT */
+/* b) encrypt the private buffer, excluding the leading integrity HMAC area */
+/* c) compute integrity HMAC and append to the beginning of the buffer. */
+/* d) Set the total size of TPM2B_ID_OBJECT buffer */
+void
+SecretToCredential(
+ TPM2B_DIGEST *secret, // IN: secret information
+ TPM2B *name, // IN: the name of the object
+ TPM2B *seed, // IN: an external seed.
+ OBJECT *protector, // IN: the protector
+ TPM2B_ID_OBJECT *outIDObject // OUT: output credential
+ )
+{
+ BYTE *buffer; // Auxiliary buffer pointer
+ BYTE *sensitiveData; // pointer to the sensitive data
+ TPMI_ALG_HASH outerHash; // The hash algorithm for outer wrap
+ UINT16 dataSize; // data blob size
+ pAssert(secret != NULL && outIDObject != NULL);
+ // use protector's name algorithm as outer hash
+ outerHash = protector->publicArea.nameAlg;
+ // Marshal secret area to credential buffer, leave space for integrity
+ sensitiveData = outIDObject->t.credential
+ + sizeof(UINT16) + CryptHashGetDigestSize(outerHash);
+ // Marshal secret area
+ buffer = sensitiveData;
+ dataSize = TPM2B_DIGEST_Marshal(secret, &buffer, NULL);
+ // Apply outer wrap
+ outIDObject->t.size = ProduceOuterWrap(protector, name, outerHash, seed, FALSE,
+ dataSize, outIDObject->t.credential);
+ return;
+}
+/* 7.6.3.16 CredentialToSecret() */
+/* Unwrap a credential. Check the integrity, decrypt and retrieve data to a TPM2B_DIGEST
+ structure. The operations in this function: */
+/* a) check the integrity HMAC of the input credential area */
+/* b) decrypt the credential buffer */
+/* c) unmarshal TPM2B_DIGEST structure into the buffer of TPM2B_DIGEST */
+/* Error Returns Meaning */
+/* TPM_RC_INSUFFICIENT error during credential unmarshaling */
+/* TPM_RC_INTEGRITY credential integrity is broken */
+/* TPM_RC_SIZE error during credential unmarshaling */
+/* TPM_RC_VALUE IV size does not match the encryption algorithm block size */
+TPM_RC
+CredentialToSecret(
+ TPM2B *inIDObject, // IN: input credential blob
+ TPM2B *name, // IN: the name of the object
+ TPM2B *seed, // IN: an external seed.
+ OBJECT *protector, // IN: the protector
+ TPM2B_DIGEST *secret // OUT: secret information
+ )
+{
+ TPM_RC result;
+ BYTE *buffer;
+ INT32 size;
+ TPMI_ALG_HASH outerHash; // The hash algorithm for outer wrap
+ BYTE *sensitiveData; // pointer to the sensitive data
+ UINT16 dataSize;
+ // use protector's name algorithm as outer hash
+ outerHash = protector->publicArea.nameAlg;
+ // Unwrap outer, a TPM_RC_INTEGRITY error may be returned at this point
+ result = UnwrapOuter(protector, name, outerHash, seed, FALSE,
+ inIDObject->size, inIDObject->buffer);
+ if(result == TPM_RC_SUCCESS)
+ {
+ // Compute the beginning of sensitive data
+ sensitiveData = inIDObject->buffer
+ + sizeof(UINT16) + CryptHashGetDigestSize(outerHash);
+ dataSize = inIDObject->size
+ - (sizeof(UINT16) + CryptHashGetDigestSize(outerHash));
+ // Unmarshal secret buffer to TPM2B_DIGEST structure
+ buffer = sensitiveData;
+ size = (INT32)dataSize;
+ result = TPM2B_DIGEST_Unmarshal(secret, &buffer, &size);
+ // If there were no other unmarshaling errors, make sure that the
+ // expected amount of data was recovered
+ if(result == TPM_RC_SUCCESS && size != 0)
+ return TPM_RC_SIZE;
+ }
+ return result;
+}
+/* 7.6.3.17 MemoryRemoveTrailingZeros() */
+/* This function is used to adjust the length of an authorization value. It adjusts the size of the
+ TPM2B so that it does not include octets at the end of the buffer that contain zero. The function
+ returns the number of non-zero octets in the buffer. */
+UINT16
+MemoryRemoveTrailingZeros(
+ TPM2B_AUTH *auth // IN/OUT: value to adjust
+ )
+{
+ while((auth->t.size > 0) && (auth->t.buffer[auth->t.size - 1] == 0))
+ auth->t.size--;
+ return auth->t.size;
+}
+/* 7.6.3.18 SetLabelAndContext() */
+/* This function sets the label and context for a derived key. It is possible that label or context
+ can end up being an Empty Buffer. */
+TPM_RC
+SetLabelAndContext(
+ TPMS_DERIVE *labelContext, // IN/OUT: the recovered label and context
+ TPM2B_SENSITIVE_DATA *sensitive // IN: the sensitive data
+ )
+{
+ TPMS_DERIVE sensitiveValue;
+ TPM_RC result;
+ INT32 size;
+ BYTE *buff;
+ //
+ // Unmarshal a TPMS_DERIVE from the TPM2B_SENSITIVE_DATA buffer
+ // If there is something to unmarshal...
+ if(sensitive->t.size != 0)
+ {
+ size = sensitive->t.size;
+ buff = sensitive->t.buffer;
+ result = TPMS_DERIVE_Unmarshal(&sensitiveValue, &buff, &size);
+ if(result != TPM_RC_SUCCESS)
+ return result;
+ // If there was a label in the public area leave it there, otherwise, copy
+ // the new value
+ if(labelContext->label.t.size == 0)
+ MemoryCopy2B(&labelContext->label.b, &sensitiveValue.label.b,
+ sizeof(labelContext->label.t.buffer));
+ // if there was a context string in publicArea, it overrides
+ if(labelContext->context.t.size == 0)
+ MemoryCopy2B(&labelContext->context.b, &sensitiveValue.context.b,
+ sizeof(labelContext->label.t.buffer));
+ }
+ return TPM_RC_SUCCESS;
+}
+/* 7.6.3.19 UnmarshalToPublic() */
+/* Support function to unmarshal the template. This is used because the Input may be a TPMT_TEMPLATE
+ and that structure does not have the same size as a TPMT_PUBLIC() because of the difference
+ between the unique and seed fields. If derive is not NULL, then the seed field is assumed to
+ contain a label and context that are unmarshaled into derive. */
+TPM_RC
+UnmarshalToPublic(
+ TPMT_PUBLIC *tOut, // OUT: output
+ TPM2B_TEMPLATE *tIn, // IN:
+ BOOL derivation, // IN: indicates if this is for a derivation
+ TPMS_DERIVE *labelContext // OUT: label and context if derivation
+ )
+{
+ BYTE *buffer = tIn->t.buffer;
+ INT32 size = tIn->t.size;
+ TPM_RC result;
+ //
+ // make sure that tOut is zeroed so that there are no remnants from previous
+ // uses
+ MemorySet(tOut, 0, sizeof(TPMT_PUBLIC));
+ // Unmarshal the components of the TPMT_PUBLIC up to the unique field
+ result = TPMI_ALG_PUBLIC_Unmarshal(&tOut->type, &buffer, &size);
+ if(result != TPM_RC_SUCCESS)
+ return result;
+ result = TPMI_ALG_HASH_Unmarshal(&tOut->nameAlg, &buffer, &size, FALSE);
+ if(result != TPM_RC_SUCCESS)
+ return result;
+ result = TPMA_OBJECT_Unmarshal(&tOut->objectAttributes, &buffer, &size);
+ if(result != TPM_RC_SUCCESS)
+ return result;
+ result = TPM2B_DIGEST_Unmarshal(&tOut->authPolicy, &buffer, &size);
+ if(result != TPM_RC_SUCCESS)
+ return result;
+ result = TPMU_PUBLIC_PARMS_Unmarshal(&tOut->parameters, &buffer, &size,
+ tOut->type);
+ if(result != TPM_RC_SUCCESS)
+ return result;
+ // Now unmarshal a TPMS_DERIVE if this is for derivation
+ if(derivation)
+ result = TPMS_DERIVE_Unmarshal(labelContext, &buffer, &size);
+ else
+ // otherwise, unmarshal a TPMU_PUBLIC_ID
+ result = TPMU_PUBLIC_ID_Unmarshal(&tOut->unique, &buffer, &size,
+ tOut->type);
+ // Make sure the template was used up
+ if((result == TPM_RC_SUCCESS) && (size != 0))
+ result = TPM_RC_SIZE;
+ return result;
+}
+#if 0 /* libtpms added */
+/* 7.6.3.20 ObjectSetExternal() */
+/* Set the external attributes for an object. */
+void
+ObjectSetExternal(
+ OBJECT *object
+ )
+{
+ object->attributes.external = SET;
+}
+#endif /* libtpms added */
diff --git a/src/tpm2/Object_spt_fp.h b/src/tpm2/Object_spt_fp.h
new file mode 100644
index 0000000..16e1d92
--- /dev/null
+++ b/src/tpm2/Object_spt_fp.h
@@ -0,0 +1,250 @@
+/********************************************************************************/
+/* */
+/* Object Command Support */
+/* Written by Ken Goldman */
+/* IBM Thomas J. Watson Research Center */
+/* $Id: Object_spt_fp.h 1490 2019-07-26 21:13:22Z kgoldman $ */
+/* */
+/* Licenses and Notices */
+/* */
+/* 1. Copyright Licenses: */
+/* */
+/* - Trusted Computing Group (TCG) grants to the user of the source code in */
+/* this specification (the "Source Code") a worldwide, irrevocable, */
+/* nonexclusive, royalty free, copyright license to reproduce, create */
+/* derivative works, distribute, display and perform the Source Code and */
+/* derivative works thereof, and to grant others the rights granted herein. */
+/* */
+/* - The TCG grants to the user of the other parts of the specification */
+/* (other than the Source Code) the rights to reproduce, distribute, */
+/* display, and perform the specification solely for the purpose of */
+/* developing products based on such documents. */
+/* */
+/* 2. Source Code Distribution Conditions: */
+/* */
+/* - Redistributions of Source Code must retain the above copyright licenses, */
+/* this list of conditions and the following disclaimers. */
+/* */
+/* - Redistributions in binary form must reproduce the above copyright */
+/* licenses, this list of conditions and the following disclaimers in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* 3. Disclaimers: */
+/* */
+/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
+/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
+/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
+/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
+/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
+/* information on specification licensing rights available through TCG */
+/* membership agreements. */
+/* */
+/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
+/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
+/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
+/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
+/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
+/* */
+/* - Without limitation, TCG and its members and licensors disclaim all */
+/* liability, including liability for infringement of any proprietary */
+/* rights, relating to use of information in this specification and to the */
+/* implementation of this specification, and TCG disclaims all liability for */
+/* cost of procurement of substitute goods or services, lost profits, loss */
+/* of use, loss of data or any incidental, consequential, direct, indirect, */
+/* or special damages, whether under contract, tort, warranty or otherwise, */
+/* arising in any way out of use or reliance upon this specification or any */
+/* information herein. */
+/* */
+/* (c) Copyright IBM Corp. and others, 2016 - 2019 */
+/* */
+/********************************************************************************/
+
+#ifndef OBJECT_SPT_FP_H
+#define OBJECT_SPT_FP_H
+
+BOOL
+AdjustAuthSize(
+ TPM2B_AUTH *auth, // IN/OUT: value to adjust
+ TPMI_ALG_HASH nameAlg // IN:
+ );
+BOOL
+ObjectIsParent(
+ OBJECT *parentObject // IN: parent handle
+ );
+TPM_RC
+CreateChecks(
+ OBJECT *parentObject,
+ TPMT_PUBLIC *publicArea,
+ UINT16 sensitiveDataSize
+ );
+TPM_RC
+SchemeChecks(
+ OBJECT *parentObject, // IN: parent (null if primary seed)
+ TPMT_PUBLIC *publicArea // IN: public area of the object
+ );
+TPM_RC
+PublicAttributesValidation(
+ OBJECT *parentObject, // IN: input parent object
+ TPMT_PUBLIC *publicArea // IN: public area of the object
+ );
+void
+FillInCreationData(
+ TPMI_DH_OBJECT parentHandle, // IN: handle of parent
+ TPMI_ALG_HASH nameHashAlg, // IN: name hash algorithm
+ TPML_PCR_SELECTION *creationPCR, // IN: PCR selection
+ TPM2B_DATA *outsideData, // IN: outside data
+ TPM2B_CREATION_DATA *outCreation, // OUT: creation data for output
+ TPM2B_DIGEST *creationDigest // OUT: creation digest
+ );
+const TPM2B *
+GetSeedForKDF(
+ OBJECT *protector // IN: the protector handle
+ );
+UINT16
+ProduceOuterWrap(
+ OBJECT *protector, // IN: The handle of the object that provides
+ // protection. For object, it is parent
+ // handle. For credential, it is the handle
+ // of encrypt object.
+ TPM2B *name, // IN: the name of the object
+ TPM_ALG_ID hashAlg, // IN: hash algorithm for outer wrap
+ TPM2B *seed, // IN: an external seed may be provided for
+ // duplication blob. For non duplication
+ // blob, this parameter should be NULL
+ BOOL useIV, // IN: indicate if an IV is used
+ UINT16 dataSize, // IN: the size of sensitive data, excluding the
+ // leading integrity buffer size or the
+ // optional iv size
+ BYTE *outerBuffer // IN/OUT: outer buffer with sensitive data in
+ // it
+ );
+TPM_RC
+UnwrapOuter(
+ OBJECT *protector, // IN: The object that provides
+ // protection. For object, it is parent
+ // handle. For credential, it is the
+ // encrypt object.
+ TPM2B *name, // IN: the name of the object
+ TPM_ALG_ID hashAlg, // IN: hash algorithm for outer wrap
+ TPM2B *seed, // IN: an external seed may be provided for
+ // duplication blob. For non duplication
+ // blob, this parameter should be NULL.
+ BOOL useIV, // IN: indicates if an IV is used
+ UINT16 dataSize, // IN: size of sensitive data in outerBuffer,
+ // including the leading integrity buffer
+ // size, and an optional iv area
+ BYTE *outerBuffer // IN/OUT: sensitive data
+ );
+void
+SensitiveToPrivate(
+ TPMT_SENSITIVE *sensitive, // IN: sensitive structure
+ TPM2B_NAME *name, // IN: the name of the object
+ OBJECT *parent, // IN: The parent object
+ TPM_ALG_ID nameAlg, // IN: hash algorithm in public area. This
+ // parameter is used when parentHandle is
+ // NULL, in which case the object is
+ // temporary.
+ TPM2B_PRIVATE *outPrivate // OUT: output private structure
+ );
+TPM_RC
+PrivateToSensitive(
+ TPM2B *inPrivate, // IN: input private structure
+ TPM2B *name, // IN: the name of the object
+ OBJECT *parent, // IN: parent object
+ TPM_ALG_ID nameAlg, // IN: hash algorithm in public area. It is
+ // passed separately because we only pass
+ // name, rather than the whole public area
+ // of the object. This parameter is used in
+ // the following two cases: 1. primary
+ // objects. 2. duplication blob with inner
+ // wrap. In other cases, this parameter
+ // will be ignored
+ TPMT_SENSITIVE *sensitive // OUT: sensitive structure
+ );
+void
+SensitiveToDuplicate(
+ TPMT_SENSITIVE *sensitive, // IN: sensitive structure
+ TPM2B *name, // IN: the name of the object
+ OBJECT *parent, // IN: The new parent object
+ TPM_ALG_ID nameAlg, // IN: hash algorithm in public area. It
+ // is passed separately because we
+ // only pass name, rather than the
+ // whole public area of the object.
+ TPM2B *seed, // IN: the external seed. If external
+ // seed is provided with size of 0,
+ // no outer wrap should be applied
+ // to duplication blob.
+ TPMT_SYM_DEF_OBJECT *symDef, // IN: Symmetric key definition. If the
+ // symmetric key algorithm is NULL,
+ // no inner wrap should be applied.
+ TPM2B_DATA *innerSymKey, // IN/OUT: a symmetric key may be
+ // provided to encrypt the inner
+ // wrap of a duplication blob. May
+ // be generated here if needed.
+ TPM2B_PRIVATE *outPrivate // OUT: output private structure
+ );
+TPM_RC
+DuplicateToSensitive(
+ TPM2B *inPrivate, // IN: input private structure
+ TPM2B *name, // IN: the name of the object
+ OBJECT *parent, // IN: the parent
+ TPM_ALG_ID nameAlg, // IN: hash algorithm in public area.
+ TPM2B *seed, // IN: an external seed may be provided.
+ // If external seed is provided with
+ // size of 0, no outer wrap is
+ // applied
+ TPMT_SYM_DEF_OBJECT *symDef, // IN: Symmetric key definition. If the
+ // symmetric key algorithm is NULL,
+ // no inner wrap is applied
+ TPM2B *innerSymKey, // IN: a symmetric key may be provided
+ // to decrypt the inner wrap of a
+ // duplication blob.
+ TPMT_SENSITIVE *sensitive // OUT: sensitive structure
+ );
+void
+SecretToCredential(
+ TPM2B_DIGEST *secret, // IN: secret information
+ TPM2B *name, // IN: the name of the object
+ TPM2B *seed, // IN: an external seed.
+ OBJECT *protector, // IN: the protector
+ TPM2B_ID_OBJECT *outIDObject // OUT: output credential
+ );
+TPM_RC
+CredentialToSecret(
+ TPM2B *inIDObject, // IN: input credential blob
+ TPM2B *name, // IN: the name of the object
+ TPM2B *seed, // IN: an external seed.
+ OBJECT *protector, // IN: the protector
+ TPM2B_DIGEST *secret // OUT: secret information
+ );
+UINT16
+MemoryRemoveTrailingZeros(
+ TPM2B_AUTH *auth // IN/OUT: value to adjust
+ );
+TPM_RC
+SetLabelAndContext(
+ TPMS_DERIVE *labelContext, // OUT: the recovered label and context
+ TPM2B_SENSITIVE_DATA *sensitive // IN: the sensitive data
+ );
+TPM_RC
+UnmarshalToPublic(
+ TPMT_PUBLIC *tOut, // OUT: output
+ TPM2B_TEMPLATE *tIn, // IN:
+ BOOL derivation, // IN: indicates if this is for a derivation
+ TPMS_DERIVE *labelContext // OUT: label and context if derivation
+ );
+void
+ObjectSetHierarchy(
+ OBJECT *object,
+ TPM_HANDLE parentHandle,
+ OBJECT *parent
+ );
+#if 0 /* libtpms added */
+void
+ObjectSetExternal(
+ OBJECT *object
+ );
+#endif /* libtpms added */
+
+
+#endif
diff --git a/src/tpm2/PCR.c b/src/tpm2/PCR.c
new file mode 100644
index 0000000..464d9c0
--- /dev/null
+++ b/src/tpm2/PCR.c
@@ -0,0 +1,1185 @@
+/********************************************************************************/
+/* */
+/* PCR access and manipulation */
+/* Written by Ken Goldman */
+/* IBM Thomas J. Watson Research Center */
+/* $Id: PCR.c 1658 2021-01-22 23:14:01Z kgoldman $ */
+/* */
+/* Licenses and Notices */
+/* */
+/* 1. Copyright Licenses: */
+/* */
+/* - Trusted Computing Group (TCG) grants to the user of the source code in */
+/* this specification (the "Source Code") a worldwide, irrevocable, */
+/* nonexclusive, royalty free, copyright license to reproduce, create */
+/* derivative works, distribute, display and perform the Source Code and */
+/* derivative works thereof, and to grant others the rights granted herein. */
+/* */
+/* - The TCG grants to the user of the other parts of the specification */
+/* (other than the Source Code) the rights to reproduce, distribute, */
+/* display, and perform the specification solely for the purpose of */
+/* developing products based on such documents. */
+/* */
+/* 2. Source Code Distribution Conditions: */
+/* */
+/* - Redistributions of Source Code must retain the above copyright licenses, */
+/* this list of conditions and the following disclaimers. */
+/* */
+/* - Redistributions in binary form must reproduce the above copyright */
+/* licenses, this list of conditions and the following disclaimers in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* 3. Disclaimers: */
+/* */
+/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
+/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
+/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
+/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
+/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
+/* information on specification licensing rights available through TCG */
+/* membership agreements. */
+/* */
+/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
+/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
+/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
+/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
+/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
+/* */
+/* - Without limitation, TCG and its members and licensors disclaim all */
+/* liability, including liability for infringement of any proprietary */
+/* rights, relating to use of information in this specification and to the */
+/* implementation of this specification, and TCG disclaims all liability for */
+/* cost of procurement of substitute goods or services, lost profits, loss */
+/* of use, loss of data or any incidental, consequential, direct, indirect, */
+/* or special damages, whether under contract, tort, warranty or otherwise, */
+/* arising in any way out of use or reliance upon this specification or any */
+/* information herein. */
+/* */
+/* (c) Copyright IBM Corp. and others, 2016 - 2021 */
+/* */
+/********************************************************************************/
+
+/* 8.7 PCR.c */
+/* 8.7.1 Introduction */
+/* This function contains the functions needed for PCR access and manipulation. */
+/* This implementation uses a static allocation for the PCR. The amount of memory is allocated based
+ on the number of PCR in the implementation and the number of implemented hash algorithms. This is
+ not the expected implementation. PCR SPACE DEFINITIONS. */
+/* In the definitions below, the g_hashPcrMap is a bit array that indicates which of the PCR are
+ implemented. The g_hashPcr array is an array of digests. In this implementation, the space is
+ allocated whether the PCR is implemented or not. */
+/* 8.7.2 Includes, Defines, and Data Definitions */
+#define PCR_C
+#include "Tpm.h"
+/* The initial value of PCR attributes. The value of these fields should be consistent with PC
+ Client specification In this implementation, we assume the total number of implemented PCR is
+ 24. */
+static const PCR_Attributes s_initAttributes[] =
+ {
+ // PCR 0 - 15, static RTM
+ {1, 0, 0x1F}, {1, 0, 0x1F}, {1, 0, 0x1F}, {1, 0, 0x1F},
+ {1, 0, 0x1F}, {1, 0, 0x1F}, {1, 0, 0x1F}, {1, 0, 0x1F},
+ {1, 0, 0x1F}, {1, 0, 0x1F}, {1, 0, 0x1F}, {1, 0, 0x1F},
+ {1, 0, 0x1F}, {1, 0, 0x1F}, {1, 0, 0x1F}, {1, 0, 0x1F},
+ {0, 0x0F, 0x1F}, // PCR 16, Debug
+ {0, 0x10, 0x1C}, // PCR 17, Locality 4
+ {0, 0x10, 0x1C}, // PCR 18, Locality 3
+ {0, 0x10, 0x0C}, // PCR 19, Locality 2
+ {0, 0x14, 0x0E}, // PCR 20, Locality 1
+ {0, 0x14, 0x04}, // PCR 21, Dynamic OS
+ {0, 0x14, 0x04}, // PCR 22, Dynamic OS
+ {0, 0x0F, 0x1F}, // PCR 23, Application specific
+ {0, 0x0F, 0x1F} // PCR 24, testing policy
+ };
+/* 8.7.2 Functions */
+/* 8.7.2.1 PCRBelongsAuthGroup() */
+/* This function indicates if a PCR belongs to a group that requires an authValue in order to modify
+ the PCR. If it does, groupIndex is set to value of the group index. This feature of PCR is
+ decided by the platform specification. */
+/* Return Type: BOOL */
+/* TRUE: PCR belongs an authorization group */
+/* FALSE: PCR does not belong an authorization group */
+BOOL
+PCRBelongsAuthGroup(
+ TPMI_DH_PCR handle, // IN: handle of PCR
+ UINT32 *groupIndex // OUT: group index if PCR belongs a
+ // group that allows authValue. If PCR
+ // does not belong to an authorization
+ // group, the value in this parameter is
+ // invalid
+ )
+{
+#if defined NUM_AUTHVALUE_PCR_GROUP && NUM_AUTHVALUE_PCR_GROUP > 0
+ // Platform specification determines to which authorization group a PCR belongs
+ // (if any). In this implementation, we assume there is only
+ // one authorization group which contains PCR[20-22]. If the platform
+ // specification requires differently, the implementation should be changed
+ // accordingly
+ if(handle >= 20 && handle <= 22)
+ {
+ *groupIndex = 0;
+ return TRUE;
+ }
+#endif
+ return FALSE;
+}
+/* 8.7.2.2 PCRBelongsPolicyGroup() */
+/* This function indicates if a PCR belongs to a group that requires a policy authorization in order
+ to modify the PCR. If it does, groupIndex is set to value of the group index. This feature of
+ PCR is decided by the platform specification. */
+/* Return Values Meaning */
+/* TRUE: PCR belongs to a policy group */
+/* FALSE: PCR does not belong to a policy group */
+BOOL
+PCRBelongsPolicyGroup(
+ TPMI_DH_PCR handle, // IN: handle of PCR
+ UINT32 *groupIndex // OUT: group index if PCR belongs a group that
+ // allows policy. If PCR does not belong to
+ // a policy group, the value in this
+ // parameter is invalid
+ )
+{
+#if defined NUM_POLICY_PCR_GROUP && NUM_POLICY_PCR_GROUP > 0
+ // Platform specification decides if a PCR belongs to a policy group and
+ // belongs to which group. In this implementation, we assume there is only
+ // one policy group which contains PCR20-22. If the platform specification
+ // requires differently, the implementation should be changed accordingly
+ if(handle >= 20 && handle <= 22)
+ {
+ *groupIndex = 0;
+ return TRUE;
+ }
+#endif
+ return FALSE;
+}
+/* 8.7.2.3 PCRBelongsTCBGroup() */
+/* This function indicates if a PCR belongs to the TCB group. */
+/* Return Values Meaning */
+/* TRUE: PCR belongs to a TCB group */
+/* FALSE: PCR does not belong to a TCB group */
+static BOOL
+PCRBelongsTCBGroup(
+ TPMI_DH_PCR handle // IN: handle of PCR
+ )
+{
+#if ENABLE_PCR_NO_INCREMENT == YES
+#if 0
+ // Platform specification decides if a PCR belongs to a TCB group. In this
+ // implementation, we assume PCR[20-22] belong to TCB group. If the platform
+ // specification requires differently, the implementation should be
+ // changed accordingly
+ if(handle >= 20 && handle <= 22)
+ return TRUE;
+#endif
+ /* kgold - changed for PC Client, 16, 21-23 no increment */
+ if ((handle == 16) ||
+ ((handle >= 21) && (handle <= 23))) {
+ return TRUE;
+ }
+#endif
+ return FALSE;
+}
+/* 8.7.2.4 PCRPolicyIsAvailable() */
+/* This function indicates if a policy is available for a PCR. */
+/* Return Values Meaning */
+/* TRUE the PCR may be authorized by policy */
+/* FALSE the PCR does not allow policy */
+BOOL
+PCRPolicyIsAvailable(
+ TPMI_DH_PCR handle // IN: PCR handle
+ )
+{
+ UINT32 groupIndex;
+ return PCRBelongsPolicyGroup(handle, &groupIndex);
+}
+/* 8.7.2.5 PCRGetAuthValue() */
+/* This function is used to access the authValue of a PCR. If PCR does not belong to an authValue
+ group, an EmptyAuth() will be returned. */
+TPM2B_AUTH *
+PCRGetAuthValue(
+ TPMI_DH_PCR handle // IN: PCR handle
+ )
+{
+ UINT32 groupIndex;
+ if(PCRBelongsAuthGroup(handle, &groupIndex))
+ {
+ return &gc.pcrAuthValues.auth[groupIndex];
+ }
+ else
+ {
+ return NULL;
+ }
+}
+/* 8.7.2.6 PCRGetAuthPolicy() */
+/* This function is used to access the authorization policy of a PCR. It sets policy to the
+ authorization policy and returns the hash algorithm for policy If the PCR does not allow a
+ policy, TPM_ALG_NULL is returned. */
+TPMI_ALG_HASH
+PCRGetAuthPolicy(
+ TPMI_DH_PCR handle, // IN: PCR handle
+ TPM2B_DIGEST *policy // OUT: policy of PCR
+ )
+{
+ UINT32 groupIndex;
+ if(PCRBelongsPolicyGroup(handle, &groupIndex))
+ {
+ *policy = gp.pcrPolicies.policy[groupIndex];
+ return gp.pcrPolicies.hashAlg[groupIndex];
+ }
+ else
+ {
+ policy->t.size = 0;
+ return TPM_ALG_NULL;
+ }
+}
+/* 8.7.2.7 PCRSimStart() */
+/* This function is used to initialize the policies when a TPM is manufactured. This function would
+ only be called in a manufacturing environment or in a TPM simulator. */
+void
+PCRSimStart(
+ void
+ )
+{
+ UINT32 i;
+#if defined NUM_POLICY_PCR_GROUP && NUM_POLICY_PCR_GROUP > 0
+ for(i = 0; i < NUM_POLICY_PCR_GROUP; i++)
+ {
+ gp.pcrPolicies.hashAlg[i] = TPM_ALG_NULL;
+ gp.pcrPolicies.policy[i].t.size = 0;
+ }
+#endif
+#if defined NUM_AUTHVALUE_PCR_GROUP && NUM_AUTHVALUE_PCR_GROUP > 0
+ for(i = 0; i < NUM_AUTHVALUE_PCR_GROUP; i++)
+ {
+ gc.pcrAuthValues.auth[i].t.size = 0;
+ }
+#endif
+ // We need to give an initial configuration on allocated PCR before
+ // receiving any TPM2_PCR_Allocate command to change this configuration
+ // When the simulation environment starts, we allocate all the PCRs
+ for(gp.pcrAllocated.count = 0; gp.pcrAllocated.count < HASH_COUNT;
+ gp.pcrAllocated.count++)
+ {
+ gp.pcrAllocated.pcrSelections[gp.pcrAllocated.count].hash
+ = CryptHashGetAlgByIndex(gp.pcrAllocated.count);
+ gp.pcrAllocated.pcrSelections[gp.pcrAllocated.count].sizeofSelect
+ = PCR_SELECT_MAX;
+ for(i = 0; i < PCR_SELECT_MAX; i++)
+ gp.pcrAllocated.pcrSelections[gp.pcrAllocated.count].pcrSelect[i]
+ = 0xFF;
+ }
+ // Store the initial configuration to NV
+ NV_SYNC_PERSISTENT(pcrPolicies);
+ NV_SYNC_PERSISTENT(pcrAllocated);
+ return;
+}
+/* 8.7.3.8 GetSavedPcrPointer() */
+/* This function returns the address of an array of state saved PCR based on the hash algorithm. */
+/* Return Values Meaning */
+/* NULL no such algorithm */
+/* not NULL pointer to the 0th byte of the 0th PCR */
+
+static BYTE *
+GetSavedPcrPointer(
+ TPM_ALG_ID alg, // IN: algorithm for bank
+ UINT32 pcrIndex // IN: PCR index in PCR_SAVE
+ )
+{
+ BYTE *retVal;
+ switch(alg)
+ {
+#define HASH_CASE(HASH, Hash) \
+ case TPM_ALG_##HASH: \
+ retVal = gc.pcrSave.Hash[pcrIndex]; \
+ break;
+
+ FOR_EACH_HASH(HASH_CASE)
+#undef HASH_CASE
+
+ default:
+ FAIL(FATAL_ERROR_INTERNAL);
+ }
+ return retVal;
+}
+
+/* 8.7.2.9 PcrIsAllocated() */
+/* This function indicates if a PCR number for the particular hash algorithm is allocated. */
+/* Return Values Meaning */
+/* FALSE PCR is not allocated */
+/* TRUE PCR is allocated */
+BOOL
+PcrIsAllocated(
+ UINT32 pcr, // IN: The number of the PCR
+ TPMI_ALG_HASH hashAlg // IN: The PCR algorithm
+ )
+{
+ UINT32 i;
+ BOOL allocated = FALSE;
+ if(pcr < IMPLEMENTATION_PCR)
+ {
+ for(i = 0; i < gp.pcrAllocated.count; i++)
+ {
+ if(gp.pcrAllocated.pcrSelections[i].hash == hashAlg)
+ {
+ if(((gp.pcrAllocated.pcrSelections[i].pcrSelect[pcr / 8])
+ & (1 << (pcr % 8))) != 0)
+ allocated = TRUE;
+ else
+ allocated = FALSE;
+ break;
+ }
+ }
+ }
+ return allocated;
+}
+/* 8.7.3.10 GetPcrPointer() */
+/* This function returns the address of an array of PCR based on the hash algorithm. */
+/* Return Values Meaning */
+/* NULL no such algorithm */
+/* not NULL pointer to the 0th byte of the 0th PCR */
+
+static BYTE *
+GetPcrPointer(
+ TPM_ALG_ID alg, // IN: algorithm for bank
+ UINT32 pcrNumber // IN: PCR number
+ )
+{
+ static BYTE *pcr = NULL;
+
+ if(!PcrIsAllocated(pcrNumber, alg))
+ return NULL;
+ switch(alg)
+ {
+#define HASH_CASE(HASH, Hash) \
+ case TPM_ALG_##HASH: \
+ pcr = s_pcrs[pcrNumber].Hash##Pcr; \
+ break;
+
+ FOR_EACH_HASH(HASH_CASE)
+#undef HASH_CASE
+
+ default:
+ FAIL(FATAL_ERROR_INTERNAL);
+ break;
+ }
+ return pcr;
+}
+
+/* 8.7.2.11 IsPcrSelected() */
+/* This function indicates if an indicated PCR number is selected by the bit map in selection. */
+/* Return Values Meaning */
+/* FALSE PCR is not selected */
+/* TRUE PCR is selected */
+static BOOL
+IsPcrSelected(
+ UINT32 pcr, // IN: The number of the PCR
+ TPMS_PCR_SELECTION *selection // IN: The selection structure
+ )
+{
+ BOOL selected;
+ selected = (pcr < IMPLEMENTATION_PCR
+ && ((selection->pcrSelect[pcr / 8]) & (1 << (pcr % 8))) != 0);
+ return selected;
+}
+/* 8.7.2.12 FilterPcr() */
+/* This function modifies a PCR selection array based on the implemented PCR. */
+static void
+FilterPcr(
+ TPMS_PCR_SELECTION *selection // IN: input PCR selection
+ )
+{
+ UINT32 i;
+ TPMS_PCR_SELECTION *allocated = NULL;
+ // If size of select is less than PCR_SELECT_MAX, zero the unspecified PCR
+ for(i = selection->sizeofSelect; i < PCR_SELECT_MAX; i++)
+ selection->pcrSelect[i] = 0;
+ // Find the internal configuration for the bank
+ for(i = 0; i < gp.pcrAllocated.count; i++)
+ {
+ if(gp.pcrAllocated.pcrSelections[i].hash == selection->hash)
+ {
+ allocated = &gp.pcrAllocated.pcrSelections[i];
+ break;
+ }
+ }
+ for(i = 0; i < selection->sizeofSelect; i++)
+ {
+ if(allocated == NULL)
+ {
+ // If the required bank does not exist, clear input selection
+ selection->pcrSelect[i] = 0;
+ }
+ else
+ selection->pcrSelect[i] &= allocated->pcrSelect[i];
+ }
+ return;
+}
+/* 8.7.2.13 PcrDrtm() */
+/* This function does the DRTM and H-CRTM processing it is called from _TPM_Hash_End(). */
+void
+PcrDrtm(
+ const TPMI_DH_PCR pcrHandle, // IN: the index of the PCR to be
+ // modified
+ const TPMI_ALG_HASH hash, // IN: the bank identifier
+ const TPM2B_DIGEST *digest // IN: the digest to modify the PCR
+ )
+{
+ BYTE *pcrData = GetPcrPointer(hash, pcrHandle);
+ if(pcrData != NULL)
+ {
+ // Rest the PCR to zeros
+ MemorySet(pcrData, 0, digest->t.size);
+ // if the TPM has not started, then set the PCR to 0...04 and then extend
+ if(!TPMIsStarted())
+ {
+ pcrData[digest->t.size - 1] = 4;
+ }
+ // Now, extend the value
+ PCRExtend(pcrHandle, hash, digest->t.size, (BYTE *)digest->t.buffer);
+ }
+}
+/* 8.7.2.14 PCR_ClearAuth() */
+/* This function is used to reset the PCR authorization values. It is called on TPM2_Startup(CLEAR)
+ and TPM2_Clear(). */
+void
+PCR_ClearAuth(
+ void
+ )
+{
+#if defined NUM_AUTHVALUE_PCR_GROUP && NUM_AUTHVALUE_PCR_GROUP > 0
+ int j;
+ for(j = 0; j < NUM_AUTHVALUE_PCR_GROUP; j++)
+ {
+ gc.pcrAuthValues.auth[j].t.size = 0;
+ }
+#endif
+}
+/* 8.7.2.15 PCRStartup() */
+/* This function initializes the PCR subsystem at TPM2_Startup(). */
+BOOL
+PCRStartup(
+ STARTUP_TYPE type, // IN: startup type
+ BYTE locality // IN: startup locality
+ )
+{
+ UINT32 pcr, j;
+ UINT32 saveIndex = 0;
+ g_pcrReConfig = FALSE;
+ // Don't test for SU_RESET because that should be the default when nothing
+ // else is selected
+ if(type != SU_RESUME && type != SU_RESTART)
+ {
+ // PCR generation counter is cleared at TPM_RESET
+ gr.pcrCounter = 0;
+ }
+ // Initialize/Restore PCR values
+ for(pcr = 0; pcr < IMPLEMENTATION_PCR; pcr++)
+ {
+ // On resume, need to know if this PCR had its state saved or not
+ UINT32 stateSaved;
+ if(type == SU_RESUME
+ && s_initAttributes[pcr].stateSave == SET)
+ {
+ stateSaved = 1;
+ }
+ else
+ {
+ stateSaved = 0;
+ PCRChanged(pcr);
+ }
+ // If this is the H-CRTM PCR and we are not doing a resume and we
+ // had an H-CRTM event, then we don't change this PCR
+ if(pcr == HCRTM_PCR && type != SU_RESUME && g_DrtmPreStartup == TRUE)
+ continue;
+ // Iterate each hash algorithm bank
+ for(j = 0; j < gp.pcrAllocated.count; j++)
+ {
+ TPMI_ALG_HASH hash = gp.pcrAllocated.pcrSelections[j].hash;
+ BYTE *pcrData = GetPcrPointer(hash, pcr);
+ UINT16 pcrSize = CryptHashGetDigestSize(hash);
+ if(pcrData != NULL)
+ {
+ // if state was saved
+ if(stateSaved == 1)
+ {
+ // Restore saved PCR value
+ BYTE *pcrSavedData;
+ pcrSavedData = GetSavedPcrPointer(
+ gp.pcrAllocated.pcrSelections[j].hash,
+ saveIndex);
+ if(pcrSavedData == NULL)
+ return FALSE;
+ MemoryCopy(pcrData, pcrSavedData, pcrSize);
+ }
+ else
+ // PCR was not restored by state save
+ {
+ // If the reset locality of the PCR is 4, then
+ // the reset value is all one's, otherwise it is
+ // all zero.
+ if((s_initAttributes[pcr].resetLocality & 0x10) != 0)
+ MemorySet(pcrData, 0xFF, pcrSize);
+ else
+ {
+ MemorySet(pcrData, 0, pcrSize);
+ if(pcr == HCRTM_PCR)
+ pcrData[pcrSize - 1] = locality;
+ }
+ }
+ }
+ }
+ saveIndex += stateSaved;
+ }
+ // Reset authValues on TPM2_Startup(CLEAR)
+ if(type != SU_RESUME)
+ PCR_ClearAuth();
+ return TRUE;
+}
+/* 8.7.2.16 PCRStateSave() */
+/* This function is used to save the PCR values that will be restored on TPM Resume. */
+void
+PCRStateSave(
+ TPM_SU type // IN: startup type
+ )
+{
+ UINT32 pcr, j;
+ UINT32 saveIndex = 0;
+ // if state save CLEAR, nothing to be done. Return here
+ if(type == TPM_SU_CLEAR)
+ return;
+ // Copy PCR values to the structure that should be saved to NV
+ for(pcr = 0; pcr < IMPLEMENTATION_PCR; pcr++)
+ {
+ UINT32 stateSaved = (s_initAttributes[pcr].stateSave == SET) ? 1 : 0;
+ // Iterate each hash algorithm bank
+ for(j = 0; j < gp.pcrAllocated.count; j++)
+ {
+ BYTE *pcrData;
+ UINT32 pcrSize;
+ pcrData = GetPcrPointer(gp.pcrAllocated.pcrSelections[j].hash, pcr);
+ if(pcrData != NULL)
+ {
+ pcrSize
+ = CryptHashGetDigestSize(gp.pcrAllocated.pcrSelections[j].hash);
+ if(stateSaved == 1)
+ {
+ // Restore saved PCR value
+ BYTE *pcrSavedData;
+ pcrSavedData
+ = GetSavedPcrPointer(gp.pcrAllocated.pcrSelections[j].hash,
+ saveIndex);
+ MemoryCopy(pcrSavedData, pcrData, pcrSize);
+ }
+ }
+ }
+ saveIndex += stateSaved;
+ }
+ return;
+}
+/* 8.7.2.17 PCRIsStateSaved() */
+/* This function indicates if the selected PCR is a PCR that is state saved on
+ TPM2_Shutdown(STATE). The return value is based on PCR attributes. */
+/* Return Values Meaning */
+/* TRUE PCR is state saved */
+/* FALSE PCR is not state saved */
+BOOL
+PCRIsStateSaved(
+ TPMI_DH_PCR handle // IN: PCR handle to be extended
+ )
+{
+ UINT32 pcr = handle - PCR_FIRST;
+ if(s_initAttributes[pcr].stateSave == SET)
+ return TRUE;
+ else
+ return FALSE;
+}
+/* 8.7.2.18 PCRIsResetAllowed() */
+/* This function indicates if a PCR may be reset by the current command locality. The return value
+ is based on PCR attributes, and not the PCR allocation. */
+/* Return Values Meaning */
+/* TRUE TPM2_PCR_Reset() is allowed */
+/* FALSE TPM2_PCR_Reset() is not allowed */
+BOOL
+PCRIsResetAllowed(
+ TPMI_DH_PCR handle // IN: PCR handle to be extended
+ )
+{
+ UINT8 commandLocality;
+ UINT8 localityBits = 1;
+ UINT32 pcr = handle - PCR_FIRST;
+ // Check for the locality
+ commandLocality = _plat__LocalityGet();
+#ifdef DRTM_PCR
+ // For a TPM that does DRTM, Reset is not allowed at locality 4
+ if(commandLocality == 4)
+ return FALSE;
+#endif
+ localityBits = localityBits << commandLocality;
+ if((localityBits & s_initAttributes[pcr].resetLocality) == 0)
+ return FALSE;
+ else
+ return TRUE;
+}
+/* 8.7.2.19 PCRChanged() */
+/* This function checks a PCR handle to see if the attributes for the PCR are set so that any change
+ to the PCR causes an increment of the pcrCounter. If it does, then the function increments the
+ counter. Will also bump the counter if the handle is zero which means that PCR 0 can not be in
+ the TCB group. Bump on zero is used by TPM2_Clear(). */
+void
+PCRChanged(
+ TPM_HANDLE pcrHandle // IN: the handle of the PCR that changed.
+ )
+{
+ // For the reference implementation, the only change that does not cause
+ // increment is a change to a PCR in the TCB group.
+ if((pcrHandle == 0) || !PCRBelongsTCBGroup(pcrHandle))
+ {
+ gr.pcrCounter++;
+ if(gr.pcrCounter == 0)
+ FAIL(FATAL_ERROR_COUNTER_OVERFLOW);
+ }
+}
+/* 8.7.2.20 PCRIsExtendAllowed() */
+/* This function indicates a PCR may be extended at the current command locality. The return value
+ is based on PCR attributes, and not the PCR allocation. */
+/* Return Values Meaning */
+/* TRUE extend is allowed */
+/* FALSE extend is not allowed */
+BOOL
+PCRIsExtendAllowed(
+ TPMI_DH_PCR handle // IN: PCR handle to be extended
+ )
+{
+ UINT8 commandLocality;
+ UINT8 localityBits = 1;
+ UINT32 pcr = handle - PCR_FIRST;
+ // Check for the locality
+ commandLocality = _plat__LocalityGet();
+ localityBits = localityBits << commandLocality;
+ if((localityBits & s_initAttributes[pcr].extendLocality) == 0)
+ return FALSE;
+ else
+ return TRUE;
+}
+/* 8.7.2.21 PCRExtend() */
+/* This function is used to extend a PCR in a specific bank. */
+void
+PCRExtend(
+ TPMI_DH_PCR handle, // IN: PCR handle to be extended
+ TPMI_ALG_HASH hash, // IN: hash algorithm of PCR
+ UINT32 size, // IN: size of data to be extended
+ BYTE *data // IN: data to be extended
+ )
+{
+ BYTE *pcrData;
+ HASH_STATE hashState;
+ UINT16 pcrSize;
+ pcrData = GetPcrPointer(hash, handle - PCR_FIRST);
+ // Extend PCR if it is allocated
+ if(pcrData != NULL)
+ {
+ pcrSize = CryptHashGetDigestSize(hash);
+ CryptHashStart(&hashState, hash);
+ CryptDigestUpdate(&hashState, pcrSize, pcrData);
+ CryptDigestUpdate(&hashState, size, data);
+ CryptHashEnd(&hashState, pcrSize, pcrData);
+ // PCR has changed so update the pcrCounter if necessary
+ PCRChanged(handle);
+ }
+ return;
+}
+/* 8.7.2.22 PCRComputeCurrentDigest() */
+/* This function computes the digest of the selected PCR. */
+/* As a side-effect, selection is modified so that only the implemented PCR will have their bits
+ still set. */
+void
+PCRComputeCurrentDigest(
+ TPMI_ALG_HASH hashAlg, // IN: hash algorithm to compute digest
+ TPML_PCR_SELECTION *selection, // IN/OUT: PCR selection (filtered on
+ // output)
+ TPM2B_DIGEST *digest // OUT: digest
+ )
+{
+ HASH_STATE hashState;
+ TPMS_PCR_SELECTION *select;
+ BYTE *pcrData; // will point to a digest
+ UINT32 pcrSize;
+ UINT32 pcr;
+ UINT32 i;
+ // Initialize the hash
+ digest->t.size = CryptHashStart(&hashState, hashAlg);
+ pAssert(digest->t.size > 0 && digest->t.size < UINT16_MAX);
+ // Iterate through the list of PCR selection structures
+ for(i = 0; i < selection->count; i++)
+ {
+ // Point to the current selection
+ select = &selection->pcrSelections[i]; // Point to the current selection
+ FilterPcr(select); // Clear out the bits for unimplemented PCR
+ // Need the size of each digest
+ pcrSize = CryptHashGetDigestSize(selection->pcrSelections[i].hash);
+ // Iterate through the selection
+ for(pcr = 0; pcr < IMPLEMENTATION_PCR; pcr++)
+ {
+ if(IsPcrSelected(pcr, select)) // Is this PCR selected
+ {
+ // Get pointer to the digest data for the bank
+ pcrData = GetPcrPointer(selection->pcrSelections[i].hash, pcr);
+ pAssert(pcrData != NULL);
+ CryptDigestUpdate(&hashState, pcrSize, pcrData); // add to digest
+ }
+ }
+ }
+ // Complete hash stack
+ CryptHashEnd2B(&hashState, &digest->b);
+ return;
+}
+/* 8.7.2.23 PCRRead() */
+/* This function is used to read a list of selected PCR. If the requested PCR number exceeds the
+ maximum number that can be output, the selection is adjusted to reflect the actual output PCR. */
+void
+PCRRead(
+ TPML_PCR_SELECTION *selection, // IN/OUT: PCR selection (filtered on
+ // output)
+ TPML_DIGEST *digest, // OUT: digest
+ UINT32 *pcrCounter // OUT: the current value of PCR generation
+ // number
+ )
+{
+ TPMS_PCR_SELECTION *select;
+ BYTE *pcrData; // will point to a digest
+ UINT32 pcr;
+ UINT32 i;
+ digest->count = 0;
+ // Iterate through the list of PCR selection structures
+ for(i = 0; i < selection->count; i++)
+ {
+ // Point to the current selection
+ select = &selection->pcrSelections[i]; // Point to the current selection
+ FilterPcr(select); // Clear out the bits for unimplemented PCR
+ // Iterate through the selection
+ for(pcr = 0; pcr < IMPLEMENTATION_PCR; pcr++)
+ {
+ if(IsPcrSelected(pcr, select)) // Is this PCR selected
+ {
+ // Check if number of digest exceed upper bound
+ if(digest->count > 7)
+ {
+ // Clear rest of the current select bitmap
+ while(pcr < IMPLEMENTATION_PCR
+ // do not round up!
+ && (pcr / 8) < select->sizeofSelect)
+ {
+ // do not round up!
+ select->pcrSelect[pcr / 8] &= (BYTE)~(1 << (pcr % 8));
+ pcr++;
+ }
+ // Exit inner loop
+ break;
+ }
+ // Need the size of each digest
+ digest->digests[digest->count].t.size =
+ CryptHashGetDigestSize(selection->pcrSelections[i].hash);
+ // Get pointer to the digest data for the bank
+ pcrData = GetPcrPointer(selection->pcrSelections[i].hash, pcr);
+ pAssert(pcrData != NULL);
+ // Add to the data to digest
+ MemoryCopy(digest->digests[digest->count].t.buffer,
+ pcrData,
+ digest->digests[digest->count].t.size);
+ digest->count++;
+ }
+ }
+ // If we exit inner loop because we have exceed the output upper bound
+ if(digest->count > 7 && pcr < IMPLEMENTATION_PCR)
+ {
+ // Clear rest of the selection
+ while(i < selection->count)
+ {
+ MemorySet(selection->pcrSelections[i].pcrSelect, 0,
+ selection->pcrSelections[i].sizeofSelect);
+ i++;
+ }
+ // exit outer loop
+ break;
+ }
+ }
+ *pcrCounter = gr.pcrCounter;
+ return;
+}
+/* 8.7.2.25 PCRAllocate() */
+/* This function is used to change the PCR allocation. */
+/* Error Returns Meaning */
+/* TPM_RC_NO_RESULT allocate failed */
+/* TPM_RC_PCR improper allocation */
+TPM_RC
+PCRAllocate(
+ TPML_PCR_SELECTION *allocate, // IN: required allocation
+ UINT32 *maxPCR, // OUT: Maximum number of PCR
+ UINT32 *sizeNeeded, // OUT: required space
+ UINT32 *sizeAvailable // OUT: available space
+ )
+{
+ UINT32 i, j, k;
+ TPML_PCR_SELECTION newAllocate;
+ // Initialize the flags to indicate if HCRTM PCR and DRTM PCR are allocated.
+ BOOL pcrHcrtm = FALSE;
+ BOOL pcrDrtm = FALSE;
+ // Create the expected new PCR allocation based on the existing allocation
+ // and the new input:
+ // 1. if a PCR bank does not appear in the new allocation, the existing
+ // allocation of this PCR bank will be preserved.
+ // 2. if a PCR bank appears multiple times in the new allocation, only the
+ // last one will be in effect.
+ newAllocate = gp.pcrAllocated;
+ for(i = 0; i < allocate->count; i++)
+ {
+ for(j = 0; j < newAllocate.count; j++)
+ {
+ // If hash matches, the new allocation covers the old allocation
+ // for this particular bank.
+ // The assumption is the initial PCR allocation (from manufacture)
+ // has all the supported hash algorithms with an assigned bank
+ // (possibly empty). So there must be a match for any new bank
+ // allocation from the input.
+ if(newAllocate.pcrSelections[j].hash ==
+ allocate->pcrSelections[i].hash)
+ {
+ newAllocate.pcrSelections[j] = allocate->pcrSelections[i];
+ break;
+ }
+ }
+ // The j loop must exit with a match.
+ pAssert(j < newAllocate.count);
+ }
+ // Max PCR in a bank is MIN(implemented PCR, PCR with attributes defined)
+ *maxPCR = sizeof(s_initAttributes) / sizeof(PCR_Attributes);
+ if(*maxPCR > IMPLEMENTATION_PCR)
+ *maxPCR = IMPLEMENTATION_PCR;
+ // Compute required size for allocation
+ *sizeNeeded = 0;
+ for(i = 0; i < newAllocate.count; i++)
+ {
+ UINT32 digestSize
+ = CryptHashGetDigestSize(newAllocate.pcrSelections[i].hash);
+#if defined(DRTM_PCR)
+ // Make sure that we end up with at least one DRTM PCR
+ pcrDrtm = pcrDrtm || TestBit(DRTM_PCR,
+ newAllocate.pcrSelections[i].pcrSelect,
+ newAllocate.pcrSelections[i].sizeofSelect);
+#else // if DRTM PCR is not required, indicate that the allocation is OK
+ pcrDrtm = TRUE;
+#endif
+#if defined(HCRTM_PCR)
+ // and one HCRTM PCR (since this is usually PCR 0...)
+ pcrHcrtm = pcrHcrtm || TestBit(HCRTM_PCR,
+ newAllocate.pcrSelections[i].pcrSelect,
+ newAllocate.pcrSelections[i].sizeofSelect);
+#else
+ pcrHcrtm = TRUE;
+#endif
+ for(j = 0; j < newAllocate.pcrSelections[i].sizeofSelect; j++)
+ {
+ BYTE mask = 1;
+ for(k = 0; k < 8; k++)
+ {
+ if((newAllocate.pcrSelections[i].pcrSelect[j] & mask) != 0)
+ *sizeNeeded += digestSize;
+ mask = mask << 1;
+ }
+ }
+ }
+ if(!pcrDrtm || !pcrHcrtm)
+ return TPM_RC_PCR;
+ // In this particular implementation, we always have enough space to
+ // allocate PCR. Different implementation may return a sizeAvailable less
+ // than the sizeNeed.
+ *sizeAvailable = sizeof(s_pcrs);
+ // Save the required allocation to NV. Note that after NV is written, the
+ // PCR allocation in NV is no longer consistent with the RAM data
+ // gp.pcrAllocated. The NV version reflect the allocate after next
+ // TPM_RESET, while the RAM version reflects the current allocation
+ NV_WRITE_PERSISTENT(pcrAllocated, newAllocate);
+ return TPM_RC_SUCCESS;
+}
+/* 8.7.2.26 PCRSetValue() */
+/* This function is used to set the designated PCR in all banks to an initial value. The initial
+ value is signed and will be sign extended into the entire PCR. */
+void
+PCRSetValue(
+ TPM_HANDLE handle, // IN: the handle of the PCR to set
+ INT8 initialValue // IN: the value to set
+ )
+{
+ int i;
+ UINT32 pcr = handle - PCR_FIRST;
+ TPMI_ALG_HASH hash;
+ UINT16 digestSize;
+ BYTE *pcrData;
+ // Iterate supported PCR bank algorithms to reset
+ for(i = 0; i < HASH_COUNT; i++)
+ {
+ hash = CryptHashGetAlgByIndex(i);
+ // Prevent runaway
+ if(hash == TPM_ALG_NULL)
+ break;
+ // Get a pointer to the data
+ pcrData = GetPcrPointer(gp.pcrAllocated.pcrSelections[i].hash, pcr);
+ // If the PCR is allocated
+ if(pcrData != NULL)
+ {
+ // And the size of the digest
+ digestSize = CryptHashGetDigestSize(hash);
+ // Set the LSO to the input value
+ pcrData[digestSize - 1] = initialValue;
+ // Sign extend
+ if(initialValue >= 0)
+ MemorySet(pcrData, 0, digestSize - 1);
+ else
+ MemorySet(pcrData, -1, digestSize - 1);
+ }
+ }
+}
+/* 8.7.2.27 PCRResetDynamics */
+/* This function is used to reset a dynamic PCR to 0. This function is used in DRTM sequence. */
+void
+PCRResetDynamics(
+ void
+ )
+{
+ UINT32 pcr, i;
+ // Initialize PCR values
+ for(pcr = 0; pcr < IMPLEMENTATION_PCR; pcr++)
+ {
+ // Iterate each hash algorithm bank
+ for(i = 0; i < gp.pcrAllocated.count; i++)
+ {
+ BYTE *pcrData;
+ UINT32 pcrSize;
+ pcrData = GetPcrPointer(gp.pcrAllocated.pcrSelections[i].hash, pcr);
+ if(pcrData != NULL)
+ {
+ pcrSize =
+ CryptHashGetDigestSize(gp.pcrAllocated.pcrSelections[i].hash);
+ // Reset PCR
+ // Any PCR can be reset by locality 4 should be reset to 0
+ if((s_initAttributes[pcr].resetLocality & 0x10) != 0)
+ MemorySet(pcrData, 0, pcrSize);
+ }
+ }
+ }
+ return;
+}
+/* 8.7.2.28 PCRCapGetAllocation() */
+/* This function is used to get the current allocation of PCR banks. */
+/* Return Values Meaning */
+/* YES: if the return count is 0 */
+/* NO: if the return count is not 0 */
+TPMI_YES_NO
+PCRCapGetAllocation(
+ UINT32 count, // IN: count of return
+ TPML_PCR_SELECTION *pcrSelection // OUT: PCR allocation list
+ )
+{
+ if(count == 0)
+ {
+ pcrSelection->count = 0;
+ return YES;
+ }
+ else
+ {
+ *pcrSelection = gp.pcrAllocated;
+ return NO;
+ }
+}
+/* 8.7.2.29 PCRSetSelectBit() */
+/* This function sets a bit in a bitmap array. */
+static void
+PCRSetSelectBit(
+ UINT32 pcr, // IN: PCR number
+ BYTE *bitmap // OUT: bit map to be set
+ )
+{
+ bitmap[pcr / 8] |= (1 << (pcr % 8));
+ return;
+}
+/* 8.7.2.30 PCRGetProperty() */
+/* This function returns the selected PCR property. */
+/* Return Values Meaning */
+/* TRUE the property type is implemented */
+/* FALSE the property type is not implemented */
+static BOOL
+PCRGetProperty(
+ TPM_PT_PCR property,
+ TPMS_TAGGED_PCR_SELECT *select
+ )
+{
+ UINT32 pcr;
+ UINT32 groupIndex;
+ select->tag = property;
+ // Always set the bitmap to be the size of all PCR
+ select->sizeofSelect = (IMPLEMENTATION_PCR + 7) / 8;
+ // Initialize bitmap
+ MemorySet(select->pcrSelect, 0, select->sizeofSelect);
+ // Collecting properties
+ for(pcr = 0; pcr < IMPLEMENTATION_PCR; pcr++)
+ {
+ switch(property)
+ {
+ case TPM_PT_PCR_SAVE:
+ if(s_initAttributes[pcr].stateSave == SET)
+ PCRSetSelectBit(pcr, select->pcrSelect);
+ break;
+ case TPM_PT_PCR_EXTEND_L0:
+ if((s_initAttributes[pcr].extendLocality & 0x01) != 0)
+ PCRSetSelectBit(pcr, select->pcrSelect);
+ break;
+ case TPM_PT_PCR_RESET_L0:
+ if((s_initAttributes[pcr].resetLocality & 0x01) != 0)
+ PCRSetSelectBit(pcr, select->pcrSelect);
+ break;
+ case TPM_PT_PCR_EXTEND_L1:
+ if((s_initAttributes[pcr].extendLocality & 0x02) != 0)
+ PCRSetSelectBit(pcr, select->pcrSelect);
+ break;
+ case TPM_PT_PCR_RESET_L1:
+ if((s_initAttributes[pcr].resetLocality & 0x02) != 0)
+ PCRSetSelectBit(pcr, select->pcrSelect);
+ break;
+ case TPM_PT_PCR_EXTEND_L2:
+ if((s_initAttributes[pcr].extendLocality & 0x04) != 0)
+ PCRSetSelectBit(pcr, select->pcrSelect);
+ break;
+ case TPM_PT_PCR_RESET_L2:
+ if((s_initAttributes[pcr].resetLocality & 0x04) != 0)
+ PCRSetSelectBit(pcr, select->pcrSelect);
+ break;
+ case TPM_PT_PCR_EXTEND_L3:
+ if((s_initAttributes[pcr].extendLocality & 0x08) != 0)
+ PCRSetSelectBit(pcr, select->pcrSelect);
+ break;
+ case TPM_PT_PCR_RESET_L3:
+ if((s_initAttributes[pcr].resetLocality & 0x08) != 0)
+ PCRSetSelectBit(pcr, select->pcrSelect);
+ break;
+ case TPM_PT_PCR_EXTEND_L4:
+ if((s_initAttributes[pcr].extendLocality & 0x10) != 0)
+ PCRSetSelectBit(pcr, select->pcrSelect);
+ break;
+ case TPM_PT_PCR_RESET_L4:
+ if((s_initAttributes[pcr].resetLocality & 0x10) != 0)
+ PCRSetSelectBit(pcr, select->pcrSelect);
+ break;
+ case TPM_PT_PCR_DRTM_RESET:
+ // DRTM reset PCRs are the PCR reset by locality 4
+ if((s_initAttributes[pcr].resetLocality & 0x10) != 0)
+ PCRSetSelectBit(pcr, select->pcrSelect);
+ break;
+#if defined NUM_POLICY_PCR_GROUP && NUM_POLICY_PCR_GROUP > 0
+ case TPM_PT_PCR_POLICY:
+ if(PCRBelongsPolicyGroup(pcr + PCR_FIRST, &groupIndex))
+ PCRSetSelectBit(pcr, select->pcrSelect);
+ break;
+#endif
+#if defined NUM_AUTHVALUE_PCR_GROUP && NUM_AUTHVALUE_PCR_GROUP > 0
+ case TPM_PT_PCR_AUTH:
+ if(PCRBelongsAuthGroup(pcr + PCR_FIRST, &groupIndex))
+ PCRSetSelectBit(pcr, select->pcrSelect);
+ break;
+#endif
+#if ENABLE_PCR_NO_INCREMENT == YES
+ case TPM_PT_PCR_NO_INCREMENT:
+ if(PCRBelongsTCBGroup(pcr + PCR_FIRST))
+ PCRSetSelectBit(pcr, select->pcrSelect);
+ break;
+#endif
+ default:
+ // If property is not supported, stop scanning PCR attributes
+ // and return.
+ return FALSE;
+ break;
+ }
+ }
+ return TRUE;
+}
+/* 8.7.2.31 PCRCapGetProperties() */
+/* This function returns a list of PCR properties starting at property. */
+/* Return Values Meaning */
+/* YES: if no more property is available */
+/* NO: if there are more properties not reported */
+TPMI_YES_NO
+PCRCapGetProperties(
+ TPM_PT_PCR property, // IN: the starting PCR property
+ UINT32 count, // IN: count of returned properties
+ TPML_TAGGED_PCR_PROPERTY *select // OUT: PCR select
+ )
+{
+ TPMI_YES_NO more = NO;
+ UINT32 i;
+ // Initialize output property list
+ select->count = 0;
+ // The maximum count of properties we may return is MAX_PCR_PROPERTIES
+ if(count > MAX_PCR_PROPERTIES) count = MAX_PCR_PROPERTIES;
+ // TPM_PT_PCR_FIRST is defined as 0 in spec. It ensures that property
+ // value would never be less than TPM_PT_PCR_FIRST
+ cAssert(TPM_PT_PCR_FIRST == 0);
+ // Iterate PCR properties. TPM_PT_PCR_LAST is the index of the last property
+ // implemented on the TPM.
+ for(i = property; i <= TPM_PT_PCR_LAST; i++)
+ {
+ if(select->count < count)
+ {
+ // If we have not filled up the return list, add more properties to it
+ if(PCRGetProperty(i, &select->pcrProperty[select->count]))
+ // only increment if the property is implemented
+ select->count++;
+ }
+ else
+ {
+ // If the return list is full but we still have properties
+ // available, report this and stop iterating.
+ more = YES;
+ break;
+ }
+ }
+ return more;
+}
+/* 8.7.2.32 PCRCapGetHandles() */
+/* This function is used to get a list of handles of PCR, started from handle. If handle exceeds the
+ maximum PCR handle range, an empty list will be returned and the return value will be NO. */
+/* Return Values Meaning */
+/* YES if there are more handles available */
+/* NO all the available handles has been returned */
+TPMI_YES_NO
+PCRCapGetHandles(
+ TPMI_DH_PCR handle, // IN: start handle
+ UINT32 count, // IN: count of returned handles
+ TPML_HANDLE *handleList // OUT: list of handle
+ )
+{
+ TPMI_YES_NO more = NO;
+ UINT32 i;
+ pAssert(HandleGetType(handle) == TPM_HT_PCR);
+ // Initialize output handle list
+ handleList->count = 0;
+ // The maximum count of handles we may return is MAX_CAP_HANDLES
+ if(count > MAX_CAP_HANDLES) count = MAX_CAP_HANDLES;
+ // Iterate PCR handle range
+ for(i = handle & HR_HANDLE_MASK; i <= PCR_LAST; i++)
+ {
+ if(handleList->count < count)
+ {
+ // If we have not filled up the return list, add this PCR
+ // handle to it
+ handleList->handle[handleList->count] = i + PCR_FIRST;
+ handleList->count++;
+ }
+ else
+ {
+ // If the return list is full but we still have PCR handle
+ // available, report this and stop iterating
+ more = YES;
+ break;
+ }
+ }
+ return more;
+}
diff --git a/src/tpm2/PCR_Allocate_fp.h b/src/tpm2/PCR_Allocate_fp.h
new file mode 100644
index 0000000..30f9299
--- /dev/null
+++ b/src/tpm2/PCR_Allocate_fp.h
@@ -0,0 +1,89 @@
+/********************************************************************************/
+/* */
+/* */
+/* Written by Ken Goldman */
+/* IBM Thomas J. Watson Research Center */
+/* $Id: PCR_Allocate_fp.h 1521 2019-11-15 21:00:47Z kgoldman $ */
+/* */
+/* Licenses and Notices */
+/* */
+/* 1. Copyright Licenses: */
+/* */
+/* - Trusted Computing Group (TCG) grants to the user of the source code in */
+/* this specification (the "Source Code") a worldwide, irrevocable, */
+/* nonexclusive, royalty free, copyright license to reproduce, create */
+/* derivative works, distribute, display and perform the Source Code and */
+/* derivative works thereof, and to grant others the rights granted herein. */
+/* */
+/* - The TCG grants to the user of the other parts of the specification */
+/* (other than the Source Code) the rights to reproduce, distribute, */
+/* display, and perform the specification solely for the purpose of */
+/* developing products based on such documents. */
+/* */
+/* 2. Source Code Distribution Conditions: */
+/* */
+/* - Redistributions of Source Code must retain the above copyright licenses, */
+/* this list of conditions and the following disclaimers. */
+/* */
+/* - Redistributions in binary form must reproduce the above copyright */
+/* licenses, this list of conditions and the following disclaimers in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* 3. Disclaimers: */
+/* */
+/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
+/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
+/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
+/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
+/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
+/* information on specification licensing rights available through TCG */
+/* membership agreements. */
+/* */
+/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
+/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
+/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
+/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
+/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
+/* */
+/* - Without limitation, TCG and its members and licensors disclaim all */
+/* liability, including liability for infringement of any proprietary */
+/* rights, relating to use of information in this specification and to the */
+/* implementation of this specification, and TCG disclaims all liability for */
+/* cost of procurement of substitute goods or services, lost profits, loss */
+/* of use, loss of data or any incidental, consequential, direct, indirect, */
+/* or special damages, whether under contract, tort, warranty or otherwise, */
+/* arising in any way out of use or reliance upon this specification or any */
+/* information herein. */
+/* */
+/* (c) Copyright IBM Corp. and others, 2012-2015 */
+/* */
+/********************************************************************************/
+
+/* rev 119 */
+
+#ifndef PCR_ALLOCATE_FP_H
+#define PCR_ALLOCATE_FP_H
+
+typedef struct {
+ TPMI_RH_PLATFORM authHandle;
+ TPML_PCR_SELECTION pcrAllocation;
+} PCR_Allocate_In;
+
+#define RC_PCR_Allocate_authHandle (TPM_RC_H + TPM_RC_1)
+#define RC_PCR_Allocate_pcrAllocation (TPM_RC_P + TPM_RC_1)
+
+typedef struct {
+ TPMI_YES_NO allocationSuccess;
+ UINT32 maxPCR;
+ UINT32 sizeNeeded;
+ UINT32 sizeAvailable;
+} PCR_Allocate_Out;
+
+TPM_RC
+TPM2_PCR_Allocate(
+ PCR_Allocate_In *in, // IN: input parameter list
+ PCR_Allocate_Out *out // OUT: output parameter list
+ );
+
+
+#endif
diff --git a/src/tpm2/PCR_Event_fp.h b/src/tpm2/PCR_Event_fp.h
new file mode 100644
index 0000000..3c36851
--- /dev/null
+++ b/src/tpm2/PCR_Event_fp.h
@@ -0,0 +1,85 @@
+/********************************************************************************/
+/* */
+/* */
+/* Written by Ken Goldman */
+/* IBM Thomas J. Watson Research Center */
+/* $Id: PCR_Event_fp.h 809 2016-11-16 18:31:54Z kgoldman $ */
+/* */
+/* Licenses and Notices */
+/* */
+/* 1. Copyright Licenses: */
+/* */
+/* - Trusted Computing Group (TCG) grants to the user of the source code in */
+/* this specification (the "Source Code") a worldwide, irrevocable, */
+/* nonexclusive, royalty free, copyright license to reproduce, create */
+/* derivative works, distribute, display and perform the Source Code and */
+/* derivative works thereof, and to grant others the rights granted herein. */
+/* */
+/* - The TCG grants to the user of the other parts of the specification */
+/* (other than the Source Code) the rights to reproduce, distribute, */
+/* display, and perform the specification solely for the purpose of */
+/* developing products based on such documents. */
+/* */
+/* 2. Source Code Distribution Conditions: */
+/* */
+/* - Redistributions of Source Code must retain the above copyright licenses, */
+/* this list of conditions and the following disclaimers. */
+/* */
+/* - Redistributions in binary form must reproduce the above copyright */
+/* licenses, this list of conditions and the following disclaimers in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* 3. Disclaimers: */
+/* */
+/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
+/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
+/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
+/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
+/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
+/* information on specification licensing rights available through TCG */
+/* membership agreements. */
+/* */
+/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
+/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
+/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
+/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
+/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
+/* */
+/* - Without limitation, TCG and its members and licensors disclaim all */
+/* liability, including liability for infringement of any proprietary */
+/* rights, relating to use of information in this specification and to the */
+/* implementation of this specification, and TCG disclaims all liability for */
+/* cost of procurement of substitute goods or services, lost profits, loss */
+/* of use, loss of data or any incidental, consequential, direct, indirect, */
+/* or special damages, whether under contract, tort, warranty or otherwise, */
+/* arising in any way out of use or reliance upon this specification or any */
+/* information herein. */
+/* */
+/* (c) Copyright IBM Corp. and others, 2012-2015 */
+/* */
+/********************************************************************************/
+
+/* rev 119 */
+
+#ifndef PCR_EVENT_FP_H
+#define PCR_EVENT_FP_H
+
+typedef struct {
+ TPMI_DH_PCR pcrHandle;
+ TPM2B_EVENT eventData;
+} PCR_Event_In;
+
+#define RC_PCR_Event_pcrHandle (TPM_RC_H + TPM_RC_1)
+#define RC_PCR_Event_eventData (TPM_RC_P + TPM_RC_1)
+
+typedef struct {
+ TPML_DIGEST_VALUES digests;
+} PCR_Event_Out;
+
+TPM_RC
+TPM2_PCR_Event(
+ PCR_Event_In *in, // IN: input parameter list
+ PCR_Event_Out *out // OUT: output parameter list
+ );
+
+#endif
diff --git a/src/tpm2/PCR_Extend_fp.h b/src/tpm2/PCR_Extend_fp.h
new file mode 100644
index 0000000..37ca3f9
--- /dev/null
+++ b/src/tpm2/PCR_Extend_fp.h
@@ -0,0 +1,81 @@
+/********************************************************************************/
+/* */
+/* */
+/* Written by Ken Goldman */
+/* IBM Thomas J. Watson Research Center */
+/* $Id: PCR_Extend_fp.h 809 2016-11-16 18:31:54Z kgoldman $ */
+/* */
+/* Licenses and Notices */
+/* */
+/* 1. Copyright Licenses: */
+/* */
+/* - Trusted Computing Group (TCG) grants to the user of the source code in */
+/* this specification (the "Source Code") a worldwide, irrevocable, */
+/* nonexclusive, royalty free, copyright license to reproduce, create */
+/* derivative works, distribute, display and perform the Source Code and */
+/* derivative works thereof, and to grant others the rights granted herein. */
+/* */
+/* - The TCG grants to the user of the other parts of the specification */
+/* (other than the Source Code) the rights to reproduce, distribute, */
+/* display, and perform the specification solely for the purpose of */
+/* developing products based on such documents. */
+/* */
+/* 2. Source Code Distribution Conditions: */
+/* */
+/* - Redistributions of Source Code must retain the above copyright licenses, */
+/* this list of conditions and the following disclaimers. */
+/* */
+/* - Redistributions in binary form must reproduce the above copyright */
+/* licenses, this list of conditions and the following disclaimers in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* 3. Disclaimers: */
+/* */
+/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
+/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
+/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
+/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
+/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
+/* information on specification licensing rights available through TCG */
+/* membership agreements. */
+/* */
+/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
+/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
+/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
+/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
+/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
+/* */
+/* - Without limitation, TCG and its members and licensors disclaim all */
+/* liability, including liability for infringement of any proprietary */
+/* rights, relating to use of information in this specification and to the */
+/* implementation of this specification, and TCG disclaims all liability for */
+/* cost of procurement of substitute goods or services, lost profits, loss */
+/* of use, loss of data or any incidental, consequential, direct, indirect, */
+/* or special damages, whether under contract, tort, warranty or otherwise, */
+/* arising in any way out of use or reliance upon this specification or any */
+/* information herein. */
+/* */
+/* (c) Copyright IBM Corp. and others, 2012-2015 */
+/* */
+/********************************************************************************/
+
+/* rev 119 */
+
+#ifndef PCR_EXTEND_FP_H
+#define PCR_EXTEND_FP_H
+
+typedef struct {
+ TPMI_DH_PCR pcrHandle;
+ TPML_DIGEST_VALUES digests;
+} PCR_Extend_In;
+
+#define RC_PCR_Extend_pcrHandle (TPM_RC_H + TPM_RC_1)
+#define RC_PCR_Extend_digests (TPM_RC_P + TPM_RC_1)
+
+TPM_RC
+TPM2_PCR_Extend(
+ PCR_Extend_In *in // IN: input parameter list
+ );
+
+
+#endif
diff --git a/src/tpm2/PCR_Read_fp.h b/src/tpm2/PCR_Read_fp.h
new file mode 100644
index 0000000..ec3ef40
--- /dev/null
+++ b/src/tpm2/PCR_Read_fp.h
@@ -0,0 +1,85 @@
+/********************************************************************************/
+/* */
+/* */
+/* Written by Ken Goldman */
+/* IBM Thomas J. Watson Research Center */
+/* $Id: PCR_Read_fp.h 809 2016-11-16 18:31:54Z kgoldman $ */
+/* */
+/* Licenses and Notices */
+/* */
+/* 1. Copyright Licenses: */
+/* */
+/* - Trusted Computing Group (TCG) grants to the user of the source code in */
+/* this specification (the "Source Code") a worldwide, irrevocable, */
+/* nonexclusive, royalty free, copyright license to reproduce, create */
+/* derivative works, distribute, display and perform the Source Code and */
+/* derivative works thereof, and to grant others the rights granted herein. */
+/* */
+/* - The TCG grants to the user of the other parts of the specification */
+/* (other than the Source Code) the rights to reproduce, distribute, */
+/* display, and perform the specification solely for the purpose of */
+/* developing products based on such documents. */
+/* */
+/* 2. Source Code Distribution Conditions: */
+/* */
+/* - Redistributions of Source Code must retain the above copyright licenses, */
+/* this list of conditions and the following disclaimers. */
+/* */
+/* - Redistributions in binary form must reproduce the above copyright */
+/* licenses, this list of conditions and the following disclaimers in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* 3. Disclaimers: */
+/* */
+/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
+/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
+/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
+/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
+/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
+/* information on specification licensing rights available through TCG */
+/* membership agreements. */
+/* */
+/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
+/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
+/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
+/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
+/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
+/* */
+/* - Without limitation, TCG and its members and licensors disclaim all */
+/* liability, including liability for infringement of any proprietary */
+/* rights, relating to use of information in this specification and to the */
+/* implementation of this specification, and TCG disclaims all liability for */
+/* cost of procurement of substitute goods or services, lost profits, loss */
+/* of use, loss of data or any incidental, consequential, direct, indirect, */
+/* or special damages, whether under contract, tort, warranty or otherwise, */
+/* arising in any way out of use or reliance upon this specification or any */
+/* information herein. */
+/* */
+/* (c) Copyright IBM Corp. and others, 2012-2015 */
+/* */
+/********************************************************************************/
+
+/* rev 119 */
+
+#ifndef PCR_READ_FP_H
+#define PCR_READ_FP_H
+
+typedef struct {
+ TPML_PCR_SELECTION pcrSelectionIn;
+} PCR_Read_In;
+
+#define RC_PCR_Read_pcrSelectionIn (TPM_RC_P + TPM_RC_1)
+
+typedef struct {
+ UINT32 pcrUpdateCounter;
+ TPML_PCR_SELECTION pcrSelectionOut;
+ TPML_DIGEST pcrValues;
+} PCR_Read_Out;
+
+TPM_RC
+TPM2_PCR_Read(
+ PCR_Read_In *in, // IN: input parameter list
+ PCR_Read_Out *out // OUT: output parameter list
+ );
+
+#endif
diff --git a/src/tpm2/PCR_Reset_fp.h b/src/tpm2/PCR_Reset_fp.h
new file mode 100644
index 0000000..835d2a0
--- /dev/null
+++ b/src/tpm2/PCR_Reset_fp.h
@@ -0,0 +1,78 @@
+/********************************************************************************/
+/* */
+/* */
+/* Written by Ken Goldman */
+/* IBM Thomas J. Watson Research Center */
+/* $Id: PCR_Reset_fp.h 809 2016-11-16 18:31:54Z kgoldman $ */
+/* */
+/* Licenses and Notices */
+/* */
+/* 1. Copyright Licenses: */
+/* */
+/* - Trusted Computing Group (TCG) grants to the user of the source code in */
+/* this specification (the "Source Code") a worldwide, irrevocable, */
+/* nonexclusive, royalty free, copyright license to reproduce, create */
+/* derivative works, distribute, display and perform the Source Code and */
+/* derivative works thereof, and to grant others the rights granted herein. */
+/* */
+/* - The TCG grants to the user of the other parts of the specification */
+/* (other than the Source Code) the rights to reproduce, distribute, */
+/* display, and perform the specification solely for the purpose of */
+/* developing products based on such documents. */
+/* */
+/* 2. Source Code Distribution Conditions: */
+/* */
+/* - Redistributions of Source Code must retain the above copyright licenses, */
+/* this list of conditions and the following disclaimers. */
+/* */
+/* - Redistributions in binary form must reproduce the above copyright */
+/* licenses, this list of conditions and the following disclaimers in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* 3. Disclaimers: */
+/* */
+/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
+/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
+/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
+/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
+/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
+/* information on specification licensing rights available through TCG */
+/* membership agreements. */
+/* */
+/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
+/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
+/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
+/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
+/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
+/* */
+/* - Without limitation, TCG and its members and licensors disclaim all */
+/* liability, including liability for infringement of any proprietary */
+/* rights, relating to use of information in this specification and to the */
+/* implementation of this specification, and TCG disclaims all liability for */
+/* cost of procurement of substitute goods or services, lost profits, loss */
+/* of use, loss of data or any incidental, consequential, direct, indirect, */
+/* or special damages, whether under contract, tort, warranty or otherwise, */
+/* arising in any way out of use or reliance upon this specification or any */
+/* information herein. */
+/* */
+/* (c) Copyright IBM Corp. and others, 2012-2015 */
+/* */
+/********************************************************************************/
+
+/* rev 119 */
+
+#ifndef PCR_RESET_FP_H
+#define PCR_RESET_FP_H
+
+typedef struct {
+ TPMI_DH_PCR pcrHandle;
+} PCR_Reset_In;
+
+#define RC_PCR_Reset__pcrHandle (TPM_RC_H + TPM_RC_1)
+
+TPM_RC
+TPM2_PCR_Reset(
+ PCR_Reset_In *in // IN: input parameter list
+ );
+
+#endif
diff --git a/src/tpm2/PCR_SetAuthPolicy_fp.h b/src/tpm2/PCR_SetAuthPolicy_fp.h
new file mode 100644
index 0000000..3d8a02b
--- /dev/null
+++ b/src/tpm2/PCR_SetAuthPolicy_fp.h
@@ -0,0 +1,85 @@
+/********************************************************************************/
+/* */
+/* */
+/* Written by Ken Goldman */
+/* IBM Thomas J. Watson Research Center */
+/* $Id: PCR_SetAuthPolicy_fp.h 809 2016-11-16 18:31:54Z kgoldman $ */
+/* */
+/* Licenses and Notices */
+/* */
+/* 1. Copyright Licenses: */
+/* */
+/* - Trusted Computing Group (TCG) grants to the user of the source code in */
+/* this specification (the "Source Code") a worldwide, irrevocable, */
+/* nonexclusive, royalty free, copyright license to reproduce, create */
+/* derivative works, distribute, display and perform the Source Code and */
+/* derivative works thereof, and to grant others the rights granted herein. */
+/* */
+/* - The TCG grants to the user of the other parts of the specification */
+/* (other than the Source Code) the rights to reproduce, distribute, */
+/* display, and perform the specification solely for the purpose of */
+/* developing products based on such documents. */
+/* */
+/* 2. Source Code Distribution Conditions: */
+/* */
+/* - Redistributions of Source Code must retain the above copyright licenses, */
+/* this list of conditions and the following disclaimers. */
+/* */
+/* - Redistributions in binary form must reproduce the above copyright */
+/* licenses, this list of conditions and the following disclaimers in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* 3. Disclaimers: */
+/* */
+/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
+/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
+/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
+/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
+/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
+/* information on specification licensing rights available through TCG */
+/* membership agreements. */
+/* */
+/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
+/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
+/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
+/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
+/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
+/* */
+/* - Without limitation, TCG and its members and licensors disclaim all */
+/* liability, including liability for infringement of any proprietary */
+/* rights, relating to use of information in this specification and to the */
+/* implementation of this specification, and TCG disclaims all liability for */
+/* cost of procurement of substitute goods or services, lost profits, loss */
+/* of use, loss of data or any incidental, consequential, direct, indirect, */
+/* or special damages, whether under contract, tort, warranty or otherwise, */
+/* arising in any way out of use or reliance upon this specification or any */
+/* information herein. */
+/* */
+/* (c) Copyright IBM Corp. and others, 2012-2015 */
+/* */
+/********************************************************************************/
+
+/* rev 119 */
+
+#ifndef PCR_SETAUTHPOLICY_FP_H
+#define PCR_SETAUTHPOLICY_FP_H
+
+typedef struct {
+ TPMI_RH_PLATFORM authHandle;
+ TPM2B_DIGEST authPolicy;
+ TPMI_ALG_HASH hashAlg;
+ TPMI_DH_PCR pcrNum;
+} PCR_SetAuthPolicy_In;
+
+#define RC_PCR_SetAuthPolicy_authHandle (TPM_RC_H + TPM_RC_1)
+#define RC_PCR_SetAuthPolicy_authPolicy (TPM_RC_P + TPM_RC_1)
+#define RC_PCR_SetAuthPolicy_hashAlg (TPM_RC_P + TPM_RC_2)
+#define RC_PCR_SetAuthPolicy_pcrNum (TPM_RC_P + TPM_RC_3)
+
+TPM_RC
+TPM2_PCR_SetAuthPolicy(
+ PCR_SetAuthPolicy_In *in // IN: input parameter list
+ );
+
+
+#endif
diff --git a/src/tpm2/PCR_SetAuthValue_fp.h b/src/tpm2/PCR_SetAuthValue_fp.h
new file mode 100644
index 0000000..a06c3f6
--- /dev/null
+++ b/src/tpm2/PCR_SetAuthValue_fp.h
@@ -0,0 +1,81 @@
+/********************************************************************************/
+/* */
+/* */
+/* Written by Ken Goldman */
+/* IBM Thomas J. Watson Research Center */
+/* $Id: PCR_SetAuthValue_fp.h 809 2016-11-16 18:31:54Z kgoldman $ */
+/* */
+/* Licenses and Notices */
+/* */
+/* 1. Copyright Licenses: */
+/* */
+/* - Trusted Computing Group (TCG) grants to the user of the source code in */
+/* this specification (the "Source Code") a worldwide, irrevocable, */
+/* nonexclusive, royalty free, copyright license to reproduce, create */
+/* derivative works, distribute, display and perform the Source Code and */
+/* derivative works thereof, and to grant others the rights granted herein. */
+/* */
+/* - The TCG grants to the user of the other parts of the specification */
+/* (other than the Source Code) the rights to reproduce, distribute, */
+/* display, and perform the specification solely for the purpose of */
+/* developing products based on such documents. */
+/* */
+/* 2. Source Code Distribution Conditions: */
+/* */
+/* - Redistributions of Source Code must retain the above copyright licenses, */
+/* this list of conditions and the following disclaimers. */
+/* */
+/* - Redistributions in binary form must reproduce the above copyright */
+/* licenses, this list of conditions and the following disclaimers in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* 3. Disclaimers: */
+/* */
+/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
+/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
+/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
+/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
+/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
+/* information on specification licensing rights available through TCG */
+/* membership agreements. */
+/* */
+/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
+/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
+/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
+/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
+/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
+/* */
+/* - Without limitation, TCG and its members and licensors disclaim all */
+/* liability, including liability for infringement of any proprietary */
+/* rights, relating to use of information in this specification and to the */
+/* implementation of this specification, and TCG disclaims all liability for */
+/* cost of procurement of substitute goods or services, lost profits, loss */
+/* of use, loss of data or any incidental, consequential, direct, indirect, */
+/* or special damages, whether under contract, tort, warranty or otherwise, */
+/* arising in any way out of use or reliance upon this specification or any */
+/* information herein. */
+/* */
+/* (c) Copyright IBM Corp. and others, 2012-2015 */
+/* */
+/********************************************************************************/
+
+/* rev 119 */
+
+#ifndef PCR_SETAUTHVALUE_FP_H
+#define PCR_SETAUTHVALUE_FP_H
+
+typedef struct {
+ TPMI_DH_PCR pcrHandle;
+ TPM2B_DIGEST auth;
+} PCR_SetAuthValue_In;
+
+#define RC_PCR_SetAuthValue_pcrHandle (TPM_RC_H + TPM_RC_1)
+#define RC_PCR_SetAuthValue_auth (TPM_RC_P + TPM_RC_1)
+
+TPM_RC
+TPM2_PCR_SetAuthValue(
+ PCR_SetAuthValue_In *in // IN: input parameter list
+ );
+
+
+#endif
diff --git a/src/tpm2/PCR_fp.h b/src/tpm2/PCR_fp.h
new file mode 100644
index 0000000..cfad535
--- /dev/null
+++ b/src/tpm2/PCR_fp.h
@@ -0,0 +1,197 @@
+/********************************************************************************/
+/* */
+/* Functions Needed for PCR Access and Manipulation */
+/* Written by Ken Goldman */
+/* IBM Thomas J. Watson Research Center */
+/* $Id: PCR_fp.h 1519 2019-11-15 20:43:51Z kgoldman $ */
+/* */
+/* Licenses and Notices */
+/* */
+/* 1. Copyright Licenses: */
+/* */
+/* - Trusted Computing Group (TCG) grants to the user of the source code in */
+/* this specification (the "Source Code") a worldwide, irrevocable, */
+/* nonexclusive, royalty free, copyright license to reproduce, create */
+/* derivative works, distribute, display and perform the Source Code and */
+/* derivative works thereof, and to grant others the rights granted herein. */
+/* */
+/* - The TCG grants to the user of the other parts of the specification */
+/* (other than the Source Code) the rights to reproduce, distribute, */
+/* display, and perform the specification solely for the purpose of */
+/* developing products based on such documents. */
+/* */
+/* 2. Source Code Distribution Conditions: */
+/* */
+/* - Redistributions of Source Code must retain the above copyright licenses, */
+/* this list of conditions and the following disclaimers. */
+/* */
+/* - Redistributions in binary form must reproduce the above copyright */
+/* licenses, this list of conditions and the following disclaimers in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* 3. Disclaimers: */
+/* */
+/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
+/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
+/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
+/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
+/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
+/* information on specification licensing rights available through TCG */
+/* membership agreements. */
+/* */
+/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
+/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
+/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
+/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
+/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
+/* */
+/* - Without limitation, TCG and its members and licensors disclaim all */
+/* liability, including liability for infringement of any proprietary */
+/* rights, relating to use of information in this specification and to the */
+/* implementation of this specification, and TCG disclaims all liability for */
+/* cost of procurement of substitute goods or services, lost profits, loss */
+/* of use, loss of data or any incidental, consequential, direct, indirect, */
+/* or special damages, whether under contract, tort, warranty or otherwise, */
+/* arising in any way out of use or reliance upon this specification or any */
+/* information herein. */
+/* */
+/* (c) Copyright IBM Corp. and others, 2016 - 2019 */
+/* */
+/********************************************************************************/
+
+#ifndef PCR_FP_H
+#define PCR_FP_H
+
+BOOL
+PCRBelongsAuthGroup(
+ TPMI_DH_PCR handle, // IN: handle of PCR
+ UINT32 *groupIndex // OUT: group index if PCR belongs a
+ // group that allows authValue. If PCR
+ // does not belong to an authorization
+ // group, the value in this parameter is
+ // invalid
+ );
+BOOL
+PCRBelongsPolicyGroup(
+ TPMI_DH_PCR handle, // IN: handle of PCR
+ UINT32 *groupIndex // OUT: group index if PCR belongs a group that
+ // allows policy. If PCR does not belong to
+ // a policy group, the value in this
+ // parameter is invalid
+ );
+BOOL
+PCRPolicyIsAvailable(
+ TPMI_DH_PCR handle // IN: PCR handle
+ );
+TPM2B_AUTH *
+PCRGetAuthValue(
+ TPMI_DH_PCR handle // IN: PCR handle
+ );
+TPMI_ALG_HASH
+PCRGetAuthPolicy(
+ TPMI_DH_PCR handle, // IN: PCR handle
+ TPM2B_DIGEST *policy // OUT: policy of PCR
+ );
+void
+PCRSimStart(
+ void
+ );
+BOOL
+PcrIsAllocated(
+ UINT32 pcr, // IN: The number of the PCR
+ TPMI_ALG_HASH hashAlg // IN: The PCR algorithm
+ );
+void
+PcrDrtm(
+ const TPMI_DH_PCR pcrHandle, // IN: the index of the PCR to be
+ // modified
+ const TPMI_ALG_HASH hash, // IN: the bank identifier
+ const TPM2B_DIGEST *digest // IN: the digest to modify the PCR
+ );
+void
+PCR_ClearAuth(
+ void
+ );
+BOOL
+PCRStartup(
+ STARTUP_TYPE type, // IN: startup type
+ BYTE locality // IN: startup locality
+ );
+void
+PCRStateSave(
+ TPM_SU type // IN: startup type
+ );
+BOOL
+PCRIsStateSaved(
+ TPMI_DH_PCR handle // IN: PCR handle to be extended
+ );
+BOOL
+PCRIsResetAllowed(
+ TPMI_DH_PCR handle // IN: PCR handle to be extended
+ );
+void
+PCRChanged(
+ TPM_HANDLE pcrHandle // IN: the handle of the PCR that changed.
+ );
+BOOL
+PCRIsExtendAllowed(
+ TPMI_DH_PCR handle // IN: PCR handle to be extended
+ );
+void
+PCRExtend(
+ TPMI_DH_PCR handle, // IN: PCR handle to be extended
+ TPMI_ALG_HASH hash, // IN: hash algorithm of PCR
+ UINT32 size, // IN: size of data to be extended
+ BYTE *data // IN: data to be extended
+ );
+void
+PCRComputeCurrentDigest(
+ TPMI_ALG_HASH hashAlg, // IN: hash algorithm to compute digest
+ TPML_PCR_SELECTION *selection, // IN/OUT: PCR selection (filtered on
+ // output)
+ TPM2B_DIGEST *digest // OUT: digest
+ );
+void
+PCRRead(
+ TPML_PCR_SELECTION *selection, // IN/OUT: PCR selection (filtered on
+ // output)
+ TPML_DIGEST *digest, // OUT: digest
+ UINT32 *pcrCounter // OUT: the current value of PCR generation
+ // number
+ );
+TPM_RC
+PCRAllocate(
+ TPML_PCR_SELECTION *allocate, // IN: required allocation
+ UINT32 *maxPCR, // OUT: Maximum number of PCR
+ UINT32 *sizeNeeded, // OUT: required space
+ UINT32 *sizeAvailable // OUT: available space
+ );
+void
+PCRSetValue(
+ TPM_HANDLE handle, // IN: the handle of the PCR to set
+ INT8 initialValue // IN: the value to set
+ );
+void
+PCRResetDynamics(
+ void
+ );
+TPMI_YES_NO
+PCRCapGetAllocation(
+ UINT32 count, // IN: count of return
+ TPML_PCR_SELECTION *pcrSelection // OUT: PCR allocation list
+ );
+TPMI_YES_NO
+PCRCapGetProperties(
+ TPM_PT_PCR property, // IN: the starting PCR property
+ UINT32 count, // IN: count of returned properties
+ TPML_TAGGED_PCR_PROPERTY *select // OUT: PCR select
+ );
+TPMI_YES_NO
+PCRCapGetHandles(
+ TPMI_DH_PCR handle, // IN: start handle
+ UINT32 count, // IN: count of returned handles
+ TPML_HANDLE *handleList // OUT: list of handle
+ );
+
+
+#endif
diff --git a/src/tpm2/PP.c b/src/tpm2/PP.c
new file mode 100644
index 0000000..2c73010
--- /dev/null
+++ b/src/tpm2/PP.c
@@ -0,0 +1,182 @@
+/********************************************************************************/
+/* */
+/* */
+/* Written by Ken Goldman */
+/* IBM Thomas J. Watson Research Center */
+/* $Id: PP.c 1490 2019-07-26 21:13:22Z kgoldman $ */
+/* */
+/* Licenses and Notices */
+/* */
+/* 1. Copyright Licenses: */
+/* */
+/* - Trusted Computing Group (TCG) grants to the user of the source code in */
+/* this specification (the "Source Code") a worldwide, irrevocable, */
+/* nonexclusive, royalty free, copyright license to reproduce, create */
+/* derivative works, distribute, display and perform the Source Code and */
+/* derivative works thereof, and to grant others the rights granted herein. */
+/* */
+/* - The TCG grants to the user of the other parts of the specification */
+/* (other than the Source Code) the rights to reproduce, distribute, */
+/* display, and perform the specification solely for the purpose of */
+/* developing products based on such documents. */
+/* */
+/* 2. Source Code Distribution Conditions: */
+/* */
+/* - Redistributions of Source Code must retain the above copyright licenses, */
+/* this list of conditions and the following disclaimers. */
+/* */
+/* - Redistributions in binary form must reproduce the above copyright */
+/* licenses, this list of conditions and the following disclaimers in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* 3. Disclaimers: */
+/* */
+/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
+/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
+/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
+/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
+/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
+/* information on specification licensing rights available through TCG */
+/* membership agreements. */
+/* */
+/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
+/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
+/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
+/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
+/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
+/* */
+/* - Without limitation, TCG and its members and licensors disclaim all */
+/* liability, including liability for infringement of any proprietary */
+/* rights, relating to use of information in this specification and to the */
+/* implementation of this specification, and TCG disclaims all liability for */
+/* cost of procurement of substitute goods or services, lost profits, loss */
+/* of use, loss of data or any incidental, consequential, direct, indirect, */
+/* or special damages, whether under contract, tort, warranty or otherwise, */
+/* arising in any way out of use or reliance upon this specification or any */
+/* information herein. */
+/* */
+/* (c) Copyright IBM Corp. and others, 2016 */
+/* */
+/********************************************************************************/
+
+/* 8.8 PP.c */
+/* 8.8.1 Introduction */
+/* This file contains the functions that support the physical presence operations of the TPM. */
+/* 8.8.2 Includes */
+#include "Tpm.h"
+/* 8.8.3 Functions */
+/* 8.8.3.1 PhysicalPresencePreInstall_Init() */
+/* This function is used to initialize the array of commands that always require confirmation with
+ physical presence. The array is an array of bits that has a correspondence with the command
+ code. */
+/* This command should only ever be executable in a manufacturing setting or in a simulation. */
+/* When set, these cannot be cleared. */
+void
+PhysicalPresencePreInstall_Init(
+ void
+ )
+{
+ COMMAND_INDEX commandIndex;
+ // Clear all the PP commands
+ MemorySet(&gp.ppList, 0, sizeof(gp.ppList));
+ // Any command that is PP_REQUIRED should be SET
+ for(commandIndex = 0; commandIndex < COMMAND_COUNT; commandIndex++)
+ {
+ if(s_commandAttributes[commandIndex] & IS_IMPLEMENTED
+ && s_commandAttributes[commandIndex] & PP_REQUIRED)
+ SET_BIT(commandIndex, gp.ppList);
+ }
+ // Write PP list to NV
+ NV_SYNC_PERSISTENT(ppList);
+ return;
+}
+/* 8.8.3.2 PhysicalPresenceCommandSet() */
+/* This function is used to set the indicator that a command requires PP confirmation. */
+void
+PhysicalPresenceCommandSet(
+ TPM_CC commandCode // IN: command code
+ )
+{
+ COMMAND_INDEX commandIndex = CommandCodeToCommandIndex(commandCode);
+ // if the command isn't implemented, the do nothing
+ if(commandIndex == UNIMPLEMENTED_COMMAND_INDEX)
+ return;
+ // only set the bit if this is a command for which PP is allowed
+ if(s_commandAttributes[commandIndex] & PP_COMMAND)
+ SET_BIT(commandIndex, gp.ppList);
+ return;
+}
+/* 8.8.3.3 PhysicalPresenceCommandClear() */
+/* This function is used to clear the indicator that a command requires PP confirmation. */
+void
+PhysicalPresenceCommandClear(
+ TPM_CC commandCode // IN: command code
+ )
+{
+ COMMAND_INDEX commandIndex = CommandCodeToCommandIndex(commandCode);
+ // If the command isn't implemented, then don't do anything
+ if(commandIndex == UNIMPLEMENTED_COMMAND_INDEX)
+ return;
+ // Only clear the bit if the command does not require PP
+ if((s_commandAttributes[commandIndex] & PP_REQUIRED) == 0)
+ CLEAR_BIT(commandIndex, gp.ppList);
+ return;
+}
+/* 8.8.3.4 PhysicalPresenceIsRequired() */
+/* This function indicates if PP confirmation is required for a command. */
+/* Return Values Meaning */
+/* TRUE if physical presence is required */
+/* FALSE if physical presence is not required */
+BOOL
+PhysicalPresenceIsRequired(
+ COMMAND_INDEX commandIndex // IN: command index
+ )
+{
+ // Check the bit map. If the bit is SET, PP authorization is required
+ return (TEST_BIT(commandIndex, gp.ppList));
+}
+/* 8.8.3.5 PhysicalPresenceCapGetCCList() */
+/* This function returns a list of commands that require PP confirmation. The list starts from the
+ first implemented command that has a command code that the same or greater than commandCode. */
+/* Return Values Meaning */
+/* YES if there are more command codes available */
+/* NO all the available command codes have been returned */
+TPMI_YES_NO
+PhysicalPresenceCapGetCCList(
+ TPM_CC commandCode, // IN: start command code
+ UINT32 count, // IN: count of returned TPM_CC
+ TPML_CC *commandList // OUT: list of TPM_CC
+ )
+{
+ TPMI_YES_NO more = NO;
+ COMMAND_INDEX commandIndex;
+ // Initialize output handle list
+ commandList->count = 0;
+ // The maximum count of command we may return is MAX_CAP_CC
+ if(count > MAX_CAP_CC) count = MAX_CAP_CC;
+ // Collect PP commands
+ for(commandIndex = GetClosestCommandIndex(commandCode);
+ commandIndex != UNIMPLEMENTED_COMMAND_INDEX;
+ commandIndex = GetNextCommandIndex(commandIndex))
+ {
+ if(PhysicalPresenceIsRequired(commandIndex))
+ {
+ if(commandList->count < count)
+ {
+ // If we have not filled up the return list, add this command
+ // code to it
+ commandList->commandCodes[commandList->count]
+ = GetCommandCode(commandIndex);
+ commandList->count++;
+ }
+ else
+ {
+ // If the return list is full but we still have PP command
+ // available, report this and stop iterating
+ more = YES;
+ break;
+ }
+ }
+ }
+ return more;
+}
diff --git a/src/tpm2/PPPlat.c b/src/tpm2/PPPlat.c
new file mode 100644
index 0000000..edb0007
--- /dev/null
+++ b/src/tpm2/PPPlat.c
@@ -0,0 +1,112 @@
+/********************************************************************************/
+/* */
+/* Simulates the Physical Present Interface */
+/* Written by Ken Goldman */
+/* IBM Thomas J. Watson Research Center */
+/* $Id: PPPlat.c 1490 2019-07-26 21:13:22Z kgoldman $ */
+/* */
+/* Licenses and Notices */
+/* */
+/* 1. Copyright Licenses: */
+/* */
+/* - Trusted Computing Group (TCG) grants to the user of the source code in */
+/* this specification (the "Source Code") a worldwide, irrevocable, */
+/* nonexclusive, royalty free, copyright license to reproduce, create */
+/* derivative works, distribute, display and perform the Source Code and */
+/* derivative works thereof, and to grant others the rights granted herein. */
+/* */
+/* - The TCG grants to the user of the other parts of the specification */
+/* (other than the Source Code) the rights to reproduce, distribute, */
+/* display, and perform the specification solely for the purpose of */
+/* developing products based on such documents. */
+/* */
+/* 2. Source Code Distribution Conditions: */
+/* */
+/* - Redistributions of Source Code must retain the above copyright licenses, */
+/* this list of conditions and the following disclaimers. */
+/* */
+/* - Redistributions in binary form must reproduce the above copyright */
+/* licenses, this list of conditions and the following disclaimers in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* 3. Disclaimers: */
+/* */
+/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
+/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
+/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
+/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
+/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
+/* information on specification licensing rights available through TCG */
+/* membership agreements. */
+/* */
+/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
+/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
+/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
+/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
+/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
+/* */
+/* - Without limitation, TCG and its members and licensors disclaim all */
+/* liability, including liability for infringement of any proprietary */
+/* rights, relating to use of information in this specification and to the */
+/* implementation of this specification, and TCG disclaims all liability for */
+/* cost of procurement of substitute goods or services, lost profits, loss */
+/* of use, loss of data or any incidental, consequential, direct, indirect, */
+/* or special damages, whether under contract, tort, warranty or otherwise, */
+/* arising in any way out of use or reliance upon this specification or any */
+/* information herein. */
+/* */
+/* (c) Copyright IBM Corp. and others, 2016 - 2019 */
+/* */
+/********************************************************************************/
+
+/* C.10 PPPlat.c */
+/* C.10.1. Description */
+/* This module simulates the physical presence interface pins on the TPM. */
+/* C.10.2. Includes */
+#include "Platform.h"
+#include "LibtpmsCallbacks.h" /* libtpms added */
+/* C.10.3. Functions */
+/* C.10.3.1. _plat__PhysicalPresenceAsserted() */
+/* Check if physical presence is signaled */
+/* Return Values Meaning */
+/* TRUE(1) if physical presence is signaled */
+/* FALSE(0) if physical presence is not signaled */
+LIB_EXPORT int
+_plat__PhysicalPresenceAsserted(
+ void
+ )
+{
+#ifdef TPM_LIBTPMS_CALLBACKS
+ BOOL pp;
+ int ret = libtpms_plat__PhysicalPresenceAsserted(&pp);
+
+ if (ret != LIBTPMS_CALLBACK_FALLTHROUGH)
+ return pp;
+#endif /* TPM_LIBTPMS_CALLBACKS */
+
+ // Do not know how to check physical presence without real hardware.
+ // so always return TRUE;
+ return s_physicalPresence;
+}
+#if 0 /* libtpms added */
+/* C.10.3.2. _plat__Signal_PhysicalPresenceOn() */
+/* Signal physical presence on */
+LIB_EXPORT void
+_plat__Signal_PhysicalPresenceOn(
+ void
+ )
+{
+ s_physicalPresence = TRUE;
+ return;
+}
+/* C.10.3.3. _plat__Signal_PhysicalPresenceOff() */
+/* Signal physical presence off */
+LIB_EXPORT void
+_plat__Signal_PhysicalPresenceOff(
+ void
+ )
+{
+ s_physicalPresence = FALSE;
+ return;
+}
+#endif /* libtpms added */
diff --git a/src/tpm2/PP_Commands_fp.h b/src/tpm2/PP_Commands_fp.h
new file mode 100644
index 0000000..7f858c6
--- /dev/null
+++ b/src/tpm2/PP_Commands_fp.h
@@ -0,0 +1,80 @@
+/********************************************************************************/
+/* */
+/* */
+/* Written by Ken Goldman */
+/* IBM Thomas J. Watson Research Center */
+/* $Id: PP_Commands_fp.h 1521 2019-11-15 21:00:47Z kgoldman $ */
+/* */
+/* Licenses and Notices */
+/* */
+/* 1. Copyright Licenses: */
+/* */
+/* - Trusted Computing Group (TCG) grants to the user of the source code in */
+/* this specification (the "Source Code") a worldwide, irrevocable, */
+/* nonexclusive, royalty free, copyright license to reproduce, create */
+/* derivative works, distribute, display and perform the Source Code and */
+/* derivative works thereof, and to grant others the rights granted herein. */
+/* */
+/* - The TCG grants to the user of the other parts of the specification */
+/* (other than the Source Code) the rights to reproduce, distribute, */
+/* display, and perform the specification solely for the purpose of */
+/* developing products based on such documents. */
+/* */
+/* 2. Source Code Distribution Conditions: */
+/* */
+/* - Redistributions of Source Code must retain the above copyright licenses, */
+/* this list of conditions and the following disclaimers. */
+/* */
+/* - Redistributions in binary form must reproduce the above copyright */
+/* licenses, this list of conditions and the following disclaimers in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* 3. Disclaimers: */
+/* */
+/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
+/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
+/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
+/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
+/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
+/* information on specification licensing rights available through TCG */
+/* membership agreements. */
+/* */
+/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
+/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
+/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
+/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
+/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
+/* */
+/* - Without limitation, TCG and its members and licensors disclaim all */
+/* liability, including liability for infringement of any proprietary */
+/* rights, relating to use of information in this specification and to the */
+/* implementation of this specification, and TCG disclaims all liability for */
+/* cost of procurement of substitute goods or services, lost profits, loss */
+/* of use, loss of data or any incidental, consequential, direct, indirect, */
+/* or special damages, whether under contract, tort, warranty or otherwise, */
+/* arising in any way out of use or reliance upon this specification or any */
+/* information herein. */
+/* */
+/* (c) Copyright IBM Corp. and others, 2016 */
+/* */
+/********************************************************************************/
+
+#ifndef PP_COMMANDS_FP_H
+#define PP_COMMANDS_FP_H
+
+typedef struct {
+ TPMI_RH_PLATFORM auth;
+ TPML_CC setList;
+ TPML_CC clearList;
+} PP_Commands_In;
+
+#define RC_PP_Commands_auth (TPM_RC_H + TPM_RC_1)
+#define RC_PP_Commands_setList (TPM_RC_P + TPM_RC_1)
+#define RC_PP_Commands_clearList (TPM_RC_P + TPM_RC_2)
+
+TPM_RC
+TPM2_PP_Commands(
+ PP_Commands_In *in // IN: input parameter list
+ );
+
+#endif
diff --git a/src/tpm2/PP_fp.h b/src/tpm2/PP_fp.h
new file mode 100644
index 0000000..fb78176
--- /dev/null
+++ b/src/tpm2/PP_fp.h
@@ -0,0 +1,89 @@
+/********************************************************************************/
+/* */
+/* */
+/* Written by Ken Goldman */
+/* IBM Thomas J. Watson Research Center */
+/* $Id: PP_fp.h 1490 2019-07-26 21:13:22Z kgoldman $ */
+/* */
+/* Licenses and Notices */
+/* */
+/* 1. Copyright Licenses: */
+/* */
+/* - Trusted Computing Group (TCG) grants to the user of the source code in */
+/* this specification (the "Source Code") a worldwide, irrevocable, */
+/* nonexclusive, royalty free, copyright license to reproduce, create */
+/* derivative works, distribute, display and perform the Source Code and */
+/* derivative works thereof, and to grant others the rights granted herein. */
+/* */
+/* - The TCG grants to the user of the other parts of the specification */
+/* (other than the Source Code) the rights to reproduce, distribute, */
+/* display, and perform the specification solely for the purpose of */
+/* developing products based on such documents. */
+/* */
+/* 2. Source Code Distribution Conditions: */
+/* */
+/* - Redistributions of Source Code must retain the above copyright licenses, */
+/* this list of conditions and the following disclaimers. */
+/* */
+/* - Redistributions in binary form must reproduce the above copyright */
+/* licenses, this list of conditions and the following disclaimers in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* 3. Disclaimers: */
+/* */
+/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
+/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
+/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
+/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
+/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
+/* information on specification licensing rights available through TCG */
+/* membership agreements. */
+/* */
+/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
+/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
+/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
+/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
+/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
+/* */
+/* - Without limitation, TCG and its members and licensors disclaim all */
+/* liability, including liability for infringement of any proprietary */
+/* rights, relating to use of information in this specification and to the */
+/* implementation of this specification, and TCG disclaims all liability for */
+/* cost of procurement of substitute goods or services, lost profits, loss */
+/* of use, loss of data or any incidental, consequential, direct, indirect, */
+/* or special damages, whether under contract, tort, warranty or otherwise, */
+/* arising in any way out of use or reliance upon this specification or any */
+/* information herein. */
+/* */
+/* (c) Copyright IBM Corp. and others, 2016 */
+/* */
+/********************************************************************************/
+
+#ifndef PP_FP_H
+#define PP_FP_H
+
+void
+PhysicalPresencePreInstall_Init(
+ void
+ );
+void
+PhysicalPresenceCommandSet(
+ TPM_CC commandCode // IN: command code
+ );
+void
+PhysicalPresenceCommandClear(
+ TPM_CC commandCode // IN: command code
+ );
+BOOL
+PhysicalPresenceIsRequired(
+ COMMAND_INDEX commandIndex // IN: command index
+ );
+TPMI_YES_NO
+PhysicalPresenceCapGetCCList(
+ TPM_CC commandCode, // IN: start command code
+ UINT32 count, // IN: count of returned TPM_CC
+ TPML_CC *commandList // OUT: list of TPM_CC
+ );
+
+
+#endif
diff --git a/src/tpm2/PRNG_TestVectors.h b/src/tpm2/PRNG_TestVectors.h
new file mode 100644
index 0000000..eca09b1
--- /dev/null
+++ b/src/tpm2/PRNG_TestVectors.h
@@ -0,0 +1,110 @@
+/********************************************************************************/
+/* */
+/* PRNG Test Vectors */
+/* Written by Ken Goldman */
+/* IBM Thomas J. Watson Research Center */
+/* $Id: PRNG_TestVectors.h 1529 2019-11-21 23:29:01Z kgoldman $ */
+/* */
+/* Licenses and Notices */
+/* */
+/* 1. Copyright Licenses: */
+/* */
+/* - Trusted Computing Group (TCG) grants to the user of the source code in */
+/* this specification (the "Source Code") a worldwide, irrevocable, */
+/* nonexclusive, royalty free, copyright license to reproduce, create */
+/* derivative works, distribute, display and perform the Source Code and */
+/* derivative works thereof, and to grant others the rights granted herein. */
+/* */
+/* - The TCG grants to the user of the other parts of the specification */
+/* (other than the Source Code) the rights to reproduce, distribute, */
+/* display, and perform the specification solely for the purpose of */
+/* developing products based on such documents. */
+/* */
+/* 2. Source Code Distribution Conditions: */
+/* */
+/* - Redistributions of Source Code must retain the above copyright licenses, */
+/* this list of conditions and the following disclaimers. */
+/* */
+/* - Redistributions in binary form must reproduce the above copyright */
+/* licenses, this list of conditions and the following disclaimers in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* 3. Disclaimers: */
+/* */
+/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
+/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
+/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
+/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
+/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
+/* information on specification licensing rights available through TCG */
+/* membership agreements. */
+/* */
+/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
+/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
+/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
+/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
+/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
+/* */
+/* - Without limitation, TCG and its members and licensors disclaim all */
+/* liability, including liability for infringement of any proprietary */
+/* rights, relating to use of information in this specification and to the */
+/* implementation of this specification, and TCG disclaims all liability for */
+/* cost of procurement of substitute goods or services, lost profits, loss */
+/* of use, loss of data or any incidental, consequential, direct, indirect, */
+/* or special damages, whether under contract, tort, warranty or otherwise, */
+/* arising in any way out of use or reliance upon this specification or any */
+/* information herein. */
+/* */
+/* (c) Copyright IBM Corp. and others, 2016 - 2019 */
+/* */
+/********************************************************************************/
+
+/* 10.1.17 PRNG_TestVectors.h */
+
+#ifndef _MSBN_DRBG_TEST_VECTORS_H
+#define _MSBN_DRBG_TEST_VECTORS_H
+//#if DRBG_ALGORITHM == TPM_ALG_AES && DRBG_KEY_BITS == 256
+#if DRBG_KEY_SIZE_BITS == 256
+
+/* Entropy is the size of the state. The state is the size of the key plus the IV. The IV is a
+ block. If Key = 256 and Block = 128 then State = 384 */
+
+#define DRBG_TEST_INITIATE_ENTROPY \
+ 0x0d, 0x15, 0xaa, 0x80, 0xb1, 0x6c, 0x3a, 0x10, \
+ 0x90, 0x6c, 0xfe, 0xdb, 0x79, 0x5d, 0xae, 0x0b, \
+ 0x5b, 0x81, 0x04, 0x1c, 0x5c, 0x5b, 0xfa, 0xcb, \
+ 0x37, 0x3d, 0x44, 0x40, 0xd9, 0x12, 0x0f, 0x7e, \
+ 0x3d, 0x6c, 0xf9, 0x09, 0x86, 0xcf, 0x52, 0xd8, \
+ 0x5d, 0x3e, 0x94, 0x7d, 0x8c, 0x06, 0x1f, 0x91
+#define DRBG_TEST_RESEED_ENTROPY \
+ 0x6e, 0xe7, 0x93, 0xa3, 0x39, 0x55, 0xd7, 0x2a, \
+ 0xd1, 0x2f, 0xd8, 0x0a, 0x8a, 0x3f, 0xcf, 0x95, \
+ 0xed, 0x3b, 0x4d, 0xac, 0x57, 0x95, 0xfe, 0x25, \
+ 0xcf, 0x86, 0x9f, 0x7c, 0x27, 0x57, 0x3b, 0xbc, \
+ 0x56, 0xf1, 0xac, 0xae, 0x13, 0xa6, 0x50, 0x42, \
+ 0xb3, 0x40, 0x09, 0x3c, 0x46, 0x4a, 0x7a, 0x22
+#define DRBG_TEST_GENERATED_INTERM \
+ 0x28, 0xe0, 0xeb, 0xb8, 0x21, 0x01, 0x66, 0x50, \
+ 0x8c, 0x8f, 0x65, 0xf2, 0x20, 0x7b, 0xd0, 0xa3
+#define DRBG_TEST_GENERATED \
+ 0x94, 0x6f, 0x51, 0x82, 0xd5, 0x45, 0x10, 0xb9, \
+ 0x46, 0x12, 0x48, 0xf5, 0x71, 0xca, 0x06, 0xc9
+#elif DRBG_KEY_SIZE_BITS == 128
+#define DRBG_TEST_INITIATE_ENTROPY \
+ 0x8f, 0xc1, 0x1b, 0xdb, 0x5a, 0xab, 0xb7, 0xe0, \
+ 0x93, 0xb6, 0x14, 0x28, 0xe0, 0x90, 0x73, 0x03, \
+ 0xcb, 0x45, 0x9f, 0x3b, 0x60, 0x0d, 0xad, 0x87, \
+ 0x09, 0x55, 0xf2, 0x2d, 0xa8, 0x0a, 0x44, 0xf8
+#define DRBG_TEST_RESEED_ENTROPY \
+ 0x0c, 0xd5, 0x3c, 0xd5, 0xec, 0xcd, 0x5a, 0x10, \
+ 0xd7, 0xea, 0x26, 0x61, 0x11, 0x25, 0x9b, 0x05, \
+ 0x57, 0x4f, 0xc6, 0xdd, 0xd8, 0xbe, 0xd8, 0xbd, \
+ 0x72, 0x37, 0x8c, 0xf8, 0x2f, 0x1d, 0xba, 0x2a
+#define DRBG_TEST_GENERATED_INTERM \
+ 0xdc, 0x3c, 0xf6, 0xbf, 0x5b, 0xd3, 0x41, 0x13, \
+ 0x5f, 0x2c, 0x68, 0x11, 0xa1, 0x07, 0x1c, 0x87
+#define DRBG_TEST_GENERATED \
+ 0xb6, 0x18, 0x50, 0xde, 0xcf, 0xd7, 0x10, 0x6d, \
+ 0x44, 0x76, 0x9a, 0x8e, 0x6e, 0x8c, 0x1a, 0xd4
+#endif
+#endif // _MSBN_DRBG_TEST_VECTORS_H
diff --git a/src/tpm2/Platform.h b/src/tpm2/Platform.h
new file mode 100644
index 0000000..126d0fe
--- /dev/null
+++ b/src/tpm2/Platform.h
@@ -0,0 +1,75 @@
+/********************************************************************************/
+/* */
+/* */
+/* Written by Ken Goldman */
+/* IBM Thomas J. Watson Research Center */
+/* $Id: Platform.h 1521 2019-11-15 21:00:47Z kgoldman $ */
+/* */
+/* Licenses and Notices */
+/* */
+/* 1. Copyright Licenses: */
+/* */
+/* - Trusted Computing Group (TCG) grants to the user of the source code in */
+/* this specification (the "Source Code") a worldwide, irrevocable, */
+/* nonexclusive, royalty free, copyright license to reproduce, create */
+/* derivative works, distribute, display and perform the Source Code and */
+/* derivative works thereof, and to grant others the rights granted herein. */
+/* */
+/* - The TCG grants to the user of the other parts of the specification */
+/* (other than the Source Code) the rights to reproduce, distribute, */
+/* display, and perform the specification solely for the purpose of */
+/* developing products based on such documents. */
+/* */
+/* 2. Source Code Distribution Conditions: */
+/* */
+/* - Redistributions of Source Code must retain the above copyright licenses, */
+/* this list of conditions and the following disclaimers. */
+/* */
+/* - Redistributions in binary form must reproduce the above copyright */
+/* licenses, this list of conditions and the following disclaimers in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* 3. Disclaimers: */
+/* */
+/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
+/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
+/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
+/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
+/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
+/* information on specification licensing rights available through TCG */
+/* membership agreements. */
+/* */
+/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
+/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
+/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
+/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
+/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
+/* */
+/* - Without limitation, TCG and its members and licensors disclaim all */
+/* liability, including liability for infringement of any proprietary */
+/* rights, relating to use of information in this specification and to the */
+/* implementation of this specification, and TCG disclaims all liability for */
+/* cost of procurement of substitute goods or services, lost profits, loss */
+/* of use, loss of data or any incidental, consequential, direct, indirect, */
+/* or special damages, whether under contract, tort, warranty or otherwise, */
+/* arising in any way out of use or reliance upon this specification or any */
+/* information herein. */
+/* */
+/* (c) Copyright IBM Corp. and others, 2019. */
+/* */
+/********************************************************************************/
+
+/* C.14 Platform.h */
+
+#ifndef _PLATFORM_H_
+#define _PLATFORM_H_
+#include "TpmBuildSwitches.h"
+#include "BaseTypes.h"
+#include "TPMB.h"
+#include "MinMax.h"
+#include "TpmProfile.h"
+#include "PlatformACT.h"
+#include "PlatformClock.h"
+#include "PlatformData.h"
+#include "Platform_fp.h"
+#endif // _PLATFORM_H_
diff --git a/src/tpm2/PlatformACT.c b/src/tpm2/PlatformACT.c
new file mode 100644
index 0000000..7d62dcb
--- /dev/null
+++ b/src/tpm2/PlatformACT.c
@@ -0,0 +1,353 @@
+/********************************************************************************/
+/* */
+/* Platform Authenticated Countdown Timer */
+/* Written by Ken Goldman */
+/* IBM Thomas J. Watson Research Center */
+/* $Id: PlatformACT.c 1594 2020-03-26 22:15:48Z kgoldman $ */
+/* */
+/* Licenses and Notices */
+/* */
+/* 1. Copyright Licenses: */
+/* */
+/* - Trusted Computing Group (TCG) grants to the user of the source code in */
+/* this specification (the "Source Code") a worldwide, irrevocable, */
+/* nonexclusive, royalty free, copyright license to reproduce, create */
+/* derivative works, distribute, display and perform the Source Code and */
+/* derivative works thereof, and to grant others the rights granted herein. */
+/* */
+/* - The TCG grants to the user of the other parts of the specification */
+/* (other than the Source Code) the rights to reproduce, distribute, */
+/* display, and perform the specification solely for the purpose of */
+/* developing products based on such documents. */
+/* */
+/* 2. Source Code Distribution Conditions: */
+/* */
+/* - Redistributions of Source Code must retain the above copyright licenses, */
+/* this list of conditions and the following disclaimers. */
+/* */
+/* - Redistributions in binary form must reproduce the above copyright */
+/* licenses, this list of conditions and the following disclaimers in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* 3. Disclaimers: */
+/* */
+/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
+/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
+/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
+/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
+/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
+/* information on specification licensing rights available through TCG */
+/* membership agreements. */
+/* */
+/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
+/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
+/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
+/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
+/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
+/* */
+/* - Without limitation, TCG and its members and licensors disclaim all */
+/* liability, including liability for infringement of any proprietary */
+/* rights, relating to use of information in this specification and to the */
+/* implementation of this specification, and TCG disclaims all liability for */
+/* cost of procurement of substitute goods or services, lost profits, loss */
+/* of use, loss of data or any incidental, consequential, direct, indirect, */
+/* or special damages, whether under contract, tort, warranty or otherwise, */
+/* arising in any way out of use or reliance upon this specification or any */
+/* information herein. */
+/* */
+/* (c) Copyright IBM Corp. and others, 2019 - 2020 */
+/* */
+/********************************************************************************/
+/* C.16 PlatformACT.c */
+/* C.16.1. Includes */
+#include "Platform.h"
+#include "PlatformACT_fp.h"
+/* C.16.2. Functions */
+/* C.16.2.1. ActSignal() */
+/* Function called when there is an ACT event to signal or unsignal */
+#ifndef __ACT_DISABLED // libtpms added
+static void
+ActSignal(
+ P_ACT_DATA actData,
+ int on
+ )
+{
+ if(actData == NULL)
+ return;
+ // If this is to turn a signal on, don't do anything if it is already on. If this
+ // is to turn the signal off, do it anyway because this might be for
+ // initialization.
+ if(on && (actData->signaled == TRUE))
+ return;
+ actData->signaled = (uint8_t)on;
+
+ // If there is an action, then replace the "Do something" with the correct action.
+ // It should test 'on' to see if it is turning the signal on or off.
+ switch(actData->number)
+ {
+#if RH_ACT_0
+ case 0: // Do something
+ return;
+#endif
+#if RH_ACT_1
+ case 1: // Do something
+ return;
+#endif
+#if RH_ACT_2
+ case 2: // Do something
+ return;
+#endif
+#if RH_ACT_3
+ case 3: // Do something
+ return;
+#endif
+#if RH_ACT_4
+ case 4: // Do something
+ return;
+#endif
+#if RH_ACT_5
+ case 5: // Do something
+ return;
+#endif
+#if RH_ACT_6
+ case 6: // Do something
+ return;
+#endif
+#if RH_ACT_7
+ case 7: // Do something
+ return;
+#endif
+#if RH_ACT_8
+ case 8: // Do something
+ return;
+#endif
+#if RH_ACT_9
+ case 9: // Do something
+ return;
+#endif
+#if RH_ACT_A
+ case 0xA: // Do something
+ return;
+#endif
+#if RH_ACT_B
+ case 0xB:
+ // Do something
+ return;
+#endif
+#if RH_ACT_C
+ case 0xC: // Do something
+ return;
+#endif
+#if RH_ACT_D
+ case 0xD: // Do something
+ return;
+#endif
+#if RH_ACT_E
+ case 0xE: // Do something
+ return;
+#endif
+#if RH_ACT_F
+ case 0xF: // Do something
+ return;
+#endif
+ default:
+ return;
+ }
+}
+#endif // libtpms added
+/* C.16.2.2. ActGetDataPointer() */
+static P_ACT_DATA
+ActGetDataPointer(
+ uint32_t act
+ )
+{
+
+#define RETURN_ACT_POINTER(N) if(0x##N == act) return &ACT_##N;
+
+ FOR_EACH_ACT(RETURN_ACT_POINTER)
+
+ return (P_ACT_DATA)NULL;
+}
+/* C.16.2.3. _plat__ACT_GetImplemented() */
+/* This function tests to see if an ACT is implemented. It is a belt and suspenders function because
+ the TPM should not be calling to manipulate an ACT that is not implemented. However, this
+ could help the simulator code which doesn't necessarily know if an ACT is implemented or not. */
+LIB_EXPORT int
+_plat__ACT_GetImplemented(
+ uint32_t act
+ )
+{
+ return (ActGetDataPointer(act) != NULL);
+}
+/* C.16.2.4. _plat__ACT_GetRemaining() */
+/* This function returns the remaining time. If an update is pending, newValue is
+ returned. Otherwise, the current counter value is returned. Note that since the timers keep
+ running, the returned value can get stale immediately. The actual count value will be no greater
+ than the returned value. */
+LIB_EXPORT uint32_t
+_plat__ACT_GetRemaining(
+ uint32_t act //IN: the ACT selector
+ )
+{
+ P_ACT_DATA actData = ActGetDataPointer(act);
+ uint32_t remain;
+ //
+ if(actData == NULL)
+ return 0;
+ remain = actData->remaining;
+ if(actData->pending)
+ remain = actData->newValue;
+ return remain;
+}
+/* C.16.2.5. _plat__ACT_GetSignaled() */
+LIB_EXPORT int
+_plat__ACT_GetSignaled(
+ uint32_t act //IN: number of ACT to check
+ )
+{
+ P_ACT_DATA actData = ActGetDataPointer(act);
+ //
+ if(actData == NULL)
+ return 0;
+ return (int)actData->signaled;
+}
+/* C.16.2.6. _plat__ACT_SetSignaled() */
+#ifndef __ACT_DISABLED // libtpms added
+LIB_EXPORT void
+_plat__ACT_SetSignaled(
+ uint32_t act,
+ int on
+ )
+{
+ ActSignal(ActGetDataPointer(act), on);
+}
+/* C.16.2.7. _plat__ACT_GetPending() */
+LIB_EXPORT int
+_plat__ACT_GetPending(
+ uint32_t act //IN: number of ACT to check
+ )
+{
+ P_ACT_DATA actData = ActGetDataPointer(act);
+ //
+ if(actData == NULL)
+ return 0;
+ return (int)actData->pending;
+}
+/* C.16.2.8. _plat__ACT_UpdateCounter() */
+/* This function is used to write the newValue for the counter. If an update is pending, then no
+ update occurs and the function returns FALSE. If setSignaled is TRUE, then the ACT signaled state
+ is SET and if newValue is 0, nothing is posted. */
+LIB_EXPORT int
+_plat__ACT_UpdateCounter(
+ uint32_t act, // IN: ACT to update
+ uint32_t newValue // IN: the value to post
+ )
+{
+ P_ACT_DATA actData = ActGetDataPointer(act);
+ //
+ if(actData == NULL)
+ // actData doesn't exist but pretend update is pending rather than indicate
+ // that a retry is necessary.
+ return TRUE;
+ // if an update is pending then return FALSE so that there will be a retry
+ if(actData->pending != 0)
+ return FALSE;
+ actData->newValue = newValue;
+ actData->pending = TRUE;
+
+ return TRUE;
+}
+#endif // libtpms added
+/* C.16.2.9. _plat__ACT_EnableTicks() */
+/* This enables and disables the processing of the once-per-second ticks. This should be turned off
+ (enable = FALSE) by _TPM_Init() and turned on (enable = TRUE) by TPM2_Startup() after all the
+ initializations have completed. */
+LIB_EXPORT void
+_plat__ACT_EnableTicks(
+ int enable
+ )
+{
+ actTicksAllowed = enable;
+}
+/* C.16.2.10. ActDecrement() */
+/* If newValue is non-zero it is copied to remaining and then newValue is set to zero. Then
+ remaining is decremented by one if it is not already zero. If the value is decremented to zero,
+ then the associated event is signaled. If setting remaining causes it to be greater than 1, then
+ the signal associated with the ACT is turned off. */
+#ifndef __ACT_DISABLED // libtpms added
+static void
+ActDecrement(
+ P_ACT_DATA actData
+ )
+{
+ // Check to see if there is an update pending
+ if(actData->pending)
+ {
+ // If this update will cause the count to go from non-zero to zero, set
+ // the newValue to 1 so that it will timeout when decremented below.
+ if((actData->newValue == 0) && (actData->remaining != 0))
+ actData->newValue = 1;
+ actData->remaining = actData->newValue;
+
+ // Update processed
+ actData->pending = 0;
+ }
+ // no update so countdown if the count is non-zero but not max
+ if((actData->remaining != 0) && (actData->remaining != UINT32_MAX))
+ {
+ // If this countdown causes the count to go to zero, then turn the signal for
+ // the ACT on.
+ if((actData->remaining -= 1) == 0)
+ ActSignal(actData, TRUE);
+ }
+ // If the current value of the counter is non-zero, then the signal should be
+ // off.
+ if(actData->signaled && (actData->remaining > 0))
+ ActSignal(actData, FALSE);
+}
+/* C.16.2.11. _plat__ACT_Tick() */
+/* This processes the once-per-second clock tick from the hardware. This is set up for the simulator to use the control interface to send ticks to the TPM. These ticks do not have to be on a per second basis. They can be as slow or as fast as desired so that the simulation can be tested. */
+LIB_EXPORT void
+_plat__ACT_Tick(
+ void
+ )
+{
+ // Ticks processing is turned off at certain times just to make sure that nothing
+ // strange is happening before pointers and things are
+ if(actTicksAllowed)
+ {
+ // Handle the update for each counter.
+#define DECREMENT_COUNT(N) ActDecrement(&ACT_##N);
+
+ FOR_EACH_ACT(DECREMENT_COUNT)
+ }
+}
+/* C.16.2.12. ActZero() */
+/* This function initializes a single ACT */
+static void
+ActZero(
+ uint32_t act,
+ P_ACT_DATA actData
+ )
+{
+ actData->remaining = 0;
+ actData->newValue = 0;
+ actData->pending = 0;
+ actData->number = (uint8_t)act;
+ ActSignal(actData, FALSE);
+}
+#endif // libtpms added
+/* C.16.2.13. _plat__ACT_Initialize() */
+/* This function initializes the ACT hardware and data structures */
+LIB_EXPORT int
+_plat__ACT_Initialize(
+ void
+ )
+{
+ actTicksAllowed = 0;
+#define ZERO_ACT(N) ActZero(0x##N, &ACT_##N);
+ FOR_EACH_ACT(ZERO_ACT)
+
+ return TRUE;
+}
+
diff --git a/src/tpm2/PlatformACT.h b/src/tpm2/PlatformACT.h
new file mode 100644
index 0000000..e57b445
--- /dev/null
+++ b/src/tpm2/PlatformACT.h
@@ -0,0 +1,210 @@
+/********************************************************************************/
+/* */
+/* Platform Authenticated Countdown Timer */
+/* Written by Ken Goldman */
+/* IBM Thomas J. Watson Research Center */
+/* $Id: PlatformACT.h 1531 2019-11-21 23:54:38Z kgoldman $ */
+/* */
+/* Licenses and Notices */
+/* */
+/* 1. Copyright Licenses: */
+/* */
+/* - Trusted Computing Group (TCG) grants to the user of the source code in */
+/* this specification (the "Source Code") a worldwide, irrevocable, */
+/* nonexclusive, royalty free, copyright license to reproduce, create */
+/* derivative works, distribute, display and perform the Source Code and */
+/* derivative works thereof, and to grant others the rights granted herein. */
+/* */
+/* - The TCG grants to the user of the other parts of the specification */
+/* (other than the Source Code) the rights to reproduce, distribute, */
+/* display, and perform the specification solely for the purpose of */
+/* developing products based on such documents. */
+/* */
+/* 2. Source Code Distribution Conditions: */
+/* */
+/* - Redistributions of Source Code must retain the above copyright licenses, */
+/* this list of conditions and the following disclaimers. */
+/* */
+/* - Redistributions in binary form must reproduce the above copyright */
+/* licenses, this list of conditions and the following disclaimers in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* 3. Disclaimers: */
+/* */
+/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
+/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
+/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
+/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
+/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
+/* information on specification licensing rights available through TCG */
+/* membership agreements. */
+/* */
+/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
+/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
+/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
+/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
+/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
+/* */
+/* - Without limitation, TCG and its members and licensors disclaim all */
+/* liability, including liability for infringement of any proprietary */
+/* rights, relating to use of information in this specification and to the */
+/* implementation of this specification, and TCG disclaims all liability for */
+/* cost of procurement of substitute goods or services, lost profits, loss */
+/* of use, loss of data or any incidental, consequential, direct, indirect, */
+/* or special damages, whether under contract, tort, warranty or otherwise, */
+/* arising in any way out of use or reliance upon this specification or any */
+/* information herein. */
+/* */
+/* (c) Copyright IBM Corp. and others, 2019. */
+/* */
+/********************************************************************************/
+
+/* C.15 PlatformACT.h */
+
+// This file contains the definitions for the ACT macros and data types used in the ACT
+// implementation.
+
+#ifndef PLATFORMACT_H
+#define PLATFORMACT_H
+
+typedef struct ACT_DATA
+{
+ uint32_t remaining;
+ uint32_t newValue;
+ uint8_t signaled;
+ uint8_t pending;
+ uint8_t number;
+} ACT_DATA, *P_ACT_DATA;
+
+#if !(defined RH_ACT_0) || (RH_ACT_0 != YES)
+# undef RH_ACT_0
+# define RH_ACT_0 NO
+# define IF_ACT_0_IMPLEMENTED(op)
+#else
+# define IF_ACT_0_IMPLEMENTED(op) op(0)
+#endif
+#if !(defined RH_ACT_1) || (RH_ACT_1 != YES)
+# undef RH_ACT_1
+# define RH_ACT_1 NO
+# define IF_ACT_1_IMPLEMENTED(op)
+#else
+# define IF_ACT_1_IMPLEMENTED(op) op(1)
+#endif
+#if !(defined RH_ACT_2) || (RH_ACT_2 != YES)
+# undef RH_ACT_2
+# define RH_ACT_2 NO
+# define IF_ACT_2_IMPLEMENTED(op)
+#else
+# define IF_ACT_2_IMPLEMENTED(op) op(2)
+#endif
+#if !(defined RH_ACT_3) || (RH_ACT_3 != YES)
+# undef RH_ACT_3
+# define RH_ACT_3 NO
+# define IF_ACT_3_IMPLEMENTED(op)
+#else
+# define IF_ACT_3_IMPLEMENTED(op) op(3)
+#endif
+#if !(defined RH_ACT_4) || (RH_ACT_4 != YES)
+# undef RH_ACT_4
+# define RH_ACT_4 NO
+# define IF_ACT_4_IMPLEMENTED(op)
+#else
+# define IF_ACT_4_IMPLEMENTED(op) op(4)
+#endif
+#if !(defined RH_ACT_5) || (RH_ACT_5 != YES)
+# undef RH_ACT_5
+# define RH_ACT_5 NO
+# define IF_ACT_5_IMPLEMENTED(op)
+#else
+# define IF_ACT_5_IMPLEMENTED(op) op(5)
+#endif
+#if !(defined RH_ACT_6) || (RH_ACT_6 != YES)
+# undef RH_ACT_6
+# define RH_ACT_6 NO
+# define IF_ACT_6_IMPLEMENTED(op)
+#else
+# define IF_ACT_6_IMPLEMENTED(op) op(6)
+#endif
+#if !(defined RH_ACT_7) || (RH_ACT_7 != YES)
+# undef RH_ACT_7
+# define RH_ACT_7 NO
+# define IF_ACT_7_IMPLEMENTED(op)
+#else
+# define IF_ACT_7_IMPLEMENTED(op) op(7)
+#endif
+#if !(defined RH_ACT_8) || (RH_ACT_8 != YES)
+# undef RH_ACT_8
+# define RH_ACT_8 NO
+# define IF_ACT_8_IMPLEMENTED(op)
+#else
+# define IF_ACT_8_IMPLEMENTED(op) op(8)
+#endif
+#if !(defined RH_ACT_9) || (RH_ACT_9 != YES)
+# undef RH_ACT_9
+# define RH_ACT_9 NO
+# define IF_ACT_9_IMPLEMENTED(op)
+#else
+# define IF_ACT_9_IMPLEMENTED(op) op(9)
+#endif
+#if !(defined RH_ACT_A) || (RH_ACT_A != YES)
+# undef RH_ACT_A
+# define RH_ACT_A NO
+# define IF_ACT_A_IMPLEMENTED(op)
+#else
+# define IF_ACT_A_IMPLEMENTED(op) op(A)
+#endif
+#if !(defined RH_ACT_B) || (RH_ACT_B != YES)
+# undef RH_ACT_B
+# define RH_ACT_B NO
+# define IF_ACT_B_IMPLEMENTED(op)
+#else
+# define IF_ACT_B_IMPLEMENTED(op) op(B)
+#endif
+#if !(defined RH_ACT_C) || (RH_ACT_C != YES)
+# undef RH_ACT_C
+# define RH_ACT_C NO
+# define IF_ACT_C_IMPLEMENTED(op)
+#else
+# define IF_ACT_C_IMPLEMENTED(op) op(C)
+#endif
+#if !(defined RH_ACT_D) || (RH_ACT_D != YES)
+# undef RH_ACT_D
+# define RH_ACT_D NO
+# define IF_ACT_D_IMPLEMENTED(op)
+#else
+# define IF_ACT_D_IMPLEMENTED(op) op(D)
+#endif
+#if !(defined RH_ACT_E) || (RH_ACT_E != YES)
+# undef RH_ACT_E
+# define RH_ACT_E NO
+# define IF_ACT_E_IMPLEMENTED(op)
+#else
+# define IF_ACT_E_IMPLEMENTED(op) op(E)
+#endif
+#if !(defined RH_ACT_F) || (RH_ACT_F != YES)
+# undef RH_ACT_F
+# define RH_ACT_F NO
+# define IF_ACT_F_IMPLEMENTED(op)
+#else
+# define IF_ACT_F_IMPLEMENTED(op) op(F)
+#endif
+
+#define FOR_EACH_ACT(op) \
+ IF_ACT_0_IMPLEMENTED(op) \
+ IF_ACT_1_IMPLEMENTED(op) \
+ IF_ACT_2_IMPLEMENTED(op) \
+ IF_ACT_3_IMPLEMENTED(op) \
+ IF_ACT_4_IMPLEMENTED(op) \
+ IF_ACT_5_IMPLEMENTED(op) \
+ IF_ACT_6_IMPLEMENTED(op) \
+ IF_ACT_7_IMPLEMENTED(op) \
+ IF_ACT_8_IMPLEMENTED(op) \
+ IF_ACT_9_IMPLEMENTED(op) \
+ IF_ACT_A_IMPLEMENTED(op) \
+ IF_ACT_B_IMPLEMENTED(op) \
+ IF_ACT_C_IMPLEMENTED(op) \
+ IF_ACT_D_IMPLEMENTED(op) \
+ IF_ACT_E_IMPLEMENTED(op) \
+ IF_ACT_F_IMPLEMENTED(op)
+
+#endif // _PLATFORM_ACT_H_
diff --git a/src/tpm2/PlatformACT_fp.h b/src/tpm2/PlatformACT_fp.h
new file mode 100644
index 0000000..5d2caf5
--- /dev/null
+++ b/src/tpm2/PlatformACT_fp.h
@@ -0,0 +1,104 @@
+/********************************************************************************/
+/* */
+/* Platform Authenticated Countdown Timer */
+/* Written by Ken Goldman */
+/* IBM Thomas J. Watson Research Center */
+/* $Id: PlatformACT_fp.h 1531 2019-11-21 23:54:38Z kgoldman $ */
+/* */
+/* Licenses and Notices */
+/* */
+/* 1. Copyright Licenses: */
+/* */
+/* - Trusted Computing Group (TCG) grants to the user of the source code in */
+/* this specification (the "Source Code") a worldwide, irrevocable, */
+/* nonexclusive, royalty free, copyright license to reproduce, create */
+/* derivative works, distribute, display and perform the Source Code and */
+/* derivative works thereof, and to grant others the rights granted herein. */
+/* */
+/* - The TCG grants to the user of the other parts of the specification */
+/* (other than the Source Code) the rights to reproduce, distribute, */
+/* display, and perform the specification solely for the purpose of */
+/* developing products based on such documents. */
+/* */
+/* 2. Source Code Distribution Conditions: */
+/* */
+/* - Redistributions of Source Code must retain the above copyright licenses, */
+/* this list of conditions and the following disclaimers. */
+/* */
+/* - Redistributions in binary form must reproduce the above copyright */
+/* licenses, this list of conditions and the following disclaimers in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* 3. Disclaimers: */
+/* */
+/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
+/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
+/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
+/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
+/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
+/* information on specification licensing rights available through TCG */
+/* membership agreements. */
+/* */
+/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
+/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
+/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
+/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
+/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
+/* */
+/* - Without limitation, TCG and its members and licensors disclaim all */
+/* liability, including liability for infringement of any proprietary */
+/* rights, relating to use of information in this specification and to the */
+/* implementation of this specification, and TCG disclaims all liability for */
+/* cost of procurement of substitute goods or services, lost profits, loss */
+/* of use, loss of data or any incidental, consequential, direct, indirect, */
+/* or special damages, whether under contract, tort, warranty or otherwise, */
+/* arising in any way out of use or reliance upon this specification or any */
+/* information herein. */
+/* */
+/* (c) Copyright IBM Corp. and others, 2019 */
+/* */
+/********************************************************************************/
+
+#ifndef PLATFORMACT_FP_H
+#define PLATFORMACT_FP_H
+
+LIB_EXPORT int
+_plat__ACT_GetImplemented(
+ uint32_t act
+ );
+LIB_EXPORT uint32_t
+_plat__ACT_GetRemaining(
+ uint32_t act //IN: the ACT selector
+ );
+LIB_EXPORT int
+_plat__ACT_GetSignaled(
+ uint32_t act //IN: number of ACT to check
+ );
+LIB_EXPORT void
+_plat__ACT_SetSignaled(
+ uint32_t act,
+ int on
+ );
+LIB_EXPORT int
+_plat__ACT_GetPending(
+ uint32_t act //IN: number of ACT to check
+ );
+LIB_EXPORT int
+_plat__ACT_UpdateCounter(
+ uint32_t act, // IN: ACT to update
+ uint32_t newValue // IN: the value to post
+ );
+LIB_EXPORT void
+_plat__ACT_EnableTicks(
+ int enable
+ );
+LIB_EXPORT void
+_plat__ACT_Tick(
+ void
+ );
+LIB_EXPORT int
+_plat__ACT_Initialize(
+ void
+ );
+
+#endif
diff --git a/src/tpm2/PlatformClock.h b/src/tpm2/PlatformClock.h
new file mode 100644
index 0000000..8f6ebb9
--- /dev/null
+++ b/src/tpm2/PlatformClock.h
@@ -0,0 +1,89 @@
+/********************************************************************************/
+/* */
+/* Platform Clock . */
+/* Written by Ken Goldman */
+/* IBM Thomas J. Watson Research Center */
+/* $Id: PlatformClock.h 1594 2020-03-26 22:15:48Z kgoldman $ */
+/* */
+/* Licenses and Notices */
+/* */
+/* 1. Copyright Licenses: */
+/* */
+/* - Trusted Computing Group (TCG) grants to the user of the source code in */
+/* this specification (the "Source Code") a worldwide, irrevocable, */
+/* nonexclusive, royalty free, copyright license to reproduce, create */
+/* derivative works, distribute, display and perform the Source Code and */
+/* derivative works thereof, and to grant others the rights granted herein. */
+/* */
+/* - The TCG grants to the user of the other parts of the specification */
+/* (other than the Source Code) the rights to reproduce, distribute, */
+/* display, and perform the specification solely for the purpose of */
+/* developing products based on such documents. */
+/* */
+/* 2. Source Code Distribution Conditions: */
+/* */
+/* - Redistributions of Source Code must retain the above copyright licenses, */
+/* this list of conditions and the following disclaimers. */
+/* */
+/* - Redistributions in binary form must reproduce the above copyright */
+/* licenses, this list of conditions and the following disclaimers in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* 3. Disclaimers: */
+/* */
+/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
+/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
+/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
+/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
+/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
+/* information on specification licensing rights available through TCG */
+/* membership agreements. */
+/* */
+/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
+/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
+/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
+/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
+/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
+/* */
+/* - Without limitation, TCG and its members and licensors disclaim all */
+/* liability, including liability for infringement of any proprietary */
+/* rights, relating to use of information in this specification and to the */
+/* implementation of this specification, and TCG disclaims all liability for */
+/* cost of procurement of substitute goods or services, lost profits, loss */
+/* of use, loss of data or any incidental, consequential, direct, indirect, */
+/* or special damages, whether under contract, tort, warranty or otherwise, */
+/* arising in any way out of use or reliance upon this specification or any */
+/* information herein. */
+/* */
+/* (c) Copyright IBM Corp. and others, 2019 - 2020 */
+/* */
+/********************************************************************************/
+
+// C.16 PlatformClock.h This file contains the instance data for the Platform module. It is
+// collected in this file so that the state of the module is easier to manage.
+#ifndef _PLATFORM_CLOCK_H_
+#define _PLATFORM_CLOCK_H_
+#ifdef _MSC_VER
+#include <sys/types.h>
+#include <sys/timeb.h>
+#else
+#include <sys/time.h>
+#include <time.h>
+#endif
+// CLOCK_NOMINAL is the number of hardware ticks per mS. A value of 300000 means that the nominal
+// clock rate used to drive the hardware clock is 30 MHz. The adjustment rates are used to determine
+// the conversion of the hardware ticks to internal hardware clock value. In practice, we would
+// expect that there would be a hardware register will accumulated mS. It would be incremented by
+// the output of a pre-scaler. The pre-scaler would divide the ticks from the clock by some value
+// that would compensate for the difference between clock time and real time. The code in Clock does
+// the emulation of this function.
+#define CLOCK_NOMINAL 30000
+// A 1% change in rate is 300 counts
+#define CLOCK_ADJUST_COARSE 300
+// A 0.1% change in rate is 30 counts
+#define CLOCK_ADJUST_MEDIUM 30
+// A minimum change in rate is 1 count
+#define CLOCK_ADJUST_FINE 1
+// The clock tolerance is +/-15% (4500 counts) Allow some guard band (16.7%)
+#define CLOCK_ADJUST_LIMIT 5000
+#endif // _PLATFORM_CLOCK_H_
diff --git a/src/tpm2/PlatformData.c b/src/tpm2/PlatformData.c
new file mode 100644
index 0000000..d6fb0c5
--- /dev/null
+++ b/src/tpm2/PlatformData.c
@@ -0,0 +1,70 @@
+/********************************************************************************/
+/* */
+/* TPM variables that are not stack allocated */
+/* Written by Ken Goldman */
+/* IBM Thomas J. Watson Research Center */
+/* $Id: PlatformData.c 1519 2019-11-15 20:43:51Z kgoldman $ */
+/* */
+/* Licenses and Notices */
+/* */
+/* 1. Copyright Licenses: */
+/* */
+/* - Trusted Computing Group (TCG) grants to the user of the source code in */
+/* this specification (the "Source Code") a worldwide, irrevocable, */
+/* nonexclusive, royalty free, copyright license to reproduce, create */
+/* derivative works, distribute, display and perform the Source Code and */
+/* derivative works thereof, and to grant others the rights granted herein. */
+/* */
+/* - The TCG grants to the user of the other parts of the specification */
+/* (other than the Source Code) the rights to reproduce, distribute, */
+/* display, and perform the specification solely for the purpose of */
+/* developing products based on such documents. */
+/* */
+/* 2. Source Code Distribution Conditions: */
+/* */
+/* - Redistributions of Source Code must retain the above copyright licenses, */
+/* this list of conditions and the following disclaimers. */
+/* */
+/* - Redistributions in binary form must reproduce the above copyright */
+/* licenses, this list of conditions and the following disclaimers in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* 3. Disclaimers: */
+/* */
+/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
+/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
+/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
+/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
+/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
+/* information on specification licensing rights available through TCG */
+/* membership agreements. */
+/* */
+/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
+/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
+/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
+/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
+/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
+/* */
+/* - Without limitation, TCG and its members and licensors disclaim all */
+/* liability, including liability for infringement of any proprietary */
+/* rights, relating to use of information in this specification and to the */
+/* implementation of this specification, and TCG disclaims all liability for */
+/* cost of procurement of substitute goods or services, lost profits, loss */
+/* of use, loss of data or any incidental, consequential, direct, indirect, */
+/* or special damages, whether under contract, tort, warranty or otherwise, */
+/* arising in any way out of use or reliance upon this specification or any */
+/* information herein. */
+/* */
+/* (c) Copyright IBM Corp. and others, 2016 - 2019 */
+/* */
+/********************************************************************************/
+
+/* C.9 PlatformData.c */
+/* C.9.1. Description */
+/* This file will instance the TPM variables that are not stack allocated. The descriptions for
+ these variables are in Global.h for this project. */
+/* C.9.2. Includes */
+
+#define _PLATFORM_DATA_C_
+#include "Platform.h"
+
diff --git a/src/tpm2/PlatformData.h b/src/tpm2/PlatformData.h
new file mode 100644
index 0000000..3555389
--- /dev/null
+++ b/src/tpm2/PlatformData.h
@@ -0,0 +1,142 @@
+/********************************************************************************/
+/* */
+/* Instance data for the Platform module. */
+/* Written by Ken Goldman */
+/* IBM Thomas J. Watson Research Center */
+/* $Id: PlatformData.h 1519 2019-11-15 20:43:51Z kgoldman $ */
+/* */
+/* Licenses and Notices */
+/* */
+/* 1. Copyright Licenses: */
+/* */
+/* - Trusted Computing Group (TCG) grants to the user of the source code in */
+/* this specification (the "Source Code") a worldwide, irrevocable, */
+/* nonexclusive, royalty free, copyright license to reproduce, create */
+/* derivative works, distribute, display and perform the Source Code and */
+/* derivative works thereof, and to grant others the rights granted herein. */
+/* */
+/* - The TCG grants to the user of the other parts of the specification */
+/* (other than the Source Code) the rights to reproduce, distribute, */
+/* display, and perform the specification solely for the purpose of */
+/* developing products based on such documents. */
+/* */
+/* 2. Source Code Distribution Conditions: */
+/* */
+/* - Redistributions of Source Code must retain the above copyright licenses, */
+/* this list of conditions and the following disclaimers. */
+/* */
+/* - Redistributions in binary form must reproduce the above copyright */
+/* licenses, this list of conditions and the following disclaimers in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* 3. Disclaimers: */
+/* */
+/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
+/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
+/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
+/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
+/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
+/* information on specification licensing rights available through TCG */
+/* membership agreements. */
+/* */
+/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
+/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
+/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
+/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
+/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
+/* */
+/* - Without limitation, TCG and its members and licensors disclaim all */
+/* liability, including liability for infringement of any proprietary */
+/* rights, relating to use of information in this specification and to the */
+/* implementation of this specification, and TCG disclaims all liability for */
+/* cost of procurement of substitute goods or services, lost profits, loss */
+/* of use, loss of data or any incidental, consequential, direct, indirect, */
+/* or special damages, whether under contract, tort, warranty or otherwise, */
+/* arising in any way out of use or reliance upon this specification or any */
+/* information herein. */
+/* */
+/* (c) Copyright IBM Corp. and others, 2016 - 2019. */
+/* */
+/********************************************************************************/
+
+/* c.8 PlatformData.h */
+/* This file contains the instance data for the Platform module. It is collected in this file so
+ that the state of the module is easier to manage. */
+
+#ifndef _PLATFORM_DATA_H_
+#define _PLATFORM_DATA_H_
+#ifdef _PLATFORM_DATA_C_
+#define EXTERN
+#else
+#define EXTERN extern
+#endif
+
+/* From Cancel.c Cancel flag. It is initialized as FALSE, which indicate the command is not being
+ canceled */
+EXTERN int s_isCanceled;
+
+#ifndef HARDWARE_CLOCK
+typedef uint64_t clock64_t;
+// This is the value returned the last time that the system clock was read. This is only relevant
+// for a simulator or virtual TPM.
+EXTERN clock64_t s_realTimePrevious;
+// These values are used to try to synthesize a long lived version of clock().
+EXTERN clock64_t s_lastSystemTime;
+EXTERN clock64_t s_lastReportedTime;
+// This is the rate adjusted value that is the equivalent of what would be read from a hardware
+// register that produced rate adjusted time.
+EXTERN clock64_t s_tpmTime;
+/* libtpms added begin */
+EXTERN int64_t s_hostMonotonicAdjustTime;
+EXTERN uint64_t s_suspendedElapsedTime;
+/* libtpms added end */
+#endif // HARDWARE_CLOCK
+
+/* This value indicates that the timer was reset */
+EXTERN BOOL s_timerReset;
+/* This value indicates that the timer was stopped. It causes a clock discontinuity. */
+EXTERN BOOL s_timerStopped;
+/* This variable records the time when _plat__TimerReset() is called. This mechanism allow us to
+ subtract the time when TPM is power off from the total time reported by clock() function */
+EXTERN uint64_t s_initClock;
+/* This variable records the timer adjustment factor. */
+EXTERN unsigned int s_adjustRate;
+/* From LocalityPlat.c Locality of current command */
+EXTERN unsigned char s_locality;
+/* From NVMem.c Choose if the NV memory should be backed by RAM or by file. If this macro is
+ defined, then a file is used as NV. If it is not defined, then RAM is used to back NV
+ memory. Comment out to use RAM. */
+#if (!defined VTPM) || ((VTPM != NO) && (VTPM != YES))
+# undef VTPM
+# define VTPM NO // Default: Either YES or NO libtpms: NO
+#endif
+
+// For a simulation, use a file to back up the NV
+
+#if (!defined FILE_BACKED_NV) || ((FILE_BACKED_NV != NO) && (FILE_BACKED_NV != YES))
+# undef FILE_BACKED_NV
+# define FILE_BACKED_NV (VTPM && YES) // Default: Either YES or NO
+#endif
+#if !SIMULATION
+# undef FILE_BACKED_NV
+# define FILE_BACKED_NV YES // libtpms: write NvChip file if no callbacks are set
+#else
+#error Do not define SIMULATION for libtpms!
+#endif // SIMULATION
+
+EXTERN unsigned char s_NV[NV_MEMORY_SIZE];
+EXTERN BOOL s_NvIsAvailable;
+EXTERN BOOL s_NV_unrecoverable;
+EXTERN BOOL s_NV_recoverable;
+/* From PPPlat.c Physical presence. It is initialized to FALSE */
+EXTERN BOOL s_physicalPresence;
+/* From Power */
+EXTERN BOOL s_powerLost;
+/* From Entropy.c */
+EXTERN uint32_t lastEntropy;
+
+#define DEFINE_ACT(N) EXTERN ACT_DATA ACT_##N;
+FOR_EACH_ACT(DEFINE_ACT)
+EXTERN int actTicksAllowed;
+
+#endif // _PLATFORM_DATA_H_
diff --git a/src/tpm2/Platform_fp.h b/src/tpm2/Platform_fp.h
new file mode 100644
index 0000000..4bc7cd4
--- /dev/null
+++ b/src/tpm2/Platform_fp.h
@@ -0,0 +1,407 @@
+/********************************************************************************/
+/* */
+/* NV read and write access methods */
+/* Written by Ken Goldman */
+/* IBM Thomas J. Watson Research Center */
+/* $Id: Platform_fp.h 1594 2020-03-26 22:15:48Z kgoldman $ */
+/* */
+/* Licenses and Notices */
+/* */
+/* 1. Copyright Licenses: */
+/* */
+/* - Trusted Computing Group (TCG) grants to the user of the source code in */
+/* this specification (the "Source Code") a worldwide, irrevocable, */
+/* nonexclusive, royalty free, copyright license to reproduce, create */
+/* derivative works, distribute, display and perform the Source Code and */
+/* derivative works thereof, and to grant others the rights granted herein. */
+/* */
+/* - The TCG grants to the user of the other parts of the specification */
+/* (other than the Source Code) the rights to reproduce, distribute, */
+/* display, and perform the specification solely for the purpose of */
+/* developing products based on such documents. */
+/* */
+/* 2. Source Code Distribution Conditions: */
+/* */
+/* - Redistributions of Source Code must retain the above copyright licenses, */
+/* this list of conditions and the following disclaimers. */
+/* */
+/* - Redistributions in binary form must reproduce the above copyright */
+/* licenses, this list of conditions and the following disclaimers in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* 3. Disclaimers: */
+/* */
+/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
+/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
+/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
+/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
+/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
+/* information on specification licensing rights available through TCG */
+/* membership agreements. */
+/* */
+/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
+/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
+/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
+/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
+/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
+/* */
+/* - Without limitation, TCG and its members and licensors disclaim all */
+/* liability, including liability for infringement of any proprietary */
+/* rights, relating to use of information in this specification and to the */
+/* implementation of this specification, and TCG disclaims all liability for */
+/* cost of procurement of substitute goods or services, lost profits, loss */
+/* of use, loss of data or any incidental, consequential, direct, indirect, */
+/* or special damages, whether under contract, tort, warranty or otherwise, */
+/* arising in any way out of use or reliance upon this specification or any */
+/* information herein. */
+/* */
+/* (c) Copyright IBM Corp. and others, 2016 - 2020 */
+/* */
+/********************************************************************************/
+
+/* C.8 Platform_fp.h */
+#ifndef _PLATFORM_FP_H_
+#define _PLATFORM_FP_H_
+
+#include "BaseTypes.h"
+
+/* C.8.1. From Cancel.c */
+/* C.8.1.1. _plat__IsCanceled() */
+/* Check if the cancel flag is set */
+/* Return Values Meaning */
+/* TRUE(1) if cancel flag is set */
+/* FALSE(0) if cancel flag is not set */
+LIB_EXPORT int
+_plat__IsCanceled(
+ void
+ );
+/* Set cancel flag. */
+LIB_EXPORT void
+_plat__SetCancel(
+ void
+ );
+/* C.8.1.2. _plat__ClearCancel() */
+/* Clear cancel flag */
+LIB_EXPORT void
+_plat__ClearCancel(
+ void
+ );
+/* C.8.2. From Clock.c */
+/* C.8.2.1. _plat__TimerReset() */
+/* This function sets current system clock time as t0 for counting TPM time. This function is called
+ at a power on event to reset the clock. When the clock is reset, the indication that the clock
+ was stopped is also set. */
+LIB_EXPORT void
+_plat__TimerReset(
+ void
+ );
+/* C.8.2.2. _plat__TimerRestart() */
+/* This function should be called in order to simulate the restart of the timer should it be stopped
+ while power is still applied. */
+LIB_EXPORT void
+_plat__TimerRestart(
+ void
+ );
+// C.8.2.3. _plat__Time() This is another, probably futile, attempt to define a portable function
+// that will return a 64-bit clock value that has mSec resolution.
+LIB_EXPORT uint64_t
+_plat__RealTime(
+ void
+ );
+/* C.8.2.4. _plat__TimerRead() */
+/* This function provides access to the tick timer of the platform. The TPM code uses this value to
+ drive the TPM Clock. */
+/* The tick timer is supposed to run when power is applied to the device. This timer should not be
+ reset by time events including _TPM_Init(). It should only be reset when TPM power is
+ re-applied. */
+/* If the TPM is run in a protected environment, that environment may provide the tick time to the
+ TPM as long as the time provided by the environment is not allowed to go backwards. If the time
+ provided by the system can go backwards during a power discontinuity, then the
+ _plat__Signal_PowerOn() should call _plat__TimerReset(). */
+LIB_EXPORT uint64_t
+_plat__TimerRead(
+ void
+ );
+/* C.8.2.5. _plat__TimerWasReset() */
+/* This function is used to interrogate the flag indicating if the tick timer has been reset. */
+/* If the resetFlag parameter is SET, then the flag will be CLEAR before the function returns. */
+LIB_EXPORT int
+_plat__TimerWasReset(
+ void
+ );
+/* C.8.2.6. _plat__TimerWasStopped() */
+/* This function is used to interrogate the flag indicating if the tick timer has been stopped. If
+ so, this is typically a reason to roll the nonce. */
+/* This function will CLEAR the s_timerStopped flag before returning. This provides functionality
+ that is similar to status register that is cleared when read. This is the model used here because
+ it is the one that has the most impact on the TPM code as the flag can only be accessed by one
+ entity in the TPM. Any other implementation of the hardware can be made to look like a read-once
+ register. */
+LIB_EXPORT int
+_plat__TimerWasStopped(
+ void
+ );
+/* C.8.2.7. _plat__ClockAdjustRate() */
+/* Adjust the clock rate */
+LIB_EXPORT void
+_plat__ClockAdjustRate(
+ int adjust // IN: the adjust number. It could be positive
+ // or negative
+ );
+/* C.8.3. From Entropy.c */
+// C.8.4. _plat__GetEntropy()
+// This function is used to get available hardware entropy. In a hardware implementation of this
+// function, there would be no call to the system to get entropy.
+/* Return Values Meaning */
+/* < 0 hardware failure of the entropy generator, this is sticky */
+/* >= 0 the returned amount of entropy (bytes) */
+LIB_EXPORT int32_t
+_plat__GetEntropy(
+ unsigned char *entropy, // output buffer
+ uint32_t amount // amount requested
+ );
+/* C.8.4. From LocalityPlat.c */
+/* C.8.4.1. _plat__LocalityGet() */
+/* Get the most recent command locality in locality value form. This is an integer value for
+ locality and not a locality structure The locality can be 0-4 or 32-255. 5-31 is not allowed. */
+LIB_EXPORT unsigned char
+_plat__LocalityGet(
+ void
+ );
+/* C.8.4.2. _plat__LocalitySet() */
+/* Set the most recent command locality in locality value form */
+LIB_EXPORT void
+_plat__LocalitySet(
+ unsigned char locality
+ );
+/* C.8.5. From NVMem.c */
+#if 0 /* libtpms added */
+/* C.8.5.1. _plat__NvErrors() */
+/* This function is used by the simulator to set the error flags in the NV subsystem to simulate an error in the NV loading process */
+LIB_EXPORT void
+_plat__NvErrors(
+ int recoverable,
+ int unrecoverable
+ );
+#endif /* libtpms added */
+/* C.8.5.2. _plat__NVEnable() */
+/* Enable NV memory. */
+/* This version just pulls in data from a file. In a real TPM, with NV on chip, this function would
+ verify the integrity of the saved context. If the NV memory was not on chip but was in something
+ like RPMB, the NV state would be read in, decrypted and integrity checked. */
+/* The recovery from an integrity failure depends on where the error occurred. It it was in the
+ state that is discarded by TPM Reset, then the error is recoverable if the TPM is
+ reset. Otherwise, the TPM must go into failure mode. */
+/* Return Values Meaning */
+/* 0 if success */
+/* > 0 if receive recoverable error */
+/* <0 if unrecoverable error */
+LIB_EXPORT int
+_plat__NVEnable(
+ void *platParameter // IN: platform specific parameters
+ );
+/* libtpms added begin */
+LIB_EXPORT int
+_plat__NVEnable_NVChipFile(
+ void *platParameter // IN: platform specific parameters
+ );
+/* libtpms added end */
+/* C.8.5.3. _plat__NVDisable() */
+/* Disable NV memory */
+LIB_EXPORT void
+_plat__NVDisable(
+ int delete // IN: If TRUE, delete the NV contents.
+ );
+/* C.8.6.4. _plat__IsNvAvailable() */
+/* Check if NV is available */
+/* Return Values Meaning */
+/* 0 NV is available */
+/* 1 NV is not available due to write failure */
+/* 2 NV is not available due to rate limit */
+LIB_EXPORT int
+_plat__IsNvAvailable(
+ void
+ );
+/* C.8.5.5. _plat__NvMemoryRead() */
+/* Function: Read a chunk of NV memory */
+LIB_EXPORT void
+_plat__NvMemoryRead(
+ unsigned int startOffset, // IN: read start
+ unsigned int size, // IN: size of bytes to read
+ void *data // OUT: data buffer
+ );
+/* C.8.5.6. _plat__NvIsDifferent() */
+/* This function checks to see if the NV is different from the test value. This is so that NV will
+ not be written if it has not changed. */
+/* Return Values Meaning */
+/* TRUE(1) the NV location is different from the test value */
+/* FALSE(0) the NV location is the same as the test value */
+LIB_EXPORT int
+_plat__NvIsDifferent(
+ unsigned int startOffset, // IN: read start
+ unsigned int size, // IN: size of bytes to read
+ void *data // IN: data buffer
+ );
+/* C.8.5.7. _plat__NvMemoryWrite() */
+/* This function is used to update NV memory. The write is to a memory copy of NV. At the end of the
+ current command, any changes are written to the actual NV memory. */
+/* NOTE: A useful optimization would be for this code to compare the current contents of NV with the
+ local copy and note the blocks that have changed. Then only write those blocks when
+ _plat__NvCommit() is called. */
+LIB_EXPORT int
+_plat__NvMemoryWrite(
+ unsigned int startOffset, // IN: write start
+ unsigned int size, // IN: size of bytes to write
+ void *data // OUT: data buffer
+ );
+/* C.8.6.8. _plat__NvMemoryClear() */
+/* Function is used to set a range of NV memory bytes to an implementation-dependent value. The
+ value represents the erase state of the memory. */
+LIB_EXPORT void
+_plat__NvMemoryClear(
+ unsigned int start, // IN: clear start
+ unsigned int size // IN: number of bytes to clear
+ );
+/* C.8.5.9. _plat__NvMemoryMove() */
+/* Function: Move a chunk of NV memory from source to destination This function should ensure that
+ if there overlap, the original data is copied before it is written */
+LIB_EXPORT void
+_plat__NvMemoryMove(
+ unsigned int sourceOffset, // IN: source offset
+ unsigned int destOffset, // IN: destination offset
+ unsigned int size // IN: size of data being moved
+ );
+/* C.8.5.10. _plat__NvCommit() */
+// This function writes the local copy of NV to NV for permanent store. It will write NV_MEMORY_SIZE
+// bytes to NV. If a file is use, the entire file is written.
+/* Return Values Meaning */
+/* 0 NV write success */
+/* non-0 NV write fail */
+LIB_EXPORT int
+_plat__NvCommit(
+ void
+ );
+/* C.8.5.11. _plat__SetNvAvail() */
+/* Set the current NV state to available. This function is for testing purpose only. It is not
+ part of the platform NV logic */
+LIB_EXPORT void
+_plat__SetNvAvail(
+ void
+ );
+/* C.8.5.12. _plat__ClearNvAvail() */
+/* Set the current NV state to unavailable. This function is for testing purpose only. It is not
+ part of the platform NV logic */
+LIB_EXPORT void
+_plat__ClearNvAvail(
+ void
+ );
+
+/* C.6.2.15. _plat__NVNeedsManufacture() */
+/* This function is used by the simulator to determine when the TPM's NV state needs to be manufactured. */
+
+LIB_EXPORT int
+_plat__NVNeedsManufacture(
+ void
+ );
+
+/* C.8.6. From PowerPlat.c */
+/* C.8.6.1. _plat__Signal_PowerOn() */
+/* Signal platform power on */
+LIB_EXPORT int
+_plat__Signal_PowerOn(
+ void
+ );
+/* C.8.6.2. _plat__WasPowerLost() */
+/* Test whether power was lost before a _TPM_Init(). */
+/* This function will clear the hardware indication of power loss before return. This means that
+ there can only be one spot in the TPM code where this value gets read. This method is used here
+ as it is the most difficult to manage in the TPM code and, if the hardware actually works this
+ way, it is hard to make it look like anything else. So, the burden is placed on the TPM code
+ rather than the platform code */
+/* Return Values Meaning */
+/* TRUE(1) power was lost */
+/* FALSE(0) power was not lost */
+LIB_EXPORT int
+_plat__WasPowerLost(
+ void
+ );
+/* C.8.6.3. _plat_Signal_Reset() */
+/* This a TPM reset without a power loss. */
+LIB_EXPORT int
+_plat__Signal_Reset(
+ void
+ );
+/* C.8.6.4. _plat__Signal_PowerOff() */
+/* Signal platform power off */
+LIB_EXPORT void
+_plat__Signal_PowerOff(
+ void
+ );
+
+/* C.8.7. From PPPlat.c */
+/* C.8.7.1. _plat__PhysicalPresenceAsserted() */
+/* Check if physical presence is signaled */
+/* Return Values Meaning */
+/* TRUE(1) if physical presence is signaled */
+/* FALSE(0) if physical presence is not signaled */
+LIB_EXPORT int
+_plat__PhysicalPresenceAsserted(
+ void
+ );
+#if 0 /* libtpms added */
+/* C.8.7.2. _plat__Signal_PhysicalPresenceOn() */
+/* Signal physical presence on */
+LIB_EXPORT void
+_plat__Signal_PhysicalPresenceOn(
+ void
+ );
+/* C.8.7.3. _plat__Signal_PhysicalPresenceOff() */
+/* Signal physical presence off */
+LIB_EXPORT void
+_plat__Signal_PhysicalPresenceOff(
+ void
+ );
+#endif /* libtpms added */
+
+/* C.8.8. From RunCommand.c */
+/* C.8.8.1. _plat__RunCommand() */
+/* This version of RunCommand() will set up a jum_buf and call ExecuteCommand(). If the command
+ executes without failing, it will return and RunCommand() will return. If there is a failure in
+ the command, then _plat__Fail() is called and it will longjump back to RunCommand() which will
+ call ExecuteCommand() again. However, this time, the TPM will be in failure mode so
+ ExecuteCommand() will simply build a failure response and return. */
+LIB_EXPORT void
+_plat__RunCommand(
+ uint32_t requestSize, // IN: command buffer size
+ unsigned char *request, // IN: command buffer
+ uint32_t *responseSize, // IN/OUT: response buffer size
+ unsigned char **response // IN/OUT: response buffer
+ );
+/* C.8.8.2. _plat__Fail() */
+/* This is the platform depended failure exit for the TPM. */
+LIB_EXPORT NORETURN void
+_plat__Fail(
+ void
+ );
+
+/* C.8.9. From Unique.c */
+/* C.8.9.1 _plat__GetUnique() */
+/* This function is used to access the platform-specific unique value. This function places the
+ unique value in the provided buffer (b) and returns the number of bytes transferred. The function
+ will not copy more data than bSize. */
+/* NOTE: If a platform unique value has unequal distribution of uniqueness and bSize is smaller than
+ the size of the unique value, the bSize portion with the most uniqueness should be returned. */
+LIB_EXPORT uint32_t
+_plat__GetUnique(
+ uint32_t which, // authorities (0) or details
+ uint32_t bSize, // size of the buffer
+ unsigned char *b // output buffer
+ );
+
+/* libtpms added begin */
+#include <time.h>
+void ClockAdjustPostResume(UINT64 backthen, BOOL timesAreRealtime);
+uint64_t ClockGetTime(clockid_t clk_id);
+/* libtpms added end */
+
+#endif // _PLATFORM_FP_H_
diff --git a/src/tpm2/PolicyAuthValue_fp.h b/src/tpm2/PolicyAuthValue_fp.h
new file mode 100644
index 0000000..836cea0
--- /dev/null
+++ b/src/tpm2/PolicyAuthValue_fp.h
@@ -0,0 +1,79 @@
+/********************************************************************************/
+/* */
+/* */
+/* Written by Ken Goldman */
+/* IBM Thomas J. Watson Research Center */
+/* $Id: PolicyAuthValue_fp.h 809 2016-11-16 18:31:54Z kgoldman $ */
+/* */
+/* Licenses and Notices */
+/* */
+/* 1. Copyright Licenses: */
+/* */
+/* - Trusted Computing Group (TCG) grants to the user of the source code in */
+/* this specification (the "Source Code") a worldwide, irrevocable, */
+/* nonexclusive, royalty free, copyright license to reproduce, create */
+/* derivative works, distribute, display and perform the Source Code and */
+/* derivative works thereof, and to grant others the rights granted herein. */
+/* */
+/* - The TCG grants to the user of the other parts of the specification */
+/* (other than the Source Code) the rights to reproduce, distribute, */
+/* display, and perform the specification solely for the purpose of */
+/* developing products based on such documents. */
+/* */
+/* 2. Source Code Distribution Conditions: */
+/* */
+/* - Redistributions of Source Code must retain the above copyright licenses, */
+/* this list of conditions and the following disclaimers. */
+/* */
+/* - Redistributions in binary form must reproduce the above copyright */
+/* licenses, this list of conditions and the following disclaimers in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* 3. Disclaimers: */
+/* */
+/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
+/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
+/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
+/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
+/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
+/* information on specification licensing rights available through TCG */
+/* membership agreements. */
+/* */
+/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
+/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
+/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
+/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
+/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
+/* */
+/* - Without limitation, TCG and its members and licensors disclaim all */
+/* liability, including liability for infringement of any proprietary */
+/* rights, relating to use of information in this specification and to the */
+/* implementation of this specification, and TCG disclaims all liability for */
+/* cost of procurement of substitute goods or services, lost profits, loss */
+/* of use, loss of data or any incidental, consequential, direct, indirect, */
+/* or special damages, whether under contract, tort, warranty or otherwise, */
+/* arising in any way out of use or reliance upon this specification or any */
+/* information herein. */
+/* */
+/* (c) Copyright IBM Corp. and others, 2012-2015 */
+/* */
+/********************************************************************************/
+
+/* rev 119 */
+
+#ifndef POLICYAUTHVALUE_FP_H
+#define POLICYAUTHVALUE_FP_H
+
+typedef struct {
+ TPMI_SH_POLICY policySession;
+} PolicyAuthValue_In;
+
+#define RC_PolicyAuthValue_policySession (TPM_RC_H + TPM_RC_1)
+
+TPM_RC
+TPM2_PolicyAuthValue(
+ PolicyAuthValue_In *in // IN: input parameter list
+ );
+
+
+#endif
diff --git a/src/tpm2/PolicyAuthorizeNV_fp.h b/src/tpm2/PolicyAuthorizeNV_fp.h
new file mode 100644
index 0000000..03ebe52
--- /dev/null
+++ b/src/tpm2/PolicyAuthorizeNV_fp.h
@@ -0,0 +1,82 @@
+/********************************************************************************/
+/* */
+/* */
+/* Written by Ken Goldman */
+/* IBM Thomas J. Watson Research Center */
+/* $Id: PolicyAuthorizeNV_fp.h 809 2016-11-16 18:31:54Z kgoldman $ */
+/* */
+/* Licenses and Notices */
+/* */
+/* 1. Copyright Licenses: */
+/* */
+/* - Trusted Computing Group (TCG) grants to the user of the source code in */
+/* this specification (the "Source Code") a worldwide, irrevocable, */
+/* nonexclusive, royalty free, copyright license to reproduce, create */
+/* derivative works, distribute, display and perform the Source Code and */
+/* derivative works thereof, and to grant others the rights granted herein. */
+/* */
+/* - The TCG grants to the user of the other parts of the specification */
+/* (other than the Source Code) the rights to reproduce, distribute, */
+/* display, and perform the specification solely for the purpose of */
+/* developing products based on such documents. */
+/* */
+/* 2. Source Code Distribution Conditions: */
+/* */
+/* - Redistributions of Source Code must retain the above copyright licenses, */
+/* this list of conditions and the following disclaimers. */
+/* */
+/* - Redistributions in binary form must reproduce the above copyright */
+/* licenses, this list of conditions and the following disclaimers in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* 3. Disclaimers: */
+/* */
+/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
+/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
+/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
+/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
+/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
+/* information on specification licensing rights available through TCG */
+/* membership agreements. */
+/* */
+/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
+/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
+/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
+/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
+/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
+/* */
+/* - Without limitation, TCG and its members and licensors disclaim all */
+/* liability, including liability for infringement of any proprietary */
+/* rights, relating to use of information in this specification and to the */
+/* implementation of this specification, and TCG disclaims all liability for */
+/* cost of procurement of substitute goods or services, lost profits, loss */
+/* of use, loss of data or any incidental, consequential, direct, indirect, */
+/* or special damages, whether under contract, tort, warranty or otherwise, */
+/* arising in any way out of use or reliance upon this specification or any */
+/* information herein. */
+/* */
+/* (c) Copyright IBM Corp. and others, 2012-2015, 2016 */
+/* */
+/********************************************************************************/
+
+/* rev 136 */
+
+#ifndef POLICYAUTHORIZENV_FP_H
+#define POLICYAUTHORIZENV_FP_H
+
+typedef struct {
+ TPMI_RH_NV_AUTH authHandle;
+ TPMI_RH_NV_INDEX nvIndex;
+ TPMI_SH_POLICY policySession;
+} PolicyAuthorizeNV_In;
+
+#define RC_PolicyAuthorizeNV_authHandle (TPM_RC_H + TPM_RC_1)
+#define RC_PolicyAuthorizeNV_nvIndex (TPM_RC_H + TPM_RC_2)
+#define RC_PolicyAuthorizeNV_policySession (TPM_RC_H + TPM_RC_3)
+
+TPM_RC
+TPM2_PolicyAuthorizeNV(
+ PolicyAuthorizeNV_In *in // IN: input parameter list
+ );
+
+#endif
diff --git a/src/tpm2/PolicyAuthorize_fp.h b/src/tpm2/PolicyAuthorize_fp.h
new file mode 100644
index 0000000..42b6704
--- /dev/null
+++ b/src/tpm2/PolicyAuthorize_fp.h
@@ -0,0 +1,86 @@
+/********************************************************************************/
+/* */
+/* */
+/* Written by Ken Goldman */
+/* IBM Thomas J. Watson Research Center */
+/* $Id: PolicyAuthorize_fp.h 809 2016-11-16 18:31:54Z kgoldman $ */
+/* */
+/* Licenses and Notices */
+/* */
+/* 1. Copyright Licenses: */
+/* */
+/* - Trusted Computing Group (TCG) grants to the user of the source code in */
+/* this specification (the "Source Code") a worldwide, irrevocable, */
+/* nonexclusive, royalty free, copyright license to reproduce, create */
+/* derivative works, distribute, display and perform the Source Code and */
+/* derivative works thereof, and to grant others the rights granted herein. */
+/* */
+/* - The TCG grants to the user of the other parts of the specification */
+/* (other than the Source Code) the rights to reproduce, distribute, */
+/* display, and perform the specification solely for the purpose of */
+/* developing products based on such documents. */
+/* */
+/* 2. Source Code Distribution Conditions: */
+/* */
+/* - Redistributions of Source Code must retain the above copyright licenses, */
+/* this list of conditions and the following disclaimers. */
+/* */
+/* - Redistributions in binary form must reproduce the above copyright */
+/* licenses, this list of conditions and the following disclaimers in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* 3. Disclaimers: */
+/* */
+/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
+/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
+/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
+/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
+/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
+/* information on specification licensing rights available through TCG */
+/* membership agreements. */
+/* */
+/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
+/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
+/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
+/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
+/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
+/* */
+/* - Without limitation, TCG and its members and licensors disclaim all */
+/* liability, including liability for infringement of any proprietary */
+/* rights, relating to use of information in this specification and to the */
+/* implementation of this specification, and TCG disclaims all liability for */
+/* cost of procurement of substitute goods or services, lost profits, loss */
+/* of use, loss of data or any incidental, consequential, direct, indirect, */
+/* or special damages, whether under contract, tort, warranty or otherwise, */
+/* arising in any way out of use or reliance upon this specification or any */
+/* information herein. */
+/* */
+/* (c) Copyright IBM Corp. and others, 2012-2015 */
+/* */
+/********************************************************************************/
+
+/* rev 119 */
+
+#ifndef POLICYAUTHORIZE_FP_H
+#define POLICYAUTHORIZE_FP_H
+
+typedef struct {
+ TPMI_SH_POLICY policySession;
+ TPM2B_DIGEST approvedPolicy;
+ TPM2B_NONCE policyRef;
+ TPM2B_NAME keySign;
+ TPMT_TK_VERIFIED checkTicket;
+} PolicyAuthorize_In;
+
+#define RC_PolicyAuthorize_policySession (TPM_RC_H + TPM_RC_1)
+#define RC_PolicyAuthorize_approvedPolicy (TPM_RC_P + TPM_RC_1)
+#define RC_PolicyAuthorize_policyRef (TPM_RC_P + TPM_RC_2)
+#define RC_PolicyAuthorize_keySign (TPM_RC_P + TPM_RC_3)
+#define RC_PolicyAuthorize_checkTicket (TPM_RC_P + TPM_RC_4)
+
+TPM_RC
+TPM2_PolicyAuthorize(
+ PolicyAuthorize_In *in // IN: input parameter list
+ );
+
+#endif
diff --git a/src/tpm2/PolicyCommandCode_fp.h b/src/tpm2/PolicyCommandCode_fp.h
new file mode 100644
index 0000000..698c5a5
--- /dev/null
+++ b/src/tpm2/PolicyCommandCode_fp.h
@@ -0,0 +1,80 @@
+/********************************************************************************/
+/* */
+/* */
+/* Written by Ken Goldman */
+/* IBM Thomas J. Watson Research Center */
+/* $Id: PolicyCommandCode_fp.h 809 2016-11-16 18:31:54Z kgoldman $ */
+/* */
+/* Licenses and Notices */
+/* */
+/* 1. Copyright Licenses: */
+/* */
+/* - Trusted Computing Group (TCG) grants to the user of the source code in */
+/* this specification (the "Source Code") a worldwide, irrevocable, */
+/* nonexclusive, royalty free, copyright license to reproduce, create */
+/* derivative works, distribute, display and perform the Source Code and */
+/* derivative works thereof, and to grant others the rights granted herein. */
+/* */
+/* - The TCG grants to the user of the other parts of the specification */
+/* (other than the Source Code) the rights to reproduce, distribute, */
+/* display, and perform the specification solely for the purpose of */
+/* developing products based on such documents. */
+/* */
+/* 2. Source Code Distribution Conditions: */
+/* */
+/* - Redistributions of Source Code must retain the above copyright licenses, */
+/* this list of conditions and the following disclaimers. */
+/* */
+/* - Redistributions in binary form must reproduce the above copyright */
+/* licenses, this list of conditions and the following disclaimers in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* 3. Disclaimers: */
+/* */
+/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
+/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
+/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
+/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
+/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
+/* information on specification licensing rights available through TCG */
+/* membership agreements. */
+/* */
+/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
+/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
+/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
+/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
+/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
+/* */
+/* - Without limitation, TCG and its members and licensors disclaim all */
+/* liability, including liability for infringement of any proprietary */
+/* rights, relating to use of information in this specification and to the */
+/* implementation of this specification, and TCG disclaims all liability for */
+/* cost of procurement of substitute goods or services, lost profits, loss */
+/* of use, loss of data or any incidental, consequential, direct, indirect, */
+/* or special damages, whether under contract, tort, warranty or otherwise, */
+/* arising in any way out of use or reliance upon this specification or any */
+/* information herein. */
+/* */
+/* (c) Copyright IBM Corp. and others, 2012-2015 */
+/* */
+/********************************************************************************/
+
+/* rev 119 */
+
+#ifndef POLICYCOMMANDCODE_FP_H
+#define POLICYCOMMANDCODE_FP_H
+
+typedef struct {
+ TPMI_SH_POLICY policySession;
+ TPM_CC code;
+} PolicyCommandCode_In;
+
+#define RC_PolicyCommandCode_policySession (TPM_RC_H + TPM_RC_1)
+#define RC_PolicyCommandCode_code (TPM_RC_P + TPM_RC_1)
+
+TPM_RC
+TPM2_PolicyCommandCode(
+ PolicyCommandCode_In *in // IN: input parameter list
+ );
+
+#endif
diff --git a/src/tpm2/PolicyCounterTimer_fp.h b/src/tpm2/PolicyCounterTimer_fp.h
new file mode 100644
index 0000000..2302b65
--- /dev/null
+++ b/src/tpm2/PolicyCounterTimer_fp.h
@@ -0,0 +1,85 @@
+/********************************************************************************/
+/* */
+/* */
+/* Written by Ken Goldman */
+/* IBM Thomas J. Watson Research Center */
+/* $Id: PolicyCounterTimer_fp.h 809 2016-11-16 18:31:54Z kgoldman $ */
+/* */
+/* Licenses and Notices */
+/* */
+/* 1. Copyright Licenses: */
+/* */
+/* - Trusted Computing Group (TCG) grants to the user of the source code in */
+/* this specification (the "Source Code") a worldwide, irrevocable, */
+/* nonexclusive, royalty free, copyright license to reproduce, create */
+/* derivative works, distribute, display and perform the Source Code and */
+/* derivative works thereof, and to grant others the rights granted herein. */
+/* */
+/* - The TCG grants to the user of the other parts of the specification */
+/* (other than the Source Code) the rights to reproduce, distribute, */
+/* display, and perform the specification solely for the purpose of */
+/* developing products based on such documents. */
+/* */
+/* 2. Source Code Distribution Conditions: */
+/* */
+/* - Redistributions of Source Code must retain the above copyright licenses, */
+/* this list of conditions and the following disclaimers. */
+/* */
+/* - Redistributions in binary form must reproduce the above copyright */
+/* licenses, this list of conditions and the following disclaimers in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* 3. Disclaimers: */
+/* */
+/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
+/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
+/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
+/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
+/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
+/* information on specification licensing rights available through TCG */
+/* membership agreements. */
+/* */
+/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
+/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
+/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
+/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
+/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
+/* */
+/* - Without limitation, TCG and its members and licensors disclaim all */
+/* liability, including liability for infringement of any proprietary */
+/* rights, relating to use of information in this specification and to the */
+/* implementation of this specification, and TCG disclaims all liability for */
+/* cost of procurement of substitute goods or services, lost profits, loss */
+/* of use, loss of data or any incidental, consequential, direct, indirect, */
+/* or special damages, whether under contract, tort, warranty or otherwise, */
+/* arising in any way out of use or reliance upon this specification or any */
+/* information herein. */
+/* */
+/* (c) Copyright IBM Corp. and others, 2012-2015 */
+/* */
+/********************************************************************************/
+
+/* rev 119 */
+
+#ifndef POLICYCOUNTERTIMER_FP_H
+#define POLICYCOUNTERTIMER_FP_H
+
+typedef struct {
+ TPMI_SH_POLICY policySession;
+ TPM2B_OPERAND operandB;
+ UINT16 offset;
+ TPM_EO operation;
+} PolicyCounterTimer_In;
+
+#define RC_PolicyCounterTimer_policySession (TPM_RC_H + TPM_RC_1)
+#define RC_PolicyCounterTimer_operandB (TPM_RC_P + TPM_RC_1)
+#define RC_PolicyCounterTimer_offset (TPM_RC_P + TPM_RC_2)
+#define RC_PolicyCounterTimer_operation (TPM_RC_P + TPM_RC_3)
+
+TPM_RC
+TPM2_PolicyCounterTimer(
+ PolicyCounterTimer_In *in // IN: input parameter list
+ );
+
+
+#endif
diff --git a/src/tpm2/PolicyCpHash_fp.h b/src/tpm2/PolicyCpHash_fp.h
new file mode 100644
index 0000000..0ee1ea2
--- /dev/null
+++ b/src/tpm2/PolicyCpHash_fp.h
@@ -0,0 +1,81 @@
+/********************************************************************************/
+/* */
+/* */
+/* Written by Ken Goldman */
+/* IBM Thomas J. Watson Research Center */
+/* $Id: PolicyCpHash_fp.h 1521 2019-11-15 21:00:47Z kgoldman $ */
+/* */
+/* Licenses and Notices */
+/* */
+/* 1. Copyright Licenses: */
+/* */
+/* - Trusted Computing Group (TCG) grants to the user of the source code in */
+/* this specification (the "Source Code") a worldwide, irrevocable, */
+/* nonexclusive, royalty free, copyright license to reproduce, create */
+/* derivative works, distribute, display and perform the Source Code and */
+/* derivative works thereof, and to grant others the rights granted herein. */
+/* */
+/* - The TCG grants to the user of the other parts of the specification */
+/* (other than the Source Code) the rights to reproduce, distribute, */
+/* display, and perform the specification solely for the purpose of */
+/* developing products based on such documents. */
+/* */
+/* 2. Source Code Distribution Conditions: */
+/* */
+/* - Redistributions of Source Code must retain the above copyright licenses, */
+/* this list of conditions and the following disclaimers. */
+/* */
+/* - Redistributions in binary form must reproduce the above copyright */
+/* licenses, this list of conditions and the following disclaimers in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* 3. Disclaimers: */
+/* */
+/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
+/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
+/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
+/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
+/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
+/* information on specification licensing rights available through TCG */
+/* membership agreements. */
+/* */
+/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
+/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
+/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
+/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
+/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
+/* */
+/* - Without limitation, TCG and its members and licensors disclaim all */
+/* liability, including liability for infringement of any proprietary */
+/* rights, relating to use of information in this specification and to the */
+/* implementation of this specification, and TCG disclaims all liability for */
+/* cost of procurement of substitute goods or services, lost profits, loss */
+/* of use, loss of data or any incidental, consequential, direct, indirect, */
+/* or special damages, whether under contract, tort, warranty or otherwise, */
+/* arising in any way out of use or reliance upon this specification or any */
+/* information herein. */
+/* */
+/* (c) Copyright IBM Corp. and others, 2012-2015 */
+/* */
+/********************************************************************************/
+
+/* rev 119 */
+
+#ifndef POLICYCPHASH_FP_H
+#define POLICYCPHASH_FP_H
+
+typedef struct {
+ TPMI_SH_POLICY policySession;
+ TPM2B_DIGEST cpHashA;
+} PolicyCpHash_In;
+
+#define RC_PolicyCpHash_policySession (TPM_RC_H + TPM_RC_1)
+#define RC_PolicyCpHash_cpHashA (TPM_RC_P + TPM_RC_1)
+
+TPM_RC
+TPM2_PolicyCpHash(
+ PolicyCpHash_In *in // IN: input parameter list
+ );
+
+
+#endif
diff --git a/src/tpm2/PolicyDuplicationSelect_fp.h b/src/tpm2/PolicyDuplicationSelect_fp.h
new file mode 100644
index 0000000..c1010da
--- /dev/null
+++ b/src/tpm2/PolicyDuplicationSelect_fp.h
@@ -0,0 +1,85 @@
+/********************************************************************************/
+/* */
+/* */
+/* Written by Ken Goldman */
+/* IBM Thomas J. Watson Research Center */
+/* $Id: PolicyDuplicationSelect_fp.h 809 2016-11-16 18:31:54Z kgoldman $ */
+/* */
+/* Licenses and Notices */
+/* */
+/* 1. Copyright Licenses: */
+/* */
+/* - Trusted Computing Group (TCG) grants to the user of the source code in */
+/* this specification (the "Source Code") a worldwide, irrevocable, */
+/* nonexclusive, royalty free, copyright license to reproduce, create */
+/* derivative works, distribute, display and perform the Source Code and */
+/* derivative works thereof, and to grant others the rights granted herein. */
+/* */
+/* - The TCG grants to the user of the other parts of the specification */
+/* (other than the Source Code) the rights to reproduce, distribute, */
+/* display, and perform the specification solely for the purpose of */
+/* developing products based on such documents. */
+/* */
+/* 2. Source Code Distribution Conditions: */
+/* */
+/* - Redistributions of Source Code must retain the above copyright licenses, */
+/* this list of conditions and the following disclaimers. */
+/* */
+/* - Redistributions in binary form must reproduce the above copyright */
+/* licenses, this list of conditions and the following disclaimers in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* 3. Disclaimers: */
+/* */
+/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
+/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
+/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
+/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
+/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
+/* information on specification licensing rights available through TCG */
+/* membership agreements. */
+/* */
+/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
+/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
+/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
+/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
+/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
+/* */
+/* - Without limitation, TCG and its members and licensors disclaim all */
+/* liability, including liability for infringement of any proprietary */
+/* rights, relating to use of information in this specification and to the */
+/* implementation of this specification, and TCG disclaims all liability for */
+/* cost of procurement of substitute goods or services, lost profits, loss */
+/* of use, loss of data or any incidental, consequential, direct, indirect, */
+/* or special damages, whether under contract, tort, warranty or otherwise, */
+/* arising in any way out of use or reliance upon this specification or any */
+/* information herein. */
+/* */
+/* (c) Copyright IBM Corp. and others, 2012-2015 */
+/* */
+/********************************************************************************/
+
+/* rev 119 */
+
+#ifndef POLICYDUPLICATIONSELECT_FP_H
+#define POLICYDUPLICATIONSELECT_FP_H
+
+typedef struct {
+ TPMI_SH_POLICY policySession;
+ TPM2B_NAME objectName;
+ TPM2B_NAME newParentName;
+ TPMI_YES_NO includeObject;
+} PolicyDuplicationSelect_In;
+
+#define RC_PolicyDuplicationSelect_policySession (TPM_RC_H + TPM_RC_1)
+#define RC_PolicyDuplicationSelect_objectName (TPM_RC_P + TPM_RC_1)
+#define RC_PolicyDuplicationSelect_newParentName (TPM_RC_P + TPM_RC_2)
+#define RC_PolicyDuplicationSelect_includeObject (TPM_RC_P + TPM_RC_3)
+
+TPM_RC
+TPM2_PolicyDuplicationSelect(
+ PolicyDuplicationSelect_In *in // IN: input parameter list
+ );
+
+
+#endif
diff --git a/src/tpm2/PolicyGetDigest_fp.h b/src/tpm2/PolicyGetDigest_fp.h
new file mode 100644
index 0000000..921d55e
--- /dev/null
+++ b/src/tpm2/PolicyGetDigest_fp.h
@@ -0,0 +1,84 @@
+/********************************************************************************/
+/* */
+/* */
+/* Written by Ken Goldman */
+/* IBM Thomas J. Watson Research Center */
+/* $Id: PolicyGetDigest_fp.h 809 2016-11-16 18:31:54Z kgoldman $ */
+/* */
+/* Licenses and Notices */
+/* */
+/* 1. Copyright Licenses: */
+/* */
+/* - Trusted Computing Group (TCG) grants to the user of the source code in */
+/* this specification (the "Source Code") a worldwide, irrevocable, */
+/* nonexclusive, royalty free, copyright license to reproduce, create */
+/* derivative works, distribute, display and perform the Source Code and */
+/* derivative works thereof, and to grant others the rights granted herein. */
+/* */
+/* - The TCG grants to the user of the other parts of the specification */
+/* (other than the Source Code) the rights to reproduce, distribute, */
+/* display, and perform the specification solely for the purpose of */
+/* developing products based on such documents. */
+/* */
+/* 2. Source Code Distribution Conditions: */
+/* */
+/* - Redistributions of Source Code must retain the above copyright licenses, */
+/* this list of conditions and the following disclaimers. */
+/* */
+/* - Redistributions in binary form must reproduce the above copyright */
+/* licenses, this list of conditions and the following disclaimers in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* 3. Disclaimers: */
+/* */
+/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
+/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
+/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
+/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
+/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
+/* information on specification licensing rights available through TCG */
+/* membership agreements. */
+/* */
+/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
+/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
+/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
+/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
+/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
+/* */
+/* - Without limitation, TCG and its members and licensors disclaim all */
+/* liability, including liability for infringement of any proprietary */
+/* rights, relating to use of information in this specification and to the */
+/* implementation of this specification, and TCG disclaims all liability for */
+/* cost of procurement of substitute goods or services, lost profits, loss */
+/* of use, loss of data or any incidental, consequential, direct, indirect, */
+/* or special damages, whether under contract, tort, warranty or otherwise, */
+/* arising in any way out of use or reliance upon this specification or any */
+/* information herein. */
+/* */
+/* (c) Copyright IBM Corp. and others, 2012-2015 */
+/* */
+/********************************************************************************/
+
+/* rev 119 */
+
+#ifndef POLICYGETDIGEST_FP_H
+#define POLICYGETDIGEST_FP_H
+
+typedef struct {
+ TPMI_SH_POLICY policySession;
+} PolicyGetDigest_In;
+
+#define RC_PolicyGetDigest_policySession (TPM_RC_P + TPM_RC_1)
+
+typedef struct {
+ TPM2B_DIGEST policyDigest;
+} PolicyGetDigest_Out;
+
+TPM_RC
+TPM2_PolicyGetDigest(
+ PolicyGetDigest_In *in, // IN: input parameter list
+ PolicyGetDigest_Out *out // OUT: output parameter list
+ );
+
+
+#endif
diff --git a/src/tpm2/PolicyLocality_fp.h b/src/tpm2/PolicyLocality_fp.h
new file mode 100644
index 0000000..c9f0cc4
--- /dev/null
+++ b/src/tpm2/PolicyLocality_fp.h
@@ -0,0 +1,81 @@
+/********************************************************************************/
+/* */
+/* */
+/* Written by Ken Goldman */
+/* IBM Thomas J. Watson Research Center */
+/* $Id: PolicyLocality_fp.h 809 2016-11-16 18:31:54Z kgoldman $ */
+/* */
+/* Licenses and Notices */
+/* */
+/* 1. Copyright Licenses: */
+/* */
+/* - Trusted Computing Group (TCG) grants to the user of the source code in */
+/* this specification (the "Source Code") a worldwide, irrevocable, */
+/* nonexclusive, royalty free, copyright license to reproduce, create */
+/* derivative works, distribute, display and perform the Source Code and */
+/* derivative works thereof, and to grant others the rights granted herein. */
+/* */
+/* - The TCG grants to the user of the other parts of the specification */
+/* (other than the Source Code) the rights to reproduce, distribute, */
+/* display, and perform the specification solely for the purpose of */
+/* developing products based on such documents. */
+/* */
+/* 2. Source Code Distribution Conditions: */
+/* */
+/* - Redistributions of Source Code must retain the above copyright licenses, */
+/* this list of conditions and the following disclaimers. */
+/* */
+/* - Redistributions in binary form must reproduce the above copyright */
+/* licenses, this list of conditions and the following disclaimers in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* 3. Disclaimers: */
+/* */
+/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
+/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
+/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
+/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
+/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
+/* information on specification licensing rights available through TCG */
+/* membership agreements. */
+/* */
+/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
+/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
+/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
+/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
+/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
+/* */
+/* - Without limitation, TCG and its members and licensors disclaim all */
+/* liability, including liability for infringement of any proprietary */
+/* rights, relating to use of information in this specification and to the */
+/* implementation of this specification, and TCG disclaims all liability for */
+/* cost of procurement of substitute goods or services, lost profits, loss */
+/* of use, loss of data or any incidental, consequential, direct, indirect, */
+/* or special damages, whether under contract, tort, warranty or otherwise, */
+/* arising in any way out of use or reliance upon this specification or any */
+/* information herein. */
+/* */
+/* (c) Copyright IBM Corp. and others, 2012-2015 */
+/* */
+/********************************************************************************/
+
+/* rev 119 */
+
+#ifndef POLICYLOCALITY_FP_H
+#define POLICYLOCALITY_FP_H
+
+typedef struct {
+ TPMI_SH_POLICY policySession;
+ TPMA_LOCALITY locality;
+} PolicyLocality_In;
+
+#define RC_PolicyLocality_policySession (TPM_RC_H + TPM_RC_1)
+#define RC_PolicyLocality_locality (TPM_RC_P + TPM_RC_1)
+
+TPM_RC
+TPM2_PolicyLocality(
+ PolicyLocality_In *in // IN: input parameter list
+ );
+
+
+#endif
diff --git a/src/tpm2/PolicyNV_fp.h b/src/tpm2/PolicyNV_fp.h
new file mode 100644
index 0000000..4666e95
--- /dev/null
+++ b/src/tpm2/PolicyNV_fp.h
@@ -0,0 +1,88 @@
+/********************************************************************************/
+/* */
+/* */
+/* Written by Ken Goldman */
+/* IBM Thomas J. Watson Research Center */
+/* $Id: PolicyNV_fp.h 809 2016-11-16 18:31:54Z kgoldman $ */
+/* */
+/* Licenses and Notices */
+/* */
+/* 1. Copyright Licenses: */
+/* */
+/* - Trusted Computing Group (TCG) grants to the user of the source code in */
+/* this specification (the "Source Code") a worldwide, irrevocable, */
+/* nonexclusive, royalty free, copyright license to reproduce, create */
+/* derivative works, distribute, display and perform the Source Code and */
+/* derivative works thereof, and to grant others the rights granted herein. */
+/* */
+/* - The TCG grants to the user of the other parts of the specification */
+/* (other than the Source Code) the rights to reproduce, distribute, */
+/* display, and perform the specification solely for the purpose of */
+/* developing products based on such documents. */
+/* */
+/* 2. Source Code Distribution Conditions: */
+/* */
+/* - Redistributions of Source Code must retain the above copyright licenses, */
+/* this list of conditions and the following disclaimers. */
+/* */
+/* - Redistributions in binary form must reproduce the above copyright */
+/* licenses, this list of conditions and the following disclaimers in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* 3. Disclaimers: */
+/* */
+/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
+/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
+/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
+/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
+/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
+/* information on specification licensing rights available through TCG */
+/* membership agreements. */
+/* */
+/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
+/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
+/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
+/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
+/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
+/* */
+/* - Without limitation, TCG and its members and licensors disclaim all */
+/* liability, including liability for infringement of any proprietary */
+/* rights, relating to use of information in this specification and to the */
+/* implementation of this specification, and TCG disclaims all liability for */
+/* cost of procurement of substitute goods or services, lost profits, loss */
+/* of use, loss of data or any incidental, consequential, direct, indirect, */
+/* or special damages, whether under contract, tort, warranty or otherwise, */
+/* arising in any way out of use or reliance upon this specification or any */
+/* information herein. */
+/* */
+/* (c) Copyright IBM Corp. and others, 2012-2015 */
+/* */
+/********************************************************************************/
+
+/* rev 119 */
+
+#ifndef POLICYNV_FP_H
+#define POLICYNV_FP_H
+
+typedef struct {
+ TPMI_RH_NV_AUTH authHandle;
+ TPMI_RH_NV_INDEX nvIndex;
+ TPMI_SH_POLICY policySession;
+ TPM2B_OPERAND operandB;
+ UINT16 offset;
+ TPM_EO operation;
+} PolicyNV_In;
+
+#define RC_PolicyNV_authHandle (TPM_RC_H + TPM_RC_1)
+#define RC_PolicyNV_nvIndex (TPM_RC_H + TPM_RC_2)
+#define RC_PolicyNV_policySession (TPM_RC_H + TPM_RC_3)
+#define RC_PolicyNV_operandB (TPM_RC_P + TPM_RC_1)
+#define RC_PolicyNV_offset (TPM_RC_P + TPM_RC_2)
+#define RC_PolicyNV_operation (TPM_RC_P + TPM_RC_3)
+
+TPM_RC
+TPM2_PolicyNV(
+ PolicyNV_In *in // IN: input parameter list
+ );
+
+#endif
diff --git a/src/tpm2/PolicyNameHash_fp.h b/src/tpm2/PolicyNameHash_fp.h
new file mode 100644
index 0000000..89945b1
--- /dev/null
+++ b/src/tpm2/PolicyNameHash_fp.h
@@ -0,0 +1,81 @@
+/********************************************************************************/
+/* */
+/* */
+/* Written by Ken Goldman */
+/* IBM Thomas J. Watson Research Center */
+/* $Id: PolicyNameHash_fp.h 809 2016-11-16 18:31:54Z kgoldman $ */
+/* */
+/* Licenses and Notices */
+/* */
+/* 1. Copyright Licenses: */
+/* */
+/* - Trusted Computing Group (TCG) grants to the user of the source code in */
+/* this specification (the "Source Code") a worldwide, irrevocable, */
+/* nonexclusive, royalty free, copyright license to reproduce, create */
+/* derivative works, distribute, display and perform the Source Code and */
+/* derivative works thereof, and to grant others the rights granted herein. */
+/* */
+/* - The TCG grants to the user of the other parts of the specification */
+/* (other than the Source Code) the rights to reproduce, distribute, */
+/* display, and perform the specification solely for the purpose of */
+/* developing products based on such documents. */
+/* */
+/* 2. Source Code Distribution Conditions: */
+/* */
+/* - Redistributions of Source Code must retain the above copyright licenses, */
+/* this list of conditions and the following disclaimers. */
+/* */
+/* - Redistributions in binary form must reproduce the above copyright */
+/* licenses, this list of conditions and the following disclaimers in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* 3. Disclaimers: */
+/* */
+/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
+/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
+/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
+/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
+/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
+/* information on specification licensing rights available through TCG */
+/* membership agreements. */
+/* */
+/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
+/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
+/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
+/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
+/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
+/* */
+/* - Without limitation, TCG and its members and licensors disclaim all */
+/* liability, including liability for infringement of any proprietary */
+/* rights, relating to use of information in this specification and to the */
+/* implementation of this specification, and TCG disclaims all liability for */
+/* cost of procurement of substitute goods or services, lost profits, loss */
+/* of use, loss of data or any incidental, consequential, direct, indirect, */
+/* or special damages, whether under contract, tort, warranty or otherwise, */
+/* arising in any way out of use or reliance upon this specification or any */
+/* information herein. */
+/* */
+/* (c) Copyright IBM Corp. and others, 2012-2015 */
+/* */
+/********************************************************************************/
+
+/* rev 119 */
+
+#ifndef POLICYNAMEHASH_FP_H
+#define POLICYNAMEHASH_FP_H
+
+typedef struct {
+ TPMI_SH_POLICY policySession;
+ TPM2B_DIGEST nameHash;
+} PolicyNameHash_In;
+
+#define RC_PolicyNameHash_policySession (TPM_RC_H + TPM_RC_1)
+#define RC_PolicyNameHash_nameHash (TPM_RC_P + TPM_RC_1)
+
+TPM_RC
+TPM2_PolicyNameHash(
+ PolicyNameHash_In *in // IN: input parameter list
+ );
+
+
+#endif
diff --git a/src/tpm2/PolicyNvWritten_fp.h b/src/tpm2/PolicyNvWritten_fp.h
new file mode 100644
index 0000000..2e78a14
--- /dev/null
+++ b/src/tpm2/PolicyNvWritten_fp.h
@@ -0,0 +1,81 @@
+/********************************************************************************/
+/* */
+/* */
+/* Written by Ken Goldman */
+/* IBM Thomas J. Watson Research Center */
+/* $Id: PolicyNvWritten_fp.h 809 2016-11-16 18:31:54Z kgoldman $ */
+/* */
+/* Licenses and Notices */
+/* */
+/* 1. Copyright Licenses: */
+/* */
+/* - Trusted Computing Group (TCG) grants to the user of the source code in */
+/* this specification (the "Source Code") a worldwide, irrevocable, */
+/* nonexclusive, royalty free, copyright license to reproduce, create */
+/* derivative works, distribute, display and perform the Source Code and */
+/* derivative works thereof, and to grant others the rights granted herein. */
+/* */
+/* - The TCG grants to the user of the other parts of the specification */
+/* (other than the Source Code) the rights to reproduce, distribute, */
+/* display, and perform the specification solely for the purpose of */
+/* developing products based on such documents. */
+/* */
+/* 2. Source Code Distribution Conditions: */
+/* */
+/* - Redistributions of Source Code must retain the above copyright licenses, */
+/* this list of conditions and the following disclaimers. */
+/* */
+/* - Redistributions in binary form must reproduce the above copyright */
+/* licenses, this list of conditions and the following disclaimers in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* 3. Disclaimers: */
+/* */
+/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
+/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
+/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
+/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
+/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
+/* information on specification licensing rights available through TCG */
+/* membership agreements. */
+/* */
+/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
+/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
+/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
+/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
+/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
+/* */
+/* - Without limitation, TCG and its members and licensors disclaim all */
+/* liability, including liability for infringement of any proprietary */
+/* rights, relating to use of information in this specification and to the */
+/* implementation of this specification, and TCG disclaims all liability for */
+/* cost of procurement of substitute goods or services, lost profits, loss */
+/* of use, loss of data or any incidental, consequential, direct, indirect, */
+/* or special damages, whether under contract, tort, warranty or otherwise, */
+/* arising in any way out of use or reliance upon this specification or any */
+/* information herein. */
+/* */
+/* (c) Copyright IBM Corp. and others, 2012-2015 */
+/* */
+/********************************************************************************/
+
+/* rev 119 */
+
+#ifndef POLICYNVWRITTEN_FP_H
+#define POLICYNVWRITTEN_FP_H
+
+typedef struct {
+ TPMI_SH_POLICY policySession;
+ TPMI_YES_NO writtenSet;
+} PolicyNvWritten_In;
+
+#define RC_PolicyNvWritten_policySession (TPM_RC_H + TPM_RC_1)
+#define RC_PolicyNvWritten_writtenSet (TPM_RC_P + TPM_RC_1)
+
+TPM_RC
+TPM2_PolicyNvWritten(
+ PolicyNvWritten_In *in // IN: input parameter list
+ );
+
+
+#endif
diff --git a/src/tpm2/PolicyOR_fp.h b/src/tpm2/PolicyOR_fp.h
new file mode 100644
index 0000000..5af84b9
--- /dev/null
+++ b/src/tpm2/PolicyOR_fp.h
@@ -0,0 +1,81 @@
+/********************************************************************************/
+/* */
+/* */
+/* Written by Ken Goldman */
+/* IBM Thomas J. Watson Research Center */
+/* $Id: PolicyOR_fp.h 809 2016-11-16 18:31:54Z kgoldman $ */
+/* */
+/* Licenses and Notices */
+/* */
+/* 1. Copyright Licenses: */
+/* */
+/* - Trusted Computing Group (TCG) grants to the user of the source code in */
+/* this specification (the "Source Code") a worldwide, irrevocable, */
+/* nonexclusive, royalty free, copyright license to reproduce, create */
+/* derivative works, distribute, display and perform the Source Code and */
+/* derivative works thereof, and to grant others the rights granted herein. */
+/* */
+/* - The TCG grants to the user of the other parts of the specification */
+/* (other than the Source Code) the rights to reproduce, distribute, */
+/* display, and perform the specification solely for the purpose of */
+/* developing products based on such documents. */
+/* */
+/* 2. Source Code Distribution Conditions: */
+/* */
+/* - Redistributions of Source Code must retain the above copyright licenses, */
+/* this list of conditions and the following disclaimers. */
+/* */
+/* - Redistributions in binary form must reproduce the above copyright */
+/* licenses, this list of conditions and the following disclaimers in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* 3. Disclaimers: */
+/* */
+/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
+/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
+/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
+/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
+/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
+/* information on specification licensing rights available through TCG */
+/* membership agreements. */
+/* */
+/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
+/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
+/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
+/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
+/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
+/* */
+/* - Without limitation, TCG and its members and licensors disclaim all */
+/* liability, including liability for infringement of any proprietary */
+/* rights, relating to use of information in this specification and to the */
+/* implementation of this specification, and TCG disclaims all liability for */
+/* cost of procurement of substitute goods or services, lost profits, loss */
+/* of use, loss of data or any incidental, consequential, direct, indirect, */
+/* or special damages, whether under contract, tort, warranty or otherwise, */
+/* arising in any way out of use or reliance upon this specification or any */
+/* information herein. */
+/* */
+/* (c) Copyright IBM Corp. and others, 2012-2015 */
+/* */
+/********************************************************************************/
+
+/* rev 119 */
+
+#ifndef POLICYOR_FP_H
+#define POLICYOR_FP_H
+
+typedef struct {
+ TPMI_SH_POLICY policySession;
+ TPML_DIGEST pHashList;
+} PolicyOR_In;
+
+#define RC_PolicyOR_policySession (TPM_RC_H + TPM_RC_1)
+#define RC_PolicyOR_pHashList (TPM_RC_P + TPM_RC_1)
+
+TPM_RC
+TPM2_PolicyOR(
+ PolicyOR_In *in // IN: input parameter list
+ );
+
+
+#endif
diff --git a/src/tpm2/PolicyPCR_fp.h b/src/tpm2/PolicyPCR_fp.h
new file mode 100644
index 0000000..cc53313
--- /dev/null
+++ b/src/tpm2/PolicyPCR_fp.h
@@ -0,0 +1,82 @@
+/********************************************************************************/
+/* */
+/* */
+/* Written by Ken Goldman */
+/* IBM Thomas J. Watson Research Center */
+/* $Id: PolicyPCR_fp.h 809 2016-11-16 18:31:54Z kgoldman $ */
+/* */
+/* Licenses and Notices */
+/* */
+/* 1. Copyright Licenses: */
+/* */
+/* - Trusted Computing Group (TCG) grants to the user of the source code in */
+/* this specification (the "Source Code") a worldwide, irrevocable, */
+/* nonexclusive, royalty free, copyright license to reproduce, create */
+/* derivative works, distribute, display and perform the Source Code and */
+/* derivative works thereof, and to grant others the rights granted herein. */
+/* */
+/* - The TCG grants to the user of the other parts of the specification */
+/* (other than the Source Code) the rights to reproduce, distribute, */
+/* display, and perform the specification solely for the purpose of */
+/* developing products based on such documents. */
+/* */
+/* 2. Source Code Distribution Conditions: */
+/* */
+/* - Redistributions of Source Code must retain the above copyright licenses, */
+/* this list of conditions and the following disclaimers. */
+/* */
+/* - Redistributions in binary form must reproduce the above copyright */
+/* licenses, this list of conditions and the following disclaimers in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* 3. Disclaimers: */
+/* */
+/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
+/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
+/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
+/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
+/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
+/* information on specification licensing rights available through TCG */
+/* membership agreements. */
+/* */
+/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
+/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
+/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
+/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
+/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
+/* */
+/* - Without limitation, TCG and its members and licensors disclaim all */
+/* liability, including liability for infringement of any proprietary */
+/* rights, relating to use of information in this specification and to the */
+/* implementation of this specification, and TCG disclaims all liability for */
+/* cost of procurement of substitute goods or services, lost profits, loss */
+/* of use, loss of data or any incidental, consequential, direct, indirect, */
+/* or special damages, whether under contract, tort, warranty or otherwise, */
+/* arising in any way out of use or reliance upon this specification or any */
+/* information herein. */
+/* */
+/* (c) Copyright IBM Corp. and others, 2012-2015 */
+/* */
+/********************************************************************************/
+
+/* rev 119 */
+
+#ifndef POLICYPCR_FP_H
+#define POLICYPCR_FP_H
+
+typedef struct {
+ TPMI_SH_POLICY policySession;
+ TPM2B_DIGEST pcrDigest;
+ TPML_PCR_SELECTION pcrs;
+} PolicyPCR_In;
+
+#define RC_PolicyPCR_policySession (TPM_RC_H + TPM_RC_1)
+#define RC_PolicyPCR_pcrDigest (TPM_RC_P + TPM_RC_1)
+#define RC_PolicyPCR_pcrs (TPM_RC_P + TPM_RC_2)
+
+TPM_RC
+TPM2_PolicyPCR(
+ PolicyPCR_In *in // IN: input parameter list
+ );
+
+#endif
diff --git a/src/tpm2/PolicyPassword_fp.h b/src/tpm2/PolicyPassword_fp.h
new file mode 100644
index 0000000..7671a5e
--- /dev/null
+++ b/src/tpm2/PolicyPassword_fp.h
@@ -0,0 +1,79 @@
+/********************************************************************************/
+/* */
+/* */
+/* Written by Ken Goldman */
+/* IBM Thomas J. Watson Research Center */
+/* $Id: PolicyPassword_fp.h 809 2016-11-16 18:31:54Z kgoldman $ */
+/* */
+/* Licenses and Notices */
+/* */
+/* 1. Copyright Licenses: */
+/* */
+/* - Trusted Computing Group (TCG) grants to the user of the source code in */
+/* this specification (the "Source Code") a worldwide, irrevocable, */
+/* nonexclusive, royalty free, copyright license to reproduce, create */
+/* derivative works, distribute, display and perform the Source Code and */
+/* derivative works thereof, and to grant others the rights granted herein. */
+/* */
+/* - The TCG grants to the user of the other parts of the specification */
+/* (other than the Source Code) the rights to reproduce, distribute, */
+/* display, and perform the specification solely for the purpose of */
+/* developing products based on such documents. */
+/* */
+/* 2. Source Code Distribution Conditions: */
+/* */
+/* - Redistributions of Source Code must retain the above copyright licenses, */
+/* this list of conditions and the following disclaimers. */
+/* */
+/* - Redistributions in binary form must reproduce the above copyright */
+/* licenses, this list of conditions and the following disclaimers in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* 3. Disclaimers: */
+/* */
+/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
+/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
+/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
+/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
+/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
+/* information on specification licensing rights available through TCG */
+/* membership agreements. */
+/* */
+/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
+/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
+/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
+/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
+/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
+/* */
+/* - Without limitation, TCG and its members and licensors disclaim all */
+/* liability, including liability for infringement of any proprietary */
+/* rights, relating to use of information in this specification and to the */
+/* implementation of this specification, and TCG disclaims all liability for */
+/* cost of procurement of substitute goods or services, lost profits, loss */
+/* of use, loss of data or any incidental, consequential, direct, indirect, */
+/* or special damages, whether under contract, tort, warranty or otherwise, */
+/* arising in any way out of use or reliance upon this specification or any */
+/* information herein. */
+/* */
+/* (c) Copyright IBM Corp. and others, 2012-2015 */
+/* */
+/********************************************************************************/
+
+/* rev 119 */
+
+#ifndef POLICYPASSWORD_FP_H
+#define POLICYPASSWORD_FP_H
+
+typedef struct {
+ TPMI_SH_POLICY policySession;
+} PolicyPassword_In;
+
+#define RC_PolicyPassword_policySession (TPM_RC_H + TPM_RC_1)
+
+TPM_RC
+TPM2_PolicyPassword(
+ PolicyPassword_In *in // IN: input parameter list
+ );
+
+
+#endif
diff --git a/src/tpm2/PolicyPhysicalPresence_fp.h b/src/tpm2/PolicyPhysicalPresence_fp.h
new file mode 100644
index 0000000..aa59a6a
--- /dev/null
+++ b/src/tpm2/PolicyPhysicalPresence_fp.h
@@ -0,0 +1,78 @@
+/********************************************************************************/
+/* */
+/* */
+/* Written by Ken Goldman */
+/* IBM Thomas J. Watson Research Center */
+/* $Id: PolicyPhysicalPresence_fp.h 809 2016-11-16 18:31:54Z kgoldman $ */
+/* */
+/* Licenses and Notices */
+/* */
+/* 1. Copyright Licenses: */
+/* */
+/* - Trusted Computing Group (TCG) grants to the user of the source code in */
+/* this specification (the "Source Code") a worldwide, irrevocable, */
+/* nonexclusive, royalty free, copyright license to reproduce, create */
+/* derivative works, distribute, display and perform the Source Code and */
+/* derivative works thereof, and to grant others the rights granted herein. */
+/* */
+/* - The TCG grants to the user of the other parts of the specification */
+/* (other than the Source Code) the rights to reproduce, distribute, */
+/* display, and perform the specification solely for the purpose of */
+/* developing products based on such documents. */
+/* */
+/* 2. Source Code Distribution Conditions: */
+/* */
+/* - Redistributions of Source Code must retain the above copyright licenses, */
+/* this list of conditions and the following disclaimers. */
+/* */
+/* - Redistributions in binary form must reproduce the above copyright */
+/* licenses, this list of conditions and the following disclaimers in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* 3. Disclaimers: */
+/* */
+/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
+/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
+/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
+/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
+/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
+/* information on specification licensing rights available through TCG */
+/* membership agreements. */
+/* */
+/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
+/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
+/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
+/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
+/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
+/* */
+/* - Without limitation, TCG and its members and licensors disclaim all */
+/* liability, including liability for infringement of any proprietary */
+/* rights, relating to use of information in this specification and to the */
+/* implementation of this specification, and TCG disclaims all liability for */
+/* cost of procurement of substitute goods or services, lost profits, loss */
+/* of use, loss of data or any incidental, consequential, direct, indirect, */
+/* or special damages, whether under contract, tort, warranty or otherwise, */
+/* arising in any way out of use or reliance upon this specification or any */
+/* information herein. */
+/* */
+/* (c) Copyright IBM Corp. and others, 2012-2015 */
+/* */
+/********************************************************************************/
+
+/* rev 119 */
+
+#ifndef POLICYPHYSICALPRESENCE_FP_H
+#define POLICYPHYSICALPRESENCE_FP_H
+
+typedef struct {
+ TPMI_SH_POLICY policySession;
+} PolicyPhysicalPresence_In;
+
+#define RC_PolicyPhysicalPresence_policySession (TPM_RC_H + TPM_RC_1)
+
+TPM_RC
+TPM2_PolicyPhysicalPresence(
+ PolicyPhysicalPresence_In *in // IN: input parameter list
+ );
+
+#endif
diff --git a/src/tpm2/PolicyRestart_fp.h b/src/tpm2/PolicyRestart_fp.h
new file mode 100644
index 0000000..279b7ce
--- /dev/null
+++ b/src/tpm2/PolicyRestart_fp.h
@@ -0,0 +1,79 @@
+/********************************************************************************/
+/* */
+/* */
+/* Written by Ken Goldman */
+/* IBM Thomas J. Watson Research Center */
+/* $Id: PolicyRestart_fp.h 809 2016-11-16 18:31:54Z kgoldman $ */
+/* */
+/* Licenses and Notices */
+/* */
+/* 1. Copyright Licenses: */
+/* */
+/* - Trusted Computing Group (TCG) grants to the user of the source code in */
+/* this specification (the "Source Code") a worldwide, irrevocable, */
+/* nonexclusive, royalty free, copyright license to reproduce, create */
+/* derivative works, distribute, display and perform the Source Code and */
+/* derivative works thereof, and to grant others the rights granted herein. */
+/* */
+/* - The TCG grants to the user of the other parts of the specification */
+/* (other than the Source Code) the rights to reproduce, distribute, */
+/* display, and perform the specification solely for the purpose of */
+/* developing products based on such documents. */
+/* */
+/* 2. Source Code Distribution Conditions: */
+/* */
+/* - Redistributions of Source Code must retain the above copyright licenses, */
+/* this list of conditions and the following disclaimers. */
+/* */
+/* - Redistributions in binary form must reproduce the above copyright */
+/* licenses, this list of conditions and the following disclaimers in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* 3. Disclaimers: */
+/* */
+/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
+/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
+/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
+/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
+/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
+/* information on specification licensing rights available through TCG */
+/* membership agreements. */
+/* */
+/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
+/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
+/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
+/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
+/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
+/* */
+/* - Without limitation, TCG and its members and licensors disclaim all */
+/* liability, including liability for infringement of any proprietary */
+/* rights, relating to use of information in this specification and to the */
+/* implementation of this specification, and TCG disclaims all liability for */
+/* cost of procurement of substitute goods or services, lost profits, loss */
+/* of use, loss of data or any incidental, consequential, direct, indirect, */
+/* or special damages, whether under contract, tort, warranty or otherwise, */
+/* arising in any way out of use or reliance upon this specification or any */
+/* information herein. */
+/* */
+/* (c) Copyright IBM Corp. and others, 2012-2015 */
+/* */
+/********************************************************************************/
+
+/* rev 119 */
+
+#ifndef POLICYRESTART_FP_H
+#define POLICYRESTART_FP_H
+
+typedef struct {
+ TPMI_SH_POLICY sessionHandle;
+} PolicyRestart_In;
+
+#define RC_PolicyRestart_sessionHandle (TPM_RC_H + TPM_RC_1)
+
+TPM_RC
+TPM2_PolicyRestart(
+ PolicyRestart_In *in // IN: input parameter list
+ );
+
+
+#endif
diff --git a/src/tpm2/PolicySecret_fp.h b/src/tpm2/PolicySecret_fp.h
new file mode 100644
index 0000000..ff89a6c
--- /dev/null
+++ b/src/tpm2/PolicySecret_fp.h
@@ -0,0 +1,95 @@
+/********************************************************************************/
+/* */
+/* */
+/* Written by Ken Goldman */
+/* IBM Thomas J. Watson Research Center */
+/* $Id: PolicySecret_fp.h 1521 2019-11-15 21:00:47Z kgoldman $ */
+/* */
+/* Licenses and Notices */
+/* */
+/* 1. Copyright Licenses: */
+/* */
+/* - Trusted Computing Group (TCG) grants to the user of the source code in */
+/* this specification (the "Source Code") a worldwide, irrevocable, */
+/* nonexclusive, royalty free, copyright license to reproduce, create */
+/* derivative works, distribute, display and perform the Source Code and */
+/* derivative works thereof, and to grant others the rights granted herein. */
+/* */
+/* - The TCG grants to the user of the other parts of the specification */
+/* (other than the Source Code) the rights to reproduce, distribute, */
+/* display, and perform the specification solely for the purpose of */
+/* developing products based on such documents. */
+/* */
+/* 2. Source Code Distribution Conditions: */
+/* */
+/* - Redistributions of Source Code must retain the above copyright licenses, */
+/* this list of conditions and the following disclaimers. */
+/* */
+/* - Redistributions in binary form must reproduce the above copyright */
+/* licenses, this list of conditions and the following disclaimers in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* 3. Disclaimers: */
+/* */
+/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
+/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
+/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
+/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
+/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
+/* information on specification licensing rights available through TCG */
+/* membership agreements. */
+/* */
+/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
+/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
+/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
+/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
+/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
+/* */
+/* - Without limitation, TCG and its members and licensors disclaim all */
+/* liability, including liability for infringement of any proprietary */
+/* rights, relating to use of information in this specification and to the */
+/* implementation of this specification, and TCG disclaims all liability for */
+/* cost of procurement of substitute goods or services, lost profits, loss */
+/* of use, loss of data or any incidental, consequential, direct, indirect, */
+/* or special damages, whether under contract, tort, warranty or otherwise, */
+/* arising in any way out of use or reliance upon this specification or any */
+/* information herein. */
+/* */
+/* (c) Copyright IBM Corp. and others, 2012-2015 */
+/* */
+/********************************************************************************/
+
+/* rev 124 */
+
+#ifndef POLICYSECRET_FP_H
+#define POLICYSECRET_FP_H
+
+typedef struct {
+ TPMI_DH_ENTITY authHandle;
+ TPMI_SH_POLICY policySession;
+ TPM2B_NONCE nonceTPM;
+ TPM2B_DIGEST cpHashA;
+ TPM2B_NONCE policyRef;
+ INT32 expiration;
+} PolicySecret_In;
+
+#define RC_PolicySecret_authHandle (TPM_RC_H + TPM_RC_1)
+#define RC_PolicySecret_policySession (TPM_RC_H + TPM_RC_2)
+#define RC_PolicySecret_nonceTPM (TPM_RC_P + TPM_RC_1)
+#define RC_PolicySecret_cpHashA (TPM_RC_P + TPM_RC_2)
+#define RC_PolicySecret_policyRef (TPM_RC_P + TPM_RC_3)
+#define RC_PolicySecret_expiration (TPM_RC_P + TPM_RC_4)
+
+typedef struct {
+ TPM2B_TIMEOUT timeout;
+ TPMT_TK_AUTH policyTicket;
+} PolicySecret_Out;
+
+TPM_RC
+TPM2_PolicySecret(
+ PolicySecret_In *in, // IN: input parameter list
+ PolicySecret_Out *out // OUT: output parameter list
+ );
+
+
+#endif
diff --git a/src/tpm2/PolicySigned_fp.h b/src/tpm2/PolicySigned_fp.h
new file mode 100644
index 0000000..3c75b42
--- /dev/null
+++ b/src/tpm2/PolicySigned_fp.h
@@ -0,0 +1,96 @@
+/********************************************************************************/
+/* */
+/* */
+/* Written by Ken Goldman */
+/* IBM Thomas J. Watson Research Center */
+/* $Id: PolicySigned_fp.h 1521 2019-11-15 21:00:47Z kgoldman $ */
+/* */
+/* Licenses and Notices */
+/* */
+/* 1. Copyright Licenses: */
+/* */
+/* - Trusted Computing Group (TCG) grants to the user of the source code in */
+/* this specification (the "Source Code") a worldwide, irrevocable, */
+/* nonexclusive, royalty free, copyright license to reproduce, create */
+/* derivative works, distribute, display and perform the Source Code and */
+/* derivative works thereof, and to grant others the rights granted herein. */
+/* */
+/* - The TCG grants to the user of the other parts of the specification */
+/* (other than the Source Code) the rights to reproduce, distribute, */
+/* display, and perform the specification solely for the purpose of */
+/* developing products based on such documents. */
+/* */
+/* 2. Source Code Distribution Conditions: */
+/* */
+/* - Redistributions of Source Code must retain the above copyright licenses, */
+/* this list of conditions and the following disclaimers. */
+/* */
+/* - Redistributions in binary form must reproduce the above copyright */
+/* licenses, this list of conditions and the following disclaimers in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* 3. Disclaimers: */
+/* */
+/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
+/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
+/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
+/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
+/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
+/* information on specification licensing rights available through TCG */
+/* membership agreements. */
+/* */
+/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
+/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
+/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
+/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
+/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
+/* */
+/* - Without limitation, TCG and its members and licensors disclaim all */
+/* liability, including liability for infringement of any proprietary */
+/* rights, relating to use of information in this specification and to the */
+/* implementation of this specification, and TCG disclaims all liability for */
+/* cost of procurement of substitute goods or services, lost profits, loss */
+/* of use, loss of data or any incidental, consequential, direct, indirect, */
+/* or special damages, whether under contract, tort, warranty or otherwise, */
+/* arising in any way out of use or reliance upon this specification or any */
+/* information herein. */
+/* */
+/* (c) Copyright IBM Corp. and others, 2012-2015 */
+/* */
+/********************************************************************************/
+
+/* rev 119 */
+
+#ifndef POLICYSIGNED_FP_H
+#define POLICYSIGNED_FP_H
+
+typedef struct {
+ TPMI_DH_OBJECT authObject;
+ TPMI_SH_POLICY policySession;
+ TPM2B_NONCE nonceTPM;
+ TPM2B_DIGEST cpHashA;
+ TPM2B_NONCE policyRef;
+ INT32 expiration;
+ TPMT_SIGNATURE auth;
+} PolicySigned_In;
+
+#define RC_PolicySigned_authObject (TPM_RC_H + TPM_RC_1)
+#define RC_PolicySigned_policySession (TPM_RC_H + TPM_RC_2)
+#define RC_PolicySigned_nonceTPM (TPM_RC_P + TPM_RC_1)
+#define RC_PolicySigned_cpHashA (TPM_RC_P + TPM_RC_2)
+#define RC_PolicySigned_policyRef (TPM_RC_P + TPM_RC_3)
+#define RC_PolicySigned_expiration (TPM_RC_P + TPM_RC_4)
+#define RC_PolicySigned_auth (TPM_RC_P + TPM_RC_5)
+
+typedef struct {
+ TPM2B_TIMEOUT timeout;
+ TPMT_TK_AUTH policyTicket;
+} PolicySigned_Out;
+
+TPM_RC
+TPM2_PolicySigned(
+ PolicySigned_In *in, // IN: input parameter list
+ PolicySigned_Out *out // OUT: output parameter list
+ );
+
+#endif
diff --git a/src/tpm2/PolicyTemplate_fp.h b/src/tpm2/PolicyTemplate_fp.h
new file mode 100644
index 0000000..d56825b
--- /dev/null
+++ b/src/tpm2/PolicyTemplate_fp.h
@@ -0,0 +1,81 @@
+/********************************************************************************/
+/* */
+/* */
+/* Written by Ken Goldman */
+/* IBM Thomas J. Watson Research Center */
+/* $Id: PolicyTemplate_fp.h 809 2016-11-16 18:31:54Z kgoldman $ */
+/* */
+/* Licenses and Notices */
+/* */
+/* 1. Copyright Licenses: */
+/* */
+/* - Trusted Computing Group (TCG) grants to the user of the source code in */
+/* this specification (the "Source Code") a worldwide, irrevocable, */
+/* nonexclusive, royalty free, copyright license to reproduce, create */
+/* derivative works, distribute, display and perform the Source Code and */
+/* derivative works thereof, and to grant others the rights granted herein. */
+/* */
+/* - The TCG grants to the user of the other parts of the specification */
+/* (other than the Source Code) the rights to reproduce, distribute, */
+/* display, and perform the specification solely for the purpose of */
+/* developing products based on such documents. */
+/* */
+/* 2. Source Code Distribution Conditions: */
+/* */
+/* - Redistributions of Source Code must retain the above copyright licenses, */
+/* this list of conditions and the following disclaimers. */
+/* */
+/* - Redistributions in binary form must reproduce the above copyright */
+/* licenses, this list of conditions and the following disclaimers in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* 3. Disclaimers: */
+/* */
+/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
+/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
+/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
+/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
+/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
+/* information on specification licensing rights available through TCG */
+/* membership agreements. */
+/* */
+/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
+/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
+/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
+/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
+/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
+/* */
+/* - Without limitation, TCG and its members and licensors disclaim all */
+/* liability, including liability for infringement of any proprietary */
+/* rights, relating to use of information in this specification and to the */
+/* implementation of this specification, and TCG disclaims all liability for */
+/* cost of procurement of substitute goods or services, lost profits, loss */
+/* of use, loss of data or any incidental, consequential, direct, indirect, */
+/* or special damages, whether under contract, tort, warranty or otherwise, */
+/* arising in any way out of use or reliance upon this specification or any */
+/* information herein. */
+/* */
+/* (c) Copyright IBM Corp. and others, 2012-2015, 2016 */
+/* */
+/********************************************************************************/
+
+/* rev 119 */
+
+#ifndef POLICYTEMPLATE_FP_H
+#define POLICYTEMPLATE_FP_H
+
+typedef struct {
+ TPMI_SH_POLICY policySession;
+ TPM2B_DIGEST templateHash;
+} PolicyTemplate_In;
+
+#define RC_PolicyTemplate_policySession (TPM_RC_H + TPM_RC_1)
+#define RC_PolicyTemplate_templateHash (TPM_RC_P + TPM_RC_1)
+
+TPM_RC
+TPM2_PolicyTemplate(
+ PolicyTemplate_In *in // IN: input parameter list
+ );
+
+
+#endif
diff --git a/src/tpm2/PolicyTicket_fp.h b/src/tpm2/PolicyTicket_fp.h
new file mode 100644
index 0000000..8d78c87
--- /dev/null
+++ b/src/tpm2/PolicyTicket_fp.h
@@ -0,0 +1,89 @@
+/********************************************************************************/
+/* */
+/* */
+/* Written by Ken Goldman */
+/* IBM Thomas J. Watson Research Center */
+/* $Id: PolicyTicket_fp.h 1521 2019-11-15 21:00:47Z kgoldman $ */
+/* */
+/* Licenses and Notices */
+/* */
+/* 1. Copyright Licenses: */
+/* */
+/* - Trusted Computing Group (TCG) grants to the user of the source code in */
+/* this specification (the "Source Code") a worldwide, irrevocable, */
+/* nonexclusive, royalty free, copyright license to reproduce, create */
+/* derivative works, distribute, display and perform the Source Code and */
+/* derivative works thereof, and to grant others the rights granted herein. */
+/* */
+/* - The TCG grants to the user of the other parts of the specification */
+/* (other than the Source Code) the rights to reproduce, distribute, */
+/* display, and perform the specification solely for the purpose of */
+/* developing products based on such documents. */
+/* */
+/* 2. Source Code Distribution Conditions: */
+/* */
+/* - Redistributions of Source Code must retain the above copyright licenses, */
+/* this list of conditions and the following disclaimers. */
+/* */
+/* - Redistributions in binary form must reproduce the above copyright */
+/* licenses, this list of conditions and the following disclaimers in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* 3. Disclaimers: */
+/* */
+/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
+/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
+/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
+/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
+/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
+/* information on specification licensing rights available through TCG */
+/* membership agreements. */
+/* */
+/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
+/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
+/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
+/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
+/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
+/* */
+/* - Without limitation, TCG and its members and licensors disclaim all */
+/* liability, including liability for infringement of any proprietary */
+/* rights, relating to use of information in this specification and to the */
+/* implementation of this specification, and TCG disclaims all liability for */
+/* cost of procurement of substitute goods or services, lost profits, loss */
+/* of use, loss of data or any incidental, consequential, direct, indirect, */
+/* or special damages, whether under contract, tort, warranty or otherwise, */
+/* arising in any way out of use or reliance upon this specification or any */
+/* information herein. */
+/* */
+/* (c) Copyright IBM Corp. and others, 2012-2015 */
+/* */
+/********************************************************************************/
+
+/* rev 119 */
+
+#ifndef POLICYTICKET_FP_H
+#define POLICYTICKET_FP_H
+
+typedef struct {
+ TPMI_SH_POLICY policySession;
+ TPM2B_TIMEOUT timeout;
+ TPM2B_DIGEST cpHashA;
+ TPM2B_NONCE policyRef;
+ TPM2B_NAME authName;
+ TPMT_TK_AUTH ticket;
+} PolicyTicket_In;
+
+#define RC_PolicyTicket_policySession (TPM_RC_H + TPM_RC_1)
+#define RC_PolicyTicket_timeout (TPM_RC_P + TPM_RC_1)
+#define RC_PolicyTicket_cpHashA (TPM_RC_P + TPM_RC_2)
+#define RC_PolicyTicket_policyRef (TPM_RC_P + TPM_RC_3)
+#define RC_PolicyTicket_authName (TPM_RC_P + TPM_RC_4)
+#define RC_PolicyTicket_ticket (TPM_RC_P + TPM_RC_5)
+
+TPM_RC
+TPM2_PolicyTicket(
+ PolicyTicket_In *in // IN: input parameter list
+ );
+
+
+#endif
diff --git a/src/tpm2/Policy_spt.c b/src/tpm2/Policy_spt.c
new file mode 100644
index 0000000..4c2de20
--- /dev/null
+++ b/src/tpm2/Policy_spt.c
@@ -0,0 +1,300 @@
+/********************************************************************************/
+/* */
+/* Policy Command Support */
+/* Written by Ken Goldman */
+/* IBM Thomas J. Watson Research Center */
+/* $Id: Policy_spt.c 1594 2020-03-26 22:15:48Z kgoldman $ */
+/* */
+/* Licenses and Notices */
+/* */
+/* 1. Copyright Licenses: */
+/* */
+/* - Trusted Computing Group (TCG) grants to the user of the source code in */
+/* this specification (the "Source Code") a worldwide, irrevocable, */
+/* nonexclusive, royalty free, copyright license to reproduce, create */
+/* derivative works, distribute, display and perform the Source Code and */
+/* derivative works thereof, and to grant others the rights granted herein. */
+/* */
+/* - The TCG grants to the user of the other parts of the specification */
+/* (other than the Source Code) the rights to reproduce, distribute, */
+/* display, and perform the specification solely for the purpose of */
+/* developing products based on such documents. */
+/* */
+/* 2. Source Code Distribution Conditions: */
+/* */
+/* - Redistributions of Source Code must retain the above copyright licenses, */
+/* this list of conditions and the following disclaimers. */
+/* */
+/* - Redistributions in binary form must reproduce the above copyright */
+/* licenses, this list of conditions and the following disclaimers in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* 3. Disclaimers: */
+/* */
+/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
+/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
+/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
+/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
+/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
+/* information on specification licensing rights available through TCG */
+/* membership agreements. */
+/* */
+/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
+/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
+/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
+/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
+/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
+/* */
+/* - Without limitation, TCG and its members and licensors disclaim all */
+/* liability, including liability for infringement of any proprietary */
+/* rights, relating to use of information in this specification and to the */
+/* implementation of this specification, and TCG disclaims all liability for */
+/* cost of procurement of substitute goods or services, lost profits, loss */
+/* of use, loss of data or any incidental, consequential, direct, indirect, */
+/* or special damages, whether under contract, tort, warranty or otherwise, */
+/* arising in any way out of use or reliance upon this specification or any */
+/* information herein. */
+/* */
+/* (c) Copyright IBM Corp. and others, 2016 - 2020 */
+/* */
+/********************************************************************************/
+
+/* 7.4 Policy Command Support (Policy_spt.c) */
+#include "Tpm.h"
+#include "Policy_spt_fp.h"
+#include "PolicySigned_fp.h"
+#include "PolicySecret_fp.h"
+#include "PolicyTicket_fp.h"
+/* 7.4.1 PolicyParameterChecks() */
+/* This function validates the common parameters of TPM2_PolicySiged() and TPM2_PolicySecret(). The
+ common parameters are nonceTPM, expiration, and cpHashA. */
+TPM_RC
+PolicyParameterChecks(
+ SESSION *session,
+ UINT64 authTimeout,
+ TPM2B_DIGEST *cpHashA,
+ TPM2B_NONCE *nonce,
+ TPM_RC blameNonce,
+ TPM_RC blameCpHash,
+ TPM_RC blameExpiration
+ )
+{
+ // Validate that input nonceTPM is correct if present
+ if(nonce != NULL && nonce->t.size != 0)
+ {
+ if(!MemoryEqual2B(&nonce->b, &session->nonceTPM.b))
+ return TPM_RCS_NONCE + blameNonce;
+ }
+ // If authTimeout is set (expiration != 0...
+ if(authTimeout != 0)
+ {
+ // Validate input expiration.
+ // Cannot compare time if clock stop advancing. A TPM_RC_NV_UNAVAILABLE
+ // or TPM_RC_NV_RATE error may be returned here.
+ RETURN_IF_NV_IS_NOT_AVAILABLE;
+ // if the time has already passed or the time epoch has changed then the
+ // time value is no longer good.
+ if((authTimeout < g_time)
+ || (session->epoch != g_timeEpoch))
+ return TPM_RCS_EXPIRED + blameExpiration;
+ }
+ // If the cpHash is present, then check it
+ if(cpHashA != NULL && cpHashA->t.size != 0)
+ {
+ // The cpHash input has to have the correct size
+ if(cpHashA->t.size != session->u2.policyDigest.t.size)
+ return TPM_RCS_SIZE + blameCpHash;
+ // If the cpHash has already been set, then this input value
+ // must match the current value.
+ if(session->u1.cpHash.b.size != 0
+ && !MemoryEqual2B(&cpHashA->b, &session->u1.cpHash.b))
+ return TPM_RC_CPHASH;
+ }
+ return TPM_RC_SUCCESS;
+}
+/* 7.4.2 PolicyContextUpdate() */
+/* Update policy hash Update the policyDigest in policy session by extending policyRef and
+ objectName to it. This will also update the cpHash if it is present. */
+void
+PolicyContextUpdate(
+ TPM_CC commandCode, // IN: command code
+ TPM2B_NAME *name, // IN: name of entity
+ TPM2B_NONCE *ref, // IN: the reference data
+ TPM2B_DIGEST *cpHash, // IN: the cpHash (optional)
+ UINT64 policyTimeout, // IN: the timeout value for the policy
+ SESSION *session // IN/OUT: policy session to be updated
+ )
+{
+ HASH_STATE hashState;
+ // Start hash
+ CryptHashStart(&hashState, session->authHashAlg);
+ // policyDigest size should always be the digest size of session hash algorithm.
+ pAssert(session->u2.policyDigest.t.size
+ == CryptHashGetDigestSize(session->authHashAlg));
+ // add old digest
+ CryptDigestUpdate2B(&hashState, &session->u2.policyDigest.b);
+ // add commandCode
+ CryptDigestUpdateInt(&hashState, sizeof(commandCode), commandCode);
+ // add name if applicable
+ if(name != NULL)
+ CryptDigestUpdate2B(&hashState, &name->b);
+ // Complete the digest and get the results
+ CryptHashEnd2B(&hashState, &session->u2.policyDigest.b);
+ // If the policy reference is not null, do a second update to the digest.
+ if(ref != NULL)
+ {
+ // Start second hash computation
+ CryptHashStart(&hashState, session->authHashAlg);
+ // add policyDigest
+ CryptDigestUpdate2B(&hashState, &session->u2.policyDigest.b);
+ // add policyRef
+ CryptDigestUpdate2B(&hashState, &ref->b);
+ // Complete second digest
+ CryptHashEnd2B(&hashState, &session->u2.policyDigest.b);
+ }
+ // Deal with the cpHash. If the cpHash value is present
+ // then it would have already been checked to make sure that
+ // it is compatible with the current value so all we need
+ // to do here is copy it and set the isCpHashDefined attribute
+ if(cpHash != NULL && cpHash->t.size != 0)
+ {
+ session->u1.cpHash = *cpHash;
+ session->attributes.isCpHashDefined = SET;
+ }
+ // update the timeout if it is specified
+ if(policyTimeout != 0)
+ {
+ // If the timeout has not been set, then set it to the new value
+ // than the current timeout then set it to the new value
+ if(session->timeout == 0 || session->timeout > policyTimeout)
+ session->timeout = policyTimeout;
+ }
+ return;
+}
+/* 7.4.2.1 ComputeAuthTimeout() */
+/* This function is used to determine what the authorization timeout value for the session should
+ be. */
+UINT64
+ComputeAuthTimeout(
+ SESSION *session, // IN: the session containing the time
+ // values
+ INT32 expiration, // IN: either the number of seconds from
+ // the start of the session or the
+ // time in g_timer;
+ TPM2B_NONCE *nonce // IN: indicator of the time base
+ )
+{
+ UINT64 policyTime;
+ // If no expiration, policy time is 0
+ if(expiration == 0)
+ policyTime = 0;
+ else
+ {
+ if(expiration < 0) {
+ if (expiration == (INT32)0x80000000) /* libtpms changed begin; ubsan */
+ expiration++; /* libtpms changed end */
+ expiration = -expiration;
+ }
+ if(nonce->t.size == 0)
+ // The input time is absolute Time (not Clock), but it is expressed
+ // in seconds. To make sure that we don't time out too early, take the
+ // current value of milliseconds in g_time and add that to the input
+ // seconds value.
+ policyTime = (((UINT64)expiration) * 1000) + g_time % 1000;
+ else
+ // The policy timeout is the absolute value of the expiration in seconds
+ // added to the start time of the policy.
+ policyTime = session->startTime + (((UINT64)expiration) * 1000);
+ }
+ return policyTime;
+}
+/* 7.4.2.2 PolicyDigestClear() */
+/* Function to reset the policyDigest of a session */
+void
+PolicyDigestClear(
+ SESSION *session
+ )
+{
+ session->u2.policyDigest.t.size = CryptHashGetDigestSize(session->authHashAlg);
+ MemorySet(session->u2.policyDigest.t.buffer, 0,
+ session->u2.policyDigest.t.size);
+}
+
+/* 7.4.2.5 PolicySptCheckCondition() */
+/* Checks to see if the condition in the policy is satisfied. */
+
+BOOL
+PolicySptCheckCondition(
+ TPM_EO operation,
+ BYTE *opA,
+ BYTE *opB,
+ UINT16 size
+ )
+{
+ // Arithmetic Comparison
+ switch(operation)
+ {
+ case TPM_EO_EQ:
+ // compare A = B
+ return (UnsignedCompareB(size, opA, size, opB) == 0);
+ break;
+ case TPM_EO_NEQ:
+ // compare A != B
+ return (UnsignedCompareB(size, opA, size, opB) != 0);
+ break;
+ case TPM_EO_SIGNED_GT:
+ // compare A > B signed
+ return (SignedCompareB(size, opA, size, opB) > 0);
+ break;
+ case TPM_EO_UNSIGNED_GT:
+ // compare A > B unsigned
+ return (UnsignedCompareB(size, opA, size, opB) > 0);
+ break;
+ case TPM_EO_SIGNED_LT:
+ // compare A < B signed
+ return (SignedCompareB(size, opA, size, opB) < 0);
+ break;
+ case TPM_EO_UNSIGNED_LT:
+ // compare A < B unsigned
+ return (UnsignedCompareB(size, opA, size, opB) < 0);
+ break;
+ case TPM_EO_SIGNED_GE:
+ // compare A >= B signed
+ return (SignedCompareB(size, opA, size, opB) >= 0);
+ break;
+ case TPM_EO_UNSIGNED_GE:
+ // compare A >= B unsigned
+ return (UnsignedCompareB(size, opA, size, opB) >= 0);
+ break;
+ case TPM_EO_SIGNED_LE:
+ // compare A <= B signed
+ return (SignedCompareB(size, opA, size, opB) <= 0);
+ break;
+ case TPM_EO_UNSIGNED_LE:
+ // compare A <= B unsigned
+ return (UnsignedCompareB(size, opA, size, opB) <= 0);
+ break;
+ case TPM_EO_BITSET:
+ // All bits SET in B are SET in A. ((A&B)=B)
+ {
+ UINT32 i;
+ for(i = 0; i < size; i++)
+ if((opA[i] & opB[i]) != opB[i])
+ return FALSE;
+ }
+ break;
+ case TPM_EO_BITCLEAR:
+ // All bits SET in B are CLEAR in A. ((A&B)=0)
+ {
+ UINT32 i;
+ for(i = 0; i < size; i++)
+ if((opA[i] & opB[i]) != 0)
+ return FALSE;
+ }
+ break;
+ default:
+ FAIL(FATAL_ERROR_INTERNAL);
+ break;
+ }
+ return TRUE;
+}
diff --git a/src/tpm2/Policy_spt_fp.h b/src/tpm2/Policy_spt_fp.h
new file mode 100644
index 0000000..86bd43e
--- /dev/null
+++ b/src/tpm2/Policy_spt_fp.h
@@ -0,0 +1,110 @@
+/********************************************************************************/
+/* */
+/* */
+/* Written by Ken Goldman */
+/* IBM Thomas J. Watson Research Center */
+/* $Id: Policy_spt_fp.h 1490 2019-07-26 21:13:22Z kgoldman $ */
+/* */
+/* Licenses and Notices */
+/* */
+/* 1. Copyright Licenses: */
+/* */
+/* - Trusted Computing Group (TCG) grants to the user of the source code in */
+/* this specification (the "Source Code") a worldwide, irrevocable, */
+/* nonexclusive, royalty free, copyright license to reproduce, create */
+/* derivative works, distribute, display and perform the Source Code and */
+/* derivative works thereof, and to grant others the rights granted herein. */
+/* */
+/* - The TCG grants to the user of the other parts of the specification */
+/* (other than the Source Code) the rights to reproduce, distribute, */
+/* display, and perform the specification solely for the purpose of */
+/* developing products based on such documents. */
+/* */
+/* 2. Source Code Distribution Conditions: */
+/* */
+/* - Redistributions of Source Code must retain the above copyright licenses, */
+/* this list of conditions and the following disclaimers. */
+/* */
+/* - Redistributions in binary form must reproduce the above copyright */
+/* licenses, this list of conditions and the following disclaimers in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* 3. Disclaimers: */
+/* */
+/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
+/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
+/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
+/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
+/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
+/* information on specification licensing rights available through TCG */
+/* membership agreements. */
+/* */
+/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
+/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
+/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
+/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
+/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
+/* */
+/* - Without limitation, TCG and its members and licensors disclaim all */
+/* liability, including liability for infringement of any proprietary */
+/* rights, relating to use of information in this specification and to the */
+/* implementation of this specification, and TCG disclaims all liability for */
+/* cost of procurement of substitute goods or services, lost profits, loss */
+/* of use, loss of data or any incidental, consequential, direct, indirect, */
+/* or special damages, whether under contract, tort, warranty or otherwise, */
+/* arising in any way out of use or reliance upon this specification or any */
+/* information herein. */
+/* */
+/* (c) Copyright IBM Corp. and others, 2016 */
+/* */
+/********************************************************************************/
+
+#ifndef POLICY_SPT_FP_H
+#define POLICY_SPT_FP_H
+
+TPM_RC
+PolicyParameterChecks(
+ SESSION *session,
+ UINT64 authTimeout,
+ TPM2B_DIGEST *cpHashA,
+ TPM2B_NONCE *nonce,
+ TPM_RC blameNonce,
+ TPM_RC blameCpHash,
+ TPM_RC blameExpiration
+ );
+void
+PolicyContextUpdate(
+ TPM_CC commandCode, // IN: command code
+ TPM2B_NAME *name, // IN: name of entity
+ TPM2B_NONCE *ref, // IN: the reference data
+ TPM2B_DIGEST *cpHash, // IN: the cpHash (optional)
+ UINT64 policyTimeout, // IN: the timeout value for the policy
+ SESSION *session // IN/OUT: policy session to be updated
+ );
+UINT64
+ComputeAuthTimeout(
+ SESSION *session, // IN: the session containing the time
+ // values
+ INT32 expiration, // IN: either the number of seconds from
+ // the start of the session or the
+ // time in g_timer;
+ TPM2B_NONCE *nonce // IN: indicator of the time base
+ );
+void
+PolicyDigestClear(
+ SESSION *session
+ );
+BOOL
+PolicySptCheckCondition(
+ TPM_EO operation,
+ BYTE *opA,
+ BYTE *opB,
+ UINT16 size
+ );
+
+
+
+
+
+
+#endif
diff --git a/src/tpm2/Power.c b/src/tpm2/Power.c
new file mode 100644
index 0000000..30363b5
--- /dev/null
+++ b/src/tpm2/Power.c
@@ -0,0 +1,109 @@
+/********************************************************************************/
+/* */
+/* Simulated Power State Transitions of the TPM */
+/* Written by Ken Goldman */
+/* IBM Thomas J. Watson Research Center */
+/* $Id: Power.c 1490 2019-07-26 21:13:22Z kgoldman $ */
+/* */
+/* Licenses and Notices */
+/* */
+/* 1. Copyright Licenses: */
+/* */
+/* - Trusted Computing Group (TCG) grants to the user of the source code in */
+/* this specification (the "Source Code") a worldwide, irrevocable, */
+/* nonexclusive, royalty free, copyright license to reproduce, create */
+/* derivative works, distribute, display and perform the Source Code and */
+/* derivative works thereof, and to grant others the rights granted herein. */
+/* */
+/* - The TCG grants to the user of the other parts of the specification */
+/* (other than the Source Code) the rights to reproduce, distribute, */
+/* display, and perform the specification solely for the purpose of */
+/* developing products based on such documents. */
+/* */
+/* 2. Source Code Distribution Conditions: */
+/* */
+/* - Redistributions of Source Code must retain the above copyright licenses, */
+/* this list of conditions and the following disclaimers. */
+/* */
+/* - Redistributions in binary form must reproduce the above copyright */
+/* licenses, this list of conditions and the following disclaimers in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* 3. Disclaimers: */
+/* */
+/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
+/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
+/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
+/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
+/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
+/* information on specification licensing rights available through TCG */
+/* membership agreements. */
+/* */
+/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
+/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
+/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
+/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
+/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
+/* */
+/* - Without limitation, TCG and its members and licensors disclaim all */
+/* liability, including liability for infringement of any proprietary */
+/* rights, relating to use of information in this specification and to the */
+/* implementation of this specification, and TCG disclaims all liability for */
+/* cost of procurement of substitute goods or services, lost profits, loss */
+/* of use, loss of data or any incidental, consequential, direct, indirect, */
+/* or special damages, whether under contract, tort, warranty or otherwise, */
+/* arising in any way out of use or reliance upon this specification or any */
+/* information herein. */
+/* */
+/* (c) Copyright IBM Corp. and others, 2016 - 2019 */
+/* */
+/********************************************************************************/
+
+/* 9.13 Power.c */
+/* 9.13.1 Description */
+/* This file contains functions that receive the simulated power state transitions of the TPM. */
+/* 9.13.2 Includes and Data Definitions */
+#define POWER_C
+#include "Tpm.h"
+/* 9.13.3 Functions */
+/* 9.13.3.1 TPMInit() */
+/* This function is used to process a power on event. */
+
+void
+TPMInit(
+ void
+ )
+{
+ // Set state as not initialized. This means that Startup is required
+ g_initialized = FALSE;
+ return;
+}
+
+/* 9.13.3.2 TPMRegisterStartup() */
+/* This function registers the fact that the TPM has been initialized (a TPM2_Startup() has
+ completed successfully). */
+
+BOOL
+TPMRegisterStartup(
+ void
+ )
+{
+ g_initialized = TRUE;
+ return TRUE;
+}
+
+/* 9.13.3.3 TPMIsStarted() */
+/* Indicates if the TPM has been initialized (a TPM2_Startup() has completed successfully after a
+ _TPM_Init()). */
+/* Return Values Meaning */
+/* TRUE TPM has been initialized */
+/* FALSE TPM has not been initialized */
+
+BOOL
+TPMIsStarted(
+ void
+ )
+{
+ return g_initialized;
+}
+
diff --git a/src/tpm2/PowerPlat.c b/src/tpm2/PowerPlat.c
new file mode 100644
index 0000000..9077a33
--- /dev/null
+++ b/src/tpm2/PowerPlat.c
@@ -0,0 +1,128 @@
+/********************************************************************************/
+/* */
+/* Platform Power Support */
+/* Written by Ken Goldman */
+/* IBM Thomas J. Watson Research Center */
+/* $Id: PowerPlat.c 1529 2019-11-21 23:29:01Z kgoldman $ */
+/* */
+/* Licenses and Notices */
+/* */
+/* 1. Copyright Licenses: */
+/* */
+/* - Trusted Computing Group (TCG) grants to the user of the source code in */
+/* this specification (the "Source Code") a worldwide, irrevocable, */
+/* nonexclusive, royalty free, copyright license to reproduce, create */
+/* derivative works, distribute, display and perform the Source Code and */
+/* derivative works thereof, and to grant others the rights granted herein. */
+/* */
+/* - The TCG grants to the user of the other parts of the specification */
+/* (other than the Source Code) the rights to reproduce, distribute, */
+/* display, and perform the specification solely for the purpose of */
+/* developing products based on such documents. */
+/* */
+/* 2. Source Code Distribution Conditions: */
+/* */
+/* - Redistributions of Source Code must retain the above copyright licenses, */
+/* this list of conditions and the following disclaimers. */
+/* */
+/* - Redistributions in binary form must reproduce the above copyright */
+/* licenses, this list of conditions and the following disclaimers in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* 3. Disclaimers: */
+/* */
+/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
+/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
+/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
+/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
+/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
+/* information on specification licensing rights available through TCG */
+/* membership agreements. */
+/* */
+/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
+/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
+/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
+/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
+/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
+/* */
+/* - Without limitation, TCG and its members and licensors disclaim all */
+/* liability, including liability for infringement of any proprietary */
+/* rights, relating to use of information in this specification and to the */
+/* implementation of this specification, and TCG disclaims all liability for */
+/* cost of procurement of substitute goods or services, lost profits, loss */
+/* of use, loss of data or any incidental, consequential, direct, indirect, */
+/* or special damages, whether under contract, tort, warranty or otherwise, */
+/* arising in any way out of use or reliance upon this specification or any */
+/* information herein. */
+/* */
+/* (c) Copyright IBM Corp. and others, 2016 - 2019 */
+/* */
+/********************************************************************************/
+
+/* C.7 PowerPlat.c */
+/* C.7.1. Includes and Function Prototypes */
+#include "Platform.h"
+#include "PlatformACT_fp.h" /* added kgold */
+#include "_TPM_Init_fp.h"
+/* C.7.2. Functions */
+/* C.7.2.1. _plat__Signal_PowerOn() */
+/* Signal platform power on */
+LIB_EXPORT int
+_plat__Signal_PowerOn(
+ void
+ )
+{
+ // Reset the timer
+ _plat__TimerReset();
+ // Need to indicate that we lost power
+ s_powerLost = TRUE;
+ return 0;
+}
+/* C.7.2.2. _plat__WasPowerLost() */
+/* Test whether power was lost before a _TPM_Init(). */
+/* This function will clear the hardware indication of power loss before return. This means that
+ there can only be one spot in the TPM code where this value gets read. This method is used here
+ as it is the most difficult to manage in the TPM code and, if the hardware actually works this
+ way, it is hard to make it look like anything else. So, the burden is placed on the TPM code
+ rather than the platform code */
+/* Return Values Meaning */
+/* TRUE(1) power was lost */
+/* FALSE(0) power was not lost */
+LIB_EXPORT int
+_plat__WasPowerLost(
+ void
+ )
+{
+ int retVal = s_powerLost;
+ s_powerLost = FALSE;
+ return retVal;
+}
+/* C.7.2.3. _plat_Signal_Reset() */
+/* This a TPM reset without a power loss. */
+LIB_EXPORT int
+_plat__Signal_Reset(
+ void
+ )
+{
+ // Initialize locality
+ s_locality = 0;
+ // Command cancel
+ s_isCanceled = FALSE;
+ _TPM_Init();
+ // if we are doing reset but did not have a power failure, then we should
+ // not need to reload NV ...
+ return 0;
+}
+/* C.7.2.4. _plat__Signal_PowerOff() */
+/* Signal platform power off */
+LIB_EXPORT void
+_plat__Signal_PowerOff(
+ void
+ )
+{
+ // Prepare NV memory for power off
+ _plat__NVDisable(0);
+ // Disable tick ACT tick processing
+ _plat__ACT_EnableTicks(FALSE);
+ return;
+}
diff --git a/src/tpm2/Power_fp.h b/src/tpm2/Power_fp.h
new file mode 100644
index 0000000..7c99543
--- /dev/null
+++ b/src/tpm2/Power_fp.h
@@ -0,0 +1,79 @@
+/********************************************************************************/
+/* */
+/* Functions That Receive the Simulated Power State Transitions of the TPM */
+/* Written by Ken Goldman */
+/* IBM Thomas J. Watson Research Center */
+/* $Id: Power_fp.h 1490 2019-07-26 21:13:22Z kgoldman $ */
+/* */
+/* Licenses and Notices */
+/* */
+/* 1. Copyright Licenses: */
+/* */
+/* - Trusted Computing Group (TCG) grants to the user of the source code in */
+/* this specification (the "Source Code") a worldwide, irrevocable, */
+/* nonexclusive, royalty free, copyright license to reproduce, create */
+/* derivative works, distribute, display and perform the Source Code and */
+/* derivative works thereof, and to grant others the rights granted herein. */
+/* */
+/* - The TCG grants to the user of the other parts of the specification */
+/* (other than the Source Code) the rights to reproduce, distribute, */
+/* display, and perform the specification solely for the purpose of */
+/* developing products based on such documents. */
+/* */
+/* 2. Source Code Distribution Conditions: */
+/* */
+/* - Redistributions of Source Code must retain the above copyright licenses, */
+/* this list of conditions and the following disclaimers. */
+/* */
+/* - Redistributions in binary form must reproduce the above copyright */
+/* licenses, this list of conditions and the following disclaimers in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* 3. Disclaimers: */
+/* */
+/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
+/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
+/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
+/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
+/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
+/* information on specification licensing rights available through TCG */
+/* membership agreements. */
+/* */
+/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
+/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
+/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
+/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
+/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
+/* */
+/* - Without limitation, TCG and its members and licensors disclaim all */
+/* liability, including liability for infringement of any proprietary */
+/* rights, relating to use of information in this specification and to the */
+/* implementation of this specification, and TCG disclaims all liability for */
+/* cost of procurement of substitute goods or services, lost profits, loss */
+/* of use, loss of data or any incidental, consequential, direct, indirect, */
+/* or special damages, whether under contract, tort, warranty or otherwise, */
+/* arising in any way out of use or reliance upon this specification or any */
+/* information herein. */
+/* */
+/* (c) Copyright IBM Corp. and others, 2016 - 2019 */
+/* */
+/********************************************************************************/
+
+#ifndef POWER_FP_H
+#define POWER_FP_H
+
+void
+TPMInit(
+ void
+ );
+BOOL
+TPMRegisterStartup(
+ void
+ );
+BOOL
+TPMIsStarted(
+ void
+ );
+
+
+#endif
diff --git a/src/tpm2/PrimeData.c b/src/tpm2/PrimeData.c
new file mode 100644
index 0000000..9ef684d
--- /dev/null
+++ b/src/tpm2/PrimeData.c
@@ -0,0 +1,441 @@
+/********************************************************************************/
+/* */
+/* Product of all of the Primes up to 1000 */
+/* Written by Ken Goldman */
+/* IBM Thomas J. Watson Research Center */
+/* $Id: PrimeData.c 1311 2018-08-23 21:39:29Z kgoldman $ */
+/* */
+/* Licenses and Notices */
+/* */
+/* 1. Copyright Licenses: */
+/* */
+/* - Trusted Computing Group (TCG) grants to the user of the source code in */
+/* this specification (the "Source Code") a worldwide, irrevocable, */
+/* nonexclusive, royalty free, copyright license to reproduce, create */
+/* derivative works, distribute, display and perform the Source Code and */
+/* derivative works thereof, and to grant others the rights granted herein. */
+/* */
+/* - The TCG grants to the user of the other parts of the specification */
+/* (other than the Source Code) the rights to reproduce, distribute, */
+/* display, and perform the specification solely for the purpose of */
+/* developing products based on such documents. */
+/* */
+/* 2. Source Code Distribution Conditions: */
+/* */
+/* - Redistributions of Source Code must retain the above copyright licenses, */
+/* this list of conditions and the following disclaimers. */
+/* */
+/* - Redistributions in binary form must reproduce the above copyright */
+/* licenses, this list of conditions and the following disclaimers in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* 3. Disclaimers: */
+/* */
+/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
+/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
+/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
+/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
+/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
+/* information on specification licensing rights available through TCG */
+/* membership agreements. */
+/* */
+/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
+/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
+/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
+/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
+/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
+/* */
+/* - Without limitation, TCG and its members and licensors disclaim all */
+/* liability, including liability for infringement of any proprietary */
+/* rights, relating to use of information in this specification and to the */
+/* implementation of this specification, and TCG disclaims all liability for */
+/* cost of procurement of substitute goods or services, lost profits, loss */
+/* of use, loss of data or any incidental, consequential, direct, indirect, */
+/* or special damages, whether under contract, tort, warranty or otherwise, */
+/* arising in any way out of use or reliance upon this specification or any */
+/* information herein. */
+/* */
+/* (c) Copyright IBM Corp. and others, 2016 - 2018 */
+/* */
+/********************************************************************************/
+
+#include "Tpm.h"
+/* This table is the product of all of the primes up to 1000. Checking to see if there is a GCD
+ between a prime candidate and this number will eliminate many prime candidates from consideration
+ before running Miller-Rabin on the result. */
+const BN_STRUCT(43 * RADIX_BITS) s_CompositeOfSmallPrimes_ =
+{44, 44,
+ { 0x2ED42696, 0x2BBFA177, 0x4820594F, 0xF73F4841,
+ 0xBFAC313A, 0xCAC3EB81, 0xF6F26BF8, 0x7FAB5061,
+ 0x59746FB7, 0xF71377F6, 0x3B19855B, 0xCBD03132,
+ 0xBB92EF1B, 0x3AC3152C, 0xE87C8273, 0xC0AE0E69,
+ 0x74A9E295, 0x448CCE86, 0x63CA1907, 0x8A0BF944,
+ 0xF8CC3BE0, 0xC26F0AF5, 0xC501C02F, 0x6579441A,
+ 0xD1099CDA, 0x6BC76A00, 0xC81A3228, 0xBFB1AB25,
+ 0x70FA3841, 0x51B3D076, 0xCC2359ED, 0xD9EE0769,
+ 0x75E47AF0, 0xD45FF31E, 0x52CCE4F6, 0x04DBC891,
+ 0x96658ED2, 0x1753EFE5, 0x3AE4A5A6, 0x8FD4A97F,
+ 0x8B15E7EB, 0x0243C3E1, 0xE0F0C31D, 0x0000000B }
+};
+bigConst s_CompositeOfSmallPrimes = (const bigNum)&s_CompositeOfSmallPrimes_;
+/* This table contains a bit for each of the odd values between 1 and 2^16 + 1. This table allows
+ fast checking of the primes in that range. Don't change the size of this table unless you are
+ prepared to do redo IsPrimeInt(). */
+const uint32_t s_LastPrimeInTable = 65537;
+const uint32_t s_PrimeTableSize = 4097;
+const uint32_t s_PrimesInTable = 6542;
+const unsigned char s_PrimeTable[] = {
+ 0x6e, 0xcb, 0xb4, 0x64, 0x9a, 0x12, 0x6d, 0x81, 0x32, 0x4c, 0x4a, 0x86,
+ 0x0d, 0x82, 0x96, 0x21, 0xc9, 0x34, 0x04, 0x5a, 0x20, 0x61, 0x89, 0xa4,
+ 0x44, 0x11, 0x86, 0x29, 0xd1, 0x82, 0x28, 0x4a, 0x30, 0x40, 0x42, 0x32,
+ 0x21, 0x99, 0x34, 0x08, 0x4b, 0x06, 0x25, 0x42, 0x84, 0x48, 0x8a, 0x14,
+ 0x05, 0x42, 0x30, 0x6c, 0x08, 0xb4, 0x40, 0x0b, 0xa0, 0x08, 0x51, 0x12,
+ 0x28, 0x89, 0x04, 0x65, 0x98, 0x30, 0x4c, 0x80, 0x96, 0x44, 0x12, 0x80,
+ 0x21, 0x42, 0x12, 0x41, 0xc9, 0x04, 0x21, 0xc0, 0x32, 0x2d, 0x98, 0x00,
+ 0x00, 0x49, 0x04, 0x08, 0x81, 0x96, 0x68, 0x82, 0xb0, 0x25, 0x08, 0x22,
+ 0x48, 0x89, 0xa2, 0x40, 0x59, 0x26, 0x04, 0x90, 0x06, 0x40, 0x43, 0x30,
+ 0x44, 0x92, 0x00, 0x69, 0x10, 0x82, 0x08, 0x08, 0xa4, 0x0d, 0x41, 0x12,
+ 0x60, 0xc0, 0x00, 0x24, 0xd2, 0x22, 0x61, 0x08, 0x84, 0x04, 0x1b, 0x82,
+ 0x01, 0xd3, 0x10, 0x01, 0x02, 0xa0, 0x44, 0xc0, 0x22, 0x60, 0x91, 0x14,
+ 0x0c, 0x40, 0xa6, 0x04, 0xd2, 0x94, 0x20, 0x09, 0x94, 0x20, 0x52, 0x00,
+ 0x08, 0x10, 0xa2, 0x4c, 0x00, 0x82, 0x01, 0x51, 0x10, 0x08, 0x8b, 0xa4,
+ 0x25, 0x9a, 0x30, 0x44, 0x81, 0x10, 0x4c, 0x03, 0x02, 0x25, 0x52, 0x80,
+ 0x08, 0x49, 0x84, 0x20, 0x50, 0x32, 0x00, 0x18, 0xa2, 0x40, 0x11, 0x24,
+ 0x28, 0x01, 0x84, 0x01, 0x01, 0xa0, 0x41, 0x0a, 0x12, 0x45, 0x00, 0x36,
+ 0x08, 0x00, 0x26, 0x29, 0x83, 0x82, 0x61, 0xc0, 0x80, 0x04, 0x10, 0x10,
+ 0x6d, 0x00, 0x22, 0x48, 0x58, 0x26, 0x0c, 0xc2, 0x10, 0x48, 0x89, 0x24,
+ 0x20, 0x58, 0x20, 0x45, 0x88, 0x24, 0x00, 0x19, 0x02, 0x25, 0xc0, 0x10,
+ 0x68, 0x08, 0x14, 0x01, 0xca, 0x32, 0x28, 0x80, 0x00, 0x04, 0x4b, 0x26,
+ 0x00, 0x13, 0x90, 0x60, 0x82, 0x80, 0x25, 0xd0, 0x00, 0x01, 0x10, 0x32,
+ 0x0c, 0x43, 0x86, 0x21, 0x11, 0x00, 0x08, 0x43, 0x24, 0x04, 0x48, 0x10,
+ 0x0c, 0x90, 0x92, 0x00, 0x43, 0x20, 0x2d, 0x00, 0x06, 0x09, 0x88, 0x24,
+ 0x40, 0xc0, 0x32, 0x09, 0x09, 0x82, 0x00, 0x53, 0x80, 0x08, 0x80, 0x96,
+ 0x41, 0x81, 0x00, 0x40, 0x48, 0x10, 0x48, 0x08, 0x96, 0x48, 0x58, 0x20,
+ 0x29, 0xc3, 0x80, 0x20, 0x02, 0x94, 0x60, 0x92, 0x00, 0x20, 0x81, 0x22,
+ 0x44, 0x10, 0xa0, 0x05, 0x40, 0x90, 0x01, 0x49, 0x20, 0x04, 0x0a, 0x00,
+ 0x24, 0x89, 0x34, 0x48, 0x13, 0x80, 0x2c, 0xc0, 0x82, 0x29, 0x00, 0x24,
+ 0x45, 0x08, 0x00, 0x08, 0x98, 0x36, 0x04, 0x52, 0x84, 0x04, 0xd0, 0x04,
+ 0x00, 0x8a, 0x90, 0x44, 0x82, 0x32, 0x65, 0x18, 0x90, 0x00, 0x0a, 0x02,
+ 0x01, 0x40, 0x02, 0x28, 0x40, 0xa4, 0x04, 0x92, 0x30, 0x04, 0x11, 0x86,
+ 0x08, 0x42, 0x00, 0x2c, 0x52, 0x04, 0x08, 0xc9, 0x84, 0x60, 0x48, 0x12,
+ 0x09, 0x99, 0x24, 0x44, 0x00, 0x24, 0x00, 0x03, 0x14, 0x21, 0x00, 0x10,
+ 0x01, 0x1a, 0x32, 0x05, 0x88, 0x20, 0x40, 0x40, 0x06, 0x09, 0xc3, 0x84,
+ 0x40, 0x01, 0x30, 0x60, 0x18, 0x02, 0x68, 0x11, 0x90, 0x0c, 0x02, 0xa2,
+ 0x04, 0x00, 0x86, 0x29, 0x89, 0x14, 0x24, 0x82, 0x02, 0x41, 0x08, 0x80,
+ 0x04, 0x19, 0x80, 0x08, 0x10, 0x12, 0x68, 0x42, 0xa4, 0x04, 0x00, 0x02,
+ 0x61, 0x10, 0x06, 0x0c, 0x10, 0x00, 0x01, 0x12, 0x10, 0x20, 0x03, 0x94,
+ 0x21, 0x42, 0x12, 0x65, 0x18, 0x94, 0x0c, 0x0a, 0x04, 0x28, 0x01, 0x14,
+ 0x29, 0x0a, 0xa4, 0x40, 0xd0, 0x00, 0x40, 0x01, 0x90, 0x04, 0x41, 0x20,
+ 0x2d, 0x40, 0x82, 0x48, 0xc1, 0x20, 0x00, 0x10, 0x30, 0x01, 0x08, 0x24,
+ 0x04, 0x59, 0x84, 0x24, 0x00, 0x02, 0x29, 0x82, 0x00, 0x61, 0x58, 0x02,
+ 0x48, 0x81, 0x16, 0x48, 0x10, 0x00, 0x21, 0x11, 0x06, 0x00, 0xca, 0xa0,
+ 0x40, 0x02, 0x00, 0x04, 0x91, 0xb0, 0x00, 0x42, 0x04, 0x0c, 0x81, 0x06,
+ 0x09, 0x48, 0x14, 0x25, 0x92, 0x20, 0x25, 0x11, 0xa0, 0x00, 0x0a, 0x86,
+ 0x0c, 0xc1, 0x02, 0x48, 0x00, 0x20, 0x45, 0x08, 0x32, 0x00, 0x98, 0x06,
+ 0x04, 0x13, 0x22, 0x00, 0x82, 0x04, 0x48, 0x81, 0x14, 0x44, 0x82, 0x12,
+ 0x24, 0x18, 0x10, 0x40, 0x43, 0x80, 0x28, 0xd0, 0x04, 0x20, 0x81, 0x24,
+ 0x64, 0xd8, 0x00, 0x2c, 0x09, 0x12, 0x08, 0x41, 0xa2, 0x00, 0x00, 0x02,
+ 0x41, 0xca, 0x20, 0x41, 0xc0, 0x10, 0x01, 0x18, 0xa4, 0x04, 0x18, 0xa4,
+ 0x20, 0x12, 0x94, 0x20, 0x83, 0xa0, 0x40, 0x02, 0x32, 0x44, 0x80, 0x04,
+ 0x00, 0x18, 0x00, 0x0c, 0x40, 0x86, 0x60, 0x8a, 0x00, 0x64, 0x88, 0x12,
+ 0x05, 0x01, 0x82, 0x00, 0x4a, 0xa2, 0x01, 0xc1, 0x10, 0x61, 0x09, 0x04,
+ 0x01, 0x88, 0x00, 0x60, 0x01, 0xb4, 0x40, 0x08, 0x06, 0x01, 0x03, 0x80,
+ 0x08, 0x40, 0x94, 0x04, 0x8a, 0x20, 0x29, 0x80, 0x02, 0x0c, 0x52, 0x02,
+ 0x01, 0x42, 0x84, 0x00, 0x80, 0x84, 0x64, 0x02, 0x32, 0x48, 0x00, 0x30,
+ 0x44, 0x40, 0x22, 0x21, 0x00, 0x02, 0x08, 0xc3, 0xa0, 0x04, 0xd0, 0x20,
+ 0x40, 0x18, 0x16, 0x40, 0x40, 0x00, 0x28, 0x52, 0x90, 0x08, 0x82, 0x14,
+ 0x01, 0x18, 0x10, 0x08, 0x09, 0x82, 0x40, 0x0a, 0xa0, 0x20, 0x93, 0x80,
+ 0x08, 0xc0, 0x00, 0x20, 0x52, 0x00, 0x05, 0x01, 0x10, 0x40, 0x11, 0x06,
+ 0x0c, 0x82, 0x00, 0x00, 0x4b, 0x90, 0x44, 0x9a, 0x00, 0x28, 0x80, 0x90,
+ 0x04, 0x4a, 0x06, 0x09, 0x43, 0x02, 0x28, 0x00, 0x34, 0x01, 0x18, 0x00,
+ 0x65, 0x09, 0x80, 0x44, 0x03, 0x00, 0x24, 0x02, 0x82, 0x61, 0x48, 0x14,
+ 0x41, 0x00, 0x12, 0x28, 0x00, 0x34, 0x08, 0x51, 0x04, 0x05, 0x12, 0x90,
+ 0x28, 0x89, 0x84, 0x60, 0x12, 0x10, 0x49, 0x10, 0x26, 0x40, 0x49, 0x82,
+ 0x00, 0x91, 0x10, 0x01, 0x0a, 0x24, 0x40, 0x88, 0x10, 0x4c, 0x10, 0x04,
+ 0x00, 0x50, 0xa2, 0x2c, 0x40, 0x90, 0x48, 0x0a, 0xb0, 0x01, 0x50, 0x12,
+ 0x08, 0x00, 0xa4, 0x04, 0x09, 0xa0, 0x28, 0x92, 0x02, 0x00, 0x43, 0x10,
+ 0x21, 0x02, 0x20, 0x41, 0x81, 0x32, 0x00, 0x08, 0x04, 0x0c, 0x52, 0x00,
+ 0x21, 0x49, 0x84, 0x20, 0x10, 0x02, 0x01, 0x81, 0x10, 0x48, 0x40, 0x22,
+ 0x01, 0x01, 0x84, 0x69, 0xc1, 0x30, 0x01, 0xc8, 0x02, 0x44, 0x88, 0x00,
+ 0x0c, 0x01, 0x02, 0x2d, 0xc0, 0x12, 0x61, 0x00, 0xa0, 0x00, 0xc0, 0x30,
+ 0x40, 0x01, 0x12, 0x08, 0x0b, 0x20, 0x00, 0x80, 0x94, 0x40, 0x01, 0x84,
+ 0x40, 0x00, 0x32, 0x00, 0x10, 0x84, 0x00, 0x0b, 0x24, 0x00, 0x01, 0x06,
+ 0x29, 0x8a, 0x84, 0x41, 0x80, 0x10, 0x08, 0x08, 0x94, 0x4c, 0x03, 0x80,
+ 0x01, 0x40, 0x96, 0x40, 0x41, 0x20, 0x20, 0x50, 0x22, 0x25, 0x89, 0xa2,
+ 0x40, 0x40, 0xa4, 0x20, 0x02, 0x86, 0x28, 0x01, 0x20, 0x21, 0x4a, 0x10,
+ 0x08, 0x00, 0x14, 0x08, 0x40, 0x04, 0x25, 0x42, 0x02, 0x21, 0x43, 0x10,
+ 0x04, 0x92, 0x00, 0x21, 0x11, 0xa0, 0x4c, 0x18, 0x22, 0x09, 0x03, 0x84,
+ 0x41, 0x89, 0x10, 0x04, 0x82, 0x22, 0x24, 0x01, 0x14, 0x08, 0x08, 0x84,
+ 0x08, 0xc1, 0x00, 0x09, 0x42, 0xb0, 0x41, 0x8a, 0x02, 0x00, 0x80, 0x36,
+ 0x04, 0x49, 0xa0, 0x24, 0x91, 0x00, 0x00, 0x02, 0x94, 0x41, 0x92, 0x02,
+ 0x01, 0x08, 0x06, 0x08, 0x09, 0x00, 0x01, 0xd0, 0x16, 0x28, 0x89, 0x80,
+ 0x60, 0x00, 0x00, 0x68, 0x01, 0x90, 0x0c, 0x50, 0x20, 0x01, 0x40, 0x80,
+ 0x40, 0x42, 0x30, 0x41, 0x00, 0x20, 0x25, 0x81, 0x06, 0x40, 0x49, 0x00,
+ 0x08, 0x01, 0x12, 0x49, 0x00, 0xa0, 0x20, 0x18, 0x30, 0x05, 0x01, 0xa6,
+ 0x00, 0x10, 0x24, 0x28, 0x00, 0x02, 0x20, 0xc8, 0x20, 0x00, 0x88, 0x12,
+ 0x0c, 0x90, 0x92, 0x00, 0x02, 0x26, 0x01, 0x42, 0x16, 0x49, 0x00, 0x04,
+ 0x24, 0x42, 0x02, 0x01, 0x88, 0x80, 0x0c, 0x1a, 0x80, 0x08, 0x10, 0x00,
+ 0x60, 0x02, 0x94, 0x44, 0x88, 0x00, 0x69, 0x11, 0x30, 0x08, 0x12, 0xa0,
+ 0x24, 0x13, 0x84, 0x00, 0x82, 0x00, 0x65, 0xc0, 0x10, 0x28, 0x00, 0x30,
+ 0x04, 0x03, 0x20, 0x01, 0x11, 0x06, 0x01, 0xc8, 0x80, 0x00, 0xc2, 0x20,
+ 0x08, 0x10, 0x82, 0x0c, 0x13, 0x02, 0x0c, 0x52, 0x06, 0x40, 0x00, 0xb0,
+ 0x61, 0x40, 0x10, 0x01, 0x98, 0x86, 0x04, 0x10, 0x84, 0x08, 0x92, 0x14,
+ 0x60, 0x41, 0x80, 0x41, 0x1a, 0x10, 0x04, 0x81, 0x22, 0x40, 0x41, 0x20,
+ 0x29, 0x52, 0x00, 0x41, 0x08, 0x34, 0x60, 0x10, 0x00, 0x28, 0x01, 0x10,
+ 0x40, 0x00, 0x84, 0x08, 0x42, 0x90, 0x20, 0x48, 0x04, 0x04, 0x52, 0x02,
+ 0x00, 0x08, 0x20, 0x04, 0x00, 0x82, 0x0d, 0x00, 0x82, 0x40, 0x02, 0x10,
+ 0x05, 0x48, 0x20, 0x40, 0x99, 0x00, 0x00, 0x01, 0x06, 0x24, 0xc0, 0x00,
+ 0x68, 0x82, 0x04, 0x21, 0x12, 0x10, 0x44, 0x08, 0x04, 0x00, 0x40, 0xa6,
+ 0x20, 0xd0, 0x16, 0x09, 0xc9, 0x24, 0x41, 0x02, 0x20, 0x0c, 0x09, 0x92,
+ 0x40, 0x12, 0x00, 0x00, 0x40, 0x00, 0x09, 0x43, 0x84, 0x20, 0x98, 0x02,
+ 0x01, 0x11, 0x24, 0x00, 0x43, 0x24, 0x00, 0x03, 0x90, 0x08, 0x41, 0x30,
+ 0x24, 0x58, 0x20, 0x4c, 0x80, 0x82, 0x08, 0x10, 0x24, 0x25, 0x81, 0x06,
+ 0x41, 0x09, 0x10, 0x20, 0x18, 0x10, 0x44, 0x80, 0x10, 0x00, 0x4a, 0x24,
+ 0x0d, 0x01, 0x94, 0x28, 0x80, 0x30, 0x00, 0xc0, 0x02, 0x60, 0x10, 0x84,
+ 0x0c, 0x02, 0x00, 0x09, 0x02, 0x82, 0x01, 0x08, 0x10, 0x04, 0xc2, 0x20,
+ 0x68, 0x09, 0x06, 0x04, 0x18, 0x00, 0x00, 0x11, 0x90, 0x08, 0x0b, 0x10,
+ 0x21, 0x82, 0x02, 0x0c, 0x10, 0xb6, 0x08, 0x00, 0x26, 0x00, 0x41, 0x02,
+ 0x01, 0x4a, 0x24, 0x21, 0x1a, 0x20, 0x24, 0x80, 0x00, 0x44, 0x02, 0x00,
+ 0x2d, 0x40, 0x02, 0x00, 0x8b, 0x94, 0x20, 0x10, 0x00, 0x20, 0x90, 0xa6,
+ 0x40, 0x13, 0x00, 0x2c, 0x11, 0x86, 0x61, 0x01, 0x80, 0x41, 0x10, 0x02,
+ 0x04, 0x81, 0x30, 0x48, 0x48, 0x20, 0x28, 0x50, 0x80, 0x21, 0x8a, 0x10,
+ 0x04, 0x08, 0x10, 0x09, 0x10, 0x10, 0x48, 0x42, 0xa0, 0x0c, 0x82, 0x92,
+ 0x60, 0xc0, 0x20, 0x05, 0xd2, 0x20, 0x40, 0x01, 0x00, 0x04, 0x08, 0x82,
+ 0x2d, 0x82, 0x02, 0x00, 0x48, 0x80, 0x41, 0x48, 0x10, 0x00, 0x91, 0x04,
+ 0x04, 0x03, 0x84, 0x00, 0xc2, 0x04, 0x68, 0x00, 0x00, 0x64, 0xc0, 0x22,
+ 0x40, 0x08, 0x32, 0x44, 0x09, 0x86, 0x00, 0x91, 0x02, 0x28, 0x01, 0x00,
+ 0x64, 0x48, 0x00, 0x24, 0x10, 0x90, 0x00, 0x43, 0x00, 0x21, 0x52, 0x86,
+ 0x41, 0x8b, 0x90, 0x20, 0x40, 0x20, 0x08, 0x88, 0x04, 0x44, 0x13, 0x20,
+ 0x00, 0x02, 0x84, 0x60, 0x81, 0x90, 0x24, 0x40, 0x30, 0x00, 0x08, 0x10,
+ 0x08, 0x08, 0x02, 0x01, 0x10, 0x04, 0x20, 0x43, 0xb4, 0x40, 0x90, 0x12,
+ 0x68, 0x01, 0x80, 0x4c, 0x18, 0x00, 0x08, 0xc0, 0x12, 0x49, 0x40, 0x10,
+ 0x24, 0x1a, 0x00, 0x41, 0x89, 0x24, 0x4c, 0x10, 0x00, 0x04, 0x52, 0x10,
+ 0x09, 0x4a, 0x20, 0x41, 0x48, 0x22, 0x69, 0x11, 0x14, 0x08, 0x10, 0x06,
+ 0x24, 0x80, 0x84, 0x28, 0x00, 0x10, 0x00, 0x40, 0x10, 0x01, 0x08, 0x26,
+ 0x08, 0x48, 0x06, 0x28, 0x00, 0x14, 0x01, 0x42, 0x84, 0x04, 0x0a, 0x20,
+ 0x00, 0x01, 0x82, 0x08, 0x00, 0x82, 0x24, 0x12, 0x04, 0x40, 0x40, 0xa0,
+ 0x40, 0x90, 0x10, 0x04, 0x90, 0x22, 0x40, 0x10, 0x20, 0x2c, 0x80, 0x10,
+ 0x28, 0x43, 0x00, 0x04, 0x58, 0x00, 0x01, 0x81, 0x10, 0x48, 0x09, 0x20,
+ 0x21, 0x83, 0x04, 0x00, 0x42, 0xa4, 0x44, 0x00, 0x00, 0x6c, 0x10, 0xa0,
+ 0x44, 0x48, 0x80, 0x00, 0x83, 0x80, 0x48, 0xc9, 0x00, 0x00, 0x00, 0x02,
+ 0x05, 0x10, 0xb0, 0x04, 0x13, 0x04, 0x29, 0x10, 0x92, 0x40, 0x08, 0x04,
+ 0x44, 0x82, 0x22, 0x00, 0x19, 0x20, 0x00, 0x19, 0x20, 0x01, 0x81, 0x90,
+ 0x60, 0x8a, 0x00, 0x41, 0xc0, 0x02, 0x45, 0x10, 0x04, 0x00, 0x02, 0xa2,
+ 0x09, 0x40, 0x10, 0x21, 0x49, 0x20, 0x01, 0x42, 0x30, 0x2c, 0x00, 0x14,
+ 0x44, 0x01, 0x22, 0x04, 0x02, 0x92, 0x08, 0x89, 0x04, 0x21, 0x80, 0x10,
+ 0x05, 0x01, 0x20, 0x40, 0x41, 0x80, 0x04, 0x00, 0x12, 0x09, 0x40, 0xb0,
+ 0x64, 0x58, 0x32, 0x01, 0x08, 0x90, 0x00, 0x41, 0x04, 0x09, 0xc1, 0x80,
+ 0x61, 0x08, 0x90, 0x00, 0x9a, 0x00, 0x24, 0x01, 0x12, 0x08, 0x02, 0x26,
+ 0x05, 0x82, 0x06, 0x08, 0x08, 0x00, 0x20, 0x48, 0x20, 0x00, 0x18, 0x24,
+ 0x48, 0x03, 0x02, 0x00, 0x11, 0x00, 0x09, 0x00, 0x84, 0x01, 0x4a, 0x10,
+ 0x01, 0x98, 0x00, 0x04, 0x18, 0x86, 0x00, 0xc0, 0x00, 0x20, 0x81, 0x80,
+ 0x04, 0x10, 0x30, 0x05, 0x00, 0xb4, 0x0c, 0x4a, 0x82, 0x29, 0x91, 0x02,
+ 0x28, 0x00, 0x20, 0x44, 0xc0, 0x00, 0x2c, 0x91, 0x80, 0x40, 0x01, 0xa2,
+ 0x00, 0x12, 0x04, 0x09, 0xc3, 0x20, 0x00, 0x08, 0x02, 0x0c, 0x10, 0x22,
+ 0x04, 0x00, 0x00, 0x2c, 0x11, 0x86, 0x00, 0xc0, 0x00, 0x00, 0x12, 0x32,
+ 0x40, 0x89, 0x80, 0x40, 0x40, 0x02, 0x05, 0x50, 0x86, 0x60, 0x82, 0xa4,
+ 0x60, 0x0a, 0x12, 0x4d, 0x80, 0x90, 0x08, 0x12, 0x80, 0x09, 0x02, 0x14,
+ 0x48, 0x01, 0x24, 0x20, 0x8a, 0x00, 0x44, 0x90, 0x04, 0x04, 0x01, 0x02,
+ 0x00, 0xd1, 0x12, 0x00, 0x0a, 0x04, 0x40, 0x00, 0x32, 0x21, 0x81, 0x24,
+ 0x08, 0x19, 0x84, 0x20, 0x02, 0x04, 0x08, 0x89, 0x80, 0x24, 0x02, 0x02,
+ 0x68, 0x18, 0x82, 0x44, 0x42, 0x00, 0x21, 0x40, 0x00, 0x28, 0x01, 0x80,
+ 0x45, 0x82, 0x20, 0x40, 0x11, 0x80, 0x0c, 0x02, 0x00, 0x24, 0x40, 0x90,
+ 0x01, 0x40, 0x20, 0x20, 0x50, 0x20, 0x28, 0x19, 0x00, 0x40, 0x09, 0x20,
+ 0x08, 0x80, 0x04, 0x60, 0x40, 0x80, 0x20, 0x08, 0x30, 0x49, 0x09, 0x34,
+ 0x00, 0x11, 0x24, 0x24, 0x82, 0x00, 0x41, 0xc2, 0x00, 0x04, 0x92, 0x02,
+ 0x24, 0x80, 0x00, 0x0c, 0x02, 0xa0, 0x00, 0x01, 0x06, 0x60, 0x41, 0x04,
+ 0x21, 0xd0, 0x00, 0x01, 0x01, 0x00, 0x48, 0x12, 0x84, 0x04, 0x91, 0x12,
+ 0x08, 0x00, 0x24, 0x44, 0x00, 0x12, 0x41, 0x18, 0x26, 0x0c, 0x41, 0x80,
+ 0x00, 0x52, 0x04, 0x20, 0x09, 0x00, 0x24, 0x90, 0x20, 0x48, 0x18, 0x02,
+ 0x00, 0x03, 0xa2, 0x09, 0xd0, 0x14, 0x00, 0x8a, 0x84, 0x25, 0x4a, 0x00,
+ 0x20, 0x98, 0x14, 0x40, 0x00, 0xa2, 0x05, 0x00, 0x00, 0x00, 0x40, 0x14,
+ 0x01, 0x58, 0x20, 0x2c, 0x80, 0x84, 0x00, 0x09, 0x20, 0x20, 0x91, 0x02,
+ 0x08, 0x02, 0xb0, 0x41, 0x08, 0x30, 0x00, 0x09, 0x10, 0x00, 0x18, 0x02,
+ 0x21, 0x02, 0x02, 0x00, 0x00, 0x24, 0x44, 0x08, 0x12, 0x60, 0x00, 0xb2,
+ 0x44, 0x12, 0x02, 0x0c, 0xc0, 0x80, 0x40, 0xc8, 0x20, 0x04, 0x50, 0x20,
+ 0x05, 0x00, 0xb0, 0x04, 0x0b, 0x04, 0x29, 0x53, 0x00, 0x61, 0x48, 0x30,
+ 0x00, 0x82, 0x20, 0x29, 0x00, 0x16, 0x00, 0x53, 0x22, 0x20, 0x43, 0x10,
+ 0x48, 0x00, 0x80, 0x04, 0xd2, 0x00, 0x40, 0x00, 0xa2, 0x44, 0x03, 0x80,
+ 0x29, 0x00, 0x04, 0x08, 0xc0, 0x04, 0x64, 0x40, 0x30, 0x28, 0x09, 0x84,
+ 0x44, 0x50, 0x80, 0x21, 0x02, 0x92, 0x00, 0xc0, 0x10, 0x60, 0x88, 0x22,
+ 0x08, 0x80, 0x00, 0x00, 0x18, 0x84, 0x04, 0x83, 0x96, 0x00, 0x81, 0x20,
+ 0x05, 0x02, 0x00, 0x45, 0x88, 0x84, 0x00, 0x51, 0x20, 0x20, 0x51, 0x86,
+ 0x41, 0x4b, 0x94, 0x00, 0x80, 0x00, 0x08, 0x11, 0x20, 0x4c, 0x58, 0x80,
+ 0x04, 0x03, 0x06, 0x20, 0x89, 0x00, 0x05, 0x08, 0x22, 0x05, 0x90, 0x00,
+ 0x40, 0x00, 0x82, 0x09, 0x50, 0x00, 0x00, 0x00, 0xa0, 0x41, 0xc2, 0x20,
+ 0x08, 0x00, 0x16, 0x08, 0x40, 0x26, 0x21, 0xd0, 0x90, 0x08, 0x81, 0x90,
+ 0x41, 0x00, 0x02, 0x44, 0x08, 0x10, 0x0c, 0x0a, 0x86, 0x09, 0x90, 0x04,
+ 0x00, 0xc8, 0xa0, 0x04, 0x08, 0x30, 0x20, 0x89, 0x84, 0x00, 0x11, 0x22,
+ 0x2c, 0x40, 0x00, 0x08, 0x02, 0xb0, 0x01, 0x48, 0x02, 0x01, 0x09, 0x20,
+ 0x04, 0x03, 0x04, 0x00, 0x80, 0x02, 0x60, 0x42, 0x30, 0x21, 0x4a, 0x10,
+ 0x44, 0x09, 0x02, 0x00, 0x01, 0x24, 0x00, 0x12, 0x82, 0x21, 0x80, 0xa4,
+ 0x20, 0x10, 0x02, 0x04, 0x91, 0xa0, 0x40, 0x18, 0x04, 0x00, 0x02, 0x06,
+ 0x69, 0x09, 0x00, 0x05, 0x58, 0x02, 0x01, 0x00, 0x00, 0x48, 0x00, 0x00,
+ 0x00, 0x03, 0x92, 0x20, 0x00, 0x34, 0x01, 0xc8, 0x20, 0x48, 0x08, 0x30,
+ 0x08, 0x42, 0x80, 0x20, 0x91, 0x90, 0x68, 0x01, 0x04, 0x40, 0x12, 0x02,
+ 0x61, 0x00, 0x12, 0x08, 0x01, 0xa0, 0x00, 0x11, 0x04, 0x21, 0x48, 0x04,
+ 0x24, 0x92, 0x00, 0x0c, 0x01, 0x84, 0x04, 0x00, 0x00, 0x01, 0x12, 0x96,
+ 0x40, 0x01, 0xa0, 0x41, 0x88, 0x22, 0x28, 0x88, 0x00, 0x44, 0x42, 0x80,
+ 0x24, 0x12, 0x14, 0x01, 0x42, 0x90, 0x60, 0x1a, 0x10, 0x04, 0x81, 0x10,
+ 0x48, 0x08, 0x06, 0x29, 0x83, 0x02, 0x40, 0x02, 0x24, 0x64, 0x80, 0x10,
+ 0x05, 0x80, 0x10, 0x40, 0x02, 0x02, 0x08, 0x42, 0x84, 0x01, 0x09, 0x20,
+ 0x04, 0x50, 0x00, 0x60, 0x11, 0x30, 0x40, 0x13, 0x02, 0x04, 0x81, 0x00,
+ 0x09, 0x08, 0x20, 0x45, 0x4a, 0x10, 0x61, 0x90, 0x26, 0x0c, 0x08, 0x02,
+ 0x21, 0x91, 0x00, 0x60, 0x02, 0x04, 0x00, 0x02, 0x00, 0x0c, 0x08, 0x06,
+ 0x08, 0x48, 0x84, 0x08, 0x11, 0x02, 0x00, 0x80, 0xa4, 0x00, 0x5a, 0x20,
+ 0x00, 0x88, 0x04, 0x04, 0x02, 0x00, 0x09, 0x00, 0x14, 0x08, 0x49, 0x14,
+ 0x20, 0xc8, 0x00, 0x04, 0x91, 0xa0, 0x40, 0x59, 0x80, 0x00, 0x12, 0x10,
+ 0x00, 0x80, 0x80, 0x65, 0x00, 0x00, 0x04, 0x00, 0x80, 0x40, 0x19, 0x00,
+ 0x21, 0x03, 0x84, 0x60, 0xc0, 0x04, 0x24, 0x1a, 0x12, 0x61, 0x80, 0x80,
+ 0x08, 0x02, 0x04, 0x09, 0x42, 0x12, 0x20, 0x08, 0x34, 0x04, 0x90, 0x20,
+ 0x01, 0x01, 0xa0, 0x00, 0x0b, 0x00, 0x08, 0x91, 0x92, 0x40, 0x02, 0x34,
+ 0x40, 0x88, 0x10, 0x61, 0x19, 0x02, 0x00, 0x40, 0x04, 0x25, 0xc0, 0x80,
+ 0x68, 0x08, 0x04, 0x21, 0x80, 0x22, 0x04, 0x00, 0xa0, 0x0c, 0x01, 0x84,
+ 0x20, 0x41, 0x00, 0x08, 0x8a, 0x00, 0x20, 0x8a, 0x00, 0x48, 0x88, 0x04,
+ 0x04, 0x11, 0x82, 0x08, 0x40, 0x86, 0x09, 0x49, 0xa4, 0x40, 0x00, 0x10,
+ 0x01, 0x01, 0xa2, 0x04, 0x50, 0x80, 0x0c, 0x80, 0x00, 0x48, 0x82, 0xa0,
+ 0x01, 0x18, 0x12, 0x41, 0x01, 0x04, 0x48, 0x41, 0x00, 0x24, 0x01, 0x00,
+ 0x00, 0x88, 0x14, 0x00, 0x02, 0x00, 0x68, 0x01, 0x20, 0x08, 0x4a, 0x22,
+ 0x08, 0x83, 0x80, 0x00, 0x89, 0x04, 0x01, 0xc2, 0x00, 0x00, 0x00, 0x34,
+ 0x04, 0x00, 0x82, 0x28, 0x02, 0x02, 0x41, 0x4a, 0x90, 0x05, 0x82, 0x02,
+ 0x09, 0x80, 0x24, 0x04, 0x41, 0x00, 0x01, 0x92, 0x80, 0x28, 0x01, 0x14,
+ 0x00, 0x50, 0x20, 0x4c, 0x10, 0xb0, 0x04, 0x43, 0xa4, 0x21, 0x90, 0x04,
+ 0x01, 0x02, 0x00, 0x44, 0x48, 0x00, 0x64, 0x08, 0x06, 0x00, 0x42, 0x20,
+ 0x08, 0x02, 0x92, 0x01, 0x4a, 0x00, 0x20, 0x50, 0x32, 0x25, 0x90, 0x22,
+ 0x04, 0x09, 0x00, 0x08, 0x11, 0x80, 0x21, 0x01, 0x10, 0x05, 0x00, 0x32,
+ 0x08, 0x88, 0x94, 0x08, 0x08, 0x24, 0x0d, 0xc1, 0x80, 0x40, 0x0b, 0x20,
+ 0x40, 0x18, 0x12, 0x04, 0x00, 0x22, 0x40, 0x10, 0x26, 0x05, 0xc1, 0x82,
+ 0x00, 0x01, 0x30, 0x24, 0x02, 0x22, 0x41, 0x08, 0x24, 0x48, 0x1a, 0x00,
+ 0x25, 0xd2, 0x12, 0x28, 0x42, 0x00, 0x04, 0x40, 0x30, 0x41, 0x00, 0x02,
+ 0x00, 0x13, 0x20, 0x24, 0xd1, 0x84, 0x08, 0x89, 0x80, 0x04, 0x52, 0x00,
+ 0x44, 0x18, 0xa4, 0x00, 0x00, 0x06, 0x20, 0x91, 0x10, 0x09, 0x42, 0x20,
+ 0x24, 0x40, 0x30, 0x28, 0x00, 0x84, 0x40, 0x40, 0x80, 0x08, 0x10, 0x04,
+ 0x09, 0x08, 0x04, 0x40, 0x08, 0x22, 0x00, 0x19, 0x02, 0x00, 0x00, 0x80,
+ 0x2c, 0x02, 0x02, 0x21, 0x01, 0x90, 0x20, 0x40, 0x00, 0x0c, 0x00, 0x34,
+ 0x48, 0x58, 0x20, 0x01, 0x43, 0x04, 0x20, 0x80, 0x14, 0x00, 0x90, 0x00,
+ 0x6d, 0x11, 0x00, 0x00, 0x40, 0x20, 0x00, 0x03, 0x10, 0x40, 0x88, 0x30,
+ 0x05, 0x4a, 0x00, 0x65, 0x10, 0x24, 0x08, 0x18, 0x84, 0x28, 0x03, 0x80,
+ 0x20, 0x42, 0xb0, 0x40, 0x00, 0x10, 0x69, 0x19, 0x04, 0x00, 0x00, 0x80,
+ 0x04, 0xc2, 0x04, 0x00, 0x01, 0x00, 0x05, 0x00, 0x22, 0x25, 0x08, 0x96,
+ 0x04, 0x02, 0x22, 0x00, 0xd0, 0x10, 0x29, 0x01, 0xa0, 0x60, 0x08, 0x10,
+ 0x04, 0x01, 0x16, 0x44, 0x10, 0x02, 0x28, 0x02, 0x82, 0x48, 0x40, 0x84,
+ 0x20, 0x90, 0x22, 0x28, 0x80, 0x04, 0x00, 0x40, 0x04, 0x24, 0x00, 0x80,
+ 0x29, 0x03, 0x10, 0x60, 0x48, 0x00, 0x00, 0x81, 0xa0, 0x00, 0x51, 0x20,
+ 0x0c, 0xd1, 0x00, 0x01, 0x41, 0x20, 0x04, 0x92, 0x00, 0x00, 0x10, 0x92,
+ 0x00, 0x42, 0x04, 0x05, 0x01, 0x86, 0x40, 0x80, 0x10, 0x20, 0x52, 0x20,
+ 0x21, 0x00, 0x10, 0x48, 0x0a, 0x02, 0x00, 0xd0, 0x12, 0x41, 0x48, 0x80,
+ 0x04, 0x00, 0x00, 0x48, 0x09, 0x22, 0x04, 0x00, 0x24, 0x00, 0x43, 0x10,
+ 0x60, 0x0a, 0x00, 0x44, 0x12, 0x20, 0x2c, 0x08, 0x20, 0x44, 0x00, 0x84,
+ 0x09, 0x40, 0x06, 0x08, 0xc1, 0x00, 0x40, 0x80, 0x20, 0x00, 0x98, 0x12,
+ 0x48, 0x10, 0xa2, 0x20, 0x00, 0x84, 0x48, 0xc0, 0x10, 0x20, 0x90, 0x12,
+ 0x08, 0x98, 0x82, 0x00, 0x0a, 0xa0, 0x04, 0x03, 0x00, 0x28, 0xc3, 0x00,
+ 0x44, 0x42, 0x10, 0x04, 0x08, 0x04, 0x40, 0x00, 0x00, 0x05, 0x10, 0x00,
+ 0x21, 0x03, 0x80, 0x04, 0x88, 0x12, 0x69, 0x10, 0x00, 0x04, 0x08, 0x04,
+ 0x04, 0x02, 0x84, 0x48, 0x49, 0x04, 0x20, 0x18, 0x02, 0x64, 0x80, 0x30,
+ 0x08, 0x01, 0x02, 0x00, 0x52, 0x12, 0x49, 0x08, 0x20, 0x41, 0x88, 0x10,
+ 0x48, 0x08, 0x34, 0x00, 0x01, 0x86, 0x05, 0xd0, 0x00, 0x00, 0x83, 0x84,
+ 0x21, 0x40, 0x02, 0x41, 0x10, 0x80, 0x48, 0x40, 0xa2, 0x20, 0x51, 0x00,
+ 0x00, 0x49, 0x00, 0x01, 0x90, 0x20, 0x40, 0x18, 0x02, 0x40, 0x02, 0x22,
+ 0x05, 0x40, 0x80, 0x08, 0x82, 0x10, 0x20, 0x18, 0x00, 0x05, 0x01, 0x82,
+ 0x40, 0x58, 0x00, 0x04, 0x81, 0x90, 0x29, 0x01, 0xa0, 0x64, 0x00, 0x22,
+ 0x40, 0x01, 0xa2, 0x00, 0x18, 0x04, 0x0d, 0x00, 0x00, 0x60, 0x80, 0x94,
+ 0x60, 0x82, 0x10, 0x0d, 0x80, 0x30, 0x0c, 0x12, 0x20, 0x00, 0x00, 0x12,
+ 0x40, 0xc0, 0x20, 0x21, 0x58, 0x02, 0x41, 0x10, 0x80, 0x44, 0x03, 0x02,
+ 0x04, 0x13, 0x90, 0x29, 0x08, 0x00, 0x44, 0xc0, 0x00, 0x21, 0x00, 0x26,
+ 0x00, 0x1a, 0x80, 0x01, 0x13, 0x14, 0x20, 0x0a, 0x14, 0x20, 0x00, 0x32,
+ 0x61, 0x08, 0x00, 0x40, 0x42, 0x20, 0x09, 0x80, 0x06, 0x01, 0x81, 0x80,
+ 0x60, 0x42, 0x00, 0x68, 0x90, 0x82, 0x08, 0x42, 0x80, 0x04, 0x02, 0x80,
+ 0x09, 0x0b, 0x04, 0x00, 0x98, 0x00, 0x0c, 0x81, 0x06, 0x44, 0x48, 0x84,
+ 0x28, 0x03, 0x92, 0x00, 0x01, 0x80, 0x40, 0x0a, 0x00, 0x0c, 0x81, 0x02,
+ 0x08, 0x51, 0x04, 0x28, 0x90, 0x02, 0x20, 0x09, 0x10, 0x60, 0x00, 0x00,
+ 0x09, 0x81, 0xa0, 0x0c, 0x00, 0xa4, 0x09, 0x00, 0x02, 0x28, 0x80, 0x20,
+ 0x00, 0x02, 0x02, 0x04, 0x81, 0x14, 0x04, 0x00, 0x04, 0x09, 0x11, 0x12,
+ 0x60, 0x40, 0x20, 0x01, 0x48, 0x30, 0x40, 0x11, 0x00, 0x08, 0x0a, 0x86,
+ 0x00, 0x00, 0x04, 0x60, 0x81, 0x04, 0x01, 0xd0, 0x02, 0x41, 0x18, 0x90,
+ 0x00, 0x0a, 0x20, 0x00, 0xc1, 0x06, 0x01, 0x08, 0x80, 0x64, 0xca, 0x10,
+ 0x04, 0x99, 0x80, 0x48, 0x01, 0x82, 0x20, 0x50, 0x90, 0x48, 0x80, 0x84,
+ 0x20, 0x90, 0x22, 0x00, 0x19, 0x00, 0x04, 0x18, 0x20, 0x24, 0x10, 0x86,
+ 0x40, 0xc2, 0x00, 0x24, 0x12, 0x10, 0x44, 0x00, 0x16, 0x08, 0x10, 0x24,
+ 0x00, 0x12, 0x06, 0x01, 0x08, 0x90, 0x00, 0x12, 0x02, 0x4d, 0x10, 0x80,
+ 0x40, 0x50, 0x22, 0x00, 0x43, 0x10, 0x01, 0x00, 0x30, 0x21, 0x0a, 0x00,
+ 0x00, 0x01, 0x14, 0x00, 0x10, 0x84, 0x04, 0xc1, 0x10, 0x29, 0x0a, 0x00,
+ 0x01, 0x8a, 0x00, 0x20, 0x01, 0x12, 0x0c, 0x49, 0x20, 0x04, 0x81, 0x00,
+ 0x48, 0x01, 0x04, 0x60, 0x80, 0x12, 0x0c, 0x08, 0x10, 0x48, 0x4a, 0x04,
+ 0x28, 0x10, 0x00, 0x28, 0x40, 0x84, 0x45, 0x50, 0x10, 0x60, 0x10, 0x06,
+ 0x44, 0x01, 0x80, 0x09, 0x00, 0x86, 0x01, 0x42, 0xa0, 0x00, 0x90, 0x00,
+ 0x05, 0x90, 0x22, 0x40, 0x41, 0x00, 0x08, 0x80, 0x02, 0x08, 0xc0, 0x00,
+ 0x01, 0x58, 0x30, 0x49, 0x09, 0x14, 0x00, 0x41, 0x02, 0x0c, 0x02, 0x80,
+ 0x40, 0x89, 0x00, 0x24, 0x08, 0x10, 0x05, 0x90, 0x32, 0x40, 0x0a, 0x82,
+ 0x08, 0x00, 0x12, 0x61, 0x00, 0x04, 0x21, 0x00, 0x22, 0x04, 0x10, 0x24,
+ 0x08, 0x0a, 0x04, 0x01, 0x10, 0x00, 0x20, 0x40, 0x84, 0x04, 0x88, 0x22,
+ 0x20, 0x90, 0x12, 0x00, 0x53, 0x06, 0x24, 0x01, 0x04, 0x40, 0x0b, 0x14,
+ 0x60, 0x82, 0x02, 0x0d, 0x10, 0x90, 0x0c, 0x08, 0x20, 0x09, 0x00, 0x14,
+ 0x09, 0x80, 0x80, 0x24, 0x82, 0x00, 0x40, 0x01, 0x02, 0x44, 0x01, 0x20,
+ 0x0c, 0x40, 0x84, 0x40, 0x0a, 0x10, 0x41, 0x00, 0x30, 0x05, 0x09, 0x80,
+ 0x44, 0x08, 0x20, 0x20, 0x02, 0x00, 0x49, 0x43, 0x20, 0x21, 0x00, 0x20,
+ 0x00, 0x01, 0xb6, 0x08, 0x40, 0x04, 0x08, 0x02, 0x80, 0x01, 0x41, 0x80,
+ 0x40, 0x08, 0x10, 0x24, 0x00, 0x20, 0x04, 0x12, 0x86, 0x09, 0xc0, 0x12,
+ 0x21, 0x81, 0x14, 0x04, 0x00, 0x02, 0x20, 0x89, 0xb4, 0x44, 0x12, 0x80,
+ 0x00, 0xd1, 0x00, 0x69, 0x40, 0x80, 0x00, 0x42, 0x12, 0x00, 0x18, 0x04,
+ 0x00, 0x49, 0x06, 0x21, 0x02, 0x04, 0x28, 0x02, 0x84, 0x01, 0xc0, 0x10,
+ 0x68, 0x00, 0x20, 0x08, 0x40, 0x00, 0x08, 0x91, 0x10, 0x01, 0x81, 0x24,
+ 0x04, 0xd2, 0x10, 0x4c, 0x88, 0x86, 0x00, 0x10, 0x80, 0x0c, 0x02, 0x14,
+ 0x00, 0x8a, 0x90, 0x40, 0x18, 0x20, 0x21, 0x80, 0xa4, 0x00, 0x58, 0x24,
+ 0x20, 0x10, 0x10, 0x60, 0xc1, 0x30, 0x41, 0x48, 0x02, 0x48, 0x09, 0x00,
+ 0x40, 0x09, 0x02, 0x05, 0x11, 0x82, 0x20, 0x4a, 0x20, 0x24, 0x18, 0x02,
+ 0x0c, 0x10, 0x22, 0x0c, 0x0a, 0x04, 0x00, 0x03, 0x06, 0x48, 0x48, 0x04,
+ 0x04, 0x02, 0x00, 0x21, 0x80, 0x84, 0x00, 0x18, 0x00, 0x0c, 0x02, 0x12,
+ 0x01, 0x00, 0x14, 0x05, 0x82, 0x10, 0x41, 0x89, 0x12, 0x08, 0x40, 0xa4,
+ 0x21, 0x01, 0x84, 0x48, 0x02, 0x10, 0x60, 0x40, 0x02, 0x28, 0x00, 0x14,
+ 0x08, 0x40, 0xa0, 0x20, 0x51, 0x12, 0x00, 0xc2, 0x00, 0x01, 0x1a, 0x30,
+ 0x40, 0x89, 0x12, 0x4c, 0x02, 0x80, 0x00, 0x00, 0x14, 0x01, 0x01, 0xa0,
+ 0x21, 0x18, 0x22, 0x21, 0x18, 0x06, 0x40, 0x01, 0x80, 0x00, 0x90, 0x04,
+ 0x48, 0x02, 0x30, 0x04, 0x08, 0x00, 0x05, 0x88, 0x24, 0x08, 0x48, 0x04,
+ 0x24, 0x02, 0x06, 0x00, 0x80, 0x00, 0x00, 0x00, 0x10, 0x65, 0x11, 0x90,
+ 0x00, 0x0a, 0x82, 0x04, 0xc3, 0x04, 0x60, 0x48, 0x24, 0x04, 0x92, 0x02,
+ 0x44, 0x88, 0x80, 0x40, 0x18, 0x06, 0x29, 0x80, 0x10, 0x01, 0x00, 0x00,
+ 0x44, 0xc8, 0x10, 0x21, 0x89, 0x30, 0x00, 0x4b, 0xa0, 0x01, 0x10, 0x14,
+ 0x00, 0x02, 0x94, 0x40, 0x00, 0x20, 0x65, 0x00, 0xa2, 0x0c, 0x40, 0x22,
+ 0x20, 0x81, 0x12, 0x20, 0x82, 0x04, 0x01, 0x10, 0x00, 0x08, 0x88, 0x00,
+ 0x00, 0x11, 0x80, 0x04, 0x42, 0x80, 0x40, 0x41, 0x14, 0x00, 0x40, 0x32,
+ 0x2c, 0x80, 0x24, 0x04, 0x19, 0x00, 0x00, 0x91, 0x00, 0x20, 0x83, 0x00,
+ 0x05, 0x40, 0x20, 0x09, 0x01, 0x84, 0x40, 0x40, 0x20, 0x20, 0x11, 0x00,
+ 0x40, 0x41, 0x90, 0x20, 0x00, 0x00, 0x40, 0x90, 0x92, 0x48, 0x18, 0x06,
+ 0x08, 0x81, 0x80, 0x48, 0x01, 0x34, 0x24, 0x10, 0x20, 0x04, 0x00, 0x20,
+ 0x04, 0x18, 0x06, 0x2d, 0x90, 0x10, 0x01, 0x00, 0x90, 0x00, 0x0a, 0x22,
+ 0x01, 0x00, 0x22, 0x00, 0x11, 0x84, 0x01, 0x01, 0x00, 0x20, 0x88, 0x00,
+ 0x44, 0x00, 0x22, 0x01, 0x00, 0xa6, 0x40, 0x02, 0x06, 0x20, 0x11, 0x00,
+ 0x01, 0xc8, 0xa0, 0x04, 0x8a, 0x00, 0x28, 0x19, 0x80, 0x00, 0x52, 0xa0,
+ 0x24, 0x12, 0x12, 0x09, 0x08, 0x24, 0x01, 0x48, 0x00, 0x04, 0x00, 0x24,
+ 0x40, 0x02, 0x84, 0x08, 0x00, 0x04, 0x48, 0x40, 0x90, 0x60, 0x0a, 0x22,
+ 0x01, 0x88, 0x14, 0x08, 0x01, 0x02, 0x08, 0xd3, 0x00, 0x20, 0xc0, 0x90,
+ 0x24, 0x10, 0x00, 0x00, 0x01, 0xb0, 0x08, 0x0a, 0xa0, 0x00, 0x80, 0x00,
+ 0x01, 0x09, 0x00, 0x20, 0x52, 0x02, 0x25, 0x00, 0x24, 0x04, 0x02, 0x84,
+ 0x24, 0x10, 0x92, 0x40, 0x02, 0xa0, 0x40, 0x00, 0x22, 0x08, 0x11, 0x04,
+ 0x08, 0x01, 0x22, 0x00, 0x42, 0x14, 0x00, 0x09, 0x90, 0x21, 0x00, 0x30,
+ 0x6c, 0x00, 0x00, 0x0c, 0x00, 0x22, 0x09, 0x90, 0x10, 0x28, 0x40, 0x00,
+ 0x20, 0xc0, 0x20, 0x00, 0x90, 0x00, 0x40, 0x01, 0x82, 0x05, 0x12, 0x12,
+ 0x09, 0xc1, 0x04, 0x61, 0x80, 0x02, 0x28, 0x81, 0x24, 0x00, 0x49, 0x04,
+ 0x08, 0x10, 0x86, 0x29, 0x41, 0x80, 0x21, 0x0a, 0x30, 0x49, 0x88, 0x90,
+ 0x00, 0x41, 0x04, 0x29, 0x81, 0x80, 0x41, 0x09, 0x00, 0x40, 0x12, 0x10,
+ 0x40, 0x00, 0x10, 0x40, 0x48, 0x02, 0x05, 0x80, 0x02, 0x21, 0x40, 0x20,
+ 0x00, 0x58, 0x20, 0x60, 0x00, 0x90, 0x48, 0x00, 0x80, 0x28, 0xc0, 0x80,
+ 0x48, 0x00, 0x00, 0x44, 0x80, 0x02, 0x00, 0x09, 0x06, 0x00, 0x12, 0x02,
+ 0x01, 0x00, 0x10, 0x08, 0x83, 0x10, 0x45, 0x12, 0x00, 0x2c, 0x08, 0x04,
+ 0x44, 0x00, 0x20, 0x20, 0xc0, 0x10, 0x20, 0x01, 0x00, 0x05, 0xc8, 0x20,
+ 0x04, 0x98, 0x10, 0x08, 0x10, 0x00, 0x24, 0x02, 0x16, 0x40, 0x88, 0x00,
+ 0x61, 0x88, 0x12, 0x24, 0x80, 0xa6, 0x00, 0x42, 0x00, 0x08, 0x10, 0x06,
+ 0x48, 0x40, 0xa0, 0x00, 0x50, 0x20, 0x04, 0x81, 0xa4, 0x40, 0x18, 0x00,
+ 0x08, 0x10, 0x80, 0x01, 0x01};
+#if RSA_KEY_SIEVE && SIMULATION && RSA_INSTRUMENT
+UINT32 PrimeIndex = 0;
+UINT32 failedAtIteration[10] = {0};
+UINT32 PrimeCounts[3] = {0};
+UINT32 MillerRabinTrials[3] = {0};
+UINT32 totalFieldsSieved[3] = {0};
+UINT32 bitsInFieldAfterSieve[3] = {0};
+UINT32 emptyFieldsSieved[3] = {0};
+UINT32 noPrimeFields[3] = {0};
+UINT32 primesChecked[3] = {0};
+UINT16 lastSievePrime = 0;
+#endif
diff --git a/src/tpm2/PropertyCap.c b/src/tpm2/PropertyCap.c
new file mode 100644
index 0000000..db7d679
--- /dev/null
+++ b/src/tpm2/PropertyCap.c
@@ -0,0 +1,610 @@
+/********************************************************************************/
+/* */
+/* For accessing the TPM_CAP_TPM_PROPERTY values */
+/* Written by Ken Goldman */
+/* IBM Thomas J. Watson Research Center */
+/* $Id: PropertyCap.c 1519 2019-11-15 20:43:51Z kgoldman $ */
+/* */
+/* Licenses and Notices */
+/* */
+/* 1. Copyright Licenses: */
+/* */
+/* - Trusted Computing Group (TCG) grants to the user of the source code in */
+/* this specification (the "Source Code") a worldwide, irrevocable, */
+/* nonexclusive, royalty free, copyright license to reproduce, create */
+/* derivative works, distribute, display and perform the Source Code and */
+/* derivative works thereof, and to grant others the rights granted herein. */
+/* */
+/* - The TCG grants to the user of the other parts of the specification */
+/* (other than the Source Code) the rights to reproduce, distribute, */
+/* display, and perform the specification solely for the purpose of */
+/* developing products based on such documents. */
+/* */
+/* 2. Source Code Distribution Conditions: */
+/* */
+/* - Redistributions of Source Code must retain the above copyright licenses, */
+/* this list of conditions and the following disclaimers. */
+/* */
+/* - Redistributions in binary form must reproduce the above copyright */
+/* licenses, this list of conditions and the following disclaimers in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* 3. Disclaimers: */
+/* */
+/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
+/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
+/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
+/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
+/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
+/* information on specification licensing rights available through TCG */
+/* membership agreements. */
+/* */
+/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
+/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
+/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
+/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
+/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
+/* */
+/* - Without limitation, TCG and its members and licensors disclaim all */
+/* liability, including liability for infringement of any proprietary */
+/* rights, relating to use of information in this specification and to the */
+/* implementation of this specification, and TCG disclaims all liability for */
+/* cost of procurement of substitute goods or services, lost profits, loss */
+/* of use, loss of data or any incidental, consequential, direct, indirect, */
+/* or special damages, whether under contract, tort, warranty or otherwise, */
+/* arising in any way out of use or reliance upon this specification or any */
+/* information herein. */
+/* */
+/* (c) Copyright IBM Corp. and others, 2016 - 2019 */
+/* */
+/********************************************************************************/
+
+/* 9.14 PropertyCap.c */
+/* 9.14.1 Description */
+/* This file contains the functions that are used for accessing the TPM_CAP_TPM_PROPERTY values. */
+/* 9.14.2 Includes */
+#include "Tpm.h"
+
+#define TPM_HAVE_TPM2_DECLARATIONS
+#include "tpm_library_intern.h" // libtpms added
+/* 9.14.3 Functions */
+/* 9.14.3.1 TPMPropertyIsDefined() */
+/* This function accepts a property selection and, if so, sets value to the value of the
+ property. */
+/* All the fixed values are vendor dependent or determined by a platform-specific specification. The
+ values in the table below are examples and should be changed by the vendor. */
+/* Return Values Meaning */
+/* TRUE referenced property exists and value set */
+/* FALSE referenced property does not exist */
+static BOOL
+TPMPropertyIsDefined(
+ TPM_PT property, // IN: property
+ UINT32 *value // OUT: property value
+ )
+{
+ switch(property)
+ {
+ case TPM_PT_FAMILY_INDICATOR:
+ // from the title page of the specification
+ // For this specification, the value is "2.0".
+ *value = TPM_SPEC_FAMILY;
+ break;
+ case TPM_PT_LEVEL:
+ // from the title page of the specification
+ *value = TPM_SPEC_LEVEL;
+ break;
+ case TPM_PT_REVISION:
+ // from the title page of the specification
+ *value = TPM_SPEC_VERSION;
+ break;
+ case TPM_PT_DAY_OF_YEAR:
+ // computed from the date value on the title page of the specification
+ *value = TPM_SPEC_DAY_OF_YEAR;
+ break;
+ case TPM_PT_YEAR:
+ // from the title page of the specification
+ *value = TPM_SPEC_YEAR;
+ break;
+ case TPM_PT_MANUFACTURER:
+ // vendor ID unique to each TPM manufacturer
+ *value = BYTE_ARRAY_TO_UINT32(MANUFACTURER);
+ break;
+ case TPM_PT_VENDOR_STRING_1:
+ // first four characters of the vendor ID string
+ *value = BYTE_ARRAY_TO_UINT32(VENDOR_STRING_1);
+ break;
+ case TPM_PT_VENDOR_STRING_2:
+ // second four characters of the vendor ID string
+#ifdef VENDOR_STRING_2
+ *value = BYTE_ARRAY_TO_UINT32(VENDOR_STRING_2);
+#else
+ *value = 0;
+#endif
+ break;
+ case TPM_PT_VENDOR_STRING_3:
+ // third four characters of the vendor ID string
+#ifdef VENDOR_STRING_3
+ *value = BYTE_ARRAY_TO_UINT32(VENDOR_STRING_3);
+#else
+ *value = 0;
+#endif
+ break;
+ case TPM_PT_VENDOR_STRING_4:
+ // fourth four characters of the vendor ID string
+#ifdef VENDOR_STRING_4
+ *value = BYTE_ARRAY_TO_UINT32(VENDOR_STRING_4);
+#else
+ *value = 0;
+#endif
+ break;
+ case TPM_PT_VENDOR_TPM_TYPE:
+ // vendor-defined value indicating the TPM model
+ *value = 1;
+ break;
+ case TPM_PT_FIRMWARE_VERSION_1:
+ // more significant 32-bits of a vendor-specific value
+ *value = gp.firmwareV1;
+ break;
+ case TPM_PT_FIRMWARE_VERSION_2:
+ // less significant 32-bits of a vendor-specific value
+ *value = gp.firmwareV2;
+ break;
+ case TPM_PT_INPUT_BUFFER:
+ // maximum size of TPM2B_MAX_BUFFER
+ *value = MAX_DIGEST_BUFFER;
+ break;
+ case TPM_PT_HR_TRANSIENT_MIN:
+ // minimum number of transient objects that can be held in TPM
+ // RAM
+ *value = MAX_LOADED_OBJECTS;
+ break;
+ case TPM_PT_HR_PERSISTENT_MIN:
+ // minimum number of persistent objects that can be held in
+ // TPM NV memory
+ // In this implementation, there is no minimum number of
+ // persistent objects.
+ *value = MIN_EVICT_OBJECTS;
+ break;
+ case TPM_PT_HR_LOADED_MIN:
+ // minimum number of authorization sessions that can be held in
+ // TPM RAM
+ *value = MAX_LOADED_SESSIONS;
+ break;
+ case TPM_PT_ACTIVE_SESSIONS_MAX:
+ // number of authorization sessions that may be active at a time
+ *value = MAX_ACTIVE_SESSIONS;
+ break;
+ case TPM_PT_PCR_COUNT:
+ // number of PCR implemented
+ *value = IMPLEMENTATION_PCR;
+ break;
+ case TPM_PT_PCR_SELECT_MIN:
+ // minimum number of bytes in a TPMS_PCR_SELECT.sizeOfSelect
+ *value = PCR_SELECT_MIN;
+ break;
+ case TPM_PT_CONTEXT_GAP_MAX:
+ // maximum allowed difference (unsigned) between the contextID
+ // values of two saved session contexts
+#if 0
+ *value = ((UINT32)1 << (sizeof(CONTEXT_SLOT) * 8)) - 1;
+#endif
+ *value = s_ContextSlotMask; // libtpms added; the mask is either 0xff (old state) or 0xffff
+ break;
+ case TPM_PT_NV_COUNTERS_MAX:
+ // maximum number of NV indexes that are allowed to have the
+ // TPMA_NV_COUNTER attribute SET
+ // In this implementation, there is no limitation on the number
+ // of counters, except for the size of the NV Index memory.
+ *value = 0;
+ break;
+ case TPM_PT_NV_INDEX_MAX:
+ // maximum size of an NV index data area
+ *value = MAX_NV_INDEX_SIZE;
+ break;
+ case TPM_PT_MEMORY:
+ // a TPMA_MEMORY indicating the memory management method for the TPM
+ {
+ union
+ {
+ TPMA_MEMORY att;
+ UINT32 u32;
+ } attributes = { TPMA_ZERO_INITIALIZER() };
+ SET_ATTRIBUTE(attributes.att, TPMA_MEMORY, sharedNV);
+ SET_ATTRIBUTE(attributes.att, TPMA_MEMORY, objectCopiedToRam);
+ // Note: For a LSb0 machine, the bits in a bit field are in the correct
+ // order even if the machine is MSB0. For a MSb0 machine, a TPMA will
+ // be an integer manipulated by masking (USE_BIT_FIELD_STRUCTURES will
+ // NO) so the bits are manipulated correctly.
+ *value = attributes.u32;
+ break;
+ }
+ case TPM_PT_CLOCK_UPDATE:
+ // interval, in seconds, between updates to the copy of
+ // TPMS_TIME_INFO .clock in NV
+ *value = (1 << NV_CLOCK_UPDATE_INTERVAL);
+ break;
+ case TPM_PT_CONTEXT_HASH:
+ // algorithm used for the integrity hash on saved contexts and
+ // for digesting the fuData of TPM2_FirmwareRead()
+ *value = CONTEXT_INTEGRITY_HASH_ALG;
+ break;
+ case TPM_PT_CONTEXT_SYM:
+ // algorithm used for encryption of saved contexts
+ *value = CONTEXT_ENCRYPT_ALG;
+ break;
+ case TPM_PT_CONTEXT_SYM_SIZE:
+ // size of the key used for encryption of saved contexts
+ *value = CONTEXT_ENCRYPT_KEY_BITS;
+ break;
+ case TPM_PT_ORDERLY_COUNT:
+ // maximum difference between the volatile and non-volatile
+ // versions of TPMA_NV_COUNTER that have TPMA_NV_ORDERLY SET
+ *value = MAX_ORDERLY_COUNT;
+ break;
+ case TPM_PT_MAX_COMMAND_SIZE:
+ // maximum value for 'commandSize'
+ *value = MAX_COMMAND_SIZE;
+ break;
+ case TPM_PT_MAX_RESPONSE_SIZE:
+ // maximum value for 'responseSize'
+ *value = MAX_RESPONSE_SIZE;
+ break;
+ case TPM_PT_MAX_DIGEST:
+ // maximum size of a digest that can be produced by the TPM
+ *value = sizeof(TPMU_HA);
+ break;
+ case TPM_PT_MAX_OBJECT_CONTEXT:
+ // Header has 'sequence', 'handle' and 'hierarchy'
+#define SIZE_OF_CONTEXT_HEADER \
+ sizeof(UINT64) + sizeof(TPMI_DH_CONTEXT) + sizeof(TPMI_RH_HIERARCHY)
+#define SIZE_OF_CONTEXT_INTEGRITY (sizeof(UINT16) + CONTEXT_INTEGRITY_HASH_SIZE)
+#define SIZE_OF_FINGERPRINT sizeof(UINT64)
+#define SIZE_OF_CONTEXT_BLOB_OVERHEAD \
+ (sizeof(UINT16) + SIZE_OF_CONTEXT_INTEGRITY + SIZE_OF_FINGERPRINT)
+#define SIZE_OF_CONTEXT_OVERHEAD \
+ (SIZE_OF_CONTEXT_HEADER + SIZE_OF_CONTEXT_BLOB_OVERHEAD)
+#if 0
+ // maximum size of a TPMS_CONTEXT that will be returned by
+ // TPM2_ContextSave for object context
+ *value = 0;
+ // adding sequence, saved handle and hierarchy
+ *value += sizeof(UINT64) + sizeof(TPMI_DH_CONTEXT) +
+ sizeof(TPMI_RH_HIERARCHY);
+ // add size field in TPM2B_CONTEXT
+ *value += sizeof(UINT16);
+ // add integrity hash size
+ *value += sizeof(UINT16) +
+ CryptHashGetDigestSize(CONTEXT_INTEGRITY_HASH_ALG);
+ // Add fingerprint size, which is the same as sequence size
+ *value += sizeof(UINT64);
+ // Add OBJECT structure size
+ *value += sizeof(OBJECT);
+#else
+ // the maximum size of a TPMS_CONTEXT that will be returned by
+ // TPM2_ContextSave for object context
+ *value = SIZE_OF_CONTEXT_OVERHEAD + sizeof(OBJECT);
+#endif
+ break;
+ case TPM_PT_MAX_SESSION_CONTEXT:
+#if 0
+ // the maximum size of a TPMS_CONTEXT that will be returned by
+ // TPM2_ContextSave for object context
+ *value = 0;
+ // adding sequence, saved handle and hierarchy
+ *value += sizeof(UINT64) + sizeof(TPMI_DH_CONTEXT) +
+ sizeof(TPMI_RH_HIERARCHY);
+ // Add size field in TPM2B_CONTEXT
+ *value += sizeof(UINT16);
+ // Add integrity hash size
+ *value += sizeof(UINT16) +
+ CryptHashGetDigestSize(CONTEXT_INTEGRITY_HASH_ALG);
+ // Add fingerprint size, which is the same as sequence size
+ *value += sizeof(UINT64);
+ // Add SESSION structure size
+ *value += sizeof(SESSION);
+#else
+ // the maximum size of a TPMS_CONTEXT that will be returned by
+ // TPM2_ContextSave for object context
+ *value = SIZE_OF_CONTEXT_OVERHEAD + sizeof(SESSION);
+#endif
+ break;
+ case TPM_PT_PS_FAMILY_INDICATOR:
+ // platform specific values for the TPM_PT_PS parameters from
+ // the relevant platform-specific specification
+ // In this reference implementation, all of these values are 0.
+ *value = PLATFORM_FAMILY;
+ break;
+ case TPM_PT_PS_LEVEL:
+ // level of the platform-specific specification
+ *value = PLATFORM_LEVEL;
+ break;
+ case TPM_PT_PS_REVISION:
+ // specification Revision times 100 for the platform-specific
+ // specification
+ *value = PLATFORM_VERSION;
+ break;
+ case TPM_PT_PS_DAY_OF_YEAR:
+ // platform-specific specification day of year using TCG calendar
+ *value = PLATFORM_DAY_OF_YEAR;
+ break;
+ case TPM_PT_PS_YEAR:
+ // platform-specific specification year using the CE
+ *value = PLATFORM_YEAR;
+ break;
+ case TPM_PT_SPLIT_MAX:
+ // number of split signing operations supported by the TPM
+ *value = 0;
+#if ALG_ECC
+ *value = sizeof(gr.commitArray) * 8;
+#endif
+ break;
+ case TPM_PT_TOTAL_COMMANDS:
+ // total number of commands implemented in the TPM
+ // Since the reference implementation does not have any
+ // vendor-defined commands, this will be the same as the
+ // number of library commands.
+ {
+#if COMPRESSED_LISTS
+ (*value) = COMMAND_COUNT;
+#else
+ COMMAND_INDEX commandIndex;
+ *value = 0;
+ // scan all implemented commands
+ for(commandIndex = GetClosestCommandIndex(0);
+ commandIndex != UNIMPLEMENTED_COMMAND_INDEX;
+ commandIndex = GetNextCommandIndex(commandIndex))
+ {
+ (*value)++; // count of all implemented
+ }
+#endif
+ break;
+ }
+ case TPM_PT_LIBRARY_COMMANDS:
+ // number of commands from the TPM library that are implemented
+ {
+#if COMPRESSED_LISTS
+ *value = LIBRARY_COMMAND_ARRAY_SIZE;
+#else
+ COMMAND_INDEX commandIndex;
+ *value = 0;
+ // scan all implemented commands
+ for(commandIndex = GetClosestCommandIndex(0);
+ commandIndex < LIBRARY_COMMAND_ARRAY_SIZE;
+ commandIndex = GetNextCommandIndex(commandIndex))
+ {
+ (*value)++;
+ }
+#endif
+ break;
+ }
+ case TPM_PT_VENDOR_COMMANDS:
+ // number of vendor commands that are implemented
+ *value = VENDOR_COMMAND_ARRAY_SIZE;
+ break;
+ case TPM_PT_NV_BUFFER_MAX:
+ // Maximum data size in an NV write command
+ *value = MAX_NV_BUFFER_SIZE;
+ break;
+ case TPM_PT_MODES:
+#if FIPS_COMPLIANT
+ *value = 1;
+#else
+ *value = 0;
+#endif
+ break;
+ case TPM_PT_MAX_CAP_BUFFER:
+ *value = MAX_CAP_BUFFER;
+ break;
+ // Start of variable commands
+ case TPM_PT_PERMANENT:
+ // TPMA_PERMANENT
+ {
+ union {
+ TPMA_PERMANENT attr;
+ UINT32 u32;
+ } flags = { TPMA_ZERO_INITIALIZER() };
+ if(gp.ownerAuth.t.size != 0)
+ SET_ATTRIBUTE(flags.attr, TPMA_PERMANENT, ownerAuthSet);
+ if(gp.endorsementAuth.t.size != 0)
+ SET_ATTRIBUTE(flags.attr, TPMA_PERMANENT, endorsementAuthSet);
+ if(gp.lockoutAuth.t.size != 0)
+ SET_ATTRIBUTE(flags.attr, TPMA_PERMANENT, lockoutAuthSet);
+ if(gp.disableClear)
+ SET_ATTRIBUTE(flags.attr, TPMA_PERMANENT, disableClear);
+ if(gp.failedTries >= gp.maxTries)
+ SET_ATTRIBUTE(flags.attr, TPMA_PERMANENT, inLockout);
+ // In this implementation, EPS is always generated by TPM
+ SET_ATTRIBUTE(flags.attr, TPMA_PERMANENT, tpmGeneratedEPS);
+ // Note: For a LSb0 machine, the bits in a bit field are in the correct
+ // order even if the machine is MSB0. For a MSb0 machine, a TPMA will
+ // be an integer manipulated by masking (USE_BIT_FIELD_STRUCTURES will
+ // be NO ) so the bits are manipulate correctly.
+ *value = flags.u32;
+ break;
+ }
+ case TPM_PT_STARTUP_CLEAR:
+ // TPMA_STARTUP_CLEAR
+ {
+ union {
+ TPMA_STARTUP_CLEAR attr;
+ UINT32 u32;
+ } flags = { TPMA_ZERO_INITIALIZER() };
+ //
+ if(g_phEnable)
+ SET_ATTRIBUTE(flags.attr, TPMA_STARTUP_CLEAR, phEnable);
+ if(gc.shEnable)
+ SET_ATTRIBUTE(flags.attr, TPMA_STARTUP_CLEAR, shEnable);
+ if(gc.ehEnable)
+ SET_ATTRIBUTE(flags.attr, TPMA_STARTUP_CLEAR, ehEnable);
+ if(gc.phEnableNV)
+ SET_ATTRIBUTE(flags.attr, TPMA_STARTUP_CLEAR, phEnableNV);
+ if(g_prevOrderlyState != SU_NONE_VALUE)
+ SET_ATTRIBUTE(flags.attr, TPMA_STARTUP_CLEAR, orderly);
+ // Note: For a LSb0 machine, the bits in a bit field are in the correct
+ // order even if the machine is MSB0. For a MSb0 machine, a TPMA will
+ // be an integer manipulated by masking (USE_BIT_FIELD_STRUCTURES will
+ // be NO) so the bits are manipulate correctly.
+ *value = flags.u32;
+ break;
+ }
+ case TPM_PT_HR_NV_INDEX:
+ // number of NV indexes currently defined
+ *value = NvCapGetIndexNumber();
+ break;
+ case TPM_PT_HR_LOADED:
+ // number of authorization sessions currently loaded into TPM
+ // RAM
+ *value = SessionCapGetLoadedNumber();
+ break;
+ case TPM_PT_HR_LOADED_AVAIL:
+ // number of additional authorization sessions, of any type,
+ // that could be loaded into TPM RAM
+ *value = SessionCapGetLoadedAvail();
+ break;
+ case TPM_PT_HR_ACTIVE:
+ // number of active authorization sessions currently being
+ // tracked by the TPM
+ *value = SessionCapGetActiveNumber();
+ break;
+ case TPM_PT_HR_ACTIVE_AVAIL:
+ // number of additional authorization sessions, of any type,
+ // that could be created
+ *value = SessionCapGetActiveAvail();
+ break;
+ case TPM_PT_HR_TRANSIENT_AVAIL:
+ // estimate of the number of additional transient objects that
+ // could be loaded into TPM RAM
+ *value = ObjectCapGetTransientAvail();
+ break;
+ case TPM_PT_HR_PERSISTENT:
+ // number of persistent objects currently loaded into TPM
+ // NV memory
+ *value = NvCapGetPersistentNumber();
+ break;
+ case TPM_PT_HR_PERSISTENT_AVAIL:
+ // number of additional persistent objects that could be loaded
+ // into NV memory
+ *value = NvCapGetPersistentAvail();
+ break;
+ case TPM_PT_NV_COUNTERS:
+ // number of defined NV indexes that have NV TPMA_NV_COUNTER
+ // attribute SET
+ *value = NvCapGetCounterNumber();
+ break;
+ case TPM_PT_NV_COUNTERS_AVAIL:
+ // number of additional NV indexes that can be defined with their
+ // TPMA_NV_COUNTER attribute SET
+ *value = NvCapGetCounterAvail();
+ break;
+ case TPM_PT_ALGORITHM_SET:
+ // region code for the TPM
+ *value = gp.algorithmSet;
+ break;
+ case TPM_PT_LOADED_CURVES:
+#if ALG_ECC
+ // number of loaded ECC curves
+ *value = ECC_CURVE_COUNT;
+#else // ALG_ECC
+ *value = 0;
+#endif // ALG_ECC
+ break;
+ case TPM_PT_LOCKOUT_COUNTER:
+ // current value of the lockout counter
+ *value = gp.failedTries;
+ break;
+ case TPM_PT_MAX_AUTH_FAIL:
+ // number of authorization failures before DA lockout is invoked
+ *value = gp.maxTries;
+ break;
+ case TPM_PT_LOCKOUT_INTERVAL:
+ // number of seconds before the value reported by
+ // TPM_PT_LOCKOUT_COUNTER is decremented
+ *value = gp.recoveryTime;
+ break;
+ case TPM_PT_LOCKOUT_RECOVERY:
+ // number of seconds after a lockoutAuth failure before use of
+ // lockoutAuth may be attempted again
+ *value = gp.lockoutRecovery;
+ break;
+ case TPM_PT_NV_WRITE_RECOVERY:
+ // number of milliseconds before the TPM will accept another command
+ // that will modify NV.
+ // This should make a call to the platform code that is doing rate
+ // limiting of NV. Rate limiting is not implemented in the reference
+ // code so no call is made.
+ *value = 0;
+ break;
+ case TPM_PT_AUDIT_COUNTER_0:
+ // high-order 32 bits of the command audit counter
+ *value = (UINT32)(gp.auditCounter >> 32);
+ break;
+ case TPM_PT_AUDIT_COUNTER_1:
+ // low-order 32 bits of the command audit counter
+ *value = (UINT32)(gp.auditCounter);
+ break;
+ default:
+ // property is not defined
+ return FALSE;
+ break;
+ }
+ return TRUE;
+}
+/* 9.14.3.2 TPMCapGetProperties() */
+/* This function is used to get the TPM_PT values. The search of properties will start at property
+ and continue until propertyList has as many values as will fit, or the last property has been
+ reported, or the list has as many values as requested in count. */
+/* Return Values Meaning */
+/* YES more properties are available */
+/* NO no more properties to be reported */
+TPMI_YES_NO
+TPMCapGetProperties(
+ TPM_PT property, // IN: the starting TPM property
+ UINT32 count, // IN: maximum number of returned
+ // properties
+ TPML_TAGGED_TPM_PROPERTY *propertyList // OUT: property list
+ )
+{
+ TPMI_YES_NO more = NO;
+ UINT32 i;
+ UINT32 nextGroup;
+ // initialize output property list
+ propertyList->count = 0;
+ // maximum count of properties we may return is MAX_PCR_PROPERTIES
+ if(count > MAX_TPM_PROPERTIES) count = MAX_TPM_PROPERTIES;
+ // if property is less than PT_FIXED, start from PT_FIXED
+ if(property < PT_FIXED)
+ property = PT_FIXED;
+ // There is only the fixed and variable groups with the variable group coming
+ // last
+ if(property >= (PT_VAR + PT_GROUP))
+ return more;
+ // Don't read past the end of the selected group
+ nextGroup = ((property / PT_GROUP) * PT_GROUP) + PT_GROUP;
+ // Scan through the TPM properties of the requested group.
+ for(i = property; i < nextGroup; i++)
+ {
+ UINT32 value;
+ // if we have hit the end of the group, quit
+ if(i != property && ((i % PT_GROUP) == 0))
+ break;
+ if(TPMPropertyIsDefined((TPM_PT)i, &value))
+ {
+ if(propertyList->count < count)
+ {
+ // If the list is not full, add this property
+ propertyList->tpmProperty[propertyList->count].property =
+ (TPM_PT)i;
+ propertyList->tpmProperty[propertyList->count].value = value;
+ propertyList->count++;
+ }
+ else
+ {
+ // If the return list is full but there are more properties
+ // available, set the indication and exit the loop.
+ more = YES;
+ break;
+ }
+ }
+ }
+ return more;
+}
diff --git a/src/tpm2/PropertyCap_fp.h b/src/tpm2/PropertyCap_fp.h
new file mode 100644
index 0000000..b827963
--- /dev/null
+++ b/src/tpm2/PropertyCap_fp.h
@@ -0,0 +1,74 @@
+/********************************************************************************/
+/* */
+/* */
+/* Written by Ken Goldman */
+/* IBM Thomas J. Watson Research Center */
+/* $Id: PropertyCap_fp.h 1490 2019-07-26 21:13:22Z kgoldman $ */
+/* */
+/* Licenses and Notices */
+/* */
+/* 1. Copyright Licenses: */
+/* */
+/* - Trusted Computing Group (TCG) grants to the user of the source code in */
+/* this specification (the "Source Code") a worldwide, irrevocable, */
+/* nonexclusive, royalty free, copyright license to reproduce, create */
+/* derivative works, distribute, display and perform the Source Code and */
+/* derivative works thereof, and to grant others the rights granted herein. */
+/* */
+/* - The TCG grants to the user of the other parts of the specification */
+/* (other than the Source Code) the rights to reproduce, distribute, */
+/* display, and perform the specification solely for the purpose of */
+/* developing products based on such documents. */
+/* */
+/* 2. Source Code Distribution Conditions: */
+/* */
+/* - Redistributions of Source Code must retain the above copyright licenses, */
+/* this list of conditions and the following disclaimers. */
+/* */
+/* - Redistributions in binary form must reproduce the above copyright */
+/* licenses, this list of conditions and the following disclaimers in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* 3. Disclaimers: */
+/* */
+/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
+/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
+/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
+/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
+/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
+/* information on specification licensing rights available through TCG */
+/* membership agreements. */
+/* */
+/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
+/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
+/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
+/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
+/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
+/* */
+/* - Without limitation, TCG and its members and licensors disclaim all */
+/* liability, including liability for infringement of any proprietary */
+/* rights, relating to use of information in this specification and to the */
+/* implementation of this specification, and TCG disclaims all liability for */
+/* cost of procurement of substitute goods or services, lost profits, loss */
+/* of use, loss of data or any incidental, consequential, direct, indirect, */
+/* or special damages, whether under contract, tort, warranty or otherwise, */
+/* arising in any way out of use or reliance upon this specification or any */
+/* information herein. */
+/* */
+/* (c) Copyright IBM Corp. and others, 2016 */
+/* */
+/********************************************************************************/
+
+#ifndef PROPERTYCAP_FP_H
+#define PROPERTYCAP_FP_H
+
+TPMI_YES_NO
+TPMCapGetProperties(
+ TPM_PT property, // IN: the starting TPM property
+ UINT32 count, // IN: maximum number of returned
+ // properties
+ TPML_TAGGED_TPM_PROPERTY *propertyList // OUT: property list
+ );
+
+
+#endif
diff --git a/src/tpm2/Quote_fp.h b/src/tpm2/Quote_fp.h
new file mode 100644
index 0000000..b347f2f
--- /dev/null
+++ b/src/tpm2/Quote_fp.h
@@ -0,0 +1,91 @@
+/********************************************************************************/
+/* */
+/* */
+/* Written by Ken Goldman */
+/* IBM Thomas J. Watson Research Center */
+/* $Id: Quote_fp.h 809 2016-11-16 18:31:54Z kgoldman $ */
+/* */
+/* Licenses and Notices */
+/* */
+/* 1. Copyright Licenses: */
+/* */
+/* - Trusted Computing Group (TCG) grants to the user of the source code in */
+/* this specification (the "Source Code") a worldwide, irrevocable, */
+/* nonexclusive, royalty free, copyright license to reproduce, create */
+/* derivative works, distribute, display and perform the Source Code and */
+/* derivative works thereof, and to grant others the rights granted herein. */
+/* */
+/* - The TCG grants to the user of the other parts of the specification */
+/* (other than the Source Code) the rights to reproduce, distribute, */
+/* display, and perform the specification solely for the purpose of */
+/* developing products based on such documents. */
+/* */
+/* 2. Source Code Distribution Conditions: */
+/* */
+/* - Redistributions of Source Code must retain the above copyright licenses, */
+/* this list of conditions and the following disclaimers. */
+/* */
+/* - Redistributions in binary form must reproduce the above copyright */
+/* licenses, this list of conditions and the following disclaimers in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* 3. Disclaimers: */
+/* */
+/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
+/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
+/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
+/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
+/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
+/* information on specification licensing rights available through TCG */
+/* membership agreements. */
+/* */
+/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
+/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
+/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
+/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
+/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
+/* */
+/* - Without limitation, TCG and its members and licensors disclaim all */
+/* liability, including liability for infringement of any proprietary */
+/* rights, relating to use of information in this specification and to the */
+/* implementation of this specification, and TCG disclaims all liability for */
+/* cost of procurement of substitute goods or services, lost profits, loss */
+/* of use, loss of data or any incidental, consequential, direct, indirect, */
+/* or special damages, whether under contract, tort, warranty or otherwise, */
+/* arising in any way out of use or reliance upon this specification or any */
+/* information herein. */
+/* */
+/* (c) Copyright IBM Corp. and others, 2012-2015 */
+/* */
+/********************************************************************************/
+
+/* rev 119 */
+
+#ifndef QUOTE_FP_H
+#define QUOTE_FP_H
+
+typedef struct {
+ TPMI_DH_OBJECT signHandle;
+ TPM2B_DATA qualifyingData;
+ TPMT_SIG_SCHEME inScheme;
+ TPML_PCR_SELECTION PCRselect;
+} Quote_In;
+
+#define RC_Quote_signHandle (TPM_RC_H + TPM_RC_1)
+#define RC_Quote_qualifyingData (TPM_RC_P + TPM_RC_1)
+#define RC_Quote_inScheme (TPM_RC_P + TPM_RC_2)
+#define RC_Quote_PCRselect (TPM_RC_P + TPM_RC_3)
+
+typedef struct {
+ TPM2B_ATTEST quoted;
+ TPMT_SIGNATURE signature;
+} Quote_Out;
+
+TPM_RC
+TPM2_Quote(
+ Quote_In *in, // IN: input parameter list
+ Quote_Out *out // OUT: output parameter list
+ );
+
+
+#endif
diff --git a/src/tpm2/RSA_Decrypt_fp.h b/src/tpm2/RSA_Decrypt_fp.h
new file mode 100644
index 0000000..1f58395
--- /dev/null
+++ b/src/tpm2/RSA_Decrypt_fp.h
@@ -0,0 +1,90 @@
+/********************************************************************************/
+/* */
+/* */
+/* Written by Ken Goldman */
+/* IBM Thomas J. Watson Research Center */
+/* $Id: RSA_Decrypt_fp.h 809 2016-11-16 18:31:54Z kgoldman $ */
+/* */
+/* Licenses and Notices */
+/* */
+/* 1. Copyright Licenses: */
+/* */
+/* - Trusted Computing Group (TCG) grants to the user of the source code in */
+/* this specification (the "Source Code") a worldwide, irrevocable, */
+/* nonexclusive, royalty free, copyright license to reproduce, create */
+/* derivative works, distribute, display and perform the Source Code and */
+/* derivative works thereof, and to grant others the rights granted herein. */
+/* */
+/* - The TCG grants to the user of the other parts of the specification */
+/* (other than the Source Code) the rights to reproduce, distribute, */
+/* display, and perform the specification solely for the purpose of */
+/* developing products based on such documents. */
+/* */
+/* 2. Source Code Distribution Conditions: */
+/* */
+/* - Redistributions of Source Code must retain the above copyright licenses, */
+/* this list of conditions and the following disclaimers. */
+/* */
+/* - Redistributions in binary form must reproduce the above copyright */
+/* licenses, this list of conditions and the following disclaimers in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* 3. Disclaimers: */
+/* */
+/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
+/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
+/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
+/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
+/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
+/* information on specification licensing rights available through TCG */
+/* membership agreements. */
+/* */
+/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
+/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
+/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
+/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
+/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
+/* */
+/* - Without limitation, TCG and its members and licensors disclaim all */
+/* liability, including liability for infringement of any proprietary */
+/* rights, relating to use of information in this specification and to the */
+/* implementation of this specification, and TCG disclaims all liability for */
+/* cost of procurement of substitute goods or services, lost profits, loss */
+/* of use, loss of data or any incidental, consequential, direct, indirect, */
+/* or special damages, whether under contract, tort, warranty or otherwise, */
+/* arising in any way out of use or reliance upon this specification or any */
+/* information herein. */
+/* */
+/* (c) Copyright IBM Corp. and others, 2012-2015 */
+/* */
+/********************************************************************************/
+
+/* rev 119 */
+
+#ifndef RSA_DECRYPT_FP_H
+#define RSA_DECRYPT_FP_H
+
+typedef struct {
+ TPMI_DH_OBJECT keyHandle;
+ TPM2B_PUBLIC_KEY_RSA cipherText;
+ TPMT_RSA_DECRYPT inScheme;
+ TPM2B_DATA label;
+} RSA_Decrypt_In;
+
+#define RC_RSA_Decrypt_keyHandle (TPM_RC_H + TPM_RC_1)
+#define RC_RSA_Decrypt_cipherText (TPM_RC_P + TPM_RC_1)
+#define RC_RSA_Decrypt_inScheme (TPM_RC_P + TPM_RC_2)
+#define RC_RSA_Decrypt_label (TPM_RC_P + TPM_RC_3)
+
+typedef struct {
+ TPM2B_PUBLIC_KEY_RSA message;
+} RSA_Decrypt_Out;
+
+TPM_RC
+TPM2_RSA_Decrypt(
+ RSA_Decrypt_In *in, // IN: input parameter list
+ RSA_Decrypt_Out *out // OUT: output parameter list
+ );
+
+
+#endif
diff --git a/src/tpm2/RSA_Encrypt_fp.h b/src/tpm2/RSA_Encrypt_fp.h
new file mode 100644
index 0000000..a1f0373
--- /dev/null
+++ b/src/tpm2/RSA_Encrypt_fp.h
@@ -0,0 +1,89 @@
+/********************************************************************************/
+/* */
+/* */
+/* Written by Ken Goldman */
+/* IBM Thomas J. Watson Research Center */
+/* $Id: RSA_Encrypt_fp.h 809 2016-11-16 18:31:54Z kgoldman $ */
+/* */
+/* Licenses and Notices */
+/* */
+/* 1. Copyright Licenses: */
+/* */
+/* - Trusted Computing Group (TCG) grants to the user of the source code in */
+/* this specification (the "Source Code") a worldwide, irrevocable, */
+/* nonexclusive, royalty free, copyright license to reproduce, create */
+/* derivative works, distribute, display and perform the Source Code and */
+/* derivative works thereof, and to grant others the rights granted herein. */
+/* */
+/* - The TCG grants to the user of the other parts of the specification */
+/* (other than the Source Code) the rights to reproduce, distribute, */
+/* display, and perform the specification solely for the purpose of */
+/* developing products based on such documents. */
+/* */
+/* 2. Source Code Distribution Conditions: */
+/* */
+/* - Redistributions of Source Code must retain the above copyright licenses, */
+/* this list of conditions and the following disclaimers. */
+/* */
+/* - Redistributions in binary form must reproduce the above copyright */
+/* licenses, this list of conditions and the following disclaimers in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* 3. Disclaimers: */
+/* */
+/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
+/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
+/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
+/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
+/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
+/* information on specification licensing rights available through TCG */
+/* membership agreements. */
+/* */
+/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
+/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
+/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
+/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
+/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
+/* */
+/* - Without limitation, TCG and its members and licensors disclaim all */
+/* liability, including liability for infringement of any proprietary */
+/* rights, relating to use of information in this specification and to the */
+/* implementation of this specification, and TCG disclaims all liability for */
+/* cost of procurement of substitute goods or services, lost profits, loss */
+/* of use, loss of data or any incidental, consequential, direct, indirect, */
+/* or special damages, whether under contract, tort, warranty or otherwise, */
+/* arising in any way out of use or reliance upon this specification or any */
+/* information herein. */
+/* */
+/* (c) Copyright IBM Corp. and others, 2012-2015 */
+/* */
+/********************************************************************************/
+
+/* rev 119 */
+
+#ifndef RSA_ENCRYPT_FP_H
+#define RSA_ENCRYPT_FP_H
+
+typedef struct {
+ TPMI_DH_OBJECT keyHandle;
+ TPM2B_PUBLIC_KEY_RSA message;
+ TPMT_RSA_DECRYPT inScheme;
+ TPM2B_DATA label;
+} RSA_Encrypt_In;
+
+#define RC_RSA_Encrypt_keyHandle (TPM_RC_H + TPM_RC_1)
+#define RC_RSA_Encrypt_message (TPM_RC_P + TPM_RC_1)
+#define RC_RSA_Encrypt_inScheme (TPM_RC_P + TPM_RC_2)
+#define RC_RSA_Encrypt_label (TPM_RC_P + TPM_RC_3)
+
+typedef struct {
+ TPM2B_PUBLIC_KEY_RSA outData;
+} RSA_Encrypt_Out;
+
+TPM_RC
+TPM2_RSA_Encrypt(
+ RSA_Encrypt_In *in, // IN: input parameter list
+ RSA_Encrypt_Out *out // OUT: output parameter list
+ );
+
+#endif
diff --git a/src/tpm2/RandomCommands.c b/src/tpm2/RandomCommands.c
new file mode 100644
index 0000000..b6573a5
--- /dev/null
+++ b/src/tpm2/RandomCommands.c
@@ -0,0 +1,94 @@
+/********************************************************************************/
+/* */
+/* */
+/* Written by Ken Goldman */
+/* IBM Thomas J. Watson Research Center */
+/* $Id: RandomCommands.c 1490 2019-07-26 21:13:22Z kgoldman $ */
+/* */
+/* Licenses and Notices */
+/* */
+/* 1. Copyright Licenses: */
+/* */
+/* - Trusted Computing Group (TCG) grants to the user of the source code in */
+/* this specification (the "Source Code") a worldwide, irrevocable, */
+/* nonexclusive, royalty free, copyright license to reproduce, create */
+/* derivative works, distribute, display and perform the Source Code and */
+/* derivative works thereof, and to grant others the rights granted herein. */
+/* */
+/* - The TCG grants to the user of the other parts of the specification */
+/* (other than the Source Code) the rights to reproduce, distribute, */
+/* display, and perform the specification solely for the purpose of */
+/* developing products based on such documents. */
+/* */
+/* 2. Source Code Distribution Conditions: */
+/* */
+/* - Redistributions of Source Code must retain the above copyright licenses, */
+/* this list of conditions and the following disclaimers. */
+/* */
+/* - Redistributions in binary form must reproduce the above copyright */
+/* licenses, this list of conditions and the following disclaimers in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* 3. Disclaimers: */
+/* */
+/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
+/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
+/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
+/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
+/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
+/* information on specification licensing rights available through TCG */
+/* membership agreements. */
+/* */
+/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
+/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
+/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
+/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
+/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
+/* */
+/* - Without limitation, TCG and its members and licensors disclaim all */
+/* liability, including liability for infringement of any proprietary */
+/* rights, relating to use of information in this specification and to the */
+/* implementation of this specification, and TCG disclaims all liability for */
+/* cost of procurement of substitute goods or services, lost profits, loss */
+/* of use, loss of data or any incidental, consequential, direct, indirect, */
+/* or special damages, whether under contract, tort, warranty or otherwise, */
+/* arising in any way out of use or reliance upon this specification or any */
+/* information herein. */
+/* */
+/* (c) Copyright IBM Corp. and others, 2016 - 2018 */
+/* */
+/********************************************************************************/
+
+#include "Tpm.h"
+#include "GetRandom_fp.h"
+#if CC_GetRandom // Conditional expansion of this file
+TPM_RC
+TPM2_GetRandom(
+ GetRandom_In *in, // IN: input parameter list
+ GetRandom_Out *out // OUT: output parameter list
+ )
+{
+ // Command Output
+ // if the requested bytes exceed the output buffer size, generates the
+ // maximum bytes that the output buffer allows
+ if(in->bytesRequested > sizeof(TPMU_HA))
+ out->randomBytes.t.size = sizeof(TPMU_HA);
+ else
+ out->randomBytes.t.size = in->bytesRequested;
+ CryptRandomGenerate(out->randomBytes.t.size, out->randomBytes.t.buffer);
+ return TPM_RC_SUCCESS;
+}
+#endif // CC_GetRandom
+#include "Tpm.h"
+#include "StirRandom_fp.h"
+#if CC_StirRandom // Conditional expansion of this file
+TPM_RC
+TPM2_StirRandom(
+ StirRandom_In *in // IN: input parameter list
+ )
+{
+ // Internal Data Update
+ CryptRandomStir(in->inData.t.size, in->inData.t.buffer);
+ return TPM_RC_SUCCESS;
+}
+#endif // CC_StirRandom
diff --git a/src/tpm2/ReadClock_fp.h b/src/tpm2/ReadClock_fp.h
new file mode 100644
index 0000000..3d01b54
--- /dev/null
+++ b/src/tpm2/ReadClock_fp.h
@@ -0,0 +1,77 @@
+/********************************************************************************/
+/* */
+/* */
+/* Written by Ken Goldman */
+/* IBM Thomas J. Watson Research Center */
+/* $Id: ReadClock_fp.h 809 2016-11-16 18:31:54Z kgoldman $ */
+/* */
+/* Licenses and Notices */
+/* */
+/* 1. Copyright Licenses: */
+/* */
+/* - Trusted Computing Group (TCG) grants to the user of the source code in */
+/* this specification (the "Source Code") a worldwide, irrevocable, */
+/* nonexclusive, royalty free, copyright license to reproduce, create */
+/* derivative works, distribute, display and perform the Source Code and */
+/* derivative works thereof, and to grant others the rights granted herein. */
+/* */
+/* - The TCG grants to the user of the other parts of the specification */
+/* (other than the Source Code) the rights to reproduce, distribute, */
+/* display, and perform the specification solely for the purpose of */
+/* developing products based on such documents. */
+/* */
+/* 2. Source Code Distribution Conditions: */
+/* */
+/* - Redistributions of Source Code must retain the above copyright licenses, */
+/* this list of conditions and the following disclaimers. */
+/* */
+/* - Redistributions in binary form must reproduce the above copyright */
+/* licenses, this list of conditions and the following disclaimers in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* 3. Disclaimers: */
+/* */
+/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
+/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
+/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
+/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
+/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
+/* information on specification licensing rights available through TCG */
+/* membership agreements. */
+/* */
+/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
+/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
+/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
+/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
+/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
+/* */
+/* - Without limitation, TCG and its members and licensors disclaim all */
+/* liability, including liability for infringement of any proprietary */
+/* rights, relating to use of information in this specification and to the */
+/* implementation of this specification, and TCG disclaims all liability for */
+/* cost of procurement of substitute goods or services, lost profits, loss */
+/* of use, loss of data or any incidental, consequential, direct, indirect, */
+/* or special damages, whether under contract, tort, warranty or otherwise, */
+/* arising in any way out of use or reliance upon this specification or any */
+/* information herein. */
+/* */
+/* (c) Copyright IBM Corp. and others, 2012-2015 */
+/* */
+/********************************************************************************/
+
+/* rev 119 */
+
+#ifndef READCLOCK_FP_H
+#define READCLOCK_FP_H
+
+typedef struct {
+ TPMS_TIME_INFO currentTime;
+} ReadClock_Out;
+
+TPM_RC
+TPM2_ReadClock(
+ ReadClock_Out *out // OUT: output parameter list
+ );
+
+
+#endif
diff --git a/src/tpm2/ReadPublic_fp.h b/src/tpm2/ReadPublic_fp.h
new file mode 100644
index 0000000..1365f87
--- /dev/null
+++ b/src/tpm2/ReadPublic_fp.h
@@ -0,0 +1,84 @@
+/********************************************************************************/
+/* */
+/* */
+/* Written by Ken Goldman */
+/* IBM Thomas J. Watson Research Center */
+/* $Id: ReadPublic_fp.h 809 2016-11-16 18:31:54Z kgoldman $ */
+/* */
+/* Licenses and Notices */
+/* */
+/* 1. Copyright Licenses: */
+/* */
+/* - Trusted Computing Group (TCG) grants to the user of the source code in */
+/* this specification (the "Source Code") a worldwide, irrevocable, */
+/* nonexclusive, royalty free, copyright license to reproduce, create */
+/* derivative works, distribute, display and perform the Source Code and */
+/* derivative works thereof, and to grant others the rights granted herein. */
+/* */
+/* - The TCG grants to the user of the other parts of the specification */
+/* (other than the Source Code) the rights to reproduce, distribute, */
+/* display, and perform the specification solely for the purpose of */
+/* developing products based on such documents. */
+/* */
+/* 2. Source Code Distribution Conditions: */
+/* */
+/* - Redistributions of Source Code must retain the above copyright licenses, */
+/* this list of conditions and the following disclaimers. */
+/* */
+/* - Redistributions in binary form must reproduce the above copyright */
+/* licenses, this list of conditions and the following disclaimers in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* 3. Disclaimers: */
+/* */
+/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
+/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
+/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
+/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
+/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
+/* information on specification licensing rights available through TCG */
+/* membership agreements. */
+/* */
+/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
+/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
+/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
+/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
+/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
+/* */
+/* - Without limitation, TCG and its members and licensors disclaim all */
+/* liability, including liability for infringement of any proprietary */
+/* rights, relating to use of information in this specification and to the */
+/* implementation of this specification, and TCG disclaims all liability for */
+/* cost of procurement of substitute goods or services, lost profits, loss */
+/* of use, loss of data or any incidental, consequential, direct, indirect, */
+/* or special damages, whether under contract, tort, warranty or otherwise, */
+/* arising in any way out of use or reliance upon this specification or any */
+/* information herein. */
+/* */
+/* (c) Copyright IBM Corp. and others, 2012-2015 */
+/* */
+/********************************************************************************/
+
+/* rev 119 */
+
+#ifndef READPUBLIC_FP_H
+#define READPUBLIC_FP_H
+
+typedef struct {
+ TPMI_DH_OBJECT objectHandle;
+} ReadPublic_In;
+
+#define RC_ReadPublic_objectHandle (TPM_RC_H + TPM_RC_1)
+
+typedef struct {
+ TPM2B_PUBLIC outPublic;
+ TPM2B_NAME name;
+ TPM2B_NAME qualifiedName;
+} ReadPublic_Out;
+
+TPM_RC
+TPM2_ReadPublic(
+ ReadPublic_In *in, // IN: input parameter list
+ ReadPublic_Out *out // OUT: output parameter list
+ );
+#endif
diff --git a/src/tpm2/Response.c b/src/tpm2/Response.c
new file mode 100644
index 0000000..40d62ce
--- /dev/null
+++ b/src/tpm2/Response.c
@@ -0,0 +1,105 @@
+/********************************************************************************/
+/* */
+/* */
+/* Written by Ken Goldman */
+/* IBM Thomas J. Watson Research Center */
+/* $Id: Response.c 1259 2018-07-10 19:11:09Z kgoldman $ */
+/* */
+/* Licenses and Notices */
+/* */
+/* 1. Copyright Licenses: */
+/* */
+/* - Trusted Computing Group (TCG) grants to the user of the source code in */
+/* this specification (the "Source Code") a worldwide, irrevocable, */
+/* nonexclusive, royalty free, copyright license to reproduce, create */
+/* derivative works, distribute, display and perform the Source Code and */
+/* derivative works thereof, and to grant others the rights granted herein. */
+/* */
+/* - The TCG grants to the user of the other parts of the specification */
+/* (other than the Source Code) the rights to reproduce, distribute, */
+/* display, and perform the specification solely for the purpose of */
+/* developing products based on such documents. */
+/* */
+/* 2. Source Code Distribution Conditions: */
+/* */
+/* - Redistributions of Source Code must retain the above copyright licenses, */
+/* this list of conditions and the following disclaimers. */
+/* */
+/* - Redistributions in binary form must reproduce the above copyright */
+/* licenses, this list of conditions and the following disclaimers in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* 3. Disclaimers: */
+/* */
+/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
+/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
+/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
+/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
+/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
+/* information on specification licensing rights available through TCG */
+/* membership agreements. */
+/* */
+/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
+/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
+/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
+/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
+/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
+/* */
+/* - Without limitation, TCG and its members and licensors disclaim all */
+/* liability, including liability for infringement of any proprietary */
+/* rights, relating to use of information in this specification and to the */
+/* implementation of this specification, and TCG disclaims all liability for */
+/* cost of procurement of substitute goods or services, lost profits, loss */
+/* of use, loss of data or any incidental, consequential, direct, indirect, */
+/* or special damages, whether under contract, tort, warranty or otherwise, */
+/* arising in any way out of use or reliance upon this specification or any */
+/* information herein. */
+/* */
+/* (c) Copyright IBM Corp. and others, 2016 - 2018 */
+/* */
+/********************************************************************************/
+
+/* 9.15 Response.c */
+/* 9.15.1 Description */
+/* This file contains the common code for building a response header, including setting the size of
+ the structure. command may be NULL if result is not TPM_RC_SUCCESS. */
+/* 9.15.2 Includes and Defines */
+#include "Tpm.h"
+/* 9.15.3 BuildResponseHeader() */
+/* Adds the response header to the response. It will update command->parameterSize to indicate the
+ total size of the response. */
+void
+BuildResponseHeader(
+ COMMAND *command, // IN: main control structure
+ BYTE *buffer, // OUT: the output buffer
+ TPM_RC result // IN: the response code
+ )
+{
+ TPM_ST tag;
+ UINT32 size;
+ if(result != TPM_RC_SUCCESS)
+ {
+ tag = TPM_ST_NO_SESSIONS;
+ size = 10;
+ }
+ else
+ {
+ tag = command->tag;
+ // Compute the overall size of the response
+ size = STD_RESPONSE_HEADER + command->handleNum * sizeof(TPM_HANDLE);
+ size += command->parameterSize;
+ size += (command->tag == TPM_ST_SESSIONS) ?
+ command->authSize + sizeof(UINT32) : 0;
+ }
+ TPM_ST_Marshal(&tag, &buffer, NULL);
+ UINT32_Marshal(&size, &buffer, NULL);
+ TPM_RC_Marshal(&result, &buffer, NULL);
+ if(result == TPM_RC_SUCCESS)
+ {
+ if(command->handleNum > 0)
+ TPM_HANDLE_Marshal(&command->handles[0], &buffer, NULL);
+ if(tag == TPM_ST_SESSIONS)
+ UINT32_Marshal((UINT32 *)&command->parameterSize, &buffer, NULL);
+ }
+ command->parameterSize = size;
+}
diff --git a/src/tpm2/ResponseCodeProcessing.c b/src/tpm2/ResponseCodeProcessing.c
new file mode 100644
index 0000000..3fa00ef
--- /dev/null
+++ b/src/tpm2/ResponseCodeProcessing.c
@@ -0,0 +1,81 @@
+/********************************************************************************/
+/* */
+/* Miscellaneous Functions For Processing Response Codes */
+/* Written by Ken Goldman */
+/* IBM Thomas J. Watson Research Center */
+/* $Id: ResponseCodeProcessing.c 1259 2018-07-10 19:11:09Z kgoldman $ */
+/* */
+/* Licenses and Notices */
+/* */
+/* 1. Copyright Licenses: */
+/* */
+/* - Trusted Computing Group (TCG) grants to the user of the source code in */
+/* this specification (the "Source Code") a worldwide, irrevocable, */
+/* nonexclusive, royalty free, copyright license to reproduce, create */
+/* derivative works, distribute, display and perform the Source Code and */
+/* derivative works thereof, and to grant others the rights granted herein. */
+/* */
+/* - The TCG grants to the user of the other parts of the specification */
+/* (other than the Source Code) the rights to reproduce, distribute, */
+/* display, and perform the specification solely for the purpose of */
+/* developing products based on such documents. */
+/* */
+/* 2. Source Code Distribution Conditions: */
+/* */
+/* - Redistributions of Source Code must retain the above copyright licenses, */
+/* this list of conditions and the following disclaimers. */
+/* */
+/* - Redistributions in binary form must reproduce the above copyright */
+/* licenses, this list of conditions and the following disclaimers in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* 3. Disclaimers: */
+/* */
+/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
+/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
+/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
+/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
+/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
+/* information on specification licensing rights available through TCG */
+/* membership agreements. */
+/* */
+/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
+/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
+/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
+/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
+/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
+/* */
+/* - Without limitation, TCG and its members and licensors disclaim all */
+/* liability, including liability for infringement of any proprietary */
+/* rights, relating to use of information in this specification and to the */
+/* implementation of this specification, and TCG disclaims all liability for */
+/* cost of procurement of substitute goods or services, lost profits, loss */
+/* of use, loss of data or any incidental, consequential, direct, indirect, */
+/* or special damages, whether under contract, tort, warranty or otherwise, */
+/* arising in any way out of use or reliance upon this specification or any */
+/* information herein. */
+/* */
+/* (c) Copyright IBM Corp. and others, 2016 - 2018 */
+/* */
+/********************************************************************************/
+
+/* 9.16 ResponseCodeProcessing.c */
+/* 9.16.1 Description */
+/* This file contains the miscellaneous functions for processing response codes. */
+/* NOTE: Currently, there is only one. */
+/* 9.16.2 Includes and Defines */
+#include "Tpm.h"
+/* 9.16.3 RcSafeAddToResult() */
+/* Adds a modifier to a response code as long as the response code allows a modifier and no modifier
+ has already been added. */
+TPM_RC
+RcSafeAddToResult(
+ TPM_RC responseCode,
+ TPM_RC modifier
+ )
+{
+ if((responseCode & RC_FMT1) && !(responseCode & 0xf40))
+ return responseCode + modifier;
+ else
+ return responseCode;
+}
diff --git a/src/tpm2/ResponseCodeProcessing_fp.h b/src/tpm2/ResponseCodeProcessing_fp.h
new file mode 100644
index 0000000..da50c52
--- /dev/null
+++ b/src/tpm2/ResponseCodeProcessing_fp.h
@@ -0,0 +1,71 @@
+/********************************************************************************/
+/* */
+/* */
+/* Written by Ken Goldman */
+/* IBM Thomas J. Watson Research Center */
+/* $Id: ResponseCodeProcessing_fp.h 809 2016-11-16 18:31:54Z kgoldman $ */
+/* */
+/* Licenses and Notices */
+/* */
+/* 1. Copyright Licenses: */
+/* */
+/* - Trusted Computing Group (TCG) grants to the user of the source code in */
+/* this specification (the "Source Code") a worldwide, irrevocable, */
+/* nonexclusive, royalty free, copyright license to reproduce, create */
+/* derivative works, distribute, display and perform the Source Code and */
+/* derivative works thereof, and to grant others the rights granted herein. */
+/* */
+/* - The TCG grants to the user of the other parts of the specification */
+/* (other than the Source Code) the rights to reproduce, distribute, */
+/* display, and perform the specification solely for the purpose of */
+/* developing products based on such documents. */
+/* */
+/* 2. Source Code Distribution Conditions: */
+/* */
+/* - Redistributions of Source Code must retain the above copyright licenses, */
+/* this list of conditions and the following disclaimers. */
+/* */
+/* - Redistributions in binary form must reproduce the above copyright */
+/* licenses, this list of conditions and the following disclaimers in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* 3. Disclaimers: */
+/* */
+/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
+/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
+/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
+/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
+/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
+/* information on specification licensing rights available through TCG */
+/* membership agreements. */
+/* */
+/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
+/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
+/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
+/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
+/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
+/* */
+/* - Without limitation, TCG and its members and licensors disclaim all */
+/* liability, including liability for infringement of any proprietary */
+/* rights, relating to use of information in this specification and to the */
+/* implementation of this specification, and TCG disclaims all liability for */
+/* cost of procurement of substitute goods or services, lost profits, loss */
+/* of use, loss of data or any incidental, consequential, direct, indirect, */
+/* or special damages, whether under contract, tort, warranty or otherwise, */
+/* arising in any way out of use or reliance upon this specification or any */
+/* information herein. */
+/* */
+/* (c) Copyright IBM Corp. and others, 2016 */
+/* */
+/********************************************************************************/
+
+#ifndef RESPONSECODEPROCESSING_FP_H
+#define RESPONSECODEPROCESSING_FP_H
+
+TPM_RC
+RcSafeAddToResult(
+ TPM_RC responseCode,
+ TPM_RC modifier
+ );
+
+#endif
diff --git a/src/tpm2/Response_fp.h b/src/tpm2/Response_fp.h
new file mode 100644
index 0000000..5460531
--- /dev/null
+++ b/src/tpm2/Response_fp.h
@@ -0,0 +1,73 @@
+/********************************************************************************/
+/* */
+/* */
+/* Written by Ken Goldman */
+/* IBM Thomas J. Watson Research Center */
+/* $Id: Response_fp.h 809 2016-11-16 18:31:54Z kgoldman $ */
+/* */
+/* Licenses and Notices */
+/* */
+/* 1. Copyright Licenses: */
+/* */
+/* - Trusted Computing Group (TCG) grants to the user of the source code in */
+/* this specification (the "Source Code") a worldwide, irrevocable, */
+/* nonexclusive, royalty free, copyright license to reproduce, create */
+/* derivative works, distribute, display and perform the Source Code and */
+/* derivative works thereof, and to grant others the rights granted herein. */
+/* */
+/* - The TCG grants to the user of the other parts of the specification */
+/* (other than the Source Code) the rights to reproduce, distribute, */
+/* display, and perform the specification solely for the purpose of */
+/* developing products based on such documents. */
+/* */
+/* 2. Source Code Distribution Conditions: */
+/* */
+/* - Redistributions of Source Code must retain the above copyright licenses, */
+/* this list of conditions and the following disclaimers. */
+/* */
+/* - Redistributions in binary form must reproduce the above copyright */
+/* licenses, this list of conditions and the following disclaimers in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* 3. Disclaimers: */
+/* */
+/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
+/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
+/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
+/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
+/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
+/* information on specification licensing rights available through TCG */
+/* membership agreements. */
+/* */
+/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
+/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
+/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
+/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
+/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
+/* */
+/* - Without limitation, TCG and its members and licensors disclaim all */
+/* liability, including liability for infringement of any proprietary */
+/* rights, relating to use of information in this specification and to the */
+/* implementation of this specification, and TCG disclaims all liability for */
+/* cost of procurement of substitute goods or services, lost profits, loss */
+/* of use, loss of data or any incidental, consequential, direct, indirect, */
+/* or special damages, whether under contract, tort, warranty or otherwise, */
+/* arising in any way out of use or reliance upon this specification or any */
+/* information herein. */
+/* */
+/* (c) Copyright IBM Corp. and others, 2016 */
+/* */
+/********************************************************************************/
+
+#ifndef RESPONSE_FP_H
+#define RESPONSE_FP_H
+
+void
+BuildResponseHeader(
+ COMMAND *command, // IN: main control structure
+ BYTE *buffer, // OUT: the output buffer
+ TPM_RC result // IN: the response code
+ );
+
+
+#endif
diff --git a/src/tpm2/Rewrap_fp.h b/src/tpm2/Rewrap_fp.h
new file mode 100644
index 0000000..6a29a5c
--- /dev/null
+++ b/src/tpm2/Rewrap_fp.h
@@ -0,0 +1,92 @@
+/********************************************************************************/
+/* */
+/* */
+/* Written by Ken Goldman */
+/* IBM Thomas J. Watson Research Center */
+/* $Id: Rewrap_fp.h 809 2016-11-16 18:31:54Z kgoldman $ */
+/* */
+/* Licenses and Notices */
+/* */
+/* 1. Copyright Licenses: */
+/* */
+/* - Trusted Computing Group (TCG) grants to the user of the source code in */
+/* this specification (the "Source Code") a worldwide, irrevocable, */
+/* nonexclusive, royalty free, copyright license to reproduce, create */
+/* derivative works, distribute, display and perform the Source Code and */
+/* derivative works thereof, and to grant others the rights granted herein. */
+/* */
+/* - The TCG grants to the user of the other parts of the specification */
+/* (other than the Source Code) the rights to reproduce, distribute, */
+/* display, and perform the specification solely for the purpose of */
+/* developing products based on such documents. */
+/* */
+/* 2. Source Code Distribution Conditions: */
+/* */
+/* - Redistributions of Source Code must retain the above copyright licenses, */
+/* this list of conditions and the following disclaimers. */
+/* */
+/* - Redistributions in binary form must reproduce the above copyright */
+/* licenses, this list of conditions and the following disclaimers in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* 3. Disclaimers: */
+/* */
+/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
+/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
+/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
+/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
+/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
+/* information on specification licensing rights available through TCG */
+/* membership agreements. */
+/* */
+/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
+/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
+/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
+/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
+/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
+/* */
+/* - Without limitation, TCG and its members and licensors disclaim all */
+/* liability, including liability for infringement of any proprietary */
+/* rights, relating to use of information in this specification and to the */
+/* implementation of this specification, and TCG disclaims all liability for */
+/* cost of procurement of substitute goods or services, lost profits, loss */
+/* of use, loss of data or any incidental, consequential, direct, indirect, */
+/* or special damages, whether under contract, tort, warranty or otherwise, */
+/* arising in any way out of use or reliance upon this specification or any */
+/* information herein. */
+/* */
+/* (c) Copyright IBM Corp. and others, 2012-2015 */
+/* */
+/********************************************************************************/
+
+/* rev 119 */
+
+#ifndef REWRAP_FP_H
+#define REWRAP_FP_H
+
+typedef struct {
+ TPMI_DH_OBJECT oldParent;
+ TPMI_DH_OBJECT newParent;
+ TPM2B_PRIVATE inDuplicate;
+ TPM2B_NAME name;
+ TPM2B_ENCRYPTED_SECRET inSymSeed;
+} Rewrap_In;
+
+#define RC_Rewrap_oldParent (TPM_RC_H + TPM_RC_1)
+#define RC_Rewrap_newParent (TPM_RC_H + TPM_RC_2)
+#define RC_Rewrap_inDuplicate (TPM_RC_P + TPM_RC_1)
+#define RC_Rewrap_name (TPM_RC_P + TPM_RC_2)
+#define RC_Rewrap_inSymSeed (TPM_RC_P + TPM_RC_3)
+
+typedef struct {
+ TPM2B_PRIVATE outDuplicate;
+ TPM2B_ENCRYPTED_SECRET outSymSeed;
+} Rewrap_Out;
+
+TPM_RC
+TPM2_Rewrap(
+ Rewrap_In *in, // IN: input parameter list
+ Rewrap_Out *out // OUT: output parameter list
+ );
+
+#endif
diff --git a/src/tpm2/RsaTestData.h b/src/tpm2/RsaTestData.h
new file mode 100644
index 0000000..abbaa8d
--- /dev/null
+++ b/src/tpm2/RsaTestData.h
@@ -0,0 +1,425 @@
+/********************************************************************************/
+/* */
+/* RSA Test Vectors */
+/* Written by Ken Goldman */
+/* IBM Thomas J. Watson Research Center */
+/* $Id: RsaTestData.h 1259 2018-07-10 19:11:09Z kgoldman $ */
+/* */
+/* Licenses and Notices */
+/* */
+/* 1. Copyright Licenses: */
+/* */
+/* - Trusted Computing Group (TCG) grants to the user of the source code in */
+/* this specification (the "Source Code") a worldwide, irrevocable, */
+/* nonexclusive, royalty free, copyright license to reproduce, create */
+/* derivative works, distribute, display and perform the Source Code and */
+/* derivative works thereof, and to grant others the rights granted herein. */
+/* */
+/* - The TCG grants to the user of the other parts of the specification */
+/* (other than the Source Code) the rights to reproduce, distribute, */
+/* display, and perform the specification solely for the purpose of */
+/* developing products based on such documents. */
+/* */
+/* 2. Source Code Distribution Conditions: */
+/* */
+/* - Redistributions of Source Code must retain the above copyright licenses, */
+/* this list of conditions and the following disclaimers. */
+/* */
+/* - Redistributions in binary form must reproduce the above copyright */
+/* licenses, this list of conditions and the following disclaimers in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* 3. Disclaimers: */
+/* */
+/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
+/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
+/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
+/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
+/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
+/* information on specification licensing rights available through TCG */
+/* membership agreements. */
+/* */
+/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
+/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
+/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
+/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
+/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
+/* */
+/* - Without limitation, TCG and its members and licensors disclaim all */
+/* liability, including liability for infringement of any proprietary */
+/* rights, relating to use of information in this specification and to the */
+/* implementation of this specification, and TCG disclaims all liability for */
+/* cost of procurement of substitute goods or services, lost profits, loss */
+/* of use, loss of data or any incidental, consequential, direct, indirect, */
+/* or special damages, whether under contract, tort, warranty or otherwise, */
+/* arising in any way out of use or reliance upon this specification or any */
+/* information herein. */
+/* */
+/* (c) Copyright IBM Corp. and others, 2016 - 2018 */
+/* */
+/********************************************************************************/
+
+#ifndef RSATESTDATA_H
+#define RSATESTDATA_H
+
+
+/* 10.1.9 RsaTestData.h */
+/* RSA Test Vectors */
+#define RSA_TEST_KEY_SIZE 256
+typedef struct
+{
+ UINT16 size;
+ BYTE buffer[RSA_TEST_KEY_SIZE];
+} TPM2B_RSA_TEST_KEY;
+typedef TPM2B_RSA_TEST_KEY TPM2B_RSA_TEST_VALUE;
+typedef struct
+{
+ UINT16 size;
+ BYTE buffer[RSA_TEST_KEY_SIZE / 2];
+} TPM2B_RSA_TEST_PRIME;
+const TPM2B_RSA_TEST_KEY c_rsaPublicModulus = {256, {
+ 0x91,0x12,0xf5,0x07,0x9d,0x5f,0x6b,0x1c,0x90,0xf6,0xcc,0x87,0xde,0x3a,0x7a,0x15,
+ 0xdc,0x54,0x07,0x6c,0x26,0x8f,0x25,0xef,0x7e,0x66,0xc0,0xe3,0x82,0x12,0x2f,0xab,
+ 0x52,0x82,0x1e,0x85,0xbc,0x53,0xba,0x2b,0x01,0xad,0x01,0xc7,0x8d,0x46,0x4f,0x7d,
+ 0xdd,0x7e,0xdc,0xb0,0xad,0xf6,0x0c,0xa1,0x62,0x92,0x97,0x8a,0x3e,0x6f,0x7e,0x3e,
+ 0xf6,0x9a,0xcc,0xf9,0xa9,0x86,0x77,0xb6,0x85,0x43,0x42,0x04,0x13,0x65,0xe2,0xad,
+ 0x36,0xc9,0xbf,0xc1,0x97,0x84,0x6f,0xee,0x7c,0xda,0x58,0xd2,0xae,0x07,0x00,0xaf,
+ 0xc5,0x5f,0x4d,0x3a,0x98,0xb0,0xed,0x27,0x7c,0xc2,0xce,0x26,0x5d,0x87,0xe1,0xe3,
+ 0xa9,0x69,0x88,0x4f,0x8c,0x08,0x31,0x18,0xae,0x93,0x16,0xe3,0x74,0xde,0xd3,0xf6,
+ 0x16,0xaf,0xa3,0xac,0x37,0x91,0x8d,0x10,0xc6,0x6b,0x64,0x14,0x3a,0xd9,0xfc,0xe4,
+ 0xa0,0xf2,0xd1,0x01,0x37,0x4f,0x4a,0xeb,0xe5,0xec,0x98,0xc5,0xd9,0x4b,0x30,0xd2,
+ 0x80,0x2a,0x5a,0x18,0x5a,0x7d,0xd4,0x3d,0xb7,0x62,0x98,0xce,0x6d,0xa2,0x02,0x6e,
+ 0x45,0xaa,0x95,0x73,0xe0,0xaa,0x75,0x57,0xb1,0x3d,0x1b,0x05,0x75,0x23,0x6b,0x20,
+ 0x69,0x9e,0x14,0xb0,0x7f,0xac,0xae,0xd2,0xc7,0x48,0x3b,0xe4,0x56,0x11,0x34,0x1e,
+ 0x05,0x1a,0x30,0x20,0xef,0x68,0x93,0x6b,0x9d,0x7e,0xdd,0xba,0x96,0x50,0xcc,0x1c,
+ 0x81,0xb4,0x59,0xb9,0x74,0x36,0xd9,0x97,0xdc,0x8f,0x17,0x82,0x72,0xb3,0x59,0xf6,
+ 0x23,0xfa,0x84,0xf7,0x6d,0xf2,0x05,0xff,0xf1,0xb9,0xcc,0xe9,0xa2,0x82,0x01,0xfb}};
+const TPM2B_RSA_TEST_PRIME c_rsaPrivatePrime = {RSA_TEST_KEY_SIZE / 2, {
+ 0xb7,0xa0,0x90,0xc7,0x92,0x09,0xde,0x71,0x03,0x37,0x4a,0xb5,0x2f,0xda,0x61,0xb8,
+ 0x09,0x1b,0xba,0x99,0x70,0x45,0xc1,0x0b,0x15,0x12,0x71,0x8a,0xb3,0x2a,0x4d,0x5a,
+ 0x41,0x9b,0x73,0x89,0x80,0x0a,0x8f,0x18,0x4c,0x8b,0xa2,0x5b,0xda,0xbd,0x43,0xbe,
+ 0xdc,0x76,0x4d,0x71,0x0f,0xb9,0xfc,0x7a,0x09,0xfe,0x4f,0xac,0x63,0xd9,0x2e,0x50,
+ 0x3a,0xa1,0x37,0xc6,0xf2,0xa1,0x89,0x12,0xe7,0x72,0x64,0x2b,0xba,0xc1,0x1f,0xca,
+ 0x9d,0xb7,0xaa,0x3a,0xa9,0xd3,0xa6,0x6f,0x73,0x02,0xbb,0x85,0x5d,0x9a,0xb9,0x5c,
+ 0x08,0x83,0x22,0x20,0x49,0x91,0x5f,0x4b,0x86,0xbc,0x3f,0x76,0x43,0x08,0x97,0xbf,
+ 0x82,0x55,0x36,0x2d,0x8b,0x6e,0x9e,0xfb,0xc1,0x67,0x6a,0x43,0xa2,0x46,0x81,0x71}};
+const BYTE c_RsaTestValue[RSA_TEST_KEY_SIZE] = {
+ 0x2a,0x24,0x3a,0xbb,0x50,0x1d,0xd4,0x2a,0xf9,0x18,0x32,0x34,0xa2,0x0f,0xea,0x5c,
+ 0x91,0x77,0xe9,0xe1,0x09,0x83,0xdc,0x5f,0x71,0x64,0x5b,0xeb,0x57,0x79,0xa0,0x41,
+ 0xc9,0xe4,0x5a,0x0b,0xf4,0x9f,0xdb,0x84,0x04,0xa6,0x48,0x24,0xf6,0x3f,0x66,0x1f,
+ 0xa8,0x04,0x5c,0xf0,0x7a,0x6b,0x4a,0x9c,0x7e,0x21,0xb6,0xda,0x6b,0x65,0x9c,0x3a,
+ 0x68,0x50,0x13,0x1e,0xa4,0xb7,0xca,0xec,0xd3,0xcc,0xb2,0x9b,0x8c,0x87,0xa4,0x6a,
+ 0xba,0xc2,0x06,0x3f,0x40,0x48,0x7b,0xa8,0xb8,0x2c,0x03,0x14,0x33,0xf3,0x1d,0xe9,
+ 0xbd,0x6f,0x54,0x66,0xb4,0x69,0x5e,0xbc,0x80,0x7c,0xe9,0x6a,0x43,0x7f,0xb8,0x6a,
+ 0xa0,0x5f,0x5d,0x7a,0x20,0xfd,0x7a,0x39,0xe1,0xea,0x0e,0x94,0x91,0x28,0x63,0x7a,
+ 0xac,0xc9,0xa5,0x3a,0x6d,0x31,0x7b,0x7c,0x54,0x56,0x99,0x56,0xbb,0xb7,0xa1,0x2d,
+ 0xd2,0x5c,0x91,0x5f,0x1c,0xd3,0x06,0x7f,0x34,0x53,0x2f,0x4c,0xd1,0x8b,0xd2,0x9e,
+ 0xdc,0xc3,0x94,0x0a,0xe1,0x0f,0xa5,0x15,0x46,0x2a,0x8e,0x10,0xc2,0xfe,0xb7,0x5e,
+ 0x2d,0x0d,0xd1,0x25,0xfc,0xe4,0xf7,0x02,0x19,0xfe,0xb6,0xe4,0x95,0x9c,0x17,0x4a,
+ 0x9b,0xdb,0xab,0xc7,0x79,0xe3,0x5e,0x40,0xd0,0x56,0x6d,0x25,0x0a,0x72,0x65,0x80,
+ 0x92,0x9a,0xa8,0x07,0x70,0x32,0x14,0xfb,0xfe,0x08,0xeb,0x13,0xb4,0x07,0x68,0xb4,
+ 0x58,0x39,0xbe,0x8e,0x78,0x3a,0x59,0x3f,0x9c,0x4c,0xe9,0xa8,0x64,0x68,0xf7,0xb9,
+ 0x6e,0x20,0xf5,0xcb,0xca,0x47,0xf2,0x17,0xaa,0x8b,0xbc,0x13,0x14,0x84,0xf6,0xab};
+const TPM2B_RSA_TEST_VALUE c_RsaepKvt = {RSA_TEST_KEY_SIZE, {
+ 0x73,0xbd,0x65,0x49,0xda,0x7b,0xb8,0x50,0x9e,0x87,0xf0,0x0a,0x8a,0x9a,0x07,0xb6,
+ 0x00,0x82,0x10,0x14,0x60,0xd8,0x01,0xfc,0xc5,0x18,0xea,0x49,0x5f,0x13,0xcf,0x65,
+ 0x66,0x30,0x6c,0x60,0x3f,0x24,0x3c,0xfb,0xe2,0x31,0x16,0x99,0x7e,0x31,0x98,0xab,
+ 0x93,0xb8,0x07,0x53,0xcc,0xdb,0x7f,0x44,0xd9,0xee,0x5d,0xe8,0x5f,0x97,0x5f,0xe8,
+ 0x1f,0x88,0x52,0x24,0x7b,0xac,0x62,0x95,0xb7,0x7d,0xf5,0xf8,0x9f,0x5a,0xa8,0x24,
+ 0x9a,0x76,0x71,0x2a,0x35,0x2a,0xa1,0x08,0xbb,0x95,0xe3,0x64,0xdc,0xdb,0xc2,0x33,
+ 0xa9,0x5f,0xbe,0x4c,0xc4,0xcc,0x28,0xc9,0x25,0xff,0xee,0x17,0x15,0x9a,0x50,0x90,
+ 0x0e,0x15,0xb4,0xea,0x6a,0x09,0xe6,0xff,0xa4,0xee,0xc7,0x7e,0xce,0xa9,0x73,0xe4,
+ 0xa0,0x56,0xbd,0x53,0x2a,0xe4,0xc0,0x2b,0xa8,0x9b,0x09,0x30,0x72,0x62,0x0f,0xf9,
+ 0xf6,0xa1,0x52,0xd2,0x8a,0x37,0xee,0xa5,0xc8,0x47,0xe1,0x99,0x21,0x47,0xeb,0xdd,
+ 0x37,0xaa,0xe4,0xbd,0x55,0x46,0x5a,0x5a,0x5d,0xfb,0x7b,0xfc,0xff,0xbf,0x26,0x71,
+ 0xf6,0x1e,0xad,0xbc,0xbf,0x33,0xca,0xe1,0x92,0x8f,0x2a,0x89,0x6c,0x45,0x24,0xd1,
+ 0xa6,0x52,0x56,0x24,0x5e,0x90,0x47,0xe5,0xcb,0x12,0xb0,0x32,0xf9,0xa6,0xbb,0xea,
+ 0x37,0xa9,0xbd,0xef,0x23,0xef,0x63,0x07,0x6c,0xc4,0x4e,0x64,0x3c,0xc6,0x11,0x84,
+ 0x7d,0x65,0xd6,0x5d,0x7a,0x17,0x58,0xa5,0xf7,0x74,0x3b,0x42,0xe3,0xd2,0xda,0x5f,
+ 0x6f,0xe0,0x1e,0x4b,0xcf,0x46,0xe2,0xdf,0x3e,0x41,0x8e,0x0e,0xb0,0x3f,0x8b,0x65}};
+
+#define OAEP_TEST_LABEL "OAEP Test Value"
+
+#if ALG_SHA1_VALUE == DEFAULT_TEST_HASH
+
+const TPM2B_RSA_TEST_VALUE c_OaepKvt = {RSA_TEST_KEY_SIZE, {
+ 0x32,0x68,0x84,0x0b,0x9c,0xc9,0x25,0x26,0xd9,0xc0,0xd0,0xb1,0xde,0x60,0x55,0xae,
+ 0x33,0xe5,0xcf,0x6c,0x85,0xbe,0x0d,0x71,0x11,0xe1,0x45,0x60,0xbb,0x42,0x3d,0xf3,
+ 0xb1,0x18,0x84,0x7b,0xc6,0x5d,0xce,0x1d,0x5f,0x9a,0x97,0xcf,0xb1,0x97,0x9a,0x85,
+ 0x7c,0xa7,0xa1,0x63,0x23,0xb6,0x74,0x0f,0x1a,0xee,0x29,0x51,0xeb,0x50,0x8f,0x3c,
+ 0x8e,0x4e,0x31,0x38,0xdc,0x11,0xfc,0x9a,0x4e,0xaf,0x93,0xc9,0x7f,0x6e,0x35,0xf3,
+ 0xc9,0xe4,0x89,0x14,0x53,0xe2,0xc2,0x1a,0xf7,0x6b,0x9b,0xf0,0x7a,0xa4,0x69,0x52,
+ 0xe0,0x24,0x8f,0xea,0x31,0xa7,0x5c,0x43,0xb0,0x65,0xc9,0xfe,0xba,0xfe,0x80,0x9e,
+ 0xa5,0xc0,0xf5,0x8d,0xce,0x41,0xf9,0x83,0x0d,0x8e,0x0f,0xef,0x3d,0x1f,0x6a,0xcc,
+ 0x8a,0x3d,0x3b,0xdf,0x22,0x38,0xd7,0x34,0x58,0x7b,0x55,0xc9,0xf6,0xbc,0x7c,0x4c,
+ 0x3f,0xd7,0xde,0x4e,0x30,0xa9,0x69,0xf3,0x5f,0x56,0x8f,0xc2,0xe7,0x75,0x79,0xb8,
+ 0xa5,0xc8,0x0d,0xc0,0xcd,0xb6,0xc9,0x63,0xad,0x7c,0xe4,0x8f,0x39,0x60,0x4d,0x7d,
+ 0xdb,0x34,0x49,0x2a,0x47,0xde,0xc0,0x42,0x4a,0x19,0x94,0x2e,0x50,0x21,0x03,0x47,
+ 0xff,0x73,0xb3,0xb7,0x89,0xcc,0x7b,0x2c,0xeb,0x03,0xa7,0x9a,0x06,0xfd,0xed,0x19,
+ 0xbb,0x82,0xa0,0x13,0xe9,0xfa,0xac,0x06,0x5f,0xc5,0xa9,0x2b,0xda,0x88,0x23,0xa2,
+ 0x5d,0xc2,0x7f,0xda,0xc8,0x5a,0x94,0x31,0xc1,0x21,0xd7,0x1e,0x6b,0xd7,0x89,0xb1,
+ 0x93,0x80,0xab,0xd1,0x37,0xf2,0x6f,0x50,0xcd,0x2a,0xea,0xb1,0xc4,0xcd,0xcb,0xb5}};
+const TPM2B_RSA_TEST_VALUE c_RsaesKvt = {RSA_TEST_KEY_SIZE, {
+ 0x29,0xa4,0x2f,0xbb,0x8a,0x14,0x05,0x1e,0x3c,0x72,0x76,0x77,0x38,0xe7,0x73,0xe3,
+ 0x6e,0x24,0x4b,0x38,0xd2,0x1a,0xcf,0x23,0x58,0x78,0x36,0x82,0x23,0x6e,0x6b,0xef,
+ 0x2c,0x3d,0xf2,0xe8,0xd6,0xc6,0x87,0x8e,0x78,0x9b,0x27,0x39,0xc0,0xd6,0xef,0x4d,
+ 0x0b,0xfc,0x51,0x27,0x18,0xf3,0x51,0x5e,0x4d,0x96,0x3a,0xe2,0x15,0xe2,0x7e,0x42,
+ 0xf4,0x16,0xd5,0xc6,0x52,0x5d,0x17,0x44,0x76,0x09,0x7a,0xcf,0xe3,0x30,0xe3,0x84,
+ 0xf6,0x6f,0x3a,0x33,0xfb,0x32,0x0d,0x1d,0xe7,0x7c,0x80,0x82,0x4f,0xed,0xda,0x87,
+ 0x11,0x9c,0xc3,0x7e,0x85,0xbd,0x18,0x58,0x08,0x2b,0x23,0x37,0xe7,0x9d,0xd0,0xd1,
+ 0x79,0xe2,0x05,0xbd,0xf5,0x4f,0x0e,0x0f,0xdb,0x4a,0x74,0xeb,0x09,0x01,0xb3,0xca,
+ 0xbd,0xa6,0x7b,0x09,0xb1,0x13,0x77,0x30,0x4d,0x87,0x41,0x06,0x57,0x2e,0x5f,0x36,
+ 0x6e,0xfc,0x35,0x69,0xfe,0x0a,0x24,0x6c,0x98,0x8c,0xda,0x97,0xf4,0xfb,0xc7,0x83,
+ 0x2d,0x3e,0x7d,0xc0,0x5c,0x34,0xfd,0x11,0x2a,0x12,0xa7,0xae,0x4a,0xde,0xc8,0x4e,
+ 0xcf,0xf4,0x85,0x63,0x77,0xc6,0x33,0x34,0xe0,0x27,0xe4,0x9e,0x91,0x0b,0x4b,0x85,
+ 0xf0,0xb0,0x79,0xaa,0x7c,0xc6,0xff,0x3b,0xbc,0x04,0x73,0xb8,0x95,0xd7,0x31,0x54,
+ 0x3b,0x56,0xec,0x52,0x15,0xd7,0x3e,0x62,0xf5,0x82,0x99,0x3e,0x2a,0xc0,0x4b,0x2e,
+ 0x06,0x57,0x6d,0x3f,0x3e,0x77,0x1f,0x2b,0x2d,0xc5,0xb9,0x3b,0x68,0x56,0x73,0x70,
+ 0x32,0x6b,0x6b,0x65,0x25,0x76,0x45,0x6c,0x45,0xf1,0x6c,0x59,0xfc,0x94,0xa7,0x15}};
+const TPM2B_RSA_TEST_VALUE c_RsapssKvt = {RSA_TEST_KEY_SIZE, {
+ 0x01,0xfe,0xd5,0x83,0x0b,0x15,0xba,0x90,0x2c,0xdf,0xf7,0x26,0xb7,0x8f,0xb1,0xd7,
+ 0x0b,0xfd,0x83,0xf9,0x95,0xd5,0xd7,0xb5,0xc5,0xc5,0x4a,0xde,0xd5,0xe6,0x20,0x78,
+ 0xca,0x73,0x77,0x3d,0x61,0x36,0x48,0xae,0x3e,0x8f,0xee,0x43,0x29,0x96,0xdf,0x3f,
+ 0x1c,0x97,0x5a,0xbe,0xe5,0xa2,0x7e,0x5b,0xd0,0xc0,0x29,0x39,0x83,0x81,0x77,0x24,
+ 0x43,0xdb,0x3c,0x64,0x4d,0xf0,0x23,0xe4,0xae,0x0f,0x78,0x31,0x8c,0xda,0x0c,0xec,
+ 0xf1,0xdf,0x09,0xf2,0x14,0x6a,0x4d,0xaf,0x36,0x81,0x6e,0xbd,0xbe,0x36,0x79,0x88,
+ 0x98,0xb6,0x6f,0x5a,0xad,0xcf,0x7c,0xee,0xe0,0xdd,0x00,0xbe,0x59,0x97,0x88,0x00,
+ 0x34,0xc0,0x8b,0x48,0x42,0x05,0x04,0x5a,0xb7,0x85,0x38,0xa0,0x35,0xd7,0x3b,0x51,
+ 0xb8,0x7b,0x81,0x83,0xee,0xff,0x76,0x6f,0x50,0x39,0x4d,0xab,0x89,0x63,0x07,0x6d,
+ 0xf5,0xe5,0x01,0x10,0x56,0xfe,0x93,0x06,0x8f,0xd3,0xc9,0x41,0xab,0xc9,0xdf,0x6e,
+ 0x59,0xa8,0xc3,0x1d,0xbf,0x96,0x4a,0x59,0x80,0x3c,0x90,0x3a,0x59,0x56,0x4c,0x6d,
+ 0x44,0x6d,0xeb,0xdc,0x73,0xcd,0xc1,0xec,0xb8,0x41,0xbf,0x89,0x8c,0x03,0x69,0x4c,
+ 0xaf,0x3f,0xc1,0xc5,0xc7,0xe7,0x7d,0xa7,0x83,0x39,0x70,0xa2,0x6b,0x83,0xbc,0xbe,
+ 0xf5,0xbf,0x1c,0xee,0x6e,0xa3,0x22,0x1e,0x25,0x2f,0x16,0x68,0x69,0x5a,0x1d,0xfa,
+ 0x2c,0x3a,0x0f,0x67,0xe1,0x77,0x12,0xe8,0x3d,0xba,0xaa,0xef,0x96,0x9c,0x1f,0x64,
+ 0x32,0xf4,0xa7,0xb3,0x3f,0x7d,0x61,0xbb,0x9a,0x27,0xad,0xfb,0x2f,0x33,0xc4,0x70}};
+const TPM2B_RSA_TEST_VALUE c_RsassaKvt = {RSA_TEST_KEY_SIZE, {
+ 0x67,0x4e,0xdd,0xc2,0xd2,0x6d,0xe0,0x03,0xc4,0xc2,0x41,0xd3,0xd4,0x61,0x30,0xd0,
+ 0xe1,0x68,0x31,0x4a,0xda,0xd9,0xc2,0x5d,0xaa,0xa2,0x7b,0xfb,0x44,0x02,0xf5,0xd6,
+ 0xd8,0x2e,0xcd,0x13,0x36,0xc9,0x4b,0xdb,0x1a,0x4b,0x66,0x1b,0x4f,0x9c,0xb7,0x17,
+ 0xac,0x53,0x37,0x4f,0x21,0xbd,0x0c,0x66,0xac,0x06,0x65,0x52,0x9f,0x04,0xf6,0xa5,
+ 0x22,0x5b,0xf7,0xe6,0x0d,0x3c,0x9f,0x41,0x19,0x09,0x88,0x7c,0x41,0x4c,0x2f,0x9c,
+ 0x8b,0x3c,0xdd,0x7c,0x28,0x78,0x24,0xd2,0x09,0xa6,0x5b,0xf7,0x3c,0x88,0x7e,0x73,
+ 0x5a,0x2d,0x36,0x02,0x4f,0x65,0xb0,0xcb,0xc8,0xdc,0xac,0xa2,0xda,0x8b,0x84,0x91,
+ 0x71,0xe4,0x30,0x8b,0xb6,0x12,0xf2,0xf0,0xd0,0xa0,0x38,0xcf,0x75,0xb7,0x20,0xcb,
+ 0x35,0x51,0x52,0x6b,0xc4,0xf4,0x21,0x95,0xc2,0xf7,0x9a,0x13,0xc1,0x1a,0x7b,0x8f,
+ 0x77,0xda,0x19,0x48,0xbb,0x6d,0x14,0x5d,0xba,0x65,0xb4,0x9e,0x43,0x42,0x58,0x98,
+ 0x0b,0x91,0x46,0xd8,0x4c,0xf3,0x4c,0xaf,0x2e,0x02,0xa6,0xb2,0x49,0x12,0x62,0x43,
+ 0x4e,0xa8,0xac,0xbf,0xfd,0xfa,0x37,0x24,0xea,0x69,0x1c,0xf5,0xae,0xfa,0x08,0x82,
+ 0x30,0xc3,0xc0,0xf8,0x9a,0x89,0x33,0xe1,0x40,0x6d,0x18,0x5c,0x7b,0x90,0x48,0xbf,
+ 0x37,0xdb,0xea,0xfb,0x0e,0xd4,0x2e,0x11,0xfa,0xa9,0x86,0xff,0x00,0x0b,0x7b,0xca,
+ 0x09,0x64,0x6a,0x8f,0x0c,0x0e,0x09,0x14,0x36,0x4a,0x74,0x31,0x18,0x5b,0x18,0xeb,
+ 0xea,0x83,0xc3,0x66,0x68,0xa6,0x7d,0x43,0x06,0x0f,0x99,0x60,0xce,0x65,0x08,0xf6}};
+#endif // SHA1
+#if ALG_SHA256_VALUE == DEFAULT_TEST_HASH
+const TPM2B_RSA_TEST_VALUE c_OaepKvt = {RSA_TEST_KEY_SIZE, {
+ 0x33,0x20,0x6e,0x21,0xc3,0xf6,0xcd,0xf8,0xd7,0x5d,0x9f,0xe9,0x05,0x14,0x8c,0x7c,
+ 0xbb,0x69,0x24,0x9e,0x52,0x8f,0xaf,0x84,0x73,0x21,0x2c,0x85,0xa5,0x30,0x4d,0xb6,
+ 0xb8,0xfa,0x15,0x9b,0xc7,0x8f,0xc9,0x7a,0x72,0x4b,0x85,0xa4,0x1c,0xc5,0xd8,0xe4,
+ 0x92,0xb3,0xec,0xd9,0xa8,0xca,0x5e,0x74,0x73,0x89,0x7f,0xb4,0xac,0x7e,0x68,0x12,
+ 0xb2,0x53,0x27,0x4b,0xbf,0xd0,0x71,0x69,0x46,0x9f,0xef,0xf4,0x70,0x60,0xf8,0xd7,
+ 0xae,0xc7,0x5a,0x27,0x38,0x25,0x2d,0x25,0xab,0x96,0x56,0x66,0x3a,0x23,0x40,0xa8,
+ 0xdb,0xbc,0x86,0xe8,0xf3,0xd2,0x58,0x0b,0x44,0xfc,0x94,0x1e,0xb7,0x5d,0xb4,0x57,
+ 0xb5,0xf3,0x56,0xee,0x9b,0xcf,0x97,0x91,0x29,0x36,0xe3,0x06,0x13,0xa2,0xea,0xd6,
+ 0xd6,0x0b,0x86,0x0b,0x1a,0x27,0xe6,0x22,0xc4,0x7b,0xff,0xde,0x0f,0xbf,0x79,0xc8,
+ 0x1b,0xed,0xf1,0x27,0x62,0xb5,0x8b,0xf9,0xd9,0x76,0x90,0xf6,0xcc,0x83,0x0f,0xce,
+ 0xce,0x2e,0x63,0x7a,0x9b,0xf4,0x48,0x5b,0xd7,0x81,0x2c,0x3a,0xdb,0x59,0x0d,0x4d,
+ 0x9e,0x46,0xe9,0x9e,0x92,0x22,0x27,0x1c,0xb0,0x67,0x8a,0xe6,0x8a,0x16,0x8a,0xdf,
+ 0x95,0x76,0x24,0x82,0xad,0xf1,0xbc,0x97,0xbf,0xd3,0x5e,0x6e,0x14,0x0c,0x5b,0x25,
+ 0xfe,0x58,0xfa,0x64,0xe5,0x14,0x46,0xb7,0x58,0xc6,0x3f,0x7f,0x42,0xd2,0x8e,0x45,
+ 0x13,0x41,0x85,0x12,0x2e,0x96,0x19,0xd0,0x5e,0x7d,0x34,0x06,0x32,0x2b,0xc8,0xd9,
+ 0x0d,0x6c,0x06,0x36,0xa0,0xff,0x47,0x57,0x2c,0x25,0xbc,0x8a,0xa5,0xe2,0xc7,0xe3}};
+const TPM2B_RSA_TEST_VALUE c_RsaesKvt = {RSA_TEST_KEY_SIZE, {
+ 0x39,0xfc,0x10,0x5d,0xf4,0x45,0x3d,0x94,0x53,0x06,0x89,0x24,0xe7,0xe8,0xfd,0x03,
+ 0xac,0xfd,0xbd,0xb2,0x28,0xd3,0x4a,0x52,0xc5,0xd4,0xdb,0x17,0xd4,0x24,0x05,0xc4,
+ 0xeb,0x6a,0xce,0x1d,0xbb,0x37,0xcb,0x09,0xd8,0x6c,0x83,0x19,0x93,0xd4,0xe2,0x88,
+ 0x88,0x9b,0xaf,0x92,0x16,0xc4,0x15,0xbd,0x49,0x13,0x22,0xb7,0x84,0xcf,0x23,0xf2,
+ 0x6f,0x0c,0x3e,0x8f,0xde,0x04,0x09,0x31,0x2d,0x99,0xdf,0xe6,0x74,0x70,0x30,0xde,
+ 0x8c,0xad,0x32,0x86,0xe2,0x7c,0x12,0x90,0x21,0xf3,0x86,0xb7,0xe2,0x64,0xca,0x98,
+ 0xcc,0x64,0x4b,0xef,0x57,0x4f,0x5a,0x16,0x6e,0xd7,0x2f,0x5b,0xf6,0x07,0xad,0x33,
+ 0xb4,0x8f,0x3b,0x3a,0x8b,0xd9,0x06,0x2b,0xed,0x3c,0x3c,0x76,0xf6,0x21,0x31,0xe3,
+ 0xfb,0x2c,0x45,0x61,0x42,0xba,0xe0,0xc3,0x72,0x63,0xd0,0x6b,0x8f,0x36,0x26,0xfb,
+ 0x9e,0x89,0x0e,0x44,0x9a,0xc1,0x84,0x5e,0x84,0x8d,0xb6,0xea,0xf1,0x0d,0x66,0xc7,
+ 0xdb,0x44,0xbd,0x19,0x7c,0x05,0xbe,0xc4,0xab,0x88,0x32,0xbe,0xc7,0x63,0x31,0xe6,
+ 0x38,0xd4,0xe5,0xb8,0x4b,0xf5,0x0e,0x55,0x9a,0x3a,0xe6,0x0a,0xec,0xee,0xe2,0xa8,
+ 0x88,0x04,0xf2,0xb8,0xaa,0x5a,0xd8,0x97,0x5d,0xa0,0xa8,0x42,0xfb,0xd9,0xde,0x80,
+ 0xae,0x4c,0xb3,0xa1,0x90,0x47,0x57,0x03,0x10,0x78,0xa6,0x8f,0x11,0xba,0x4b,0xce,
+ 0x2d,0x56,0xa4,0xe1,0xbd,0xf8,0xa0,0xa4,0xd5,0x48,0x3c,0x63,0x20,0x00,0x38,0xa0,
+ 0xd1,0xe6,0x12,0xe9,0x1d,0xd8,0x49,0xe3,0xd5,0x24,0xb5,0xc5,0x3a,0x1f,0xb0,0xd4}};
+const TPM2B_RSA_TEST_VALUE c_RsapssKvt = {RSA_TEST_KEY_SIZE, {
+ 0x74,0x89,0x29,0x3e,0x1b,0xac,0xc6,0x85,0xca,0xf0,0x63,0x43,0x30,0x7d,0x1c,0x9b,
+ 0x2f,0xbd,0x4d,0x69,0x39,0x5e,0x85,0xe2,0xef,0x86,0x0a,0xc6,0x6b,0xa6,0x08,0x19,
+ 0x6c,0x56,0x38,0x24,0x55,0x92,0x84,0x9b,0x1b,0x8b,0x04,0xcf,0x24,0x14,0x24,0x13,
+ 0x0e,0x8b,0x82,0x6f,0x96,0xc8,0x9a,0x68,0xfc,0x4c,0x02,0xf0,0xdc,0xcd,0x36,0x25,
+ 0x31,0xd5,0x82,0xcf,0xc9,0x69,0x72,0xf6,0x1d,0xab,0x68,0x20,0x2e,0x2d,0x19,0x49,
+ 0xf0,0x2e,0xad,0xd2,0xda,0xaf,0xff,0xb6,0x92,0x83,0x5b,0x8a,0x06,0x2d,0x0c,0x32,
+ 0x11,0x32,0x3b,0x77,0x17,0xf6,0x50,0xfb,0xf8,0x57,0xc9,0xc7,0x9b,0x9e,0xc6,0xd1,
+ 0xa9,0x55,0xf0,0x22,0x35,0xda,0xca,0x3c,0x8e,0xc6,0x9a,0xd8,0x25,0xc8,0x5e,0x93,
+ 0x0d,0xaa,0xa7,0x06,0xaf,0x11,0x29,0x99,0xe7,0x7c,0xee,0x49,0x82,0x30,0xba,0x2c,
+ 0xe2,0x40,0x8f,0x0a,0xa6,0x7b,0x24,0x75,0xc5,0xcd,0x03,0x12,0xf4,0xb2,0x4b,0x3a,
+ 0xd1,0x91,0x3c,0x20,0x0e,0x58,0x2b,0x31,0xf8,0x8b,0xee,0xbc,0x1f,0x95,0x35,0x58,
+ 0x6a,0x73,0xee,0x99,0xb0,0x01,0x42,0x4f,0x66,0xc0,0x66,0xbb,0x35,0x86,0xeb,0xd9,
+ 0x7b,0x55,0x77,0x2d,0x54,0x78,0x19,0x49,0xe8,0xcc,0xfd,0xb1,0xcb,0x49,0xc9,0xea,
+ 0x20,0xab,0xed,0xb5,0xed,0xfe,0xb2,0xb5,0xa8,0xcf,0x05,0x06,0xd5,0x7d,0x2b,0xbb,
+ 0x0b,0x65,0x6b,0x2b,0x6d,0x55,0x95,0x85,0x44,0x8b,0x12,0x05,0xf3,0x4b,0xd4,0x8e,
+ 0x3d,0x68,0x2d,0x29,0x9c,0x05,0x79,0xd6,0xfc,0x72,0x90,0x6a,0xab,0x46,0x38,0x81}};
+const TPM2B_RSA_TEST_VALUE c_RsassaKvt = {RSA_TEST_KEY_SIZE, {
+ 0x8a,0xb1,0x0a,0xb5,0xe4,0x02,0xf7,0xdd,0x45,0x2a,0xcc,0x2b,0x6b,0x8c,0x0e,0x9a,
+ 0x92,0x4f,0x9b,0xc5,0xe4,0x8b,0x82,0xb9,0xb0,0xd9,0x87,0x8c,0xcb,0xf0,0xb0,0x59,
+ 0xa5,0x92,0x21,0xa0,0xa7,0x61,0x5c,0xed,0xa8,0x6e,0x22,0x29,0x46,0xc7,0x86,0x37,
+ 0x4b,0x1b,0x1e,0x94,0x93,0xc8,0x4c,0x17,0x7a,0xae,0x59,0x91,0xf8,0x83,0x84,0xc4,
+ 0x8c,0x38,0xc2,0x35,0x0e,0x7e,0x50,0x67,0x76,0xe7,0xd3,0xec,0x6f,0x0d,0xa0,0x5c,
+ 0x2f,0x0a,0x80,0x28,0xd3,0xc5,0x7d,0x2d,0x1a,0x0b,0x96,0xd6,0xe5,0x98,0x05,0x8c,
+ 0x4d,0xa0,0x1f,0x8c,0xb6,0xfb,0xb1,0xcf,0xe9,0xcb,0x38,0x27,0x60,0x64,0x17,0xca,
+ 0xf4,0x8b,0x61,0xb7,0x1d,0xb6,0x20,0x9d,0x40,0x2a,0x1c,0xfd,0x55,0x40,0x4b,0x95,
+ 0x39,0x52,0x18,0x3b,0xab,0x44,0xe8,0x83,0x4b,0x7c,0x47,0xfb,0xed,0x06,0x9c,0xcd,
+ 0x4f,0xba,0x81,0xd6,0xb7,0x31,0xcf,0x5c,0x23,0xf8,0x25,0xab,0x95,0x77,0x0a,0x8f,
+ 0x46,0xef,0xfb,0x59,0xb8,0x04,0xd7,0x1e,0xf5,0xaf,0x6a,0x1a,0x26,0x9b,0xae,0xf4,
+ 0xf5,0x7f,0x84,0x6f,0x3c,0xed,0xf8,0x24,0x0b,0x43,0xd1,0xba,0x74,0x89,0x4e,0x39,
+ 0xfe,0xab,0xa5,0x16,0xa5,0x28,0xee,0x96,0x84,0x3e,0x16,0x6d,0x5f,0x4e,0x0b,0x7d,
+ 0x94,0x16,0x1b,0x8c,0xf9,0xaa,0x9b,0xc0,0x49,0x02,0x4c,0x3e,0x62,0xff,0xfe,0xa2,
+ 0x20,0x33,0x5e,0xa6,0xdd,0xda,0x15,0x2d,0xb7,0xcd,0xda,0xff,0xb1,0x0b,0x45,0x7b,
+ 0xd3,0xa0,0x42,0x29,0xab,0xa9,0x73,0xe9,0xa4,0xd9,0x8d,0xac,0xa1,0x88,0x2c,0x2d}};
+#endif // SHA256
+#if ALG_SHA384_VALUE == DEFAULT_TEST_HASH
+const TPM2B_RSA_TEST_VALUE c_OaepKvt = {RSA_TEST_KEY_SIZE, {
+ 0x0f,0x3c,0x42,0x4d,0x8c,0x91,0x96,0x05,0x3c,0xfd,0x59,0x3b,0x7f,0x29,0xbc,0x03,
+ 0x67,0xc1,0xff,0x74,0xe7,0x09,0xf4,0x13,0x45,0xbe,0x13,0x1d,0xc9,0x86,0x94,0xfe,
+ 0xed,0xa6,0xe8,0x3a,0xcb,0x89,0x4d,0xec,0x86,0x63,0x4c,0xdb,0xf1,0x95,0xee,0xc1,
+ 0x46,0xc5,0x3b,0xd8,0xf8,0xa2,0x41,0x6a,0x60,0x8b,0x9e,0x5e,0x7f,0x20,0x16,0xe3,
+ 0x69,0xb6,0x2d,0x92,0xfc,0x60,0xa2,0x74,0x88,0xd5,0xc7,0xa6,0xd1,0xff,0xe3,0x45,
+ 0x02,0x51,0x39,0xd9,0xf3,0x56,0x0b,0x91,0x80,0xe0,0x6c,0xa8,0xc3,0x78,0xef,0x34,
+ 0x22,0x8c,0xf5,0xfb,0x47,0x98,0x5d,0x57,0x8e,0x3a,0xb9,0xff,0x92,0x04,0xc7,0xc2,
+ 0x6e,0xfa,0x14,0xc1,0xb9,0x68,0x15,0x5c,0x12,0xe8,0xa8,0xbe,0xea,0xe8,0x8d,0x9b,
+ 0x48,0x28,0x35,0xdb,0x4b,0x52,0xc1,0x2d,0x85,0x47,0x83,0xd0,0xe9,0xae,0x90,0x6e,
+ 0x65,0xd4,0x34,0x7f,0x81,0xce,0x69,0xf0,0x96,0x62,0xf7,0xec,0x41,0xd5,0xc2,0xe3,
+ 0x4b,0xba,0x9c,0x8a,0x02,0xce,0xf0,0x5d,0x14,0xf7,0x09,0x42,0x8e,0x4a,0x27,0xfe,
+ 0x3e,0x66,0x42,0x99,0x03,0xe1,0x69,0xbd,0xdb,0x7f,0x9b,0x70,0xeb,0x4e,0x9c,0xac,
+ 0x45,0x67,0x91,0x9f,0x75,0x10,0xc6,0xfc,0x14,0xe1,0x28,0xc1,0x0e,0xe0,0x7e,0xc0,
+ 0x5c,0x1d,0xee,0xe8,0xff,0x45,0x79,0x51,0x86,0x08,0xe6,0x39,0xac,0xb5,0xfd,0xb8,
+ 0xf1,0xdd,0x2e,0xf4,0xb2,0x1a,0x69,0x0d,0xd9,0x98,0x8e,0xdb,0x85,0x61,0x70,0x20,
+ 0x82,0x91,0x26,0x87,0x80,0xc4,0x6a,0xd8,0x3b,0x91,0x4d,0xd3,0x33,0x84,0xad,0xb7}};
+const TPM2B_RSA_TEST_VALUE c_RsaesKvt = {RSA_TEST_KEY_SIZE, {
+ 0x44,0xd5,0x9f,0xbc,0x48,0x03,0x3d,0x9f,0x22,0x91,0x2a,0xab,0x3c,0x31,0x71,0xab,
+ 0x86,0x3f,0x0f,0x6f,0x59,0x5b,0x93,0x27,0xbc,0xbc,0xcd,0x29,0x38,0x43,0x2a,0x3b,
+ 0x3b,0xd2,0xb3,0x45,0x40,0xba,0x15,0xb4,0x45,0xe3,0x56,0xab,0xff,0xb3,0x20,0x26,
+ 0x39,0xcc,0x48,0xc5,0x5d,0x41,0x0d,0x2f,0x57,0x7f,0x9d,0x16,0x2e,0x26,0x57,0xc7,
+ 0x6b,0xf3,0x36,0x54,0xbd,0xb6,0x1d,0x46,0x4e,0x13,0x50,0xd7,0x61,0x9d,0x8d,0x7b,
+ 0xeb,0x21,0x9f,0x79,0xf3,0xfd,0xe0,0x1b,0xa8,0xed,0x6d,0x29,0x33,0x0d,0x65,0x94,
+ 0x24,0x1e,0x62,0x88,0x6b,0x2b,0x4e,0x39,0xf5,0x80,0x39,0xca,0x76,0x95,0xbc,0x7c,
+ 0x27,0x1d,0xdd,0x3a,0x11,0xf1,0x3e,0x54,0x03,0xb7,0x43,0x91,0x99,0x33,0xfe,0x9d,
+ 0x14,0x2c,0x87,0x9a,0x95,0x18,0x1f,0x02,0x04,0x6a,0xe2,0xb7,0x81,0x14,0x13,0x45,
+ 0x16,0xfb,0xe4,0xb7,0x8f,0xab,0x2b,0xd7,0x60,0x34,0x8a,0x55,0xbc,0x01,0x8c,0x49,
+ 0x02,0x29,0xf1,0x9c,0x94,0x98,0x44,0xd0,0x94,0xcb,0xd4,0x85,0x4c,0x3b,0x77,0x72,
+ 0x99,0xd5,0x4b,0xc6,0x3b,0xe4,0xd2,0xc8,0xe9,0x6a,0x23,0x18,0x3b,0x3b,0x5e,0x32,
+ 0xec,0x70,0x84,0x5d,0xbb,0x6a,0x8f,0x0c,0x5f,0x55,0xa5,0x30,0x34,0x48,0xbb,0xc2,
+ 0xdf,0x12,0xb9,0x81,0xad,0x36,0x3f,0xf0,0x24,0x16,0x48,0x04,0x4a,0x7f,0xfd,0x9f,
+ 0x4c,0xea,0xfe,0x1d,0x83,0xd0,0x81,0xad,0x25,0x6c,0x5f,0x45,0x36,0x91,0xf0,0xd5,
+ 0x8b,0x53,0x0a,0xdf,0xec,0x9f,0x04,0x58,0xc4,0x35,0xa0,0x78,0x1f,0x68,0xe0,0x22}};
+const TPM2B_RSA_TEST_VALUE c_RsapssKvt = {RSA_TEST_KEY_SIZE, {
+ 0x3f,0x3a,0x82,0x6d,0x42,0xe3,0x8b,0x4f,0x45,0x9c,0xda,0x6c,0xbe,0xbe,0xcd,0x00,
+ 0x98,0xfb,0xbe,0x59,0x30,0xc6,0x3c,0xaa,0xb3,0x06,0x27,0xb5,0xda,0xfa,0xb2,0xc3,
+ 0x43,0xb7,0xbd,0xe9,0xd3,0x23,0xed,0x80,0xce,0x74,0xb3,0xb8,0x77,0x8d,0xe6,0x8d,
+ 0x3c,0xe5,0xf5,0xd7,0x80,0xcf,0x38,0x55,0x76,0xd7,0x87,0xa8,0xd6,0x3a,0xcf,0xfd,
+ 0xd8,0x91,0x65,0xab,0x43,0x66,0x50,0xb7,0x9a,0x13,0x6b,0x45,0x80,0x76,0x86,0x22,
+ 0x27,0x72,0xf7,0xbb,0x65,0x22,0x5c,0x55,0x60,0xd8,0x84,0x9f,0xf2,0x61,0x52,0xac,
+ 0xf2,0x4f,0x5b,0x7b,0x21,0xe1,0xf5,0x4b,0x8f,0x01,0xf2,0x4b,0xcf,0xd3,0xfb,0x74,
+ 0x5e,0x6e,0x96,0xb4,0xa8,0x0f,0x01,0x9b,0x26,0x54,0x0a,0x70,0x55,0x26,0xb7,0x0b,
+ 0xe8,0x01,0x68,0x66,0x0d,0x6f,0xb5,0xfc,0x66,0xbd,0x9e,0x44,0xed,0x6a,0x1e,0x3c,
+ 0x3b,0x61,0x5d,0xe8,0xdb,0x99,0x5b,0x67,0xbf,0x94,0xfb,0xe6,0x8c,0x4b,0x07,0xcb,
+ 0x43,0x3a,0x0d,0xb1,0x1b,0x10,0x66,0x81,0xe2,0x0d,0xe7,0xd1,0xca,0x85,0xa7,0x50,
+ 0x82,0x2d,0xbf,0xed,0xcf,0x43,0x6d,0xdb,0x2c,0x7b,0x73,0x20,0xfe,0x73,0x3f,0x19,
+ 0xc6,0xdb,0x69,0xb8,0xc3,0xd3,0xf4,0xe5,0x64,0xf8,0x36,0x8e,0xd5,0xd8,0x09,0x2a,
+ 0x5f,0x26,0x70,0xa1,0xd9,0x5b,0x14,0xf8,0x22,0xe9,0x9d,0x22,0x51,0xf4,0x52,0xc1,
+ 0x6f,0x53,0xf5,0xca,0x0d,0xda,0x39,0x8c,0x29,0x42,0xe8,0x58,0x89,0xbb,0xd1,0x2e,
+ 0xc5,0xdb,0x86,0x8d,0xaf,0xec,0x58,0x36,0x8d,0x8d,0x57,0x23,0xd5,0xdd,0xb9,0x24}};
+const TPM2B_RSA_TEST_VALUE c_RsassaKvt = {RSA_TEST_KEY_SIZE, {
+ 0x39,0x10,0x58,0x7d,0x6d,0xa8,0xd5,0x90,0x07,0xd6,0x2b,0x13,0xe9,0xd8,0x93,0x7e,
+ 0xf3,0x5d,0x71,0xe0,0xf0,0x33,0x3a,0x4a,0x22,0xf3,0xe6,0x95,0xd3,0x8e,0x8c,0x41,
+ 0xe7,0xb3,0x13,0xde,0x4a,0x45,0xd3,0xd1,0xfb,0xb1,0x3f,0x9b,0x39,0xa5,0x50,0x58,
+ 0xef,0xb6,0x3a,0x43,0xdd,0x54,0xab,0xda,0x9d,0x32,0x49,0xe4,0x57,0x96,0xe5,0x1b,
+ 0x1d,0x8f,0x33,0x8e,0x07,0x67,0x56,0x14,0xc1,0x18,0x78,0xa2,0x52,0xe6,0x2e,0x07,
+ 0x81,0xbe,0xd8,0xca,0x76,0x63,0x68,0xc5,0x47,0xa2,0x92,0x5e,0x4c,0xfd,0x14,0xc7,
+ 0x46,0x14,0xbe,0xc7,0x85,0xef,0xe6,0xb8,0x46,0xcb,0x3a,0x67,0x66,0x89,0xc6,0xee,
+ 0x9d,0x64,0xf5,0x0d,0x09,0x80,0x9a,0x6f,0x0e,0xeb,0xe4,0xb9,0xe9,0xab,0x90,0x4f,
+ 0xe7,0x5a,0xc8,0xca,0xf6,0x16,0x0a,0x82,0xbd,0xb7,0x76,0x59,0x08,0x2d,0xd9,0x40,
+ 0x5d,0xaa,0xa5,0xef,0xfb,0xe3,0x81,0x2c,0x2c,0x5c,0xa8,0x16,0xbd,0x63,0x20,0xc2,
+ 0x4d,0x3b,0x51,0xaa,0x62,0x1f,0x06,0xe5,0xbb,0x78,0x44,0x04,0x0c,0x5c,0xe1,0x1b,
+ 0x6b,0x9d,0x21,0x10,0xaf,0x48,0x48,0x98,0x97,0x77,0xc2,0x73,0xb4,0x98,0x64,0xcc,
+ 0x94,0x2c,0x29,0x28,0x45,0x36,0xd1,0xc5,0xd0,0x2f,0x97,0x27,0x92,0x65,0x22,0xbb,
+ 0x63,0x79,0xea,0xf5,0xff,0x77,0x0f,0x4b,0x56,0x8a,0x9f,0xad,0x1a,0x97,0x67,0x39,
+ 0x69,0xb8,0x4c,0x6c,0xc2,0x56,0xc5,0x7a,0xa8,0x14,0x5a,0x24,0x7a,0xa4,0x6e,0x55,
+ 0xb2,0x86,0x1d,0xf4,0x62,0x5a,0x2d,0x87,0x6d,0xde,0x99,0x78,0x2d,0xef,0xd7,0xdc}};
+#endif // SHA384
+#if ALG_SHA512_VALUE == DEFAULT_TEST_HASH
+const TPM2B_RSA_TEST_VALUE c_OaepKvt = {RSA_TEST_KEY_SIZE, {
+ 0x48,0x45,0xa7,0x70,0xb2,0x41,0xb7,0x48,0x5e,0x79,0x8c,0xdf,0x1c,0xc6,0x7e,0xbb,
+ 0x11,0x80,0x82,0x52,0xbf,0x40,0x3d,0x90,0x03,0x6e,0x20,0x3a,0xb9,0x65,0xc8,0x51,
+ 0x4c,0xbd,0x9c,0xa9,0x43,0x89,0xd0,0x57,0x0c,0xa3,0x69,0x22,0x7e,0x82,0x2a,0x1c,
+ 0x1d,0x5a,0x80,0x84,0x81,0xbb,0x5e,0x5e,0xd0,0xc1,0x66,0x9a,0xac,0x00,0xba,0x14,
+ 0xa2,0xe9,0xd0,0x3a,0x89,0x5a,0x63,0xe2,0xec,0x92,0x05,0xf4,0x47,0x66,0x12,0x7f,
+ 0xdb,0xa7,0x3c,0x5b,0x67,0xe1,0x55,0xca,0x0a,0x27,0xbf,0x39,0x89,0x11,0x05,0xba,
+ 0x9b,0x5a,0x9b,0x65,0x44,0xad,0x78,0xcf,0x8f,0x94,0xf6,0x9a,0xb4,0x52,0x39,0x0e,
+ 0x00,0xba,0xbc,0xe0,0xbd,0x6f,0x81,0x2d,0x76,0x42,0x66,0x70,0x07,0x77,0xbf,0x09,
+ 0x88,0x2a,0x0c,0xb1,0x56,0x3e,0xee,0xfd,0xdc,0xb6,0x3c,0x0d,0xc5,0xa4,0x0d,0x10,
+ 0x32,0x80,0x3e,0x1e,0xfe,0x36,0x8f,0xb5,0x42,0xc1,0x21,0x7b,0xdf,0xdf,0x4a,0xd2,
+ 0x68,0x0c,0x01,0x9f,0x4a,0xfd,0xd4,0xec,0xf7,0x49,0x06,0xab,0xed,0xc6,0xd5,0x1b,
+ 0x63,0x76,0x38,0xc8,0x6c,0xc7,0x4f,0xcb,0x29,0x8a,0x0e,0x6f,0x33,0xaf,0x69,0x31,
+ 0x8e,0xa7,0xdd,0x9a,0x36,0xde,0x9b,0xf1,0x0b,0xfb,0x20,0xa0,0x6d,0x33,0x31,0xc9,
+ 0x9e,0xb4,0x2e,0xc5,0x40,0x0e,0x60,0x71,0x36,0x75,0x05,0xf9,0x37,0xe0,0xca,0x8e,
+ 0x8f,0x56,0xe0,0xea,0x9b,0xeb,0x17,0xf3,0xca,0x40,0xc3,0x48,0x01,0xba,0xdc,0xc6,
+ 0x4b,0x2b,0x5b,0x7b,0x5c,0x81,0xa6,0xbb,0xc7,0x43,0xc0,0xbe,0xc0,0x30,0x7b,0x55}};
+const TPM2B_RSA_TEST_VALUE c_RsaesKvt = {RSA_TEST_KEY_SIZE, {
+ 0x74,0x83,0xfa,0x52,0x65,0x50,0x68,0xd0,0x82,0x05,0x72,0x70,0x78,0x1c,0xac,0x10,
+ 0x23,0xc5,0x07,0xf8,0x93,0xd2,0xeb,0x65,0x87,0xbb,0x47,0xc2,0xfb,0x30,0x9e,0x61,
+ 0x4c,0xac,0x04,0x57,0x5a,0x7c,0xeb,0x29,0x08,0x84,0x86,0x89,0x1e,0x8f,0x07,0x32,
+ 0xa3,0x8b,0x70,0xe7,0xa2,0x9f,0x9c,0x42,0x71,0x3d,0x23,0x59,0x82,0x5e,0x8a,0xde,
+ 0xd6,0xfb,0xd8,0xc5,0x8b,0xc0,0xdb,0x10,0x38,0x87,0xd3,0xbf,0x04,0xb0,0x66,0xb9,
+ 0x85,0x81,0x54,0x4c,0x69,0xdc,0xba,0x78,0xf3,0x4a,0xdb,0x25,0xa2,0xf2,0x34,0x55,
+ 0xdd,0xaa,0xa5,0xc4,0xed,0x55,0x06,0x0e,0x2a,0x30,0x77,0xab,0x82,0x79,0xf0,0xcd,
+ 0x9d,0x6f,0x09,0xa0,0xc8,0x82,0xc9,0xe0,0x61,0xda,0x40,0xcd,0x17,0x59,0xc0,0xef,
+ 0x95,0x6d,0xa3,0x6d,0x1c,0x2b,0xee,0x24,0xef,0xd8,0x4a,0x55,0x6c,0xd6,0x26,0x42,
+ 0x32,0x17,0xfd,0x6a,0xb3,0x4f,0xde,0x07,0x2f,0x10,0xd4,0xac,0x14,0xea,0x89,0x68,
+ 0xcc,0xd3,0x07,0xb7,0xcf,0xba,0x39,0x20,0x63,0x20,0x7b,0x44,0x8b,0x48,0x60,0x5d,
+ 0x3a,0x2a,0x0a,0xe9,0x68,0xab,0x15,0x46,0x27,0x64,0xb5,0x82,0x06,0x29,0xe7,0x25,
+ 0xca,0x46,0x48,0x6e,0x2a,0x34,0x57,0x4b,0x81,0x75,0xae,0xb6,0xfd,0x6f,0x51,0x5f,
+ 0x04,0x59,0xc7,0x15,0x1f,0xe0,0x68,0xf7,0x36,0x2d,0xdf,0xc8,0x9d,0x05,0x27,0x2d,
+ 0x3f,0x2b,0x59,0x5d,0xcb,0xf3,0xc4,0x92,0x6e,0x00,0xa8,0x8d,0xd0,0x69,0xe5,0x59,
+ 0xda,0xba,0x4f,0x38,0xf5,0xa0,0x8b,0xf1,0x73,0xe9,0x0d,0xee,0x64,0xe5,0xa2,0xd8}};
+const TPM2B_RSA_TEST_VALUE c_RsapssKvt = {RSA_TEST_KEY_SIZE, {
+ 0x1b,0xca,0x8b,0x18,0x15,0x3b,0x95,0x5b,0x0a,0x89,0x10,0x03,0x7f,0x7c,0xa0,0xc9,
+ 0x66,0x57,0x86,0x6a,0xc9,0xeb,0x82,0x71,0xf3,0x8d,0x6f,0xa9,0xa4,0x2d,0xd0,0x22,
+ 0xdf,0xe9,0xc6,0x71,0x5b,0xf4,0x27,0x38,0x5b,0x2c,0x8a,0x54,0xcc,0x85,0x11,0x69,
+ 0x6d,0x6f,0x42,0xe7,0x22,0xcb,0xd6,0xad,0x1a,0xc5,0xab,0x6a,0xa5,0xfc,0xa5,0x70,
+ 0x72,0x4a,0x62,0x25,0xd0,0xa2,0x16,0x61,0xab,0xac,0x31,0xa0,0x46,0x24,0x4f,0xdd,
+ 0x9a,0x36,0x55,0xb6,0x00,0x9e,0x23,0x50,0x0d,0x53,0x01,0xb3,0x46,0x56,0xb2,0x1d,
+ 0x33,0x5b,0xca,0x41,0x7f,0x65,0x7e,0x00,0x5c,0x12,0xff,0x0a,0x70,0x5d,0x8c,0x69,
+ 0x4a,0x02,0xee,0x72,0x30,0xa7,0x5c,0xa4,0xbb,0xbe,0x03,0x0c,0xe4,0x5f,0x33,0xb6,
+ 0x78,0x91,0x9d,0xd8,0xec,0x34,0x03,0x2e,0x63,0x32,0xc7,0x2a,0x36,0x50,0xd5,0x8b,
+ 0x0e,0x7f,0x54,0x4e,0xf4,0x29,0x11,0x1b,0xcd,0x0f,0x37,0xa5,0xbc,0x61,0x83,0x50,
+ 0xfa,0x18,0x75,0xd9,0xfe,0xa7,0xe8,0x9b,0xc1,0x4f,0x96,0x37,0x81,0x71,0xdf,0x71,
+ 0x8b,0x89,0x81,0xf4,0x95,0xb5,0x29,0x66,0x41,0x0c,0x73,0xd7,0x0b,0x21,0xb4,0xfb,
+ 0xf9,0x63,0x2f,0xe9,0x7b,0x38,0xaa,0x20,0xc3,0x96,0xcc,0xb7,0xb2,0x24,0xa1,0xe0,
+ 0x59,0x9c,0x10,0x9e,0x5a,0xf7,0xe3,0x02,0xe6,0x23,0xe2,0x44,0x21,0x3f,0x6e,0x5e,
+ 0x79,0xb2,0x93,0x7d,0xce,0xed,0xe2,0xe1,0xab,0x98,0x07,0xa7,0xbd,0xbc,0xd8,0xf7,
+ 0x06,0xeb,0xc5,0xa6,0x37,0x18,0x11,0x88,0xf7,0x63,0x39,0xb9,0x57,0x29,0xdc,0x03}};
+const TPM2B_RSA_TEST_VALUE c_RsassaKvt = {RSA_TEST_KEY_SIZE, {
+ 0x05,0x55,0x00,0x62,0x01,0xc6,0x04,0x31,0x55,0x73,0x3f,0x2a,0xf9,0xd4,0x0f,0xc1,
+ 0x2b,0xeb,0xd8,0xc8,0xdb,0xb2,0xab,0x6c,0x26,0xde,0x2d,0x89,0xc2,0x2d,0x36,0x62,
+ 0xc8,0x22,0x5d,0x58,0x03,0xb1,0x46,0x14,0xa5,0xd4,0xbc,0x25,0x6b,0x7f,0x8f,0x14,
+ 0x7e,0x03,0x2f,0x3d,0xb8,0x39,0xa5,0x79,0x13,0x7e,0x22,0x2a,0xb9,0x3e,0x8f,0xaa,
+ 0x01,0x7c,0x03,0x12,0x21,0x6c,0x2a,0xb4,0x39,0x98,0x6d,0xff,0x08,0x6c,0x59,0x2d,
+ 0xdc,0xc6,0xf1,0x77,0x62,0x10,0xa6,0xcc,0xe2,0x71,0x8e,0x97,0x00,0x87,0x5b,0x0e,
+ 0x20,0x00,0x3f,0x18,0x63,0x83,0xf0,0xe4,0x0a,0x64,0x8c,0xe9,0x8c,0x91,0xe7,0x89,
+ 0x04,0x64,0x2c,0x8b,0x41,0xc8,0xac,0xf6,0x5a,0x75,0xe6,0xa5,0x76,0x43,0xcb,0xa5,
+ 0x33,0x8b,0x07,0xc9,0x73,0x0f,0x45,0xa4,0xc3,0xac,0xc1,0xc3,0xe6,0xe7,0x21,0x66,
+ 0x1c,0xba,0xbf,0xea,0x3e,0x39,0xfa,0xb2,0xe2,0x8f,0xfe,0x9c,0xb4,0x85,0x89,0x33,
+ 0x2a,0x0c,0xc8,0x5d,0x58,0xe1,0x89,0x12,0xe9,0x4d,0x42,0xb3,0x1f,0x99,0x0c,0x3e,
+ 0xd8,0xb2,0xeb,0xf5,0x88,0xfb,0xe1,0x4b,0x8e,0xdc,0xd3,0xa8,0xda,0xbe,0x04,0x45,
+ 0xbf,0x56,0xc6,0x54,0x70,0x00,0xb8,0x66,0x46,0x3a,0xa3,0x1e,0xb6,0xeb,0x1a,0xa0,
+ 0x0b,0xd3,0x9a,0x9a,0x52,0xda,0x60,0x69,0xb7,0xef,0x93,0x47,0x38,0xab,0x1a,0xa0,
+ 0x22,0x6e,0x76,0x06,0xb6,0x74,0xaf,0x74,0x8f,0x51,0xc0,0x89,0x5a,0x4b,0xbe,0x6a,
+ 0x91,0x18,0x25,0x7d,0xa6,0x77,0xe6,0xfd,0xc2,0x62,0x36,0x07,0xc6,0xef,0x79,0xc9}};
+#endif // SHA512
+
+#endif
diff --git a/src/tpm2/RunCommand.c b/src/tpm2/RunCommand.c
new file mode 100644
index 0000000..06465b7
--- /dev/null
+++ b/src/tpm2/RunCommand.c
@@ -0,0 +1,105 @@
+/********************************************************************************/
+/* */
+/* Platform specific entry and fail processing */
+/* Written by Ken Goldman */
+/* IBM Thomas J. Watson Research Center */
+/* $Id: RunCommand.c 1476 2019-06-10 19:32:03Z kgoldman $ */
+/* */
+/* Licenses and Notices */
+/* */
+/* 1. Copyright Licenses: */
+/* */
+/* - Trusted Computing Group (TCG) grants to the user of the source code in */
+/* this specification (the "Source Code") a worldwide, irrevocable, */
+/* nonexclusive, royalty free, copyright license to reproduce, create */
+/* derivative works, distribute, display and perform the Source Code and */
+/* derivative works thereof, and to grant others the rights granted herein. */
+/* */
+/* - The TCG grants to the user of the other parts of the specification */
+/* (other than the Source Code) the rights to reproduce, distribute, */
+/* display, and perform the specification solely for the purpose of */
+/* developing products based on such documents. */
+/* */
+/* 2. Source Code Distribution Conditions: */
+/* */
+/* - Redistributions of Source Code must retain the above copyright licenses, */
+/* this list of conditions and the following disclaimers. */
+/* */
+/* - Redistributions in binary form must reproduce the above copyright */
+/* licenses, this list of conditions and the following disclaimers in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* 3. Disclaimers: */
+/* */
+/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
+/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
+/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
+/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
+/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
+/* information on specification licensing rights available through TCG */
+/* membership agreements. */
+/* */
+/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
+/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
+/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
+/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
+/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
+/* */
+/* - Without limitation, TCG and its members and licensors disclaim all */
+/* liability, including liability for infringement of any proprietary */
+/* rights, relating to use of information in this specification and to the */
+/* implementation of this specification, and TCG disclaims all liability for */
+/* cost of procurement of substitute goods or services, lost profits, loss */
+/* of use, loss of data or any incidental, consequential, direct, indirect, */
+/* or special damages, whether under contract, tort, warranty or otherwise, */
+/* arising in any way out of use or reliance upon this specification or any */
+/* information herein. */
+/* */
+/* (c) Copyright IBM Corp. and others, 2016 - 2019 */
+/* */
+/********************************************************************************/
+
+/* C.11 RunCommand.c */
+/* C.11.1. Introduction */
+/* This module provides the platform specific entry and fail processing. The _plat__RunCommand()
+ function is used to call to ExecuteCommand() in the TPM code. This function does whatever
+ processing is necessary to set up the platform in anticipation of the call to the TPM including
+ setup for error processing. */
+/* The _plat__Fail() function is called when there is a failure in the TPM. The TPM code will have
+ set the flag to indicate that the TPM is in failure mode. This call will then recursively call
+ ExecuteCommand() in order to build the failure mode response. When ExecuteCommand() returns to
+ _plat__Fail(), the platform will do some platform specif operation to return to the environment
+ in which the TPM is executing. For a simulator, setjmp/longjmp is used. For an OS, a system exit
+ to the OS would be appropriate. */
+/* C.11.2. Includes and locals */
+#include "Platform.h"
+#include <setjmp.h>
+#include "ExecCommand_fp.h"
+jmp_buf s_jumpBuffer;
+/* C.11.3. Functions */
+/* C.11.3.1. _plat__RunCommand() */
+/* This version of RunCommand() will set up a jum_buf and call ExecuteCommand(). If the command
+ executes without failing, it will return and RunCommand() will return. If there is a failure in
+ the command, then _plat__Fail() is called and it will longjump back to RunCommand() which will
+ call ExecuteCommand() again. However, this time, the TPM will be in failure mode so
+ ExecuteCommand() will simply build a failure response and return. */
+LIB_EXPORT void
+_plat__RunCommand(
+ uint32_t requestSize, // IN: command buffer size
+ unsigned char *request, // IN: command buffer
+ uint32_t *responseSize, // IN/OUT: response buffer size
+ unsigned char **response // IN/OUT: response buffer
+ )
+{
+ setjmp(s_jumpBuffer);
+ ExecuteCommand(requestSize, request, responseSize, response);
+}
+/* C.11.3.2. _plat__Fail() */
+/* This is the platform depended failure exit for the TPM. */
+LIB_EXPORT NORETURN void
+_plat__Fail(
+ void
+ )
+{
+ longjmp(&s_jumpBuffer[0], 1);
+}
diff --git a/src/tpm2/SelfTest.h b/src/tpm2/SelfTest.h
new file mode 100644
index 0000000..1973721
--- /dev/null
+++ b/src/tpm2/SelfTest.h
@@ -0,0 +1,130 @@
+/********************************************************************************/
+/* */
+/* Structure definitions for the self-test */
+/* Written by Ken Goldman */
+/* IBM Thomas J. Watson Research Center */
+/* $Id: SelfTest.h 1594 2020-03-26 22:15:48Z kgoldman $ */
+/* */
+/* Licenses and Notices */
+/* */
+/* 1. Copyright Licenses: */
+/* */
+/* - Trusted Computing Group (TCG) grants to the user of the source code in */
+/* this specification (the "Source Code") a worldwide, irrevocable, */
+/* nonexclusive, royalty free, copyright license to reproduce, create */
+/* derivative works, distribute, display and perform the Source Code and */
+/* derivative works thereof, and to grant others the rights granted herein. */
+/* */
+/* - The TCG grants to the user of the other parts of the specification */
+/* (other than the Source Code) the rights to reproduce, distribute, */
+/* display, and perform the specification solely for the purpose of */
+/* developing products based on such documents. */
+/* */
+/* 2. Source Code Distribution Conditions: */
+/* */
+/* - Redistributions of Source Code must retain the above copyright licenses, */
+/* this list of conditions and the following disclaimers. */
+/* */
+/* - Redistributions in binary form must reproduce the above copyright */
+/* licenses, this list of conditions and the following disclaimers in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* 3. Disclaimers: */
+/* */
+/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
+/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
+/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
+/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
+/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
+/* information on specification licensing rights available through TCG */
+/* membership agreements. */
+/* */
+/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
+/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
+/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
+/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
+/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
+/* */
+/* - Without limitation, TCG and its members and licensors disclaim all */
+/* liability, including liability for infringement of any proprietary */
+/* rights, relating to use of information in this specification and to the */
+/* implementation of this specification, and TCG disclaims all liability for */
+/* cost of procurement of substitute goods or services, lost profits, loss */
+/* of use, loss of data or any incidental, consequential, direct, indirect, */
+/* or special damages, whether under contract, tort, warranty or otherwise, */
+/* arising in any way out of use or reliance upon this specification or any */
+/* information herein. */
+/* */
+/* (c) Copyright IBM Corp. and others, 2016 - 2020 */
+/* */
+/********************************************************************************/
+
+#ifndef SELFTEST_H
+#define SELFTEST_H
+
+/* 10.1.10 SelfTest.h */
+/* 10.1.10.1 Introduction */
+
+/* This file contains the structure definitions for the self-test. It also contains macros for use
+ when the self-test is implemented. */
+
+#define SELF_TEST_FAILURE FAIL(FATAL_ERROR_SELF_TEST)
+
+// Use the definition of key sizes to set algorithm values for key size.
+
+#define AES_ENTRIES (AES_128 + AES_192 + AES_256)
+#define SM4_ENTRIES (SM4_128)
+#define CAMELLIA_ENTRIES (CAMELLIA_128 + CAMELLIA_192 + CAMELLIA_256)
+#define TDES_ENTRIES (TDES_128 * 2 + TDES_192 * 2) /* libtpms changed */
+#define NUM_SYMS (AES_ENTRIES + SM4_ENTRIES + CAMELLIA_ENTRIES + TDES_ENTRIES)
+typedef UINT32 SYM_INDEX;
+
+/* These two defines deal with the fact that the TPM_ALG_ID table does not delimit the symmetric
+ mode values with a SYM_MODE_FIRST and SYM_MODE_LAST */
+
+#define SYM_MODE_FIRST ALG_CTR_VALUE
+#define SYM_MODE_LAST ALG_ECB_VALUE
+
+#define NUM_SYM_MODES (SYM_MODE_LAST - SYM_MODE_FIRST + 1)
+
+/* Define a type to hold a bit vector for the modes. */
+#if NUM_SYM_MODES <= 0
+#error "No symmetric modes implemented"
+#elif NUM_SYM_MODES <= 8
+typedef BYTE SYM_MODES;
+#elif NUM_SYM_MODES <= 16
+typedef UINT16 SYM_MODES;
+#elif NUM_SYM_MODES <= 32
+typedef UINT32 SYM_MODES;
+#else
+#error "Too many symmetric modes"
+#endif
+typedef struct SYMMETRIC_TEST_VECTOR {
+ const TPM_ALG_ID alg; // the algorithm
+ const UINT16 keyBits; // bits in the key
+ const BYTE *key; // The test key
+ const UINT32 ivSize; // block size of the algorithm
+ const UINT32 dataInOutSize; // size to encrypt/decrypt
+ const BYTE *dataIn; // data to encrypt
+ const BYTE *dataOut[NUM_SYM_MODES];// data to decrypt
+} SYMMETRIC_TEST_VECTOR;
+#if ALG_SHA512
+# define DEFAULT_TEST_HASH ALG_SHA512_VALUE
+# define DEFAULT_TEST_DIGEST_SIZE SHA512_DIGEST_SIZE
+# define DEFAULT_TEST_HASH_BLOCK_SIZE SHA512_BLOCK_SIZE
+#elif ALG_SHA384
+# define DEFAULT_TEST_HASH ALG_SHA384_VALUE
+# define DEFAULT_TEST_DIGEST_SIZE SHA384_DIGEST_SIZE
+# define DEFAULT_TEST_HASH_BLOCK_SIZE SHA384_BLOCK_SIZE
+#elif ALG_SHA256
+# define DEFAULT_TEST_HASH ALG_SHA256_VALUE
+# define DEFAULT_TEST_DIGEST_SIZE SHA256_DIGEST_SIZE
+# define DEFAULT_TEST_HASH_BLOCK_SIZE SHA256_BLOCK_SIZE
+#elif ALG_SHA1
+# define DEFAULT_TEST_HASH ALG_SHA1_VALUE
+# define DEFAULT_TEST_DIGEST_SIZE SHA1_DIGEST_SIZE
+# define DEFAULT_TEST_HASH_BLOCK_SIZE SHA1_BLOCK_SIZE
+#endif
+
+
+#endif
diff --git a/src/tpm2/SelfTest_fp.h b/src/tpm2/SelfTest_fp.h
new file mode 100644
index 0000000..63ecb2c
--- /dev/null
+++ b/src/tpm2/SelfTest_fp.h
@@ -0,0 +1,78 @@
+/********************************************************************************/
+/* */
+/* */
+/* Written by Ken Goldman */
+/* IBM Thomas J. Watson Research Center */
+/* $Id: SelfTest_fp.h 809 2016-11-16 18:31:54Z kgoldman $ */
+/* */
+/* Licenses and Notices */
+/* */
+/* 1. Copyright Licenses: */
+/* */
+/* - Trusted Computing Group (TCG) grants to the user of the source code in */
+/* this specification (the "Source Code") a worldwide, irrevocable, */
+/* nonexclusive, royalty free, copyright license to reproduce, create */
+/* derivative works, distribute, display and perform the Source Code and */
+/* derivative works thereof, and to grant others the rights granted herein. */
+/* */
+/* - The TCG grants to the user of the other parts of the specification */
+/* (other than the Source Code) the rights to reproduce, distribute, */
+/* display, and perform the specification solely for the purpose of */
+/* developing products based on such documents. */
+/* */
+/* 2. Source Code Distribution Conditions: */
+/* */
+/* - Redistributions of Source Code must retain the above copyright licenses, */
+/* this list of conditions and the following disclaimers. */
+/* */
+/* - Redistributions in binary form must reproduce the above copyright */
+/* licenses, this list of conditions and the following disclaimers in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* 3. Disclaimers: */
+/* */
+/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
+/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
+/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
+/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
+/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
+/* information on specification licensing rights available through TCG */
+/* membership agreements. */
+/* */
+/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
+/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
+/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
+/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
+/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
+/* */
+/* - Without limitation, TCG and its members and licensors disclaim all */
+/* liability, including liability for infringement of any proprietary */
+/* rights, relating to use of information in this specification and to the */
+/* implementation of this specification, and TCG disclaims all liability for */
+/* cost of procurement of substitute goods or services, lost profits, loss */
+/* of use, loss of data or any incidental, consequential, direct, indirect, */
+/* or special damages, whether under contract, tort, warranty or otherwise, */
+/* arising in any way out of use or reliance upon this specification or any */
+/* information herein. */
+/* */
+/* (c) Copyright IBM Corp. and others, 2012-2015 */
+/* */
+/********************************************************************************/
+
+/* rev 119 */
+
+#ifndef SELFTEST_FP_H
+#define SELFTEST_FP_H
+
+typedef struct{
+ TPMI_YES_NO fullTest;
+} SelfTest_In;
+
+#define RC_SelfTest_fullTest (TPM_RC_P + TPM_RC_1)
+
+TPM_RC
+TPM2_SelfTest(
+ SelfTest_In *in // IN: input parameter list
+ );
+
+#endif
diff --git a/src/tpm2/SequenceComplete_fp.h b/src/tpm2/SequenceComplete_fp.h
new file mode 100644
index 0000000..efe5965
--- /dev/null
+++ b/src/tpm2/SequenceComplete_fp.h
@@ -0,0 +1,92 @@
+/********************************************************************************/
+/* */
+/* */
+/* Written by Ken Goldman */
+/* IBM Thomas J. Watson Research Center */
+/* $Id: SequenceComplete_fp.h 809 2016-11-16 18:31:54Z kgoldman $ */
+/* */
+/* Licenses and Notices */
+/* */
+/* 1. Copyright Licenses: */
+/* */
+/* - Trusted Computing Group (TCG) grants to the user of the source code in */
+/* this specification (the "Source Code") a worldwide, irrevocable, */
+/* nonexclusive, royalty free, copyright license to reproduce, create */
+/* derivative works, distribute, display and perform the Source Code and */
+/* derivative works thereof, and to grant others the rights granted herein. */
+/* */
+/* - The TCG grants to the user of the other parts of the specification */
+/* (other than the Source Code) the rights to reproduce, distribute, */
+/* display, and perform the specification solely for the purpose of */
+/* developing products based on such documents. */
+/* */
+/* 2. Source Code Distribution Conditions: */
+/* */
+/* - Redistributions of Source Code must retain the above copyright licenses, */
+/* this list of conditions and the following disclaimers. */
+/* */
+/* - Redistributions in binary form must reproduce the above copyright */
+/* licenses, this list of conditions and the following disclaimers in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* 3. Disclaimers: */
+/* */
+/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
+/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
+/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
+/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
+/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
+/* information on specification licensing rights available through TCG */
+/* membership agreements. */
+/* */
+/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
+/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
+/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
+/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
+/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
+/* */
+/* - Without limitation, TCG and its members and licensors disclaim all */
+/* liability, including liability for infringement of any proprietary */
+/* rights, relating to use of information in this specification and to the */
+/* implementation of this specification, and TCG disclaims all liability for */
+/* cost of procurement of substitute goods or services, lost profits, loss */
+/* of use, loss of data or any incidental, consequential, direct, indirect, */
+/* or special damages, whether under contract, tort, warranty or otherwise, */
+/* arising in any way out of use or reliance upon this specification or any */
+/* information herein. */
+/* */
+/* (c) Copyright IBM Corp. and others, 2012-2015 */
+/* */
+/********************************************************************************/
+
+/* rev 119 */
+
+#ifndef SEQUENCECOMPLETE_FP_H
+#define SEQUENCECOMPLETE_FP_H
+
+typedef struct {
+ TPMI_DH_OBJECT sequenceHandle;
+ TPM2B_MAX_BUFFER buffer;
+ TPMI_RH_HIERARCHY hierarchy;
+} SequenceComplete_In;
+
+#define RC_SequenceComplete_sequenceHandle (TPM_RC_H + TPM_RC_1)
+#define RC_SequenceComplete_buffer (TPM_RC_P + TPM_RC_1)
+#define RC_SequenceComplete_hierarchy (TPM_RC_P + TPM_RC_2)
+
+
+typedef struct {
+ TPM2B_DIGEST result;
+ TPMT_TK_HASHCHECK validation;
+} SequenceComplete_Out;
+
+
+
+TPM_RC
+TPM2_SequenceComplete(
+ SequenceComplete_In *in, // IN: input parameter list
+ SequenceComplete_Out *out // OUT: output parameter list
+ );
+
+
+#endif
diff --git a/src/tpm2/SequenceUpdate_fp.h b/src/tpm2/SequenceUpdate_fp.h
new file mode 100644
index 0000000..bedff79
--- /dev/null
+++ b/src/tpm2/SequenceUpdate_fp.h
@@ -0,0 +1,82 @@
+/********************************************************************************/
+/* */
+/* */
+/* Written by Ken Goldman */
+/* IBM Thomas J. Watson Research Center */
+/* $Id: SequenceUpdate_fp.h 809 2016-11-16 18:31:54Z kgoldman $ */
+/* */
+/* Licenses and Notices */
+/* */
+/* 1. Copyright Licenses: */
+/* */
+/* - Trusted Computing Group (TCG) grants to the user of the source code in */
+/* this specification (the "Source Code") a worldwide, irrevocable, */
+/* nonexclusive, royalty free, copyright license to reproduce, create */
+/* derivative works, distribute, display and perform the Source Code and */
+/* derivative works thereof, and to grant others the rights granted herein. */
+/* */
+/* - The TCG grants to the user of the other parts of the specification */
+/* (other than the Source Code) the rights to reproduce, distribute, */
+/* display, and perform the specification solely for the purpose of */
+/* developing products based on such documents. */
+/* */
+/* 2. Source Code Distribution Conditions: */
+/* */
+/* - Redistributions of Source Code must retain the above copyright licenses, */
+/* this list of conditions and the following disclaimers. */
+/* */
+/* - Redistributions in binary form must reproduce the above copyright */
+/* licenses, this list of conditions and the following disclaimers in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* 3. Disclaimers: */
+/* */
+/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
+/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
+/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
+/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
+/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
+/* information on specification licensing rights available through TCG */
+/* membership agreements. */
+/* */
+/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
+/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
+/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
+/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
+/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
+/* */
+/* - Without limitation, TCG and its members and licensors disclaim all */
+/* liability, including liability for infringement of any proprietary */
+/* rights, relating to use of information in this specification and to the */
+/* implementation of this specification, and TCG disclaims all liability for */
+/* cost of procurement of substitute goods or services, lost profits, loss */
+/* of use, loss of data or any incidental, consequential, direct, indirect, */
+/* or special damages, whether under contract, tort, warranty or otherwise, */
+/* arising in any way out of use or reliance upon this specification or any */
+/* information herein. */
+/* */
+/* (c) Copyright IBM Corp. and others, 2012-2015 */
+/* */
+/********************************************************************************/
+
+/* rev 119 */
+
+#ifndef SEQUENCEUPDATE_FP_H
+#define SEQUENCEUPDATE_FP_H
+
+
+typedef struct {
+ TPMI_DH_OBJECT sequenceHandle;
+ TPM2B_MAX_BUFFER buffer;
+} SequenceUpdate_In;
+
+#define RC_SequenceUpdate_sequenceHandle (TPM_RC_P + TPM_RC_1)
+#define RC_SequenceUpdate_buffer (TPM_RC_P + TPM_RC_2)
+
+TPM_RC
+TPM2_SequenceUpdate(
+ SequenceUpdate_In *in // IN: input parameter list
+ );
+
+
+#endif
diff --git a/src/tpm2/Session.c b/src/tpm2/Session.c
new file mode 100644
index 0000000..991a146
--- /dev/null
+++ b/src/tpm2/Session.c
@@ -0,0 +1,835 @@
+/********************************************************************************/
+/* */
+/* Manage the session context counter */
+/* Written by Ken Goldman */
+/* IBM Thomas J. Watson Research Center */
+/* $Id: Session.c 1594 2020-03-26 22:15:48Z kgoldman $ */
+/* */
+/* Licenses and Notices */
+/* */
+/* 1. Copyright Licenses: */
+/* */
+/* - Trusted Computing Group (TCG) grants to the user of the source code in */
+/* this specification (the "Source Code") a worldwide, irrevocable, */
+/* nonexclusive, royalty free, copyright license to reproduce, create */
+/* derivative works, distribute, display and perform the Source Code and */
+/* derivative works thereof, and to grant others the rights granted herein. */
+/* */
+/* - The TCG grants to the user of the other parts of the specification */
+/* (other than the Source Code) the rights to reproduce, distribute, */
+/* display, and perform the specification solely for the purpose of */
+/* developing products based on such documents. */
+/* */
+/* 2. Source Code Distribution Conditions: */
+/* */
+/* - Redistributions of Source Code must retain the above copyright licenses, */
+/* this list of conditions and the following disclaimers. */
+/* */
+/* - Redistributions in binary form must reproduce the above copyright */
+/* licenses, this list of conditions and the following disclaimers in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* 3. Disclaimers: */
+/* */
+/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
+/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
+/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
+/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
+/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
+/* information on specification licensing rights available through TCG */
+/* membership agreements. */
+/* */
+/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
+/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
+/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
+/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
+/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
+/* */
+/* - Without limitation, TCG and its members and licensors disclaim all */
+/* liability, including liability for infringement of any proprietary */
+/* rights, relating to use of information in this specification and to the */
+/* implementation of this specification, and TCG disclaims all liability for */
+/* cost of procurement of substitute goods or services, lost profits, loss */
+/* of use, loss of data or any incidental, consequential, direct, indirect, */
+/* or special damages, whether under contract, tort, warranty or otherwise, */
+/* arising in any way out of use or reliance upon this specification or any */
+/* information herein. */
+/* */
+/* (c) Copyright IBM Corp. and others, 2016 - 2020 */
+/* */
+/********************************************************************************/
+
+
+/* 8.9.2 Includes, Defines, and Local Variables */
+#define SESSION_C
+#include "Tpm.h"
+
+/* 8.9.3 File Scope Function -- ContextIdSetOldest() */
+
+static void
+ContextIdSetOldest(
+ void
+ )
+{
+ CONTEXT_SLOT lowBits;
+ CONTEXT_SLOT entry;
+ CONTEXT_SLOT smallest = CONTEXT_SLOT_MASKED(~0); // libtpms changed
+ UINT32 i;
+ pAssert(s_ContextSlotMask == 0xff || s_ContextSlotMask == 0xffff); // libtpms added
+ // Set oldestSaveContext to a value indicating none assigned
+ s_oldestSavedSession = MAX_ACTIVE_SESSIONS + 1;
+ lowBits = CONTEXT_SLOT_MASKED(gr.contextCounter); // libtpms changed
+ for(i = 0; i < MAX_ACTIVE_SESSIONS; i++)
+ {
+ entry = gr.contextArray[i];
+ // only look at entries that are saved contexts
+ if(entry > MAX_LOADED_SESSIONS)
+ {
+ // Use a less than or equal in case the oldest
+ // is brand new (= lowBits-1) and equal to our initial
+ // value for smallest.
+ if(CONTEXT_SLOT_MASKED(entry - lowBits) <= smallest) // libtpms changed
+ {
+ smallest = CONTEXT_SLOT_MASKED(entry - lowBits); // libtpms changed
+ s_oldestSavedSession = i;
+ }
+ }
+ }
+ // When we finish, either the s_oldestSavedSession still has its initial
+ // value, or it has the index of the oldest saved context.
+}
+/* 8.9.4 Startup Function -- SessionStartup() */
+/* This function initializes the session subsystem on TPM2_Startup(). */
+BOOL
+SessionStartup(
+ STARTUP_TYPE type
+ )
+{
+ UINT32 i;
+ // Initialize session slots. At startup, all the in-memory session slots
+ // are cleared and marked as not occupied
+ for(i = 0; i < MAX_LOADED_SESSIONS; i++)
+ s_sessions[i].occupied = FALSE; // session slot is not occupied
+ // The free session slots the number of maximum allowed loaded sessions
+ s_freeSessionSlots = MAX_LOADED_SESSIONS;
+ // Initialize context ID data. On a ST_SAVE or hibernate sequence, it will
+ // scan the saved array of session context counts, and clear any entry that
+ // references a session that was in memory during the state save since that
+ // memory was not preserved over the ST_SAVE.
+ if(type == SU_RESUME || type == SU_RESTART)
+ {
+ // On ST_SAVE we preserve the contexts that were saved but not the ones
+ // in memory
+ for(i = 0; i < MAX_ACTIVE_SESSIONS; i++)
+ {
+ // If the array value is unused or references a loaded session then
+ // that loaded session context is lost and the array entry is
+ // reclaimed.
+ if(gr.contextArray[i] <= MAX_LOADED_SESSIONS)
+ gr.contextArray[i] = 0;
+ }
+ // Find the oldest session in context ID data and set it in
+ // s_oldestSavedSession
+ ContextIdSetOldest();
+ }
+ else
+ {
+ // For STARTUP_CLEAR, clear out the contextArray
+ for(i = 0; i < MAX_ACTIVE_SESSIONS; i++)
+ gr.contextArray[i] = 0;
+ // reset the context counter
+ gr.contextCounter = MAX_LOADED_SESSIONS + 1;
+ // Initialize oldest saved session
+ s_oldestSavedSession = MAX_ACTIVE_SESSIONS + 1;
+
+ // Initialize the context slot mask for UINT16
+ s_ContextSlotMask = 0xffff; // libtpms added
+ }
+ return TRUE;
+}
+/* 8.9.5 Access Functions */
+/* 8.9.5.1 SessionIsLoaded() */
+/* This function test a session handle references a loaded session. The handle must have previously
+ been checked to make sure that it is a valid handle for an authorization session. */
+/* NOTE: A PWAP authorization does not have a session. */
+/* Return Values Meaning */
+/* TRUE if session is loaded */
+/* FALSE if it is not loaded */
+BOOL
+SessionIsLoaded(
+ TPM_HANDLE handle // IN: session handle
+ )
+{
+ pAssert(HandleGetType(handle) == TPM_HT_POLICY_SESSION
+ || HandleGetType(handle) == TPM_HT_HMAC_SESSION);
+ handle = handle & HR_HANDLE_MASK;
+ // if out of range of possible active session, or not assigned to a loaded
+ // session return false
+ if(handle >= MAX_ACTIVE_SESSIONS
+ || gr.contextArray[handle] == 0
+ || gr.contextArray[handle] > MAX_LOADED_SESSIONS)
+ return FALSE;
+ return TRUE;
+}
+/* 8.9.5.2 SessionIsSaved() */
+/* This function test a session handle references a saved session. The handle must have previously
+ been checked to make sure that it is a valid handle for an authorization session. */
+/* NOTE: A password authorization does not have a session. */
+/* This function requires that the handle be a valid session handle. */
+/* Return Values Meaning */
+/* TRUE if session is saved */
+/* FALSE if it is not saved */
+BOOL
+SessionIsSaved(
+ TPM_HANDLE handle // IN: session handle
+ )
+{
+ pAssert(HandleGetType(handle) == TPM_HT_POLICY_SESSION
+ || HandleGetType(handle) == TPM_HT_HMAC_SESSION);
+ handle = handle & HR_HANDLE_MASK;
+ // if out of range of possible active session, or not assigned, or
+ // assigned to a loaded session, return false
+ if(handle >= MAX_ACTIVE_SESSIONS
+ || gr.contextArray[handle] == 0
+ || gr.contextArray[handle] <= MAX_LOADED_SESSIONS
+ )
+ return FALSE;
+ return TRUE;
+}
+/* 8.9.5.3 SequenceNumberForSavedContextIsValid() */
+BOOL
+SequenceNumberForSavedContextIsValid(
+ TPMS_CONTEXT *context // IN: pointer to a context
+ // structure to be validated
+ )
+{
+#define MAX_CONTEXT_GAP ((UINT64)(CONTEXT_SLOT_MASKED(~0) + 1)) /* libtpms changed */
+ pAssert(s_ContextSlotMask == 0xff || s_ContextSlotMask == 0xffff); // libtpms added
+
+ TPM_HANDLE handle = context->savedHandle & HR_HANDLE_MASK;
+ if(// Handle must be with the range of active sessions
+ handle >= MAX_ACTIVE_SESSIONS
+ // the array entry must be for a saved context
+ || gr.contextArray[handle] <= MAX_LOADED_SESSIONS
+ // the array entry must agree with the sequence number
+ || gr.contextArray[handle] != CONTEXT_SLOT_MASKED(context->sequence) // libtpms changed
+ // the provided sequence number has to be less than the current counter
+ || context->sequence > gr.contextCounter
+ // but not so much that it could not be a valid sequence number
+ || gr.contextCounter - context->sequence > MAX_CONTEXT_GAP)
+ return FALSE;
+ return TRUE;
+}
+/* 8.9.5.4 SessionPCRValueIsCurrent() */
+/* This function is used to check if PCR values have been updated since the last time they were
+ checked in a policy session. */
+/* This function requires the session is loaded. */
+/* Return Values Meaning */
+/* TRUE if PCR value is current */
+/* FALSE if PCR value is not current */
+BOOL
+SessionPCRValueIsCurrent(
+ SESSION *session // IN: session structure
+ )
+{
+ if(session->pcrCounter != 0
+ && session->pcrCounter != gr.pcrCounter
+ )
+ return FALSE;
+ else
+ return TRUE;
+}
+/* 8.9.5.5 SessionGet() */
+/* This function returns a pointer to the session object associated with a session handle. */
+/* The function requires that the session is loaded. */
+SESSION *
+SessionGet(
+ TPM_HANDLE handle // IN: session handle
+ )
+{
+ size_t slotIndex;
+ CONTEXT_SLOT sessionIndex;
+ pAssert(HandleGetType(handle) == TPM_HT_POLICY_SESSION
+ || HandleGetType(handle) == TPM_HT_HMAC_SESSION
+ );
+ slotIndex = handle & HR_HANDLE_MASK;
+ pAssert(slotIndex < MAX_ACTIVE_SESSIONS);
+ // get the contents of the session array. Because session is loaded, we
+ // should always get a valid sessionIndex
+ sessionIndex = gr.contextArray[slotIndex] - 1;
+ pAssert(sessionIndex < MAX_LOADED_SESSIONS);
+ return &s_sessions[sessionIndex].session;
+}
+/* 8.9.6 Utility Functions */
+/* 8.9.6.1 ContextIdSessionCreate() */
+/* This function is called when a session is created. It will check to see if the current gap would
+ prevent a context from being saved. If so it will return TPM_RC_CONTEXT_GAP. Otherwise, it will
+ try to find an open slot in contextArray, set contextArray to the slot. This routine requires
+ that the caller has determined the session array index for the session. */
+/* TPM_RC_CONTEXT_GAP can't assign a new contextID until the oldest saved session context is
+ recycled */
+/* TPM_RC_SESSION_HANDLE there is no slot available in the context array for tracking of this
+ session context */
+static TPM_RC
+ContextIdSessionCreate(
+ TPM_HANDLE *handle, /* OUT: receives the assigned handle. This will be
+ an index that must be adjusted by the caller
+ according to the type of the session created */
+ UINT32 sessionIndex /* IN: The session context array entry that
+ will be occupied by the created session */
+ )
+{
+ pAssert(sessionIndex < MAX_LOADED_SESSIONS);
+ // check to see if creating the context is safe
+ // Is this going to be an assignment for the last session context
+ // array entry? If so, then there will be no room to recycle the
+ // oldest context if needed. If the gap is not at maximum, then
+ // it will be possible to save a context if it becomes necessary.
+ if(s_oldestSavedSession < MAX_ACTIVE_SESSIONS
+ && s_freeSessionSlots == 1)
+ {
+ // See if the gap is at maximum
+ // The current value of the contextCounter will be assigned to the next
+ // saved context. If the value to be assigned would make the same as an
+ // existing context, then we can't use it because of the ambiguity it would
+ // create.
+ if(CONTEXT_SLOT_MASKED(gr.contextCounter) // libtpms changed
+ == gr.contextArray[s_oldestSavedSession])
+ return TPM_RC_CONTEXT_GAP;
+ }
+ // Find an unoccupied entry in the contextArray
+ for(*handle = 0; *handle < MAX_ACTIVE_SESSIONS; (*handle)++)
+ {
+ if(gr.contextArray[*handle] == 0)
+ {
+ // indicate that the session associated with this handle
+ // references a loaded session
+ gr.contextArray[*handle] = CONTEXT_SLOT_MASKED(sessionIndex + 1); // libtpms changed
+ return TPM_RC_SUCCESS;
+ }
+ }
+ return TPM_RC_SESSION_HANDLES;
+}
+/* 8.9.6.2 SessionCreate() */
+/* This function does the detailed work for starting an authorization session. This is done in a
+ support routine rather than in the action code because the session management may differ in
+ implementations. This implementation uses a fixed memory allocation to hold sessions and a fixed
+ allocation to hold the contextID for the saved contexts. */
+/* Error Returns Meaning */
+/* TPM_RC_CONTEXT_GAP need to recycle sessions */
+/* TPM_RC_SESSION_HANDLE active session space is full */
+/* TPM_RC_SESSION_MEMORY loaded session space is full */
+TPM_RC
+SessionCreate(
+ TPM_SE sessionType, // IN: the session type
+ TPMI_ALG_HASH authHash, // IN: the hash algorithm
+ TPM2B_NONCE *nonceCaller, // IN: initial nonceCaller
+ TPMT_SYM_DEF *symmetric, // IN: the symmetric algorithm
+ TPMI_DH_ENTITY bind, // IN: the bind object
+ TPM2B_DATA *seed, // IN: seed data
+ TPM_HANDLE *sessionHandle, // OUT: the session handle
+ TPM2B_NONCE *nonceTpm // OUT: the session nonce
+ )
+{
+ TPM_RC result = TPM_RC_SUCCESS;
+ CONTEXT_SLOT slotIndex;
+ SESSION *session = NULL;
+ pAssert(sessionType == TPM_SE_HMAC
+ || sessionType == TPM_SE_POLICY
+ || sessionType == TPM_SE_TRIAL);
+ // If there are no open spots in the session array, then no point in searching
+ if(s_freeSessionSlots == 0)
+ return TPM_RC_SESSION_MEMORY;
+ // Find a space for loading a session
+ for(slotIndex = 0; slotIndex < MAX_LOADED_SESSIONS; slotIndex++)
+ {
+ // Is this available?
+ if(s_sessions[slotIndex].occupied == FALSE)
+ {
+ session = &s_sessions[slotIndex].session;
+ break;
+ }
+ }
+ // if no spot found, then this is an internal error
+ if(slotIndex >= MAX_LOADED_SESSIONS) { // libtpms changed
+ FAIL(FATAL_ERROR_INTERNAL);
+ // should never get here due to longjmp in FAIL() libtpms added begin; cppcheck
+ return TPM_RC_FAILURE;
+ } // libtpms added end
+ // Call context ID function to get a handle. TPM_RC_SESSION_HANDLE may be
+ // returned from ContextIdHandelAssign()
+ result = ContextIdSessionCreate(sessionHandle, slotIndex);
+ if(result != TPM_RC_SUCCESS)
+ return result;
+ //*** Only return from this point on is TPM_RC_SUCCESS
+ // Can now indicate that the session array entry is occupied.
+ s_freeSessionSlots--;
+ s_sessions[slotIndex].occupied = TRUE;
+ // Initialize the session data
+ MemorySet(session, 0, sizeof(SESSION));
+ // Initialize internal session data
+ session->authHashAlg = authHash;
+ // Initialize session type
+ if(sessionType == TPM_SE_HMAC)
+ {
+ *sessionHandle += HMAC_SESSION_FIRST;
+ }
+ else
+ {
+ *sessionHandle += POLICY_SESSION_FIRST;
+ // For TPM_SE_POLICY or TPM_SE_TRIAL
+ session->attributes.isPolicy = SET;
+ if(sessionType == TPM_SE_TRIAL)
+ session->attributes.isTrialPolicy = SET;
+ SessionSetStartTime(session);
+ // Initialize policyDigest. policyDigest is initialized with a string of 0
+ // of session algorithm digest size. Since the session is already clear.
+ // Just need to set the size
+ session->u2.policyDigest.t.size =
+ CryptHashGetDigestSize(session->authHashAlg);
+ }
+ // Create initial session nonce
+ session->nonceTPM.t.size = nonceCaller->t.size;
+ CryptRandomGenerate(session->nonceTPM.t.size, session->nonceTPM.t.buffer);
+ MemoryCopy2B(&nonceTpm->b, &session->nonceTPM.b,
+ sizeof(nonceTpm->t.buffer));
+ // Set up session parameter encryption algorithm
+ session->symmetric = *symmetric;
+ // If there is a bind object or a session secret, then need to compute
+ // a sessionKey.
+ if(bind != TPM_RH_NULL || seed->t.size != 0)
+ {
+ // sessionKey = KDFa(hash, (authValue || seed), "ATH", nonceTPM,
+ // nonceCaller, bits)
+ // The HMAC key for generating the sessionSecret can be the concatenation
+ // of an authorization value and a seed value
+ TPM2B_TYPE(KEY, (sizeof(TPMT_HA) + sizeof(seed->t.buffer)));
+ TPM2B_KEY key;
+ // Get hash size, which is also the length of sessionKey
+ session->sessionKey.t.size = CryptHashGetDigestSize(session->authHashAlg);
+ // Get authValue of associated entity
+ EntityGetAuthValue(bind, (TPM2B_AUTH *)&key);
+ pAssert(key.t.size + seed->t.size <= sizeof(key.t.buffer));
+ // Concatenate authValue and seed
+ MemoryConcat2B(&key.b, &seed->b, sizeof(key.t.buffer));
+ // Compute the session key
+ CryptKDFa(session->authHashAlg, &key.b, SESSION_KEY, &session->nonceTPM.b,
+ &nonceCaller->b,
+ session->sessionKey.t.size * 8, session->sessionKey.t.buffer,
+ NULL, FALSE);
+ }
+ // Copy the name of the entity that the HMAC session is bound to
+ // Policy session is not bound to an entity
+ if(bind != TPM_RH_NULL && sessionType == TPM_SE_HMAC)
+ {
+ session->attributes.isBound = SET;
+ SessionComputeBoundEntity(bind, &session->u1.boundEntity);
+ }
+ // If there is a bind object and it is subject to DA, then use of this session
+ // is subject to DA regardless of how it is used.
+ session->attributes.isDaBound = (bind != TPM_RH_NULL)
+ && (IsDAExempted(bind) == FALSE);
+ // If the session is bound, then check to see if it is bound to lockoutAuth
+ session->attributes.isLockoutBound = (session->attributes.isDaBound == SET)
+ && (bind == TPM_RH_LOCKOUT);
+ return TPM_RC_SUCCESS;
+}
+/* 8.9.6.3 SessionContextSave() */
+/* This function is called when a session context is to be saved. The contextID of the saved
+ session is returned. If no contextID can be assigned, then the routine returns
+ TPM_RC_CONTEXT_GAP. If the function completes normally, the session slot will be freed. */
+/* This function requires that handle references a loaded session. Otherwise, it should not be
+ called at the first place. */
+/* Error Returns Meaning */
+/* TPM_RC_CONTEXT_GAP a contextID could not be assigned. */
+/* TPM_RC_TOO_MANY_CONTEXTS the counter maxed out */
+TPM_RC
+SessionContextSave(
+ TPM_HANDLE handle, // IN: session handle
+ CONTEXT_COUNTER *contextID // OUT: assigned contextID
+ )
+{
+ UINT32 contextIndex;
+ CONTEXT_SLOT slotIndex;
+ pAssert(SessionIsLoaded(handle));
+ pAssert(s_ContextSlotMask == 0xff || s_ContextSlotMask == 0xffff); // libtpms added
+ // check to see if the gap is already maxed out
+ // Need to have a saved session
+ if(s_oldestSavedSession < MAX_ACTIVE_SESSIONS
+ // if the oldest saved session has the same value as the low bits
+ // of the contextCounter, then the GAP is maxed out.
+ && gr.contextArray[s_oldestSavedSession] == CONTEXT_SLOT_MASKED(gr.contextCounter)) // libtpms changed
+ return TPM_RC_CONTEXT_GAP;
+ // if the caller wants the context counter, set it
+ if(contextID != NULL)
+ *contextID = gr.contextCounter;
+ contextIndex = handle & HR_HANDLE_MASK;
+ pAssert(contextIndex < MAX_ACTIVE_SESSIONS);
+ // Extract the session slot number referenced by the contextArray
+ // because we are going to overwrite this with the low order
+ // contextID value.
+ slotIndex = gr.contextArray[contextIndex] - 1;
+ // Set the contextID for the contextArray
+ gr.contextArray[contextIndex] = CONTEXT_SLOT_MASKED(gr.contextCounter); // libtpms changed
+ // Increment the counter
+ gr.contextCounter++;
+ // In the unlikely event that the 64-bit context counter rolls over...
+ if(gr.contextCounter == 0)
+ {
+ // back it up
+ gr.contextCounter--;
+ // return an error
+ return TPM_RC_TOO_MANY_CONTEXTS;
+ }
+ // if the low-order bits wrapped, need to advance the value to skip over
+ // the values used to indicate that a session is loaded
+ if(CONTEXT_SLOT_MASKED(gr.contextCounter) == 0) // libtpms changed
+ gr.contextCounter += MAX_LOADED_SESSIONS + 1;
+ // If no other sessions are saved, this is now the oldest.
+ if(s_oldestSavedSession >= MAX_ACTIVE_SESSIONS)
+ s_oldestSavedSession = contextIndex;
+ // Mark the session slot as unoccupied
+ s_sessions[slotIndex].occupied = FALSE;
+ // and indicate that there is an additional open slot
+ s_freeSessionSlots++;
+ return TPM_RC_SUCCESS;
+}
+/* 8.9.6.4 SessionContextLoad() */
+/* This function is used to load a session from saved context. The session handle must be for a
+ saved context. */
+/* If the gap is at a maximum, then the only session that can be loaded is the oldest session,
+ otherwise TPM_RC_CONTEXT_GAP is returned. */
+/* This function requires that handle references a valid saved session. */
+/* Error Returns Meaning */
+/* TPM_RC_SESSION_MEMORY no free session slots */
+/* TPM_RC_CONTEXT_GAP the gap count is maximum and this is not the oldest saved context */
+TPM_RC
+SessionContextLoad(
+ SESSION_BUF *session, // IN: session structure from saved context
+ TPM_HANDLE *handle // IN/OUT: session handle
+ )
+{
+ UINT32 contextIndex;
+ CONTEXT_SLOT slotIndex;
+ pAssert(s_ContextSlotMask == 0xff || s_ContextSlotMask == 0xffff); // libtpms added
+ pAssert(HandleGetType(*handle) == TPM_HT_POLICY_SESSION
+ || HandleGetType(*handle) == TPM_HT_HMAC_SESSION);
+ // Don't bother looking if no openings
+ if(s_freeSessionSlots == 0)
+ return TPM_RC_SESSION_MEMORY;
+ // Find a free session slot to load the session
+ for(slotIndex = 0; slotIndex < MAX_LOADED_SESSIONS; slotIndex++)
+ if(s_sessions[slotIndex].occupied == FALSE) break;
+ // if no spot found, then this is an internal error
+ pAssert(slotIndex < MAX_LOADED_SESSIONS);
+ // libtpms: besides the s_freeSessionSlots guard add another array index guard
+ if (slotIndex >= MAX_LOADED_SESSIONS) { // libtpms added begin; cppcheck
+ FAIL(FATAL_ERROR_INTERNAL);
+ // should never get here due to longjmp in FAIL()
+ return TPM_RC_FAILURE;
+ } // libtpms added end
+ contextIndex = *handle & HR_HANDLE_MASK; // extract the index
+ // If there is only one slot left, and the gap is at maximum, the only session
+ // context that we can safely load is the oldest one.
+ if(s_oldestSavedSession < MAX_ACTIVE_SESSIONS
+ && s_freeSessionSlots == 1
+ && CONTEXT_SLOT_MASKED(gr.contextCounter) == gr.contextArray[s_oldestSavedSession] // libtpms changed
+ && contextIndex != s_oldestSavedSession)
+ return TPM_RC_CONTEXT_GAP;
+ pAssert(contextIndex < MAX_ACTIVE_SESSIONS);
+ // set the contextArray value to point to the session slot where
+ // the context is loaded
+ gr.contextArray[contextIndex] = slotIndex + 1;
+ // if this was the oldest context, find the new oldest
+ if(contextIndex == s_oldestSavedSession)
+ ContextIdSetOldest();
+ // Copy session data to session slot
+ MemoryCopy(&s_sessions[slotIndex].session, session, sizeof(SESSION));
+ // Set session slot as occupied
+ s_sessions[slotIndex].occupied = TRUE;
+ // Reduce the number of open spots
+ s_freeSessionSlots--;
+ return TPM_RC_SUCCESS;
+}
+/* 8.9.6.5 SessionFlush() */
+/* This function is used to flush a session referenced by its handle. If the session associated
+ with handle is loaded, the session array entry is marked as available. */
+/* This function requires that handle be a valid active session. */
+void
+SessionFlush(
+ TPM_HANDLE handle // IN: loaded or saved session handle
+ )
+{
+ CONTEXT_SLOT slotIndex;
+ UINT32 contextIndex; // Index into contextArray
+ pAssert((HandleGetType(handle) == TPM_HT_POLICY_SESSION
+ || HandleGetType(handle) == TPM_HT_HMAC_SESSION
+ )
+ && (SessionIsLoaded(handle) || SessionIsSaved(handle))
+ );
+ // Flush context ID of this session
+ // Convert handle to an index into the contextArray
+ contextIndex = handle & HR_HANDLE_MASK;
+ pAssert(contextIndex < sizeof(gr.contextArray) / sizeof(gr.contextArray[0]));
+ // Get the current contents of the array
+ slotIndex = gr.contextArray[contextIndex];
+ // Mark context array entry as available
+ gr.contextArray[contextIndex] = 0;
+ // Is this a saved session being flushed
+ if(slotIndex > MAX_LOADED_SESSIONS)
+ {
+ // Flushing the oldest session?
+ if(contextIndex == s_oldestSavedSession)
+ // If so, find a new value for oldest.
+ ContextIdSetOldest();
+ }
+ else
+ {
+ // Adjust slot index to point to session array index
+ slotIndex -= 1;
+ // Free session array index
+ s_sessions[slotIndex].occupied = FALSE;
+ s_freeSessionSlots++;
+ }
+ return;
+}
+/* 8.9.6.6 SessionComputeBoundEntity() */
+/* This function computes the binding value for a session. The binding value for a reserved handle
+ is the handle itself. For all the other entities, the authValue at the time of binding is
+ included to prevent squatting. For those values, the Name and the authValue are concatenated into
+ the bind buffer. If they will not both fit, the will be overlapped by XORing() bytes. If XOR is
+ required, the bind value will be full. */
+void
+SessionComputeBoundEntity(
+ TPMI_DH_ENTITY entityHandle, // IN: handle of entity
+ TPM2B_NAME *bind // OUT: binding value
+ )
+{
+ TPM2B_AUTH auth;
+ BYTE *pAuth = auth.t.buffer;
+ UINT16 i;
+ // Get name
+ EntityGetName(entityHandle, bind);
+ // // The bound value of a reserved handle is the handle itself
+ // if(bind->t.size == sizeof(TPM_HANDLE)) return;
+ // For all the other entities, concatenate the authorization value to the name.
+ // Get a local copy of the authorization value because some overlapping
+ // may be necessary.
+ EntityGetAuthValue(entityHandle, &auth);
+ // Make sure that the extra space is zeroed
+ MemorySet(&bind->t.name[bind->t.size], 0, sizeof(bind->t.name) - bind->t.size);
+ // XOR the authValue at the end of the name
+ for(i = sizeof(bind->t.name) - auth.t.size; i < sizeof(bind->t.name); i++)
+ bind->t.name[i] ^= *pAuth++;
+ // Set the bind value to the maximum size
+ bind->t.size = sizeof(bind->t.name);
+ return;
+}
+/* 8.9.6.7 SessionSetStartTime() */
+/* This function is used to initialize the session timing */
+void
+SessionSetStartTime(
+ SESSION *session // IN: the session to update
+ )
+{
+ session->startTime = g_time;
+ session->epoch = g_timeEpoch;
+ session->timeout = 0;
+}
+/* 8.9.6.8 SessionResetPolicyData() */
+/* This function is used to reset the policy data without changing the nonce or the start time of
+ the session. */
+void
+SessionResetPolicyData(
+ SESSION *session // IN: the session to reset
+ )
+{
+ SESSION_ATTRIBUTES oldAttributes;
+ pAssert(session != NULL);
+ // Will need later
+ oldAttributes = session->attributes;
+ // No command
+ session->commandCode = 0;
+ // No locality selected
+ MemorySet(&session->commandLocality, 0, sizeof(session->commandLocality));
+ // The cpHash size to zero
+ session->u1.cpHash.b.size = 0;
+ // No timeout
+ session->timeout = 0;
+ // Reset the pcrCounter
+ session->pcrCounter = 0;
+ // Reset the policy hash
+ MemorySet(&session->u2.policyDigest.t.buffer, 0,
+ session->u2.policyDigest.t.size);
+ // Reset the session attributes
+ MemorySet(&session->attributes, 0, sizeof(SESSION_ATTRIBUTES));
+ // Restore the policy attributes
+ session->attributes.isPolicy = SET;
+ session->attributes.isTrialPolicy = oldAttributes.isTrialPolicy;
+ // Restore the bind attributes
+ session->attributes.isDaBound = oldAttributes.isDaBound;
+ session->attributes.isLockoutBound = oldAttributes.isLockoutBound;
+}
+/* 8.9.6.9 SessionCapGetLoaded() */
+/* This function returns a list of handles of loaded session, started from input handle */
+/* Handle must be in valid loaded session handle range, but does not have to point to a loaded
+ session. */
+/* Return Values Meaning */
+/* YES if there are more handles available */
+/* NO all the available handles has been returned */
+TPMI_YES_NO
+SessionCapGetLoaded(
+ TPMI_SH_POLICY handle, // IN: start handle
+ UINT32 count, // IN: count of returned handles
+ TPML_HANDLE *handleList // OUT: list of handle
+ )
+{
+ TPMI_YES_NO more = NO;
+ UINT32 i;
+ pAssert(HandleGetType(handle) == TPM_HT_LOADED_SESSION);
+ // Initialize output handle list
+ handleList->count = 0;
+ // The maximum count of handles we may return is MAX_CAP_HANDLES
+ if(count > MAX_CAP_HANDLES) count = MAX_CAP_HANDLES;
+ // Iterate session context ID slots to get loaded session handles
+ for(i = handle & HR_HANDLE_MASK; i < MAX_ACTIVE_SESSIONS; i++)
+ {
+ // If session is active
+ if(gr.contextArray[i] != 0)
+ {
+ // If session is loaded
+ if(gr.contextArray[i] <= MAX_LOADED_SESSIONS)
+ {
+ if(handleList->count < count)
+ {
+ SESSION *session;
+ // If we have not filled up the return list, add this
+ // session handle to it
+ // assume that this is going to be an HMAC session
+ handle = i + HMAC_SESSION_FIRST;
+ session = SessionGet(handle);
+ if(session->attributes.isPolicy)
+ handle = i + POLICY_SESSION_FIRST;
+ handleList->handle[handleList->count] = handle;
+ handleList->count++;
+ }
+ else
+ {
+ // If the return list is full but we still have loaded object
+ // available, report this and stop iterating
+ more = YES;
+ break;
+ }
+ }
+ }
+ }
+ return more;
+}
+/* 8.9.6.10 SessionCapGetSaved() */
+/* This function returns a list of handles for saved session, starting at handle. */
+/* Handle must be in a valid handle range, but does not have to point to a saved session */
+/* Return Values Meaning */
+/* YES if there are more handles available */
+/* NO all the available handles has been returned */
+TPMI_YES_NO
+SessionCapGetSaved(
+ TPMI_SH_HMAC handle, // IN: start handle
+ UINT32 count, // IN: count of returned handles
+ TPML_HANDLE *handleList // OUT: list of handle
+ )
+{
+ TPMI_YES_NO more = NO;
+ UINT32 i;
+#ifdef TPM_HT_SAVED_SESSION
+ pAssert(HandleGetType(handle) == TPM_HT_SAVED_SESSION);
+#else
+ pAssert(HandleGetType(handle) == TPM_HT_ACTIVE_SESSION);
+#endif
+ // Initialize output handle list
+ handleList->count = 0;
+ // The maximum count of handles we may return is MAX_CAP_HANDLES
+ if(count > MAX_CAP_HANDLES) count = MAX_CAP_HANDLES;
+ // Iterate session context ID slots to get loaded session handles
+ for(i = handle & HR_HANDLE_MASK; i < MAX_ACTIVE_SESSIONS; i++)
+ {
+ // If session is active
+ if(gr.contextArray[i] != 0)
+ {
+ // If session is saved
+ if(gr.contextArray[i] > MAX_LOADED_SESSIONS)
+ {
+ if(handleList->count < count)
+ {
+ // If we have not filled up the return list, add this
+ // session handle to it
+ handleList->handle[handleList->count] = i + HMAC_SESSION_FIRST;
+ handleList->count++;
+ }
+ else
+ {
+ // If the return list is full but we still have loaded object
+ // available, report this and stop iterating
+ more = YES;
+ break;
+ }
+ }
+ }
+ }
+ return more;
+}
+/* 8.9.6.11 SessionCapGetLoadedNumber() */
+/* This function return the number of authorization sessions currently loaded into TPM RAM. */
+UINT32
+SessionCapGetLoadedNumber(
+ void
+ )
+{
+ return MAX_LOADED_SESSIONS - s_freeSessionSlots;
+}
+/* 8.9.6.12 SessionCapGetLoadedAvail() */
+/* This function returns the number of additional authorization sessions, of any type, that could be
+ loaded into TPM RAM. */
+/* NOTE: In other implementations, this number may just be an estimate. The only requirement for the
+ estimate is, if it is one or more, then at least one session must be loadable. */
+UINT32
+SessionCapGetLoadedAvail(
+ void
+ )
+{
+ return s_freeSessionSlots;
+}
+/* 8.9.6.13 SessionCapGetActiveNumber() */
+/* This function returns the number of active authorization sessions currently being tracked by the
+ TPM. */
+UINT32
+SessionCapGetActiveNumber(
+ void
+ )
+{
+ UINT32 i;
+ UINT32 num = 0;
+ // Iterate the context array to find the number of non-zero slots
+ for(i = 0; i < MAX_ACTIVE_SESSIONS; i++)
+ {
+ if(gr.contextArray[i] != 0) num++;
+ }
+ return num;
+}
+/* 8.9.6.14 SessionCapGetActiveAvail() */
+/* This function returns the number of additional authorization sessions, of any type, that could be
+ created. This not the number of slots for sessions, but the number of additional sessions that
+ the TPM is capable of tracking. */
+UINT32
+SessionCapGetActiveAvail(
+ void
+ )
+{
+ UINT32 i;
+ UINT32 num = 0;
+ // Iterate the context array to find the number of zero slots
+ for(i = 0; i < MAX_ACTIVE_SESSIONS; i++)
+ {
+ if(gr.contextArray[i] == 0) num++;
+ }
+ return num;
+}
diff --git a/src/tpm2/SessionCommands.c b/src/tpm2/SessionCommands.c
new file mode 100644
index 0000000..d2f3f96
--- /dev/null
+++ b/src/tpm2/SessionCommands.c
@@ -0,0 +1,175 @@
+/********************************************************************************/
+/* */
+/* Session Commands */
+/* Written by Ken Goldman */
+/* IBM Thomas J. Watson Research Center */
+/* $Id: SessionCommands.c 1519 2019-11-15 20:43:51Z kgoldman $ */
+/* */
+/* Licenses and Notices */
+/* */
+/* 1. Copyright Licenses: */
+/* */
+/* - Trusted Computing Group (TCG) grants to the user of the source code in */
+/* this specification (the "Source Code") a worldwide, irrevocable, */
+/* nonexclusive, royalty free, copyright license to reproduce, create */
+/* derivative works, distribute, display and perform the Source Code and */
+/* derivative works thereof, and to grant others the rights granted herein. */
+/* */
+/* - The TCG grants to the user of the other parts of the specification */
+/* (other than the Source Code) the rights to reproduce, distribute, */
+/* display, and perform the specification solely for the purpose of */
+/* developing products based on such documents. */
+/* */
+/* 2. Source Code Distribution Conditions: */
+/* */
+/* - Redistributions of Source Code must retain the above copyright licenses, */
+/* this list of conditions and the following disclaimers. */
+/* */
+/* - Redistributions in binary form must reproduce the above copyright */
+/* licenses, this list of conditions and the following disclaimers in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* 3. Disclaimers: */
+/* */
+/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
+/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
+/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
+/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
+/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
+/* information on specification licensing rights available through TCG */
+/* membership agreements. */
+/* */
+/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
+/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
+/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
+/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
+/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
+/* */
+/* - Without limitation, TCG and its members and licensors disclaim all */
+/* liability, including liability for infringement of any proprietary */
+/* rights, relating to use of information in this specification and to the */
+/* implementation of this specification, and TCG disclaims all liability for */
+/* cost of procurement of substitute goods or services, lost profits, loss */
+/* of use, loss of data or any incidental, consequential, direct, indirect, */
+/* or special damages, whether under contract, tort, warranty or otherwise, */
+/* arising in any way out of use or reliance upon this specification or any */
+/* information herein. */
+/* */
+/* (c) Copyright IBM Corp. and others, 2016 - 2019 */
+/* */
+/********************************************************************************/
+
+#include "Tpm.h"
+#include "StartAuthSession_fp.h"
+#if CC_StartAuthSession // Conditional expansion of this file
+TPM_RC
+TPM2_StartAuthSession(
+ StartAuthSession_In *in, // IN: input parameter buffer
+ StartAuthSession_Out *out // OUT: output parameter buffer
+ )
+{
+ TPM_RC result = TPM_RC_SUCCESS;
+ OBJECT *tpmKey; // TPM key for decrypt salt
+ TPM2B_DATA salt;
+ // Input Validation
+ // Check input nonce size. IT should be at least 16 bytes but not larger
+ // than the digest size of session hash.
+ if(in->nonceCaller.t.size < 16
+ || in->nonceCaller.t.size > CryptHashGetDigestSize(in->authHash))
+ return TPM_RCS_SIZE + RC_StartAuthSession_nonceCaller;
+ // If an decrypt key is passed in, check its validation
+ if(in->tpmKey != TPM_RH_NULL)
+ {
+ // Get pointer to loaded decrypt key
+ tpmKey = HandleToObject(in->tpmKey);
+ // key must be asymmetric with its sensitive area loaded. Since this
+ // command does not require authorization, the presence of the sensitive
+ // area was not already checked as it is with most other commands that
+ // use the sensitive are so check it here
+ if(!CryptIsAsymAlgorithm(tpmKey->publicArea.type))
+ return TPM_RCS_KEY + RC_StartAuthSession_tpmKey;
+ // secret size cannot be 0
+ if(in->encryptedSalt.t.size == 0)
+ return TPM_RCS_VALUE + RC_StartAuthSession_encryptedSalt;
+ // Decrypting salt requires accessing the private portion of a key.
+ // Therefore, tmpKey can not be a key with only public portion loaded
+ if(tpmKey->attributes.publicOnly)
+ return TPM_RCS_HANDLE + RC_StartAuthSession_tpmKey;
+ // HMAC session input handle check.
+ // tpmKey should be a decryption key
+ if(!IS_ATTRIBUTE(tpmKey->publicArea.objectAttributes, TPMA_OBJECT, decrypt))
+ return TPM_RCS_ATTRIBUTES + RC_StartAuthSession_tpmKey;
+ // Secret Decryption. A TPM_RC_VALUE, TPM_RC_KEY or Unmarshal errors
+ // may be returned at this point
+ result = CryptSecretDecrypt(tpmKey, &in->nonceCaller, SECRET_KEY,
+ &in->encryptedSalt, &salt);
+ if(result != TPM_RC_SUCCESS)
+ return TPM_RCS_VALUE + RC_StartAuthSession_encryptedSalt;
+ }
+ else
+ {
+ // secret size must be 0
+ if(in->encryptedSalt.t.size != 0)
+ return TPM_RCS_VALUE + RC_StartAuthSession_encryptedSalt;
+ salt.t.size = 0;
+ }
+ switch(HandleGetType(in->bind))
+ {
+ case TPM_HT_TRANSIENT:
+ {
+ OBJECT *object = HandleToObject(in->bind);
+ // If the bind handle references a transient object, make sure that we
+ // can get to the authorization value. Also, make sure that the object
+ // has a proper Name (nameAlg != TPM_ALG_NULL). If it doesn't, then
+ // it might be possible to bind to an object where the authValue is
+ // known. This does not create a real issue in that, if you know the
+ // authorization value, you can actually bind to the object. However,
+ // there is a potential
+ if(object->attributes.publicOnly == SET)
+ return TPM_RCS_HANDLE + RC_StartAuthSession_bind;
+ break;
+ }
+ case TPM_HT_NV_INDEX:
+ // a PIN index can't be a bind object
+ {
+ NV_INDEX *nvIndex = NvGetIndexInfo(in->bind, NULL);
+ if(IsNvPinPassIndex(nvIndex->publicArea.attributes)
+ || IsNvPinFailIndex(nvIndex->publicArea.attributes))
+ return TPM_RCS_HANDLE + RC_StartAuthSession_bind;
+ break;
+ }
+ default:
+ break;
+ }
+ // If 'symmetric' is a symmetric block cipher (not TPM_ALG_NULL or TPM_ALG_XOR)
+ // then the mode must be CFB.
+ if(in->symmetric.algorithm != TPM_ALG_NULL
+ && in->symmetric.algorithm != TPM_ALG_XOR
+ && in->symmetric.mode.sym != TPM_ALG_CFB)
+ return TPM_RCS_MODE + RC_StartAuthSession_symmetric;
+ // Internal Data Update and command output
+ // Create internal session structure. TPM_RC_CONTEXT_GAP, TPM_RC_NO_HANDLES
+ // or TPM_RC_SESSION_MEMORY errors may be returned at this point.
+ //
+ // The detailed actions for creating the session context are not shown here
+ // as the details are implementation dependent
+ // SessionCreate sets the output handle and nonceTPM
+ result = SessionCreate(in->sessionType, in->authHash, &in->nonceCaller,
+ &in->symmetric, in->bind, &salt, &out->sessionHandle,
+ &out->nonceTPM);
+ return result;
+}
+#endif // CC_StartAuthSession
+#include "Tpm.h"
+#include "PolicyRestart_fp.h"
+#if CC_PolicyRestart // Conditional expansion of this file
+TPM_RC
+TPM2_PolicyRestart(
+ PolicyRestart_In *in // IN: input parameter list
+ )
+{
+ // Initialize policy session data
+ SessionResetPolicyData(SessionGet(in->sessionHandle));
+ return TPM_RC_SUCCESS;
+}
+#endif // CC_PolicyRestart
diff --git a/src/tpm2/SessionProcess.c b/src/tpm2/SessionProcess.c
new file mode 100644
index 0000000..f8efc68
--- /dev/null
+++ b/src/tpm2/SessionProcess.c
@@ -0,0 +1,1990 @@
+/********************************************************************************/
+/* */
+/* Process the Authorization Sessions */
+/* Written by Ken Goldman */
+/* IBM Thomas J. Watson Research Center */
+/* $Id: SessionProcess.c 1658 2021-01-22 23:14:01Z kgoldman $ */
+/* */
+/* Licenses and Notices */
+/* */
+/* 1. Copyright Licenses: */
+/* */
+/* - Trusted Computing Group (TCG) grants to the user of the source code in */
+/* this specification (the "Source Code") a worldwide, irrevocable, */
+/* nonexclusive, royalty free, copyright license to reproduce, create */
+/* derivative works, distribute, display and perform the Source Code and */
+/* derivative works thereof, and to grant others the rights granted herein. */
+/* */
+/* - The TCG grants to the user of the other parts of the specification */
+/* (other than the Source Code) the rights to reproduce, distribute, */
+/* display, and perform the specification solely for the purpose of */
+/* developing products based on such documents. */
+/* */
+/* 2. Source Code Distribution Conditions: */
+/* */
+/* - Redistributions of Source Code must retain the above copyright licenses, */
+/* this list of conditions and the following disclaimers. */
+/* */
+/* - Redistributions in binary form must reproduce the above copyright */
+/* licenses, this list of conditions and the following disclaimers in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* 3. Disclaimers: */
+/* */
+/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
+/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
+/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
+/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
+/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
+/* information on specification licensing rights available through TCG */
+/* membership agreements. */
+/* */
+/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
+/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
+/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
+/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
+/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
+/* */
+/* - Without limitation, TCG and its members and licensors disclaim all */
+/* liability, including liability for infringement of any proprietary */
+/* rights, relating to use of information in this specification and to the */
+/* implementation of this specification, and TCG disclaims all liability for */
+/* cost of procurement of substitute goods or services, lost profits, loss */
+/* of use, loss of data or any incidental, consequential, direct, indirect, */
+/* or special damages, whether under contract, tort, warranty or otherwise, */
+/* arising in any way out of use or reliance upon this specification or any */
+/* information herein. */
+/* */
+/* (c) Copyright IBM Corp. and others, 2016 - 2021 */
+/* */
+/********************************************************************************/
+
+/* 6.4 SessionProcess.c */
+/* 6.4.1 Introduction */
+/* This file contains the subsystem that process the authorization sessions including implementation
+ of the Dictionary Attack logic. ExecCommand() uses ParseSessionBuffer() to process the
+ authorization session area of a command and BuildResponseSession() to create the authorization
+ session area of a response */
+#define SESSION_PROCESS_C
+#include "Tpm.h"
+#include "ACT.h"
+/* 6.4.3.1 IsDAExempted() */
+/* This function indicates if a handle is exempted from DA logic. A handle is exempted if it is */
+/* a) a primary seed handle, */
+/* b) an object with noDA bit SET, */
+/* c) an NV Index with TPMA_NV_NO_DA bit SET, or */
+/* d) a PCR handle. */
+BOOL
+IsDAExempted(
+ TPM_HANDLE handle // IN: entity handle
+ )
+{
+ BOOL result = FALSE;
+ //
+ switch(HandleGetType(handle))
+ {
+ case TPM_HT_PERMANENT:
+ // All permanent handles, other than TPM_RH_LOCKOUT, are exempt from
+ // DA protection.
+ result = (handle != TPM_RH_LOCKOUT);
+ break;
+ // When this function is called, a persistent object will have been loaded
+ // into an object slot and assigned a transient handle.
+ case TPM_HT_TRANSIENT:
+ {
+ TPMA_OBJECT attributes = ObjectGetPublicAttributes(handle);
+ result = IS_ATTRIBUTE(attributes, TPMA_OBJECT, noDA);
+ break;
+ }
+ case TPM_HT_NV_INDEX:
+ {
+ NV_INDEX *nvIndex = NvGetIndexInfo(handle, NULL);
+ result = IS_ATTRIBUTE(nvIndex->publicArea.attributes, TPMA_NV, NO_DA);
+ break;
+ }
+ case TPM_HT_PCR:
+ // PCRs are always exempted from DA.
+ result = TRUE;
+ break;
+ default:
+ break;
+ }
+ return result;
+}
+/* 6.4.3.2 IncrementLockout() */
+/* This function is called after an authorization failure that involves use of an authValue. If the
+ entity referenced by the handle is not exempt from DA protection, then the failedTries counter
+ will be incremented. */
+static TPM_RC
+IncrementLockout(
+ UINT32 sessionIndex
+ )
+{
+ TPM_HANDLE handle = s_associatedHandles[sessionIndex];
+ TPM_HANDLE sessionHandle = s_sessionHandles[sessionIndex];
+ SESSION *session = NULL;
+ //
+ // Don't increment lockout unless the handle associated with the session
+ // is DA protected or the session is bound to a DA protected entity.
+ if(sessionHandle == TPM_RS_PW)
+ {
+ if(IsDAExempted(handle))
+ return TPM_RC_BAD_AUTH;
+ }
+ else
+ {
+ session = SessionGet(sessionHandle);
+ // If the session is bound to lockout, then use that as the relevant
+ // handle. This means that an authorization failure with a bound session
+ // bound to lockoutAuth will take precedence over any other
+ // lockout check
+ if(session->attributes.isLockoutBound == SET)
+ handle = TPM_RH_LOCKOUT;
+ if(session->attributes.isDaBound == CLEAR
+ && (IsDAExempted(handle) || session->attributes.includeAuth == CLEAR))
+ // If the handle was changed to TPM_RH_LOCKOUT, this will not return
+ // TPM_RC_BAD_AUTH
+ return TPM_RC_BAD_AUTH;
+ }
+ if(handle == TPM_RH_LOCKOUT)
+ {
+ pAssert(gp.lockOutAuthEnabled == TRUE);
+ // lockout is no longer enabled
+ gp.lockOutAuthEnabled = FALSE;
+ // For TPM_RH_LOCKOUT, if lockoutRecovery is 0, no need to update NV since
+ // the lockout authorization will be reset at startup.
+ if(gp.lockoutRecovery != 0)
+ {
+ if(NV_IS_AVAILABLE)
+ // Update NV.
+ NV_SYNC_PERSISTENT(lockOutAuthEnabled);
+ else
+ // No NV access for now. Put the TPM in pending mode.
+ s_DAPendingOnNV = TRUE;
+ }
+ }
+ else
+ {
+ if(gp.recoveryTime != 0)
+ {
+ gp.failedTries++;
+ if(NV_IS_AVAILABLE)
+ // Record changes to NV. NvWrite will SET g_updateNV
+ NV_SYNC_PERSISTENT(failedTries);
+ else
+ // No NV access for now. Put the TPM in pending mode.
+ s_DAPendingOnNV = TRUE;
+ }
+ }
+ // Register a DA failure and reset the timers.
+ DARegisterFailure(handle);
+ return TPM_RC_AUTH_FAIL;
+}
+/* 6.4.3.3 IsSessionBindEntity() */
+/* This function indicates if the entity associated with the handle is the entity, to which this
+ session is bound. The binding would occur by making the bind parameter in TPM2_StartAuthSession()
+ not equal to TPM_RH_NULL. The binding only occurs if the session is an HMAC session. The bind
+ value is a combination of the Name and the authValue of the entity. */
+static BOOL
+IsSessionBindEntity(
+ TPM_HANDLE associatedHandle, // IN: handle to be authorized
+ SESSION *session // IN: associated session
+ )
+{
+ TPM2B_NAME entity; // The bind value for the entity
+ // If the session is not bound, return FALSE.
+ if(session->attributes.isBound)
+ {
+ // Compute the bind value for the entity.
+ SessionComputeBoundEntity(associatedHandle, &entity);
+ // Compare to the bind value in the session.
+ return MemoryEqual2B(&entity.b, &session->u1.boundEntity.b);
+ }
+ return FALSE;
+}
+/* 6.4.3.4 IsPolicySessionRequired() */
+/* Checks if a policy session is required for a command. If a command requires DUP or ADMIN role
+ authorization, then the handle that requires that role is the first handle in the command. This
+ simplifies this checking. If a new command is created that requires multiple ADMIN role
+ authorizations, then it will have to be special-cased in this function. A policy session is
+ required if: */
+/* a) the command requires the DUP role, */
+/* b) the command requires the ADMIN role and the authorized entity is an object and its
+ adminWithPolicy bit is SET, or */
+/* c) the command requires the ADMIN role and the authorized entity is a permanent handle or an NV
+ Index. */
+/* d) The authorized entity is a PCR belonging to a policy group, and has its policy initialized */
+/* Return Values Meaning */
+/* TRUE policy session is required */
+/* FALSE policy session is not required */
+static BOOL
+IsPolicySessionRequired(
+ COMMAND_INDEX commandIndex, // IN: command index
+ UINT32 sessionIndex // IN: session index
+ )
+{
+ AUTH_ROLE role = CommandAuthRole(commandIndex, sessionIndex);
+ TPM_HT type = HandleGetType(s_associatedHandles[sessionIndex]);
+ if(role == AUTH_DUP)
+ return TRUE;
+ if(role == AUTH_ADMIN)
+ {
+ // We allow an exception for ADMIN role in a transient object. If the object
+ // allows ADMIN role actions with authorization, then policy is not
+ // required. For all other cases, there is no way to override the command
+ // requirement that a policy be used
+ if(type == TPM_HT_TRANSIENT)
+ {
+ OBJECT *object = HandleToObject(s_associatedHandles[sessionIndex]);
+ if(!IS_ATTRIBUTE(object->publicArea.objectAttributes, TPMA_OBJECT,
+ adminWithPolicy))
+ return FALSE;
+ }
+ return TRUE;
+ }
+ if(type == TPM_HT_PCR)
+ {
+ if(PCRPolicyIsAvailable(s_associatedHandles[sessionIndex]))
+ {
+ TPM2B_DIGEST policy;
+ TPMI_ALG_HASH policyAlg;
+ policyAlg = PCRGetAuthPolicy(s_associatedHandles[sessionIndex],
+ &policy);
+ if(policyAlg != TPM_ALG_NULL)
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+/* 6.4.3.5 IsAuthValueAvailable() */
+/* This function indicates if authValue is available and allowed for USER role authorization of an
+ entity. */
+/* This function is similar to IsAuthPolicyAvailable() except that it does not check the size of the
+ authValue as IsAuthPolicyAvailable() does (a null authValue is a valid authorization, but a null
+ policy is not a valid policy). */
+/* This function does not check that the handle reference is valid or if the entity is in an
+ enabled hierarchy. Those checks are assumed to have been performed during the handle
+ unmarshaling. */
+static BOOL
+IsAuthValueAvailable(
+ TPM_HANDLE handle, // IN: handle of entity
+ COMMAND_INDEX commandIndex, // IN: command index
+ UINT32 sessionIndex // IN: session index
+ )
+{
+ BOOL result = FALSE;
+ //
+ switch(HandleGetType(handle))
+ {
+ case TPM_HT_PERMANENT:
+ switch(handle)
+ {
+ // At this point hierarchy availability has already been
+ // checked so primary seed handles are always available here
+ case TPM_RH_OWNER:
+ case TPM_RH_ENDORSEMENT:
+ case TPM_RH_PLATFORM:
+#ifdef VENDOR_PERMANENT
+ // This vendor defined handle associated with the
+ // manufacturer's shared secret
+ case VENDOR_PERMANENT:
+#endif
+ // The DA checking has been performed on LockoutAuth but we
+ // bypass the DA logic if we are using lockout policy. The
+ // policy would allow execution to continue an lockoutAuth
+ // could be used, even if direct use of lockoutAuth is disabled
+ case TPM_RH_LOCKOUT:
+ // NullAuth is always available.
+ case TPM_RH_NULL:
+ result = TRUE;
+ break;
+#ifndef __ACT_DISABLED // libtpms added begin
+ FOR_EACH_ACT(CASE_ACT_HANDLE)
+ {
+ // The ACT auth value is not available if the platform is disabled
+ result = g_phEnable == SET;
+ break;
+ }
+#endif // libtpms added end
+ default:
+ // Otherwise authValue is not available.
+ break;
+ }
+ break;
+ case TPM_HT_TRANSIENT:
+ // A persistent object has already been loaded and the internal
+ // handle changed.
+ {
+ OBJECT *object;
+ TPMA_OBJECT attributes;
+ //
+ object = HandleToObject(handle);
+ attributes = object->publicArea.objectAttributes;
+ // authValue is always available for a sequence object.
+ // An alternative for this is to
+ // SET_ATTRIBUTE(object->publicArea, TPMA_OBJECT, userWithAuth) when the
+ // sequence is started.
+ if(ObjectIsSequence(object))
+ {
+ result = TRUE;
+ break;
+ }
+ // authValue is available for an object if it has its sensitive
+ // portion loaded and
+ // 1. userWithAuth bit is SET, or
+ // 2. ADMIN role is required
+ if(object->attributes.publicOnly == CLEAR
+ && (IS_ATTRIBUTE(attributes, TPMA_OBJECT, userWithAuth)
+ || (CommandAuthRole(commandIndex, sessionIndex) == AUTH_ADMIN
+ && !IS_ATTRIBUTE(attributes, TPMA_OBJECT, adminWithPolicy))))
+ result = TRUE;
+ }
+ break;
+ case TPM_HT_NV_INDEX:
+ // NV Index.
+ {
+ NV_REF locator;
+ NV_INDEX *nvIndex = NvGetIndexInfo(handle, &locator);
+ TPMA_NV nvAttributes;
+ //
+ pAssert(nvIndex != 0);
+ nvAttributes = nvIndex->publicArea.attributes;
+ if(IsWriteOperation(commandIndex))
+ {
+ // AuthWrite can't be set for a PIN index
+ if(IS_ATTRIBUTE(nvAttributes, TPMA_NV, AUTHWRITE))
+ result = TRUE;
+ }
+ else
+ {
+ // A "read" operation
+ // For a PIN Index, the authValue is available as long as the
+ // Index has been written and the pinCount is less than pinLimit
+ if(IsNvPinFailIndex(nvAttributes)
+ || IsNvPinPassIndex(nvAttributes))
+ {
+ NV_PIN pin;
+ if(!IS_ATTRIBUTE(nvAttributes, TPMA_NV, WRITTEN))
+ break; // return false
+ // get the index values
+ pin.intVal = NvGetUINT64Data(nvIndex, locator);
+ if(pin.pin.pinCount < pin.pin.pinLimit)
+ result = TRUE;
+ }
+ // For non-PIN Indexes, need to allow use of the authValue
+ else if(IS_ATTRIBUTE(nvAttributes, TPMA_NV, AUTHREAD))
+ result = TRUE;
+ }
+ }
+ break;
+ case TPM_HT_PCR:
+ // PCR handle.
+ // authValue is always allowed for PCR
+ result = TRUE;
+ break;
+ default:
+ // Otherwise, authValue is not available
+ break;
+ }
+ return result;
+}
+
+/* 6.4.3.6 IsAuthPolicyAvailable() */
+/* This function indicates if an authPolicy is available and allowed. */
+/* This function does not check that the handle reference is valid or if the entity is in an enabled
+ hierarchy. Those checks are assumed to have been performed during the handle unmarshaling. */
+/* Return Values Meaning */
+/* TRUE authPolicy is available */
+/* FALSE authPolicy is not available */
+static BOOL
+IsAuthPolicyAvailable(
+ TPM_HANDLE handle, // IN: handle of entity
+ COMMAND_INDEX commandIndex, // IN: command index
+ UINT32 sessionIndex // IN: session index
+ )
+{
+ BOOL result = FALSE;
+ //
+ switch(HandleGetType(handle))
+ {
+ case TPM_HT_PERMANENT:
+ switch(handle)
+ {
+ // At this point hierarchy availability has already been checked.
+ case TPM_RH_OWNER:
+ if(gp.ownerPolicy.t.size != 0)
+ result = TRUE;
+ break;
+ case TPM_RH_ENDORSEMENT:
+ if(gp.endorsementPolicy.t.size != 0)
+ result = TRUE;
+ break;
+ case TPM_RH_PLATFORM:
+ if(gc.platformPolicy.t.size != 0)
+ result = TRUE;
+ break;
+#define ACT_GET_POLICY(N) \
+ case TPM_RH_ACT_##N: \
+ if(go.ACT_##N.authPolicy.t.size != 0) \
+ result = TRUE; \
+ break;
+
+ FOR_EACH_ACT(ACT_GET_POLICY)
+
+ case TPM_RH_LOCKOUT:
+ if(gp.lockoutPolicy.t.size != 0)
+ result = TRUE;
+ break;
+ default:
+ break;
+ }
+ break;
+ case TPM_HT_TRANSIENT:
+ {
+ // Object handle.
+ // An evict object would already have been loaded and given a
+ // transient object handle by this point.
+ OBJECT *object = HandleToObject(handle);
+ // Policy authorization is not available for an object with only
+ // public portion loaded.
+ if(object->attributes.publicOnly == CLEAR)
+ {
+ // Policy authorization is always available for an object but
+ // is never available for a sequence.
+ if(!ObjectIsSequence(object))
+ result = TRUE;
+ }
+ break;
+ }
+ case TPM_HT_NV_INDEX:
+ // An NV Index.
+ {
+ NV_INDEX *nvIndex = NvGetIndexInfo(handle, NULL);
+ TPMA_NV nvAttributes = nvIndex->publicArea.attributes;
+ //
+ // If the policy size is not zero, check if policy can be used.
+ if(nvIndex->publicArea.authPolicy.t.size != 0)
+ {
+ // If policy session is required for this handle, always
+ // uses policy regardless of the attributes bit setting
+ if(IsPolicySessionRequired(commandIndex, sessionIndex))
+ result = TRUE;
+ // Otherwise, the presence of the policy depends on the NV
+ // attributes.
+ else if(IsWriteOperation(commandIndex))
+ {
+ if(IS_ATTRIBUTE(nvAttributes, TPMA_NV, POLICYWRITE))
+ result = TRUE;
+ }
+ else
+ {
+ if(IS_ATTRIBUTE(nvAttributes, TPMA_NV, POLICYREAD))
+ result = TRUE;
+ }
+ }
+ }
+ break;
+ case TPM_HT_PCR:
+ // PCR handle.
+ if(PCRPolicyIsAvailable(handle))
+ result = TRUE;
+ break;
+ default:
+ break;
+ }
+ return result;
+}
+/* 6.4.4 Session Parsing Functions */
+/* 6.4.4.1 ClearCpRpHashes() */
+
+void
+ClearCpRpHashes(
+ COMMAND *command
+ )
+{
+ // The macros expand according to the implemented hash algorithms. An IDE may
+ // complain that COMMAND does not contain SHA1CpHash or SHA1RpHash because of the
+ // complexity of the macro expansion where the data space is defined; but, if SHA1
+ // is implemented, it actually does and the compiler is happy.
+#define CLEAR_CP_HASH(HASH, Hash) command->Hash##CpHash.b.size = 0;
+ FOR_EACH_HASH(CLEAR_CP_HASH)
+#define CLEAR_RP_HASH(HASH, Hash) command->Hash##RpHash.b.size = 0;
+ FOR_EACH_HASH(CLEAR_RP_HASH)
+}
+
+/* 6.4.4.2 GetCpHashPointer() */
+/* Function to get a pointer to the cpHash of the command */
+static TPM2B_DIGEST *
+GetCpHashPointer(
+ COMMAND *command,
+ TPMI_ALG_HASH hashAlg
+ )
+{
+ TPM2B_DIGEST *retVal;
+ //
+ // Define the macro that will expand for each implemented algorithm in the switch
+ // statement below.
+#define GET_CP_HASH_POINTER(HASH, Hash) \
+ case ALG_##HASH##_VALUE: \
+ retVal = (TPM2B_DIGEST *)&command->Hash##CpHash; \
+ break;
+
+ switch(hashAlg)
+ {
+ // For each implemented hash, this will expand as defined above
+ // by GET_CP_HASH_POINTER. Your IDE may complain that
+ // 'struct "COMMAND" has no field "SHA1CpHash"' but the compiler says
+ // it does, so...
+ FOR_EACH_HASH(GET_CP_HASH_POINTER)
+ default:
+ retVal = NULL;
+ break;
+ }
+ return retVal;
+}
+
+/* 6.4.4.3 GetRpHashPointer() */
+/* Function to get a pointer to the RpHash() of the command */
+static TPM2B_DIGEST *
+GetRpHashPointer(
+ COMMAND *command,
+ TPMI_ALG_HASH hashAlg
+ )
+{
+ TPM2B_DIGEST *retVal;
+ //
+ // Define the macro that will expand for each implemented algorithm in the switch
+ // statement below.
+#define GET_RP_HASH_POINTER(HASH, Hash) \
+ case ALG_##HASH##_VALUE: \
+ retVal = (TPM2B_DIGEST *)&command->Hash##RpHash; \
+ break;
+
+ switch(hashAlg)
+ {
+ // For each implemented hash, this will expand as defined above
+ // by GET_RP_HASH_POINTER. Your IDE may complain that
+ // 'struct "COMMAND" has no field 'SHA1RpHash'" but the compiler says
+ // it does, so...
+ FOR_EACH_HASH(GET_RP_HASH_POINTER)
+ default:
+ retVal = NULL;
+ break;
+ }
+ return retVal;
+}
+
+/* 6.4.4.4 ComputeCpHash() */
+/* This function computes the cpHash as defined in Part 2 and described in Part 1. */
+static TPM2B_DIGEST *
+ComputeCpHash(
+ COMMAND *command, // IN: command parsing structure
+ TPMI_ALG_HASH hashAlg // IN: hash algorithm
+ )
+{
+ UINT32 i;
+ HASH_STATE hashState;
+ TPM2B_NAME name;
+ TPM2B_DIGEST *cpHash;
+ // cpHash = hash(commandCode [ || authName1
+ // [ || authName2
+ // [ || authName 3 ]]]
+ // [ || parameters])
+ // A cpHash can contain just a commandCode only if the lone session is
+ // an audit session.
+ // Get pointer to the hash value
+ cpHash = GetCpHashPointer(command, hashAlg);
+ if(cpHash->t.size == 0)
+ {
+ cpHash->t.size = CryptHashStart(&hashState, hashAlg);
+ // Add commandCode.
+ CryptDigestUpdateInt(&hashState, sizeof(TPM_CC), command->code);
+ // Add authNames for each of the handles.
+ for(i = 0; i < command->handleNum; i++)
+ CryptDigestUpdate2B(&hashState, &EntityGetName(command->handles[i],
+ &name)->b);
+ // Add the parameters.
+ CryptDigestUpdate(&hashState, command->parameterSize,
+ command->parameterBuffer);
+ // Complete the hash.
+ CryptHashEnd2B(&hashState, &cpHash->b);
+ }
+ return cpHash;
+}
+/* 6.4.4.5 GetCpHash() */
+/* This function is used to access a precomputed cpHash. */
+static TPM2B_DIGEST *
+GetCpHash(
+ COMMAND *command,
+ TPMI_ALG_HASH hashAlg
+ )
+{
+ TPM2B_DIGEST *cpHash = GetCpHashPointer(command, hashAlg);
+ //
+ pAssert(cpHash->t.size != 0);
+ return cpHash;
+}
+/* 6.4.4.6 CompareTemplateHash() */
+/* This function computes the template hash and compares it to the session templateHash. It is the
+ hash of the second parameter assuming that the command is TPM2_Create(), TPM2_CreatePrimary(), or
+ TPM2_CreateLoaded() */
+static BOOL
+CompareTemplateHash(
+ COMMAND *command, // IN: parsing structure
+ SESSION *session // IN: session data
+ )
+{
+ BYTE *pBuffer = command->parameterBuffer;
+ INT32 pSize = command->parameterSize;
+ TPM2B_DIGEST tHash;
+ UINT16 size;
+ //
+ // Only try this for the three commands for which it is intended
+ if(command->code != TPM_CC_Create
+ && command->code != TPM_CC_CreatePrimary
+#if CC_CreateLoaded
+ && command->code != TPM_CC_CreateLoaded
+#endif
+ )
+ return FALSE;
+ // Assume that the first parameter is a TPM2B and unmarshal the size field
+ // Note: this will not affect the parameter buffer and size in the calling
+ // function.
+ if(UINT16_Unmarshal(&size, &pBuffer, &pSize) != TPM_RC_SUCCESS)
+ return FALSE;
+ // reduce the space in the buffer.
+ // NOTE: this could make pSize go negative if the parameters are not correct but
+ // the unmarshaling code does not try to unmarshal if the remaining size is
+ // negative.
+ pSize -= size;
+ // Advance the pointer
+ pBuffer += size;
+ // Get the size of what should be the template
+ if(UINT16_Unmarshal(&size, &pBuffer, &pSize) != TPM_RC_SUCCESS)
+ return FALSE;
+ // See if this is reasonable
+ if(size > pSize)
+ return FALSE;
+ // Hash the template data
+ tHash.t.size = CryptHashBlock(session->authHashAlg, size, pBuffer,
+ sizeof(tHash.t.buffer), tHash.t.buffer);
+ return(MemoryEqual2B(&session->u1.templateHash.b, &tHash.b));
+}
+/* 6.4.4.7 CompareNameHash() */
+/* This function computes the name hash and compares it to the nameHash in the session data. */
+BOOL
+CompareNameHash(
+ COMMAND *command, // IN: main parsing structure
+ SESSION *session // IN: session structure with nameHash
+ )
+{
+ HASH_STATE hashState;
+ TPM2B_DIGEST nameHash;
+ UINT32 i;
+ TPM2B_NAME name;
+ //
+ nameHash.t.size = CryptHashStart(&hashState, session->authHashAlg);
+ // Add names.
+ for(i = 0; i < command->handleNum; i++)
+ CryptDigestUpdate2B(&hashState, &EntityGetName(command->handles[i],
+ &name)->b);
+ // Complete hash.
+ CryptHashEnd2B(&hashState, &nameHash.b);
+ // and compare
+ return MemoryEqual(session->u1.nameHash.t.buffer, nameHash.t.buffer,
+ nameHash.t.size);
+}
+/* 6.4.4.8 CheckPWAuthSession() */
+/* This function validates the authorization provided in a PWAP session. It compares the input value
+ to authValue of the authorized entity. Argument sessionIndex is used to get handles handle of the
+ referenced entities from s_inputAuthValues[] and s_associatedHandles[]. */
+/* Error Returns Meaning */
+/* TPM_RC_AUTH_FAIL authorization fails and increments DA failure count */
+/* TPM_RC_BAD_AUTH authorization fails but DA does not apply */
+static TPM_RC
+CheckPWAuthSession(
+ UINT32 sessionIndex // IN: index of session to be processed
+ )
+{
+ TPM2B_AUTH authValue;
+ TPM_HANDLE associatedHandle = s_associatedHandles[sessionIndex];
+ // Strip trailing zeros from the password.
+ MemoryRemoveTrailingZeros(&s_inputAuthValues[sessionIndex]);
+ // Get the authValue with trailing zeros removed
+ EntityGetAuthValue(associatedHandle, &authValue);
+ // Success if the values are identical.
+ if(MemoryEqual2B(&s_inputAuthValues[sessionIndex].b, &authValue.b))
+ {
+ return TPM_RC_SUCCESS;
+ }
+ else // if the digests are not identical
+ {
+ // Invoke DA protection if applicable.
+ return IncrementLockout(sessionIndex);
+ }
+}
+/* 6.4.4.9 ComputeCommandHMAC() */
+/* This function computes the HMAC for an authorization session in a command. */
+static TPM2B_DIGEST *
+ComputeCommandHMAC(
+ COMMAND *command, // IN: primary control structure
+ UINT32 sessionIndex, // IN: index of session to be processed
+ TPM2B_DIGEST *hmac // OUT: authorization HMAC
+ )
+{
+ TPM2B_TYPE(KEY, (sizeof(AUTH_VALUE) * 2));
+ TPM2B_KEY key;
+ BYTE marshalBuffer[sizeof(TPMA_SESSION)];
+ BYTE *buffer;
+ UINT32 marshalSize;
+ HMAC_STATE hmacState;
+ TPM2B_NONCE *nonceDecrypt;
+ TPM2B_NONCE *nonceEncrypt;
+ SESSION *session;
+ nonceDecrypt = NULL;
+ nonceEncrypt = NULL;
+ // Determine if extra nonceTPM values are going to be required.
+ // If this is the first session (sessionIndex = 0) and it is an authorization
+ // session that uses an HMAC, then check if additional session nonces are to be
+ // included.
+ if(sessionIndex == 0
+ && s_associatedHandles[sessionIndex] != TPM_RH_UNASSIGNED)
+ {
+ // If there is a decrypt session and if this is not the decrypt session,
+ // then an extra nonce may be needed.
+ if(s_decryptSessionIndex != UNDEFINED_INDEX
+ && s_decryptSessionIndex != sessionIndex)
+ {
+ // Will add the nonce for the decrypt session.
+ SESSION *decryptSession
+ = SessionGet(s_sessionHandles[s_decryptSessionIndex]);
+ nonceDecrypt = &decryptSession->nonceTPM;
+ }
+ // Now repeat for the encrypt session.
+ if(s_encryptSessionIndex != UNDEFINED_INDEX
+ && s_encryptSessionIndex != sessionIndex
+ && s_encryptSessionIndex != s_decryptSessionIndex)
+ {
+ // Have to have the nonce for the encrypt session.
+ SESSION *encryptSession
+ = SessionGet(s_sessionHandles[s_encryptSessionIndex]);
+ nonceEncrypt = &encryptSession->nonceTPM;
+ }
+ }
+ // Continue with the HMAC processing.
+ session = SessionGet(s_sessionHandles[sessionIndex]);
+ // Generate HMAC key.
+ MemoryCopy2B(&key.b, &session->sessionKey.b, sizeof(key.t.buffer));
+ // Check if the session has an associated handle and if the associated entity
+ // is the one to which the session is bound. If not, add the authValue of
+ // this entity to the HMAC key.
+ // If the session is bound to the object or the session is a policy session
+ // with no authValue required, do not include the authValue in the HMAC key.
+ // Note: For a policy session, its isBound attribute is CLEARED.
+ // Include the entity authValue if it is needed
+ if(session->attributes.includeAuth == SET)
+ {
+ TPM2B_AUTH authValue;
+ // Get the entity authValue with trailing zeros removed
+ EntityGetAuthValue(s_associatedHandles[sessionIndex], &authValue);
+ // add the authValue to the HMAC key
+ MemoryConcat2B(&key.b, &authValue.b, sizeof(key.t.buffer));
+ }
+ // if the HMAC key size is 0, a NULL string HMAC is allowed
+ if(key.t.size == 0
+ && s_inputAuthValues[sessionIndex].t.size == 0)
+ {
+ hmac->t.size = 0;
+ return hmac;
+ }
+ // Start HMAC
+ hmac->t.size = CryptHmacStart2B(&hmacState, session->authHashAlg, &key.b);
+ // Add cpHash
+ CryptDigestUpdate2B(&hmacState.hashState,
+ &ComputeCpHash(command, session->authHashAlg)->b);
+ // Add nonces as required
+ CryptDigestUpdate2B(&hmacState.hashState, &s_nonceCaller[sessionIndex].b);
+ CryptDigestUpdate2B(&hmacState.hashState, &session->nonceTPM.b);
+ if(nonceDecrypt != NULL)
+ CryptDigestUpdate2B(&hmacState.hashState, &nonceDecrypt->b);
+ if(nonceEncrypt != NULL)
+ CryptDigestUpdate2B(&hmacState.hashState, &nonceEncrypt->b);
+ // Add sessionAttributes
+ buffer = marshalBuffer;
+ marshalSize = TPMA_SESSION_Marshal(&(s_attributes[sessionIndex]),
+ &buffer, NULL);
+ CryptDigestUpdate(&hmacState.hashState, marshalSize, marshalBuffer);
+ // Complete the HMAC computation
+ CryptHmacEnd2B(&hmacState, &hmac->b);
+ return hmac;
+}
+/* 6.4.4.10 CheckSessionHMAC() */
+/* This function checks the HMAC of in a session. It uses ComputeCommandHMAC() to compute the
+ expected HMAC value and then compares the result with the HMAC in the authorization session. The
+ authorization is successful if they are the same. */
+/* If the authorizations are not the same, IncrementLockout() is called. It will return
+ TPM_RC_AUTH_FAIL if the failure caused the failureCount to increment. Otherwise, it will return
+ TPM_RC_BAD_AUTH. */
+/* Error Returns Meaning */
+/* TPM_RC_AUTH_FAIL authorization failure caused failureCount increment */
+/* TPM_RC_BAD_AUTH authorization failure did not cause failureCount increment */
+static TPM_RC
+CheckSessionHMAC(
+ COMMAND *command, // IN: primary control structure
+ UINT32 sessionIndex // IN: index of session to be processed
+ )
+{
+ TPM2B_DIGEST hmac; // authHMAC for comparing
+ // Compute authHMAC
+ ComputeCommandHMAC(command, sessionIndex, &hmac);
+ // Compare the input HMAC with the authHMAC computed above.
+ if(!MemoryEqual2B(&s_inputAuthValues[sessionIndex].b, &hmac.b))
+ {
+ // If an HMAC session has a failure, invoke the anti-hammering
+ // if it applies to the authorized entity or the session.
+ // Otherwise, just indicate that the authorization is bad.
+ return IncrementLockout(sessionIndex);
+ }
+ return TPM_RC_SUCCESS;
+}
+/* 6.4.4.11 CheckPolicyAuthSession() */
+/* This function is used to validate the authorization in a policy session. This function performs
+ the following comparisons to see if a policy authorization is properly provided. The check
+ are: */
+/* a) compare policyDigest in session with authPolicy associated with the entity to be
+ authorized; */
+/* b) compare timeout if applicable; */
+/* c) compare commandCode if applicable; */
+/* d) compare cpHash if applicable; and */
+/* e) see if PCR values have changed since computed. */
+/* If all the above checks succeed, the handle is authorized. The order of these comparisons is not
+ important because any failure will result in the same error code. */
+/* Error Returns Meaning */
+/* TPM_RC_PCR_CHANGED PCR value is not current */
+/* TPM_RC_POLICY_FAIL policy session fails */
+/* TPM_RC_LOCALITY command locality is not allowed */
+/* TPM_RC_POLICY_CC CC doesn't match */
+/* TPM_RC_EXPIRED policy session has expired */
+/* TPM_RC_PP PP is required but not asserted */
+/* TPM_RC_NV_UNAVAILABLE NV is not available for write */
+/* TPM_RC_NV_RATE NV is rate limiting */
+static TPM_RC
+CheckPolicyAuthSession(
+ COMMAND *command, // IN: primary parsing structure
+ UINT32 sessionIndex // IN: index of session to be processed
+ )
+{
+ SESSION *session;
+ TPM2B_DIGEST authPolicy;
+ TPMI_ALG_HASH policyAlg;
+ UINT8 locality;
+ // Initialize pointer to the authorization session.
+ session = SessionGet(s_sessionHandles[sessionIndex]);
+ // If the command is TPM2_PolicySecret(), make sure that
+ // either password or authValue is required
+ if(command->code == TPM_CC_PolicySecret
+ && session->attributes.isPasswordNeeded == CLEAR
+ && session->attributes.isAuthValueNeeded == CLEAR)
+ return TPM_RC_MODE;
+ // See if the PCR counter for the session is still valid.
+ if(!SessionPCRValueIsCurrent(session))
+ return TPM_RC_PCR_CHANGED;
+ // Get authPolicy.
+ policyAlg = EntityGetAuthPolicy(s_associatedHandles[sessionIndex],
+ &authPolicy);
+ // Compare authPolicy.
+ if(!MemoryEqual2B(&session->u2.policyDigest.b, &authPolicy.b))
+ return TPM_RC_POLICY_FAIL;
+ // Policy is OK so check if the other factors are correct
+ // Compare policy hash algorithm.
+ if(policyAlg != session->authHashAlg)
+ return TPM_RC_POLICY_FAIL;
+ // Compare timeout.
+ if(session->timeout != 0)
+ {
+ // Cannot compare time if clock stop advancing. An TPM_RC_NV_UNAVAILABLE
+ // or TPM_RC_NV_RATE error may be returned here. This doesn't mean that
+ // a new nonce will be created just that, because TPM time can't advance
+ // we can't do time-based operations.
+ RETURN_IF_NV_IS_NOT_AVAILABLE;
+ if((session->timeout < g_time)
+ || (session->epoch != g_timeEpoch))
+ return TPM_RC_EXPIRED;
+ }
+ // If command code is provided it must match
+ if(session->commandCode != 0)
+ {
+ if(session->commandCode != command->code)
+ return TPM_RC_POLICY_CC;
+ }
+ else
+ {
+ // If command requires a DUP or ADMIN authorization, the session must have
+ // command code set.
+ AUTH_ROLE role = CommandAuthRole(command->index, sessionIndex);
+ if(role == AUTH_ADMIN || role == AUTH_DUP)
+ return TPM_RC_POLICY_FAIL;
+ }
+ // Check command locality.
+ {
+ BYTE sessionLocality[sizeof(TPMA_LOCALITY)];
+ BYTE *buffer = sessionLocality;
+ // Get existing locality setting in canonical form
+ sessionLocality[0] = 0;
+ TPMA_LOCALITY_Marshal(&session->commandLocality, &buffer, NULL);
+ // See if the locality has been set
+ if(sessionLocality[0] != 0)
+ {
+ // If so, get the current locality
+ locality = _plat__LocalityGet();
+ if(locality < 5)
+ {
+ if(((sessionLocality[0] & (1 << locality)) == 0)
+ || sessionLocality[0] > 31)
+ return TPM_RC_LOCALITY;
+ }
+ else if(locality > 31)
+ {
+ if(sessionLocality[0] != locality)
+ return TPM_RC_LOCALITY;
+ }
+ else
+ {
+ // Could throw an assert here but a locality error is just
+ // as good. It just means that, whatever the locality is, it isn't
+ // the locality requested so...
+ return TPM_RC_LOCALITY;
+ }
+ }
+ } // end of locality check
+ // Check physical presence.
+ if(session->attributes.isPPRequired == SET
+ && !_plat__PhysicalPresenceAsserted())
+ return TPM_RC_PP;
+ // Compare cpHash/nameHash if defined, or if the command requires an ADMIN or
+ // DUP role for this handle.
+ if(session->u1.cpHash.b.size != 0)
+ {
+ BOOL OK;
+ if(session->attributes.isCpHashDefined)
+ // Compare cpHash.
+ OK = MemoryEqual2B(&session->u1.cpHash.b,
+ &ComputeCpHash(command, session->authHashAlg)->b);
+ else if(session->attributes.isTemplateSet)
+ OK = CompareTemplateHash(command, session);
+ else
+ OK = CompareNameHash(command, session);
+ if(!OK)
+ return TPM_RCS_POLICY_FAIL;
+ }
+ if(session->attributes.checkNvWritten)
+ {
+ NV_REF locator;
+ NV_INDEX *nvIndex;
+ // If this is not an NV index, the policy makes no sense so fail it.
+ if(HandleGetType(s_associatedHandles[sessionIndex]) != TPM_HT_NV_INDEX)
+ return TPM_RC_POLICY_FAIL;
+ // Get the index data
+ nvIndex = NvGetIndexInfo(s_associatedHandles[sessionIndex], &locator);
+ // Make sure that the TPMA_WRITTEN_ATTRIBUTE has the desired state
+ if((IS_ATTRIBUTE(nvIndex->publicArea.attributes, TPMA_NV, WRITTEN))
+ != (session->attributes.nvWrittenState == SET))
+ return TPM_RC_POLICY_FAIL;
+ }
+ return TPM_RC_SUCCESS;
+}
+/* 6.4.4.12 RetrieveSessionData() */
+/* This function will unmarshal the sessions in the session area of a command. The values are placed
+ in the arrays that are defined at the beginning of this file. The normal unmarshaling errors are
+ possible. */
+/* Error Returns Meaning */
+/* TPM_RC_SUCCSS unmarshaled without error */
+/* TPM_RC_SIZE the number of bytes unmarshaled is not the same as the value for authorizationSize in
+ the command */
+static TPM_RC
+RetrieveSessionData(
+ COMMAND *command // IN: main parsing structure for command
+ )
+{
+ int i;
+ TPM_RC result;
+ SESSION *session;
+ TPMA_SESSION sessionAttributes;
+ TPM_HT sessionType;
+ INT32 sessionIndex;
+ TPM_RC errorIndex;
+ s_decryptSessionIndex = UNDEFINED_INDEX;
+ s_encryptSessionIndex = UNDEFINED_INDEX;
+ s_auditSessionIndex = UNDEFINED_INDEX;
+ for(sessionIndex = 0; command->authSize > 0; sessionIndex++)
+ {
+ errorIndex = TPM_RC_S + g_rcIndex[sessionIndex];
+ // If maximum allowed number of sessions has been parsed, return a size
+ // error with a session number that is larger than the number of allowed
+ // sessions
+ if(sessionIndex == MAX_SESSION_NUM)
+ return TPM_RCS_SIZE + errorIndex;
+ // make sure that the associated handle for each session starts out
+ // unassigned
+ s_associatedHandles[sessionIndex] = TPM_RH_UNASSIGNED;
+ // First parameter: Session handle.
+ result = TPMI_SH_AUTH_SESSION_Unmarshal(
+ &s_sessionHandles[sessionIndex],
+ &command->parameterBuffer,
+ &command->authSize, TRUE);
+ if(result != TPM_RC_SUCCESS)
+ return result + TPM_RC_S + g_rcIndex[sessionIndex];
+ // Second parameter: Nonce.
+ result = TPM2B_NONCE_Unmarshal(&s_nonceCaller[sessionIndex],
+ &command->parameterBuffer,
+ &command->authSize);
+ if(result != TPM_RC_SUCCESS)
+ return result + TPM_RC_S + g_rcIndex[sessionIndex];
+ // Third parameter: sessionAttributes.
+ result = TPMA_SESSION_Unmarshal(&s_attributes[sessionIndex],
+ &command->parameterBuffer,
+ &command->authSize);
+ if(result != TPM_RC_SUCCESS)
+ return result + TPM_RC_S + g_rcIndex[sessionIndex];
+ // Fourth parameter: authValue (PW or HMAC).
+ result = TPM2B_AUTH_Unmarshal(&s_inputAuthValues[sessionIndex],
+ &command->parameterBuffer,
+ &command->authSize);
+ if(result != TPM_RC_SUCCESS)
+ return result + errorIndex;
+ sessionAttributes = s_attributes[sessionIndex];
+ if(s_sessionHandles[sessionIndex] == TPM_RS_PW)
+ {
+ // A PWAP session needs additional processing.
+ // Can't have any attributes set other than continueSession bit
+ if(IS_ATTRIBUTE(sessionAttributes, TPMA_SESSION, encrypt)
+ || IS_ATTRIBUTE(sessionAttributes, TPMA_SESSION, decrypt)
+ || IS_ATTRIBUTE(sessionAttributes, TPMA_SESSION, audit)
+ || IS_ATTRIBUTE(sessionAttributes, TPMA_SESSION, auditExclusive)
+ || IS_ATTRIBUTE(sessionAttributes, TPMA_SESSION, auditReset))
+ return TPM_RCS_ATTRIBUTES + errorIndex;
+ // The nonce size must be zero.
+ if(s_nonceCaller[sessionIndex].t.size != 0)
+ return TPM_RCS_NONCE + errorIndex;
+ continue;
+ }
+ // For not password sessions...
+ // Find out if the session is loaded.
+ if(!SessionIsLoaded(s_sessionHandles[sessionIndex]))
+ return TPM_RC_REFERENCE_S0 + sessionIndex;
+ sessionType = HandleGetType(s_sessionHandles[sessionIndex]);
+ session = SessionGet(s_sessionHandles[sessionIndex]);
+ // Check if the session is an HMAC/policy session.
+ if((session->attributes.isPolicy == SET
+ && sessionType == TPM_HT_HMAC_SESSION)
+ || (session->attributes.isPolicy == CLEAR
+ && sessionType == TPM_HT_POLICY_SESSION))
+ return TPM_RCS_HANDLE + errorIndex;
+ // Check that this handle has not previously been used.
+ for(i = 0; i < sessionIndex; i++)
+ {
+ if(s_sessionHandles[i] == s_sessionHandles[sessionIndex])
+ return TPM_RCS_HANDLE + errorIndex;
+ }
+ // If the session is used for parameter encryption or audit as well, set
+ // the corresponding Indexes.
+ // First process decrypt.
+ if(IS_ATTRIBUTE(sessionAttributes, TPMA_SESSION, decrypt))
+ {
+ // Check if the commandCode allows command parameter encryption.
+ if(DecryptSize(command->index) == 0)
+ return TPM_RCS_ATTRIBUTES + errorIndex;
+ // Encrypt attribute can only appear in one session
+ if(s_decryptSessionIndex != UNDEFINED_INDEX)
+ return TPM_RCS_ATTRIBUTES + errorIndex;
+ // Can't decrypt if the session's symmetric algorithm is TPM_ALG_NULL
+ if(session->symmetric.algorithm == TPM_ALG_NULL)
+ return TPM_RCS_SYMMETRIC + errorIndex;
+ // All checks passed, so set the index for the session used to decrypt
+ // a command parameter.
+ s_decryptSessionIndex = sessionIndex;
+ }
+ // Now process encrypt.
+ if(IS_ATTRIBUTE(sessionAttributes, TPMA_SESSION, encrypt))
+ {
+ // Check if the commandCode allows response parameter encryption.
+ if(EncryptSize(command->index) == 0)
+ return TPM_RCS_ATTRIBUTES + errorIndex;
+ // Encrypt attribute can only appear in one session.
+ if(s_encryptSessionIndex != UNDEFINED_INDEX)
+ return TPM_RCS_ATTRIBUTES + errorIndex;
+ // Can't encrypt if the session's symmetric algorithm is TPM_ALG_NULL
+ if(session->symmetric.algorithm == TPM_ALG_NULL)
+ return TPM_RCS_SYMMETRIC + errorIndex;
+ // All checks passed, so set the index for the session used to encrypt
+ // a response parameter.
+ s_encryptSessionIndex = sessionIndex;
+ }
+ // At last process audit.
+ if(IS_ATTRIBUTE(sessionAttributes, TPMA_SESSION, audit))
+ {
+ // Audit attribute can only appear in one session.
+ if(s_auditSessionIndex != UNDEFINED_INDEX)
+ return TPM_RCS_ATTRIBUTES + errorIndex;
+ // An audit session can not be policy session.
+ if(HandleGetType(s_sessionHandles[sessionIndex])
+ == TPM_HT_POLICY_SESSION)
+ return TPM_RCS_ATTRIBUTES + errorIndex;
+ // If this is a reset of the audit session, or the first use
+ // of the session as an audit session, it doesn't matter what
+ // the exclusive state is. The session will become exclusive.
+ if(!IS_ATTRIBUTE(sessionAttributes, TPMA_SESSION, auditReset)
+ && session->attributes.isAudit == SET)
+ {
+ // Not first use or reset. If auditExlusive is SET, then this
+ // session must be the current exclusive session.
+ if(IS_ATTRIBUTE(sessionAttributes, TPMA_SESSION, auditExclusive)
+ && g_exclusiveAuditSession != s_sessionHandles[sessionIndex])
+ return TPM_RC_EXCLUSIVE;
+ }
+ s_auditSessionIndex = sessionIndex;
+ }
+ // Initialize associated handle as undefined. This will be changed when
+ // the handles are processed.
+ s_associatedHandles[sessionIndex] = TPM_RH_UNASSIGNED;
+ }
+ command->sessionNum = sessionIndex;
+ return TPM_RC_SUCCESS;
+}
+/* 6.4.4.13 CheckLockedOut() */
+/* This function checks to see if the TPM is in lockout. This function should only be called if the
+ entity being checked is subject to DA protection. The TPM is in lockout if the NV is not
+ available and a DA write is pending. Otherwise the TPM is locked out if checking for lockoutAuth
+ (lockoutAuthCheck == TRUE) and use of lockoutAuth is disabled, or failedTries >= maxTries */
+/* Error Returns Meaning */
+/* TPM_RC_NV_RATE NV is rate limiting */
+/* TPM_RC_NV_UNAVAILABLE NV is not available at this time */
+/* TPM_RC_LOCKOUT TPM is in lockout */
+static TPM_RC
+CheckLockedOut(
+ BOOL lockoutAuthCheck // IN: TRUE if checking is for lockoutAuth
+ )
+{
+ // If NV is unavailable, and current cycle state recorded in NV is not
+ // SU_NONE_VALUE, refuse to check any authorization because we would
+ // not be able to handle a DA failure.
+ if(!NV_IS_AVAILABLE && NV_IS_ORDERLY)
+ return g_NvStatus;
+ // Check if DA info needs to be updated in NV.
+ if(s_DAPendingOnNV)
+ {
+ // If NV is accessible,
+ RETURN_IF_NV_IS_NOT_AVAILABLE;
+ // ... write the pending DA data and proceed.
+ NV_SYNC_PERSISTENT(lockOutAuthEnabled);
+ NV_SYNC_PERSISTENT(failedTries);
+ s_DAPendingOnNV = FALSE;
+ }
+ // Lockout is in effect if checking for lockoutAuth and use of lockoutAuth
+ // is disabled...
+ if(lockoutAuthCheck)
+ {
+ if(gp.lockOutAuthEnabled == FALSE)
+ return TPM_RC_LOCKOUT;
+ }
+ else
+ {
+ // ... or if the number of failed tries has been maxed out.
+ if(gp.failedTries >= gp.maxTries)
+ return TPM_RC_LOCKOUT;
+#if USE_DA_USED
+ // If the daUsed flag is not SET, then no DA validation until the
+ // daUsed state is written to NV
+ if(!g_daUsed)
+ {
+ RETURN_IF_NV_IS_NOT_AVAILABLE;
+ g_daUsed = TRUE;
+ gp.orderlyState = SU_DA_USED_VALUE;
+ NV_SYNC_PERSISTENT(orderlyState);
+ return TPM_RC_RETRY;
+ }
+#endif
+ }
+ return TPM_RC_SUCCESS;
+}
+/* 6.4.4.14 CheckAuthSession() */
+/* This function checks that the authorization session properly authorizes the use of the associated
+ handle. */
+/* Error Returns Meaning */
+/* TPM_RC_LOCKOUT entity is protected by DA and TPM is in lockout, or TPM is locked out on NV update
+ pending on DA parameters */
+/* TPM_RC_PP Physical Presence is required but not provided */
+/* TPM_RC_AUTH_FAIL HMAC or PW authorization failed with DA side-effects (can be a policy
+ session) */
+/* TPM_RC_BAD_AUTH HMAC or PW authorization failed without DA side-effects (can be a policy
+ session) */
+/* TPM_RC_POLICY_FAIL if policy session fails */
+/* TPM_RC_POLICY_CC command code of policy was wrong */
+/* TPM_RC_EXPIRED the policy session has expired */
+/* TPM_RC_PCR ??? */
+/* TPM_RC_AUTH_UNAVAILABLE authValue or authPolicy unavailable */
+static TPM_RC
+CheckAuthSession(
+ COMMAND *command, // IN: primary parsing structure
+ UINT32 sessionIndex // IN: index of session to be processed
+ )
+{
+ TPM_RC result = TPM_RC_SUCCESS;
+ SESSION *session = NULL;
+ TPM_HANDLE sessionHandle = s_sessionHandles[sessionIndex];
+ TPM_HANDLE associatedHandle = s_associatedHandles[sessionIndex];
+ TPM_HT sessionHandleType = HandleGetType(sessionHandle);
+ BOOL authUsed;
+
+ pAssert(sessionHandle != TPM_RH_UNASSIGNED);
+
+ // Take care of physical presence
+ if(associatedHandle == TPM_RH_PLATFORM)
+ {
+ // If the physical presence is required for this command, check for PP
+ // assertion. If it isn't asserted, no point going any further.
+ if(PhysicalPresenceIsRequired(command->index)
+ && !_plat__PhysicalPresenceAsserted())
+ return TPM_RC_PP;
+ }
+ if(sessionHandle != TPM_RS_PW)
+ {
+ session = SessionGet(sessionHandle);
+ // Set includeAuth to indicate if DA checking will be required and if the
+ // authValue will be included in any HMAC.
+ if(sessionHandleType == TPM_HT_POLICY_SESSION)
+ {
+ // For a policy session, will check the DA status of the entity if either
+ // isAuthValueNeeded or isPasswordNeeded is SET.
+ session->attributes.includeAuth =
+ session->attributes.isAuthValueNeeded
+ || session->attributes.isPasswordNeeded;
+ }
+ else
+ {
+ // For an HMAC session, need to check unless the session
+ // is bound.
+ session->attributes.includeAuth =
+ !IsSessionBindEntity(s_associatedHandles[sessionIndex], session);
+ }
+ authUsed = session->attributes.includeAuth;
+ }
+ else
+ // Password session
+ authUsed = TRUE;
+ // If the authorization session is going to use an authValue, then make sure
+ // that access to that authValue isn't locked out.
+ if(authUsed)
+ {
+ // See if entity is subject to lockout.
+ if(!IsDAExempted(associatedHandle))
+ {
+ // See if in lockout
+ result = CheckLockedOut(associatedHandle == TPM_RH_LOCKOUT);
+ if(result != TPM_RC_SUCCESS)
+ return result;
+ }
+ }
+ // Policy or HMAC+PW?
+ if(sessionHandleType != TPM_HT_POLICY_SESSION)
+ {
+ // for non-policy session make sure that a policy session is not required
+ if(IsPolicySessionRequired(command->index, sessionIndex))
+ return TPM_RC_AUTH_TYPE;
+ // The authValue must be available.
+ // Note: The authValue is going to be "used" even if it is an EmptyAuth.
+ // and the session is bound.
+ if(!IsAuthValueAvailable(associatedHandle, command->index, sessionIndex))
+ return TPM_RC_AUTH_UNAVAILABLE;
+ }
+ else
+ {
+ // ... see if the entity has a policy, ...
+ // Note: IsAuthPolicyAvailable will return FALSE if the sensitive area of the
+ // object is not loaded
+ if(!IsAuthPolicyAvailable(associatedHandle, command->index, sessionIndex))
+ return TPM_RC_AUTH_UNAVAILABLE;
+ // ... and check the policy session.
+ result = CheckPolicyAuthSession(command, sessionIndex);
+ if(result != TPM_RC_SUCCESS)
+ return result;
+ }
+ // Check authorization according to the type
+ if((TPM_RS_PW == sessionHandle) || (session->attributes.isPasswordNeeded == SET))
+ result = CheckPWAuthSession(sessionIndex);
+ else
+ result = CheckSessionHMAC(command, sessionIndex);
+ // Do processing for PIN Indexes are only three possibilities for 'result' at
+ // this point: TPM_RC_SUCCESS, TPM_RC_AUTH_FAIL, TPM_RC_BAD_AUTH
+ // For all these cases, we would have to process a PIN index if the
+ // authValue of the index was used for authorization.
+ if((TPM_HT_NV_INDEX == HandleGetType(associatedHandle)) && authUsed)
+ {
+ NV_REF locator;
+ NV_INDEX *nvIndex = NvGetIndexInfo(associatedHandle, &locator);
+ NV_PIN pinData;
+ TPMA_NV nvAttributes;
+
+ pAssert(nvIndex != NULL);
+ nvAttributes = nvIndex->publicArea.attributes;
+ // If this is a PIN FAIL index and the value has been written
+ // then we can update the counter (increment or clear)
+ if(IsNvPinFailIndex(nvAttributes)
+ && IS_ATTRIBUTE(nvAttributes, TPMA_NV, WRITTEN))
+ {
+ pinData.intVal = NvGetUINT64Data(nvIndex, locator);
+ if(result != TPM_RC_SUCCESS)
+ pinData.pin.pinCount++;
+ else
+ pinData.pin.pinCount = 0;
+ NvWriteUINT64Data(nvIndex, pinData.intVal);
+ }
+ // If this is a PIN PASS Index, increment if we have used the
+ // authorization value.
+ // NOTE: If the counter has already hit the limit, then we
+ // would not get here because the authorization value would not
+ // be available and the TPM would have returned before it gets here
+ else if(IsNvPinPassIndex(nvAttributes)
+ && IS_ATTRIBUTE(nvAttributes, TPMA_NV, WRITTEN)
+ && result == TPM_RC_SUCCESS)
+ {
+ // If the access is valid, then increment the use counter
+ pinData.intVal = NvGetUINT64Data(nvIndex, locator);
+ pinData.pin.pinCount++;
+ NvWriteUINT64Data(nvIndex, pinData.intVal);
+ }
+ }
+ return result;
+}
+#if CC_GetCommandAuditDigest
+/* 6.4.4.15 CheckCommandAudit() */
+/* This function is called before the command is processed if audit is enabled for the command. It
+ will check to see if the audit can be performed and will ensure that the cpHash is available for
+ the audit. */
+/* Error Returns Meaning */
+/* TPM_RC_NV_UNAVAILABLE NV is not available for write */
+/* TPM_RC_NV_RATE NV is rate limiting */
+static TPM_RC
+CheckCommandAudit(
+ COMMAND *command
+ )
+{
+ // If the audit digest is clear and command audit is required, NV must be
+ // available so that TPM2_GetCommandAuditDigest() is able to increment
+ // audit counter. If NV is not available, the function bails out to prevent
+ // the TPM from attempting an operation that would fail anyway.
+ if(gr.commandAuditDigest.t.size == 0
+ || GetCommandCode(command->index) == TPM_CC_GetCommandAuditDigest)
+ {
+ RETURN_IF_NV_IS_NOT_AVAILABLE;
+ }
+ // Make sure that the cpHash is computed for the algorithm
+ ComputeCpHash(command, gp.auditHashAlg);
+ return TPM_RC_SUCCESS;
+}
+#endif
+/* 6.4.4.16 ParseSessionBuffer() */
+/* This function is the entry function for command session processing. It iterates sessions in
+ session area and reports if the required authorization has been properly provided. It also
+ processes audit session and passes the information of encryption sessions to parameter encryption
+ module. */
+/* Error Returns Meaning */
+/* various parsing failure or authorization failure */
+TPM_RC
+ParseSessionBuffer(
+ COMMAND *command // IN: the structure that contains
+ )
+{
+ TPM_RC result;
+ UINT32 i;
+ INT32 size = 0;
+ TPM2B_AUTH extraKey;
+ UINT32 sessionIndex;
+ TPM_RC errorIndex;
+ SESSION *session = NULL;
+ // Check if a command allows any session in its session area.
+ if(!IsSessionAllowed(command->index))
+ return TPM_RC_AUTH_CONTEXT;
+ // Default-initialization.
+ command->sessionNum = 0;
+ result = RetrieveSessionData(command);
+ if(result != TPM_RC_SUCCESS)
+ return result;
+ // There is no command in the TPM spec that has more handles than
+ // MAX_SESSION_NUM.
+ pAssert(command->handleNum <= MAX_SESSION_NUM);
+ // Associate the session with an authorization handle.
+ for(i = 0; i < command->handleNum; i++)
+ {
+ if(CommandAuthRole(command->index, i) != AUTH_NONE)
+ {
+ // If the received session number is less than the number of handles
+ // that requires authorization, an error should be returned.
+ // Note: for all the TPM 2.0 commands, handles requiring
+ // authorization come first in a command input and there are only ever
+ // two values requiring authorization
+ if(i > (command->sessionNum - 1))
+ return TPM_RC_AUTH_MISSING;
+ // Record the handle associated with the authorization session
+ s_associatedHandles[i] = command->handles[i];
+ }
+ }
+ // Consistency checks are done first to avoid authorization failure when the
+ // command will not be executed anyway.
+ for(sessionIndex = 0; sessionIndex < command->sessionNum; sessionIndex++)
+ {
+ errorIndex = TPM_RC_S + g_rcIndex[sessionIndex];
+ // PW session must be an authorization session
+ if(s_sessionHandles[sessionIndex] == TPM_RS_PW)
+ {
+ if(s_associatedHandles[sessionIndex] == TPM_RH_UNASSIGNED)
+ return TPM_RCS_HANDLE + errorIndex;
+ // a password session can't be audit, encrypt or decrypt
+ if(IS_ATTRIBUTE(s_attributes[sessionIndex], TPMA_SESSION, audit)
+ || IS_ATTRIBUTE(s_attributes[sessionIndex], TPMA_SESSION, encrypt)
+ || IS_ATTRIBUTE(s_attributes[sessionIndex], TPMA_SESSION, decrypt))
+ return TPM_RCS_ATTRIBUTES + errorIndex;
+ session = NULL;
+ }
+ else
+ {
+ session = SessionGet(s_sessionHandles[sessionIndex]);
+ // A trial session can not appear in session area, because it cannot
+ // be used for authorization, audit or encrypt/decrypt.
+ if(session->attributes.isTrialPolicy == SET)
+ return TPM_RCS_ATTRIBUTES + errorIndex;
+ // See if the session is bound to a DA protected entity
+ // NOTE: Since a policy session is never bound, a policy is still
+ // usable even if the object is DA protected and the TPM is in
+ // lockout.
+ if(session->attributes.isDaBound == SET)
+ {
+ result = CheckLockedOut(session->attributes.isLockoutBound == SET);
+ if(result != TPM_RC_SUCCESS)
+ return result;
+ }
+ // If this session is for auditing, make sure the cpHash is computed.
+ if(IS_ATTRIBUTE(s_attributes[sessionIndex], TPMA_SESSION, audit))
+ ComputeCpHash(command, session->authHashAlg);
+ }
+ // if the session has an associated handle, check the authorization
+ if(s_associatedHandles[sessionIndex] != TPM_RH_UNASSIGNED)
+ {
+ result = CheckAuthSession(command, sessionIndex);
+ if(result != TPM_RC_SUCCESS)
+ return RcSafeAddToResult(result, errorIndex);
+ }
+ else
+ {
+ // a session that is not for authorization must either be encrypt,
+ // decrypt, or audit
+ if(!IS_ATTRIBUTE(s_attributes[sessionIndex], TPMA_SESSION, audit)
+ && !IS_ATTRIBUTE(s_attributes[sessionIndex], TPMA_SESSION, encrypt)
+ && !IS_ATTRIBUTE(s_attributes[sessionIndex], TPMA_SESSION, decrypt))
+ return TPM_RCS_ATTRIBUTES + errorIndex;
+ // no authValue included in any of the HMAC computations
+ pAssert(session != NULL);
+ session->attributes.includeAuth = CLEAR;
+ // check HMAC for encrypt/decrypt/audit only sessions
+ result = CheckSessionHMAC(command, sessionIndex);
+ if(result != TPM_RC_SUCCESS)
+ return RcSafeAddToResult(result, errorIndex);
+ }
+ }
+#if CC_GetCommandAuditDigest
+ // Check if the command should be audited. Need to do this before any parameter
+ // encryption so that the cpHash for the audit is correct
+ if(CommandAuditIsRequired(command->index))
+ {
+ result = CheckCommandAudit(command);
+ if(result != TPM_RC_SUCCESS)
+ return result; // No session number to reference
+ }
+#endif
+ // Decrypt the first parameter if applicable. This should be the last operation
+ // in session processing.
+ // If the encrypt session is associated with a handle and the handle's
+ // authValue is available, then authValue is concatenated with sessionKey to
+ // generate encryption key, no matter if the handle is the session bound entity
+ // or not.
+ if(s_decryptSessionIndex != UNDEFINED_INDEX)
+ {
+ // If this is an authorization session, include the authValue in the
+ // generation of the decryption key
+ if(s_associatedHandles[s_decryptSessionIndex] != TPM_RH_UNASSIGNED)
+ {
+ EntityGetAuthValue(s_associatedHandles[s_decryptSessionIndex],
+ &extraKey);
+ }
+ else
+ {
+ extraKey.b.size = 0;
+ }
+ size = DecryptSize(command->index);
+ result = CryptParameterDecryption(s_sessionHandles[s_decryptSessionIndex],
+ &s_nonceCaller[s_decryptSessionIndex].b,
+ command->parameterSize, (UINT16)size,
+ &extraKey,
+ command->parameterBuffer);
+ if(result != TPM_RC_SUCCESS)
+ return RcSafeAddToResult(result,
+ TPM_RC_S + g_rcIndex[s_decryptSessionIndex]);
+ }
+ return TPM_RC_SUCCESS;
+}
+/* 6.4.4.17 CheckAuthNoSession() */
+/* Function to process a command with no session associated. The function makes sure all the handles
+ in the command require no authorization. */
+/* Error Returns Meaning */
+/* TPM_RC_AUTH_MISSING failure - one or more handles require authorization */
+TPM_RC
+CheckAuthNoSession(
+ COMMAND *command // IN: command parsing structure
+ )
+{
+ UINT32 i;
+ TPM_RC result = TPM_RC_SUCCESS;
+ // Check if the command requires authorization
+ for(i = 0; i < command->handleNum; i++)
+ {
+ if(CommandAuthRole(command->index, i) != AUTH_NONE)
+ return TPM_RC_AUTH_MISSING;
+ }
+#if CC_GetCommandAuditDigest
+ // Check if the command should be audited.
+ if(CommandAuditIsRequired(command->index))
+ {
+ result = CheckCommandAudit(command);
+ if(result != TPM_RC_SUCCESS)
+ return result;
+ }
+#endif
+ // Initialize number of sessions to be 0
+ command->sessionNum = 0;
+ return TPM_RC_SUCCESS;
+}
+/* 6.4.5 Response Session Processing */
+/* 6.4.5.1 Introduction */
+/* The following functions build the session area in a response and handle the audit sessions (if
+ present). */
+/* 6.4.5.2 ComputeRpHash() */
+/* Function to compute rpHash (Response Parameter Hash). The rpHash is only computed if there is an
+ HMAC authorization session and the return code is TPM_RC_SUCCESS. */
+static TPM2B_DIGEST *
+ComputeRpHash(
+ COMMAND *command, // IN: command structure
+ TPM_ALG_ID hashAlg // IN: hash algorithm to compute rpHash
+ )
+{
+ TPM2B_DIGEST *rpHash = GetRpHashPointer(command, hashAlg);
+ HASH_STATE hashState;
+ if(rpHash->t.size == 0)
+ {
+ // rpHash := hash(responseCode || commandCode || parameters)
+ // Initiate hash creation.
+ rpHash->t.size = CryptHashStart(&hashState, hashAlg);
+ // Add hash constituents.
+ CryptDigestUpdateInt(&hashState, sizeof(TPM_RC), TPM_RC_SUCCESS);
+ CryptDigestUpdateInt(&hashState, sizeof(TPM_CC), command->code);
+ CryptDigestUpdate(&hashState, command->parameterSize,
+ command->parameterBuffer);
+ // Complete hash computation.
+ CryptHashEnd2B(&hashState, &rpHash->b);
+ }
+ return rpHash;
+}
+/* 6.4.5.3 InitAuditSession() */
+/* This function initializes the audit data in an audit session. */
+static void
+InitAuditSession(
+ SESSION *session // session to be initialized
+ )
+{
+ // Mark session as an audit session.
+ session->attributes.isAudit = SET;
+ // Audit session can not be bound.
+ session->attributes.isBound = CLEAR;
+ // Size of the audit log is the size of session hash algorithm digest.
+ session->u2.auditDigest.t.size = CryptHashGetDigestSize(session->authHashAlg);
+ // Set the original digest value to be 0.
+ MemorySet(&session->u2.auditDigest.t.buffer,
+ 0,
+ session->u2.auditDigest.t.size);
+ return;
+}
+/* 6.4.5.4 UpdateAuditDigest */
+/* Function to update an audit digest */
+static void
+UpdateAuditDigest(
+ COMMAND *command,
+ TPMI_ALG_HASH hashAlg,
+ TPM2B_DIGEST *digest
+ )
+{
+ HASH_STATE hashState;
+ TPM2B_DIGEST *cpHash = GetCpHash(command, hashAlg);
+ TPM2B_DIGEST *rpHash = ComputeRpHash(command, hashAlg);
+ //
+ pAssert(cpHash != NULL);
+ // digestNew := hash (digestOld || cpHash || rpHash)
+ // Start hash computation.
+ digest->t.size = CryptHashStart(&hashState, hashAlg);
+ // Add old digest.
+ CryptDigestUpdate2B(&hashState, &digest->b);
+ // Add cpHash
+ CryptDigestUpdate2B(&hashState, &cpHash->b);
+ // Add rpHash
+ CryptDigestUpdate2B(&hashState, &rpHash->b);
+ // Finalize the hash.
+ CryptHashEnd2B(&hashState, &digest->b);
+}
+/* 6.4.5.5 Audit() */
+/* This function updates the audit digest in an audit session. */
+static void
+Audit(
+ COMMAND *command, // IN: primary control structure
+ SESSION *auditSession // IN: loaded audit session
+ )
+{
+ UpdateAuditDigest(command, auditSession->authHashAlg,
+ &auditSession->u2.auditDigest);
+ return;
+}
+#if CC_GetCommandAuditDigest
+/* 6.4.5.6 CommandAudit() */
+/* This function updates the command audit digest. */
+static void
+CommandAudit(
+ COMMAND *command // IN:
+ )
+{
+ // If the digest.size is one, it indicates the special case of changing
+ // the audit hash algorithm. For this case, no audit is done on exit.
+ // NOTE: When the hash algorithm is changed, g_updateNV is set in order to
+ // force an update to the NV on exit so that the change in digest will
+ // be recorded. So, it is safe to exit here without setting any flags
+ // because the digest change will be written to NV when this code exits.
+ if(gr.commandAuditDigest.t.size == 1)
+ {
+ gr.commandAuditDigest.t.size = 0;
+ return;
+ }
+ // If the digest size is zero, need to start a new digest and increment
+ // the audit counter.
+ if(gr.commandAuditDigest.t.size == 0)
+ {
+ gr.commandAuditDigest.t.size = CryptHashGetDigestSize(gp.auditHashAlg);
+ MemorySet(gr.commandAuditDigest.t.buffer,
+ 0,
+ gr.commandAuditDigest.t.size);
+ // Bump the counter and save its value to NV.
+ gp.auditCounter++;
+ NV_SYNC_PERSISTENT(auditCounter);
+ }
+ UpdateAuditDigest(command, gp.auditHashAlg, &gr.commandAuditDigest);
+ return;
+}
+#endif
+/* 6.4.5.7 UpdateAuditSessionStatus() */
+/* Function to update the internal audit related states of a session. It */
+/* a) initializes the session as audit session and sets it to be exclusive if this is the first time
+ it is used for audit or audit reset was requested; */
+/* b) reports exclusive audit session; */
+/* c) extends audit log; and */
+/* d) clears exclusive audit session if no audit session found in the command. */
+static void
+UpdateAuditSessionStatus(
+ COMMAND *command // IN: primary control structure
+ )
+{
+ UINT32 i;
+ TPM_HANDLE auditSession = TPM_RH_UNASSIGNED;
+ // Iterate through sessions
+ for(i = 0; i < command->sessionNum; i++)
+ {
+ SESSION *session;
+ // PW session do not have a loaded session and can not be an audit
+ // session either. Skip it.
+ if(s_sessionHandles[i] == TPM_RS_PW)
+ continue;
+ session = SessionGet(s_sessionHandles[i]);
+ // If a session is used for audit
+ if(IS_ATTRIBUTE(s_attributes[i], TPMA_SESSION, audit))
+ {
+ // An audit session has been found
+ auditSession = s_sessionHandles[i];
+ // If the session has not been an audit session yet, or
+ // the auditSetting bits indicate a reset, initialize it and set
+ // it to be the exclusive session
+ if(session->attributes.isAudit == CLEAR
+ || IS_ATTRIBUTE(s_attributes[i], TPMA_SESSION, auditReset))
+ {
+ InitAuditSession(session);
+ g_exclusiveAuditSession = auditSession;
+ }
+ else
+ {
+ // Check if the audit session is the current exclusive audit
+ // session and, if not, clear previous exclusive audit session.
+ if(g_exclusiveAuditSession != auditSession)
+ g_exclusiveAuditSession = TPM_RH_UNASSIGNED;
+ }
+ // Report audit session exclusivity.
+ if(g_exclusiveAuditSession == auditSession)
+ {
+ SET_ATTRIBUTE(s_attributes[i], TPMA_SESSION, auditExclusive);
+ }
+ else
+ {
+ CLEAR_ATTRIBUTE(s_attributes[i], TPMA_SESSION, auditExclusive);
+ }
+ // Extend audit log.
+ Audit(command, session);
+ }
+ }
+ // If no audit session is found in the command, and the command allows
+ // a session then, clear the current exclusive
+ // audit session.
+ if(auditSession == TPM_RH_UNASSIGNED && IsSessionAllowed(command->index))
+ {
+ g_exclusiveAuditSession = TPM_RH_UNASSIGNED;
+ }
+ return;
+}
+/* 6.4.5.8 ComputeResponseHMAC() */
+/* Function to compute HMAC for authorization session in a response. */
+static void
+ComputeResponseHMAC(
+ COMMAND *command, // IN: command structure
+ UINT32 sessionIndex, // IN: session index to be processed
+ SESSION *session, // IN: loaded session
+ TPM2B_DIGEST *hmac // OUT: authHMAC
+ )
+{
+ TPM2B_TYPE(KEY, (sizeof(AUTH_VALUE) * 2));
+ TPM2B_KEY key; // HMAC key
+ BYTE marshalBuffer[sizeof(TPMA_SESSION)];
+ BYTE *buffer;
+ UINT32 marshalSize;
+ HMAC_STATE hmacState;
+ TPM2B_DIGEST *rpHash = ComputeRpHash(command, session->authHashAlg);
+ // Generate HMAC key
+ MemoryCopy2B(&key.b, &session->sessionKey.b, sizeof(key.t.buffer));
+ // Add the object authValue if required
+ if(session->attributes.includeAuth == SET)
+ {
+ // Note: includeAuth may be SET for a policy that is used in
+ // UndefineSpaceSpecial(). At this point, the Index has been deleted
+ // so the includeAuth will have no meaning. However, the
+ // s_associatedHandles[] value for the session is now set to TPM_RH_NULL so
+ // this will return the authValue associated with TPM_RH_NULL and that is
+ // and empty buffer.
+ TPM2B_AUTH authValue;
+ // Get the authValue with trailing zeros removed
+ EntityGetAuthValue(s_associatedHandles[sessionIndex], &authValue);
+ // Add it to the key
+ MemoryConcat2B(&key.b, &authValue.b, sizeof(key.t.buffer));
+ }
+ // if the HMAC key size is 0, the response HMAC is computed according to the
+ // input HMAC
+ if(key.t.size == 0
+ && s_inputAuthValues[sessionIndex].t.size == 0)
+ {
+ hmac->t.size = 0;
+ return;
+ }
+ // Start HMAC computation.
+ hmac->t.size = CryptHmacStart2B(&hmacState, session->authHashAlg, &key.b);
+ // Add hash components.
+ CryptDigestUpdate2B(&hmacState.hashState, &rpHash->b);
+ CryptDigestUpdate2B(&hmacState.hashState, &session->nonceTPM.b);
+ CryptDigestUpdate2B(&hmacState.hashState, &s_nonceCaller[sessionIndex].b);
+ // Add session attributes.
+ buffer = marshalBuffer;
+ marshalSize = TPMA_SESSION_Marshal(&s_attributes[sessionIndex], &buffer, NULL);
+ CryptDigestUpdate(&hmacState.hashState, marshalSize, marshalBuffer);
+ // Finalize HMAC.
+ CryptHmacEnd2B(&hmacState, &hmac->b);
+ return;
+}
+/* 6.4.5.9 UpdateInternalSession() */
+/* Updates internal sessions: */
+/* a) Restarts session time. */
+/* b) Clears a policy session since nonce is rolling. */
+static void
+UpdateInternalSession(
+ SESSION *session, // IN: the session structure
+ UINT32 i // IN: session number
+ )
+{
+ // If nonce is rolling in a policy session, the policy related data
+ // will be re-initialized.
+ if(HandleGetType(s_sessionHandles[i]) == TPM_HT_POLICY_SESSION
+ && IS_ATTRIBUTE(s_attributes[i], TPMA_SESSION, continueSession))
+ {
+ // When the nonce rolls it starts a new timing interval for the
+ // policy session.
+ SessionResetPolicyData(session);
+ SessionSetStartTime(session);
+ }
+ return;
+}
+/* 6.4.5.10 BuildSingleResponseAuth() */
+/* Function to compute response HMAC value for a policy or HMAC session. */
+static TPM2B_NONCE *
+BuildSingleResponseAuth(
+ COMMAND *command, // IN: command structure
+ UINT32 sessionIndex, // IN: session index to be processed
+ TPM2B_AUTH *auth // OUT: authHMAC
+ )
+{
+ // Fill in policy/HMAC based session response.
+ SESSION *session = SessionGet(s_sessionHandles[sessionIndex]);
+ // If the session is a policy session with isPasswordNeeded SET, the
+ // authorization field is empty.
+ if(HandleGetType(s_sessionHandles[sessionIndex]) == TPM_HT_POLICY_SESSION
+ && session->attributes.isPasswordNeeded == SET)
+ auth->t.size = 0;
+ else
+ // Compute response HMAC.
+ ComputeResponseHMAC(command, sessionIndex, session, auth);
+ UpdateInternalSession(session, sessionIndex);
+ return &session->nonceTPM;
+}
+/* 6.4.5.11 UpdateAllNonceTPM() */
+/* Updates TPM nonce for all sessions in command. */
+static void
+UpdateAllNonceTPM(
+ COMMAND *command // IN: controlling structure
+ )
+{
+ UINT32 i;
+ SESSION *session;
+ for(i = 0; i < command->sessionNum; i++)
+ {
+ // If not a PW session, compute the new nonceTPM.
+ if(s_sessionHandles[i] != TPM_RS_PW)
+ {
+ session = SessionGet(s_sessionHandles[i]);
+ // Update nonceTPM in both internal session and response.
+ CryptRandomGenerate(session->nonceTPM.t.size,
+ session->nonceTPM.t.buffer);
+ }
+ }
+ return;
+}
+/* 6.4.5.12 BuildResponseSession() */
+/* Function to build Session buffer in a response. The authorization data is added to the end of
+ command->responseBuffer. The size of the authorization area is accumulated in
+ command->authSize. When this is called, command->responseBuffer is pointing at the next location
+ in the response buffer to be filled. This is where the authorization sessions will go, if
+ any. command->parameterSize is the number of bytes that have been marshaled as parameters in the
+ output buffer. */
+void
+BuildResponseSession(
+ COMMAND *command // IN: structure that has relevant command
+ // information
+ )
+{
+ pAssert(command->authSize == 0);
+ // Reset the parameter buffer to point to the start of the parameters so that
+ // there is a starting point for any rpHash that might be generated and so there
+ // is a place where parameter encryption would start
+ command->parameterBuffer = command->responseBuffer - command->parameterSize;
+ // Session nonces should be updated before parameter encryption
+ if(command->tag == TPM_ST_SESSIONS)
+ {
+ UpdateAllNonceTPM(command);
+ // Encrypt first parameter if applicable. Parameter encryption should
+ // happen after nonce update and before any rpHash is computed.
+ // If the encrypt session is associated with a handle, the authValue of
+ // this handle will be concatenated with sessionKey to generate
+ // encryption key, no matter if the handle is the session bound entity
+ // or not. The authValue is added to sessionKey only when the authValue
+ // is available.
+ if(s_encryptSessionIndex != UNDEFINED_INDEX)
+ {
+ UINT32 size;
+ TPM2B_AUTH extraKey;
+ extraKey.b.size = 0;
+ // If this is an authorization session, include the authValue in the
+ // generation of the encryption key
+ if(s_associatedHandles[s_encryptSessionIndex] != TPM_RH_UNASSIGNED)
+ {
+ EntityGetAuthValue(s_associatedHandles[s_encryptSessionIndex],
+ &extraKey);
+ }
+ size = EncryptSize(command->index);
+ CryptParameterEncryption(s_sessionHandles[s_encryptSessionIndex],
+ &s_nonceCaller[s_encryptSessionIndex].b,
+ (UINT16)size,
+ &extraKey,
+ command->parameterBuffer);
+ }
+ }
+ // Audit sessions should be processed regardless of the tag because
+ // a command with no session may cause a change of the exclusivity state.
+ UpdateAuditSessionStatus(command);
+#if CC_GetCommandAuditDigest
+ // Command Audit
+ if(CommandAuditIsRequired(command->index))
+ CommandAudit(command);
+#endif
+ // Process command with sessions.
+ if(command->tag == TPM_ST_SESSIONS)
+ {
+ UINT32 i;
+ pAssert(command->sessionNum > 0);
+ // Iterate over each session in the command session area, and create
+ // corresponding sessions for response.
+ for(i = 0; i < command->sessionNum; i++)
+ {
+ TPM2B_NONCE *nonceTPM;
+ TPM2B_DIGEST responseAuth;
+ // Make sure that continueSession is SET on any Password session.
+ // This makes it marginally easier for the management software
+ // to keep track of the closed sessions.
+ if(s_sessionHandles[i] == TPM_RS_PW)
+ {
+ SET_ATTRIBUTE(s_attributes[i], TPMA_SESSION, continueSession);
+ responseAuth.t.size = 0;
+ nonceTPM = (TPM2B_NONCE *)&responseAuth;
+ }
+ else
+ {
+ // Compute the response HMAC and get a pointer to the nonce used.
+ // This function will also update the values if needed. Note, the
+ nonceTPM = BuildSingleResponseAuth(command, i, &responseAuth);
+ }
+ command->authSize += TPM2B_NONCE_Marshal(nonceTPM,
+ &command->responseBuffer,
+ NULL);
+ command->authSize += TPMA_SESSION_Marshal(&s_attributes[i],
+ &command->responseBuffer,
+ NULL);
+ command->authSize += TPM2B_DIGEST_Marshal(&responseAuth,
+ &command->responseBuffer,
+ NULL);
+ if(!IS_ATTRIBUTE(s_attributes[i], TPMA_SESSION, continueSession))
+ SessionFlush(s_sessionHandles[i]);
+ }
+ }
+ return;
+}
+/* 6.4.5.13 SessionRemoveAssociationToHandle() */
+/* This function deals with the case where an entity associated with an authorization is deleted
+ during command processing. The primary use of this is to support UndefineSpaceSpecial(). */
+void
+SessionRemoveAssociationToHandle(
+ TPM_HANDLE handle
+ )
+{
+ UINT32 i;
+ for(i = 0; i < MAX_SESSION_NUM; i++)
+ {
+ if(s_associatedHandles[i] == handle)
+ {
+ s_associatedHandles[i] = TPM_RH_NULL;
+ }
+ }
+}
diff --git a/src/tpm2/SessionProcess_fp.h b/src/tpm2/SessionProcess_fp.h
new file mode 100644
index 0000000..cfc7b76
--- /dev/null
+++ b/src/tpm2/SessionProcess_fp.h
@@ -0,0 +1,97 @@
+/********************************************************************************/
+/* */
+/* */
+/* Written by Ken Goldman */
+/* IBM Thomas J. Watson Research Center */
+/* $Id: SessionProcess_fp.h 1490 2019-07-26 21:13:22Z kgoldman $ */
+/* */
+/* Licenses and Notices */
+/* */
+/* 1. Copyright Licenses: */
+/* */
+/* - Trusted Computing Group (TCG) grants to the user of the source code in */
+/* this specification (the "Source Code") a worldwide, irrevocable, */
+/* nonexclusive, royalty free, copyright license to reproduce, create */
+/* derivative works, distribute, display and perform the Source Code and */
+/* derivative works thereof, and to grant others the rights granted herein. */
+/* */
+/* - The TCG grants to the user of the other parts of the specification */
+/* (other than the Source Code) the rights to reproduce, distribute, */
+/* display, and perform the specification solely for the purpose of */
+/* developing products based on such documents. */
+/* */
+/* 2. Source Code Distribution Conditions: */
+/* */
+/* - Redistributions of Source Code must retain the above copyright licenses, */
+/* this list of conditions and the following disclaimers. */
+/* */
+/* - Redistributions in binary form must reproduce the above copyright */
+/* licenses, this list of conditions and the following disclaimers in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* 3. Disclaimers: */
+/* */
+/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
+/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
+/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
+/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
+/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
+/* information on specification licensing rights available through TCG */
+/* membership agreements. */
+/* */
+/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
+/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
+/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
+/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
+/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
+/* */
+/* - Without limitation, TCG and its members and licensors disclaim all */
+/* liability, including liability for infringement of any proprietary */
+/* rights, relating to use of information in this specification and to the */
+/* implementation of this specification, and TCG disclaims all liability for */
+/* cost of procurement of substitute goods or services, lost profits, loss */
+/* of use, loss of data or any incidental, consequential, direct, indirect, */
+/* or special damages, whether under contract, tort, warranty or otherwise, */
+/* arising in any way out of use or reliance upon this specification or any */
+/* information herein. */
+/* */
+/* (c) Copyright IBM Corp. and others, 2016 */
+/* */
+/********************************************************************************/
+
+#ifndef SESSIONPROCESS_FP_H
+#define SESSIONPROCESS_FP_H
+
+BOOL
+IsDAExempted(
+ TPM_HANDLE handle // IN: entity handle
+ );
+void
+ClearCpRpHashes(
+ COMMAND *command
+ );
+BOOL
+CompareNameHash(
+ COMMAND *command, // IN: main parsing structure
+ SESSION *session // IN: session structure with nameHash
+ );
+TPM_RC
+ParseSessionBuffer(
+ COMMAND *command // IN: the structure that contains
+ );
+TPM_RC
+CheckAuthNoSession(
+ COMMAND *command // IN: command parsing structure
+ );
+void
+BuildResponseSession(
+ COMMAND *command // IN: structure that has relevant command
+ // information
+ );
+void
+SessionRemoveAssociationToHandle(
+ TPM_HANDLE handle
+ );
+
+
+#endif
diff --git a/src/tpm2/Session_fp.h b/src/tpm2/Session_fp.h
new file mode 100644
index 0000000..10a670e
--- /dev/null
+++ b/src/tpm2/Session_fp.h
@@ -0,0 +1,158 @@
+/********************************************************************************/
+/* */
+/* */
+/* Written by Ken Goldman */
+/* IBM Thomas J. Watson Research Center */
+/* $Id: Session_fp.h 1490 2019-07-26 21:13:22Z kgoldman $ */
+/* */
+/* Licenses and Notices */
+/* */
+/* 1. Copyright Licenses: */
+/* */
+/* - Trusted Computing Group (TCG) grants to the user of the source code in */
+/* this specification (the "Source Code") a worldwide, irrevocable, */
+/* nonexclusive, royalty free, copyright license to reproduce, create */
+/* derivative works, distribute, display and perform the Source Code and */
+/* derivative works thereof, and to grant others the rights granted herein. */
+/* */
+/* - The TCG grants to the user of the other parts of the specification */
+/* (other than the Source Code) the rights to reproduce, distribute, */
+/* display, and perform the specification solely for the purpose of */
+/* developing products based on such documents. */
+/* */
+/* 2. Source Code Distribution Conditions: */
+/* */
+/* - Redistributions of Source Code must retain the above copyright licenses, */
+/* this list of conditions and the following disclaimers. */
+/* */
+/* - Redistributions in binary form must reproduce the above copyright */
+/* licenses, this list of conditions and the following disclaimers in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* 3. Disclaimers: */
+/* */
+/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
+/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
+/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
+/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
+/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
+/* information on specification licensing rights available through TCG */
+/* membership agreements. */
+/* */
+/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
+/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
+/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
+/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
+/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
+/* */
+/* - Without limitation, TCG and its members and licensors disclaim all */
+/* liability, including liability for infringement of any proprietary */
+/* rights, relating to use of information in this specification and to the */
+/* implementation of this specification, and TCG disclaims all liability for */
+/* cost of procurement of substitute goods or services, lost profits, loss */
+/* of use, loss of data or any incidental, consequential, direct, indirect, */
+/* or special damages, whether under contract, tort, warranty or otherwise, */
+/* arising in any way out of use or reliance upon this specification or any */
+/* information herein. */
+/* */
+/* (c) Copyright IBM Corp. and others, 2016 - 2019 */
+/* */
+/********************************************************************************/
+
+#ifndef SESSION_FP_H
+#define SESSION_FP_H
+
+BOOL
+SessionStartup(
+ STARTUP_TYPE type
+ );
+BOOL
+SessionIsLoaded(
+ TPM_HANDLE handle // IN: session handle
+ );
+BOOL
+SessionIsSaved(
+ TPM_HANDLE handle // IN: session handle
+ );
+BOOL
+SequenceNumberForSavedContextIsValid(
+ TPMS_CONTEXT *context // IN: pointer to a context structure to be
+ // validated
+ );
+BOOL
+SessionPCRValueIsCurrent(
+ SESSION *session // IN: session structure
+ );
+SESSION *
+SessionGet(
+ TPM_HANDLE handle // IN: session handle
+ );
+TPM_RC
+SessionCreate(
+ TPM_SE sessionType, // IN: the session type
+ TPMI_ALG_HASH authHash, // IN: the hash algorithm
+ TPM2B_NONCE *nonceCaller, // IN: initial nonceCaller
+ TPMT_SYM_DEF *symmetric, // IN: the symmetric algorithm
+ TPMI_DH_ENTITY bind, // IN: the bind object
+ TPM2B_DATA *seed, // IN: seed data
+ TPM_HANDLE *sessionHandle, // OUT: the session handle
+ TPM2B_NONCE *nonceTpm // OUT: the session nonce
+ );
+TPM_RC
+SessionContextSave(
+ TPM_HANDLE handle, // IN: session handle
+ CONTEXT_COUNTER *contextID // OUT: assigned contextID
+ );
+TPM_RC
+SessionContextLoad(
+ SESSION_BUF *session, // IN: session structure from saved context
+ TPM_HANDLE *handle // IN/OUT: session handle
+ );
+void
+SessionFlush(
+ TPM_HANDLE handle // IN: loaded or saved session handle
+ );
+void
+SessionComputeBoundEntity(
+ TPMI_DH_ENTITY entityHandle, // IN: handle of entity
+ TPM2B_NAME *bind // OUT: binding value
+ );
+void
+SessionSetStartTime(
+ SESSION *session // IN: the session to update
+ );
+void
+SessionResetPolicyData(
+ SESSION *session // IN: the session to reset
+ );
+TPMI_YES_NO
+SessionCapGetLoaded(
+ TPMI_SH_POLICY handle, // IN: start handle
+ UINT32 count, // IN: count of returned handles
+ TPML_HANDLE *handleList // OUT: list of handle
+ );
+TPMI_YES_NO
+SessionCapGetSaved(
+ TPMI_SH_HMAC handle, // IN: start handle
+ UINT32 count, // IN: count of returned handles
+ TPML_HANDLE *handleList // OUT: list of handle
+ );
+UINT32
+SessionCapGetLoadedNumber(
+ void
+ );
+UINT32
+SessionCapGetLoadedAvail(
+ void
+ );
+UINT32
+SessionCapGetActiveNumber(
+ void
+ );
+UINT32
+SessionCapGetActiveAvail(
+ void
+ );
+
+
+#endif
diff --git a/src/tpm2/SetAlgorithmSet_fp.h b/src/tpm2/SetAlgorithmSet_fp.h
new file mode 100644
index 0000000..dab38ff
--- /dev/null
+++ b/src/tpm2/SetAlgorithmSet_fp.h
@@ -0,0 +1,81 @@
+/********************************************************************************/
+/* */
+/* */
+/* Written by Ken Goldman */
+/* IBM Thomas J. Watson Research Center */
+/* $Id: SetAlgorithmSet_fp.h 809 2016-11-16 18:31:54Z kgoldman $ */
+/* */
+/* Licenses and Notices */
+/* */
+/* 1. Copyright Licenses: */
+/* */
+/* - Trusted Computing Group (TCG) grants to the user of the source code in */
+/* this specification (the "Source Code") a worldwide, irrevocable, */
+/* nonexclusive, royalty free, copyright license to reproduce, create */
+/* derivative works, distribute, display and perform the Source Code and */
+/* derivative works thereof, and to grant others the rights granted herein. */
+/* */
+/* - The TCG grants to the user of the other parts of the specification */
+/* (other than the Source Code) the rights to reproduce, distribute, */
+/* display, and perform the specification solely for the purpose of */
+/* developing products based on such documents. */
+/* */
+/* 2. Source Code Distribution Conditions: */
+/* */
+/* - Redistributions of Source Code must retain the above copyright licenses, */
+/* this list of conditions and the following disclaimers. */
+/* */
+/* - Redistributions in binary form must reproduce the above copyright */
+/* licenses, this list of conditions and the following disclaimers in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* 3. Disclaimers: */
+/* */
+/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
+/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
+/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
+/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
+/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
+/* information on specification licensing rights available through TCG */
+/* membership agreements. */
+/* */
+/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
+/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
+/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
+/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
+/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
+/* */
+/* - Without limitation, TCG and its members and licensors disclaim all */
+/* liability, including liability for infringement of any proprietary */
+/* rights, relating to use of information in this specification and to the */
+/* implementation of this specification, and TCG disclaims all liability for */
+/* cost of procurement of substitute goods or services, lost profits, loss */
+/* of use, loss of data or any incidental, consequential, direct, indirect, */
+/* or special damages, whether under contract, tort, warranty or otherwise, */
+/* arising in any way out of use or reliance upon this specification or any */
+/* information herein. */
+/* */
+/* (c) Copyright IBM Corp. and others, 2012-2015 */
+/* */
+/********************************************************************************/
+
+/* rev 119 */
+
+#ifndef SETALGORITHMSET_FP_H
+#define SETALGORITHMSET_FP_H
+
+typedef struct {
+ TPMI_RH_PLATFORM authHandle;
+ UINT32 algorithmSet;
+} SetAlgorithmSet_In;
+
+#define RC_SetAlgorithmSet_authHandle (TPM_RC_H + TPM_RC_1)
+#define RC_SetAlgorithmSet_algorithmSet (TPM_RC_P + TPM_RC_1)
+
+TPM_RC
+TPM2_SetAlgorithmSet(
+ SetAlgorithmSet_In *in // IN: input parameter list
+ );
+
+
+#endif
diff --git a/src/tpm2/SetCommandCodeAuditStatus_fp.h b/src/tpm2/SetCommandCodeAuditStatus_fp.h
new file mode 100644
index 0000000..af6cfc3
--- /dev/null
+++ b/src/tpm2/SetCommandCodeAuditStatus_fp.h
@@ -0,0 +1,84 @@
+/********************************************************************************/
+/* */
+/* */
+/* Written by Ken Goldman */
+/* IBM Thomas J. Watson Research Center */
+/* $Id: SetCommandCodeAuditStatus_fp.h 809 2016-11-16 18:31:54Z kgoldman $ */
+/* */
+/* Licenses and Notices */
+/* */
+/* 1. Copyright Licenses: */
+/* */
+/* - Trusted Computing Group (TCG) grants to the user of the source code in */
+/* this specification (the "Source Code") a worldwide, irrevocable, */
+/* nonexclusive, royalty free, copyright license to reproduce, create */
+/* derivative works, distribute, display and perform the Source Code and */
+/* derivative works thereof, and to grant others the rights granted herein. */
+/* */
+/* - The TCG grants to the user of the other parts of the specification */
+/* (other than the Source Code) the rights to reproduce, distribute, */
+/* display, and perform the specification solely for the purpose of */
+/* developing products based on such documents. */
+/* */
+/* 2. Source Code Distribution Conditions: */
+/* */
+/* - Redistributions of Source Code must retain the above copyright licenses, */
+/* this list of conditions and the following disclaimers. */
+/* */
+/* - Redistributions in binary form must reproduce the above copyright */
+/* licenses, this list of conditions and the following disclaimers in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* 3. Disclaimers: */
+/* */
+/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
+/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
+/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
+/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
+/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
+/* information on specification licensing rights available through TCG */
+/* membership agreements. */
+/* */
+/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
+/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
+/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
+/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
+/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
+/* */
+/* - Without limitation, TCG and its members and licensors disclaim all */
+/* liability, including liability for infringement of any proprietary */
+/* rights, relating to use of information in this specification and to the */
+/* implementation of this specification, and TCG disclaims all liability for */
+/* cost of procurement of substitute goods or services, lost profits, loss */
+/* of use, loss of data or any incidental, consequential, direct, indirect, */
+/* or special damages, whether under contract, tort, warranty or otherwise, */
+/* arising in any way out of use or reliance upon this specification or any */
+/* information herein. */
+/* */
+/* (c) Copyright IBM Corp. and others, 2012-2015 */
+/* */
+/********************************************************************************/
+
+/* rev 119 */
+
+#ifndef SETCOMMANDCODEAUDITSTATUS_FP_H
+#define SETCOMMANDCODEAUDITSTATUS_FP_H
+
+typedef struct {
+ TPMI_RH_PROVISION auth;
+ TPMI_ALG_HASH auditAlg;
+ TPML_CC setList;
+ TPML_CC clearList;
+} SetCommandCodeAuditStatus_In;
+
+#define RC_SetCommandCodeAuditStatus_auth (TPM_RC_H + TPM_RC_1)
+#define RC_SetCommandCodeAuditStatus_auditAlg (TPM_RC_P + TPM_RC_1)
+#define RC_SetCommandCodeAuditStatus_setList (TPM_RC_P + TPM_RC_2)
+#define RC_SetCommandCodeAuditStatus_clearList (TPM_RC_P + TPM_RC_3)
+
+TPM_RC
+TPM2_SetCommandCodeAuditStatus(
+ SetCommandCodeAuditStatus_In *in // IN: input parameter list
+ );
+
+#endif
diff --git a/src/tpm2/SetPrimaryPolicy_fp.h b/src/tpm2/SetPrimaryPolicy_fp.h
new file mode 100644
index 0000000..3c4d374
--- /dev/null
+++ b/src/tpm2/SetPrimaryPolicy_fp.h
@@ -0,0 +1,80 @@
+/********************************************************************************/
+/* */
+/* TPM2_SetPrimaryPolicy Command Header */
+/* Written by Ken Goldman */
+/* IBM Thomas J. Watson Research Center */
+/* $Id: SetPrimaryPolicy_fp.h 1521 2019-11-15 21:00:47Z kgoldman $ */
+/* */
+/* Licenses and Notices */
+/* */
+/* 1. Copyright Licenses: */
+/* */
+/* - Trusted Computing Group (TCG) grants to the user of the source code in */
+/* this specification (the "Source Code") a worldwide, irrevocable, */
+/* nonexclusive, royalty free, copyright license to reproduce, create */
+/* derivative works, distribute, display and perform the Source Code and */
+/* derivative works thereof, and to grant others the rights granted herein. */
+/* */
+/* - The TCG grants to the user of the other parts of the specification */
+/* (other than the Source Code) the rights to reproduce, distribute, */
+/* display, and perform the specification solely for the purpose of */
+/* developing products based on such documents. */
+/* */
+/* 2. Source Code Distribution Conditions: */
+/* */
+/* - Redistributions of Source Code must retain the above copyright licenses, */
+/* this list of conditions and the following disclaimers. */
+/* */
+/* - Redistributions in binary form must reproduce the above copyright */
+/* licenses, this list of conditions and the following disclaimers in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* 3. Disclaimers: */
+/* */
+/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
+/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
+/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
+/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
+/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
+/* information on specification licensing rights available through TCG */
+/* membership agreements. */
+/* */
+/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
+/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
+/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
+/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
+/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
+/* */
+/* - Without limitation, TCG and its members and licensors disclaim all */
+/* liability, including liability for infringement of any proprietary */
+/* rights, relating to use of information in this specification and to the */
+/* implementation of this specification, and TCG disclaims all liability for */
+/* cost of procurement of substitute goods or services, lost profits, loss */
+/* of use, loss of data or any incidental, consequential, direct, indirect, */
+/* or special damages, whether under contract, tort, warranty or otherwise, */
+/* arising in any way out of use or reliance upon this specification or any */
+/* information herein. */
+/* */
+/* (c) Copyright IBM Corp. and others, 2012 - 2019 */
+/* */
+/********************************************************************************/
+
+#ifndef SETPRIMARYPOLICY_FP_H
+#define SETPRIMARYPOLICY_FP_H
+
+typedef struct {
+ TPMI_RH_HIERARCHY_POLICY authHandle;
+ TPM2B_DIGEST authPolicy;
+ TPMI_ALG_HASH hashAlg;
+} SetPrimaryPolicy_In;
+
+#define RC_SetPrimaryPolicy_authHandle (TPM_RC_H + TPM_RC_1)
+#define RC_SetPrimaryPolicy_authPolicy (TPM_RC_P + TPM_RC_1)
+#define RC_SetPrimaryPolicy_hashAlg (TPM_RC_P + TPM_RC_2)
+
+TPM_RC
+TPM2_SetPrimaryPolicy(
+ SetPrimaryPolicy_In *in // IN: input parameter list
+ );
+
+#endif
diff --git a/src/tpm2/Shutdown_fp.h b/src/tpm2/Shutdown_fp.h
new file mode 100644
index 0000000..ceb6a8e
--- /dev/null
+++ b/src/tpm2/Shutdown_fp.h
@@ -0,0 +1,79 @@
+/********************************************************************************/
+/* */
+/* */
+/* Written by Ken Goldman */
+/* IBM Thomas J. Watson Research Center */
+/* $Id: Shutdown_fp.h 809 2016-11-16 18:31:54Z kgoldman $ */
+/* */
+/* Licenses and Notices */
+/* */
+/* 1. Copyright Licenses: */
+/* */
+/* - Trusted Computing Group (TCG) grants to the user of the source code in */
+/* this specification (the "Source Code") a worldwide, irrevocable, */
+/* nonexclusive, royalty free, copyright license to reproduce, create */
+/* derivative works, distribute, display and perform the Source Code and */
+/* derivative works thereof, and to grant others the rights granted herein. */
+/* */
+/* - The TCG grants to the user of the other parts of the specification */
+/* (other than the Source Code) the rights to reproduce, distribute, */
+/* display, and perform the specification solely for the purpose of */
+/* developing products based on such documents. */
+/* */
+/* 2. Source Code Distribution Conditions: */
+/* */
+/* - Redistributions of Source Code must retain the above copyright licenses, */
+/* this list of conditions and the following disclaimers. */
+/* */
+/* - Redistributions in binary form must reproduce the above copyright */
+/* licenses, this list of conditions and the following disclaimers in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* 3. Disclaimers: */
+/* */
+/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
+/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
+/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
+/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
+/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
+/* information on specification licensing rights available through TCG */
+/* membership agreements. */
+/* */
+/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
+/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
+/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
+/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
+/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
+/* */
+/* - Without limitation, TCG and its members and licensors disclaim all */
+/* liability, including liability for infringement of any proprietary */
+/* rights, relating to use of information in this specification and to the */
+/* implementation of this specification, and TCG disclaims all liability for */
+/* cost of procurement of substitute goods or services, lost profits, loss */
+/* of use, loss of data or any incidental, consequential, direct, indirect, */
+/* or special damages, whether under contract, tort, warranty or otherwise, */
+/* arising in any way out of use or reliance upon this specification or any */
+/* information herein. */
+/* */
+/* (c) Copyright IBM Corp. and others, 2012-2015 */
+/* */
+/********************************************************************************/
+
+/* rev 119 */
+
+#ifndef SHUTDOWN_FP_H
+#define SHUTDOWN_FP_H
+
+typedef struct{
+ TPM_SU shutdownType;
+} Shutdown_In;
+
+#define RC_Shutdown_shutdownType (TPM_RC_P + TPM_RC_1)
+
+TPM_RC
+TPM2_Shutdown(
+ Shutdown_In *in // IN: input parameter list
+ );
+
+
+#endif
diff --git a/src/tpm2/Sign_fp.h b/src/tpm2/Sign_fp.h
new file mode 100644
index 0000000..16a8ba7
--- /dev/null
+++ b/src/tpm2/Sign_fp.h
@@ -0,0 +1,89 @@
+/********************************************************************************/
+/* */
+/* */
+/* Written by Ken Goldman */
+/* IBM Thomas J. Watson Research Center */
+/* $Id: Sign_fp.h 1521 2019-11-15 21:00:47Z kgoldman $ */
+/* */
+/* Licenses and Notices */
+/* */
+/* 1. Copyright Licenses: */
+/* */
+/* - Trusted Computing Group (TCG) grants to the user of the source code in */
+/* this specification (the "Source Code") a worldwide, irrevocable, */
+/* nonexclusive, royalty free, copyright license to reproduce, create */
+/* derivative works, distribute, display and perform the Source Code and */
+/* derivative works thereof, and to grant others the rights granted herein. */
+/* */
+/* - The TCG grants to the user of the other parts of the specification */
+/* (other than the Source Code) the rights to reproduce, distribute, */
+/* display, and perform the specification solely for the purpose of */
+/* developing products based on such documents. */
+/* */
+/* 2. Source Code Distribution Conditions: */
+/* */
+/* - Redistributions of Source Code must retain the above copyright licenses, */
+/* this list of conditions and the following disclaimers. */
+/* */
+/* - Redistributions in binary form must reproduce the above copyright */
+/* licenses, this list of conditions and the following disclaimers in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* 3. Disclaimers: */
+/* */
+/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
+/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
+/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
+/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
+/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
+/* information on specification licensing rights available through TCG */
+/* membership agreements. */
+/* */
+/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
+/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
+/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
+/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
+/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
+/* */
+/* - Without limitation, TCG and its members and licensors disclaim all */
+/* liability, including liability for infringement of any proprietary */
+/* rights, relating to use of information in this specification and to the */
+/* implementation of this specification, and TCG disclaims all liability for */
+/* cost of procurement of substitute goods or services, lost profits, loss */
+/* of use, loss of data or any incidental, consequential, direct, indirect, */
+/* or special damages, whether under contract, tort, warranty or otherwise, */
+/* arising in any way out of use or reliance upon this specification or any */
+/* information herein. */
+/* */
+/* (c) Copyright IBM Corp. and others, 2012-2015 */
+/* */
+/********************************************************************************/
+
+/* rev 119 */
+
+#ifndef SIGN_FP_H
+#define SIGN_FP_H
+
+typedef struct {
+ TPMI_DH_OBJECT keyHandle;
+ TPM2B_DIGEST digest;
+ TPMT_SIG_SCHEME inScheme;
+ TPMT_TK_HASHCHECK validation;
+} Sign_In;
+
+#define RC_Sign_keyHandle (TPM_RC_H + TPM_RC_1)
+#define RC_Sign_digest (TPM_RC_P + TPM_RC_1)
+#define RC_Sign_inScheme (TPM_RC_P + TPM_RC_2)
+#define RC_Sign_validation (TPM_RC_P + TPM_RC_3)
+
+typedef struct {
+ TPMT_SIGNATURE signature;
+} Sign_Out;
+
+TPM_RC
+TPM2_Sign(
+ Sign_In *in, // IN: input parameter list
+ Sign_Out *out // OUT: output parameter list
+ );
+
+#endif
diff --git a/src/tpm2/SigningCommands.c b/src/tpm2/SigningCommands.c
new file mode 100644
index 0000000..529c40c
--- /dev/null
+++ b/src/tpm2/SigningCommands.c
@@ -0,0 +1,156 @@
+/********************************************************************************/
+/* */
+/* Signing and Signature Verification */
+/* Written by Ken Goldman */
+/* IBM Thomas J. Watson Research Center */
+/* $Id: SigningCommands.c 1658 2021-01-22 23:14:01Z kgoldman $ */
+/* */
+/* Licenses and Notices */
+/* */
+/* 1. Copyright Licenses: */
+/* */
+/* - Trusted Computing Group (TCG) grants to the user of the source code in */
+/* this specification (the "Source Code") a worldwide, irrevocable, */
+/* nonexclusive, royalty free, copyright license to reproduce, create */
+/* derivative works, distribute, display and perform the Source Code and */
+/* derivative works thereof, and to grant others the rights granted herein. */
+/* */
+/* - The TCG grants to the user of the other parts of the specification */
+/* (other than the Source Code) the rights to reproduce, distribute, */
+/* display, and perform the specification solely for the purpose of */
+/* developing products based on such documents. */
+/* */
+/* 2. Source Code Distribution Conditions: */
+/* */
+/* - Redistributions of Source Code must retain the above copyright licenses, */
+/* this list of conditions and the following disclaimers. */
+/* */
+/* - Redistributions in binary form must reproduce the above copyright */
+/* licenses, this list of conditions and the following disclaimers in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* 3. Disclaimers: */
+/* */
+/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
+/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
+/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
+/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
+/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
+/* information on specification licensing rights available through TCG */
+/* membership agreements. */
+/* */
+/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
+/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
+/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
+/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
+/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
+/* */
+/* - Without limitation, TCG and its members and licensors disclaim all */
+/* liability, including liability for infringement of any proprietary */
+/* rights, relating to use of information in this specification and to the */
+/* implementation of this specification, and TCG disclaims all liability for */
+/* cost of procurement of substitute goods or services, lost profits, loss */
+/* of use, loss of data or any incidental, consequential, direct, indirect, */
+/* or special damages, whether under contract, tort, warranty or otherwise, */
+/* arising in any way out of use or reliance upon this specification or any */
+/* information herein. */
+/* */
+/* (c) Copyright IBM Corp. and others, 2016 - 2021 */
+/* */
+/********************************************************************************/
+
+#include "Tpm.h"
+#include "VerifySignature_fp.h"
+#if CC_VerifySignature // Conditional expansion of this file
+TPM_RC
+TPM2_VerifySignature(
+ VerifySignature_In *in, // IN: input parameter list
+ VerifySignature_Out *out // OUT: output parameter list
+ )
+{
+ TPM_RC result;
+ OBJECT *signObject = HandleToObject(in->keyHandle);
+ TPMI_RH_HIERARCHY hierarchy;
+ // Input Validation
+ // The object to validate the signature must be a signing key.
+ if(!IS_ATTRIBUTE(signObject->publicArea.objectAttributes, TPMA_OBJECT, sign))
+ return TPM_RCS_ATTRIBUTES + RC_VerifySignature_keyHandle;
+ // Validate Signature. TPM_RC_SCHEME, TPM_RC_HANDLE or TPM_RC_SIGNATURE
+ // error may be returned by CryptCVerifySignatrue()
+ result = CryptValidateSignature(in->keyHandle, &in->digest, &in->signature);
+ if(result != TPM_RC_SUCCESS)
+ return RcSafeAddToResult(result, RC_VerifySignature_signature);
+ // Command Output
+ hierarchy = GetHieriarchy(in->keyHandle);
+ if(hierarchy == TPM_RH_NULL
+ || signObject->publicArea.nameAlg == TPM_ALG_NULL)
+ {
+ // produce empty ticket if hierarchy is TPM_RH_NULL or nameAlg is
+ // TPM_ALG_NULL
+ out->validation.tag = TPM_ST_VERIFIED;
+ out->validation.hierarchy = TPM_RH_NULL;
+ out->validation.digest.t.size = 0;
+ }
+ else
+ {
+ // Compute ticket
+ TicketComputeVerified(hierarchy, &in->digest, &signObject->name,
+ &out->validation);
+ }
+ return TPM_RC_SUCCESS;
+}
+#endif // CC_VerifySignature
+#include "Tpm.h"
+#include "Sign_fp.h"
+#if CC_Sign // Conditional expansion of this file
+#include "Attest_spt_fp.h"
+TPM_RC
+TPM2_Sign(
+ Sign_In *in, // IN: input parameter list
+ Sign_Out *out // OUT: output parameter list
+ )
+{
+ TPM_RC result;
+ TPMT_TK_HASHCHECK ticket;
+ OBJECT *signObject = HandleToObject(in->keyHandle);
+ //
+ // Input Validation
+ if(!IsSigningObject(signObject))
+ return TPM_RCS_KEY + RC_Sign_keyHandle;
+
+ // A key that will be used for x.509 signatures can't be used in TPM2_Sign().
+ if(IS_ATTRIBUTE(signObject->publicArea.objectAttributes, TPMA_OBJECT, x509sign))
+ return TPM_RCS_ATTRIBUTES + RC_Sign_keyHandle;
+
+ // pick a scheme for sign. If the input sign scheme is not compatible with
+ // the default scheme, return an error.
+ if(!CryptSelectSignScheme(signObject, &in->inScheme))
+ return TPM_RCS_SCHEME + RC_Sign_inScheme;
+ // If validation is provided, or the key is restricted, check the ticket
+ if(in->validation.digest.t.size != 0
+ || IS_ATTRIBUTE(signObject->publicArea.objectAttributes, TPMA_OBJECT, restricted))
+ {
+ // Compute and compare ticket
+ TicketComputeHashCheck(in->validation.hierarchy,
+ in->inScheme.details.any.hashAlg,
+ &in->digest, &ticket);
+ if(!MemoryEqual2B(&in->validation.digest.b, &ticket.digest.b))
+ return TPM_RCS_TICKET + RC_Sign_validation;
+ }
+ else
+ // If we don't have a ticket, at least verify that the provided 'digest'
+ // is the size of the scheme hashAlg digest.
+ // NOTE: this does not guarantee that the 'digest' is actually produced using
+ // the indicated hash algorithm, but at least it might be.
+ {
+ if(in->digest.t.size
+ != CryptHashGetDigestSize(in->inScheme.details.any.hashAlg))
+ return TPM_RCS_SIZE + RC_Sign_digest;
+ }
+ // Command Output
+ // Sign the hash. A TPM_RC_VALUE or TPM_RC_SCHEME
+ // error may be returned at this point
+ result = CryptSign(signObject, &in->inScheme, &in->digest, &out->signature);
+ return result;
+}
+#endif // CC_Sign
diff --git a/src/tpm2/Simulator_fp.h b/src/tpm2/Simulator_fp.h
new file mode 100644
index 0000000..aedcc91
--- /dev/null
+++ b/src/tpm2/Simulator_fp.h
@@ -0,0 +1,212 @@
+/********************************************************************************/
+/* */
+/* */
+/* Written by Ken Goldman */
+/* IBM Thomas J. Watson Research Center */
+/* $Id: Simulator_fp.h 1658 2021-01-22 23:14:01Z kgoldman $ */
+/* */
+/* Licenses and Notices */
+/* */
+/* 1. Copyright Licenses: */
+/* */
+/* - Trusted Computing Group (TCG) grants to the user of the source code in */
+/* this specification (the "Source Code") a worldwide, irrevocable, */
+/* nonexclusive, royalty free, copyright license to reproduce, create */
+/* derivative works, distribute, display and perform the Source Code and */
+/* derivative works thereof, and to grant others the rights granted herein. */
+/* */
+/* - The TCG grants to the user of the other parts of the specification */
+/* (other than the Source Code) the rights to reproduce, distribute, */
+/* display, and perform the specification solely for the purpose of */
+/* developing products based on such documents. */
+/* */
+/* 2. Source Code Distribution Conditions: */
+/* */
+/* - Redistributions of Source Code must retain the above copyright licenses, */
+/* this list of conditions and the following disclaimers. */
+/* */
+/* - Redistributions in binary form must reproduce the above copyright */
+/* licenses, this list of conditions and the following disclaimers in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* 3. Disclaimers: */
+/* */
+/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
+/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
+/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
+/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
+/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
+/* information on specification licensing rights available through TCG */
+/* membership agreements. */
+/* */
+/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
+/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
+/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
+/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
+/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
+/* */
+/* - Without limitation, TCG and its members and licensors disclaim all */
+/* liability, including liability for infringement of any proprietary */
+/* rights, relating to use of information in this specification and to the */
+/* implementation of this specification, and TCG disclaims all liability for */
+/* cost of procurement of substitute goods or services, lost profits, loss */
+/* of use, loss of data or any incidental, consequential, direct, indirect, */
+/* or special damages, whether under contract, tort, warranty or otherwise, */
+/* arising in any way out of use or reliance upon this specification or any */
+/* information herein. */
+/* */
+/* (c) Copyright IBM Corp. and others, 2016 - 2021 */
+/* */
+/********************************************************************************/
+
+/* D.2 Simulator_fp.h */
+#ifndef _SIMULATOR_FP_H_
+#define _SIMULATOR_FP_H_
+
+#include <stdbool.h>
+
+#ifdef TPM_WINDOWS
+#include <windows.h>
+#include <winsock.h>
+#endif
+
+#ifdef TPM_POSIX
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <pthread.h>
+#endif
+
+/* D.2.1. From TcpServer.c */
+/* D.2.1.1. PlatformServer() */
+/* Moved to TpmServer_fp.h because it's different for Windows and Unix */
+
+/* D.2.2. From TPMCmdp.c */
+/* D.2.2.1. Signal_PowerOn() */
+/* This function processes a power-on indication. Among other things, it calls the _TPM_Init()
+ handler. */
+void
+_rpc__Signal_PowerOn(
+ bool isReset
+ );
+/* D.2.2.2. Signal_Restart() */
+/* This function processes the clock restart indication. All it does is call the platform
+ function. */
+void
+_rpc__Signal_Restart(
+ void
+ );
+/* D.2.2.3. Signal_PowerOff() */
+/* This function processes the power off indication. Its primary function is to set a flag
+ indicating that the next power on indication should cause _TPM_Init() to be called. */
+void
+_rpc__Signal_PowerOff(
+ void
+ );
+#if 0 /* libtpms added */
+/* D.2.2.4. _rpc__ForceFailureMode() */
+/* This function is used to debug the Failure Mode logic of the TPM. It will set a flag in the TPM
+ code such that the next call to TPM2_SelfTest() will result in a failure, putting the TPM into
+ Failure Mode. */
+void
+_rpc__ForceFailureMode(
+ void
+ );
+/* D.2.2.5. _rpc__Signal_PhysicalPresenceOn() */
+/* This function is called to simulate activation of the physical presence pin. */
+void
+_rpc__Signal_PhysicalPresenceOn(
+ void
+ );
+/* D.2.2.6. _rpc__Signal_PhysicalPresenceOff() */
+/* This function is called to simulate deactivation of the physical presence pin. */
+void
+_rpc__Signal_PhysicalPresenceOff(
+ void
+ );
+/* D.2.2.7. _rpc__Signal_Hash_Start() */
+/* This function is called to simulate a _TPM_Hash_Start() event. It will call */
+void
+_rpc__Signal_Hash_Start(
+ void
+ );
+/* D.2.2.8. _rpc__Signal_Hash_Data() */
+/* This function is called to simulate a _TPM_Hash_Data() event. */
+void
+_rpc__Signal_Hash_Data(
+ _IN_BUFFER input
+ );
+/* D.2.2.9. _rpc__Signal_HashEnd() */
+/* This function is called to simulate a _TPM_Hash_End() event. */
+void
+_rpc__Signal_HashEnd(
+ void
+ );
+#endif /* libtpms added */
+/* rpc__Send_Command() This is the interface to the TPM code. */
+void
+_rpc__Send_Command(
+ unsigned char locality,
+ _IN_BUFFER request,
+ _OUT_BUFFER *response
+ );
+
+/* D.2.2.10. _rpc__Signal_CancelOn() */
+/* This function is used to turn on the indication to cancel a command in process. An executing
+ command is not interrupted. The command code may periodically check this indication to see if it
+ should abort the current command processing and returned TPM_RC_CANCELLED. */
+void
+_rpc__Signal_CancelOn(
+ void
+ );
+/* D.2.2.11. _rpc__Signal_CancelOff() */
+/* This function is used to turn off the indication to cancel a command in process. */
+void
+_rpc__Signal_CancelOff(
+ void
+ );
+/* D.2.2.12. _rpc__Signal_NvOn() */
+/* In a system where the NV memory used by the TPM is not within the TPM, the NV may not always be
+ available. This function turns on the indicator that indicates that NV is available. */
+void
+_rpc__Signal_NvOn(
+ void
+ );
+#if 0 /* libtpms added */
+/* D.2.2.13. _rpc__Signal_NvOff() */
+/* This function is used to set the indication that NV memory is no longer available. */
+void
+_rpc__Signal_NvOff(
+ void
+ );
+/* D.2.2.14. _rpc__RsaKeyCacheControl() */
+/* This function is used to enable/disable the use of the RSA key cache during simulation. */
+void
+_rpc__RsaKeyCacheControl(
+ int state
+ );
+/* D.4.2.15. _rpc__ACT_GetSignaled() */
+bool
+_rpc__ACT_GetSignaled(
+ uint32_t actHandle
+ );
+
+/* D.2.3. From TPMCmds.c */
+/* D.2.3.1. main() */
+/* This is the main entry point for the simulator. */
+int
+main(
+ int argc,
+ char *argv[]
+ );
+#endif /* libtpms added */
+/* libtpms added begin */
+void _rpc__Signal_SetTPMEstablished(void);
+bool _rpc__Signal_GetTPMEstablished(void);
+void _rpc__Signal_ResetTPMEstablished(void);
+bool _rpc__Signal_IsPowerOn(void);
+/* libtpms added end */
+
+#endif // _SIMULATOR_FP_H_
+
diff --git a/src/tpm2/StartAuthSession_fp.h b/src/tpm2/StartAuthSession_fp.h
new file mode 100644
index 0000000..c284864
--- /dev/null
+++ b/src/tpm2/StartAuthSession_fp.h
@@ -0,0 +1,97 @@
+/********************************************************************************/
+/* */
+/* */
+/* Written by Ken Goldman */
+/* IBM Thomas J. Watson Research Center */
+/* $Id: StartAuthSession_fp.h 809 2016-11-16 18:31:54Z kgoldman $ */
+/* */
+/* Licenses and Notices */
+/* */
+/* 1. Copyright Licenses: */
+/* */
+/* - Trusted Computing Group (TCG) grants to the user of the source code in */
+/* this specification (the "Source Code") a worldwide, irrevocable, */
+/* nonexclusive, royalty free, copyright license to reproduce, create */
+/* derivative works, distribute, display and perform the Source Code and */
+/* derivative works thereof, and to grant others the rights granted herein. */
+/* */
+/* - The TCG grants to the user of the other parts of the specification */
+/* (other than the Source Code) the rights to reproduce, distribute, */
+/* display, and perform the specification solely for the purpose of */
+/* developing products based on such documents. */
+/* */
+/* 2. Source Code Distribution Conditions: */
+/* */
+/* - Redistributions of Source Code must retain the above copyright licenses, */
+/* this list of conditions and the following disclaimers. */
+/* */
+/* - Redistributions in binary form must reproduce the above copyright */
+/* licenses, this list of conditions and the following disclaimers in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* 3. Disclaimers: */
+/* */
+/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
+/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
+/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
+/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
+/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
+/* information on specification licensing rights available through TCG */
+/* membership agreements. */
+/* */
+/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
+/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
+/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
+/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
+/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
+/* */
+/* - Without limitation, TCG and its members and licensors disclaim all */
+/* liability, including liability for infringement of any proprietary */
+/* rights, relating to use of information in this specification and to the */
+/* implementation of this specification, and TCG disclaims all liability for */
+/* cost of procurement of substitute goods or services, lost profits, loss */
+/* of use, loss of data or any incidental, consequential, direct, indirect, */
+/* or special damages, whether under contract, tort, warranty or otherwise, */
+/* arising in any way out of use or reliance upon this specification or any */
+/* information herein. */
+/* */
+/* (c) Copyright IBM Corp. and others, 2012-2015 */
+/* */
+/********************************************************************************/
+
+/* rev 119 */
+
+#ifndef STARTAUTHSESSION_FP_H
+#define STARTAUTHSESSION_FP_H
+
+typedef struct {
+ TPMI_DH_OBJECT tpmKey;
+ TPMI_DH_ENTITY bind;
+ TPM2B_NONCE nonceCaller;
+ TPM2B_ENCRYPTED_SECRET encryptedSalt;
+ TPM_SE sessionType;
+ TPMT_SYM_DEF symmetric;
+ TPMI_ALG_HASH authHash;
+} StartAuthSession_In;
+
+typedef struct {
+ TPMI_SH_AUTH_SESSION sessionHandle;
+ TPM2B_NONCE nonceTPM;
+} StartAuthSession_Out;
+
+#define RC_StartAuthSession_tpmKey (TPM_RC_H + TPM_RC_1)
+#define RC_StartAuthSession_bind (TPM_RC_H + TPM_RC_2)
+#define RC_StartAuthSession_nonceCaller (TPM_RC_P + TPM_RC_1)
+#define RC_StartAuthSession_encryptedSalt (TPM_RC_P + TPM_RC_2)
+#define RC_StartAuthSession_sessionType (TPM_RC_P + TPM_RC_3)
+#define RC_StartAuthSession_symmetric (TPM_RC_P + TPM_RC_4)
+#define RC_StartAuthSession_authHash (TPM_RC_P + TPM_RC_5)
+
+TPM_RC
+TPM2_StartAuthSession(
+ StartAuthSession_In *in, // IN: input parameter buffer
+ StartAuthSession_Out *out // OUT: output parameter buffer
+ );
+
+
+#endif
diff --git a/src/tpm2/StartupCommands.c b/src/tpm2/StartupCommands.c
new file mode 100644
index 0000000..1212b46
--- /dev/null
+++ b/src/tpm2/StartupCommands.c
@@ -0,0 +1,349 @@
+/********************************************************************************/
+/* */
+/* Startup Commands */
+/* Written by Ken Goldman */
+/* IBM Thomas J. Watson Research Center */
+/* $Id: StartupCommands.c 1594 2020-03-26 22:15:48Z kgoldman $ */
+/* */
+/* Licenses and Notices */
+/* */
+/* 1. Copyright Licenses: */
+/* */
+/* - Trusted Computing Group (TCG) grants to the user of the source code in */
+/* this specification (the "Source Code") a worldwide, irrevocable, */
+/* nonexclusive, royalty free, copyright license to reproduce, create */
+/* derivative works, distribute, display and perform the Source Code and */
+/* derivative works thereof, and to grant others the rights granted herein. */
+/* */
+/* - The TCG grants to the user of the other parts of the specification */
+/* (other than the Source Code) the rights to reproduce, distribute, */
+/* display, and perform the specification solely for the purpose of */
+/* developing products based on such documents. */
+/* */
+/* 2. Source Code Distribution Conditions: */
+/* */
+/* - Redistributions of Source Code must retain the above copyright licenses, */
+/* this list of conditions and the following disclaimers. */
+/* */
+/* - Redistributions in binary form must reproduce the above copyright */
+/* licenses, this list of conditions and the following disclaimers in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* 3. Disclaimers: */
+/* */
+/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
+/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
+/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
+/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
+/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
+/* information on specification licensing rights available through TCG */
+/* membership agreements. */
+/* */
+/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
+/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
+/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
+/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
+/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
+/* */
+/* - Without limitation, TCG and its members and licensors disclaim all */
+/* liability, including liability for infringement of any proprietary */
+/* rights, relating to use of information in this specification and to the */
+/* implementation of this specification, and TCG disclaims all liability for */
+/* cost of procurement of substitute goods or services, lost profits, loss */
+/* of use, loss of data or any incidental, consequential, direct, indirect, */
+/* or special damages, whether under contract, tort, warranty or otherwise, */
+/* arising in any way out of use or reliance upon this specification or any */
+/* information herein. */
+/* */
+/* (c) Copyright IBM Corp. and others, 2016 - 2020 */
+/* */
+/********************************************************************************/
+
+/* 9.2 _TPM_Init */
+#include "Tpm.h"
+#include "PlatformACT_fp.h" /* added kgold */
+#include "_TPM_Init_fp.h"
+#include "StateMarshal.h" /* libtpms added */
+// This function is used to process a _TPM_Init indication.
+LIB_EXPORT void
+_TPM_Init(
+ void
+ )
+{
+ BOOL restored = FALSE; /* libtpms added */
+
+ g_powerWasLost = g_powerWasLost | _plat__WasPowerLost();
+#if SIMULATION && !defined NDEBUG /* libtpms changed */
+ // If power was lost and this was a simulation, put canary in RAM used by NV
+ // so that uninitialized memory can be detected more easily
+ if(g_powerWasLost)
+ {
+ memset(&gc, 0xbb, sizeof(gc));
+ memset(&gr, 0xbb, sizeof(gr));
+ memset(&gp, 0xbb, sizeof(gp));
+ memset(&go, 0xbb, sizeof(go));
+ }
+#endif
+#if SIMULATION
+ // Clear the flag that forces failure on self-test
+ g_forceFailureMode = FALSE;
+#endif
+ // Disable the tick processing
+ _plat__ACT_EnableTicks(FALSE);
+ // Set initialization state
+ TPMInit();
+ // Set g_DRTMHandle as unassigned
+ g_DRTMHandle = TPM_RH_UNASSIGNED;
+ // No H-CRTM, yet.
+ g_DrtmPreStartup = FALSE;
+ // Initialize the NvEnvironment.
+ g_nvOk = NvPowerOn();
+ // Initialize cryptographic functions
+ g_inFailureMode |= (CryptInit() == FALSE); /* libtpms changed */
+ if(!g_inFailureMode)
+ {
+ // Load the persistent data
+ NvReadPersistent();
+ // Load the orderly data (clock and DRBG state).
+ // If this is not done here, things break
+ NvRead(&go, NV_ORDERLY_DATA, sizeof(go));
+ // Start clock. Need to do this after NV has been restored.
+ TimePowerOn();
+
+ /* libtpms added begin */
+ VolatileLoad(&restored);
+ if (restored)
+ NVShadowRestore();
+ /* libtpms added end */
+ }
+ return;
+}
+#include "Tpm.h"
+#include "Startup_fp.h"
+#if CC_Startup // Conditional expansion of this file
+TPM_RC
+TPM2_Startup(
+ Startup_In *in // IN: input parameter list
+ )
+{
+ STARTUP_TYPE startup;
+ BYTE locality = _plat__LocalityGet();
+ BOOL OK = TRUE; // The command needs NV update.
+ RETURN_IF_NV_IS_NOT_AVAILABLE;
+ // Get the flags for the current startup locality and the H-CRTM.
+ // Rather than generalizing the locality setting, this code takes advantage
+ // of the fact that the PC Client specification only allows Startup()
+ // from locality 0 and 3. To generalize this probably would require a
+ // redo of the NV space and since this is a feature that is hardly ever used
+ // outside of the PC Client, this code just support the PC Client needs.
+ // Input Validation
+ // Check that the locality is a supported value
+ if(locality != 0 && locality != 3)
+ return TPM_RC_LOCALITY;
+ // If there was a H-CRTM, then treat the locality as being 3
+ // regardless of what the Startup() was. This is done to preserve the
+ // H-CRTM PCR so that they don't get overwritten with the normal
+ // PCR startup initialization. This basically means that g_StartupLocality3
+ // and g_DrtmPreStartup can't both be SET at the same time.
+ if(g_DrtmPreStartup)
+ locality = 0;
+ g_StartupLocality3 = (locality == 3);
+#if USE_DA_USED
+ // If there was no orderly shutdown, then there might have been a write to
+ // failedTries that didn't get recorded but only if g_daUsed was SET in the
+ // shutdown state
+ g_daUsed = (gp.orderlyState == SU_DA_USED_VALUE);
+ if(g_daUsed)
+ gp.orderlyState = SU_NONE_VALUE;
+#endif
+ g_prevOrderlyState = gp.orderlyState;
+ // If there was a proper shutdown, then the startup modifiers are in the
+ // orderlyState. Turn them off in the copy.
+ if(IS_ORDERLY(g_prevOrderlyState))
+ g_prevOrderlyState &= ~(PRE_STARTUP_FLAG | STARTUP_LOCALITY_3);
+ // If this is a Resume,
+ if(in->startupType == TPM_SU_STATE)
+ {
+ // then there must have been a prior TPM2_ShutdownState(STATE)
+ if(g_prevOrderlyState != TPM_SU_STATE)
+ return TPM_RCS_VALUE + RC_Startup_startupType;
+ // and the part of NV used for state save must have been recovered
+ // correctly.
+ // NOTE: if this fails, then the caller will need to do Startup(CLEAR). The
+ // code for Startup(Clear) cannot fail if the NV can't be read correctly
+ // because that would prevent the TPM from ever getting unstuck.
+ if(g_nvOk == FALSE)
+ return TPM_RC_NV_UNINITIALIZED;
+ // For Resume, the H-CRTM has to be the same as the previous boot
+ if(g_DrtmPreStartup != ((gp.orderlyState & PRE_STARTUP_FLAG) != 0))
+ return TPM_RCS_VALUE + RC_Startup_startupType;
+ if(g_StartupLocality3 != ((gp.orderlyState & STARTUP_LOCALITY_3) != 0))
+ return TPM_RC_LOCALITY;
+ }
+ // Clean up the gp state
+ gp.orderlyState = g_prevOrderlyState;
+
+ // Internal Date Update
+ if((gp.orderlyState == TPM_SU_STATE) && (g_nvOk == TRUE))
+ {
+ // Always read the data that is only cleared on a Reset because this is not
+ // a reset
+ NvRead(&gr, NV_STATE_RESET_DATA, sizeof(gr));
+ if(in->startupType == TPM_SU_STATE)
+ {
+ // If this is a startup STATE (a Resume) need to read the data
+ // that is cleared on a startup CLEAR because this is not a Reset
+ // or Restart.
+ NvRead(&gc, NV_STATE_CLEAR_DATA, sizeof(gc));
+ startup = SU_RESUME;
+ }
+ else
+ startup = SU_RESTART;
+ }
+ else
+ // Will do a TPM reset if Shutdown(CLEAR) and Startup(CLEAR) or no shutdown
+ // or there was a failure reading the NV data.
+ startup = SU_RESET;
+ // Startup for cryptographic library. Don't do this until after the orderly
+ // state has been read in from NV.
+ OK = OK && CryptStartup(startup);
+ // When the cryptographic library has been started, indicate that a TPM2_Startup
+ // command has been received.
+ OK = OK && TPMRegisterStartup();
+ // Read the platform unique value that is used as VENDOR_PERMANENT
+ // authorization value
+ g_platformUniqueDetails.t.size
+ = (UINT16)_plat__GetUnique(1, sizeof(g_platformUniqueDetails.t.buffer),
+ g_platformUniqueDetails.t.buffer);
+ // Start up subsystems
+ // Start set the safe flag
+ OK = OK && TimeStartup(startup);
+ // Start dictionary attack subsystem
+ OK = OK && DAStartup(startup);
+ // Enable hierarchies
+ OK = OK && HierarchyStartup(startup);
+ // Restore/Initialize PCR
+ OK = OK && PCRStartup(startup, locality);
+ // Restore/Initialize command audit information
+ OK = OK && CommandAuditStartup(startup);
+ // Restore the ACT
+ OK = OK && ActStartup(startup);
+ //// The following code was moved from Time.c where it made no sense
+ if (OK)
+ {
+ switch (startup)
+ {
+ case SU_RESUME:
+ // Resume sequence
+ gr.restartCount++;
+ break;
+ case SU_RESTART:
+ // Hibernate sequence
+ gr.clearCount++;
+ gr.restartCount++;
+ break;
+ default:
+ // Reset object context ID to 0
+ gr.objectContextID = 0;
+ // Reset clearCount to 0
+ gr.clearCount = 0;
+ // Reset sequence
+ // Increase resetCount
+ gp.resetCount++;
+ // Write resetCount to NV
+ NV_SYNC_PERSISTENT(resetCount);
+ gp.totalResetCount++;
+ // We do not expect the total reset counter overflow during the life
+ // time of TPM. if it ever happens, TPM will be put to failure mode
+ // and there is no way to recover it.
+ // The reason that there is no recovery is that we don't increment
+ // the NV totalResetCount when incrementing would make it 0. When the
+ // TPM starts up again, the old value of totalResetCount will be read
+ // and we will get right back to here with the increment failing.
+#if 0 // libtpms added
+ if(gp.totalResetCount == 0)
+ FAIL(FATAL_ERROR_INTERNAL);
+#endif // libtpms added
+ // Write total reset counter to NV
+ NV_SYNC_PERSISTENT(totalResetCount);
+ // Reset restartCount
+ gr.restartCount = 0;
+ break;
+ }
+ }
+ // Initialize session table
+ OK = OK && SessionStartup(startup);
+ // Initialize object table
+ OK = OK && ObjectStartup();
+ // Initialize index/evict data. This function clears read/write locks
+ // in NV index
+ OK = OK && NvEntityStartup(startup);
+ // Initialize the orderly shut down flag for this cycle to SU_NONE_VALUE.
+ gp.orderlyState = SU_NONE_VALUE;
+ OK = OK && NV_SYNC_PERSISTENT(orderlyState);
+ // This can be reset after the first completion of a TPM2_Startup() after
+ // a power loss. It can probably be reset earlier but this is an OK place.
+ if (OK)
+ g_powerWasLost = FALSE;
+ return (OK) ? TPM_RC_SUCCESS : TPM_RC_FAILURE;
+}
+#endif // CC_Startup
+#include "Tpm.h"
+#include "Shutdown_fp.h"
+#if CC_Shutdown // Conditional expansion of this file
+TPM_RC
+TPM2_Shutdown(
+ Shutdown_In *in // IN: input parameter list
+ )
+{
+ // The command needs NV update. Check if NV is available.
+ // A TPM_RC_NV_UNAVAILABLE or TPM_RC_NV_RATE error may be returned at
+ // this point
+ RETURN_IF_NV_IS_NOT_AVAILABLE;
+ // Input Validation
+ // If PCR bank has been reconfigured, a CLEAR state save is required
+ if(g_pcrReConfig && in->shutdownType == TPM_SU_STATE)
+ return TPM_RCS_TYPE + RC_Shutdown_shutdownType;
+ // Internal Data Update
+ gp.orderlyState = in->shutdownType;
+#if USE_DA_USED
+ // CLEAR g_daUsed so that any future DA-protected access will cause the
+ // shutdown to become non-orderly. It is not sufficient to invalidate the
+ // shutdown state after a DA failure because an attacker can inhibit access
+ // to NV and use the fact that an update of failedTries was attempted as an
+ // indication of an authorization failure. By making sure that the orderly state
+ // is CLEAR before any DA attempt, this prevents the possibility of this 'attack.'
+ g_daUsed = FALSE;
+#endif
+ // PCR private date state save
+ PCRStateSave(in->shutdownType);
+ // Save the ACT state
+ ActShutdown(in->shutdownType);
+ // Save RAM backed NV index data
+ NvUpdateIndexOrderlyData();
+#if ACCUMULATE_SELF_HEAL_TIMER
+ // Save the current time value
+ go.time = g_time;
+#endif
+ // Save all orderly data
+ NvWrite(NV_ORDERLY_DATA, sizeof(ORDERLY_DATA), &go);
+ if(in->shutdownType == TPM_SU_STATE)
+ {
+ // Save STATE_RESET and STATE_CLEAR data
+ NvWrite(NV_STATE_CLEAR_DATA, sizeof(STATE_CLEAR_DATA), &gc);
+ NvWrite(NV_STATE_RESET_DATA, sizeof(STATE_RESET_DATA), &gr);
+ // Save the startup flags for resume
+ if(g_DrtmPreStartup)
+ gp.orderlyState = TPM_SU_STATE | PRE_STARTUP_FLAG;
+ else if(g_StartupLocality3)
+ gp.orderlyState = TPM_SU_STATE | STARTUP_LOCALITY_3;
+ }
+ // only two shutdown options
+ else if(in->shutdownType != TPM_SU_CLEAR)
+ {
+ return TPM_RCS_VALUE + RC_Shutdown_shutdownType;
+ }
+ NV_SYNC_PERSISTENT(orderlyState);
+ return TPM_RC_SUCCESS;
+}
+#endif // CC_Shutdown
diff --git a/src/tpm2/Startup_fp.h b/src/tpm2/Startup_fp.h
new file mode 100644
index 0000000..1aaad54
--- /dev/null
+++ b/src/tpm2/Startup_fp.h
@@ -0,0 +1,84 @@
+/********************************************************************************/
+/* */
+/* */
+/* Written by Ken Goldman */
+/* IBM Thomas J. Watson Research Center */
+/* $Id: Startup_fp.h 1521 2019-11-15 21:00:47Z kgoldman $ */
+/* */
+/* Licenses and Notices */
+/* */
+/* 1. Copyright Licenses: */
+/* */
+/* - Trusted Computing Group (TCG) grants to the user of the source code in */
+/* this specification (the "Source Code") a worldwide, irrevocable, */
+/* nonexclusive, royalty free, copyright license to reproduce, create */
+/* derivative works, distribute, display and perform the Source Code and */
+/* derivative works thereof, and to grant others the rights granted herein. */
+/* */
+/* - The TCG grants to the user of the other parts of the specification */
+/* (other than the Source Code) the rights to reproduce, distribute, */
+/* display, and perform the specification solely for the purpose of */
+/* developing products based on such documents. */
+/* */
+/* 2. Source Code Distribution Conditions: */
+/* */
+/* - Redistributions of Source Code must retain the above copyright licenses, */
+/* this list of conditions and the following disclaimers. */
+/* */
+/* - Redistributions in binary form must reproduce the above copyright */
+/* licenses, this list of conditions and the following disclaimers in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* 3. Disclaimers: */
+/* */
+/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
+/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
+/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
+/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
+/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
+/* information on specification licensing rights available through TCG */
+/* membership agreements. */
+/* */
+/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
+/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
+/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
+/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
+/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
+/* */
+/* - Without limitation, TCG and its members and licensors disclaim all */
+/* liability, including liability for infringement of any proprietary */
+/* rights, relating to use of information in this specification and to the */
+/* implementation of this specification, and TCG disclaims all liability for */
+/* cost of procurement of substitute goods or services, lost profits, loss */
+/* of use, loss of data or any incidental, consequential, direct, indirect, */
+/* or special damages, whether under contract, tort, warranty or otherwise, */
+/* arising in any way out of use or reliance upon this specification or any */
+/* information herein. */
+/* */
+/* (c) Copyright IBM Corp. and others, 2012-2015 */
+/* */
+/********************************************************************************/
+
+/* rev 119 */
+
+#ifndef STARTUP_FP_H
+#define STARTUP_FP_H
+
+void
+_TPM_Init(
+ void
+ );
+
+
+typedef struct {
+ TPM_SU startupType;
+} Startup_In;
+
+#define RC_Startup_startupType (TPM_RC_P + TPM_RC_1)
+
+TPM_RC
+TPM2_Startup(
+ Startup_In *in // IN: input parameter list
+ );
+
+#endif
diff --git a/src/tpm2/StateMarshal.c b/src/tpm2/StateMarshal.c
new file mode 100644
index 0000000..fbb2662
--- /dev/null
+++ b/src/tpm2/StateMarshal.c
@@ -0,0 +1,98 @@
+/********************************************************************************/
+/* */
+/* Marshalling and unmarshalling of state */
+/* Written by Stefan Berger */
+/* IBM Thomas J. Watson Research Center */
+/* */
+/* (c) Copyright IBM Corporation 2017,2018. */
+/* */
+/* All rights reserved. */
+/* */
+/* Redistribution and use in source and binary forms, with or without */
+/* modification, are permitted provided that the following conditions are */
+/* met: */
+/* */
+/* Redistributions of source code must retain the above copyright notice, */
+/* this list of conditions and the following disclaimer. */
+/* */
+/* Redistributions in binary form must reproduce the above copyright */
+/* notice, this list of conditions and the following disclaimer in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* Neither the names of the IBM Corporation nor the names of its */
+/* contributors may be used to endorse or promote products derived from */
+/* this software without specific prior written permission. */
+/* */
+/* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS */
+/* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT */
+/* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR */
+/* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT */
+/* HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, */
+/* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT */
+/* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, */
+/* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY */
+/* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT */
+/* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE */
+/* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */
+/********************************************************************************/
+
+#include <stdlib.h>
+
+#include "config.h"
+
+#include "StateMarshal.h"
+#include "Volatile.h"
+
+#define TPM_HAVE_TPM2_DECLARATIONS
+#include "tpm_library_intern.h"
+#include "tpm_nvfilename.h"
+#include "tpm_error.h"
+#include "tpm_memory.h"
+
+UINT16
+VolatileSave(BYTE **buffer, INT32 *size)
+{
+ return VolatileState_Save(buffer, size);
+}
+
+TPM_RC
+VolatileLoad(BOOL *restored)
+{
+ TPM_RC rc = TPM_RC_SUCCESS;
+
+#ifdef TPM_LIBTPMS_CALLBACKS
+ unsigned char *data = NULL;
+ uint32_t length = 0;
+ struct libtpms_callbacks *cbs = TPMLIB_GetCallbacks();
+ TPM_RESULT ret = TPM_SUCCESS;
+ bool is_empty_state;
+
+ *restored = FALSE;
+
+ /* try to get state blob set via TPMLIB_SetState() */
+ GetCachedState(TPMLIB_STATE_VOLATILE, &data, &length, &is_empty_state);
+ if (is_empty_state)
+ return rc;
+
+ if (!data && cbs->tpm_nvram_loaddata) {
+ uint32_t tpm_number = 0;
+ const char *name = TPM_VOLATILESTATE_NAME;
+
+ ret = cbs->tpm_nvram_loaddata(&data, &length, tpm_number, name);
+ }
+
+ if (data && ret == TPM_SUCCESS) {
+ unsigned char *p = data;
+ rc = VolatileState_Load(&data, (INT32 *)&length);
+ /*
+ * if this failed, VolatileState_Load will have started
+ * failure mode.
+ */
+ free(p);
+
+ *restored = (rc == 0);
+ }
+#endif /* TPM_LIBTPMS_CALLBACKS */
+
+ return rc;
+}
diff --git a/src/tpm2/StateMarshal.h b/src/tpm2/StateMarshal.h
new file mode 100644
index 0000000..6fc6d14
--- /dev/null
+++ b/src/tpm2/StateMarshal.h
@@ -0,0 +1,53 @@
+/********************************************************************************/
+/* */
+/* Marshalling and unmarshalling of state */
+/* Written by Stefan Berger */
+/* IBM Thomas J. Watson Research Center */
+/* */
+/* (c) Copyright IBM Corporation 2017,2018. */
+/* */
+/* All rights reserved. */
+/* */
+/* Redistribution and use in source and binary forms, with or without */
+/* modification, are permitted provided that the following conditions are */
+/* met: */
+/* */
+/* Redistributions of source code must retain the above copyright notice, */
+/* this list of conditions and the following disclaimer. */
+/* */
+/* Redistributions in binary form must reproduce the above copyright */
+/* notice, this list of conditions and the following disclaimer in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* Neither the names of the IBM Corporation nor the names of its */
+/* contributors may be used to endorse or promote products derived from */
+/* this software without specific prior written permission. */
+/* */
+/* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS */
+/* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT */
+/* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR */
+/* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT */
+/* HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, */
+/* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT */
+/* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, */
+/* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY */
+/* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT */
+/* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE */
+/* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */
+/********************************************************************************/
+
+#ifndef STATE_MARSHAL_H
+#define STATE_MARSHAL_H
+
+#include "Tpm.h"
+#include "TpmTypes.h"
+
+/*
+ * we keep these in a separate file to avoid symbol clashes when
+ * included from the interface code.
+ */
+TPM_RC VolatileLoad(BOOL *restored);
+UINT16 VolatileSave(BYTE **buffer, INT32 *size);
+
+#endif /* STATE_MARSHAL_H */
+
diff --git a/src/tpm2/StirRandom_fp.h b/src/tpm2/StirRandom_fp.h
new file mode 100644
index 0000000..40ee129
--- /dev/null
+++ b/src/tpm2/StirRandom_fp.h
@@ -0,0 +1,78 @@
+/********************************************************************************/
+/* */
+/* */
+/* Written by Ken Goldman */
+/* IBM Thomas J. Watson Research Center */
+/* $Id: StirRandom_fp.h 809 2016-11-16 18:31:54Z kgoldman $ */
+/* */
+/* Licenses and Notices */
+/* */
+/* 1. Copyright Licenses: */
+/* */
+/* - Trusted Computing Group (TCG) grants to the user of the source code in */
+/* this specification (the "Source Code") a worldwide, irrevocable, */
+/* nonexclusive, royalty free, copyright license to reproduce, create */
+/* derivative works, distribute, display and perform the Source Code and */
+/* derivative works thereof, and to grant others the rights granted herein. */
+/* */
+/* - The TCG grants to the user of the other parts of the specification */
+/* (other than the Source Code) the rights to reproduce, distribute, */
+/* display, and perform the specification solely for the purpose of */
+/* developing products based on such documents. */
+/* */
+/* 2. Source Code Distribution Conditions: */
+/* */
+/* - Redistributions of Source Code must retain the above copyright licenses, */
+/* this list of conditions and the following disclaimers. */
+/* */
+/* - Redistributions in binary form must reproduce the above copyright */
+/* licenses, this list of conditions and the following disclaimers in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* 3. Disclaimers: */
+/* */
+/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
+/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
+/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
+/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
+/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
+/* information on specification licensing rights available through TCG */
+/* membership agreements. */
+/* */
+/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
+/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
+/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
+/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
+/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
+/* */
+/* - Without limitation, TCG and its members and licensors disclaim all */
+/* liability, including liability for infringement of any proprietary */
+/* rights, relating to use of information in this specification and to the */
+/* implementation of this specification, and TCG disclaims all liability for */
+/* cost of procurement of substitute goods or services, lost profits, loss */
+/* of use, loss of data or any incidental, consequential, direct, indirect, */
+/* or special damages, whether under contract, tort, warranty or otherwise, */
+/* arising in any way out of use or reliance upon this specification or any */
+/* information herein. */
+/* */
+/* (c) Copyright IBM Corp. and others, 2012-2015 */
+/* */
+/********************************************************************************/
+
+/* rev 119 */
+
+#ifndef STIRRANDOM_FP_H
+#define STIRRANDOM_FP_H
+
+typedef struct {
+ TPM2B_SENSITIVE_DATA inData;
+} StirRandom_In;
+
+#define RC_StirRandom_inData (TPM_RC_P + TPM_RC_1)
+
+TPM_RC
+TPM2_StirRandom(
+ StirRandom_In *in // IN: input parameter list
+ );
+
+#endif
diff --git a/src/tpm2/SupportLibraryFunctionPrototypes_fp.h b/src/tpm2/SupportLibraryFunctionPrototypes_fp.h
new file mode 100644
index 0000000..3b1e1a9
--- /dev/null
+++ b/src/tpm2/SupportLibraryFunctionPrototypes_fp.h
@@ -0,0 +1,156 @@
+/********************************************************************************/
+/* */
+/* For Selected Math Library */
+/* Written by Ken Goldman */
+/* IBM Thomas J. Watson Research Center */
+/* $Id: SupportLibraryFunctionPrototypes_fp.h 1529 2019-11-21 23:29:01Z kgoldman $ */
+/* */
+/* Licenses and Notices */
+/* */
+/* 1. Copyright Licenses: */
+/* */
+/* - Trusted Computing Group (TCG) grants to the user of the source code in */
+/* this specification (the "Source Code") a worldwide, irrevocable, */
+/* nonexclusive, royalty free, copyright license to reproduce, create */
+/* derivative works, distribute, display and perform the Source Code and */
+/* derivative works thereof, and to grant others the rights granted herein. */
+/* */
+/* - The TCG grants to the user of the other parts of the specification */
+/* (other than the Source Code) the rights to reproduce, distribute, */
+/* display, and perform the specification solely for the purpose of */
+/* developing products based on such documents. */
+/* */
+/* 2. Source Code Distribution Conditions: */
+/* */
+/* - Redistributions of Source Code must retain the above copyright licenses, */
+/* this list of conditions and the following disclaimers. */
+/* */
+/* - Redistributions in binary form must reproduce the above copyright */
+/* licenses, this list of conditions and the following disclaimers in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* 3. Disclaimers: */
+/* */
+/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
+/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
+/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
+/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
+/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
+/* information on specification licensing rights available through TCG */
+/* membership agreements. */
+/* */
+/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
+/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
+/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
+/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
+/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
+/* */
+/* - Without limitation, TCG and its members and licensors disclaim all */
+/* liability, including liability for infringement of any proprietary */
+/* rights, relating to use of information in this specification and to the */
+/* implementation of this specification, and TCG disclaims all liability for */
+/* cost of procurement of substitute goods or services, lost profits, loss */
+/* of use, loss of data or any incidental, consequential, direct, indirect, */
+/* or special damages, whether under contract, tort, warranty or otherwise, */
+/* arising in any way out of use or reliance upon this specification or any */
+/* information herein. */
+/* */
+/* (c) Copyright IBM Corp. and others, 2016 - 2019 */
+/* */
+/********************************************************************************/
+
+#ifndef SUPPORT_LIBRARY_FUNCTION_PROTOTYPES_H
+#define SUPPORT_LIBRARY_FUNCTION_PROTOTYPES_H
+
+/* 10.1.11 SupportLibraryFunctionPrototypes_fp.h */
+/* 10.1.11.1 Introduction */
+
+/* This file contains the function prototypes for the functions that need to be present in the
+ selected math library. For each function listed, there should be a small stub function. That
+ stub provides the interface between the TPM code and the support library. In most cases, the stub
+ function will only need to do a format conversion between the TPM big number and the support
+ library big number. The TPM big number format was chosen to make this relatively simple and
+ fast. */
+
+
+/* 10.1.11.2 SupportLibInit() */
+/* This function is called by CryptInit() so that necessary initializations can be performed on the
+ cryptographic library. */
+
+
+LIB_EXPORT
+int SupportLibInit(void);
+
+
+/* 10.1.11.3 MathLibraryCompatibililtyCheck() */
+/* This function is only used during development to make sure that the library that is being
+ referenced is using the same size of data structures as the TPM. */
+
+BOOL
+MathLibraryCompatibilityCheck(
+ void
+ );
+/* 10.1.1114 BnModMult() */
+/* Does multiply op1 * op2 and divide by modulus returning the remainder of the divide. */
+
+LIB_EXPORT BOOL
+BnModMult(bigNum result, bigConst op1, bigConst op2, bigConst modulus);
+
+/* 10.1.11.5 BnMult() */
+/* Multiplies two numbers and returns the result */
+
+LIB_EXPORT BOOL BnMult(bigNum result, bigConst multiplicand, bigConst multiplier);
+
+/* 10.1.11.6 BnDiv() */
+/* This function divides two bigNum values. The function returns FALSE if there is an error in the
+ operation. */
+LIB_EXPORT BOOL BnDiv(bigNum quotient, bigNum remainder,
+ bigConst dividend, bigConst divisor);
+
+/* 10.1.11.7 BnMod() */
+#define BnMod(a, b) BnDiv(NULL, (a), (a), (b))
+
+/* 10.1.11.8 BnGcd() */
+/* Get the greatest common divisor of two numbers. This function is only needed when the TPM
+ implements RSA. */
+LIB_EXPORT BOOL BnGcd(bigNum gcd, bigConst number1, bigConst number2);
+
+/* 10.1.11.9 BnModExp() */
+/* Do modular exponentiation using bigNum values. This function is only needed when the TPM
+ implements RSA. */
+LIB_EXPORT BOOL BnModExp(bigNum result, bigConst number,
+ bigConst exponent, bigConst modulus);
+
+/* 10.1.11.10 BnModInverse() */
+/* Modular multiplicative inverse. This function is only needed when the TPM implements RSA. */
+LIB_EXPORT BOOL BnModInverse(bigNum result, bigConst number,
+ bigConst modulus);
+
+/* 10.1.11.11 BnEccModMult() */
+/* This function does a point multiply of the form R = [d]S. A return of FALSE indicates that the
+ result was the point at infinity. This function is only needed if the TPM supports ECC. */
+LIB_EXPORT BOOL BnEccModMult(bigPoint R, pointConst S, bigConst d, bigCurve E);
+
+/* 10.1.11.13 BnEccModMult2() */
+/* This function does a point multiply of the form R = [d]S + [u]Q. A return of FALSE indicates that
+ the result was the point at infinity. This function is only needed if the TPM supports ECC */
+LIB_EXPORT BOOL BnEccModMult2(bigPoint R, pointConst S, bigConst d,
+ pointConst Q, bigConst u, bigCurve E);
+
+/* 10.1.11.14 BnEccAdd() */
+/* This function does a point add R = S + Q. A return of FALSE indicates that the result was the
+ point at infinity. This function is only needed if the TPM supports ECC. */
+LIB_EXPORT BOOL BnEccAdd(bigPoint R, pointConst S, pointConst Q, bigCurve E);
+
+/* 10.1.11.15 BnCurveInitialize() */
+/* This function is used to initialize the pointers of a bnCurve_t structure. The structure is a set
+ of pointers to bigNum values. The curve-dependent values are set by a different function. This
+ function is only needed if the TPM supports ECC.*/
+LIB_EXPORT bigCurve BnCurveInitialize(bigCurve E, TPM_ECC_CURVE curveId);
+
+/* 10.1.11.16 BnCurveFree() */
+/* This function will free the allocated components of the curve and end the frame in which the
+ curve data exists */
+LIB_EXPORT void BnCurveFree(bigCurve E);
+
+#endif
diff --git a/src/tpm2/SymmetricCommands.c b/src/tpm2/SymmetricCommands.c
new file mode 100644
index 0000000..68b6353
--- /dev/null
+++ b/src/tpm2/SymmetricCommands.c
@@ -0,0 +1,350 @@
+/********************************************************************************/
+/* */
+/* Symmetric Commands */
+/* Written by Ken Goldman */
+/* IBM Thomas J. Watson Research Center */
+/* $Id: SymmetricCommands.c 1658 2021-01-22 23:14:01Z kgoldman $ */
+/* */
+/* Licenses and Notices */
+/* */
+/* 1. Copyright Licenses: */
+/* */
+/* - Trusted Computing Group (TCG) grants to the user of the source code in */
+/* this specification (the "Source Code") a worldwide, irrevocable, */
+/* nonexclusive, royalty free, copyright license to reproduce, create */
+/* derivative works, distribute, display and perform the Source Code and */
+/* derivative works thereof, and to grant others the rights granted herein. */
+/* */
+/* - The TCG grants to the user of the other parts of the specification */
+/* (other than the Source Code) the rights to reproduce, distribute, */
+/* display, and perform the specification solely for the purpose of */
+/* developing products based on such documents. */
+/* */
+/* 2. Source Code Distribution Conditions: */
+/* */
+/* - Redistributions of Source Code must retain the above copyright licenses, */
+/* this list of conditions and the following disclaimers. */
+/* */
+/* - Redistributions in binary form must reproduce the above copyright */
+/* licenses, this list of conditions and the following disclaimers in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* 3. Disclaimers: */
+/* */
+/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
+/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
+/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
+/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
+/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
+/* information on specification licensing rights available through TCG */
+/* membership agreements. */
+/* */
+/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
+/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
+/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
+/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
+/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
+/* */
+/* - Without limitation, TCG and its members and licensors disclaim all */
+/* liability, including liability for infringement of any proprietary */
+/* rights, relating to use of information in this specification and to the */
+/* implementation of this specification, and TCG disclaims all liability for */
+/* cost of procurement of substitute goods or services, lost profits, loss */
+/* of use, loss of data or any incidental, consequential, direct, indirect, */
+/* or special damages, whether under contract, tort, warranty or otherwise, */
+/* arising in any way out of use or reliance upon this specification or any */
+/* information herein. */
+/* */
+/* (c) Copyright IBM Corp. and others, 2016 - 2021 */
+/* */
+/********************************************************************************/
+
+#include "Tpm.h"
+#include "EncryptDecrypt_fp.h"
+#if CC_EncryptDecrypt2
+#include "EncryptDecrypt_spt_fp.h"
+#endif
+#if CC_EncryptDecrypt // Conditional expansion of this file
+TPM_RC
+TPM2_EncryptDecrypt(
+ EncryptDecrypt_In *in, // IN: input parameter list
+ EncryptDecrypt_Out *out // OUT: output parameter list
+ )
+{
+#if CC_EncryptDecrypt2
+ return EncryptDecryptShared(in->keyHandle, in->decrypt, in->mode,
+ &in->ivIn, &in->inData, out);
+#else
+ OBJECT *symKey;
+ UINT16 keySize;
+ UINT16 blockSize;
+ BYTE *key;
+ TPM_ALG_ID alg;
+ TPM_ALG_ID mode;
+ TPM_RC result;
+ BOOL OK;
+ TPMA_OBJECT attributes;
+ // Input Validation
+ symKey = HandleToObject(in->keyHandle);
+ mode = symKey->publicArea.parameters.symDetail.sym.mode.sym;
+ attributes = symKey->publicArea.objectAttributes;
+ // The input key should be a symmetric key
+ if(symKey->publicArea.type != TPM_ALG_SYMCIPHER)
+ return TPM_RCS_KEY + RC_EncryptDecrypt_keyHandle;
+ // The key must be unrestricted and allow the selected operation
+ OK = IS_ATTRIBUTE(attributes, TPMA_OBJECT, restricted)
+ if(YES == in->decrypt)
+ OK = OK && IS_ATTRIBUTE(attributes, TPMA_OBJECT, decrypt);
+ else
+ OK = OK && IS_ATTRIBUTE(attributes, TPMA_OBJECT, sign);
+ if(!OK)
+ return TPM_RCS_ATTRIBUTES + RC_EncryptDecrypt_keyHandle;
+ // If the key mode is not TPM_ALG_NULL...
+ // or TPM_ALG_NULL
+ if(mode != TPM_ALG_NULL)
+ {
+ // then the input mode has to be TPM_ALG_NULL or the same as the key
+ if((in->mode != TPM_ALG_NULL) && (in->mode != mode))
+ return TPM_RCS_MODE + RC_EncryptDecrypt_mode;
+ }
+ else
+ {
+ // if the key mode is null, then the input can't be null
+ if(in->mode == TPM_ALG_NULL)
+ return TPM_RCS_MODE + RC_EncryptDecrypt_mode;
+ mode = in->mode;
+ }
+ // The input iv for ECB mode should be an Empty Buffer. All the other modes
+ // should have an iv size same as encryption block size
+ keySize = symKey->publicArea.parameters.symDetail.sym.keyBits.sym;
+ alg = symKey->publicArea.parameters.symDetail.sym.algorithm;
+ blockSize = CryptGetSymmetricBlockSize(alg, keySize);
+ // reverify the algorithm. This is mainly to keep static analysis tools happy
+ if(blockSize == 0)
+ return TPM_RCS_KEY + RC_EncryptDecrypt_keyHandle;
+ // Note: When an algorithm is not supported by a TPM, the TPM_ALG_xxx for that
+ // algorithm is not defined. However, it is assumed that the TPM_ALG_xxx for
+ // the algorithm is always defined. Both have the same numeric value.
+ // TPM_ALG_xxx is used here so that the code does not get cluttered with
+ // #ifdef's. Having this check does not mean that the algorithm is supported.
+ // If it was not supported the unmarshaling code would have rejected it before
+ // this function were called. This means that, depending on the implementation,
+ // the check could be redundant but it doesn't hurt.
+ if(((mode == TPM_ALG_ECB) && (in->ivIn.t.size != 0))
+ || ((mode != TPM_ALG_ECB) && (in->ivIn.t.size != blockSize)))
+ return TPM_RCS_SIZE + RC_EncryptDecrypt_ivIn;
+ // The input data size of CBC mode or ECB mode must be an even multiple of
+ // the symmetric algorithm's block size
+ if(((mode == TPM_ALG_CBC) || (mode == TPM_ALG_ECB))
+ && ((in->inData.t.size % blockSize) != 0))
+ return TPM_RCS_SIZE + RC_EncryptDecrypt_inData;
+ // Copy IV
+ // Note: This is copied here so that the calls to the encrypt/decrypt functions
+ // will modify the output buffer, not the input buffer
+ out->ivOut = in->ivIn;
+ // Command Output
+ key = symKey->sensitive.sensitive.sym.t.buffer;
+ // For symmetric encryption, the cipher data size is the same as plain data
+ // size.
+ out->outData.t.size = in->inData.t.size;
+ if(in->decrypt == YES)
+ {
+ // Decrypt data to output
+ result = CryptSymmetricDecrypt(out->outData.t.buffer, alg, keySize, key,
+ &(out->ivOut), mode, in->inData.t.size,
+ in->inData.t.buffer);
+ }
+ else
+ {
+ // Encrypt data to output
+ result = CryptSymmetricEncrypt(out->outData.t.buffer, alg, keySize, key,
+ &(out->ivOut), mode, in->inData.t.size,
+ in->inData.t.buffer);
+ }
+ return result;
+#endif // CC_EncryptDecrypt2
+}
+#endif // CC_EncryptDecrypt
+#include "Tpm.h"
+#include "EncryptDecrypt2_fp.h"
+#include "EncryptDecrypt_spt_fp.h"
+#if CC_EncryptDecrypt2 // Conditional expansion of this file
+TPM_RC
+TPM2_EncryptDecrypt2(
+ EncryptDecrypt2_In *in, // IN: input parameter list
+ EncryptDecrypt2_Out *out // OUT: output parameter list
+ )
+{
+ TPM_RC result;
+ // EncryptDecyrptShared() performs the operations as shown in
+ // TPM2_EncrypDecrypt
+ result = EncryptDecryptShared(in->keyHandle, in->decrypt, in->mode,
+ &in->ivIn, &in->inData,
+ (EncryptDecrypt_Out *)out);
+ // Handle response code swizzle.
+ switch(result)
+ {
+ case TPM_RCS_MODE + RC_EncryptDecrypt_mode:
+ result = TPM_RCS_MODE + RC_EncryptDecrypt2_mode;
+ break;
+ case TPM_RCS_SIZE + RC_EncryptDecrypt_ivIn:
+ result = TPM_RCS_SIZE + RC_EncryptDecrypt2_ivIn;
+ break;
+ case TPM_RCS_SIZE + RC_EncryptDecrypt_inData:
+ result = TPM_RCS_SIZE + RC_EncryptDecrypt2_inData;
+ break;
+ default:
+ break;
+ }
+ return result;
+}
+#endif // CC_EncryptDecrypt2
+#include "Tpm.h"
+#include "Hash_fp.h"
+#if CC_Hash // Conditional expansion of this file
+TPM_RC
+TPM2_Hash(
+ Hash_In *in, // IN: input parameter list
+ Hash_Out *out // OUT: output parameter list
+ )
+{
+ HASH_STATE hashState;
+ // Command Output
+ // Output hash
+ // Start hash stack
+ out->outHash.t.size = CryptHashStart(&hashState, in->hashAlg);
+ // Adding hash data
+ CryptDigestUpdate2B(&hashState, &in->data.b);
+ // Complete hash
+ CryptHashEnd2B(&hashState, &out->outHash.b);
+ // Output ticket
+ out->validation.tag = TPM_ST_HASHCHECK;
+ out->validation.hierarchy = in->hierarchy;
+ if(in->hierarchy == TPM_RH_NULL)
+ {
+ // Ticket is not required
+ out->validation.hierarchy = TPM_RH_NULL;
+ out->validation.digest.t.size = 0;
+ }
+ else if(in->data.t.size >= sizeof(TPM_GENERATED_VALUE)
+ && !TicketIsSafe(&in->data.b))
+ {
+ // Ticket is not safe
+ out->validation.hierarchy = TPM_RH_NULL;
+ out->validation.digest.t.size = 0;
+ }
+ else
+ {
+ // Compute ticket
+ TicketComputeHashCheck(in->hierarchy, in->hashAlg,
+ &out->outHash, &out->validation);
+ }
+ return TPM_RC_SUCCESS;
+}
+#endif // CC_Hash
+#include "Tpm.h"
+#include "HMAC_fp.h"
+#if CC_HMAC // Conditional expansion of this file
+TPM_RC
+TPM2_HMAC(
+ HMAC_In *in, // IN: input parameter list
+ HMAC_Out *out // OUT: output parameter list
+ )
+{
+ HMAC_STATE hmacState;
+ OBJECT *hmacObject;
+ TPMI_ALG_HASH hashAlg;
+ TPMT_PUBLIC *publicArea;
+ // Input Validation
+ // Get HMAC key object and public area pointers
+ hmacObject = HandleToObject(in->handle);
+ publicArea = &hmacObject->publicArea;
+ // Make sure that the key is an HMAC key
+ if(publicArea->type != TPM_ALG_KEYEDHASH)
+ return TPM_RCS_TYPE + RC_HMAC_handle;
+ // and that it is unrestricted
+ if (IS_ATTRIBUTE(publicArea->objectAttributes, TPMA_OBJECT, restricted))
+ return TPM_RCS_ATTRIBUTES + RC_HMAC_handle;
+ // and that it is a signing key
+ if (!IS_ATTRIBUTE(publicArea->objectAttributes, TPMA_OBJECT, sign))
+ return TPM_RCS_KEY + RC_HMAC_handle;
+ // See if the key has a default
+ if(publicArea->parameters.keyedHashDetail.scheme.scheme == TPM_ALG_NULL)
+ // it doesn't so use the input value
+ hashAlg = in->hashAlg;
+ else
+ {
+ // key has a default so use it
+ hashAlg
+ = publicArea->parameters.keyedHashDetail.scheme.details.hmac.hashAlg;
+ // and verify that the input was either the TPM_ALG_NULL or the default
+ if(in->hashAlg != TPM_ALG_NULL && in->hashAlg != hashAlg)
+ hashAlg = TPM_ALG_NULL;
+ }
+ // if we ended up without a hash algorithm then return an error
+ if(hashAlg == TPM_ALG_NULL)
+ return TPM_RCS_VALUE + RC_HMAC_hashAlg;
+ // Command Output
+ // Start HMAC stack
+ out->outHMAC.t.size = CryptHmacStart2B(&hmacState, hashAlg,
+ &hmacObject->sensitive.sensitive.bits.b);
+ // Adding HMAC data
+ CryptDigestUpdate2B(&hmacState.hashState, &in->buffer.b);
+ // Complete HMAC
+ CryptHmacEnd2B(&hmacState, &out->outHMAC.b);
+ return TPM_RC_SUCCESS;
+}
+#endif // CC_HMAC
+
+#include "Tpm.h"
+#include "MAC_fp.h"
+#if CC_MAC // Conditional expansion of this file
+/* Error Returns Meaning */
+/* TPM_RC_ATTRIBUTES key referenced by handle is a restricted key */
+/* TPM_RC_KEY handle does not reference a signing key */
+/* TPM_RC_TYPE key referenced by handle is not an HMAC key */
+/* TPM_RC_VALUE hashAlg is not compatible with the hash algorithm of the scheme of the object
+ referenced by handle */
+TPM_RC
+TPM2_MAC(
+ MAC_In *in, // IN: input parameter list
+ MAC_Out *out // OUT: output parameter list
+ )
+{
+ OBJECT *keyObject;
+ HMAC_STATE state;
+ TPMT_PUBLIC *publicArea;
+ TPM_RC result;
+ // Input Validation
+ // Get MAC key object and public area pointers
+ keyObject = HandleToObject(in->handle);
+ publicArea = &keyObject->publicArea;
+ // If the key is not able to do a MAC, indicate that the handle selects an
+ // object that can't do a MAC
+ result = CryptSelectMac(publicArea, &in->inScheme);
+ if(result == TPM_RCS_TYPE)
+ return TPM_RCS_TYPE + RC_MAC_handle;
+ // If there is another error type, indicate that the scheme and key are not
+ // compatible
+ if(result != TPM_RC_SUCCESS)
+ return RcSafeAddToResult(result, RC_MAC_inScheme);
+ // Make sure that the key is not restricted
+ if(IS_ATTRIBUTE(publicArea->objectAttributes, TPMA_OBJECT, restricted))
+ return TPM_RCS_ATTRIBUTES + RC_MAC_handle;
+ // and that it is a signing key
+ if(!IS_ATTRIBUTE(publicArea->objectAttributes, TPMA_OBJECT, sign))
+ return TPM_RCS_KEY + RC_MAC_handle;
+ // Command Output
+ out->outMAC.t.size = CryptMacStart(&state, &publicArea->parameters,
+ in->inScheme,
+ &keyObject->sensitive.sensitive.any.b);
+ // If the mac can't start, treat it as a fatal error
+ if(out->outMAC.t.size == 0)
+ return TPM_RC_FAILURE;
+ CryptDigestUpdate2B(&state.hashState, &in->buffer.b);
+ // If the MAC result is not what was expected, it is a fatal error
+ if(CryptHmacEnd2B(&state, &out->outMAC.b) != out->outMAC.t.size)
+ return TPM_RC_FAILURE;
+ return TPM_RC_SUCCESS;
+}
+#endif // CC_MAC
diff --git a/src/tpm2/SymmetricTest.h b/src/tpm2/SymmetricTest.h
new file mode 100644
index 0000000..058f50a
--- /dev/null
+++ b/src/tpm2/SymmetricTest.h
@@ -0,0 +1,138 @@
+/********************************************************************************/
+/* */
+/* Structures and data definitions for the symmetric tests */
+/* Written by Ken Goldman */
+/* IBM Thomas J. Watson Research Center */
+/* $Id: SymmetricTest.h 1658 2021-01-22 23:14:01Z kgoldman $ */
+/* */
+/* Licenses and Notices */
+/* */
+/* 1. Copyright Licenses: */
+/* */
+/* - Trusted Computing Group (TCG) grants to the user of the source code in */
+/* this specification (the "Source Code") a worldwide, irrevocable, */
+/* nonexclusive, royalty free, copyright license to reproduce, create */
+/* derivative works, distribute, display and perform the Source Code and */
+/* derivative works thereof, and to grant others the rights granted herein. */
+/* */
+/* - The TCG grants to the user of the other parts of the specification */
+/* (other than the Source Code) the rights to reproduce, distribute, */
+/* display, and perform the specification solely for the purpose of */
+/* developing products based on such documents. */
+/* */
+/* 2. Source Code Distribution Conditions: */
+/* */
+/* - Redistributions of Source Code must retain the above copyright licenses, */
+/* this list of conditions and the following disclaimers. */
+/* */
+/* - Redistributions in binary form must reproduce the above copyright */
+/* licenses, this list of conditions and the following disclaimers in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* 3. Disclaimers: */
+/* */
+/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
+/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
+/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
+/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
+/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
+/* information on specification licensing rights available through TCG */
+/* membership agreements. */
+/* */
+/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
+/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
+/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
+/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
+/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
+/* */
+/* - Without limitation, TCG and its members and licensors disclaim all */
+/* liability, including liability for infringement of any proprietary */
+/* rights, relating to use of information in this specification and to the */
+/* implementation of this specification, and TCG disclaims all liability for */
+/* cost of procurement of substitute goods or services, lost profits, loss */
+/* of use, loss of data or any incidental, consequential, direct, indirect, */
+/* or special damages, whether under contract, tort, warranty or otherwise, */
+/* arising in any way out of use or reliance upon this specification or any */
+/* information herein. */
+/* */
+/* (c) Copyright IBM Corp. and others, 2016 - 2021 */
+/* */
+/********************************************************************************/
+
+/* 10.1.11 SymmetricTest.h */
+
+/* 10.1.11.1 Introduction */
+
+/* This file contains the structures and data definitions for the symmetric tests. This file
+ references the header file that contains the actual test vectors. This organization was chosen so
+ that the program that is used to generate the test vector values does not have to also
+ re-generate this data. */
+
+#ifndef SELF_TEST_DATA
+#error "This file may only be included in AlgorithmTests.c"
+#endif
+#ifndef _SYMMETRIC_TEST_H
+#define _SYMMETRIC_TEST_H
+#include "SymmetricTestData.h"
+
+/* 10.1.11.2 Symmetric Test Structures */
+
+const SYMMETRIC_TEST_VECTOR c_symTestValues[NUM_SYMS + 1] = {
+#if ALG_AES && AES_128
+ {TPM_ALG_AES, 128, key_AES128, 16, sizeof(dataIn_AES128), dataIn_AES128,
+ {dataOut_AES128_CTR, dataOut_AES128_OFB, dataOut_AES128_CBC,
+ dataOut_AES128_CFB, dataOut_AES128_ECB}},
+#endif
+#if ALG_AES && AES_192
+ {TPM_ALG_AES_, 192, key_AES192, 16, sizeof(dataIn_AES192), dataIn_AES192,
+ {dataOut_AES192_CTR, dataOut_AES192_OFB, dataOut_AES192_CBC,
+ dataOut_AES192_CFB, dataOut_AES192_ECB}},
+#endif
+#if ALG_AES && AES_256
+ {TPM_ALG_AES, 256, key_AES256, 16, sizeof(dataIn_AES256), dataIn_AES256,
+ {dataOut_AES256_CTR, dataOut_AES256_OFB, dataOut_AES256_CBC,
+ dataOut_AES256_CFB, dataOut_AES256_ECB}},
+#endif
+#if ALG_SM4 && SM4_128 // libtpms activated
+ {TPM_ALG_SM4, 128, key_SM4128, 16, sizeof(dataIn_SM4128), dataIn_SM4128,
+ {dataOut_SM4128_CTR, dataOut_SM4128_OFB, dataOut_SM4128_CBC,
+ dataOut_SM4128_CFB, dataOut_AES128_ECB}},
+#endif
+// libtpms added begin
+#if ALG_TDES && TDES_128
+ {TPM_ALG_TDES, 128, key_TDES128, 8, sizeof(dataIn_TDES128), dataIn_TDES128,
+ {dataOut_TDES128_CTR, dataOut_TDES128_OFB, dataOut_TDES128_CBC,
+ dataOut_TDES128_CFB, dataOut_TDES128_ECB}},
+ {TPM_ALG_TDES, 128, key_TDES128, 8, sizeof(dataInShort_TDES128), dataInShort_TDES128,
+ {NULL, dataOutShort_TDES128_OFB, NULL,
+ dataOutShort_TDES128_CFB, NULL}},
+#endif
+#if ALG_TDES && TDES_192
+ {TPM_ALG_TDES, 192, key_TDES192, 8, sizeof(dataIn_TDES192), dataIn_TDES192,
+ {dataOut_TDES192_CTR, dataOut_TDES192_OFB, dataOut_TDES192_CBC,
+ dataOut_TDES192_CFB, dataOut_TDES192_ECB}},
+ {TPM_ALG_TDES, 192, key_TDES192, 8, sizeof(dataInShort_TDES192), dataInShort_TDES192,
+ {NULL, dataOutShort_TDES192_OFB, NULL,
+ dataOutShort_TDES192_CFB, NULL}},
+#endif
+#if ALG_CAMELLIA && CAMELLIA_128
+ {TPM_ALG_CAMELLIA, 128, key_CAMELLIA128, 16, sizeof(dataIn_CAMELLIA128), dataIn_CAMELLIA128,
+ {dataOut_CAMELLIA128_CTR, dataOut_CAMELLIA128_OFB, dataOut_CAMELLIA128_CBC,
+ dataOut_CAMELLIA128_CFB, dataOut_CAMELLIA128_ECB}},
+#endif
+#if ALG_CAMELLIA && CAMELLIA_192
+ {TPM_ALG_CAMELLIA, 192, key_CAMELLIA192, 16, sizeof(dataIn_CAMELLIA192), dataIn_CAMELLIA192,
+ {dataOut_CAMELLIA192_CTR, dataOut_CAMELLIA192_OFB, dataOut_CAMELLIA192_CBC,
+ dataOut_CAMELLIA192_CFB, dataOut_CAMELLIA192_ECB}},
+#endif
+#if ALG_CAMELLIA && CAMELLIA_256
+ {TPM_ALG_CAMELLIA, 256, key_CAMELLIA256, 16, sizeof(dataIn_CAMELLIA256), dataIn_CAMELLIA256,
+ {dataOut_CAMELLIA256_CTR, dataOut_CAMELLIA256_OFB, dataOut_CAMELLIA256_CBC,
+ dataOut_CAMELLIA256_CFB, dataOut_CAMELLIA256_ECB}},
+#endif
+// libtpms added end
+ {0}
+};
+
+#endif // _SYMMETRIC_TEST_H
+
diff --git a/src/tpm2/SymmetricTestData.h b/src/tpm2/SymmetricTestData.h
new file mode 100644
index 0000000..77321fa
--- /dev/null
+++ b/src/tpm2/SymmetricTestData.h
@@ -0,0 +1,400 @@
+/********************************************************************************/
+/* */
+/* Vector for testing Either Encrypt or Decrypt */
+/* Written by Ken Goldman */
+/* IBM Thomas J. Watson Research Center */
+/* $Id: SymmetricTestData.h 1476 2019-06-10 19:32:03Z kgoldman $ */
+/* */
+/* Licenses and Notices */
+/* */
+/* 1. Copyright Licenses: */
+/* */
+/* - Trusted Computing Group (TCG) grants to the user of the source code in */
+/* this specification (the "Source Code") a worldwide, irrevocable, */
+/* nonexclusive, royalty free, copyright license to reproduce, create */
+/* derivative works, distribute, display and perform the Source Code and */
+/* derivative works thereof, and to grant others the rights granted herein. */
+/* */
+/* - The TCG grants to the user of the other parts of the specification */
+/* (other than the Source Code) the rights to reproduce, distribute, */
+/* display, and perform the specification solely for the purpose of */
+/* developing products based on such documents. */
+/* */
+/* 2. Source Code Distribution Conditions: */
+/* */
+/* - Redistributions of Source Code must retain the above copyright licenses, */
+/* this list of conditions and the following disclaimers. */
+/* */
+/* - Redistributions in binary form must reproduce the above copyright */
+/* licenses, this list of conditions and the following disclaimers in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* 3. Disclaimers: */
+/* */
+/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
+/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
+/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
+/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
+/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
+/* information on specification licensing rights available through TCG */
+/* membership agreements. */
+/* */
+/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
+/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
+/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
+/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
+/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
+/* */
+/* - Without limitation, TCG and its members and licensors disclaim all */
+/* liability, including liability for infringement of any proprietary */
+/* rights, relating to use of information in this specification and to the */
+/* implementation of this specification, and TCG disclaims all liability for */
+/* cost of procurement of substitute goods or services, lost profits, loss */
+/* of use, loss of data or any incidental, consequential, direct, indirect, */
+/* or special damages, whether under contract, tort, warranty or otherwise, */
+/* arising in any way out of use or reliance upon this specification or any */
+/* information herein. */
+/* */
+/* (c) Copyright IBM Corp. and others, 2016 - 2019 */
+/* */
+/********************************************************************************/
+
+#ifndef SYMMETRICTESTDATA_H
+#define SYMMETRICTESTDATA_H
+
+/* 10.1.10 SymmetricTestData.h */
+/* This is a vector for testing either encrypt or decrypt. The premise for decrypt is that the IV
+ for decryption is the same as the IV for encryption. However, the ivOut value may be different
+ for encryption and decryption. We will encrypt at least two blocks. This means that the chaining
+ value will be used for each of the schemes (if any) and that implicitly checks that the chaining
+ value is handled properly. */
+#if AES_128
+const BYTE key_AES128 [] = {
+ 0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6,
+ 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c};
+const BYTE dataIn_AES128 [] = {
+ 0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96,
+ 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a,
+ 0xae, 0x2d, 0x8a, 0x57, 0x1e, 0x03, 0xac, 0x9c,
+ 0x9e, 0xb7, 0x6f, 0xac, 0x45, 0xaf, 0x8e, 0x51};
+const BYTE dataOut_AES128_ECB [] = {
+ 0x3a, 0xd7, 0x7b, 0xb4, 0x0d, 0x7a, 0x36, 0x60,
+ 0xa8, 0x9e, 0xca, 0xf3, 0x24, 0x66, 0xef, 0x97,
+ 0xf5, 0xd3, 0xd5, 0x85, 0x03, 0xb9, 0x69, 0x9d,
+ 0xe7, 0x85, 0x89, 0x5a, 0x96, 0xfd, 0xba, 0xaf};
+const BYTE dataOut_AES128_CBC [] = {
+ 0x76, 0x49, 0xab, 0xac, 0x81, 0x19, 0xb2, 0x46,
+ 0xce, 0xe9, 0x8e, 0x9b, 0x12, 0xe9, 0x19, 0x7d,
+ 0x50, 0x86, 0xcb, 0x9b, 0x50, 0x72, 0x19, 0xee,
+ 0x95, 0xdb, 0x11, 0x3a, 0x91, 0x76, 0x78, 0xb2};
+const BYTE dataOut_AES128_CFB [] = {
+ 0x3b, 0x3f, 0xd9, 0x2e, 0xb7, 0x2d, 0xad, 0x20,
+ 0x33, 0x34, 0x49, 0xf8, 0xe8, 0x3c, 0xfb, 0x4a,
+ 0xc8, 0xa6, 0x45, 0x37, 0xa0, 0xb3, 0xa9, 0x3f,
+ 0xcd, 0xe3, 0xcd, 0xad, 0x9f, 0x1c, 0xe5, 0x8b};
+const BYTE dataOut_AES128_OFB [] = {
+ 0x3b, 0x3f, 0xd9, 0x2e, 0xb7, 0x2d, 0xad, 0x20,
+ 0x33, 0x34, 0x49, 0xf8, 0xe8, 0x3c, 0xfb, 0x4a,
+ 0x77, 0x89, 0x50, 0x8d, 0x16, 0x91, 0x8f, 0x03,
+ 0xf5, 0x3c, 0x52, 0xda, 0xc5, 0x4e, 0xd8, 0x25};
+const BYTE dataOut_AES128_CTR [] = {
+ 0x87, 0x4d, 0x61, 0x91, 0xb6, 0x20, 0xe3, 0x26,
+ 0x1b, 0xef, 0x68, 0x64, 0x99, 0x0d, 0xb6, 0xce,
+ 0x98, 0x06, 0xf6, 0x6b, 0x79, 0x70, 0xfd, 0xff,
+ 0x86, 0x17, 0x18, 0x7b, 0xb9, 0xff, 0xfd, 0xff};
+#endif
+#if AES_192
+const BYTE key_AES192 [] = {
+ 0x8e, 0x73, 0xb0, 0xf7, 0xda, 0x0e, 0x64, 0x52,
+ 0xc8, 0x10, 0xf3, 0x2b, 0x80, 0x90, 0x79, 0xe5,
+ 0x62, 0xf8, 0xea, 0xd2, 0x52, 0x2c, 0x6b, 0x7b};
+const BYTE dataIn_AES192 [] = {
+ 0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96,
+ 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a,
+ 0xae, 0x2d, 0x8a, 0x57, 0x1e, 0x03, 0xac, 0x9c,
+ 0x9e, 0xb7, 0x6f, 0xac, 0x45, 0xaf, 0x8e, 0x51};
+const BYTE dataOut_AES192_ECB [] = {
+ 0xbd, 0x33, 0x4f, 0x1d, 0x6e, 0x45, 0xf2, 0x5f,
+ 0xf7, 0x12, 0xa2, 0x14, 0x57, 0x1f, 0xa5, 0xcc,
+ 0x97, 0x41, 0x04, 0x84, 0x6d, 0x0a, 0xd3, 0xad,
+ 0x77, 0x34, 0xec, 0xb3, 0xec, 0xee, 0x4e, 0xef};
+const BYTE dataOut_AES192_CBC [] = {
+ 0x4f, 0x02, 0x1d, 0xb2, 0x43, 0xbc, 0x63, 0x3d,
+ 0x71, 0x78, 0x18, 0x3a, 0x9f, 0xa0, 0x71, 0xe8,
+ 0xb4, 0xd9, 0xad, 0xa9, 0xad, 0x7d, 0xed, 0xf4,
+ 0xe5, 0xe7, 0x38, 0x76, 0x3f, 0x69, 0x14, 0x5a};
+const BYTE dataOut_AES192_CFB [] = {
+ 0xcd, 0xc8, 0x0d, 0x6f, 0xdd, 0xf1, 0x8c, 0xab,
+ 0x34, 0xc2, 0x59, 0x09, 0xc9, 0x9a, 0x41, 0x74,
+ 0x67, 0xce, 0x7f, 0x7f, 0x81, 0x17, 0x36, 0x21,
+ 0x96, 0x1a, 0x2b, 0x70, 0x17, 0x1d, 0x3d, 0x7a};
+const BYTE dataOut_AES192_OFB [] = {
+ 0xcd, 0xc8, 0x0d, 0x6f, 0xdd, 0xf1, 0x8c, 0xab,
+ 0x34, 0xc2, 0x59, 0x09, 0xc9, 0x9a, 0x41, 0x74,
+ 0xfc, 0xc2, 0x8b, 0x8d, 0x4c, 0x63, 0x83, 0x7c,
+ 0x09, 0xe8, 0x17, 0x00, 0xc1, 0x10, 0x04, 0x01};
+const BYTE dataOut_AES192_CTR [] = {
+ 0x1a, 0xbc, 0x93, 0x24, 0x17, 0x52, 0x1c, 0xa2,
+ 0x4f, 0x2b, 0x04, 0x59, 0xfe, 0x7e, 0x6e, 0x0b,
+ 0x09, 0x03, 0x39, 0xec, 0x0a, 0xa6, 0xfa, 0xef,
+ 0xd5, 0xcc, 0xc2, 0xc6, 0xf4, 0xce, 0x8e, 0x94};
+#endif
+#if AES_256
+const BYTE key_AES256 [] = {
+ 0x60, 0x3d, 0xeb, 0x10, 0x15, 0xca, 0x71, 0xbe,
+ 0x2b, 0x73, 0xae, 0xf0, 0x85, 0x7d, 0x77, 0x81,
+ 0x1f, 0x35, 0x2c, 0x07, 0x3b, 0x61, 0x08, 0xd7,
+ 0x2d, 0x98, 0x10, 0xa3, 0x09, 0x14, 0xdf, 0xf4};
+const BYTE dataIn_AES256 [] = {
+ 0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96,
+ 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a,
+ 0xae, 0x2d, 0x8a, 0x57, 0x1e, 0x03, 0xac, 0x9c,
+ 0x9e, 0xb7, 0x6f, 0xac, 0x45, 0xaf, 0x8e, 0x51};
+const BYTE dataOut_AES256_ECB [] = {
+ 0xf3, 0xee, 0xd1, 0xbd, 0xb5, 0xd2, 0xa0, 0x3c,
+ 0x06, 0x4b, 0x5a, 0x7e, 0x3d, 0xb1, 0x81, 0xf8,
+ 0x59, 0x1c, 0xcb, 0x10, 0xd4, 0x10, 0xed, 0x26,
+ 0xdc, 0x5b, 0xa7, 0x4a, 0x31, 0x36, 0x28, 0x70};
+const BYTE dataOut_AES256_CBC [] = {
+ 0xf5, 0x8c, 0x4c, 0x04, 0xd6, 0xe5, 0xf1, 0xba,
+ 0x77, 0x9e, 0xab, 0xfb, 0x5f, 0x7b, 0xfb, 0xd6,
+ 0x9c, 0xfc, 0x4e, 0x96, 0x7e, 0xdb, 0x80, 0x8d,
+ 0x67, 0x9f, 0x77, 0x7b, 0xc6, 0x70, 0x2c, 0x7d};
+const BYTE dataOut_AES256_CFB [] = {
+ 0xdc, 0x7e, 0x84, 0xbf, 0xda, 0x79, 0x16, 0x4b,
+ 0x7e, 0xcd, 0x84, 0x86, 0x98, 0x5d, 0x38, 0x60,
+ 0x39, 0xff, 0xed, 0x14, 0x3b, 0x28, 0xb1, 0xc8,
+ 0x32, 0x11, 0x3c, 0x63, 0x31, 0xe5, 0x40, 0x7b};
+const BYTE dataOut_AES256_OFB [] = {
+ 0xdc, 0x7e, 0x84, 0xbf, 0xda, 0x79, 0x16, 0x4b,
+ 0x7e, 0xcd, 0x84, 0x86, 0x98, 0x5d, 0x38, 0x60,
+ 0x4f, 0xeb, 0xdc, 0x67, 0x40, 0xd2, 0x0b, 0x3a,
+ 0xc8, 0x8f, 0x6a, 0xd8, 0x2a, 0x4f, 0xb0, 0x8d};
+const BYTE dataOut_AES256_CTR [] = {
+ 0x60, 0x1e, 0xc3, 0x13, 0x77, 0x57, 0x89, 0xa5,
+ 0xb7, 0xa7, 0xf5, 0x04, 0xbb, 0xf3, 0xd2, 0x28,
+ 0xf4, 0x43, 0xe3, 0xca, 0x4d, 0x62, 0xb5, 0x9a,
+ 0xca, 0x84, 0xe9, 0x90, 0xca, 0xca, 0xf5, 0xc5};
+#endif
+// libtpms added begin
+#if TDES_128
+const BYTE key_TDES128 [] = {
+ 0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6,
+ 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c};
+const BYTE dataIn_TDES128 [] = {
+ 0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96,
+ 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a,
+ 0xae, 0x2d, 0x8a, 0x57, 0x1e, 0x03, 0xac, 0x9c,
+ 0x9e, 0xb7, 0x6f, 0xac, 0x45, 0xaf, 0x8e, 0x51};
+const BYTE dataOut_TDES128_ECB [] = {
+ 0xdf, 0x8f, 0x88, 0x43, 0x2f, 0xea, 0x61, 0x0c,
+ 0xc1, 0xfa, 0xaf, 0x1a, 0xb1, 0xc0, 0xc0, 0x37,
+ 0x27, 0xf2, 0xe0, 0x8e, 0xda, 0x14, 0xbe, 0x79,
+ 0x91, 0x95, 0xd2, 0x61, 0x2b, 0x46, 0x49, 0x4e,
+ 0x1b, 0x10, 0xa6, 0xcc, 0x02, 0xb6, 0x5a, 0x6c};
+const BYTE dataOut_TDES128_CBC [] = {
+ 0x0a, 0xdd, 0xd5, 0x8a, 0x85, 0x33, 0xda, 0x86,
+ 0x68, 0x8f, 0xb9, 0x05, 0xe3, 0x32, 0xe1, 0x58,
+ 0x82, 0x33, 0x72, 0x85, 0xbc, 0x64, 0xcd, 0xd2,
+ 0x25, 0xa2, 0x54, 0x5e, 0x22, 0xe0, 0xde, 0x92,
+ 0x80, 0x69, 0x5e, 0x61, 0x77, 0xb5, 0x94, 0x1b};
+const BYTE dataOut_TDES128_CFB [] = {
+ 0x9c, 0xe7, 0x8f, 0x92, 0x6d, 0x37, 0xe4, 0xaa,
+ 0x8e, 0x12, 0x14, 0xdc, 0xb7, 0x46, 0xc3, 0x6d,
+ 0x3f, 0x6f, 0x17, 0x5b, 0x97, 0x9d, 0x9e, 0x8a,
+ 0xb5, 0xc4, 0xcd, 0x2a, 0x7a, 0x3e, 0xad, 0xec};
+const BYTE dataOut_TDES128_OFB [] = {
+ 0x9c, 0xe7, 0x8f, 0x92, 0x6d, 0x37, 0xe4, 0xaa,
+ 0x1b, 0x85, 0x9f, 0x7f, 0x80, 0x56, 0x10, 0xbc,
+ 0xa4, 0xaa, 0x05, 0xd0, 0xd8, 0xf1, 0xda, 0x3e,
+ 0x74, 0x82, 0x69, 0xb2, 0x8f, 0xf1, 0x6d, 0xde};
+const BYTE dataOut_TDES128_CTR [] = {
+ 0x9e, 0xf8, 0x6f, 0x66, 0x5a, 0xa7, 0x9c, 0x91,
+ 0xe8, 0x07, 0xf9, 0x7a, 0x96, 0xf9, 0x6a, 0x87,
+ 0x19, 0x22, 0x3f, 0x9d, 0x9e, 0x92, 0xc4, 0x25,
+ 0x4a, 0x31, 0x6d, 0x3c, 0x35, 0xa6, 0x3a, 0x03};
+
+const BYTE dataInShort_TDES128 [] = {
+ 0x31, 0x32, 0x33, 0x34, 0x35};
+// CBC and ECB need multiple of blocksize input
+const BYTE dataOutShort_TDES128_CFB[] = {
+ 0xc6, 0x14, 0x02, 0x44, 0x76};
+const BYTE dataOutShort_TDES128_OFB[] = {
+ 0xc6, 0x14, 0x02, 0x44, 0x76};
+#endif
+#if TDES_192
+const BYTE key_TDES192 [] = {
+ 0x8e, 0x73, 0xb0, 0xf7, 0xda, 0x0e, 0x64, 0x52,
+ 0xc8, 0x10, 0xf3, 0x2b, 0x80, 0x90, 0x79, 0xe5,
+ 0x62, 0xf8, 0xea, 0xd2, 0x52, 0x2c, 0x6b, 0x7b};
+const BYTE dataIn_TDES192 [] = {
+ 0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96,
+ 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a,
+ 0xae, 0x2d, 0x8a, 0x57, 0x1e, 0x03, 0xac, 0x9c,
+ 0x9e, 0xb7, 0x6f, 0xac, 0x45, 0xaf, 0x8e, 0x51};
+const BYTE dataOut_TDES192_ECB [] = {
+ 0x37, 0x62, 0x02, 0x5d, 0xad, 0x85, 0x03, 0xe9,
+ 0xff, 0x0f, 0xce, 0x66, 0x28, 0x74, 0x3f, 0x94,
+ 0x72, 0x42, 0xbb, 0xc5, 0x14, 0xae, 0xc6, 0x2f,
+ 0x61, 0xd1, 0x03, 0x9c, 0xd1, 0xf7, 0xf8, 0x29,
+ 0x62, 0x91, 0x03, 0x74, 0xe7, 0x05, 0xb3, 0xb6};
+const BYTE dataOut_TDES192_CBC [] = {
+ 0x6c, 0x30, 0xbb, 0x5e, 0xbc, 0x73, 0xb1, 0x2d,
+ 0x40, 0x24, 0x93, 0x65, 0xd8, 0x9a, 0x27, 0x4f,
+ 0xdd, 0x09, 0xfc, 0x95, 0x28, 0xa3, 0xd9, 0x46,
+ 0xf9, 0x15, 0x43, 0x52, 0x7a, 0x0d, 0xd6, 0x3e,
+ 0xd1, 0xb0, 0x10, 0x64, 0x63, 0x5e, 0xa0, 0xb5};
+const BYTE dataOut_TDES192_CFB [] = {
+ 0x89, 0x00, 0xbb, 0xec, 0x56, 0xdc, 0x77, 0x81,
+ 0x59, 0xdb, 0x1d, 0xa4, 0xe2, 0x33, 0x85, 0x2d,
+ 0xbf, 0xfb, 0xe3, 0xe2, 0xe0, 0x46, 0x91, 0x09,
+ 0x15, 0xcb, 0x41, 0x7c, 0xd5, 0x84, 0x60, 0xf1};
+const BYTE dataOut_TDES192_OFB [] = {
+ 0x89, 0x00, 0xbb, 0xec, 0x56, 0xdc, 0x77, 0x81,
+ 0xf0, 0x12, 0x4b, 0xe3, 0xc5, 0x83, 0x60, 0x45,
+ 0xda, 0x4d, 0xba, 0x05, 0x78, 0xa3, 0x77, 0xc8,
+ 0x21, 0x57, 0xcd, 0x62, 0xbb, 0x93, 0xc8, 0x4e};
+const BYTE dataOut_TDES192_CTR [] = {
+ 0x17, 0x4d, 0xdf, 0xde, 0x7b, 0xe0, 0x2f, 0xb7,
+ 0x58, 0x49, 0x76, 0xe5, 0x80, 0xbd, 0x49, 0x45,
+ 0x64, 0x3a, 0xe4, 0x42, 0xfe, 0x4c, 0x25, 0xd4,
+ 0x79, 0x74, 0xf0, 0xe6, 0x0b, 0x3d, 0x20, 0xac};
+
+const BYTE dataInShort_TDES192 [] = {
+ 0x31, 0x32, 0x33, 0x34, 0x35};
+// CBC and ECB need multiple of blocksize input
+const BYTE dataOutShort_TDES192_CFB[] = {
+ 0xd3, 0xf3, 0x36, 0x3a, 0x4d};
+const BYTE dataOutShort_TDES192_OFB[] = {
+ 0xd3, 0xf3, 0x36, 0x3a, 0x4d};
+#endif
+#if CAMELLIA_128
+const BYTE key_CAMELLIA128 [] = {
+ 0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6,
+ 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c};
+const BYTE dataIn_CAMELLIA128 [] = {
+ 0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96,
+ 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a,
+ 0xae, 0x2d, 0x8a, 0x57, 0x1e, 0x03, 0xac, 0x9c,
+ 0x9e, 0xb7, 0x6f, 0xac, 0x45, 0xaf, 0x8e, 0x51};
+const BYTE dataOut_CAMELLIA128_ECB [] = {
+ 0x43, 0x2f, 0xc5, 0xdc, 0xd6, 0x28, 0x11, 0x5b,
+ 0x7c, 0x38, 0x8d, 0x77, 0x0b, 0x27, 0x0c, 0x96,
+ 0x0b, 0xe1, 0xf1, 0x40, 0x23, 0x78, 0x2a, 0x22,
+ 0xe8, 0x38, 0x4c, 0x5a, 0xbb, 0x7f, 0xab, 0x2b,
+ 0x7e, 0x70, 0x91, 0x4b, 0xf1, 0x6a, 0x5b, 0xf9,
+ 0x66, 0x36, 0x97, 0x11, 0xdf, 0xeb, 0x46, 0xef};
+const BYTE dataOut_CAMELLIA128_CBC [] = {
+ 0x16, 0x07, 0xcf, 0x49, 0x4b, 0x36, 0xbb, 0xf0,
+ 0x0d, 0xae, 0xb0, 0xb5, 0x03, 0xc8, 0x31, 0xab,
+ 0xa2, 0xf2, 0xcf, 0x67, 0x16, 0x29, 0xef, 0x78,
+ 0x40, 0xc5, 0xa5, 0xdf, 0xb5, 0x07, 0x48, 0x87,
+ 0xa0, 0x0a, 0xdd, 0x48, 0xf1, 0x12, 0xef, 0xa5,
+ 0xae, 0xc3, 0x5f, 0x22, 0x3c, 0x55, 0x84, 0xc0};
+const BYTE dataOut_CAMELLIA128_CFB [] = {
+ 0x14, 0xf7, 0x64, 0x61, 0x87, 0x81, 0x7e, 0xb5,
+ 0x86, 0x59, 0x91, 0x46, 0xb8, 0x2b, 0xd7, 0x19,
+ 0xa5, 0x3d, 0x28, 0xbb, 0x82, 0xdf, 0x74, 0x11,
+ 0x03, 0xea, 0x4f, 0x92, 0x1a, 0x44, 0x88, 0x0b};
+const BYTE dataOut_CAMELLIA128_OFB [] = {
+ 0x14, 0xf7, 0x64, 0x61, 0x87, 0x81, 0x7e, 0xb5,
+ 0x86, 0x59, 0x91, 0x46, 0xb8, 0x2b, 0xd7, 0x19,
+ 0x97, 0x32, 0x91, 0x71, 0x6c, 0x4d, 0x82, 0xd0,
+ 0x1a, 0x07, 0x9e, 0x6d, 0xf7, 0x00, 0xe6, 0xeb};
+const BYTE dataOut_CAMELLIA128_CTR [] = {
+ 0xb8, 0x09, 0x14, 0x08, 0x77, 0xdd, 0x16, 0xc0,
+ 0x76, 0x78, 0x09, 0x04, 0xf8, 0x3d, 0xed, 0x11,
+ 0xbb, 0x41, 0xe6, 0x4e, 0x9b, 0xf1, 0x76, 0xce,
+ 0x05, 0xd4, 0x18, 0x6b, 0x25, 0x86, 0xd4, 0xc9};
+#endif
+#if CAMELLIA_192
+#error Missing test cases for CAMELLIA_192
+#endif
+#if CAMELLIA_256
+const BYTE key_CAMELLIA256 [] = {
+ 0x60, 0x3d, 0xeb, 0x10, 0x15, 0xca, 0x71, 0xbe,
+ 0x2b, 0x73, 0xae, 0xf0, 0x85, 0x7d, 0x77, 0x81,
+ 0x1f, 0x35, 0x2c, 0x07, 0x3b, 0x61, 0x08, 0xd7,
+ 0x2d, 0x98, 0x10, 0xa3, 0x09, 0x14, 0xdf, 0xf4};
+const BYTE dataIn_CAMELLIA256 [] = {
+ 0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96,
+ 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a,
+ 0xae, 0x2d, 0x8a, 0x57, 0x1e, 0x03, 0xac, 0x9c,
+ 0x9e, 0xb7, 0x6f, 0xac, 0x45, 0xaf, 0x8e, 0x51};
+const BYTE dataOut_CAMELLIA256_ECB [] = {
+ 0xbe, 0xfd, 0x21, 0x9b, 0x11, 0x2f, 0xa0, 0x00,
+ 0x98, 0x91, 0x9c, 0xd1, 0x01, 0xc9, 0xcc, 0xfa,
+ 0xc9, 0x1d, 0x3a, 0x8f, 0x1a, 0xea, 0x08, 0xa9,
+ 0x38, 0x6c, 0xf4, 0xb6, 0x6c, 0x01, 0x69, 0xea,
+ 0x75, 0xf3, 0x8b, 0xad, 0x6b, 0x72, 0x54, 0xfa,
+ 0xa4, 0xb0, 0x3d, 0x32, 0x0a, 0x0d, 0xb2, 0xdc};
+const BYTE dataOut_CAMELLIA256_CBC [] = {
+ 0xe6, 0xcf, 0xa3, 0x5f, 0xc0, 0x2b, 0x13, 0x4a,
+ 0x4d, 0x2c, 0x0b, 0x67, 0x37, 0xac, 0x3e, 0xda,
+ 0x36, 0xcb, 0xeb, 0x73, 0xbd, 0x50, 0x4b, 0x40,
+ 0x70, 0xb1, 0xb7, 0xde, 0x2b, 0x21, 0xeb, 0x50,
+ 0x6a, 0x0c, 0xf7, 0x4b, 0xbc, 0x7f, 0xbb, 0xa3,
+ 0x82, 0x9c, 0x6d, 0x06, 0xcb, 0x4f, 0xb2, 0xc5};
+const BYTE dataOut_CAMELLIA256_CFB [] = {
+ 0xcf, 0x61, 0x07, 0xbb, 0x0c, 0xea, 0x7d, 0x7f,
+ 0xb1, 0xbd, 0x31, 0xf5, 0xe7, 0xb0, 0x6c, 0x93,
+ 0x89, 0xbe, 0xdb, 0x4c, 0xcd, 0xd8, 0x64, 0xea,
+ 0x11, 0xba, 0x4c, 0xbe, 0x84, 0x9b, 0x5e, 0x2b};
+const BYTE dataOut_CAMELLIA256_OFB [] = {
+ 0xcf, 0x61, 0x07, 0xbb, 0x0c, 0xea, 0x7d, 0x7f,
+ 0xb1, 0xbd, 0x31, 0xf5, 0xe7, 0xb0, 0x6c, 0x93,
+ 0x85, 0x52, 0x1d, 0xb2, 0xf6, 0xbb, 0x67, 0x7f,
+ 0x1e, 0xb2, 0x24, 0x46, 0x58, 0x41, 0x83, 0x40};
+const BYTE dataOut_CAMELLIA256_CTR [] = {
+ 0x47, 0xba, 0x6e, 0xea, 0x51, 0xb4, 0x38, 0xfc,
+ 0xf2, 0x1c, 0x3c, 0xc9, 0x88, 0x76, 0x28, 0x17,
+ 0x1a, 0x7b, 0xbb, 0xfc, 0x7f, 0x6e, 0x9e, 0xe5,
+ 0x86, 0x46, 0xc3, 0xef, 0x8d, 0xab, 0xc5, 0x40};
+#endif
+#if SM4_128
+// source: https://tools.ietf.org/html/draft-ribose-cfrg-sm4-04#appendix-A.2
+const BYTE key_SM4128 [] = {
+ 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF,
+ 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10};
+const BYTE dataIn_SM4128 [] = {
+ 0xAA, 0xAA, 0xAA, 0xAA, 0xBB, 0xBB, 0xBB, 0xBB,
+ 0xCC, 0xCC, 0xCC, 0xCC, 0xDD, 0xDD, 0xDD, 0xDD,
+ 0xEE, 0xEE, 0xEE, 0xEE, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xAA, 0xAA, 0xAA, 0xAA, 0xBB, 0xBB, 0xBB, 0xBB};
+const BYTE dataOut_SM4128_ECB [] = {
+ 0x5E, 0xC8, 0x14, 0x3D, 0xE5, 0x09, 0xCF, 0xF7,
+ 0xB5, 0x17, 0x9F, 0x8F, 0x47, 0x4B, 0x86, 0x19,
+ 0x2F, 0x1D, 0x30, 0x5A, 0x7F, 0xB1, 0x7D, 0xF9,
+ 0x85, 0xF8, 0x1C, 0x84, 0x82, 0x19, 0x23, 0x04,
+ 0x00, 0x2A, 0x8A, 0x4E, 0xFA, 0x86, 0x3C, 0xCA,
+ 0xD0, 0x24, 0xAC, 0x03, 0x00, 0xBB, 0x40, 0xD2}
+const BYTE dataOut_SM4128_CBC [] = {
+ 0x78, 0xEB, 0xB1, 0x1C, 0xC4, 0x0B, 0x0A, 0x48,
+ 0x31, 0x2A, 0xAE, 0xB2, 0x04, 0x02, 0x44, 0xCB,
+ 0x4C, 0xB7, 0x01, 0x69, 0x51, 0x90, 0x92, 0x26,
+ 0x97, 0x9B, 0x0D, 0x15, 0xDC, 0x6A, 0x8F, 0x6D,
+ 0x40, 0xD8, 0x41, 0x32, 0xE9, 0x99, 0x74, 0xA4,
+ 0xA8, 0x80, 0x88, 0x68, 0x42, 0x07, 0x48, 0x59};
+const BYTE dataOut_SM4128_CFB [] = {
+ 0xAC, 0x32, 0x36, 0xCB, 0x86, 0x1D, 0xD3, 0x16,
+ 0xE6, 0x41, 0x3B, 0x4E, 0x3C, 0x75, 0x24, 0xB7,
+ 0x69, 0xD4, 0xC5, 0x4E, 0xD4, 0x33, 0xB9, 0xA0,
+ 0x34, 0x60, 0x09, 0xBE, 0xB3, 0x7B, 0x2B, 0x3F};
+const BYTE dataOut_SM4128_OFB [] = {
+ 0xAC, 0x32, 0x36, 0xCB, 0x86, 0x1D, 0xD3, 0x16,
+ 0xE6, 0x41, 0x3B, 0x4E, 0x3C, 0x75, 0x24, 0xB7,
+ 0x1D, 0x01, 0xAC, 0xA2, 0x48, 0x7C, 0xA5, 0x82,
+ 0xCB, 0xF5, 0x46, 0x3E, 0x66, 0x98, 0x53, 0x9B};
+/* The data are obtained by running the commands as below:
+ echo "AAAAAAAABBBBBBBBCCCCCCCCDDDDDDDDEEEEEEEEFFFFFFFFAAAAAAAABBBBBBBB" | xxd -p -r > plain.txt
+ openssl enc -sm4-ctr -in plain.txt -iv "F0F1F2F3F4F5F6F7F8F9FAFBFCFDFEFF" -out out.txt -K "0123456789ABCDEFFEDCBA9876543210"
+*/
+const BYTE dataOut_SM4_CTR [] = {
+ 0xF4, 0x88, 0x4C, 0x6D, 0x39, 0x7E, 0x0B, 0x06,
+ 0x3D, 0xAC, 0xD9, 0x46, 0x1A, 0xA4, 0xA5, 0x6A,
+ 0x60, 0xDD, 0xA7, 0x5F, 0x86, 0xBC, 0xFE, 0xA4,
+ 0xF1, 0x5D, 0xB4, 0x6A, 0xD1, 0x4E, 0x7C, 0x7F};
+#endif
+// libtpms added end
+
+#endif
diff --git a/src/tpm2/TPMB.h b/src/tpm2/TPMB.h
new file mode 100644
index 0000000..8559b17
--- /dev/null
+++ b/src/tpm2/TPMB.h
@@ -0,0 +1,97 @@
+/********************************************************************************/
+/* */
+/* This file contains extra TPM2B structures */
+/* Written by Ken Goldman */
+/* IBM Thomas J. Watson Research Center */
+/* $Id: TPMB.h 1521 2019-11-15 21:00:47Z kgoldman $ */
+/* */
+/* Licenses and Notices */
+/* */
+/* 1. Copyright Licenses: */
+/* */
+/* - Trusted Computing Group (TCG) grants to the user of the source code in */
+/* this specification (the "Source Code") a worldwide, irrevocable, */
+/* nonexclusive, royalty free, copyright license to reproduce, create */
+/* derivative works, distribute, display and perform the Source Code and */
+/* derivative works thereof, and to grant others the rights granted herein. */
+/* */
+/* - The TCG grants to the user of the other parts of the specification */
+/* (other than the Source Code) the rights to reproduce, distribute, */
+/* display, and perform the specification solely for the purpose of */
+/* developing products based on such documents. */
+/* */
+/* 2. Source Code Distribution Conditions: */
+/* */
+/* - Redistributions of Source Code must retain the above copyright licenses, */
+/* this list of conditions and the following disclaimers. */
+/* */
+/* - Redistributions in binary form must reproduce the above copyright */
+/* licenses, this list of conditions and the following disclaimers in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* 3. Disclaimers: */
+/* */
+/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
+/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
+/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
+/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
+/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
+/* information on specification licensing rights available through TCG */
+/* membership agreements. */
+/* */
+/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
+/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
+/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
+/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
+/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
+/* */
+/* - Without limitation, TCG and its members and licensors disclaim all */
+/* liability, including liability for infringement of any proprietary */
+/* rights, relating to use of information in this specification and to the */
+/* implementation of this specification, and TCG disclaims all liability for */
+/* cost of procurement of substitute goods or services, lost profits, loss */
+/* of use, loss of data or any incidental, consequential, direct, indirect, */
+/* or special damages, whether under contract, tort, warranty or otherwise, */
+/* arising in any way out of use or reliance upon this specification or any */
+/* information herein. */
+/* */
+/* (c) Copyright IBM Corp. and others, 2016 - 2019 */
+/* */
+/********************************************************************************/
+
+#ifndef TPMB_H
+#define TPMB_H
+
+/* 5.17 TPMB.h */
+/* This file contains extra TPM2B structures */
+
+/* TPM2B Types */
+typedef struct {
+ UINT16 size;
+ BYTE buffer[1];
+} TPM2B, *P2B;
+typedef const TPM2B *PC2B;
+
+/* This macro helps avoid having to type in the structure in order to create a new TPM2B type that
+ is used in a function. */
+
+#define TPM2B_TYPE(name, bytes) \
+ typedef union { \
+ struct { \
+ UINT16 size; \
+ BYTE buffer[(bytes)]; \
+ } t; \
+ TPM2B b; \
+ } TPM2B_##name
+
+/* This macro defines a TPM2B with a constant character value. This macro sets the size of the
+ string to the size minus the terminating zero byte. This lets the user of the label add their
+ terminating 0. This method is chosen so that existing code that provides a label will continue to
+ work correctly. Macro to instance and initialize a TPM2B value */
+#define TPM2B_INIT(TYPE, name) \
+ TPM2B_##TYPE name = {sizeof(name.t.buffer), {0}}
+#define TPM2B_BYTE_VALUE(bytes) TPM2B_TYPE(bytes##_BYTE_VALUE, bytes)
+
+#endif
+
+
diff --git a/src/tpm2/TPMCmdp.c b/src/tpm2/TPMCmdp.c
new file mode 100644
index 0000000..041b780
--- /dev/null
+++ b/src/tpm2/TPMCmdp.c
@@ -0,0 +1,364 @@
+/********************************************************************************/
+/* */
+/* Process the commands */
+/* Written by Ken Goldman */
+/* IBM Thomas J. Watson Research Center */
+/* $Id: TPMCmdp.c 1658 2021-01-22 23:14:01Z kgoldman $ */
+/* */
+/* Licenses and Notices */
+/* */
+/* 1. Copyright Licenses: */
+/* */
+/* - Trusted Computing Group (TCG) grants to the user of the source code in */
+/* this specification (the "Source Code") a worldwide, irrevocable, */
+/* nonexclusive, royalty free, copyright license to reproduce, create */
+/* derivative works, distribute, display and perform the Source Code and */
+/* derivative works thereof, and to grant others the rights granted herein. */
+/* */
+/* - The TCG grants to the user of the other parts of the specification */
+/* (other than the Source Code) the rights to reproduce, distribute, */
+/* display, and perform the specification solely for the purpose of */
+/* developing products based on such documents. */
+/* */
+/* 2. Source Code Distribution Conditions: */
+/* */
+/* - Redistributions of Source Code must retain the above copyright licenses, */
+/* this list of conditions and the following disclaimers. */
+/* */
+/* - Redistributions in binary form must reproduce the above copyright */
+/* licenses, this list of conditions and the following disclaimers in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* 3. Disclaimers: */
+/* */
+/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
+/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
+/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
+/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
+/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
+/* information on specification licensing rights available through TCG */
+/* membership agreements. */
+/* */
+/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
+/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
+/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
+/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
+/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
+/* */
+/* - Without limitation, TCG and its members and licensors disclaim all */
+/* liability, including liability for infringement of any proprietary */
+/* rights, relating to use of information in this specification and to the */
+/* implementation of this specification, and TCG disclaims all liability for */
+/* cost of procurement of substitute goods or services, lost profits, loss */
+/* of use, loss of data or any incidental, consequential, direct, indirect, */
+/* or special damages, whether under contract, tort, warranty or otherwise, */
+/* arising in any way out of use or reliance upon this specification or any */
+/* information herein. */
+/* */
+/* (c) Copyright IBM Corp. and others, 2016 - 2021 */
+/* */
+/********************************************************************************/
+
+/* D.4 TPMCmdp.c */
+/* D.4.1. Description */
+/* This file contains the functions that process the commands received on the control port or the
+ command port of the simulator. The control port is used to allow simulation of hardware events
+ (such as, _TPM_Hash_Start()) to test the simulated TPM's reaction to those events. This improves
+ code coverage of the testing. */
+/* D.4.2. Includes and Data Definitions */
+#include <stdlib.h>
+#include <stdio.h>
+#include <setjmp.h>
+#include <stdbool.h>
+#include "TpmBuildSwitches.h"
+#ifdef TPM_WINDOWS
+#include <windows.h>
+#include <winsock.h>
+#endif
+#include "Platform_fp.h"
+#include "PlatformACT_fp.h"
+#include "ExecCommand_fp.h"
+#include "Manufacture_fp.h"
+#include "_TPM_Init_fp.h"
+#include "_TPM_Hash_Start_fp.h"
+#include "_TPM_Hash_Data_fp.h"
+#include "_TPM_Hash_End_fp.h"
+#include "TpmFail_fp.h"
+#include "TpmTcpProtocol.h"
+#include "Simulator_fp.h"
+#ifdef TPM_WINDOWS
+#include "TcpServer_fp.h" /* kgold */
+#endif
+#ifdef TPM_POSIX
+#include "TcpServerPosix_fp.h" /* kgold */
+#endif
+#include "TpmProfile.h" /* kgold */
+
+static bool s_isPowerOn = false;
+/* D.4.3. Functions */
+/* D.4.3.1. Signal_PowerOn() */
+/* This function processes a power-on indication. Among other things, it calls the _TPM_Init()
+ handler. */
+void
+_rpc__Signal_PowerOn(
+ bool isReset
+ )
+{
+ // if power is on and this is not a call to do TPM reset then return
+ if(s_isPowerOn && !isReset)
+ return;
+ // If this is a reset but power is not on, then return
+ if(isReset && !s_isPowerOn)
+ return;
+ // Unless this is just a reset, pass power on signal to platform
+ if(!isReset)
+ _plat__Signal_PowerOn();
+ // Power on and reset both lead to _TPM_Init()
+ _plat__Signal_Reset();
+ // Set state as power on
+ s_isPowerOn = true;
+}
+#if 0 /* libtpms added */
+/* D.4.3.2. Signal_Restart() */
+/* This function processes the clock restart indication. All it does is call the platform
+ function. */
+void
+_rpc__Signal_Restart(
+ void
+ )
+{
+ _plat__TimerRestart();
+}
+#endif /* libtpms added */
+/* D.4.3.3. Signal_PowerOff() */
+/* This function processes the power off indication. Its primary function is to set a flag
+ indicating that the next power on indication should cause _TPM_Init() to be called. */
+void
+_rpc__Signal_PowerOff(
+ void
+ )
+{
+ if(s_isPowerOn)
+ // Pass power off signal to platform
+ _plat__Signal_PowerOff();
+ // This could be redundant, but...
+ s_isPowerOn = false;
+ return;
+}
+#if 0 /* libtpms added */
+/* D.4.3.4. _rpc__ForceFailureMode() */
+/* This function is used to debug the Failure Mode logic of the TPM. It will set a flag in the TPM
+ code such that the next call to TPM2_SelfTest() will result in a failure, putting the TPM into
+ Failure Mode. */
+void
+_rpc__ForceFailureMode(
+ void
+ )
+{
+ SetForceFailureMode();
+ return;
+}
+/* D.4.3.5. _rpc__Signal_PhysicalPresenceOn() */
+/* This function is called to simulate activation of the physical presence pin. */
+void
+_rpc__Signal_PhysicalPresenceOn(
+ void
+ )
+{
+ // If TPM power is on
+ if(s_isPowerOn)
+ // Pass physical presence on to platform
+ _plat__Signal_PhysicalPresenceOn();
+ return;
+}
+/* D.4.3.6. _rpc__Signal_PhysicalPresenceOff() */
+/* This function is called to simulate deactivation of the physical presence pin. */
+void
+_rpc__Signal_PhysicalPresenceOff(
+ void
+ )
+{
+ // If TPM power is on
+ if(s_isPowerOn)
+ // Pass physical presence off to platform
+ _plat__Signal_PhysicalPresenceOff();
+ return;
+}
+/* D.4.3.7. _rpc__Signal_Hash_Start() */
+/* This function is called to simulate a _TPM_Hash_Start() event. It will call */
+void
+_rpc__Signal_Hash_Start(
+ void
+ )
+{
+ // If TPM power is on
+ if(s_isPowerOn)
+ // Pass _TPM_Hash_Start signal to TPM
+ _TPM_Hash_Start();
+ return;
+}
+/* D.4.3.8. _rpc__Signal_Hash_Data() */
+/* This function is called to simulate a _TPM_Hash_Data() event. */
+void
+_rpc__Signal_Hash_Data(
+ _IN_BUFFER input
+ )
+{
+ // If TPM power is on
+ if(s_isPowerOn)
+ // Pass _TPM_Hash_Data signal to TPM
+ _TPM_Hash_Data(input.BufferSize, input.Buffer);
+ return;
+}
+/* D.4.3.9. _rpc__Signal_HashEnd() */
+/* This function is called to simulate a _TPM_Hash_End() event. */
+void
+_rpc__Signal_HashEnd(
+ void
+ )
+{
+ // If TPM power is on
+ if(s_isPowerOn)
+ // Pass _TPM_HashEnd signal to TPM
+ _TPM_Hash_End();
+ return;
+}
+#endif /* libtpms added */
+/* D.4.3.10. rpc_Send_Command() */
+/* This is the interface to the TPM code. */
+void
+_rpc__Send_Command(
+ unsigned char locality,
+ _IN_BUFFER request,
+ _OUT_BUFFER *response
+ )
+{
+ // If TPM is power off, reject any commands.
+ if(!s_isPowerOn)
+ {
+ response->BufferSize = 0;
+ return;
+ }
+ // Set the locality of the command so that it doesn't change during the command
+ _plat__LocalitySet(locality);
+ // Do implementation-specific command dispatch
+ _plat__RunCommand(request.BufferSize, request.Buffer,
+ &response->BufferSize, &response->Buffer);
+ return;
+}
+/* D.4.3.10. _rpc__Signal_CancelOn() */
+/* This function is used to turn on the indication to cancel a command in process. An executing
+ command is not interrupted. The command code may periodically check this indication to see if it
+ should abort the current command processing and returned TPM_RC_CANCELLED. */
+void
+_rpc__Signal_CancelOn(
+ void
+ )
+{
+ // If TPM is power off, reject this signal
+ if(s_isPowerOn)
+ // Set the platform canceling flag.
+ _plat__SetCancel();
+ return;
+}
+/* D.4.3.11. _rpc__Signal_CancelOff() */
+/* This function is used to turn off the indication to cancel a command in process. */
+void
+_rpc__Signal_CancelOff(
+ void
+ )
+{
+ // If TPM power is n
+ if(s_isPowerOn)
+ // Set the platform canceling flag.
+ _plat__ClearCancel();
+ return;
+}
+/* D.4.3.12. _rpc__Signal_NvOn() */
+/* In a system where the NV memory used by the TPM is not within the TPM, the NV may not always be
+ available. This function turns on the indicator that indicates that NV is available. */
+void
+_rpc__Signal_NvOn(
+ void
+ )
+{
+ // If TPM power is on
+ if(s_isPowerOn)
+ // Make the NV available
+ _plat__SetNvAvail();
+ return;
+}
+#if 0 /* libtpms added */
+/* D.4.3.13. _rpc__Signal_NvOff() */
+/* This function is used to set the indication that NV memory is no longer available. */
+void
+_rpc__Signal_NvOff(
+ void
+ )
+{
+ // If TPM power is on
+ if(s_isPowerOn)
+ // Make NV not available
+ _plat__ClearNvAvail();
+ return;
+}
+void RsaKeyCacheControl(int state);
+/* D.4.3.14. _rpc__RsaKeyCacheControl() */
+/* This function is used to enable/disable the use of the RSA key cache during simulation. */
+void
+_rpc__RsaKeyCacheControl(
+ int state
+ )
+{
+#if USE_RSA_KEY_CACHE
+ RsaKeyCacheControl(state);
+#else
+ NOT_REFERENCED(state);
+#endif
+}
+
+#define TPM_RH_ACT_0 0x40000110
+
+/* D.4.2.15. _rpc__ACT_GetSignaled() */
+/* This function is used to count the ACT second tick. */
+bool
+_rpc__ACT_GetSignaled(
+ uint32_t actHandle
+ )
+{
+ // If TPM power is on
+ if (s_isPowerOn)
+ // Query the platform
+ return _plat__ACT_GetSignaled(actHandle - TPM_RH_ACT_0);
+ return false;
+}
+#endif /* libtpms added */
+
+/* libtpms added begin */
+static bool tpmEstablished;
+
+void
+_rpc__Signal_SetTPMEstablished(void)
+{
+ tpmEstablished = TRUE;
+}
+
+void
+_rpc__Signal_ResetTPMEstablished(void)
+{
+ /* check for locality 3 or 4 already done by caller */
+ tpmEstablished = FALSE;
+}
+
+bool
+_rpc__Signal_GetTPMEstablished(void)
+{
+ return tpmEstablished;
+}
+
+bool
+_rpc__Signal_IsPowerOn(void)
+{
+ return s_isPowerOn;
+}
+/* libtpms added end */
diff --git a/src/tpm2/TcpServerPosix_fp.h b/src/tpm2/TcpServerPosix_fp.h
new file mode 100644
index 0000000..d984130
--- /dev/null
+++ b/src/tpm2/TcpServerPosix_fp.h
@@ -0,0 +1,131 @@
+/********************************************************************************/
+/* */
+/* Socket Interface to a TPM Simulator */
+/* Written by Ken Goldman */
+/* IBM Thomas J. Watson Research Center */
+/* $Id: TcpServerPosix_fp.h 1658 2021-01-22 23:14:01Z kgoldman $ */
+/* */
+/* Licenses and Notices */
+/* */
+/* 1. Copyright Licenses: */
+/* */
+/* - Trusted Computing Group (TCG) grants to the user of the source code in */
+/* this specification (the "Source Code") a worldwide, irrevocable, */
+/* nonexclusive, royalty free, copyright license to reproduce, create */
+/* derivative works, distribute, display and perform the Source Code and */
+/* derivative works thereof, and to grant others the rights granted herein. */
+/* */
+/* - The TCG grants to the user of the other parts of the specification */
+/* (other than the Source Code) the rights to reproduce, distribute, */
+/* display, and perform the specification solely for the purpose of */
+/* developing products based on such documents. */
+/* */
+/* 2. Source Code Distribution Conditions: */
+/* */
+/* - Redistributions of Source Code must retain the above copyright licenses, */
+/* this list of conditions and the following disclaimers. */
+/* */
+/* - Redistributions in binary form must reproduce the above copyright */
+/* licenses, this list of conditions and the following disclaimers in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* 3. Disclaimers: */
+/* */
+/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
+/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
+/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
+/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
+/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
+/* information on specification licensing rights available through TCG */
+/* membership agreements. */
+/* */
+/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
+/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
+/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
+/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
+/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
+/* */
+/* - Without limitation, TCG and its members and licensors disclaim all */
+/* liability, including liability for infringement of any proprietary */
+/* rights, relating to use of information in this specification and to the */
+/* implementation of this specification, and TCG disclaims all liability for */
+/* cost of procurement of substitute goods or services, lost profits, loss */
+/* of use, loss of data or any incidental, consequential, direct, indirect, */
+/* or special damages, whether under contract, tort, warranty or otherwise, */
+/* arising in any way out of use or reliance upon this specification or any */
+/* information herein. */
+/* */
+/* (c) Copyright IBM Corp. and others, 2016 - 2021 */
+/* */
+/********************************************************************************/
+
+#ifndef TCPSERVERPOSIX_FP_H
+#define TCPSERVERPOSIX_FP_H
+
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <pthread.h>
+
+#include "CompilerDependencies.h"
+#include "BaseTypes.h"
+
+bool
+PlatformServer(
+ SOCKET s
+ );
+int
+PlatformSvcRoutine(
+ void *port
+ );
+int
+PlatformSignalService(
+ int *PortNumberPlatform
+ );
+int
+RegularCommandService(
+ int *PortNumber
+ );
+int
+StartTcpServer(
+ int *PortNumber,
+ int *PortNumberPlatform
+ );
+bool
+ReadBytes(
+ SOCKET s,
+ char *buffer,
+ int NumBytes
+ );
+bool
+WriteBytes(
+ SOCKET s,
+ char *buffer,
+ int NumBytes
+ );
+bool
+WriteUINT32(
+ SOCKET s,
+ UINT32 val
+ );
+bool
+ReadVarBytes(
+ SOCKET s,
+ char *buffer,
+ UINT32 *BytesReceived,
+ int MaxLen
+ );
+bool
+WriteVarBytes(
+ SOCKET s,
+ char *buffer,
+ int BytesToSend
+ );
+bool
+TpmServer(
+ SOCKET s
+ );
+
+
+#endif
diff --git a/src/tpm2/TestParms_fp.h b/src/tpm2/TestParms_fp.h
new file mode 100644
index 0000000..c71f67e
--- /dev/null
+++ b/src/tpm2/TestParms_fp.h
@@ -0,0 +1,79 @@
+/********************************************************************************/
+/* */
+/* */
+/* Written by Ken Goldman */
+/* IBM Thomas J. Watson Research Center */
+/* $Id: TestParms_fp.h 809 2016-11-16 18:31:54Z kgoldman $ */
+/* */
+/* Licenses and Notices */
+/* */
+/* 1. Copyright Licenses: */
+/* */
+/* - Trusted Computing Group (TCG) grants to the user of the source code in */
+/* this specification (the "Source Code") a worldwide, irrevocable, */
+/* nonexclusive, royalty free, copyright license to reproduce, create */
+/* derivative works, distribute, display and perform the Source Code and */
+/* derivative works thereof, and to grant others the rights granted herein. */
+/* */
+/* - The TCG grants to the user of the other parts of the specification */
+/* (other than the Source Code) the rights to reproduce, distribute, */
+/* display, and perform the specification solely for the purpose of */
+/* developing products based on such documents. */
+/* */
+/* 2. Source Code Distribution Conditions: */
+/* */
+/* - Redistributions of Source Code must retain the above copyright licenses, */
+/* this list of conditions and the following disclaimers. */
+/* */
+/* - Redistributions in binary form must reproduce the above copyright */
+/* licenses, this list of conditions and the following disclaimers in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* 3. Disclaimers: */
+/* */
+/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
+/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
+/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
+/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
+/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
+/* information on specification licensing rights available through TCG */
+/* membership agreements. */
+/* */
+/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
+/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
+/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
+/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
+/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
+/* */
+/* - Without limitation, TCG and its members and licensors disclaim all */
+/* liability, including liability for infringement of any proprietary */
+/* rights, relating to use of information in this specification and to the */
+/* implementation of this specification, and TCG disclaims all liability for */
+/* cost of procurement of substitute goods or services, lost profits, loss */
+/* of use, loss of data or any incidental, consequential, direct, indirect, */
+/* or special damages, whether under contract, tort, warranty or otherwise, */
+/* arising in any way out of use or reliance upon this specification or any */
+/* information herein. */
+/* */
+/* (c) Copyright IBM Corp. and others, 2012-2015 */
+/* */
+/********************************************************************************/
+
+/* rev 119 */
+
+#ifndef TESTPARMS_FP_H
+#define TESTPARMS_FP_H
+
+typedef struct {
+ TPMT_PUBLIC_PARMS parameters;
+} TestParms_In;
+
+#define RC_TestParms_parameters (TPM_RC_P + TPM_RC_1)
+
+TPM_RC
+TPM2_TestParms(
+ TestParms_In *in // IN: input parameter list
+ );
+
+
+#endif
diff --git a/src/tpm2/TestingCommands.c b/src/tpm2/TestingCommands.c
new file mode 100644
index 0000000..27a2352
--- /dev/null
+++ b/src/tpm2/TestingCommands.c
@@ -0,0 +1,108 @@
+/********************************************************************************/
+/* */
+/* */
+/* Written by Ken Goldman */
+/* IBM Thomas J. Watson Research Center */
+/* $Id: TestingCommands.c 1490 2019-07-26 21:13:22Z kgoldman $ */
+/* */
+/* Licenses and Notices */
+/* */
+/* 1. Copyright Licenses: */
+/* */
+/* - Trusted Computing Group (TCG) grants to the user of the source code in */
+/* this specification (the "Source Code") a worldwide, irrevocable, */
+/* nonexclusive, royalty free, copyright license to reproduce, create */
+/* derivative works, distribute, display and perform the Source Code and */
+/* derivative works thereof, and to grant others the rights granted herein. */
+/* */
+/* - The TCG grants to the user of the other parts of the specification */
+/* (other than the Source Code) the rights to reproduce, distribute, */
+/* display, and perform the specification solely for the purpose of */
+/* developing products based on such documents. */
+/* */
+/* 2. Source Code Distribution Conditions: */
+/* */
+/* - Redistributions of Source Code must retain the above copyright licenses, */
+/* this list of conditions and the following disclaimers. */
+/* */
+/* - Redistributions in binary form must reproduce the above copyright */
+/* licenses, this list of conditions and the following disclaimers in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* 3. Disclaimers: */
+/* */
+/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
+/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
+/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
+/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
+/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
+/* information on specification licensing rights available through TCG */
+/* membership agreements. */
+/* */
+/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
+/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
+/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
+/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
+/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
+/* */
+/* - Without limitation, TCG and its members and licensors disclaim all */
+/* liability, including liability for infringement of any proprietary */
+/* rights, relating to use of information in this specification and to the */
+/* implementation of this specification, and TCG disclaims all liability for */
+/* cost of procurement of substitute goods or services, lost profits, loss */
+/* of use, loss of data or any incidental, consequential, direct, indirect, */
+/* or special damages, whether under contract, tort, warranty or otherwise, */
+/* arising in any way out of use or reliance upon this specification or any */
+/* information herein. */
+/* */
+/* (c) Copyright IBM Corp. and others, 2016-2018 */
+/* */
+/********************************************************************************/
+
+#include "Tpm.h"
+#include "SelfTest_fp.h"
+#if CC_SelfTest // Conditional expansion of this file
+TPM_RC
+TPM2_SelfTest(
+ SelfTest_In *in // IN: input parameter list
+ )
+{
+ // Command Output
+ // Call self test function in crypt module
+ return CryptSelfTest(in->fullTest);
+}
+#endif // CC_SelfTest
+#include "Tpm.h"
+#include "IncrementalSelfTest_fp.h"
+#if CC_IncrementalSelfTest // Conditional expansion of this file
+TPM_RC
+TPM2_IncrementalSelfTest(
+ IncrementalSelfTest_In *in, // IN: input parameter list
+ IncrementalSelfTest_Out *out // OUT: output parameter list
+ )
+{
+ TPM_RC result;
+ // Command Output
+ // Call incremental self test function in crypt module. If this function
+ // returns TPM_RC_VALUE, it means that an algorithm on the 'toTest' list is
+ // not implemented.
+ result = CryptIncrementalSelfTest(&in->toTest, &out->toDoList);
+ if(result == TPM_RC_VALUE)
+ return TPM_RCS_VALUE + RC_IncrementalSelfTest_toTest;
+ return result;
+}
+#endif // CC_IncrementalSelfTest
+#include "Tpm.h"
+#include "GetTestResult_fp.h"
+#if CC_GetTestResult // Conditional expansion of this file
+TPM_RC
+TPM2_GetTestResult(
+ GetTestResult_Out *out // OUT: output parameter list
+ )
+{
+ // Command Output
+ // Call incremental self test function in crypt module
+ out->testResult = CryptGetTestResult(&out->outData);
+ return TPM_RC_SUCCESS;
+}
+#endif // CC_GetTestResult
diff --git a/src/tpm2/Ticket.c b/src/tpm2/Ticket.c
new file mode 100644
index 0000000..cceac8d
--- /dev/null
+++ b/src/tpm2/Ticket.c
@@ -0,0 +1,236 @@
+/********************************************************************************/
+/* */
+/* Functions used for ticket computations. */
+/* Written by Ken Goldman */
+/* IBM Thomas J. Watson Research Center */
+/* $Id: Ticket.c 1594 2020-03-26 22:15:48Z kgoldman $ */
+/* */
+/* Licenses and Notices */
+/* */
+/* 1. Copyright Licenses: */
+/* */
+/* - Trusted Computing Group (TCG) grants to the user of the source code in */
+/* this specification (the "Source Code") a worldwide, irrevocable, */
+/* nonexclusive, royalty free, copyright license to reproduce, create */
+/* derivative works, distribute, display and perform the Source Code and */
+/* derivative works thereof, and to grant others the rights granted herein. */
+/* */
+/* - The TCG grants to the user of the other parts of the specification */
+/* (other than the Source Code) the rights to reproduce, distribute, */
+/* display, and perform the specification solely for the purpose of */
+/* developing products based on such documents. */
+/* */
+/* 2. Source Code Distribution Conditions: */
+/* */
+/* - Redistributions of Source Code must retain the above copyright licenses, */
+/* this list of conditions and the following disclaimers. */
+/* */
+/* - Redistributions in binary form must reproduce the above copyright */
+/* licenses, this list of conditions and the following disclaimers in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* 3. Disclaimers: */
+/* */
+/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
+/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
+/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
+/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
+/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
+/* information on specification licensing rights available through TCG */
+/* membership agreements. */
+/* */
+/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
+/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
+/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
+/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
+/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
+/* */
+/* - Without limitation, TCG and its members and licensors disclaim all */
+/* liability, including liability for infringement of any proprietary */
+/* rights, relating to use of information in this specification and to the */
+/* implementation of this specification, and TCG disclaims all liability for */
+/* cost of procurement of substitute goods or services, lost profits, loss */
+/* of use, loss of data or any incidental, consequential, direct, indirect, */
+/* or special damages, whether under contract, tort, warranty or otherwise, */
+/* arising in any way out of use or reliance upon this specification or any */
+/* information herein. */
+/* */
+/* (c) Copyright IBM Corp. and others, 2016 - 2020 */
+/* */
+/********************************************************************************/
+
+/* 10.2.23 Ticket.c */
+/* 10.2.23.1 Introduction */
+/* This clause contains the functions used for ticket computations. */
+/* 10.2.23.2 Includes */
+#include "Tpm.h"
+/* 10.2.23.3 Functions */
+/* 10.2.23.3.1 TicketIsSafe() */
+/* This function indicates if producing a ticket is safe. It checks if the leading bytes of an input
+ buffer is TPM_GENERATED_VALUE or its substring of canonical form. If so, it is not safe to
+ produce ticket for an input buffer claiming to be TPM generated buffer */
+/* Return Values Meaning */
+/* TRUE It is safe to produce ticket */
+/* FALSE It is not safe to produce ticket */
+BOOL
+TicketIsSafe(
+ TPM2B *buffer
+ )
+{
+ TPM_CONSTANTS32 valueToCompare = TPM_GENERATED_VALUE;
+ BYTE bufferToCompare[sizeof(valueToCompare)];
+ BYTE *marshalBuffer;
+ //
+ // If the buffer size is less than the size of TPM_GENERATED_VALUE, assume
+ // it is not safe to generate a ticket
+ if(buffer->size < sizeof(valueToCompare))
+ return FALSE;
+ marshalBuffer = bufferToCompare;
+ TPM_CONSTANTS32_Marshal(&valueToCompare, &marshalBuffer, NULL);
+ if(MemoryEqual(buffer->buffer, bufferToCompare, sizeof(valueToCompare)))
+ return FALSE;
+ else
+ return TRUE;
+}
+/* 10.2.23.3.2 TicketComputeVerified() */
+/* This function creates a TPMT_TK_VERIFIED ticket. */
+void
+TicketComputeVerified(
+ TPMI_RH_HIERARCHY hierarchy, // IN: hierarchy constant for ticket
+ TPM2B_DIGEST *digest, // IN: digest
+ TPM2B_NAME *keyName, // IN: name of key that signed the values
+ TPMT_TK_VERIFIED *ticket // OUT: verified ticket
+ )
+{
+ TPM2B_PROOF *proof;
+ HMAC_STATE hmacState;
+ //
+ // Fill in ticket fields
+ ticket->tag = TPM_ST_VERIFIED;
+ ticket->hierarchy = hierarchy;
+ proof = HierarchyGetProof(hierarchy);
+ // Start HMAC using the proof value of the hierarchy as the HMAC key
+ ticket->digest.t.size = CryptHmacStart2B(&hmacState, CONTEXT_INTEGRITY_HASH_ALG,
+ &proof->b);
+ // TPM_ST_VERIFIED
+ CryptDigestUpdateInt(&hmacState, sizeof(TPM_ST), ticket->tag);
+ // digest
+ CryptDigestUpdate2B(&hmacState.hashState, &digest->b);
+ // key name
+ CryptDigestUpdate2B(&hmacState.hashState, &keyName->b);
+ // done
+ CryptHmacEnd2B(&hmacState, &ticket->digest.b);
+ return;
+}
+/* 10.2.23.3.3 TicketComputeAuth() */
+/* This function creates a TPMT_TK_AUTH ticket. */
+void
+TicketComputeAuth(
+ TPM_ST type, // IN: the type of ticket.
+ TPMI_RH_HIERARCHY hierarchy, // IN: hierarchy constant for ticket
+ UINT64 timeout, // IN: timeout
+ BOOL expiresOnReset,// IN: flag to indicate if ticket expires on
+ // TPM Reset
+ TPM2B_DIGEST *cpHashA, // IN: input cpHashA
+ TPM2B_NONCE *policyRef, // IN: input policyRef
+ TPM2B_NAME *entityName, // IN: name of entity
+ TPMT_TK_AUTH *ticket // OUT: Created ticket
+ )
+{
+ TPM2B_PROOF *proof;
+ HMAC_STATE hmacState;
+ //
+ // Get proper proof
+ proof = HierarchyGetProof(hierarchy);
+ // Fill in ticket fields
+ ticket->tag = type;
+ ticket->hierarchy = hierarchy;
+ // Start HMAC with hierarchy proof as the HMAC key
+ ticket->digest.t.size = CryptHmacStart2B(&hmacState, CONTEXT_INTEGRITY_HASH_ALG,
+ &proof->b);
+ // TPM_ST_AUTH_SECRET or TPM_ST_AUTH_SIGNED,
+ CryptDigestUpdateInt(&hmacState, sizeof(UINT16), ticket->tag);
+ // cpHash
+ CryptDigestUpdate2B(&hmacState.hashState, &cpHashA->b);
+ // policyRef
+ CryptDigestUpdate2B(&hmacState.hashState, &policyRef->b);
+ // keyName
+ CryptDigestUpdate2B(&hmacState.hashState, &entityName->b);
+ // timeout
+ CryptDigestUpdateInt(&hmacState, sizeof(timeout), timeout);
+ if(timeout != 0)
+ {
+ // epoch
+ CryptDigestUpdateInt(&hmacState.hashState, sizeof(CLOCK_NONCE),
+ g_timeEpoch);
+ // reset count
+ if(expiresOnReset)
+ CryptDigestUpdateInt(&hmacState.hashState, sizeof(gp.totalResetCount),
+ gp.totalResetCount);
+ }
+ // done
+ CryptHmacEnd2B(&hmacState, &ticket->digest.b);
+ return;
+}
+/* 10.2.23.3.4 TicketComputeHashCheck() */
+/* This function creates a TPMT_TK_HASHCHECK ticket. */
+void
+TicketComputeHashCheck(
+ TPMI_RH_HIERARCHY hierarchy, // IN: hierarchy constant for ticket
+ TPM_ALG_ID hashAlg, // IN: the hash algorithm for 'digest'
+ TPM2B_DIGEST *digest, // IN: input digest
+ TPMT_TK_HASHCHECK *ticket // OUT: Created ticket
+ )
+{
+ TPM2B_PROOF *proof;
+ HMAC_STATE hmacState;
+ //
+ // Get proper proof
+ proof = HierarchyGetProof(hierarchy);
+ // Fill in ticket fields
+ ticket->tag = TPM_ST_HASHCHECK;
+ ticket->hierarchy = hierarchy;
+ // Start HMAC using hierarchy proof as HMAC key
+ ticket->digest.t.size = CryptHmacStart2B(&hmacState, CONTEXT_INTEGRITY_HASH_ALG,
+ &proof->b);
+ // TPM_ST_HASHCHECK
+ CryptDigestUpdateInt(&hmacState, sizeof(TPM_ST), ticket->tag);
+ // hash algorithm
+ CryptDigestUpdateInt(&hmacState, sizeof(hashAlg), hashAlg);
+ // digest
+ CryptDigestUpdate2B(&hmacState.hashState, &digest->b);
+ // done
+ CryptHmacEnd2B(&hmacState, &ticket->digest.b);
+ return;
+}
+/* 10.2.23.3.5 TicketComputeCreation() */
+/* This function creates a TPMT_TK_CREATION ticket. */
+void
+TicketComputeCreation(
+ TPMI_RH_HIERARCHY hierarchy, // IN: hierarchy for ticket
+ TPM2B_NAME *name, // IN: object name
+ TPM2B_DIGEST *creation, // IN: creation hash
+ TPMT_TK_CREATION *ticket // OUT: created ticket
+ )
+{
+ TPM2B_PROOF *proof;
+ HMAC_STATE hmacState;
+ // Get proper proof
+ proof = HierarchyGetProof(hierarchy);
+ // Fill in ticket fields
+ ticket->tag = TPM_ST_CREATION;
+ ticket->hierarchy = hierarchy;
+ // Start HMAC using hierarchy proof as HMAC key
+ ticket->digest.t.size = CryptHmacStart2B(&hmacState, CONTEXT_INTEGRITY_HASH_ALG,
+ &proof->b);
+ // TPM_ST_CREATION
+ CryptDigestUpdateInt(&hmacState, sizeof(TPM_ST), ticket->tag);
+ // name if provided
+ if(name != NULL)
+ CryptDigestUpdate2B(&hmacState.hashState, &name->b);
+ // creation hash
+ CryptDigestUpdate2B(&hmacState.hashState, &creation->b);
+ // Done
+ CryptHmacEnd2B(&hmacState, &ticket->digest.b);
+ return;
+}
diff --git a/src/tpm2/Ticket_fp.h b/src/tpm2/Ticket_fp.h
new file mode 100644
index 0000000..78e5eb2
--- /dev/null
+++ b/src/tpm2/Ticket_fp.h
@@ -0,0 +1,104 @@
+/********************************************************************************/
+/* */
+/* */
+/* Written by Ken Goldman */
+/* IBM Thomas J. Watson Research Center */
+/* $Id: Ticket_fp.h 1490 2019-07-26 21:13:22Z kgoldman $ */
+/* */
+/* Licenses and Notices */
+/* */
+/* 1. Copyright Licenses: */
+/* */
+/* - Trusted Computing Group (TCG) grants to the user of the source code in */
+/* this specification (the "Source Code") a worldwide, irrevocable, */
+/* nonexclusive, royalty free, copyright license to reproduce, create */
+/* derivative works, distribute, display and perform the Source Code and */
+/* derivative works thereof, and to grant others the rights granted herein. */
+/* */
+/* - The TCG grants to the user of the other parts of the specification */
+/* (other than the Source Code) the rights to reproduce, distribute, */
+/* display, and perform the specification solely for the purpose of */
+/* developing products based on such documents. */
+/* */
+/* 2. Source Code Distribution Conditions: */
+/* */
+/* - Redistributions of Source Code must retain the above copyright licenses, */
+/* this list of conditions and the following disclaimers. */
+/* */
+/* - Redistributions in binary form must reproduce the above copyright */
+/* licenses, this list of conditions and the following disclaimers in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* 3. Disclaimers: */
+/* */
+/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
+/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
+/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
+/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
+/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
+/* information on specification licensing rights available through TCG */
+/* membership agreements. */
+/* */
+/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
+/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
+/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
+/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
+/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
+/* */
+/* - Without limitation, TCG and its members and licensors disclaim all */
+/* liability, including liability for infringement of any proprietary */
+/* rights, relating to use of information in this specification and to the */
+/* implementation of this specification, and TCG disclaims all liability for */
+/* cost of procurement of substitute goods or services, lost profits, loss */
+/* of use, loss of data or any incidental, consequential, direct, indirect, */
+/* or special damages, whether under contract, tort, warranty or otherwise, */
+/* arising in any way out of use or reliance upon this specification or any */
+/* information herein. */
+/* */
+/* (c) Copyright IBM Corp. and others, 2016 */
+/* */
+/********************************************************************************/
+
+#ifndef TICKET_FP_H
+#define TICKET_FP_H
+
+BOOL
+TicketIsSafe(
+ TPM2B *buffer
+ );
+void
+TicketComputeVerified(
+ TPMI_RH_HIERARCHY hierarchy, // IN: hierarchy constant for ticket
+ TPM2B_DIGEST *digest, // IN: digest
+ TPM2B_NAME *keyName, // IN: name of key that signed the values
+ TPMT_TK_VERIFIED *ticket // OUT: verified ticket
+ );
+void
+TicketComputeAuth(
+ TPM_ST type, // IN: the type of ticket.
+ TPMI_RH_HIERARCHY hierarchy, // IN: hierarchy constant for ticket
+ UINT64 timeout, // IN: timeout
+ BOOL expiresOnReset,// IN: flag to indicate if ticket expires on
+ // TPM Reset
+ TPM2B_DIGEST *cpHashA, // IN: input cpHashA
+ TPM2B_NONCE *policyRef, // IN: input policyRef
+ TPM2B_NAME *entityName, // IN: name of entity
+ TPMT_TK_AUTH *ticket // OUT: Created ticket
+ );
+void
+TicketComputeHashCheck(
+ TPMI_RH_HIERARCHY hierarchy, // IN: hierarchy constant for ticket
+ TPM_ALG_ID hashAlg, // IN: the hash algorithm for 'digest'
+ TPM2B_DIGEST *digest, // IN: input digest
+ TPMT_TK_HASHCHECK *ticket // OUT: Created ticket
+ );
+void
+TicketComputeCreation(
+ TPMI_RH_HIERARCHY hierarchy, // IN: hierarchy for ticket
+ TPM2B_NAME *name, // IN: object name
+ TPM2B_DIGEST *creation, // IN: creation hash
+ TPMT_TK_CREATION *ticket // OUT: created ticket
+ );
+
+
+#endif
diff --git a/src/tpm2/Time.c b/src/tpm2/Time.c
new file mode 100644
index 0000000..9ff1bb5
--- /dev/null
+++ b/src/tpm2/Time.c
@@ -0,0 +1,273 @@
+/********************************************************************************/
+/* */
+/* Functions relating to the TPM's time functions */
+/* Written by Ken Goldman */
+/* IBM Thomas J. Watson Research Center */
+/* $Id: Time.c 1519 2019-11-15 20:43:51Z kgoldman $ */
+/* */
+/* Licenses and Notices */
+/* */
+/* 1. Copyright Licenses: */
+/* */
+/* - Trusted Computing Group (TCG) grants to the user of the source code in */
+/* this specification (the "Source Code") a worldwide, irrevocable, */
+/* nonexclusive, royalty free, copyright license to reproduce, create */
+/* derivative works, distribute, display and perform the Source Code and */
+/* derivative works thereof, and to grant others the rights granted herein. */
+/* */
+/* - The TCG grants to the user of the other parts of the specification */
+/* (other than the Source Code) the rights to reproduce, distribute, */
+/* display, and perform the specification solely for the purpose of */
+/* developing products based on such documents. */
+/* */
+/* 2. Source Code Distribution Conditions: */
+/* */
+/* - Redistributions of Source Code must retain the above copyright licenses, */
+/* this list of conditions and the following disclaimers. */
+/* */
+/* - Redistributions in binary form must reproduce the above copyright */
+/* licenses, this list of conditions and the following disclaimers in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* 3. Disclaimers: */
+/* */
+/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
+/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
+/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
+/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
+/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
+/* information on specification licensing rights available through TCG */
+/* membership agreements. */
+/* */
+/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
+/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
+/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
+/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
+/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
+/* */
+/* - Without limitation, TCG and its members and licensors disclaim all */
+/* liability, including liability for infringement of any proprietary */
+/* rights, relating to use of information in this specification and to the */
+/* implementation of this specification, and TCG disclaims all liability for */
+/* cost of procurement of substitute goods or services, lost profits, loss */
+/* of use, loss of data or any incidental, consequential, direct, indirect, */
+/* or special damages, whether under contract, tort, warranty or otherwise, */
+/* arising in any way out of use or reliance upon this specification or any */
+/* information herein. */
+/* */
+/* (c) Copyright IBM Corp. and others, 2016 - 2019 */
+/* */
+/********************************************************************************/
+
+/* 8.10.1 Introduction */
+/* This file contains the functions relating to the TPM's time functions including the interface to
+ the implementation-specific time functions. */
+/* 8.10.2 Includes */
+#include "Tpm.h"
+#include "PlatformClock.h"
+/* 8.10.3 Functions */
+/* 8.10.3.1 TimePowerOn() */
+/* This function initialize time info at _TPM_Init(). */
+/* This function is called at _TPM_Init() so that the TPM time can start counting as soon as the TPM
+ comes out of reset and doesn't have to wait until TPM2_Startup() in order to begin the new time
+ epoch. This could be significant for systems that could get powered up but not run any TPM
+ commands for some period of time. */
+void
+TimePowerOn(
+ void
+ )
+{
+ g_time = _plat__TimerRead();
+}
+/* 8.10.3.2 TimeNewEpoch() */
+/* This function does the processing to generate a new time epoch nonce and set NV for update. This
+ function is only called when NV is known to be available and the clock is running. The epoch is
+ updated to persistent data. */
+static void
+TimeNewEpoch(
+ void
+ )
+{
+#if CLOCK_STOPS
+ CryptRandomGenerate(sizeof(CLOCK_NONCE), (BYTE *)&g_timeEpoch);
+#else
+ // if the epoch is kept in NV, update it.
+ gp.timeEpoch++;
+ NV_SYNC_PERSISTENT(timeEpoch);
+#endif
+ // Clean out any lingering state
+ _plat__TimerWasStopped();
+}
+/* 8.10.3.3 TimeStartup() */
+/* This function updates the resetCount and restartCount components of TPMS_CLOCK_INFO structure at
+ TPM2_Startup(). */
+/* This function will deal with the deferred creation of a new epoch. TimeUpdateToCurrent() will not
+ start a new epoch even if one is due when TPM_Startup() has not been run. This is because the
+ state of NV is not known until startup completes. When Startup is done, then it will create the
+ epoch nonce to complete the initializations by calling this function. */
+BOOL
+TimeStartup(
+ STARTUP_TYPE type // IN: start up type
+ )
+{
+ NOT_REFERENCED(type);
+ // If the previous cycle is orderly shut down, the value of the safe bit
+ // the same as previously saved. Otherwise, it is not safe.
+ if(!NV_IS_ORDERLY)
+ go.clockSafe = NO;
+ return TRUE;
+}
+/* 8.10.3.4 TimeClockUpdate() */
+/* This function updates go.clock. If newTime requires an update of NV, then NV is checked for
+ availability. If it is not available or is rate limiting, then go.clock is not updated and the
+ function returns an error. If newTime would not cause an NV write, then go.clock is updated. If
+ an NV write occurs, then go.safe is SET. */
+void
+TimeClockUpdate(
+ UINT64 newTime // IN: New time value in mS.
+ )
+{
+#define CLOCK_UPDATE_MASK ((1ULL << NV_CLOCK_UPDATE_INTERVAL)- 1)
+ // Check to see if the update will cause a need for an nvClock update
+ if((newTime | CLOCK_UPDATE_MASK) > (go.clock | CLOCK_UPDATE_MASK))
+ {
+ pAssert(g_NvStatus == TPM_RC_SUCCESS);
+ // Going to update the NV time state so SET the safe flag
+ go.clockSafe = YES;
+ // update the time
+ go.clock = newTime;
+
+ /* libtpms: Changing the clock alone does not cause the permanent
+ * state to be written to storage, there must be other
+ * reasons as well.
+ */
+ UPDATE_TYPE old_g_updateNV = g_updateNV; // libtpms added
+
+ NvWrite(NV_ORDERLY_DATA, sizeof(go), &go);
+
+ g_updateNV = old_g_updateNV; // libtpms added
+ }
+ else
+ // No NV update needed so just update
+ go.clock = newTime;
+}
+/* 8.10.3.5 TimeUpdate() */
+/* This function is used to update the time and clock values. If the TPM has run TPM2_Startup(),
+ this function is called at the start of each command. If the TPM has not run TPM2_Startup(), this
+ is called from TPM2_Startup() to get the clock values initialized. It is not called on command
+ entry because, in this implementation, the go structure is not read from NV until
+ TPM2_Startup(). The reason for this is that the initialization code (_TPM_Init()) may run before
+ NV is accessible. */
+void
+TimeUpdate(
+ void
+ )
+{
+ UINT64 elapsed;
+ //
+ // Make sure that we consume the current _plat__TimerWasStopped() state.
+ if(_plat__TimerWasStopped())
+ {
+ TimeNewEpoch();
+ }
+ // Get the difference between this call and the last time we updated the tick
+ // timer.
+ elapsed = _plat__TimerRead() - g_time;
+ // Don't read +
+ g_time += elapsed;
+ // Don't need to check the result because it has to be success because have
+ // already checked that NV is available.
+ TimeClockUpdate(go.clock + elapsed);
+ // Call self healing logic for dictionary attack parameters
+ DASelfHeal();
+}
+/* 8.10.3.6 TimeUpdateToCurrent() */
+/* This function updates the Time and Clock in the global TPMS_TIME_INFO structure. */
+/* In this implementation, Time and Clock are updated at the beginning of each command and the
+ values are unchanged for the duration of the command. */
+/* Because Clock updates may require a write to NV memory, Time and Clock are not allowed to advance
+ if NV is not available. When clock is not advancing, any function that uses Clock will fail and
+ return TPM_RC_NV_UNAVAILABLE or TPM_RC_NV_RATE. */
+/* This implementation does not do rate limiting. If the implementation does do rate limiting, then
+ the Clock update should not be inhibited even when doing rate limiting. */
+void
+TimeUpdateToCurrent(
+ void
+ )
+{
+ // Can't update time during the dark interval or when rate limiting so don't
+ // make any modifications to the internal clock value. Also, defer any clock
+ // processing until TPM has run TPM2_Startup()
+ if(!NV_IS_AVAILABLE || !TPMIsStarted())
+ return;
+ TimeUpdate();
+}
+/* 8.10.3.7 TimeSetAdjustRate() */
+/* This function is used to perform rate adjustment on Time and Clock. */
+void
+TimeSetAdjustRate(
+ TPM_CLOCK_ADJUST adjust // IN: adjust constant
+ )
+{
+ switch(adjust)
+ {
+ case TPM_CLOCK_COARSE_SLOWER:
+ _plat__ClockAdjustRate(CLOCK_ADJUST_COARSE);
+ break;
+ case TPM_CLOCK_COARSE_FASTER:
+ _plat__ClockAdjustRate(-CLOCK_ADJUST_COARSE);
+ break;
+ case TPM_CLOCK_MEDIUM_SLOWER:
+ _plat__ClockAdjustRate(CLOCK_ADJUST_MEDIUM);
+ break;
+ case TPM_CLOCK_MEDIUM_FASTER:
+ _plat__ClockAdjustRate(-CLOCK_ADJUST_MEDIUM);
+ break;
+ case TPM_CLOCK_FINE_SLOWER:
+ _plat__ClockAdjustRate(CLOCK_ADJUST_FINE);
+ break;
+ case TPM_CLOCK_FINE_FASTER:
+ _plat__ClockAdjustRate(-CLOCK_ADJUST_FINE);
+ break;
+ case TPM_CLOCK_NO_CHANGE:
+ break;
+ default:
+ FAIL(FATAL_ERROR_INTERNAL);
+ break;
+ }
+ return;
+}
+/* 8.10.3.8 TimeGetMarshaled() */
+/* This function is used to access TPMS_TIME_INFO in canonical form. The function collects the time
+ information and marshals it into dataBuffer and returns the marshaled size */
+/* Return Value Meaning */
+UINT16
+TimeGetMarshaled(
+ TIME_INFO *dataBuffer // OUT: result buffer
+ )
+{
+ TPMS_TIME_INFO timeInfo;
+ // Fill TPMS_TIME_INFO structure
+ timeInfo.time = g_time;
+ TimeFillInfo(&timeInfo.clockInfo);
+ // Marshal TPMS_TIME_INFO to canonical form
+ return TPMS_TIME_INFO_Marshal(&timeInfo, (BYTE **)&dataBuffer, NULL);
+}
+/* 8.10.3.9 TimeFillInfo */
+/* This function gathers information to fill in a TPMS_CLOCK_INFO structure. */
+void
+TimeFillInfo(
+ TPMS_CLOCK_INFO *clockInfo
+ )
+{
+ clockInfo->clock = go.clock;
+ clockInfo->resetCount = gp.resetCount;
+ clockInfo->restartCount = gr.restartCount;
+ // If NV is not available, clock stopped advancing and the value reported is
+ // not "safe".
+ if(NV_IS_AVAILABLE)
+ clockInfo->safe = go.clockSafe;
+ else
+ clockInfo->safe = NO;
+ return;
+}
diff --git a/src/tpm2/Time_fp.h b/src/tpm2/Time_fp.h
new file mode 100644
index 0000000..b4143e5
--- /dev/null
+++ b/src/tpm2/Time_fp.h
@@ -0,0 +1,99 @@
+/********************************************************************************/
+/* */
+/* Functions relating to the TPM's time functions */
+/* Written by Ken Goldman */
+/* IBM Thomas J. Watson Research Center */
+/* $Id: Time_fp.h 1490 2019-07-26 21:13:22Z kgoldman $ */
+/* */
+/* Licenses and Notices */
+/* */
+/* 1. Copyright Licenses: */
+/* */
+/* - Trusted Computing Group (TCG) grants to the user of the source code in */
+/* this specification (the "Source Code") a worldwide, irrevocable, */
+/* nonexclusive, royalty free, copyright license to reproduce, create */
+/* derivative works, distribute, display and perform the Source Code and */
+/* derivative works thereof, and to grant others the rights granted herein. */
+/* */
+/* - The TCG grants to the user of the other parts of the specification */
+/* (other than the Source Code) the rights to reproduce, distribute, */
+/* display, and perform the specification solely for the purpose of */
+/* developing products based on such documents. */
+/* */
+/* 2. Source Code Distribution Conditions: */
+/* */
+/* - Redistributions of Source Code must retain the above copyright licenses, */
+/* this list of conditions and the following disclaimers. */
+/* */
+/* - Redistributions in binary form must reproduce the above copyright */
+/* licenses, this list of conditions and the following disclaimers in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* 3. Disclaimers: */
+/* */
+/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
+/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
+/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
+/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
+/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
+/* information on specification licensing rights available through TCG */
+/* membership agreements. */
+/* */
+/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
+/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
+/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
+/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
+/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
+/* */
+/* - Without limitation, TCG and its members and licensors disclaim all */
+/* liability, including liability for infringement of any proprietary */
+/* rights, relating to use of information in this specification and to the */
+/* implementation of this specification, and TCG disclaims all liability for */
+/* cost of procurement of substitute goods or services, lost profits, loss */
+/* of use, loss of data or any incidental, consequential, direct, indirect, */
+/* or special damages, whether under contract, tort, warranty or otherwise, */
+/* arising in any way out of use or reliance upon this specification or any */
+/* information herein. */
+/* */
+/* (c) Copyright IBM Corp. and others, 2016 - 2019 */
+/* */
+/********************************************************************************/
+
+#ifndef TIME_FP_H
+#define TIME_FP_H
+
+void
+TimePowerOn(
+ void
+ );
+BOOL
+TimeStartup(
+ STARTUP_TYPE type // IN: start up type
+ );
+void
+TimeClockUpdate(
+ UINT64 newTime
+ );
+void
+TimeUpdate(
+ void
+ );
+void
+TimeUpdateToCurrent(
+ void
+ );
+void
+TimeSetAdjustRate(
+ TPM_CLOCK_ADJUST adjust // IN: adjust constant
+ );
+UINT16
+TimeGetMarshaled(
+ TIME_INFO *dataBuffer // OUT: result buffer
+ );
+void
+TimeFillInfo(
+ TPMS_CLOCK_INFO *clockInfo
+ );
+
+
+#endif
diff --git a/src/tpm2/Tpm.h b/src/tpm2/Tpm.h
new file mode 100644
index 0000000..e05c529
--- /dev/null
+++ b/src/tpm2/Tpm.h
@@ -0,0 +1,81 @@
+/********************************************************************************/
+/* */
+/* Root header file for building any TPM.lib code */
+/* Written by Ken Goldman */
+/* IBM Thomas J. Watson Research Center */
+/* $Id: Tpm.h 1594 2020-03-26 22:15:48Z kgoldman $ */
+/* */
+/* Licenses and Notices */
+/* */
+/* 1. Copyright Licenses: */
+/* */
+/* - Trusted Computing Group (TCG) grants to the user of the source code in */
+/* this specification (the "Source Code") a worldwide, irrevocable, */
+/* nonexclusive, royalty free, copyright license to reproduce, create */
+/* derivative works, distribute, display and perform the Source Code and */
+/* derivative works thereof, and to grant others the rights granted herein. */
+/* */
+/* - The TCG grants to the user of the other parts of the specification */
+/* (other than the Source Code) the rights to reproduce, distribute, */
+/* display, and perform the specification solely for the purpose of */
+/* developing products based on such documents. */
+/* */
+/* 2. Source Code Distribution Conditions: */
+/* */
+/* - Redistributions of Source Code must retain the above copyright licenses, */
+/* this list of conditions and the following disclaimers. */
+/* */
+/* - Redistributions in binary form must reproduce the above copyright */
+/* licenses, this list of conditions and the following disclaimers in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* 3. Disclaimers: */
+/* */
+/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
+/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
+/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
+/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
+/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
+/* information on specification licensing rights available through TCG */
+/* membership agreements. */
+/* */
+/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
+/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
+/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
+/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
+/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
+/* */
+/* - Without limitation, TCG and its members and licensors disclaim all */
+/* liability, including liability for infringement of any proprietary */
+/* rights, relating to use of information in this specification and to the */
+/* implementation of this specification, and TCG disclaims all liability for */
+/* cost of procurement of substitute goods or services, lost profits, loss */
+/* of use, loss of data or any incidental, consequential, direct, indirect, */
+/* or special damages, whether under contract, tort, warranty or otherwise, */
+/* arising in any way out of use or reliance upon this specification or any */
+/* information herein. */
+/* */
+/* (c) Copyright IBM Corp. and others, 2016 - 2020 */
+/* */
+/********************************************************************************/
+
+/* 5.18 Tpm.h */
+/* Root header file for building any TPM.lib code */
+#ifndef _TPM_H_
+#define _TPM_H_
+
+#include "TpmBuildSwitches.h"
+#include "BaseTypes.h"
+#include "TPMB.h"
+#include "MinMax.h"
+#include "TpmProfile.h"
+#include "TpmAlgorithmDefines.h"
+#include "LibSupport.h" // Types from the library. These need to come before
+// Global.h because some of the structures in
+// that file depend on the structures used by the
+// cryptographic libraries.
+#include "GpMacros.h" // Define additional macros
+#include "Global.h" // Define other TPM types
+#include "InternalRoutines.h" // Function prototypes
+
+#endif // _TPM_H_
diff --git a/src/tpm2/TpmAlgorithmDefines.h b/src/tpm2/TpmAlgorithmDefines.h
new file mode 100644
index 0000000..e397367
--- /dev/null
+++ b/src/tpm2/TpmAlgorithmDefines.h
@@ -0,0 +1,405 @@
+/********************************************************************************/
+/* */
+/* Algorithm Values from the TCG Algorithm Registry */
+/* Written by Ken Goldman */
+/* IBM Thomas J. Watson Research Center */
+/* $Id: TpmAlgorithmDefines.h 1658 2021-01-22 23:14:01Z kgoldman $ */
+/* */
+/* Licenses and Notices */
+/* */
+/* 1. Copyright Licenses: */
+/* */
+/* - Trusted Computing Group (TCG) grants to the user of the source code in */
+/* this specification (the "Source Code") a worldwide, irrevocable, */
+/* nonexclusive, royalty free, copyright license to reproduce, create */
+/* derivative works, distribute, display and perform the Source Code and */
+/* derivative works thereof, and to grant others the rights granted herein. */
+/* */
+/* - The TCG grants to the user of the other parts of the specification */
+/* (other than the Source Code) the rights to reproduce, distribute, */
+/* display, and perform the specification solely for the purpose of */
+/* developing products based on such documents. */
+/* */
+/* 2. Source Code Distribution Conditions: */
+/* */
+/* - Redistributions of Source Code must retain the above copyright licenses, */
+/* this list of conditions and the following disclaimers. */
+/* */
+/* - Redistributions in binary form must reproduce the above copyright */
+/* licenses, this list of conditions and the following disclaimers in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* 3. Disclaimers: */
+/* */
+/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
+/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
+/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
+/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
+/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
+/* information on specification licensing rights available through TCG */
+/* membership agreements. */
+/* */
+/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
+/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
+/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
+/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
+/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
+/* */
+/* - Without limitation, TCG and its members and licensors disclaim all */
+/* liability, including liability for infringement of any proprietary */
+/* rights, relating to use of information in this specification and to the */
+/* implementation of this specification, and TCG disclaims all liability for */
+/* cost of procurement of substitute goods or services, lost profits, loss */
+/* of use, loss of data or any incidental, consequential, direct, indirect, */
+/* or special damages, whether under contract, tort, warranty or otherwise, */
+/* arising in any way out of use or reliance upon this specification or any */
+/* information herein. */
+/* */
+/* (c) Copyright IBM Corp. and others, 2019 - 2021 */
+/* */
+/********************************************************************************/
+
+// 10.1.18 TpmAlgorithmDefines.h
+// This file contains the algorithm values from the TCG Algorithm Registry.
+#ifndef _TPM_ALGORITHM_DEFINES_H_
+#define _TPM_ALGORITHM_DEFINES_H_
+// Table 2:3 - Definition of Base Types
+#define ECC_CURVES \
+ {TPM_ECC_BN_P256, TPM_ECC_BN_P638, TPM_ECC_NIST_P192, \
+ TPM_ECC_NIST_P224, TPM_ECC_NIST_P256, TPM_ECC_NIST_P384, \
+ TPM_ECC_NIST_P521, TPM_ECC_SM2_P256}
+#define ECC_CURVE_COUNT \
+ (ECC_BN_P256 + ECC_BN_P638 + ECC_NIST_P192 + ECC_NIST_P224 + \
+ ECC_NIST_P256 + ECC_NIST_P384 + ECC_NIST_P521 + ECC_SM2_P256)
+#define MAX_ECC_KEY_BITS \
+ MAX(ECC_BN_P256 * 256, MAX(ECC_BN_P638 * 638, \
+ MAX(ECC_NIST_P192 * 192, MAX(ECC_NIST_P224 * 224, \
+ MAX(ECC_NIST_P256 * 256, MAX(ECC_NIST_P384 * 384, \
+ MAX(ECC_NIST_P521 * 521, MAX(ECC_SM2_P256 * 256, \
+ 0))))))))
+#define MAX_ECC_KEY_BYTES BITS_TO_BYTES(MAX_ECC_KEY_BITS)
+
+// Table 0:6 - Defines for PLATFORM Values
+#define PLATFORM_FAMILY TPM_SPEC_FAMILY
+#define PLATFORM_LEVEL TPM_SPEC_LEVEL
+#define PLATFORM_VERSION TPM_SPEC_VERSION
+#define PLATFORM_YEAR TPM_SPEC_YEAR
+#define PLATFORM_DAY_OF_YEAR TPM_SPEC_DAY_OF_YEAR
+
+// Table 1:12 - Defines for SHA1 Hash Values
+#define SHA1_DIGEST_SIZE 20
+#define SHA1_BLOCK_SIZE 64
+// Table 1:13 - Defines for SHA256 Hash Values
+#define SHA256_DIGEST_SIZE 32
+#define SHA256_BLOCK_SIZE 64
+// Table 1:14 - Defines for SHA384 Hash Values
+#define SHA384_DIGEST_SIZE 48
+#define SHA384_BLOCK_SIZE 128
+// Table 1:15 - Defines for SHA512 Hash Values
+#define SHA512_DIGEST_SIZE 64
+#define SHA512_BLOCK_SIZE 128
+// Table 1:16 - Defines for SM3_256 Hash Values
+#define SM3_256_DIGEST_SIZE 32
+#define SM3_256_BLOCK_SIZE 64
+// Table 1:16 - Defines for SHA3_256 Hash Values
+#define SHA3_256_DIGEST_SIZE 32
+#define SHA3_256_BLOCK_SIZE 136
+// Table 1:16 - Defines for SHA3_384 Hash Values
+#define SHA3_384_DIGEST_SIZE 48
+#define SHA3_384_BLOCK_SIZE 104
+// Table 1:16 - Defines for SHA3_512 Hash Values
+#define SHA3_512_DIGEST_SIZE 64
+#define SHA3_512_BLOCK_SIZE 72
+// Table 1:00 - Defines for RSA Asymmetric Cipher Algorithm Constants
+#define RSA_KEY_SIZES_BITS \
+ (1024 * RSA_1024), (2048 * RSA_2048), (3072 * RSA_3072), \
+ (4096 * RSA_4096), (16384 * RSA_16384)
+#if RSA_16384
+# define RSA_MAX_KEY_SIZE_BITS 16384
+#elif RSA_4096
+# define RSA_MAX_KEY_SIZE_BITS 4096
+#elif RSA_3072
+# define RSA_MAX_KEY_SIZE_BITS 3072
+#elif RSA_2048
+# define RSA_MAX_KEY_SIZE_BITS 2048
+#elif RSA_1024
+# define RSA_MAX_KEY_SIZE_BITS 1024
+#else
+# define RSA_MAX_KEY_SIZE_BITS 0
+#endif
+#define MAX_RSA_KEY_BITS RSA_MAX_KEY_SIZE_BITS
+#define MAX_RSA_KEY_BYTES ((RSA_MAX_KEY_SIZE_BITS + 7) / 8)
+// Table 1:17 - Defines for AES Symmetric Cipher Algorithm Constants
+#define AES_KEY_SIZES_BITS \
+ (128 * AES_128), (192 * AES_192), (256 * AES_256)
+#if AES_256
+# define AES_MAX_KEY_SIZE_BITS 256
+#elif AES_192
+# define AES_MAX_KEY_SIZE_BITS 192
+#elif AES_128
+# define AES_MAX_KEY_SIZE_BITS 128
+#else
+# define AES_MAX_KEY_SIZE_BITS 0
+#endif
+#define MAX_AES_KEY_BITS AES_MAX_KEY_SIZE_BITS
+#define MAX_AES_KEY_BYTES ((AES_MAX_KEY_SIZE_BITS + 7) / 8)
+#define AES_128_BLOCK_SIZE_BYTES (AES_128 * 16)
+#define AES_192_BLOCK_SIZE_BYTES (AES_192 * 16)
+#define AES_256_BLOCK_SIZE_BYTES (AES_256 * 16)
+#define AES_BLOCK_SIZES \
+ AES_128_BLOCK_SIZE_BYTES, AES_192_BLOCK_SIZE_BYTES, \
+ AES_256_BLOCK_SIZE_BYTES
+#if ALG_AES
+# define AES_MAX_BLOCK_SIZE 16
+#else
+# define AES_MAX_BLOCK_SIZE 0
+#endif
+#define MAX_AES_BLOCK_SIZE_BYTES AES_MAX_BLOCK_SIZE
+// 1:18 - Defines for SM4 Symmetric Cipher Algorithm Constants
+#define SM4_KEY_SIZES_BITS (128 * SM4_128)
+#if SM4_128
+# define SM4_MAX_KEY_SIZE_BITS 128
+#else
+# define SM4_MAX_KEY_SIZE_BITS 0
+#endif
+#define MAX_SM4_KEY_BITS SM4_MAX_KEY_SIZE_BITS
+#define MAX_SM4_KEY_BYTES ((SM4_MAX_KEY_SIZE_BITS + 7) / 8)
+#define SM4_128_BLOCK_SIZE_BYTES (SM4_128 * 16)
+#define SM4_BLOCK_SIZES SM4_128_BLOCK_SIZE_BYTES
+#if ALG_SM4
+# define SM4_MAX_BLOCK_SIZE 16
+#else
+# define SM4_MAX_BLOCK_SIZE 0
+#endif
+#define MAX_SM4_BLOCK_SIZE_BYTES SM4_MAX_BLOCK_SIZE
+// 1:19 - Defines for CAMELLIA Symmetric Cipher Algorithm Constants
+#define CAMELLIA_KEY_SIZES_BITS \
+ (128 * CAMELLIA_128), (192 * CAMELLIA_192), (256 * CAMELLIA_256)
+#if CAMELLIA_256
+# define CAMELLIA_MAX_KEY_SIZE_BITS 256
+#elif CAMELLIA_192
+# define CAMELLIA_MAX_KEY_SIZE_BITS 192
+#elif CAMELLIA_128
+# define CAMELLIA_MAX_KEY_SIZE_BITS 128
+#else
+# define CAMELLIA_MAX_KEY_SIZE_BITS 0
+#endif
+#define MAX_CAMELLIA_KEY_BITS CAMELLIA_MAX_KEY_SIZE_BITS
+#define MAX_CAMELLIA_KEY_BYTES ((CAMELLIA_MAX_KEY_SIZE_BITS + 7) / 8)
+#define CAMELLIA_128_BLOCK_SIZE_BYTES (CAMELLIA_128 * 16)
+#define CAMELLIA_192_BLOCK_SIZE_BYTES (CAMELLIA_192 * 16)
+#define CAMELLIA_256_BLOCK_SIZE_BYTES (CAMELLIA_256 * 16)
+#define CAMELLIA_BLOCK_SIZES \
+ CAMELLIA_128_BLOCK_SIZE_BYTES, CAMELLIA_192_BLOCK_SIZE_BYTES, \
+ CAMELLIA_256_BLOCK_SIZE_BYTES
+#if ALG_CAMELLIA
+# define CAMELLIA_MAX_BLOCK_SIZE 16
+#else
+# define CAMELLIA_MAX_BLOCK_SIZE 0
+#endif
+#define MAX_CAMELLIA_BLOCK_SIZE_BYTES CAMELLIA_MAX_BLOCK_SIZE
+// 1:17 - Defines for TDES Symmetric Cipher Algorithm Constants
+#define TDES_KEY_SIZES_BITS (128 * TDES_128), (192 * TDES_192)
+#if TDES_192
+# define TDES_MAX_KEY_SIZE_BITS 192
+#elif TDES_128
+# define TDES_MAX_KEY_SIZE_BITS 128
+#else
+# define TDES_MAX_KEY_SIZE_BITS 0
+#endif
+#define MAX_TDES_KEY_BITS TDES_MAX_KEY_SIZE_BITS
+#define MAX_TDES_KEY_BYTES ((TDES_MAX_KEY_SIZE_BITS + 7) / 8)
+#define TDES_128_BLOCK_SIZE_BYTES (TDES_128 * 8)
+#define TDES_192_BLOCK_SIZE_BYTES (TDES_192 * 8)
+#define TDES_BLOCK_SIZES \
+ TDES_128_BLOCK_SIZE_BYTES, TDES_192_BLOCK_SIZE_BYTES
+#if ALG_TDES
+# define TDES_MAX_BLOCK_SIZE 8
+#else
+# define TDES_MAX_BLOCK_SIZE 0
+#endif
+#define MAX_TDES_BLOCK_SIZE_BYTES TDES_MAX_BLOCK_SIZE
+// Additional values for benefit of code
+#define TPM_CC_FIRST 0x0000011F
+#define TPM_CC_LAST 0x0000019A
+#if COMPRESSED_LISTS
+#define ADD_FILL 0
+#else
+#define ADD_FILL 1
+#endif
+// Size the array of library commands based on whether or not the array is packed (only defined
+// commands) or dense (having entries for unimplemented commands)
+#define LIBRARY_COMMAND_ARRAY_SIZE (0 \
+ + (ADD_FILL || CC_NV_UndefineSpaceSpecial) /* 0x0000011F */ \
+ + (ADD_FILL || CC_EvictControl) /* 0x00000120 */ \
+ + (ADD_FILL || CC_HierarchyControl) /* 0x00000121 */ \
+ + (ADD_FILL || CC_NV_UndefineSpace) /* 0x00000122 */ \
+ + ADD_FILL /* 0x00000123 */ \
+ + (ADD_FILL || CC_ChangeEPS) /* 0x00000124 */ \
+ + (ADD_FILL || CC_ChangePPS) /* 0x00000125 */ \
+ + (ADD_FILL || CC_Clear) /* 0x00000126 */ \
+ + (ADD_FILL || CC_ClearControl) /* 0x00000127 */ \
+ + (ADD_FILL || CC_ClockSet) /* 0x00000128 */ \
+ + (ADD_FILL || CC_HierarchyChangeAuth) /* 0x00000129 */ \
+ + (ADD_FILL || CC_NV_DefineSpace) /* 0x0000012A */ \
+ + (ADD_FILL || CC_PCR_Allocate) /* 0x0000012B */ \
+ + (ADD_FILL || CC_PCR_SetAuthPolicy) /* 0x0000012C */ \
+ + (ADD_FILL || CC_PP_Commands) /* 0x0000012D */ \
+ + (ADD_FILL || CC_SetPrimaryPolicy) /* 0x0000012E */ \
+ + (ADD_FILL || CC_FieldUpgradeStart) /* 0x0000012F */ \
+ + (ADD_FILL || CC_ClockRateAdjust) /* 0x00000130 */ \
+ + (ADD_FILL || CC_CreatePrimary) /* 0x00000131 */ \
+ + (ADD_FILL || CC_NV_GlobalWriteLock) /* 0x00000132 */ \
+ + (ADD_FILL || CC_GetCommandAuditDigest) /* 0x00000133 */ \
+ + (ADD_FILL || CC_NV_Increment) /* 0x00000134 */ \
+ + (ADD_FILL || CC_NV_SetBits) /* 0x00000135 */ \
+ + (ADD_FILL || CC_NV_Extend) /* 0x00000136 */ \
+ + (ADD_FILL || CC_NV_Write) /* 0x00000137 */ \
+ + (ADD_FILL || CC_NV_WriteLock) /* 0x00000138 */ \
+ + (ADD_FILL || CC_DictionaryAttackLockReset) /* 0x00000139 */ \
+ + (ADD_FILL || CC_DictionaryAttackParameters) /* 0x0000013A */ \
+ + (ADD_FILL || CC_NV_ChangeAuth) /* 0x0000013B */ \
+ + (ADD_FILL || CC_PCR_Event) /* 0x0000013C */ \
+ + (ADD_FILL || CC_PCR_Reset) /* 0x0000013D */ \
+ + (ADD_FILL || CC_SequenceComplete) /* 0x0000013E */ \
+ + (ADD_FILL || CC_SetAlgorithmSet) /* 0x0000013F */ \
+ + (ADD_FILL || CC_SetCommandCodeAuditStatus) /* 0x00000140 */ \
+ + (ADD_FILL || CC_FieldUpgradeData) /* 0x00000141 */ \
+ + (ADD_FILL || CC_IncrementalSelfTest) /* 0x00000142 */ \
+ + (ADD_FILL || CC_SelfTest) /* 0x00000143 */ \
+ + (ADD_FILL || CC_Startup) /* 0x00000144 */ \
+ + (ADD_FILL || CC_Shutdown) /* 0x00000145 */ \
+ + (ADD_FILL || CC_StirRandom) /* 0x00000146 */ \
+ + (ADD_FILL || CC_ActivateCredential) /* 0x00000147 */ \
+ + (ADD_FILL || CC_Certify) /* 0x00000148 */ \
+ + (ADD_FILL || CC_PolicyNV) /* 0x00000149 */ \
+ + (ADD_FILL || CC_CertifyCreation) /* 0x0000014A */ \
+ + (ADD_FILL || CC_Duplicate) /* 0x0000014B */ \
+ + (ADD_FILL || CC_GetTime) /* 0x0000014C */ \
+ + (ADD_FILL || CC_GetSessionAuditDigest) /* 0x0000014D */ \
+ + (ADD_FILL || CC_NV_Read) /* 0x0000014E */ \
+ + (ADD_FILL || CC_NV_ReadLock) /* 0x0000014F */ \
+ + (ADD_FILL || CC_ObjectChangeAuth) /* 0x00000150 */ \
+ + (ADD_FILL || CC_PolicySecret) /* 0x00000151 */ \
+ + (ADD_FILL || CC_Rewrap) /* 0x00000152 */ \
+ + (ADD_FILL || CC_Create) /* 0x00000153 */ \
+ + (ADD_FILL || CC_ECDH_ZGen) /* 0x00000154 */ \
+ + (ADD_FILL || CC_HMAC || CC_MAC) /* 0x00000155 */ \
+ + (ADD_FILL || CC_Import) /* 0x00000156 */ \
+ + (ADD_FILL || CC_Load) /* 0x00000157 */ \
+ + (ADD_FILL || CC_Quote) /* 0x00000158 */ \
+ + (ADD_FILL || CC_RSA_Decrypt) /* 0x00000159 */ \
+ + ADD_FILL /* 0x0000015A */ \
+ + (ADD_FILL || CC_HMAC_Start || CC_MAC_Start) /* 0x0000015B */ \
+ + (ADD_FILL || CC_SequenceUpdate) /* 0x0000015C */ \
+ + (ADD_FILL || CC_Sign) /* 0x0000015D */ \
+ + (ADD_FILL || CC_Unseal) /* 0x0000015E */ \
+ + ADD_FILL /* 0x0000015F */ \
+ + (ADD_FILL || CC_PolicySigned) /* 0x00000160 */ \
+ + (ADD_FILL || CC_ContextLoad) /* 0x00000161 */ \
+ + (ADD_FILL || CC_ContextSave) /* 0x00000162 */ \
+ + (ADD_FILL || CC_ECDH_KeyGen) /* 0x00000163 */ \
+ + (ADD_FILL || CC_EncryptDecrypt) /* 0x00000164 */ \
+ + (ADD_FILL || CC_FlushContext) /* 0x00000165 */ \
+ + ADD_FILL /* 0x00000166 */ \
+ + (ADD_FILL || CC_LoadExternal) /* 0x00000167 */ \
+ + (ADD_FILL || CC_MakeCredential) /* 0x00000168 */ \
+ + (ADD_FILL || CC_NV_ReadPublic) /* 0x00000169 */ \
+ + (ADD_FILL || CC_PolicyAuthorize) /* 0x0000016A */ \
+ + (ADD_FILL || CC_PolicyAuthValue) /* 0x0000016B */ \
+ + (ADD_FILL || CC_PolicyCommandCode) /* 0x0000016C */ \
+ + (ADD_FILL || CC_PolicyCounterTimer) /* 0x0000016D */ \
+ + (ADD_FILL || CC_PolicyCpHash) /* 0x0000016E */ \
+ + (ADD_FILL || CC_PolicyLocality) /* 0x0000016F */ \
+ + (ADD_FILL || CC_PolicyNameHash) /* 0x00000170 */ \
+ + (ADD_FILL || CC_PolicyOR) /* 0x00000171 */ \
+ + (ADD_FILL || CC_PolicyTicket) /* 0x00000172 */ \
+ + (ADD_FILL || CC_ReadPublic) /* 0x00000173 */ \
+ + (ADD_FILL || CC_RSA_Encrypt) /* 0x00000174 */ \
+ + ADD_FILL /* 0x00000175 */ \
+ + (ADD_FILL || CC_StartAuthSession) /* 0x00000176 */ \
+ + (ADD_FILL || CC_VerifySignature) /* 0x00000177 */ \
+ + (ADD_FILL || CC_ECC_Parameters) /* 0x00000178 */ \
+ + (ADD_FILL || CC_FirmwareRead) /* 0x00000179 */ \
+ + (ADD_FILL || CC_GetCapability) /* 0x0000017A */ \
+ + (ADD_FILL || CC_GetRandom) /* 0x0000017B */ \
+ + (ADD_FILL || CC_GetTestResult) /* 0x0000017C */ \
+ + (ADD_FILL || CC_Hash) /* 0x0000017D */ \
+ + (ADD_FILL || CC_PCR_Read) /* 0x0000017E */ \
+ + (ADD_FILL || CC_PolicyPCR) /* 0x0000017F */ \
+ + (ADD_FILL || CC_PolicyRestart) /* 0x00000180 */ \
+ + (ADD_FILL || CC_ReadClock) /* 0x00000181 */ \
+ + (ADD_FILL || CC_PCR_Extend) /* 0x00000182 */ \
+ + (ADD_FILL || CC_PCR_SetAuthValue) /* 0x00000183 */ \
+ + (ADD_FILL || CC_NV_Certify) /* 0x00000184 */ \
+ + (ADD_FILL || CC_EventSequenceComplete) /* 0x00000185 */ \
+ + (ADD_FILL || CC_HashSequenceStart) /* 0x00000186 */ \
+ + (ADD_FILL || CC_PolicyPhysicalPresence) /* 0x00000187 */ \
+ + (ADD_FILL || CC_PolicyDuplicationSelect) /* 0x00000188 */ \
+ + (ADD_FILL || CC_PolicyGetDigest) /* 0x00000189 */ \
+ + (ADD_FILL || CC_TestParms) /* 0x0000018A */ \
+ + (ADD_FILL || CC_Commit) /* 0x0000018B */ \
+ + (ADD_FILL || CC_PolicyPassword) /* 0x0000018C */ \
+ + (ADD_FILL || CC_ZGen_2Phase) /* 0x0000018D */ \
+ + (ADD_FILL || CC_EC_Ephemeral) /* 0x0000018E */ \
+ + (ADD_FILL || CC_PolicyNvWritten) /* 0x0000018F */ \
+ + (ADD_FILL || CC_PolicyTemplate) /* 0x00000190 */ \
+ + (ADD_FILL || CC_CreateLoaded) /* 0x00000191 */ \
+ + (ADD_FILL || CC_PolicyAuthorizeNV) /* 0x00000192 */ \
+ + (ADD_FILL || CC_EncryptDecrypt2) /* 0x00000193 */ \
+ + (ADD_FILL || CC_AC_GetCapability) /* 0x00000194 */ \
+ + (ADD_FILL || CC_AC_Send) /* 0x00000195 */ \
+ + (ADD_FILL || CC_Policy_AC_SendSelect) /* 0x00000196 */ \
+ + (ADD_FILL || CC_CertifyX509) /* 0x00000197 */ \
+ + (ADD_FILL || CC_ACT_SetTimeout) /* 0x00000198 */ \
+ + (ADD_FILL || CC_ECC_Encrypt) /* 0x00000199 */ \
+ + (ADD_FILL || CC_ECC_Decrypt) /* 0x0000019A */ \
+ )
+
+#define VENDOR_COMMAND_ARRAY_SIZE (0 + CC_Vendor_TCG_Test)
+
+#define COMMAND_COUNT (LIBRARY_COMMAND_ARRAY_SIZE + VENDOR_COMMAND_ARRAY_SIZE)
+#define HASH_COUNT \
+ (ALG_SHA1 + ALG_SHA256 + ALG_SHA384 + ALG_SHA3_256 + \
+ ALG_SHA3_384 + ALG_SHA3_512 + ALG_SHA512 + ALG_SM3_256)
+#define MAX_HASH_BLOCK_SIZE \
+ (MAX(ALG_SHA1 * SHA1_BLOCK_SIZE, \
+ MAX(ALG_SHA256 * SHA256_BLOCK_SIZE, \
+ MAX(ALG_SHA384 * SHA384_BLOCK_SIZE, \
+ MAX(ALG_SHA3_256 * SHA3_256_BLOCK_SIZE, \
+ MAX(ALG_SHA3_384 * SHA3_384_BLOCK_SIZE, \
+ MAX(ALG_SHA3_512 * SHA3_512_BLOCK_SIZE, \
+ MAX(ALG_SHA512 * SHA512_BLOCK_SIZE, \
+ MAX(ALG_SM3_256 * SM3_256_BLOCK_SIZE, \
+ 0)))))))))
+#define MAX_DIGEST_SIZE \
+ (MAX(ALG_SHA1 * SHA1_DIGEST_SIZE, \
+ MAX(ALG_SHA256 * SHA256_DIGEST_SIZE, \
+ MAX(ALG_SHA384 * SHA384_DIGEST_SIZE, \
+ MAX(ALG_SHA3_256 * SHA3_256_DIGEST_SIZE, \
+ MAX(ALG_SHA3_384 * SHA3_384_DIGEST_SIZE, \
+ MAX(ALG_SHA3_512 * SHA3_512_DIGEST_SIZE, \
+ MAX(ALG_SHA512 * SHA512_DIGEST_SIZE, \
+ MAX(ALG_SM3_256 * SM3_256_DIGEST_SIZE, \
+ 0)))))))))
+#if MAX_DIGEST_SIZE == 0 || MAX_HASH_BLOCK_SIZE == 0
+#error "Hash data not valid"
+#endif
+// Define the 2B structure that would hold any hash block
+TPM2B_TYPE(MAX_HASH_BLOCK, MAX_HASH_BLOCK_SIZE);
+// Following typedef is for some old code
+typedef TPM2B_MAX_HASH_BLOCK TPM2B_HASH_BLOCK;
+
+#define MAX_SYM_KEY_BITS \
+ (MAX(AES_MAX_KEY_SIZE_BITS, MAX(CAMELLIA_MAX_KEY_SIZE_BITS, \
+ MAX(SM4_MAX_KEY_SIZE_BITS, MAX(TDES_MAX_KEY_SIZE_BITS, \
+ 0)))))
+#define MAX_SYM_KEY_BYTES ((MAX_SYM_KEY_BITS + 7) / 8)
+#define MAX_SYM_BLOCK_SIZE \
+ (MAX(AES_MAX_BLOCK_SIZE, MAX(CAMELLIA_MAX_BLOCK_SIZE, \
+ MAX(SM4_MAX_BLOCK_SIZE, MAX(TDES_MAX_BLOCK_SIZE, \
+ 0)))))
+#if MAX_SYM_KEY_BITS == 0 || MAX_SYM_BLOCK_SIZE == 0
+# error Bad size for MAX_SYM_KEY_BITS or MAX_SYM_BLOCK
+#endif
+#endif // _TPM_ALGORITHM_DEFINES_H_
diff --git a/src/tpm2/TpmAsn1.c b/src/tpm2/TpmAsn1.c
new file mode 100644
index 0000000..f23b2a9
--- /dev/null
+++ b/src/tpm2/TpmAsn1.c
@@ -0,0 +1,508 @@
+/********************************************************************************/
+/* */
+/* TPM ASN.1 */
+/* Written by Ken Goldman */
+/* IBM Thomas J. Watson Research Center */
+/* $Id: TpmAsn1.c 1519 2019-11-15 20:43:51Z kgoldman $ */
+/* */
+/* Licenses and Notices */
+/* */
+/* 1. Copyright Licenses: */
+/* */
+/* - Trusted Computing Group (TCG) grants to the user of the source code in */
+/* this specification (the "Source Code") a worldwide, irrevocable, */
+/* nonexclusive, royalty free, copyright license to reproduce, create */
+/* derivative works, distribute, display and perform the Source Code and */
+/* derivative works thereof, and to grant others the rights granted herein. */
+/* */
+/* - The TCG grants to the user of the other parts of the specification */
+/* (other than the Source Code) the rights to reproduce, distribute, */
+/* display, and perform the specification solely for the purpose of */
+/* developing products based on such documents. */
+/* */
+/* 2. Source Code Distribution Conditions: */
+/* */
+/* - Redistributions of Source Code must retain the above copyright licenses, */
+/* this list of conditions and the following disclaimers. */
+/* */
+/* - Redistributions in binary form must reproduce the above copyright */
+/* licenses, this list of conditions and the following disclaimers in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* 3. Disclaimers: */
+/* */
+/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
+/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
+/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
+/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
+/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
+/* information on specification licensing rights available through TCG */
+/* membership agreements. */
+/* */
+/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
+/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
+/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
+/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
+/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
+/* */
+/* - Without limitation, TCG and its members and licensors disclaim all */
+/* liability, including liability for infringement of any proprietary */
+/* rights, relating to use of information in this specification and to the */
+/* implementation of this specification, and TCG disclaims all liability for */
+/* cost of procurement of substitute goods or services, lost profits, loss */
+/* of use, loss of data or any incidental, consequential, direct, indirect, */
+/* or special damages, whether under contract, tort, warranty or otherwise, */
+/* arising in any way out of use or reliance upon this specification or any */
+/* information herein. */
+/* */
+/* (c) Copyright IBM Corp. and others, 2019 */
+/* */
+/********************************************************************************/
+
+/* 10.2.23 TpmAsn1.c */
+/* 10.2.23.1 Includes */
+#include "Tpm.h"
+#define _OIDS_
+#include "OIDs.h"
+#include "TpmAsn1.h"
+#include "TpmAsn1_fp.h"
+/* 10.2.23.2 Unmarshaling Functions */
+/* 10.2.23.2.1 ASN1UnmarshalContextInitialize() */
+/* Function does standard initialization of a context. */
+/* Return Value Meaning */
+/* TRUE(1) success */
+/* FALSE(0) failure */
+BOOL
+ASN1UnmarshalContextInitialize(
+ ASN1UnmarshalContext *ctx,
+ INT16 size,
+ BYTE *buffer
+ )
+{
+ VERIFY(buffer != NULL);
+ VERIFY(size > 0);
+ ctx->buffer = buffer;
+ ctx->size = size;
+ ctx->offset = 0;
+ ctx->tag = 0xFF;
+ return TRUE;
+ Error:
+ return FALSE;
+}
+/* 10.2.23.2.2 ASN1DecodeLength() */
+/* This function extracts the length of an element from buffer starting at offset. */
+/* Return Value Meaning */
+/* >=0 the extracted length */
+/* <0 an error */
+INT16
+ASN1DecodeLength(
+ ASN1UnmarshalContext *ctx
+ )
+{
+ BYTE first; // Next octet in buffer
+ INT16 value;
+ //
+ VERIFY(ctx->offset < ctx->size);
+ first = NEXT_OCTET(ctx);
+ // If the number of octets of the entity is larger than 127, then the first octet
+ // is the number of octets in the length specifier.
+ if(first >= 0x80)
+ {
+ // Make sure that this length field is contained with the structure being
+ // parsed
+ CHECK_SIZE(ctx, (first & 0x7F));
+ if(first == 0x82)
+ {
+ // Two octets of size
+ // get the next value
+ value = (INT16)NEXT_OCTET(ctx);
+ // Make sure that the result will fit in an INT16
+ VERIFY(value < 0x0080);
+ // Shift up and add next octet
+ value = (value << 8) + NEXT_OCTET(ctx);
+ }
+ else if(first == 0x81)
+ value = NEXT_OCTET(ctx);
+ // Sizes larger than will fit in a INT16 are an error
+ else
+ goto Error;
+ }
+ else
+ value = first;
+ // Make sure that the size defined something within the current context
+ CHECK_SIZE(ctx, value);
+ return value;
+ Error:
+ ctx->size = -1; // Makes everything fail from now on.
+ return -1;
+}
+/* 10.2.23.2.3 ASN1NextTag() */
+/* This function extracts the next type from buffer starting at offset. It advances offset as it
+ parses the type and the length of the type. It returns the length of the type. On return, the
+ length octets starting at offset are the octets of the type. */
+/* Return Value Meaning */
+/* >=0 the number of octets in type */
+/* <0 an error */
+INT16
+ASN1NextTag(
+ ASN1UnmarshalContext *ctx
+ )
+{
+ // A tag to get?
+ VERIFY(ctx->offset < ctx->size);
+ // Get it
+ ctx->tag = NEXT_OCTET(ctx);
+ // Make sure that it is not an extended tag
+ VERIFY((ctx->tag & 0x1F) != 0x1F);
+ // Get the length field and return that
+ return ASN1DecodeLength(ctx);
+
+ Error:
+ // Attempt to read beyond the end of the context or an illegal tag
+ ctx->size = -1; // Persistent failure
+ ctx->tag = 0xFF;
+ return -1;
+}
+/* 10.2.23.2.4 ASN1GetBitStringValue() */
+/* Try to parse a bit string of up to 32 bits from a value that is expected to be a bit string. The
+ bit string is left justified so that the MSb of the input is the MSb of the returned value. If
+ there is a general parsing error, the context->size is set to -1. */
+/* Return Value Meaning */
+/* TRUE(1) success */
+/* FALSE(0) failure */
+
+BOOL
+ASN1GetBitStringValue(
+ ASN1UnmarshalContext *ctx,
+ UINT32 *val
+ )
+{
+ int shift;
+ INT16 length;
+ UINT32 value = 0;
+ int inputBits;
+ //
+ length = ASN1NextTag(ctx);
+ VERIFY(length >= 1);
+ VERIFY(ctx->tag == ASN1_BITSTRING);
+ // Get the shift value for the bit field (how many bits to lop off of the end)
+ shift = NEXT_OCTET(ctx);
+ length--;
+ // Get the number of bits in the input
+ inputBits = (8 * length) - shift;
+ // the shift count has to make sense
+ VERIFY((shift < 8) && ((length > 0) || (shift == 0)));
+ // if there are any bytes left
+ for(; length > 1; length--)
+ {
+
+ // for all but the last octet, just shift and add the new octet
+ VERIFY((value & 0xFF000000) == 0); // can't loose significant bits
+ value = (value << 8) + NEXT_OCTET(ctx);
+
+ }
+ if(length == 1)
+ {
+ // for the last octet, just shift the accumulated value enough to
+ // accept the significant bits in the last octet and shift the last
+ // octet down
+ VERIFY(((value & (0xFF000000 << (8 - shift)))) == 0);
+ value = (value << (8 - shift)) + (NEXT_OCTET(ctx) >> shift);
+
+ }
+ // 'Left justify' the result
+ if(inputBits > 0)
+ value <<= (32 - inputBits);
+ *val = value;
+ return TRUE;
+ Error:
+ ctx->size = -1;
+ return FALSE;
+}
+
+/* 10.2.23.3 Marshaling Functions */
+/* 10.2.23.3.1 Introduction */
+/* Marshaling of an ASN.1 structure is accomplished from the bottom up. That is, the things that
+ will be at the end of the structure are added last. To manage the collecting of the relative
+ sizes, start a context for the outermost container, if there is one, and then placing items in
+ from the bottom up. If the bottom-most item is also within a structure, create a nested context
+ by calling ASN1StartMarshalingContext(). */
+/* The context control structure contains a buffer pointer, an offset, an end and a stack. offset is
+ the offset from the start of the buffer of the last added byte. When offset reaches 0, the buffer
+ is full. offset is a signed value so that, when it becomes negative, there is an overflow. Only
+ two functions are allowed to move bytes into the buffer: ASN1PushByte() and
+ ASN1PushBytes(). These functions make sure that no data is written beyond the end of the
+ buffer. */
+/* When a new context is started, the current value of end is pushed on the stack and end is set to
+ 'offset. As bytes are added, offset gets smaller. At any time, the count of bytes in the current
+ context is simply end - offset. */
+/* Since starting a new context involves setting end = offset, the number of bytes in the context
+ starts at 0. The nominal way of ending a context is to use end - offset to set the length value,
+ and then a tag is added to the buffer. Then the previous end value is popped meaning that the
+ context just ended becomes a member of the now current context. */
+/* The nominal strategy for building a completed ASN.1 structure is to push everything into the
+ buffer and then move everything to the start of the buffer. The move is simple as the size of the
+ move is the initial end value minus the final offset value. The destination is buffer and the
+ source is buffer + offset. As Skippy would say "Easy peasy, Joe." */
+/* It is not necessary to provide a buffer into which the data is placed. If no buffer is provided,
+ then the marshaling process will return values needed for marshaling. On strategy for filling the
+ buffer would be to execute the process for building the structure without using a buffer. This
+ would return the overall size of the structure. Then that amount of data could be allocated for
+ the buffer and the fill process executed again with the data going into the buffer. At the end,
+ the data would be in its final resting place. */
+/* 10.2.23.3.2 ASN1InitialializeMarshalContext() */
+/* This creates a structure for handling marshaling of an ASN.1 formatted data structure. */
+void
+ASN1InitialializeMarshalContext(
+ ASN1MarshalContext *ctx,
+ INT16 length,
+ BYTE *buffer
+ )
+{
+ ctx->buffer = buffer;
+ if(buffer)
+ ctx->offset = length;
+ else
+ ctx->offset = INT16_MAX;
+ ctx->end = ctx->offset;
+ ctx->depth = -1;
+}
+/* 10.2.23.3.3 ASN1StartMarshalContext() */
+/* This starts a new constructed element. It is constructed on top of the value that was previously placed in the structure. */
+void
+ASN1StartMarshalContext(
+ ASN1MarshalContext *ctx
+ )
+{
+ pAssert((ctx->depth + 1) < MAX_DEPTH);
+ ctx->depth++;
+ ctx->ends[ctx->depth] = ctx->end;
+ ctx->end = ctx->offset;
+}
+/* 10.2.23.3.4 ASN1EndMarshalContext() */
+/* This function restores the end pointer for an encapsulating structure. */
+/* Return Value Meaning */
+/* > 0 the size of the encapsulated structure that was just ended */
+/* <= 0 an error */
+INT16
+ASN1EndMarshalContext(
+ ASN1MarshalContext *ctx
+ )
+{
+ INT16 length;
+ pAssert(ctx->depth >= 0);
+ length = ctx->end - ctx->offset;
+ ctx->end = ctx->ends[ctx->depth--];
+ if((ctx->depth == -1) && (ctx->buffer))
+ {
+ MemoryCopy(ctx->buffer, ctx->buffer + ctx->offset, ctx->end - ctx->offset);
+ }
+ return length;
+}
+/* 10.2.23.3.5 ASN1EndEncapsulation() */
+/* This function puts a tag and length in the buffer. In this function, an embedded BIT_STRING is
+ assumed to be a collection of octets. To indicate that all bits are used, a byte of zero is
+ prepended. If a raw bit-string is needed, a new function like ASN1PushInteger() would be
+ needed. */
+/* Return Value Meaning */
+/* > 0 number of octets in the encapsulation */
+/* == 0 failure */
+UINT16
+ASN1EndEncapsulation(
+ ASN1MarshalContext *ctx,
+ BYTE tag
+ )
+{
+ // only add a leading zero for an encapsulated BIT STRING
+ if (tag == ASN1_BITSTRING)
+ ASN1PushByte(ctx, 0);
+ ASN1PushTagAndLength(ctx, tag, ctx->end - ctx->offset);
+ return ASN1EndMarshalContext(ctx);
+}
+/* 10.2.23.3.6 ASN1PushByte() */
+BOOL
+ASN1PushByte(
+ ASN1MarshalContext *ctx,
+ BYTE b
+ )
+{
+ if(ctx->offset > 0)
+ {
+ ctx->offset -= 1;
+ if(ctx->buffer)
+ ctx->buffer[ctx->offset] = b;
+ return TRUE;
+ }
+ ctx->offset = -1;
+ return FALSE;
+}
+/* 10.2.23.3.7 ASN1PushBytes() */
+/* Push some raw bytes onto the buffer. count cannot be zero. */
+/* Return Value Meaning */
+/* > 0 count bytes */
+/* == 0 failure unless count was zero */
+INT16
+ASN1PushBytes(
+ ASN1MarshalContext *ctx,
+ INT16 count,
+ const BYTE *buffer
+ )
+{
+ // make sure that count is not negative which would mess up the math; and that
+ // if there is a count, there is a buffer
+ VERIFY((count >= 0) && ((buffer != NULL) || (count == 0)));
+ // back up the offset to determine where the new octets will get pushed
+ ctx->offset -= count;
+ // can't go negative
+ VERIFY(ctx->offset >= 0);
+ // if there are buffers, move the data, otherwise, assume that this is just a
+ // test.
+ if(count && buffer && ctx->buffer)
+ MemoryCopy(&ctx->buffer[ctx->offset], buffer, count);
+ return count;
+ Error:
+ ctx->offset = -1;
+ return 0;
+}
+/* 10.2.23.3.8 ASN1PushNull() */
+/* Return Value Meaning */
+/* > 0 count bytes */
+/* == 0 failure unless count was zero */
+INT16
+ASN1PushNull(
+ ASN1MarshalContext *ctx
+ )
+{
+ ASN1PushByte(ctx, 0);
+ ASN1PushByte(ctx, ASN1_NULL);
+ return (ctx->offset >= 0) ? 2 : 0;
+}
+/* 10.2.23.3.9 ASN1PushLength() */
+/* Push a length value. This will only handle length values that fit in an INT16. */
+/* Return Value Meaning */
+/* > 0 number of bytes added */
+/* == 0 failure */
+INT16
+ASN1PushLength(
+ ASN1MarshalContext *ctx,
+ INT16 len
+ )
+{
+ UINT16 start = ctx->offset;
+ VERIFY(len >= 0);
+ if(len <= 127)
+ ASN1PushByte(ctx, (BYTE)len);
+ else
+ {
+ ASN1PushByte(ctx, (BYTE)(len & 0xFF));
+ len >>= 8;
+ if(len == 0)
+ ASN1PushByte(ctx, 0x81);
+ else
+ {
+ ASN1PushByte(ctx, (BYTE)(len));
+ ASN1PushByte(ctx, 0x82);
+ }
+ }
+ goto Exit;
+ Error:
+ ctx->offset = -1;
+ Exit:
+ return (ctx->offset > 0) ? start - ctx->offset : 0;
+}
+/* 10.2.23.3.10 ASN1PushTagAndLength() */
+/* Return Value Meaning */
+/* > 0 number of bytes added */
+/* == 0 failure */
+INT16
+ASN1PushTagAndLength(
+ ASN1MarshalContext *ctx,
+ BYTE tag,
+ INT16 length
+ )
+{
+ INT16 bytes;
+ bytes = ASN1PushLength(ctx, length);
+ bytes += (INT16)ASN1PushByte(ctx, tag);
+ return (ctx->offset < 0) ? 0 : bytes;
+}
+/* 10.2.23.3.11 ASN1PushTaggedOctetString() */
+/* This function will push a random octet string. */
+/* Return Value Meaning */
+/* > 0 number of bytes added */
+/* == 0 failure */
+INT16
+ASN1PushTaggedOctetString(
+ ASN1MarshalContext *ctx,
+ INT16 size,
+ const BYTE *string,
+ BYTE tag
+ )
+{
+ ASN1PushBytes(ctx, size, string);
+ // PushTagAndLenght just tells how many octets it added so the total size of this
+ // element is the sum of those octets and input size.
+ size += ASN1PushTagAndLength(ctx, tag, size);
+ return size;
+}
+/* 10.2.23.3.12 ASN1PushUINT() */
+/* This function pushes an native-endian integer value. This just changes a native-endian integer
+ into a big-endian byte string and calls ASN1PushInteger(). That function will remove leading
+ zeros and make sure that the number is positive. */
+/* Return Value Meaning */
+/* > 0 count bytes */
+/* == 0 failure unless count was zero */
+INT16
+ASN1PushUINT(
+ ASN1MarshalContext *ctx,
+ UINT32 integer
+ )
+{
+ BYTE marshaled[4];
+ UINT32_TO_BYTE_ARRAY(integer, marshaled);
+ return ASN1PushInteger(ctx, 4, marshaled);
+}
+/* 10.2.23.3.13 ASN1PushInteger */
+/* Push a big-endian integer on the end of the buffer */
+/* Return Value Meaning */
+/* > 0 the number of bytes marshaled for the integer */
+/* == 0 failure */
+INT16
+ASN1PushInteger(
+ ASN1MarshalContext *ctx, // IN/OUT: buffer context
+ INT16 iLen, // IN: octets of the integer
+ BYTE *integer // IN: big-endian integer
+ )
+{
+ // no leading 0's
+ while((*integer == 0) && (--iLen > 0))
+ integer++;
+ // Move the bytes to the buffer
+ ASN1PushBytes(ctx, iLen, integer);
+ // if needed, add a leading byte of 0 to make the number positive
+ if(*integer & 0x80)
+ iLen += (INT16)ASN1PushByte(ctx, 0);
+ // PushTagAndLenght just tells how many octets it added so the total size of this
+ // element is the sum of those octets and the adjusted input size.
+ iLen += ASN1PushTagAndLength(ctx, ASN1_INTEGER, iLen);
+ return iLen;
+}
+/* 10.2.23.3.14 ASN1PushOID() */
+/* This function is used to add an OID. An OID is 0x06 followed by a byte of size followed by size
+ bytes. This is used to avoid having to do anything special in the definition of an OID. */
+/* Return Value Meaning */
+/* > 0 the number of bytes marshaled for the integer */
+/* == 0 failure */
+INT16
+ASN1PushOID(
+ ASN1MarshalContext *ctx,
+ const BYTE *OID
+ )
+{
+ if((*OID == ASN1_OBJECT_IDENTIFIER) && ((OID[1] & 0x80) == 0))
+ {
+ return ASN1PushBytes(ctx, OID[1] + 2, OID);
+ }
+ ctx->offset = -1;
+ return 0;
+}
diff --git a/src/tpm2/TpmAsn1.h b/src/tpm2/TpmAsn1.h
new file mode 100644
index 0000000..5e57eac
--- /dev/null
+++ b/src/tpm2/TpmAsn1.h
@@ -0,0 +1,137 @@
+/********************************************************************************/
+/* */
+/* Macro and Structure Definitions for the X509 Commands and Functions. */
+/* Written by Ken Goldman */
+/* IBM Thomas J. Watson Research Center */
+/* $Id: TpmAsn1.h 1519 2019-11-15 20:43:51Z kgoldman $ */
+/* */
+/* Licenses and Notices */
+/* */
+/* 1. Copyright Licenses: */
+/* */
+/* - Trusted Computing Group (TCG) grants to the user of the source code in */
+/* this specification (the "Source Code") a worldwide, irrevocable, */
+/* nonexclusive, royalty free, copyright license to reproduce, create */
+/* derivative works, distribute, display and perform the Source Code and */
+/* derivative works thereof, and to grant others the rights granted herein. */
+/* */
+/* - The TCG grants to the user of the other parts of the specification */
+/* (other than the Source Code) the rights to reproduce, distribute, */
+/* display, and perform the specification solely for the purpose of */
+/* developing products based on such documents. */
+/* */
+/* 2. Source Code Distribution Conditions: */
+/* */
+/* - Redistributions of Source Code must retain the above copyright licenses, */
+/* this list of conditions and the following disclaimers. */
+/* */
+/* - Redistributions in binary form must reproduce the above copyright */
+/* licenses, this list of conditions and the following disclaimers in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* 3. Disclaimers: */
+/* */
+/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
+/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
+/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
+/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
+/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
+/* information on specification licensing rights available through TCG */
+/* membership agreements. */
+/* */
+/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
+/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
+/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
+/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
+/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
+/* */
+/* - Without limitation, TCG and its members and licensors disclaim all */
+/* liability, including liability for infringement of any proprietary */
+/* rights, relating to use of information in this specification and to the */
+/* implementation of this specification, and TCG disclaims all liability for */
+/* cost of procurement of substitute goods or services, lost profits, loss */
+/* of use, loss of data or any incidental, consequential, direct, indirect, */
+/* or special damages, whether under contract, tort, warranty or otherwise, */
+/* arising in any way out of use or reliance upon this specification or any */
+/* information herein. */
+/* */
+/* (c) Copyright IBM Corp. and others, 2019 */
+/* */
+/********************************************************************************/
+
+// 10.1.15 TpmAsn1.h
+// 10.1.15.1 Introduction
+// This file contains the macro and structure definitions for the X509 commands and functions.
+#ifndef _TPMASN1_H_
+#define _TPMASN1_H_
+// 10.1.15.2 Includes
+#include "Tpm.h"
+#include "OIDs.h"
+// 10.1.15.3 Defined Constants
+// 10.1.15.3.1 ASN.1 Universal Types (Class 00b
+#define ASN1_EOC 0x00
+#define ASN1_BOOLEAN 0x01
+#define ASN1_INTEGER 0x02
+#define ASN1_BITSTRING 0x03
+#define ASN1_OCTET_STRING 0x04
+#define ASN1_NULL 0x05
+#define ASN1_OBJECT_IDENTIFIER 0x06
+#define ASN1_OBJECT_DESCRIPTOR 0x07
+#define ASN1_EXTERNAL 0x08
+#define ASN1_REAL 0x09
+#define ASN1_ENUMERATED 0x0A
+#define ASN1_EMBEDDED 0x0B
+#define ASN1_UTF8String 0x0C
+#define ASN1_RELATIVE_OID 0x0D
+#define ASN1_SEQUENCE 0x10 // Primitive + Constructed + 0x10
+#define ASN1_SET 0x11 // Primitive + Constructed + 0x11
+#define ASN1_NumericString 0x12
+#define ASN1_PrintableString 0x13
+#define ASN1_T61String 0x14
+#define ASN1_VideoString 0x15
+#define ASN1_IA5String 0x16
+#define ASN1_UTCTime 0x17
+#define ASN1_GeneralizeTime 0x18
+#define ASN1_VisibleString 0x1A
+#define ASN1_GeneralString 0x1B
+#define ASN1_UniversalString 0x1C
+#define ASN1_CHARACTER STRING 0x1D
+#define ASN1_BMPString 0x1E
+#define ASN1_CONSTRUCTED 0x20
+#define ASN1_APPLICAIION_SPECIFIC 0xA0
+#define ASN1_CONSTRUCTED_SEQUENCE (ASN1_SEQUENCE + ASN1_CONSTRUCTED)
+#define MAX_DEPTH 10 // maximum push depth for marshaling context.
+// 10.1.15.4 Macros
+// 10.1.15.4.1 Unmarshaling Macros
+#ifndef VERIFY
+#define VERIFY(_X_) {if(!(_X_)) goto Error; }
+#endif
+// Checks the validity of the size making sure that there is no wrap around
+#define CHECK_SIZE(context, length) \
+ VERIFY( (((length) + (context)->offset) >= (context)->offset) \
+ && (((length) + (context)->offset) <= (context)->size))
+#define NEXT_OCTET(context) ((context)->buffer[(context)->offset++])
+#define PEEK_NEXT(context) ((context)->buffer[(context)->offset])
+// 10.1.15.4.2 Marshaling Macros Marshaling works in reverse order. The offset is set to the top of
+// the buffer and, as the buffer is filled, offset counts down to zero. When the full thing is
+// encoded it can be moved to the top of the buffer. This happens when the last context is closed.
+
+#define CHECK_SPACE(context, length) VERIFY(context->offset > length)
+// 10.1.15.5 Structures
+typedef struct ASN1UnmarshalContext {
+ BYTE *buffer; // pointer to the buffer
+ INT16 size; // size of the buffer (a negative number indicates
+ // a parsing failure).
+ INT16 offset; // current offset into the buffer (a negative number
+ // indicates a parsing failure). Not used
+ BYTE tag; // The last unmarshaled tag
+} ASN1UnmarshalContext;
+typedef struct ASN1MarshalContext {
+ BYTE *buffer; // pointer to the start of the buffer
+ INT16 offset; // place on the top where the last entry was added
+ // items are added from the bottom up.
+ INT16 end; // the end offset of the current value
+ INT16 depth; // how many pushed end values.
+ INT16 ends[MAX_DEPTH];
+} ASN1MarshalContext;
+#endif // _TPMASN1_H_
diff --git a/src/tpm2/TpmAsn1_fp.h b/src/tpm2/TpmAsn1_fp.h
new file mode 100644
index 0000000..55f61c9
--- /dev/null
+++ b/src/tpm2/TpmAsn1_fp.h
@@ -0,0 +1,152 @@
+/********************************************************************************/
+/* */
+/* TPM ASN.1 */
+/* Written by Ken Goldman */
+/* IBM Thomas J. Watson Research Center */
+/* $Id: TpmAsn1_fp.h 1490 2019-07-26 21:13:22Z kgoldman $ */
+/* */
+/* Licenses and Notices */
+/* */
+/* 1. Copyright Licenses: */
+/* */
+/* - Trusted Computing Group (TCG) grants to the user of the source code in */
+/* this specification (the "Source Code") a worldwide, irrevocable, */
+/* nonexclusive, royalty free, copyright license to reproduce, create */
+/* derivative works, distribute, display and perform the Source Code and */
+/* derivative works thereof, and to grant others the rights granted herein. */
+/* */
+/* - The TCG grants to the user of the other parts of the specification */
+/* (other than the Source Code) the rights to reproduce, distribute, */
+/* display, and perform the specification solely for the purpose of */
+/* developing products based on such documents. */
+/* */
+/* 2. Source Code Distribution Conditions: */
+/* */
+/* - Redistributions of Source Code must retain the above copyright licenses, */
+/* this list of conditions and the following disclaimers. */
+/* */
+/* - Redistributions in binary form must reproduce the above copyright */
+/* licenses, this list of conditions and the following disclaimers in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* 3. Disclaimers: */
+/* */
+/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
+/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
+/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
+/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
+/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
+/* information on specification licensing rights available through TCG */
+/* membership agreements. */
+/* */
+/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
+/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
+/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
+/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
+/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
+/* */
+/* - Without limitation, TCG and its members and licensors disclaim all */
+/* liability, including liability for infringement of any proprietary */
+/* rights, relating to use of information in this specification and to the */
+/* implementation of this specification, and TCG disclaims all liability for */
+/* cost of procurement of substitute goods or services, lost profits, loss */
+/* of use, loss of data or any incidental, consequential, direct, indirect, */
+/* or special damages, whether under contract, tort, warranty or otherwise, */
+/* arising in any way out of use or reliance upon this specification or any */
+/* information herein. */
+/* */
+/* (c) Copyright IBM Corp. and others, 2019 */
+/* */
+/********************************************************************************/
+
+#ifndef TPMASN1_FP_H
+#define TPMASN1_FP_H
+
+BOOL
+ASN1UnmarshalContextInitialize(
+ ASN1UnmarshalContext *ctx,
+ INT16 size,
+ BYTE *buffer
+ );
+INT16
+ASN1DecodeLength(
+ ASN1UnmarshalContext *ctx
+ );
+INT16
+ASN1NextTag(
+ ASN1UnmarshalContext *ctx
+ );
+BOOL
+ASN1GetBitStringValue(
+ ASN1UnmarshalContext *ctx,
+ UINT32 *val
+ );
+void
+ASN1InitialializeMarshalContext(
+ ASN1MarshalContext *ctx,
+ INT16 length,
+ BYTE *buffer
+ );
+void
+ASN1StartMarshalContext(
+ ASN1MarshalContext *ctx
+ );
+INT16
+ASN1EndMarshalContext(
+ ASN1MarshalContext *ctx
+ );
+UINT16
+ASN1EndEncapsulation(
+ ASN1MarshalContext *ctx,
+ BYTE tag
+ );
+BOOL
+ASN1PushByte(
+ ASN1MarshalContext *ctx,
+ BYTE b
+ );
+INT16
+ASN1PushBytes(
+ ASN1MarshalContext *ctx,
+ INT16 count,
+ const BYTE *buffer
+ );
+INT16
+ASN1PushNull(
+ ASN1MarshalContext *ctx
+ );
+INT16
+ASN1PushLength(
+ ASN1MarshalContext *ctx,
+ INT16 len
+ );
+INT16
+ASN1PushTagAndLength(
+ ASN1MarshalContext *ctx,
+ BYTE tag,
+ INT16 length
+ );
+INT16
+ASN1PushTaggedOctetString(
+ ASN1MarshalContext *ctx,
+ INT16 size,
+ const BYTE *string,
+ BYTE tag
+ );
+INT16
+ASN1PushUINT(
+ ASN1MarshalContext *ctx,
+ UINT32 integer
+ );
+INT16
+ASN1PushInteger(
+ ASN1MarshalContext *ctx, // IN/OUT: buffer context
+ INT16 iLen, // IN: octets of the integer
+ BYTE *integer // IN: big-endian integer
+ );
+INT16
+ASN1PushOID(
+ ASN1MarshalContext *ctx,
+ const BYTE *OID
+ );
+#endif
diff --git a/src/tpm2/TpmBuildSwitches.h b/src/tpm2/TpmBuildSwitches.h
new file mode 100644
index 0000000..c4a7b31
--- /dev/null
+++ b/src/tpm2/TpmBuildSwitches.h
@@ -0,0 +1,364 @@
+/********************************************************************************/
+/* */
+/* Build Switches */
+/* Written by Ken Goldman */
+/* IBM Thomas J. Watson Research Center */
+/* $Id: TpmBuildSwitches.h 1619 2020-05-19 16:51:47Z kgoldman $ */
+/* */
+/* Licenses and Notices */
+/* */
+/* 1. Copyright Licenses: */
+/* */
+/* - Trusted Computing Group (TCG) grants to the user of the source code in */
+/* this specification (the "Source Code") a worldwide, irrevocable, */
+/* nonexclusive, royalty free, copyright license to reproduce, create */
+/* derivative works, distribute, display and perform the Source Code and */
+/* derivative works thereof, and to grant others the rights granted herein. */
+/* */
+/* - The TCG grants to the user of the other parts of the specification */
+/* (other than the Source Code) the rights to reproduce, distribute, */
+/* display, and perform the specification solely for the purpose of */
+/* developing products based on such documents. */
+/* */
+/* 2. Source Code Distribution Conditions: */
+/* */
+/* - Redistributions of Source Code must retain the above copyright licenses, */
+/* this list of conditions and the following disclaimers. */
+/* */
+/* - Redistributions in binary form must reproduce the above copyright */
+/* licenses, this list of conditions and the following disclaimers in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* 3. Disclaimers: */
+/* */
+/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
+/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
+/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
+/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
+/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
+/* information on specification licensing rights available through TCG */
+/* membership agreements. */
+/* */
+/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
+/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
+/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
+/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
+/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
+/* */
+/* - Without limitation, TCG and its members and licensors disclaim all */
+/* liability, including liability for infringement of any proprietary */
+/* rights, relating to use of information in this specification and to the */
+/* implementation of this specification, and TCG disclaims all liability for */
+/* cost of procurement of substitute goods or services, lost profits, loss */
+/* of use, loss of data or any incidental, consequential, direct, indirect, */
+/* or special damages, whether under contract, tort, warranty or otherwise, */
+/* arising in any way out of use or reliance upon this specification or any */
+/* information herein. */
+/* */
+/* (c) Copyright IBM Corp. and others, 2016 - 2020 */
+/* */
+/********************************************************************************/
+
+/* 5.19 TpmBuildSwitches.h */
+
+/* This file contains the build switches. This contains switches for multiple versions of the
+ crypto-library so some may not apply to your environment. */
+/* The switches are guarded so that they can either be set on the command line or set here. If the
+ switch is listed on the command line (-DSOME_SWITCH) with no setting, then the switch will be set
+ to YES. If the switch setting is not on the command line or if the setting is other than YES or
+ NO, then the switch will be set to the default value. The default can either be YES or NO as
+ indicated on each line where the default is selected. */
+/* A caution. Do not try to test these macros by inserting #defines in this file. For some curious
+ reason, a variable set on the command line with no setting will have a value of 1. An #if
+ SOME_VARIABLE will work if the variable is not defined or is defined on the command line with no
+ initial setting. However, a #define SOME_VARIABLE is a null string and when used in #if
+ SOME_VARIABLE will not be a proper expression. If you want to test various switches, either use
+ the command line or change the default. */
+
+#ifndef TPMBUILDSWITCHES_H
+#define TPMBUILDSWITCHES_H
+
+#undef YES
+#define YES 1
+#undef NO
+#define NO 0
+
+/* Allow the command line to specify a profile file */
+
+#ifdef PROFILE
+# define PROFILE_QUOTE(a) #a
+# define PROFILE_INCLUDE(a) PROFILE_QUOTE(a)
+# include PROFILE_INCLUDE(PROFILE)
+#endif
+
+// Need an unambiguous definition for DEBUG. Don't change this
+#ifndef DEBUG
+# ifdef NDEBUG
+# define DEBUG NO
+# else
+# define DEBUG YES
+# endif
+#elif (DEBUG != NO) && (DEBUG != YES)
+# undef DEBUG
+# define DEBUG YES // Default: Either YES or NO
+#endif
+#include "CompilerDependencies.h"
+
+// This definition is required for the re-factored code
+#if (!defined USE_BN_ECC_DATA) || ((USE_BN_ECC_DATA != NO) && (USE_BN_ECC_DATA != YES))
+# undef USE_BN_ECC_DATA
+# define USE_BN_ECC_DATA YES // Default: Either YES or NO
+#endif
+
+/* The SIMULATION switch allows certain other macros to be enabled. The things that can be enabled
+ in a simulation include key caching, reproducible random sequences, instrumentation of the RSA
+ key generation process, and certain other debug code. SIMULATION Needs to be defined as either
+ YES or NO. This grouping of macros will make sure that it is set correctly. A simulated TPM would
+ include a Virtual TPM. The interfaces for a Virtual TPM should be modified from the standard ones
+ in the Simulator project. If SIMULATION is in the compile parameters without modifiers, make
+ SIMULATION == YES */
+#if !(defined SIMULATION) || ((SIMULATION != NO) && (SIMULATION != YES))
+# undef SIMULATION
+# define SIMULATION NO // Default: Either YES or NO libtpms: NO
+#endif
+
+// Define this to run the function that checks the compatibility between the chosen big number math
+// library and the TPM code. Not all ports use this.
+
+#if !(defined LIBRARY_COMPATIBILITY_CHECK) \
+ || (( LIBRARY_COMPATIBILITY_CHECK != NO) \
+ && (LIBRARY_COMPATIBILITY_CHECK != YES))
+# undef LIBRARY_COMPATIBILITY_CHECK
+# define LIBRARY_COMPATIBILITY_CHECK YES // Default: Either YES or NO libtpms: YES
+#endif
+#if !(defined FIPS_COMPLIANT) || ((FIPS_COMPLIANT != NO) && (FIPS_COMPLIANT != YES))
+# undef FIPS_COMPLIANT
+# define FIPS_COMPLIANT NO // Default: Either YES or NO libtpms: NO
+#endif
+
+// Definition to allow alternate behavior for non-orderly startup. If there is a chance that the TPM
+// could not update failedTries
+
+/* Removes the behavior of automatically incrementing the failed tries counter after any non-orderly
+ shutdown. When YES, the failed counter is incremented on non-orderly shutdown only if an attempt
+ to access a DA protected object was made on the previous cycle. */
+
+#if !(defined USE_DA_USED) || ((USE_DA_USED != NO) && (USE_DA_USED != YES))
+# undef USE_DA_USED
+# define USE_DA_USED YES // Default: Either YES or NO
+#endif
+
+// Define TABLE_DRIVEN_DISPATCH to use tables rather than case statements for command dispatch and
+// handle unmarshaling
+#if !(defined TABLE_DRIVEN_DISPATCH) \
+ || ((TABLE_DRIVEN_DISPATCH != NO) && (TABLE_DRIVEN_DISPATCH != YES))
+# undef TABLE_DRIVEN_DISPATCH
+# define TABLE_DRIVEN_DISPATCH YES // Default: Either YES or NO
+#endif
+
+/* This switch is used to enable the self-test capability in AlgorithmTests.c */
+#if !(defined SELF_TEST) || ((SELF_TEST != NO) && (SELF_TEST != YES))
+# undef SELF_TEST
+# define SELF_TEST YES // Default: Either YES or NO
+#endif
+
+/* Enable the generation of RSA primes using a sieve. */
+#if !(defined RSA_KEY_SIEVE) || ((RSA_KEY_SIEVE != NO) && (RSA_KEY_SIEVE != YES))
+# undef RSA_KEY_SIEVE
+# define RSA_KEY_SIEVE YES // Default: Either YES or NO
+#endif
+
+/* Enable the instrumentation of the sieve process. This is used to tune the sieve variables.*/
+#if RSA_KEY_SIEVE && SIMULATION
+# if !(defined RSA_INSTRUMENT) || ((RSA_INSTRUMENT != NO) && (RSA_INSTRUMENT != YES))
+# undef RSA_INSTRUMENT
+# define RSA_INSTRUMENT NO // Default: Either YES or NO
+# endif
+#endif
+
+/* This switch enables the RNG state save and restore */
+#if !(defined _DRBG_STATE_SAVE) \
+ || ((_DRBG_STATE_SAVE != NO) && (_DRBG_STATE_SAVE != YES))
+# undef _DRBG_STATE_SAVE
+# define _DRBG_STATE_SAVE YES // Default: Either YES or NO
+#endif
+
+/* Switch added to support packed lists that leave out space associated with unimplemented
+ commands. Comment this out to use linear lists. */
+/* NOTE: if vendor specific commands are present, the associated list is always in compressed
+ form. */
+#if !(defined COMPRESSED_LISTS) \
+ || ((COMPRESSED_LISTS != NO) && (COMPRESSED_LISTS != YES))
+# undef COMPRESSED_LISTS
+# define COMPRESSED_LISTS YES // Default: Either YES or NO
+#endif
+
+
+/* This switch indicates where clock epoch value should be stored. If this value defined, then it is
+ assumed that the timer will change at any time so the nonce should be a random number kept in
+ RAM. When it is not defined, then the timer only stops during power outages. */
+#if !(defined CLOCK_STOPS) || ((CLOCK_STOPS != NO) && (CLOCK_STOPS != YES))
+# undef CLOCK_STOPS
+# define CLOCK_STOPS NO // Default: Either YES or NO
+#endif
+
+// This switch allows use of #defines in place of pass-through marshaling or unmarshaling code. A
+// pass-through function just calls another function to do the required function and does no
+// parameter checking of its own. The table-driven dispatcher calls directly to the lowest level
+// marshaling/unmarshaling code and by-passes any pass-through functions.
+#if (defined USE_MARSHALING_DEFINES) && (USE_MARSHALING_DEFINES != NO)
+# undef USE_MARSHALING_DEFINES
+# define USE_MARSHALING_DEFINES YES
+#else
+# define USE_MARSHALING_DEFINES YES // Default: Either YES or NO
+#endif
+
+// The switches in this group can only be enabled when doing debug during simulation
+#if SIMULATION && DEBUG
+
+/* This forces the use of a smaller context slot size. This reduction reduces the range of the epoch
+ allowing the tester to force the epoch to occur faster than the normal defined in TpmProfile.h */
+# if !(defined CONTEXT_SLOT)
+# define CONTEXT_SLOT UINT8
+# endif
+
+// Enables use of the key cache. Default is YES
+# if !(defined USE_RSA_KEY_CACHE) \
+ || ((USE_RSA_KEY_CACHE != NO) && (USE_RSA_KEY_CACHE != YES))
+# undef USE_RSA_KEY_CACHE
+# define USE_RSA_KEY_CACHE YES // Default: Either YES or NO
+# endif
+
+// Enables use of a file to store the key cache values so that the TPM will start faster during
+// debug. Default for this is YES
+# if USE_RSA_KEY_CACHE
+# if !(defined USE_KEY_CACHE_FILE) \
+ || ((USE_KEY_CACHE_FILE != NO) && (USE_KEY_CACHE_FILE != YES))
+# undef USE_KEY_CACHE_FILE
+# define USE_KEY_CACHE_FILE YES // Default: Either YES or NO
+# endif
+# else
+# undef USE_KEY_CACHE_FILE
+# define USE_KEY_CACHE_FILE NO
+# endif // USE_RSA_KEY_CACHE
+
+// This provides fixed seeding of the RNG when doing debug on a simulator. This should allow
+// consistent results on test runs as long as the input parameters to the functions remains the
+// same. There is no default value.
+# if !(defined USE_DEBUG_RNG) || ((USE_DEBUG_RNG != NO) && (USE_DEBUG_RNG != YES))
+# undef USE_DEBUG_RNG
+# define USE_DEBUG_RNG YES // Default: Either YES or NO
+# endif
+
+// Don't change these. They are the settings needed when not doing a simulation and not doing
+// debug. Can't use the key cache except during debug. Otherwise, all of the key values end up being
+// the same
+#else
+# define USE_RSA_KEY_CACHE NO
+# define USE_RSA_KEY_CACHE_FILE NO
+# define USE_DEBUG_RNG NO
+#endif // DEBUG && SIMULATION
+
+#if DEBUG
+
+// In some cases, the relationship between two values may be dependent on things that change based
+// on various selections like the chosen cryptographic libraries. It is possible that these
+// selections will result in incompatible settings. These are often detectable by the compiler but
+// it isn't always possible to do the check in the preprocessor code. For example, when the check
+// requires use of 'sizeof()' then the preprocessor can't do the comparison. For these cases, we
+// include a special macro that, depending on the compiler will generate a warning to indicate if
+// the check always passes or always fails because it involves fixed constants. To run these checks,
+// define COMPILER_CHECKS.
+# if !(defined COMPILER_CHECKS) \
+ || ((COMPILER_CHECKS != NO) && (COMPILER_CHECKS != YES))
+# undef COMPILER_CHECKS
+# define COMPILER_CHECKS NO // Default: Either YES or NO
+# endif
+
+// Some of the values (such as sizes) are the result of different options set in
+// TpmProfile.h. The combination might not be consistent. A function is defined
+// (TpmSizeChecks()) that is used to verify the sizes at run time. To enable the function, define
+// this parameter.
+# if !(defined RUNTIME_SIZE_CHECKS) \
+ || ((RUNTIME_SIZE_CHECKS != NO) && (RUNTIME_SIZE_CHECKS != YES))
+# undef RUNTIME_SIZE_CHECKS
+# define RUNTIME_SIZE_CHECKS NO // Default: Either YES or NO libtpms: NO
+# endif
+
+// If doing debug, can set the DRBG to print out the intermediate test values. Before enabling this,
+// make sure that the dbgDumpMemBlock() function has been added someplace (preferably, somewhere in
+// CryptRand.c)
+# if !(defined DRBG_DEBUG_PRINT) \
+ || ((DRBG_DEBUG_PRINT != NO) && (DRBG_DEBUG_PRINT != YES))
+# undef DRBG_DEBUG_PRINT
+# define DRBG_DEBUG_PRINT NO // Default: Either YES or NO
+# endif
+
+// If an assertion event it not going to produce any trace information (function and line number)
+// then make FAIL_TRACE == NO
+# if !(defined FAIL_TRACE) || ((FAIL_TRACE != NO) && (FAIL_TRACE != YES))
+# undef FAIL_TRACE
+# define FAIL_TRACE YES // Default: Either YES or NO
+# endif
+
+#endif // DEBUG
+
+/* Indicate if the implementation is going to give lockout time credit for time up to the last
+ orderly shutdown. */
+#if !(defined ACCUMULATE_SELF_HEAL_TIMER) \
+ || ((ACCUMULATE_SELF_HEAL_TIMER != NO) && (ACCUMULATE_SELF_HEAL_TIMER != YES))
+# undef ACCUMULATE_SELF_HEAL_TIMER
+# define ACCUMULATE_SELF_HEAL_TIMER YES // Default: Either YES or NO
+#endif
+
+/* If the implementation is to compute the sizes of the proof and primary seed size values based on
+ the implemented algorithms, then use this define. */
+#if !(defined USE_SPEC_COMPLIANT_PROOFS) \
+ || ((USE_SPEC_COMPLIANT_PROOFS != NO) && (USE_SPEC_COMPLIANT_PROOFS != YES))
+# undef USE_SPEC_COMPLIANT_PROOFS
+# define USE_SPEC_COMPLIANT_PROOFS YES // Default: Either YES or NO
+#endif
+
+// Comment this out to allow compile to continue even though the chosen proof values do not match
+// the compliant values. This is written so that someone would have to proactively ignore errors.
+#if !(defined SKIP_PROOF_ERRORS) \
+ || ((SKIP_PROOF_ERRORS != NO) && (SKIP_PROOF_ERRORS != YES))
+# undef SKIP_PROOF_ERRORS
+# define SKIP_PROOF_ERRORS NO // Default: Either YES or NO
+#endif
+
+// This define is used to eliminate the use of bit-fields. It can be enabled for big- or
+// little-endian machines. For big-endian architectures that number bits in registers from left to
+// right (MSb0()) this must be enabled. Little-endian machines number from right to left with the
+// least significant bit having assigned a bit number of 0. These are LSb0() machines (they are also
+// little-endian so they are also least-significant byte 0 (LSB0) machines. Big-endian (MSB0)
+// machines may number in either direction (MSb0() or LSb0()). For an MSB0+MSb0() machine this
+// value is required to be NO
+
+#if !(defined USE_BIT_FIELD_STRUCTURES) \
+ || ((USE_BIT_FIELD_STRUCTURES != NO) && (USE_BIT_FIELD_STRUCTURES != YES))
+# undef USE_BIT_FIELD_STRUCTURES
+# define USE_BIT_FIELD_STRUCTURES NO // Default: Either YES or NO libtpms: NO
+#endif
+
+// This define is used to control the debug for the CertifyX509() command.
+#if !(defined CERTIFYX509_DEBUG) \
+ || ((CERTIFYX509_DEBUG != NO) && (CERTIFYX509_DEBUG != YES))
+# undef CERTIFYX509_DEBUG
+# define CERTIFYX509_DEBUG NO // libtpms: NO
+#endif
+
+#if !(defined TABLE_DRIVEN_MARSHAL) \
+ || ((TABLE_DRIVEN_MARSHAL != NO) && (TABLE_DRIVEN_MARSHAL != YES))
+# undef TABLE_DRIVEN_MARSHAL
+# define TABLE_DRIVEN_MARSHAL NO // Default: Either YES or NO libtpms: NO
+#endif
+
+/* Change these definitions to turn all algorithms or commands ON or OFF. That is, to turn all
+ algorithms on, set ALG_NO to YES. This is mostly useful as a debug feature. */
+#define ALG_YES YES
+#define ALG_NO NO
+#define CC_YES YES
+#define CC_NO NO
+#endif // _TPM_BUILD_SWITCHES_H_
+
diff --git a/src/tpm2/TpmError.h b/src/tpm2/TpmError.h
new file mode 100644
index 0000000..299ca2d
--- /dev/null
+++ b/src/tpm2/TpmError.h
@@ -0,0 +1,84 @@
+/********************************************************************************/
+/* */
+/* */
+/* Written by Ken Goldman */
+/* IBM Thomas J. Watson Research Center */
+/* $Id: TpmError.h 1490 2019-07-26 21:13:22Z kgoldman $ */
+/* */
+/* Licenses and Notices */
+/* */
+/* 1. Copyright Licenses: */
+/* */
+/* - Trusted Computing Group (TCG) grants to the user of the source code in */
+/* this specification (the "Source Code") a worldwide, irrevocable, */
+/* nonexclusive, royalty free, copyright license to reproduce, create */
+/* derivative works, distribute, display and perform the Source Code and */
+/* derivative works thereof, and to grant others the rights granted herein. */
+/* */
+/* - The TCG grants to the user of the other parts of the specification */
+/* (other than the Source Code) the rights to reproduce, distribute, */
+/* display, and perform the specification solely for the purpose of */
+/* developing products based on such documents. */
+/* */
+/* 2. Source Code Distribution Conditions: */
+/* */
+/* - Redistributions of Source Code must retain the above copyright licenses, */
+/* this list of conditions and the following disclaimers. */
+/* */
+/* - Redistributions in binary form must reproduce the above copyright */
+/* licenses, this list of conditions and the following disclaimers in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* 3. Disclaimers: */
+/* */
+/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
+/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
+/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
+/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
+/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
+/* information on specification licensing rights available through TCG */
+/* membership agreements. */
+/* */
+/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
+/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
+/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
+/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
+/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
+/* */
+/* - Without limitation, TCG and its members and licensors disclaim all */
+/* liability, including liability for infringement of any proprietary */
+/* rights, relating to use of information in this specification and to the */
+/* implementation of this specification, and TCG disclaims all liability for */
+/* cost of procurement of substitute goods or services, lost profits, loss */
+/* of use, loss of data or any incidental, consequential, direct, indirect, */
+/* or special damages, whether under contract, tort, warranty or otherwise, */
+/* arising in any way out of use or reliance upon this specification or any */
+/* information herein. */
+/* */
+/* (c) Copyright IBM Corp. and others, 2016 */
+/* */
+/********************************************************************************/
+
+#ifndef TPMERROR_H
+#define TPMERROR_H
+
+/* 5.23 TpmError.h */
+
+#define FATAL_ERROR_ALLOCATION (1)
+#define FATAL_ERROR_DIVIDE_ZERO (2)
+#define FATAL_ERROR_INTERNAL (3)
+#define FATAL_ERROR_PARAMETER (4)
+#define FATAL_ERROR_ENTROPY (5)
+#define FATAL_ERROR_SELF_TEST (6)
+#define FATAL_ERROR_CRYPTO (7)
+#define FATAL_ERROR_NV_UNRECOVERABLE (8)
+#define FATAL_ERROR_REMANUFACTURED (9) // indicates that the TPM has
+ // been re-manufactured after an
+ // unrecoverable NV error
+#define FATAL_ERROR_DRBG (10)
+#define FATAL_ERROR_MOVE_SIZE (11)
+#define FATAL_ERROR_COUNTER_OVERFLOW (12)
+#define FATAL_ERROR_SUBTRACT (13)
+#define FATAL_ERROR_FORCED (666)
+
+#endif
diff --git a/src/tpm2/TpmFail.c b/src/tpm2/TpmFail.c
new file mode 100644
index 0000000..8912f33
--- /dev/null
+++ b/src/tpm2/TpmFail.c
@@ -0,0 +1,527 @@
+/********************************************************************************/
+/* */
+/* Failure Mode Handling */
+/* Written by Ken Goldman */
+/* IBM Thomas J. Watson Research Center */
+/* $Id: TpmFail.c 1644 2020-09-11 17:25:11Z kgoldman $ */
+/* */
+/* Licenses and Notices */
+/* */
+/* 1. Copyright Licenses: */
+/* */
+/* - Trusted Computing Group (TCG) grants to the user of the source code in */
+/* this specification (the "Source Code") a worldwide, irrevocable, */
+/* nonexclusive, royalty free, copyright license to reproduce, create */
+/* derivative works, distribute, display and perform the Source Code and */
+/* derivative works thereof, and to grant others the rights granted herein. */
+/* */
+/* - The TCG grants to the user of the other parts of the specification */
+/* (other than the Source Code) the rights to reproduce, distribute, */
+/* display, and perform the specification solely for the purpose of */
+/* developing products based on such documents. */
+/* */
+/* 2. Source Code Distribution Conditions: */
+/* */
+/* - Redistributions of Source Code must retain the above copyright licenses, */
+/* this list of conditions and the following disclaimers. */
+/* */
+/* - Redistributions in binary form must reproduce the above copyright */
+/* licenses, this list of conditions and the following disclaimers in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* 3. Disclaimers: */
+/* */
+/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
+/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
+/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
+/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
+/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
+/* information on specification licensing rights available through TCG */
+/* membership agreements. */
+/* */
+/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
+/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
+/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
+/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
+/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
+/* */
+/* - Without limitation, TCG and its members and licensors disclaim all */
+/* liability, including liability for infringement of any proprietary */
+/* rights, relating to use of information in this specification and to the */
+/* implementation of this specification, and TCG disclaims all liability for */
+/* cost of procurement of substitute goods or services, lost profits, loss */
+/* of use, loss of data or any incidental, consequential, direct, indirect, */
+/* or special damages, whether under contract, tort, warranty or otherwise, */
+/* arising in any way out of use or reliance upon this specification or any */
+/* information herein. */
+/* */
+/* (c) Copyright IBM Corp. and others, 2016 - 2019 */
+/* */
+/********************************************************************************/
+
+/* 9.17 TpmFail.c */
+/* 9.17.1 Includes, Defines, and Types */
+#define TPM_FAIL_C
+#include "Tpm.h"
+#include <assert.h>
+/* On MS C compiler, can save the alignment state and set the alignment to 1 for the duration of
+ the TpmTypes.h include. This will avoid a lot of alignment warnings from the compiler for
+ the unaligned structures. The alignment of the structures is not important as this function
+ does not use any of the structures in TpmTypes.h and only include it for the #defines of the
+ capabilities, properties, and command code values. */
+#include "TpmTypes.h"
+
+#define TPM_HAVE_TPM2_DECLARATIONS
+#include "tpm_library_intern.h" // libtpms added
+
+/* 9.17.2 Typedefs */
+/* These defines are used primarily for sizing of the local response buffer. */
+typedef struct
+{
+ TPM_ST tag;
+ UINT32 size;
+ TPM_RC code;
+} HEADER;
+typedef struct
+{
+ BYTE tag[sizeof(TPM_ST)];
+ BYTE size[sizeof(UINT32)];
+ BYTE code[sizeof(TPM_RC)];
+} PACKED_HEADER;
+typedef struct
+{
+ BYTE size[sizeof(UINT16)];
+ struct
+ {
+ BYTE function[sizeof(UINT32)];
+ BYTE line[sizeof(UINT32)];
+ BYTE code[sizeof(UINT32)];
+ } values;
+ BYTE returnCode[sizeof(TPM_RC)];
+} GET_TEST_RESULT_PARAMETERS;
+typedef struct
+{
+ BYTE moreData[sizeof(TPMI_YES_NO)];
+ BYTE capability[sizeof(TPM_CAP)]; // Always TPM_CAP_TPM_PROPERTIES
+ BYTE tpmProperty[sizeof(TPML_TAGGED_TPM_PROPERTY)];
+} GET_CAPABILITY_PARAMETERS;
+typedef struct
+{
+ BYTE header[sizeof(PACKED_HEADER)];
+ BYTE getTestResult[sizeof(GET_TEST_RESULT_PARAMETERS)];
+} TEST_RESPONSE;
+typedef struct
+{
+ BYTE header[sizeof(PACKED_HEADER)];
+ BYTE getCap[sizeof(GET_CAPABILITY_PARAMETERS)];
+} CAPABILITY_RESPONSE;
+typedef union
+{
+ BYTE test[sizeof(TEST_RESPONSE)];
+ BYTE cap[sizeof(CAPABILITY_RESPONSE)];
+} RESPONSES;
+
+/* Buffer to hold the responses. This may be a little larger than required due to padding that a
+ compiler might add. */
+/* NOTE: This is not in Global.c because of the specialized data definitions above. Since the data
+ contained in this structure is not relevant outside of the execution of a single command (when
+ the TPM is in failure mode. There is no compelling reason to move all the typedefs to Global.h
+ and this structure to Global.c. */
+#ifndef __IGNORE_STATE__ // Don't define this value
+static BYTE response[sizeof(RESPONSES)];
+#endif
+
+/* 9.17.3 Local Functions */
+
+/* 9.17.3.1 MarshalUint16() */
+/* Function to marshal a 16 bit value to the output buffer. */
+static INT32
+MarshalUint16(
+ UINT16 integer,
+ BYTE **buffer
+ )
+{
+ UINT16_TO_BYTE_ARRAY(integer, *buffer);
+ *buffer += 2;
+ return 2;
+}
+
+/* 9.17.3.2 MarshalUint32() */
+/* Function to marshal a 32 bit value to the output buffer. */
+static INT32
+MarshalUint32(
+ UINT32 integer,
+ BYTE **buffer
+ )
+{
+ UINT32_TO_BYTE_ARRAY(integer, *buffer);
+ *buffer += 4;
+ return 4;
+}
+
+/* 9.17.3.3 Unmarshal32() */
+static BOOL Unmarshal32(
+ UINT32 *target,
+ BYTE **buffer,
+ INT32 *size
+ )
+{
+ if((*size -= 4) < 0)
+ return FALSE;
+ *target = BYTE_ARRAY_TO_UINT32(*buffer);
+ *buffer += 4;
+ return TRUE;
+}
+
+/* 9.17.3.4 Unmarshal16() */
+static BOOL Unmarshal16(
+ UINT16 *target,
+ BYTE **buffer,
+ INT32 *size
+ )
+{
+ if((*size -= 2) < 0)
+ return FALSE;
+ *target = BYTE_ARRAY_TO_UINT16(*buffer);
+ *buffer += 2;
+ return TRUE;
+}
+
+/* 9.17.4Public Functions */
+#if 0 /* libtpms added */
+/* 9.17.4.1 SetForceFailureMode() */
+/* This function is called by the simulator to enable failure mode testing. */
+LIB_EXPORT void
+SetForceFailureMode(
+ void
+ )
+{
+#if SIMULATION
+ g_forceFailureMode = TRUE;
+#endif
+ return;
+}
+#endif /* libtpms added */
+
+/* 9.17.4.2 TpmLogFailure() */
+/* This function saves the failure values when the code will continue to operate. It if similar to
+ TpmFail() but returns to the caller. The assumption is that the caller will propagate a failure
+ back up the stack. */
+void
+TpmLogFailure(
+#if FAIL_TRACE
+ const char *function,
+ int line,
+#endif
+ int code
+ )
+{
+#if 0 // libtpms added
+ // Save the values that indicate where the error occurred.
+ // On a 64-bit machine, this may truncate the address of the string
+ // of the function name where the error occurred.
+#if FAIL_TRACE
+ memcpy(&s_failFunction, function, sizeof(uint32_t)); /* kgold */
+ s_failLine = line;
+#else
+ s_failFunction = 0;
+ s_failLine = 0;
+#endif
+ s_failCode = code;
+
+ // We are in failure mode
+ g_inFailureMode = TRUE;
+#else // libtpms added begin
+
+ TpmSetFailureMode(
+#if FAIL_TRACE
+ function, line,
+#endif
+ code);
+
+#endif // libtpms added end
+ return;
+}
+/* 9.17.4.2 TpmFail() */
+/* This function is called by TPM.lib when a failure occurs. It will set up the failure values to be
+ returned on TPM2_GetTestResult(). */
+NORETURN void
+TpmFail(
+#if FAIL_TRACE
+ const char *function,
+ int line,
+#endif
+ int code
+ )
+{
+#if 0 /* libtpms added */
+ // Save the values that indicate where the error occurred.
+ // On a 64-bit machine, this may truncate the address of the string
+ // of the function name where the error occurred.
+#if FAIL_TRACE
+ memcpy(&s_failFunction, function, sizeof(uint32_t));
+ s_failLine = line;
+#else
+ s_failFunction = (UINT32)NULL;
+ s_failLine = 0;
+#endif
+ s_failCode = code;
+ // We are in failure mode
+ g_inFailureMode = TRUE;
+ // if asserts are enabled, then do an assert unless the failure mode code
+ // is being tested.
+#if SIMULATION
+# ifndef NDEBUG
+ assert(g_forceFailureMode);
+# endif
+ // Clear this flag
+ g_forceFailureMode = FALSE;
+#endif
+
+#else /* libtpms added begin */
+
+ TpmSetFailureMode(
+#if FAIL_TRACE
+ function, line,
+#endif
+ code);
+
+#endif /* libtpms added end */
+ // Jump to the failure mode code.
+ // Note: only get here if asserts are off or if we are testing failure mode
+ _plat__Fail();
+}
+
+/* libtpms added begin */
+void
+TpmSetFailureMode(
+#if FAIL_TRACE
+ const char *function,
+ int line,
+#endif
+ int code
+ )
+{
+ // Save the values that indicate where the error occurred.
+ // On a 64-bit machine, this may truncate the address of the string
+ // of the function name where the error occurred.
+#if FAIL_TRACE
+ s_failFunction = *(UINT32 *)function;
+ s_failLine = line;
+#else
+ s_failFunction = (UINT32)0;
+ s_failLine = 0;
+#endif
+ s_failCode = code;
+
+ TPMLIB_LogTPM2Error("Entering failure mode; code: %d"
+#if FAIL_TRACE
+ ", location: %s line %d"
+#endif
+ "\n", s_failCode
+#if FAIL_TRACE
+ , function, s_failLine
+#endif
+ );
+
+ // We are in failure mode
+ g_inFailureMode = TRUE;
+}
+/* libtpms added end */
+/* 9.17.5 TpmFailureMode */
+/* This function is called by the interface code when the platform is in failure mode. */
+void
+TpmFailureMode(
+ unsigned int inRequestSize, // IN: command buffer size
+ unsigned char *inRequest, // IN: command buffer
+ unsigned int *outResponseSize, // OUT: response buffer size
+ unsigned char **outResponse // OUT: response buffer
+ )
+{
+ UINT32 marshalSize;
+ UINT32 capability;
+ HEADER header; // unmarshaled command header
+ UINT32 pt; // unmarshaled property type
+ UINT32 count; // unmarshaled property count
+ UINT8 *buffer = inRequest;
+ INT32 size = inRequestSize;
+
+ // If there is no command buffer, then just return TPM_RC_FAILURE
+ if(inRequestSize == 0 || inRequest == NULL)
+ goto FailureModeReturn;
+ // If the header is not correct for TPM2_GetCapability() or
+ // TPM2_GetTestResult() then just return the in failure mode response;
+ if(! (Unmarshal16(&header.tag, &buffer, &size)
+ && Unmarshal32(&header.size, &buffer, &size)
+ && Unmarshal32(&header.code, &buffer, &size)))
+ goto FailureModeReturn;
+ if(header.tag != TPM_ST_NO_SESSIONS
+ || header.size < 10)
+ goto FailureModeReturn;
+ switch(header.code)
+ {
+ case TPM_CC_GetTestResult:
+ // make sure that the command size is correct
+ if(header.size != 10)
+ goto FailureModeReturn;
+ buffer = &response[10];
+ marshalSize = MarshalUint16(3 * sizeof(UINT32), &buffer);
+ marshalSize += MarshalUint32(s_failFunction, &buffer);
+ marshalSize += MarshalUint32(s_failLine, &buffer);
+ marshalSize += MarshalUint32(s_failCode, &buffer);
+ if(s_failCode == FATAL_ERROR_NV_UNRECOVERABLE)
+ marshalSize += MarshalUint32(TPM_RC_NV_UNINITIALIZED, &buffer);
+ else
+ marshalSize += MarshalUint32(TPM_RC_FAILURE, &buffer);
+ break;
+ case TPM_CC_GetCapability:
+ // make sure that the size of the command is exactly the size
+ // returned for the capability, property, and count
+ if(header.size != (10 + (3 * sizeof(UINT32)))
+ // also verify that this is requesting TPM properties
+ || !Unmarshal32(&capability, &buffer, &size)
+ || capability != TPM_CAP_TPM_PROPERTIES
+ || !Unmarshal32(&pt, &buffer, &size)
+ || !Unmarshal32(&count, &buffer, &size))
+ goto FailureModeReturn;
+ // If in failure mode because of an unrecoverable read error, and the
+ // property is 0 and the count is 0, then this is an indication to
+ // re-manufacture the TPM. Do the re-manufacture but stay in failure
+ // mode until the TPM is reset.
+ // Note: this behavior is not required by the specification and it is
+ // OK to leave the TPM permanently bricked due to an unrecoverable NV
+ // error.
+ if(count == 0 && pt == 0 && s_failCode == FATAL_ERROR_NV_UNRECOVERABLE)
+ {
+ g_manufactured = FALSE;
+ TPM_Manufacture(0);
+ }
+ if(count > 0)
+ count = 1;
+ else if(pt > TPM_PT_FIRMWARE_VERSION_2)
+ count = 0;
+ if(pt < TPM_PT_MANUFACTURER)
+ pt = TPM_PT_MANUFACTURER;
+ // set up for return
+ buffer = &response[10];
+ // if the request was for a PT less than the last one
+ // then we indicate more, otherwise, not.
+ if(pt < TPM_PT_FIRMWARE_VERSION_2)
+ *buffer++ = YES;
+ else
+ *buffer++ = NO;
+ marshalSize = 1;
+ // indicate the capability type
+ marshalSize += MarshalUint32(capability, &buffer);
+ // indicate the number of values that are being returned (0 or 1)
+ marshalSize += MarshalUint32(count, &buffer);
+ // indicate the property
+ marshalSize += MarshalUint32(pt, &buffer);
+ if(count > 0)
+ switch(pt)
+ {
+ case TPM_PT_MANUFACTURER:
+ // the vendor ID unique to each TPM manufacturer
+#ifdef MANUFACTURER
+ pt = *(UINT32*)MANUFACTURER;
+#else
+ pt = 0;
+#endif
+ break;
+ case TPM_PT_VENDOR_STRING_1:
+ // the first four characters of the vendor ID string
+#ifdef VENDOR_STRING_1
+ pt = *(UINT32*)VENDOR_STRING_1;
+#else
+ pt = 0;
+#endif
+ break;
+ case TPM_PT_VENDOR_STRING_2:
+ // the second four characters of the vendor ID string
+#ifdef VENDOR_STRING_2
+ pt = *(UINT32*)VENDOR_STRING_2;
+#else
+ pt = 0;
+#endif
+ break;
+ case TPM_PT_VENDOR_STRING_3:
+ // the third four characters of the vendor ID string
+#ifdef VENDOR_STRING_3
+ pt = *(UINT32*)VENDOR_STRING_3;
+#else
+ pt = 0;
+#endif
+ break;
+ case TPM_PT_VENDOR_STRING_4:
+ // the fourth four characters of the vendor ID string
+#ifdef VENDOR_STRING_4
+ pt = *(UINT32*)VENDOR_STRING_4;
+#else
+ pt = 0;
+#endif
+ break;
+ case TPM_PT_VENDOR_TPM_TYPE:
+ // vendor-defined value indicating the TPM model
+ // We just make up a number here
+ pt = 1;
+ break;
+ case TPM_PT_FIRMWARE_VERSION_1:
+ // the more significant 32-bits of a vendor-specific value
+ // indicating the version of the firmware
+#ifdef FIRMWARE_V1
+ pt = FIRMWARE_V1;
+#else
+ pt = 0;
+#endif
+ break;
+ default: // TPM_PT_FIRMWARE_VERSION_2:
+ // the less significant 32-bits of a vendor-specific value
+ // indicating the version of the firmware
+#ifdef FIRMWARE_V2
+ pt = FIRMWARE_V2;
+#else
+ pt = 0;
+#endif
+ break;
+ }
+ marshalSize += MarshalUint32(pt, &buffer);
+ break;
+ default: // default for switch (cc)
+ goto FailureModeReturn;
+ }
+ // Now do the header
+ buffer = response;
+ marshalSize = marshalSize + 10; // Add the header size to the
+ // stuff already marshaled
+ MarshalUint16(TPM_ST_NO_SESSIONS, &buffer); // structure tag
+ MarshalUint32(marshalSize, &buffer); // responseSize
+ MarshalUint32(TPM_RC_SUCCESS, &buffer); // response code
+ *outResponseSize = marshalSize;
+ *outResponse = (unsigned char *)&response;
+ return;
+ FailureModeReturn:
+ buffer = response;
+ marshalSize = MarshalUint16(TPM_ST_NO_SESSIONS, &buffer);
+ marshalSize += MarshalUint32(10, &buffer);
+ marshalSize += MarshalUint32(TPM_RC_FAILURE, &buffer);
+ *outResponseSize = marshalSize;
+ *outResponse = (unsigned char *)response;
+ return;
+}
+#if 0 // libtpms added
+/* 9.17.6 UnmarshalFail() */
+/* This is a stub that is used to catch an attempt to unmarshal an entry that is not defined. Don't
+ ever expect this to be called but... */
+void
+UnmarshalFail(
+ void *type,
+ BYTE **buffer,
+ INT32 *size
+ )
+{
+ NOT_REFERENCED(type);
+ NOT_REFERENCED(buffer);
+ NOT_REFERENCED(size);
+ FAIL(FATAL_ERROR_INTERNAL);
+}
+#endif // libtpms added
diff --git a/src/tpm2/TpmFail_fp.h b/src/tpm2/TpmFail_fp.h
new file mode 100644
index 0000000..f924689
--- /dev/null
+++ b/src/tpm2/TpmFail_fp.h
@@ -0,0 +1,114 @@
+/********************************************************************************/
+/* */
+/* Failure Mode Handling */
+/* Written by Ken Goldman */
+/* IBM Thomas J. Watson Research Center */
+/* $Id: TpmFail_fp.h 1490 2019-07-26 21:13:22Z kgoldman $ */
+/* */
+/* Licenses and Notices */
+/* */
+/* 1. Copyright Licenses: */
+/* */
+/* - Trusted Computing Group (TCG) grants to the user of the source code in */
+/* this specification (the "Source Code") a worldwide, irrevocable, */
+/* nonexclusive, royalty free, copyright license to reproduce, create */
+/* derivative works, distribute, display and perform the Source Code and */
+/* derivative works thereof, and to grant others the rights granted herein. */
+/* */
+/* - The TCG grants to the user of the other parts of the specification */
+/* (other than the Source Code) the rights to reproduce, distribute, */
+/* display, and perform the specification solely for the purpose of */
+/* developing products based on such documents. */
+/* */
+/* 2. Source Code Distribution Conditions: */
+/* */
+/* - Redistributions of Source Code must retain the above copyright licenses, */
+/* this list of conditions and the following disclaimers. */
+/* */
+/* - Redistributions in binary form must reproduce the above copyright */
+/* licenses, this list of conditions and the following disclaimers in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* 3. Disclaimers: */
+/* */
+/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
+/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
+/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
+/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
+/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
+/* information on specification licensing rights available through TCG */
+/* membership agreements. */
+/* */
+/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
+/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
+/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
+/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
+/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
+/* */
+/* - Without limitation, TCG and its members and licensors disclaim all */
+/* liability, including liability for infringement of any proprietary */
+/* rights, relating to use of information in this specification and to the */
+/* implementation of this specification, and TCG disclaims all liability for */
+/* cost of procurement of substitute goods or services, lost profits, loss */
+/* of use, loss of data or any incidental, consequential, direct, indirect, */
+/* or special damages, whether under contract, tort, warranty or otherwise, */
+/* arising in any way out of use or reliance upon this specification or any */
+/* information herein. */
+/* */
+/* (c) Copyright IBM Corp. and others, 2016 - 2019 */
+/* */
+/********************************************************************************/
+
+#ifndef TPMFAIL_FP_H
+#define TPMFAIL_FP_H
+
+#include "BaseTypes.h"
+
+#if 0 /* libtpms added */
+LIB_EXPORT void
+SetForceFailureMode(
+ void
+ );
+#endif /* libtpms added */
+void
+TpmLogFailure(
+#if FAIL_TRACE
+ const char *function,
+ int line,
+#endif
+ int code
+ );
+NORETURN void
+TpmFail(
+#if FAIL_TRACE /* libtpms added begin */
+ const char *function,
+ int line,
+#endif
+ int code
+ );
+void
+TpmSetFailureMode(
+#if FAIL_TRACE /* libtpms added end */
+ const char *function,
+ int line,
+#endif
+ int code
+ );
+void
+TpmFailureMode(
+ unsigned int inRequestSize, // IN: command buffer size
+ unsigned char *inRequest, // IN: command buffer
+ unsigned int *outResponseSize, // OUT: response buffer size
+ unsigned char **outResponse // OUT: response buffer
+ );
+#if 0 /* libtpms added */
+void
+UnmarshalFail(
+ void *type,
+ BYTE **buffer,
+ INT32 *size
+ );
+#endif /* libtpms added */
+
+
+#endif
diff --git a/src/tpm2/TpmProfile.h b/src/tpm2/TpmProfile.h
new file mode 100644
index 0000000..49aaad1
--- /dev/null
+++ b/src/tpm2/TpmProfile.h
@@ -0,0 +1,865 @@
+/********************************************************************************/
+/* */
+/* Constants Reflecting a Particular TPM Implementation (e.g. PC Client) */
+/* Written by Ken Goldman */
+/* IBM Thomas J. Watson Research Center */
+/* $Id: TpmProfile.h 1629 2020-06-01 20:50:13Z kgoldman $ */
+/* */
+/* Licenses and Notices */
+/* */
+/* 1. Copyright Licenses: */
+/* */
+/* - Trusted Computing Group (TCG) grants to the user of the source code in */
+/* this specification (the "Source Code") a worldwide, irrevocable, */
+/* nonexclusive, royalty free, copyright license to reproduce, create */
+/* derivative works, distribute, display and perform the Source Code and */
+/* derivative works thereof, and to grant others the rights granted herein. */
+/* */
+/* - The TCG grants to the user of the other parts of the specification */
+/* (other than the Source Code) the rights to reproduce, distribute, */
+/* display, and perform the specification solely for the purpose of */
+/* developing products based on such documents. */
+/* */
+/* 2. Source Code Distribution Conditions: */
+/* */
+/* - Redistributions of Source Code must retain the above copyright licenses, */
+/* this list of conditions and the following disclaimers. */
+/* */
+/* - Redistributions in binary form must reproduce the above copyright */
+/* licenses, this list of conditions and the following disclaimers in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* 3. Disclaimers: */
+/* */
+/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
+/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
+/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
+/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
+/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
+/* information on specification licensing rights available through TCG */
+/* membership agreements. */
+/* */
+/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
+/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
+/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
+/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
+/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
+/* */
+/* - Without limitation, TCG and its members and licensors disclaim all */
+/* liability, including liability for infringement of any proprietary */
+/* rights, relating to use of information in this specification and to the */
+/* implementation of this specification, and TCG disclaims all liability for */
+/* cost of procurement of substitute goods or services, lost profits, loss */
+/* of use, loss of data or any incidental, consequential, direct, indirect, */
+/* or special damages, whether under contract, tort, warranty or otherwise, */
+/* arising in any way out of use or reliance upon this specification or any */
+/* information herein. */
+/* */
+/* (c) Copyright IBM Corp. and others, 2019 - 2020 */
+/* */
+/********************************************************************************/
+
+// FOR LIBTPMS: DO NOT EDIT THIS FILE!
+// ANY MODIFICATION WILL LEAD TO AN UNSUPPORTED CONFIGURATION
+
+// A.2 TpmProfile.h
+#ifndef _TPM_PROFILE_H_
+#define _TPM_PROFILE_H_
+// Table 2:4 - Defines for Logic Values
+#undef TRUE
+#define TRUE 1
+#undef FALSE
+#define FALSE 0
+#undef YES
+#define YES 1
+#undef NO
+#define NO 0
+#undef SET
+#define SET 1
+#undef CLEAR
+#define CLEAR 0
+// Table 0:1 - Defines for Processor Values
+#if defined __FreeBSD__ || defined __DragonFly__ /* libtpms added begin */
+# include <sys/endian.h>
+#elif defined __APPLE__
+# include <libkern/OSByteOrder.h>
+#else
+# include <endian.h>
+#endif
+#if defined __linux__ || defined __CYGWIN__
+ #if __BYTE_ORDER == __LITTLE_ENDIAN
+ #define BIG_ENDIAN_TPM NO
+ #endif
+ #if __BYTE_ORDER == __BIG_ENDIAN
+ #define BIG_ENDIAN_TPM YES
+ #endif
+#elif defined __OpenBSD__ || defined __FreeBSD__ || defined __NetBSD__ \
+ || defined __DragonFly__
+ #if _BYTE_ORDER == _LITTLE_ENDIAN
+ #define BIG_ENDIAN_TPM NO
+ #endif
+ #if _BYTE_ORDER == _BIG_ENDIAN
+ #define BIG_ENDIAN_TPM YES
+ #endif
+#elif defined __APPLE__
+ #define BIG_ENDIAN_TPM NO
+#else
+ #error Unsupported OS
+#endif /* libtpms added end */
+#ifndef BIG_ENDIAN_TPM
+#define BIG_ENDIAN_TPM NO
+#endif
+#ifndef LITTLE_ENDIAN_TPM
+#define LITTLE_ENDIAN_TPM !BIG_ENDIAN_TPM
+#endif
+#ifndef MOST_SIGNIFICANT_BIT_0
+#define MOST_SIGNIFICANT_BIT_0 NO
+#endif
+#ifndef LEAST_SIGNIFICANT_BIT_0
+#define LEAST_SIGNIFICANT_BIT_0 !MOST_SIGNIFICANT_BIT_0
+#endif
+#ifndef AUTO_ALIGN
+#define AUTO_ALIGN NO
+#endif
+// Table 0:4 - Defines for Implemented Curves
+#ifndef ECC_NIST_P192
+#define ECC_NIST_P192 YES /* libtpms enabled */
+#endif
+#ifndef ECC_NIST_P224
+#define ECC_NIST_P224 YES /* libtpms enabled */
+#endif
+#ifndef ECC_NIST_P256
+#define ECC_NIST_P256 YES
+#endif
+#ifndef ECC_NIST_P384
+#define ECC_NIST_P384 YES
+#endif
+#ifndef ECC_NIST_P521
+#define ECC_NIST_P521 YES /* libtpms enabled */
+#endif
+#ifndef ECC_BN_P256
+#define ECC_BN_P256 YES
+#endif
+#ifndef ECC_BN_P638
+#define ECC_BN_P638 YES /* libtpms enabled */
+#endif
+#ifndef ECC_SM2_P256
+#define ECC_SM2_P256 YES /* libtpms enabled */
+#endif
+
+/* Table 0:6 - Defines for Implemented ACT */
+
+#ifndef RH_ACT_0
+#define RH_ACT_0 NO /* libtpms: no */
+#endif
+#ifndef RH_ACT_1
+#define RH_ACT_1 NO
+#endif
+#ifndef RH_ACT_A
+#define RH_ACT_A NO /* libtpms: no */
+#endif
+// libtpms added begin
+#if RH_ACT_0 + RH_ACT_1 + RH_ACT_2 + RH_ACT_3 + RH_ACT_4 + \
+ RH_ACT_1 + RH_ACT_5 + RH_ACT_6 + RH_ACT_7 + RH_ACT_8 + \
+ RH_ACT_9 + RH_ACT_A + RH_ACT_B + RH_ACT_C + RH_ACT_D + \
+ RH_ACT_E + RH_ACT_F == 0
+#define __ACT_DISABLED
+#endif
+// libtpms added end
+
+// Table 0:7 - Defines for Implementation Values
+#ifndef FIELD_UPGRADE_IMPLEMENTED
+#define FIELD_UPGRADE_IMPLEMENTED NO
+#endif
+
+#ifdef TPM_POSIX // libtpms added begin
+# include <openssl/bn.h>
+# ifdef THIRTY_TWO_BIT
+# define RADIX_BITS 32
+# endif
+# ifdef SIXTY_FOUR_BIT_LONG
+# define RADIX_BITS 64
+# endif
+# ifndef RADIX_BITS
+# error Need to determine RADIX_BITS value
+# endif
+#endif
+#ifdef TPM_WINDOWS
+#define RADIX_BITS 32
+#endif // libtpms added end
+
+#ifndef HASH_LIB
+#define HASH_LIB Ossl
+#endif
+#ifndef SYM_LIB
+#define SYM_LIB Ossl
+#endif
+#ifndef MATH_LIB
+#define MATH_LIB Ossl
+#endif
+#ifndef IMPLEMENTATION_PCR
+#define IMPLEMENTATION_PCR 24
+#endif
+#ifndef PLATFORM_PCR
+#define PLATFORM_PCR 24
+#endif
+#ifndef DRTM_PCR
+#define DRTM_PCR 17
+#endif
+#ifndef HCRTM_PCR
+#define HCRTM_PCR 0
+#endif
+#ifndef NUM_LOCALITIES
+#define NUM_LOCALITIES 5
+#endif
+#ifndef MAX_HANDLE_NUM
+#define MAX_HANDLE_NUM 3
+#endif
+#ifndef MAX_ACTIVE_SESSIONS
+#define MAX_ACTIVE_SESSIONS 64
+#endif
+#ifndef CONTEXT_SLOT
+#define CONTEXT_SLOT UINT16 /* libtpms: changed from UINT8 in v0.9.0 */
+#endif
+#ifndef MAX_LOADED_SESSIONS
+#define MAX_LOADED_SESSIONS 3
+#endif
+#ifndef MAX_SESSION_NUM
+#define MAX_SESSION_NUM 3
+#endif
+#ifndef MAX_LOADED_OBJECTS
+#define MAX_LOADED_OBJECTS 3
+#endif
+#ifndef MIN_EVICT_OBJECTS
+#define MIN_EVICT_OBJECTS 7 /* libtpms changed -- for PC profile */
+#endif
+#ifndef NUM_POLICY_PCR_GROUP
+#define NUM_POLICY_PCR_GROUP 1
+#endif
+#ifndef NUM_AUTHVALUE_PCR_GROUP
+#define NUM_AUTHVALUE_PCR_GROUP 1
+#endif
+#ifndef MAX_CONTEXT_SIZE
+#define MAX_CONTEXT_SIZE 2680 /* libtpms changed */
+#endif
+#ifndef MAX_DIGEST_BUFFER
+#define MAX_DIGEST_BUFFER 1024
+#endif
+#ifndef MAX_NV_INDEX_SIZE
+#define MAX_NV_INDEX_SIZE 2048
+#endif
+#ifndef MAX_NV_BUFFER_SIZE
+#define MAX_NV_BUFFER_SIZE 1024
+#endif
+#ifndef MAX_CAP_BUFFER
+#define MAX_CAP_BUFFER 1024
+#endif
+
+/* for PC client, permits
+
+ 1300 bytes reserved
+ 7 * 2600 persistent objects
+ 4000 NV indexes
+ 60 * 68 nv index metadata
+*/
+
+#ifndef NV_MEMORY_SIZE
+/* libtmps: 65 OBJECTs in USER NVRAM expanded by 704 bytes due to size
+ * increase of OBJECT from 2048 bit RSA keys to 3072 bit by 704 bytes*/
+#define NV_MEMORY_SIZE (128 * 1024 + 65 * 704) /* libtpms changed */
+#endif
+#ifndef MIN_COUNTER_INDICES
+#define MIN_COUNTER_INDICES 8
+#endif
+#ifndef NUM_STATIC_PCR
+#define NUM_STATIC_PCR 16
+#endif
+#ifndef MAX_ALG_LIST_SIZE
+#define MAX_ALG_LIST_SIZE 64
+#endif
+#ifndef PRIMARY_SEED_SIZE
+#define PRIMARY_SEED_SIZE 64 /* libtpms: 64 per define USE_SPEC_COMPLIANT_PROOFS */
+#endif
+#ifndef CONTEXT_ENCRYPT_ALGORITHM
+#define CONTEXT_ENCRYPT_ALGORITHM AES
+#endif
+#ifndef NV_CLOCK_UPDATE_INTERVAL
+#define NV_CLOCK_UPDATE_INTERVAL 12
+#endif
+#ifndef NUM_POLICY_PCR
+#define NUM_POLICY_PCR 1
+#endif
+#ifndef MAX_COMMAND_SIZE
+#define MAX_COMMAND_SIZE TPM2_GetBufferSize() /* libtpms changed */
+#endif
+#ifndef MAX_RESPONSE_SIZE
+#define MAX_RESPONSE_SIZE TPM2_GetBufferSize() /* libtpms changed */
+#endif
+#ifndef ORDERLY_BITS
+#define ORDERLY_BITS 8
+#endif
+#ifndef MAX_SYM_DATA
+#define MAX_SYM_DATA 128
+#endif
+#ifndef MAX_RNG_ENTROPY_SIZE
+#define MAX_RNG_ENTROPY_SIZE 64
+#endif
+#ifndef RAM_INDEX_SPACE
+#define RAM_INDEX_SPACE 512
+#endif
+#ifndef RSA_DEFAULT_PUBLIC_EXPONENT
+#define RSA_DEFAULT_PUBLIC_EXPONENT 0x00010001
+#endif
+#ifndef ENABLE_PCR_NO_INCREMENT
+#define ENABLE_PCR_NO_INCREMENT YES
+#endif
+#ifndef CRT_FORMAT_RSA
+#define CRT_FORMAT_RSA YES
+#endif
+#ifndef VENDOR_COMMAND_COUNT
+#define VENDOR_COMMAND_COUNT 0
+#endif
+#ifndef MAX_VENDOR_BUFFER_SIZE
+#define MAX_VENDOR_BUFFER_SIZE 1024
+#endif
+#ifndef SIZE_OF_X509_SERIAL_NUMBER
+#define SIZE_OF_X509_SERIAL_NUMBER 20
+#endif
+#ifndef PRIVATE_VENDOR_SPECIFIC_BYTES
+#define PRIVATE_VENDOR_SPECIFIC_BYTES \
+ ((MAX_RSA_KEY_BYTES/2) * (3 + CRT_FORMAT_RSA * 2)) /* libtpms: keep as was in rev 150 */
+#endif
+// Table 0:2 - Defines for Implemented Algorithms
+#ifndef ALG_AES
+#define ALG_AES ALG_YES
+#endif
+#ifndef ALG_CAMELLIA
+#define ALG_CAMELLIA ALG_YES /* libtpms: YES since v0.9 */
+#endif
+#ifndef ALG_CBC
+#define ALG_CBC ALG_YES
+#endif
+#ifndef ALG_CFB
+#define ALG_CFB ALG_YES
+#endif
+#ifndef ALG_CMAC
+#define ALG_CMAC ALG_YES
+#endif
+#ifndef ALG_CTR
+#define ALG_CTR ALG_YES
+#endif
+#ifndef ALG_ECB
+#define ALG_ECB ALG_YES
+#endif
+#ifndef ALG_ECC
+#define ALG_ECC ALG_YES
+#endif
+#ifndef ALG_ECDAA
+#define ALG_ECDAA (ALG_YES && ALG_ECC)
+#endif
+#ifndef ALG_ECDH
+#define ALG_ECDH (ALG_YES && ALG_ECC)
+#endif
+#ifndef ALG_ECDSA
+#define ALG_ECDSA (ALG_YES && ALG_ECC)
+#endif
+#ifndef ALG_ECMQV
+#define ALG_ECMQV (ALG_YES && ALG_ECC) /* libtpms enabled */
+#endif
+#ifndef ALG_ECSCHNORR
+#define ALG_ECSCHNORR (ALG_YES && ALG_ECC)
+#endif
+#ifndef ALG_HMAC
+#define ALG_HMAC ALG_YES
+#endif
+#ifndef ALG_KDF1_SP800_108
+#define ALG_KDF1_SP800_108 ALG_YES
+#endif
+#ifndef ALG_KDF1_SP800_56A
+#define ALG_KDF1_SP800_56A (ALG_YES && ALG_ECC)
+#endif
+#ifndef ALG_KDF2
+#define ALG_KDF2 ALG_YES
+#endif
+#ifndef ALG_KEYEDHASH
+#define ALG_KEYEDHASH ALG_YES
+#endif
+#ifndef ALG_MGF1
+#define ALG_MGF1 ALG_YES
+#endif
+#ifndef ALG_OAEP
+#define ALG_OAEP (ALG_YES && ALG_RSA)
+#endif
+#ifndef ALG_OFB
+#define ALG_OFB ALG_YES
+#endif
+#ifndef ALG_RSA
+#define ALG_RSA ALG_YES
+#endif
+#ifndef ALG_RSAES
+#define ALG_RSAES (ALG_YES && ALG_RSA)
+#endif
+#ifndef ALG_RSAPSS
+#define ALG_RSAPSS (ALG_YES && ALG_RSA)
+#endif
+#ifndef ALG_RSASSA
+#define ALG_RSASSA (ALG_YES && ALG_RSA)
+#endif
+#ifndef ALG_SHA
+#define ALG_SHA ALG_NO /* Not specified by vendor */
+#endif
+#ifndef ALG_SHA1
+#define ALG_SHA1 ALG_YES
+#endif
+#ifndef ALG_SHA256
+#define ALG_SHA256 ALG_YES
+#endif
+#ifndef ALG_SHA384
+#define ALG_SHA384 ALG_YES
+#endif
+#ifndef ALG_SHA3_256
+#define ALG_SHA3_256 ALG_NO /* Not specified by vendor */
+#endif
+#ifndef ALG_SHA3_384
+#define ALG_SHA3_384 ALG_NO /* Not specified by vendor */
+#endif
+#ifndef ALG_SHA3_512
+#define ALG_SHA3_512 ALG_NO /* Not specified by vendor */
+#endif
+#ifndef ALG_SHA512
+#define ALG_SHA512 ALG_YES
+#endif
+#ifndef ALG_SM2
+#define ALG_SM2 (ALG_YES && ALG_ECC) /* libtpms enabled */
+#endif
+#ifndef ALG_SM3_256
+#define ALG_SM3_256 ALG_NO /* libtpms: NO */
+#endif
+#ifndef ALG_SM4
+#define ALG_SM4 ALG_NO /* libtpms: NO */
+#endif
+#ifndef ALG_SYMCIPHER
+#define ALG_SYMCIPHER ALG_YES
+#endif
+#ifndef ALG_TDES
+#define ALG_TDES ALG_YES /* libtpms enabled */
+#endif
+#ifndef ALG_XOR
+#define ALG_XOR ALG_YES
+#endif
+// Table 1:00 - Defines for RSA Asymmetric Cipher Algorithm Constants
+#ifndef RSA_1024
+#define RSA_1024 (ALG_RSA && YES)
+#endif
+#ifndef RSA_2048
+#define RSA_2048 (ALG_RSA && YES)
+#endif
+#ifndef RSA_3072
+#define RSA_3072 (ALG_RSA && YES)
+#endif
+#ifndef RSA_4096
+#define RSA_4096 (ALG_RSA && NO)
+#endif
+#ifndef RSA_16384
+#define RSA_16384 (ALG_RSA && NO)
+#endif
+
+// Table 1:17 - Defines for AES Symmetric Cipher Algorithm Constants
+#ifndef AES_128
+#define AES_128 (ALG_AES && YES)
+#endif
+#ifndef AES_192
+#define AES_192 (ALG_AES && NO)
+#endif
+#ifndef AES_256
+#define AES_256 (ALG_AES && YES)
+#endif
+// Table 1:18 - Defines for SM4 Symmetric Cipher Algorithm Constants
+#ifndef SM4_128
+#define SM4_128 (ALG_SM4 && YES)
+#endif
+// Table 1:19 - Defines for CAMELLIA Symmetric Cipher Algorithm Constants
+#ifndef CAMELLIA_128
+#define CAMELLIA_128 (ALG_CAMELLIA && YES)
+#endif
+#ifndef CAMELLIA_192
+#define CAMELLIA_192 (ALG_CAMELLIA && NO)
+#endif
+#ifndef CAMELLIA_256
+#define CAMELLIA_256 (ALG_CAMELLIA && YES)
+#endif
+// Table 1:17 - Defines for TDES Symmetric Cipher Algorithm Constants
+#ifndef TDES_128
+#define TDES_128 (ALG_TDES && YES)
+#endif
+#ifndef TDES_192
+#define TDES_192 (ALG_TDES && YES)
+#endif
+// Table 0:5 - Defines for Implemented Commands
+#ifndef CC_ACT_SetTimeout
+#define CC_ACT_SetTimeout CC_NO /* libtpms: NO */
+#endif
+#ifndef CC_AC_GetCapability
+#define CC_AC_GetCapability CC_NO /* kgold */
+#endif
+#ifndef CC_AC_Send
+#define CC_AC_Send CC_NO /* kgold */
+#endif
+#ifndef CC_ActivateCredential
+#define CC_ActivateCredential CC_YES
+#endif
+#ifndef CC_Certify
+#define CC_Certify CC_YES
+#endif
+#ifndef CC_CertifyCreation
+#define CC_CertifyCreation CC_YES
+#endif
+#ifndef CC_CertifyX509
+#define CC_CertifyX509 CC_YES
+#endif
+#ifndef CC_ChangeEPS
+#define CC_ChangeEPS CC_YES
+#endif
+#ifndef CC_ChangePPS
+#define CC_ChangePPS CC_YES
+#endif
+#ifndef CC_Clear
+#define CC_Clear CC_YES
+#endif
+#ifndef CC_ClearControl
+#define CC_ClearControl CC_YES
+#endif
+#ifndef CC_ClockRateAdjust
+#define CC_ClockRateAdjust CC_YES
+#endif
+#ifndef CC_ClockSet
+#define CC_ClockSet CC_YES
+#endif
+#ifndef CC_Commit
+#define CC_Commit (CC_YES && ALG_ECC)
+#endif
+#ifndef CC_ContextLoad
+#define CC_ContextLoad CC_YES
+#endif
+#ifndef CC_ContextSave
+#define CC_ContextSave CC_YES
+#endif
+#ifndef CC_Create
+#define CC_Create CC_YES
+#endif
+#ifndef CC_CreateLoaded
+#define CC_CreateLoaded CC_YES
+#endif
+#ifndef CC_CreatePrimary
+#define CC_CreatePrimary CC_YES
+#endif
+#ifndef CC_DictionaryAttackLockReset
+#define CC_DictionaryAttackLockReset CC_YES
+#endif
+#ifndef CC_DictionaryAttackParameters
+#define CC_DictionaryAttackParameters CC_YES
+#endif
+#ifndef CC_Duplicate
+#define CC_Duplicate CC_YES
+#endif
+#ifndef CC_ECC_Decrypt
+#define CC_ECC_Decrypt (CC_NO && ALG_ECC)
+#endif
+#ifndef CC_ECC_Encrypt
+#define CC_ECC_Encrypt (CC_NO && ALG_ECC)
+#endif
+#ifndef CC_ECC_Parameters
+#define CC_ECC_Parameters (CC_YES && ALG_ECC)
+#endif
+#ifndef CC_ECDH_KeyGen
+#define CC_ECDH_KeyGen (CC_YES && ALG_ECC)
+#endif
+#ifndef CC_ECDH_ZGen
+#define CC_ECDH_ZGen (CC_YES && ALG_ECC)
+#endif
+#ifndef CC_EC_Ephemeral
+#define CC_EC_Ephemeral (CC_YES && ALG_ECC)
+#endif
+#ifndef CC_EncryptDecrypt
+#define CC_EncryptDecrypt CC_YES
+#endif
+#ifndef CC_EncryptDecrypt2
+#define CC_EncryptDecrypt2 CC_YES
+#endif
+#ifndef CC_EventSequenceComplete
+#define CC_EventSequenceComplete CC_YES
+#endif
+#ifndef CC_EvictControl
+#define CC_EvictControl CC_YES
+#endif
+#ifndef CC_FieldUpgradeData
+#define CC_FieldUpgradeData CC_NO
+#endif
+#ifndef CC_FieldUpgradeStart
+#define CC_FieldUpgradeStart CC_NO
+#endif
+#ifndef CC_FirmwareRead
+#define CC_FirmwareRead CC_NO
+#endif
+#ifndef CC_FlushContext
+#define CC_FlushContext CC_YES
+#endif
+#ifndef CC_GetCapability
+#define CC_GetCapability CC_YES
+#endif
+#ifndef CC_GetCommandAuditDigest
+#define CC_GetCommandAuditDigest CC_YES
+#endif
+#ifndef CC_GetRandom
+#define CC_GetRandom CC_YES
+#endif
+#ifndef CC_GetSessionAuditDigest
+#define CC_GetSessionAuditDigest CC_YES
+#endif
+#ifndef CC_GetTestResult
+#define CC_GetTestResult CC_YES
+#endif
+#ifndef CC_GetTime
+#define CC_GetTime CC_YES
+#endif
+#ifndef CC_HMAC
+#define CC_HMAC (CC_YES && !ALG_CMAC)
+#endif
+#ifndef CC_HMAC_Start
+#define CC_HMAC_Start (CC_YES && !ALG_CMAC)
+#endif
+#ifndef CC_Hash
+#define CC_Hash CC_YES
+#endif
+#ifndef CC_HashSequenceStart
+#define CC_HashSequenceStart CC_YES
+#endif
+#ifndef CC_HierarchyChangeAuth
+#define CC_HierarchyChangeAuth CC_YES
+#endif
+#ifndef CC_HierarchyControl
+#define CC_HierarchyControl CC_YES
+#endif
+#ifndef CC_Import
+#define CC_Import CC_YES
+#endif
+#ifndef CC_IncrementalSelfTest
+#define CC_IncrementalSelfTest CC_YES
+#endif
+#ifndef CC_Load
+#define CC_Load CC_YES
+#endif
+#ifndef CC_LoadExternal
+#define CC_LoadExternal CC_YES
+#endif
+#ifndef CC_MAC
+#define CC_MAC (CC_YES && ALG_CMAC)
+#endif
+#ifndef CC_MAC_Start
+#define CC_MAC_Start (CC_YES && ALG_CMAC)
+#endif
+#ifndef CC_MakeCredential
+#define CC_MakeCredential CC_YES
+#endif
+#ifndef CC_NV_Certify
+#define CC_NV_Certify CC_YES
+#endif
+#ifndef CC_NV_ChangeAuth
+#define CC_NV_ChangeAuth CC_YES
+#endif
+#ifndef CC_NV_DefineSpace
+#define CC_NV_DefineSpace CC_YES
+#endif
+#ifndef CC_NV_Extend
+#define CC_NV_Extend CC_YES
+#endif
+#ifndef CC_NV_GlobalWriteLock
+#define CC_NV_GlobalWriteLock CC_YES
+#endif
+#ifndef CC_NV_Increment
+#define CC_NV_Increment CC_YES
+#endif
+#ifndef CC_NV_Read
+#define CC_NV_Read CC_YES
+#endif
+#ifndef CC_NV_ReadLock
+#define CC_NV_ReadLock CC_YES
+#endif
+#ifndef CC_NV_ReadPublic
+#define CC_NV_ReadPublic CC_YES
+#endif
+#ifndef CC_NV_SetBits
+#define CC_NV_SetBits CC_YES
+#endif
+#ifndef CC_NV_UndefineSpace
+#define CC_NV_UndefineSpace CC_YES
+#endif
+#ifndef CC_NV_UndefineSpaceSpecial
+#define CC_NV_UndefineSpaceSpecial CC_YES
+#endif
+#ifndef CC_NV_Write
+#define CC_NV_Write CC_YES
+#endif
+#ifndef CC_NV_WriteLock
+#define CC_NV_WriteLock CC_YES
+#endif
+#ifndef CC_ObjectChangeAuth
+#define CC_ObjectChangeAuth CC_YES
+#endif
+#ifndef CC_PCR_Allocate
+#define CC_PCR_Allocate CC_YES
+#endif
+#ifndef CC_PCR_Event
+#define CC_PCR_Event CC_YES
+#endif
+#ifndef CC_PCR_Extend
+#define CC_PCR_Extend CC_YES
+#endif
+#ifndef CC_PCR_Read
+#define CC_PCR_Read CC_YES
+#endif
+#ifndef CC_PCR_Reset
+#define CC_PCR_Reset CC_YES
+#endif
+#ifndef CC_PCR_SetAuthPolicy
+#define CC_PCR_SetAuthPolicy CC_YES
+#endif
+#ifndef CC_PCR_SetAuthValue
+#define CC_PCR_SetAuthValue CC_YES
+#endif
+#ifndef CC_PP_Commands
+#define CC_PP_Commands CC_YES
+#endif
+#ifndef CC_PolicyAuthValue
+#define CC_PolicyAuthValue CC_YES
+#endif
+#ifndef CC_PolicyAuthorize
+#define CC_PolicyAuthorize CC_YES
+#endif
+#ifndef CC_PolicyAuthorizeNV
+#define CC_PolicyAuthorizeNV CC_YES
+#endif
+#ifndef CC_PolicyCommandCode
+#define CC_PolicyCommandCode CC_YES
+#endif
+#ifndef CC_PolicyCounterTimer
+#define CC_PolicyCounterTimer CC_YES
+#endif
+#ifndef CC_PolicyCpHash
+#define CC_PolicyCpHash CC_YES
+#endif
+#ifndef CC_PolicyDuplicationSelect
+#define CC_PolicyDuplicationSelect CC_YES
+#endif
+#ifndef CC_PolicyGetDigest
+#define CC_PolicyGetDigest CC_YES
+#endif
+#ifndef CC_PolicyLocality
+#define CC_PolicyLocality CC_YES
+#endif
+#ifndef CC_PolicyNV
+#define CC_PolicyNV CC_YES
+#endif
+#ifndef CC_PolicyNameHash
+#define CC_PolicyNameHash CC_YES
+#endif
+#ifndef CC_PolicyNvWritten
+#define CC_PolicyNvWritten CC_YES
+#endif
+#ifndef CC_PolicyOR
+#define CC_PolicyOR CC_YES
+#endif
+#ifndef CC_PolicyPCR
+#define CC_PolicyPCR CC_YES
+#endif
+#ifndef CC_PolicyPassword
+#define CC_PolicyPassword CC_YES
+#endif
+#ifndef CC_PolicyPhysicalPresence
+#define CC_PolicyPhysicalPresence CC_YES
+#endif
+#ifndef CC_PolicyRestart
+#define CC_PolicyRestart CC_YES
+#endif
+#ifndef CC_PolicySecret
+#define CC_PolicySecret CC_YES
+#endif
+#ifndef CC_PolicySigned
+#define CC_PolicySigned CC_YES
+#endif
+#ifndef CC_PolicyTemplate
+#define CC_PolicyTemplate CC_YES
+#endif
+#ifndef CC_PolicyTicket
+#define CC_PolicyTicket CC_YES
+#endif
+#ifndef CC_Policy_AC_SendSelect
+#define CC_Policy_AC_SendSelect CC_NO /* kgold */
+#endif
+#ifndef CC_Quote
+#define CC_Quote CC_YES
+#endif
+#ifndef CC_RSA_Decrypt
+#define CC_RSA_Decrypt (CC_YES && ALG_RSA)
+#endif
+#ifndef CC_RSA_Encrypt
+#define CC_RSA_Encrypt (CC_YES && ALG_RSA)
+#endif
+#ifndef CC_ReadClock
+#define CC_ReadClock CC_YES
+#endif
+#ifndef CC_ReadPublic
+#define CC_ReadPublic CC_YES
+#endif
+#ifndef CC_Rewrap
+#define CC_Rewrap CC_YES
+#endif
+#ifndef CC_SelfTest
+#define CC_SelfTest CC_YES
+#endif
+#ifndef CC_SequenceComplete
+#define CC_SequenceComplete CC_YES
+#endif
+#ifndef CC_SequenceUpdate
+#define CC_SequenceUpdate CC_YES
+#endif
+#ifndef CC_SetAlgorithmSet
+#define CC_SetAlgorithmSet CC_YES
+#endif
+#ifndef CC_SetCommandCodeAuditStatus
+#define CC_SetCommandCodeAuditStatus CC_YES
+#endif
+#ifndef CC_SetPrimaryPolicy
+#define CC_SetPrimaryPolicy CC_YES
+#endif
+#ifndef CC_Shutdown
+#define CC_Shutdown CC_YES
+#endif
+#ifndef CC_Sign
+#define CC_Sign CC_YES
+#endif
+#ifndef CC_StartAuthSession
+#define CC_StartAuthSession CC_YES
+#endif
+#ifndef CC_Startup
+#define CC_Startup CC_YES
+#endif
+#ifndef CC_StirRandom
+#define CC_StirRandom CC_YES
+#endif
+#ifndef CC_TestParms
+#define CC_TestParms CC_YES
+#endif
+#ifndef CC_Unseal
+#define CC_Unseal CC_YES
+#endif
+#ifndef CC_Vendor_TCG_Test
+#define CC_Vendor_TCG_Test CC_NO /* libtpms changed */
+#endif
+#ifndef CC_VerifySignature
+#define CC_VerifySignature CC_YES
+#endif
+#ifndef CC_ZGen_2Phase
+#define CC_ZGen_2Phase (CC_YES && ALG_ECC)
+#endif
+#endif // _TPM_PROFIL
diff --git a/src/tpm2/TpmSizeChecks.c b/src/tpm2/TpmSizeChecks.c
new file mode 100644
index 0000000..01d0777
--- /dev/null
+++ b/src/tpm2/TpmSizeChecks.c
@@ -0,0 +1,229 @@
+/********************************************************************************/
+/* */
+/* TPM Size Checks */
+/* Written by Ken Goldman */
+/* IBM Thomas J. Watson Research Center */
+/* $Id: TpmSizeChecks.c 1628 2020-05-27 19:35:29Z kgoldman $ */
+/* */
+/* Licenses and Notices */
+/* */
+/* 1. Copyright Licenses: */
+/* */
+/* - Trusted Computing Group (TCG) grants to the user of the source code in */
+/* this specification (the "Source Code") a worldwide, irrevocable, */
+/* nonexclusive, royalty free, copyright license to reproduce, create */
+/* derivative works, distribute, display and perform the Source Code and */
+/* derivative works thereof, and to grant others the rights granted herein. */
+/* */
+/* - The TCG grants to the user of the other parts of the specification */
+/* (other than the Source Code) the rights to reproduce, distribute, */
+/* display, and perform the specification solely for the purpose of */
+/* developing products based on such documents. */
+/* */
+/* 2. Source Code Distribution Conditions: */
+/* */
+/* - Redistributions of Source Code must retain the above copyright licenses, */
+/* this list of conditions and the following disclaimers. */
+/* */
+/* - Redistributions in binary form must reproduce the above copyright */
+/* licenses, this list of conditions and the following disclaimers in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* 3. Disclaimers: */
+/* */
+/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
+/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
+/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
+/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
+/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
+/* information on specification licensing rights available through TCG */
+/* membership agreements. */
+/* */
+/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
+/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
+/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
+/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
+/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
+/* */
+/* - Without limitation, TCG and its members and licensors disclaim all */
+/* liability, including liability for infringement of any proprietary */
+/* rights, relating to use of information in this specification and to the */
+/* implementation of this specification, and TCG disclaims all liability for */
+/* cost of procurement of substitute goods or services, lost profits, loss */
+/* of use, loss of data or any incidental, consequential, direct, indirect, */
+/* or special damages, whether under contract, tort, warranty or otherwise, */
+/* arising in any way out of use or reliance upon this specification or any */
+/* information herein. */
+/* */
+/* (c) Copyright IBM Corp. and others, 2016 - 2020 */
+/* */
+/********************************************************************************/
+
+//** Includes, Defines, and Types
+#include "Tpm.h"
+#include "PlatformACT_fp.h" /* kgold */
+#include "TpmSizeChecks_fp.h"
+#include <stdio.h>
+#include <assert.h>
+
+#if RUNTIME_SIZE_CHECKS
+
+#if TABLE_DRIVEN_MARSHAL
+extern uint32_t MarshalDataSize;
+#endif
+
+static int once = 0;
+
+//** TpmSizeChecks()
+// This function is used during the development process to make sure that the
+// vendor-specific values result in a consistent implementation. When possible,
+// the code contains #if to do compile-time checks. However, in some cases, the
+// values require the use of "sizeof()" and that can't be used in an #if.
+BOOL
+TpmSizeChecks(
+ void
+ )
+{
+ BOOL PASS = TRUE;
+#if DEBUG
+ //
+ if(once++ != 0)
+ return 1;
+ {
+ UINT32 maxAsymSecurityStrength = MAX_ASYM_SECURITY_STRENGTH;
+ UINT32 maxHashSecurityStrength = MAX_HASH_SECURITY_STRENGTH;
+ UINT32 maxSymSecurityStrength = MAX_SYM_SECURITY_STRENGTH;
+ UINT32 maxSecurityStrengthBits = MAX_SECURITY_STRENGTH_BITS;
+ UINT32 proofSize = PROOF_SIZE;
+ UINT32 compliantProofSize = COMPLIANT_PROOF_SIZE;
+ UINT32 compliantPrimarySeedSize = COMPLIANT_PRIMARY_SEED_SIZE;
+ UINT32 primarySeedSize = PRIMARY_SEED_SIZE;
+
+ UINT32 cmacState = sizeof(tpmCmacState_t);
+ UINT32 hashState = sizeof(HASH_STATE);
+ UINT32 keyScheduleSize = sizeof(tpmCryptKeySchedule_t);
+ //
+ NOT_REFERENCED(cmacState);
+ NOT_REFERENCED(hashState);
+ NOT_REFERENCED(keyScheduleSize);
+ NOT_REFERENCED(maxAsymSecurityStrength);
+ NOT_REFERENCED(maxHashSecurityStrength);
+ NOT_REFERENCED(maxSymSecurityStrength);
+ NOT_REFERENCED(maxSecurityStrengthBits);
+ NOT_REFERENCED(proofSize);
+ NOT_REFERENCED(compliantProofSize);
+ NOT_REFERENCED(compliantPrimarySeedSize);
+ NOT_REFERENCED(primarySeedSize);
+
+
+ {
+ TPMT_SENSITIVE *p;
+ // This assignment keeps compiler from complaining about a conditional
+ // comparison being between two constants
+ UINT16 max_rsa_key_bytes = MAX_RSA_KEY_BYTES;
+ if((max_rsa_key_bytes / 2) != (sizeof(p->sensitive.rsa.t.buffer) / 5))
+ {
+ printf("Sensitive part of TPMT_SENSITIVE is undersized. May be caused"
+ " by use of wrong version of Part 2.\n");
+ PASS = FALSE;
+ }
+ }
+#if TABLE_DRIVEN_MARSHAL
+ printf("sizeof(MarshalData) = %zu\n", sizeof(MarshalData_st));
+#endif
+
+ printf("Size of OBJECT = %zu\n", sizeof(OBJECT));
+ printf("Size of components in TPMT_SENSITIVE = %zu\n", sizeof(TPMT_SENSITIVE));
+ printf(" TPMI_ALG_PUBLIC %zu\n", sizeof(TPMI_ALG_PUBLIC));
+ printf(" TPM2B_AUTH %zu\n", sizeof(TPM2B_AUTH));
+ printf(" TPM2B_DIGEST %zu\n", sizeof(TPM2B_DIGEST));
+ printf(" TPMU_SENSITIVE_COMPOSITE %zu\n",
+ sizeof(TPMU_SENSITIVE_COMPOSITE));
+ }
+ // Make sure that the size of the context blob is large enough for the largest
+ // context
+ // TPMS_CONTEXT_DATA contains two TPM2B values. That is not how this is
+ // implemented. Rather, the size field of the TPM2B_CONTEXT_DATA is used to
+ // determine the amount of data in the encrypted data. That part is not
+ // independently sized. This makes the actual size 2 bytes smaller than
+ // calculated using Part 2. Since this is opaque to the caller, it is not
+ // necessary to fix. The actual size is returned by TPM2_GetCapabilties().
+
+ // Initialize output handle. At the end of command action, the output
+ // handle of an object will be replaced, while the output handle
+ // for a session will be the same as input
+
+ // Get the size of fingerprint in context blob. The sequence value in
+ // TPMS_CONTEXT structure is used as the fingerprint
+ {
+ UINT32 fingerprintSize = sizeof(UINT64);
+ UINT32 integritySize = sizeof(UINT16)
+ + CryptHashGetDigestSize(CONTEXT_INTEGRITY_HASH_ALG);
+ UINT32 biggestObject = MAX(MAX(sizeof(HASH_OBJECT), sizeof(OBJECT)),
+ sizeof(SESSION));
+ UINT32 biggestContext = fingerprintSize + integritySize + biggestObject;
+
+ // round required size up to nearest 8 byte boundary.
+ biggestContext = 8 * ((biggestContext + 7) / 8);
+
+ if(MAX_CONTEXT_SIZE < biggestContext)
+ {
+ printf("MAX_CONTEXT_SIZE needs to be increased to at least to %d (%d)\n",
+ biggestContext, MAX_CONTEXT_SIZE);
+ PASS = FALSE;
+ }
+ else if (MAX_CONTEXT_SIZE > biggestContext)
+ {
+ printf("MAX_CONTEXT_SIZE can be reduced to %d (%d)\n",
+ biggestContext, MAX_CONTEXT_SIZE);
+ }
+ }
+ {
+ union u
+ {
+ TPMA_OBJECT attributes;
+ UINT32 uint32Value;
+ } u;
+ // these are defined so that compiler doesn't complain about conditional
+ // expressions comparing two constants.
+ int aSize = sizeof(u.attributes);
+ int uSize = sizeof(u.uint32Value);
+ u.uint32Value = 0;
+ SET_ATTRIBUTE(u.attributes, TPMA_OBJECT, fixedTPM);
+ if(u.uint32Value != 2)
+ {
+ printf("The bit allocation in a TPMA_OBJECT is not as expected");
+ PASS = FALSE;
+ }
+ if(aSize != uSize) // comparison of two sizeof() values annoys compiler
+ {
+ printf("A TPMA_OBJECT is not the expected size.");
+ PASS = FALSE;
+ }
+ }
+ // Check that the platform implements each of the ACT that the TPM thinks are present
+ {
+ uint32_t act;
+ for(act = 0; act < 16; act++)
+ {
+ switch(act)
+ {
+ FOR_EACH_ACT(CASE_ACT_NUMBER)
+ if(!_plat__ACT_GetImplemented(act))
+ {
+ printf("TPM_RH_ACT_%1X is not implemented by platform\n",
+ act);
+ PASS = FALSE;
+ }
+ default:
+ break;
+ }
+ }
+ }
+#endif // DEBUG
+ return (PASS);
+}
+
+#endif // RUNTIME_SIZE_CHECKS
+
+
diff --git a/src/tpm2/TpmSizeChecks_fp.h b/src/tpm2/TpmSizeChecks_fp.h
new file mode 100644
index 0000000..12f2714
--- /dev/null
+++ b/src/tpm2/TpmSizeChecks_fp.h
@@ -0,0 +1,67 @@
+/********************************************************************************/
+/* */
+/* Check COmpiler Options */
+/* Written by Ken Goldman */
+/* IBM Thomas J. Watson Research Center */
+/* $Id: TpmSizeChecks_fp.h 1519 2019-11-15 20:43:51Z kgoldman $ */
+/* */
+/* Licenses and Notices */
+/* */
+/* 1. Copyright Licenses: */
+/* */
+/* - Trusted Computing Group (TCG) grants to the user of the source code in */
+/* this specification (the "Source Code") a worldwide, irrevocable, */
+/* nonexclusive, royalty free, copyright license to reproduce, create */
+/* derivative works, distribute, display and perform the Source Code and */
+/* derivative works thereof, and to grant others the rights granted herein. */
+/* */
+/* - The TCG grants to the user of the other parts of the specification */
+/* (other than the Source Code) the rights to reproduce, distribute, */
+/* display, and perform the specification solely for the purpose of */
+/* developing products based on such documents. */
+/* */
+/* 2. Source Code Distribution Conditions: */
+/* */
+/* - Redistributions of Source Code must retain the above copyright licenses, */
+/* this list of conditions and the following disclaimers. */
+/* */
+/* - Redistributions in binary form must reproduce the above copyright */
+/* licenses, this list of conditions and the following disclaimers in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* 3. Disclaimers: */
+/* */
+/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
+/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
+/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
+/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
+/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
+/* information on specification licensing rights available through TCG */
+/* membership agreements. */
+/* */
+/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
+/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
+/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
+/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
+/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
+/* */
+/* - Without limitation, TCG and its members and licensors disclaim all */
+/* liability, including liability for infringement of any proprietary */
+/* rights, relating to use of information in this specification and to the */
+/* implementation of this specification, and TCG disclaims all liability for */
+/* cost of procurement of substitute goods or services, lost profits, loss */
+/* of use, loss of data or any incidental, consequential, direct, indirect, */
+/* or special damages, whether under contract, tort, warranty or otherwise, */
+/* arising in any way out of use or reliance upon this specification or any */
+/* information herein. */
+/* */
+/* (c) Copyright IBM Corp. and others, 2016 - 2019 */
+/* */
+/********************************************************************************/
+
+#ifndef TPMSIZECHECKS_FP_H
+#define TPMSIZECHECKS_FP_H
+
+BOOL TpmSizeChecks(void);
+
+#endif
diff --git a/src/tpm2/TpmTcpProtocol.h b/src/tpm2/TpmTcpProtocol.h
new file mode 100644
index 0000000..1fe8f66
--- /dev/null
+++ b/src/tpm2/TpmTcpProtocol.h
@@ -0,0 +1,140 @@
+/********************************************************************************/
+/* */
+/* TPM commands are communicated as BYTE streams on a TCP connection */
+/* Written by Ken Goldman */
+/* IBM Thomas J. Watson Research Center */
+/* $Id: TpmTcpProtocol.h 1658 2021-01-22 23:14:01Z kgoldman $ */
+/* */
+/* Licenses and Notices */
+/* */
+/* 1. Copyright Licenses: */
+/* */
+/* - Trusted Computing Group (TCG) grants to the user of the source code in */
+/* this specification (the "Source Code") a worldwide, irrevocable, */
+/* nonexclusive, royalty free, copyright license to reproduce, create */
+/* derivative works, distribute, display and perform the Source Code and */
+/* derivative works thereof, and to grant others the rights granted herein. */
+/* */
+/* - The TCG grants to the user of the other parts of the specification */
+/* (other than the Source Code) the rights to reproduce, distribute, */
+/* display, and perform the specification solely for the purpose of */
+/* developing products based on such documents. */
+/* */
+/* 2. Source Code Distribution Conditions: */
+/* */
+/* - Redistributions of Source Code must retain the above copyright licenses, */
+/* this list of conditions and the following disclaimers. */
+/* */
+/* - Redistributions in binary form must reproduce the above copyright */
+/* licenses, this list of conditions and the following disclaimers in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* 3. Disclaimers: */
+/* */
+/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
+/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
+/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
+/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
+/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
+/* information on specification licensing rights available through TCG */
+/* membership agreements. */
+/* */
+/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
+/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
+/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
+/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
+/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
+/* */
+/* - Without limitation, TCG and its members and licensors disclaim all */
+/* liability, including liability for infringement of any proprietary */
+/* rights, relating to use of information in this specification and to the */
+/* implementation of this specification, and TCG disclaims all liability for */
+/* cost of procurement of substitute goods or services, lost profits, loss */
+/* of use, loss of data or any incidental, consequential, direct, indirect, */
+/* or special damages, whether under contract, tort, warranty or otherwise, */
+/* arising in any way out of use or reliance upon this specification or any */
+/* information herein. */
+/* */
+/* (c) Copyright IBM Corp. and others, 2016 - 2021 */
+/* */
+/********************************************************************************/
+
+/* D.3 TpmTcpProtocol.h */
+/* D.3.1. Introduction */
+/* TPM commands are communicated as uint8_t streams on a TCP connection. The TPM command protocol is
+ enveloped with the interface protocol described in this file. The command is indicated by a
+ uint32_t with one of the values below. Most commands take no parameters and return no TPM errors. In
+ these cases the TPM interface protocol acknowledges that command processing is completed by
+ returning a uint32_t = 0. The command TPM_SIGNAL_HASH_DATA takes a uint32_t-prepended variable length
+ byte array and the interface protocol acknowledges command completion with a uint32_t = 0. Most TPM
+ commands are enveloped using the TPM_SEND_COMMAND interface command. The parameters are as
+ indicated below. The interface layer also appends a uin32_t = 0 to the TPM response for
+ regularity. */
+/* D.3.2. Typedefs and Defines */
+#ifndef TCP_TPM_PROTOCOL_H
+#define TCP_TPM_PROTOCOL_H
+/* D.3.3. TPM Commands All commands acknowledge processing by returning a uint32_t = 0 except where
+ noted */
+#define TPM_SIGNAL_POWER_ON 1
+#define TPM_SIGNAL_POWER_OFF 2
+#define TPM_SIGNAL_PHYS_PRES_ON 3
+#define TPM_SIGNAL_PHYS_PRES_OFF 4
+#define TPM_SIGNAL_HASH_START 5
+#define TPM_SIGNAL_HASH_DATA 6
+ // {uint32_t BufferSize, uint8_t[BufferSize] Buffer}
+#define TPM_SIGNAL_HASH_END 7
+#define TPM_SEND_COMMAND 8
+// {uint8_t Locality, uint32_t InBufferSize, uint8_t[InBufferSize] InBuffer} ->
+// {uint32_t OutBufferSize, uint8_t[OutBufferSize] OutBuffer}
+#define TPM_SIGNAL_CANCEL_ON 9
+#define TPM_SIGNAL_CANCEL_OFF 10
+#define TPM_SIGNAL_NV_ON 11
+#define TPM_SIGNAL_NV_OFF 12
+#define TPM_SIGNAL_KEY_CACHE_ON 13
+#define TPM_SIGNAL_KEY_CACHE_OFF 14
+#define TPM_REMOTE_HANDSHAKE 15
+#define TPM_SET_ALTERNATIVE_RESULT 16
+#define TPM_SIGNAL_RESET 17
+#define TPM_SIGNAL_RESTART 18
+#define TPM_SESSION_END 20
+#define TPM_STOP 21
+#define TPM_GET_COMMAND_RESPONSE_SIZES 25
+#define TPM_ACT_GET_SIGNALED 26
+#define TPM_TEST_FAILURE_MODE 30
+
+// D.3.4. Enumerations and Structures
+
+enum TpmEndPointInfo
+ {
+ tpmPlatformAvailable = 0x01,
+ tpmUsesTbs = 0x02,
+ tpmInRawMode = 0x04,
+ tpmSupportsPP = 0x08
+ };
+
+#ifdef _MSC_VER
+# pragma warning(push, 3)
+#endif
+
+// Existing RPC interface type definitions retained so that the implementation
+// can be re-used
+typedef struct in_buffer
+{
+ unsigned long BufferSize;
+ unsigned char *Buffer;
+} _IN_BUFFER;
+typedef unsigned char *_OUTPUT_BUFFER;
+typedef struct out_buffer
+{
+ uint32_t BufferSize;
+ _OUTPUT_BUFFER Buffer;
+} _OUT_BUFFER;
+#ifdef _MSC_VER
+# pragma warning(pop)
+#endif
+#ifndef WIN32
+typedef unsigned long DWORD;
+typedef void *LPVOID;
+#undef WINAPI
+#endif
+#endif
diff --git a/src/tpm2/TpmTypes.h b/src/tpm2/TpmTypes.h
new file mode 100644
index 0000000..a06d759
--- /dev/null
+++ b/src/tpm2/TpmTypes.h
@@ -0,0 +1,2473 @@
+/********************************************************************************/
+/* */
+/* TPM Part 2 Headers */
+/* Written by Ken Goldman */
+/* IBM Thomas J. Watson Research Center */
+/* $Id: TpmTypes.h 1606 2020-04-14 16:26:05Z kgoldman $ */
+/* */
+/* Licenses and Notices */
+/* */
+/* 1. Copyright Licenses: */
+/* */
+/* - Trusted Computing Group (TCG) grants to the user of the source code in */
+/* this specification (the "Source Code") a worldwide, irrevocable, */
+/* nonexclusive, royalty free, copyright license to reproduce, create */
+/* derivative works, distribute, display and perform the Source Code and */
+/* derivative works thereof, and to grant others the rights granted herein. */
+/* */
+/* - The TCG grants to the user of the other parts of the specification */
+/* (other than the Source Code) the rights to reproduce, distribute, */
+/* display, and perform the specification solely for the purpose of */
+/* developing products based on such documents. */
+/* */
+/* 2. Source Code Distribution Conditions: */
+/* */
+/* - Redistributions of Source Code must retain the above copyright licenses, */
+/* this list of conditions and the following disclaimers. */
+/* */
+/* - Redistributions in binary form must reproduce the above copyright */
+/* licenses, this list of conditions and the following disclaimers in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* 3. Disclaimers: */
+/* */
+/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
+/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
+/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
+/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
+/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
+/* information on specification licensing rights available through TCG */
+/* membership agreements. */
+/* */
+/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
+/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
+/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
+/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
+/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
+/* */
+/* - Without limitation, TCG and its members and licensors disclaim all */
+/* liability, including liability for infringement of any proprietary */
+/* rights, relating to use of information in this specification and to the */
+/* implementation of this specification, and TCG disclaims all liability for */
+/* cost of procurement of substitute goods or services, lost profits, loss */
+/* of use, loss of data or any incidental, consequential, direct, indirect, */
+/* or special damages, whether under contract, tort, warranty or otherwise, */
+/* arising in any way out of use or reliance upon this specification or any */
+/* information herein. */
+/* */
+/* (c) Copyright IBM Corp. and others, 2016 - 2020 */
+/* */
+/********************************************************************************/
+
+/* 5.21 TpmTypes.h */
+
+#ifndef TPMTYPES_H
+#define TPMTYPES_H
+
+/* TCG Algorithm Registry: Table 1:2 - Definition of TPM_ALG_ID Constants */
+
+typedef UINT16 TPM_ALG_ID;
+#define TYPE_OF_TPM_ALG_ID UINT16
+#define ALG_ERROR_VALUE 0x0000
+#define TPM_ALG_ERROR (TPM_ALG_ID)(ALG_ERROR_VALUE)
+#define ALG_RSA_VALUE 0x0001
+#define TPM_ALG_RSA (TPM_ALG_ID)(ALG_RSA_VALUE)
+#define ALG_TDES_VALUE 0x0003
+#define TPM_ALG_TDES (TPM_ALG_ID)(ALG_TDES_VALUE)
+#define ALG_SHA_VALUE 0x0004
+#define TPM_ALG_SHA (TPM_ALG_ID)(ALG_SHA_VALUE)
+#define ALG_SHA1_VALUE 0x0004
+#define TPM_ALG_SHA1 (TPM_ALG_ID)(ALG_SHA1_VALUE)
+#define ALG_HMAC_VALUE 0x0005
+#define TPM_ALG_HMAC (TPM_ALG_ID)(ALG_HMAC_VALUE)
+#define ALG_AES_VALUE 0x0006
+#define TPM_ALG_AES (TPM_ALG_ID)(ALG_AES_VALUE)
+#define ALG_MGF1_VALUE 0x0007
+#define TPM_ALG_MGF1 (TPM_ALG_ID)(ALG_MGF1_VALUE)
+#define ALG_KEYEDHASH_VALUE 0x0008
+#define TPM_ALG_KEYEDHASH (TPM_ALG_ID)(ALG_KEYEDHASH_VALUE)
+#define ALG_XOR_VALUE 0x000A
+#define TPM_ALG_XOR (TPM_ALG_ID)(ALG_XOR_VALUE)
+#define ALG_SHA256_VALUE 0x000B
+#define TPM_ALG_SHA256 (TPM_ALG_ID)(ALG_SHA256_VALUE)
+#define ALG_SHA384_VALUE 0x000C
+#define TPM_ALG_SHA384 (TPM_ALG_ID)(ALG_SHA384_VALUE)
+#define ALG_SHA512_VALUE 0x000D
+#define TPM_ALG_SHA512 (TPM_ALG_ID)(ALG_SHA512_VALUE)
+#define ALG_NULL_VALUE 0x0010
+#define TPM_ALG_NULL (TPM_ALG_ID)(ALG_NULL_VALUE)
+#define ALG_SM3_256_VALUE 0x0012
+#define TPM_ALG_SM3_256 (TPM_ALG_ID)(ALG_SM3_256_VALUE)
+#define ALG_SM4_VALUE 0x0013
+#define TPM_ALG_SM4 (TPM_ALG_ID)(ALG_SM4_VALUE)
+#define ALG_RSASSA_VALUE 0x0014
+#define TPM_ALG_RSASSA (TPM_ALG_ID)(ALG_RSASSA_VALUE)
+#define ALG_RSAES_VALUE 0x0015
+#define TPM_ALG_RSAES (TPM_ALG_ID)(ALG_RSAES_VALUE)
+#define ALG_RSAPSS_VALUE 0x0016
+#define TPM_ALG_RSAPSS (TPM_ALG_ID)(ALG_RSAPSS_VALUE)
+#define ALG_OAEP_VALUE 0x0017
+#define TPM_ALG_OAEP (TPM_ALG_ID)(ALG_OAEP_VALUE)
+#define ALG_ECDSA_VALUE 0x0018
+#define TPM_ALG_ECDSA (TPM_ALG_ID)(ALG_ECDSA_VALUE)
+#define ALG_ECDH_VALUE 0x0019
+#define TPM_ALG_ECDH (TPM_ALG_ID)(ALG_ECDH_VALUE)
+#define ALG_ECDAA_VALUE 0x001A
+#define TPM_ALG_ECDAA (TPM_ALG_ID)(ALG_ECDAA_VALUE)
+#define ALG_SM2_VALUE 0x001B
+#define TPM_ALG_SM2 (TPM_ALG_ID)(ALG_SM2_VALUE)
+#define ALG_ECSCHNORR_VALUE 0x001C
+#define TPM_ALG_ECSCHNORR (TPM_ALG_ID)(ALG_ECSCHNORR_VALUE)
+#define ALG_ECMQV_VALUE 0x001D
+#define TPM_ALG_ECMQV (TPM_ALG_ID)(ALG_ECMQV_VALUE)
+#define ALG_KDF1_SP800_56A_VALUE 0x0020
+#define TPM_ALG_KDF1_SP800_56A (TPM_ALG_ID)(ALG_KDF1_SP800_56A_VALUE)
+#define ALG_KDF2_VALUE 0x0021
+#define TPM_ALG_KDF2 (TPM_ALG_ID)(ALG_KDF2_VALUE)
+#define ALG_KDF1_SP800_108_VALUE 0x0022
+#define TPM_ALG_KDF1_SP800_108 (TPM_ALG_ID)(ALG_KDF1_SP800_108_VALUE)
+#define ALG_ECC_VALUE 0x0023
+#define TPM_ALG_ECC (TPM_ALG_ID)(ALG_ECC_VALUE)
+#define ALG_SYMCIPHER_VALUE 0x0025
+#define TPM_ALG_SYMCIPHER (TPM_ALG_ID)(ALG_SYMCIPHER_VALUE)
+#define ALG_CAMELLIA_VALUE 0x0026
+#define TPM_ALG_CAMELLIA (TPM_ALG_ID)(ALG_CAMELLIA_VALUE)
+#define ALG_SHA3_256_VALUE 0x0027
+#define TPM_ALG_SHA3_256 (TPM_ALG_ID)(ALG_SHA3_256_VALUE)
+#define ALG_SHA3_384_VALUE 0x0028
+#define TPM_ALG_SHA3_384 (TPM_ALG_ID)(ALG_SHA3_384_VALUE)
+#define ALG_SHA3_512_VALUE 0x0029
+#define TPM_ALG_SHA3_512 (TPM_ALG_ID)(ALG_SHA3_512_VALUE)
+#define ALG_CMAC_VALUE 0x003F
+#define TPM_ALG_CMAC (TPM_ALG_ID)(ALG_CMAC_VALUE)
+#define ALG_CTR_VALUE 0x0040
+#define TPM_ALG_CTR (TPM_ALG_ID)(ALG_CTR_VALUE)
+#define ALG_OFB_VALUE 0x0041
+#define TPM_ALG_OFB (TPM_ALG_ID)(ALG_OFB_VALUE)
+#define ALG_CBC_VALUE 0x0042
+#define TPM_ALG_CBC (TPM_ALG_ID)(ALG_CBC_VALUE)
+#define ALG_CFB_VALUE 0x0043
+#define TPM_ALG_CFB (TPM_ALG_ID)(ALG_CFB_VALUE)
+#define ALG_ECB_VALUE 0x0044
+#define TPM_ALG_ECB (TPM_ALG_ID)(ALG_ECB_VALUE)
+
+/* Values derived from Table 1:2 */
+#define ALG_FIRST_VALUE 0x0001
+#define TPM_ALG_FIRST (TPM_ALG_ID)(ALG_FIRST_VALUE)
+#define ALG_LAST_VALUE 0x0044
+#define TPM_ALG_LAST (TPM_ALG_ID)(ALG_LAST_VALUE)
+
+/* TCG Algorithm Registry: Table 1:3 - Definition of TPM_ECC_CURVE Constants */
+typedef UINT16 TPM_ECC_CURVE;
+#define TYPE_OF_TPM_ECC_CURVE UINT16
+#define TPM_ECC_NONE (TPM_ECC_CURVE)(0x0000)
+#define TPM_ECC_NIST_P192 (TPM_ECC_CURVE)(0x0001)
+#define TPM_ECC_NIST_P224 (TPM_ECC_CURVE)(0x0002)
+#define TPM_ECC_NIST_P256 (TPM_ECC_CURVE)(0x0003)
+#define TPM_ECC_NIST_P384 (TPM_ECC_CURVE)(0x0004)
+#define TPM_ECC_NIST_P521 (TPM_ECC_CURVE)(0x0005)
+#define TPM_ECC_BN_P256 (TPM_ECC_CURVE)(0x0010)
+#define TPM_ECC_BN_P638 (TPM_ECC_CURVE)(0x0011)
+#define TPM_ECC_SM2_P256 (TPM_ECC_CURVE)(0x0020)
+
+/* TPM 2.0 Part 2: Table 2:12 - Definition of TPM_CC Constants */
+typedef UINT32 TPM_CC;
+#define TYPE_OF_TPM_CC UINT32
+#define TPM_CC_NV_UndefineSpaceSpecial (TPM_CC)(0x0000011F)
+#define TPM_CC_EvictControl (TPM_CC)(0x00000120)
+#define TPM_CC_HierarchyControl (TPM_CC)(0x00000121)
+#define TPM_CC_NV_UndefineSpace (TPM_CC)(0x00000122)
+#define TPM_CC_ChangeEPS (TPM_CC)(0x00000124)
+#define TPM_CC_ChangePPS (TPM_CC)(0x00000125)
+#define TPM_CC_Clear (TPM_CC)(0x00000126)
+#define TPM_CC_ClearControl (TPM_CC)(0x00000127)
+#define TPM_CC_ClockSet (TPM_CC)(0x00000128)
+#define TPM_CC_HierarchyChangeAuth (TPM_CC)(0x00000129)
+#define TPM_CC_NV_DefineSpace (TPM_CC)(0x0000012A)
+#define TPM_CC_PCR_Allocate (TPM_CC)(0x0000012B)
+#define TPM_CC_PCR_SetAuthPolicy (TPM_CC)(0x0000012C)
+#define TPM_CC_PP_Commands (TPM_CC)(0x0000012D)
+#define TPM_CC_SetPrimaryPolicy (TPM_CC)(0x0000012E)
+#define TPM_CC_FieldUpgradeStart (TPM_CC)(0x0000012F)
+#define TPM_CC_ClockRateAdjust (TPM_CC)(0x00000130)
+#define TPM_CC_CreatePrimary (TPM_CC)(0x00000131)
+#define TPM_CC_NV_GlobalWriteLock (TPM_CC)(0x00000132)
+#define TPM_CC_GetCommandAuditDigest (TPM_CC)(0x00000133)
+#define TPM_CC_NV_Increment (TPM_CC)(0x00000134)
+#define TPM_CC_NV_SetBits (TPM_CC)(0x00000135)
+#define TPM_CC_NV_Extend (TPM_CC)(0x00000136)
+#define TPM_CC_NV_Write (TPM_CC)(0x00000137)
+#define TPM_CC_NV_WriteLock (TPM_CC)(0x00000138)
+#define TPM_CC_DictionaryAttackLockReset (TPM_CC)(0x00000139)
+#define TPM_CC_DictionaryAttackParameters (TPM_CC)(0x0000013A)
+#define TPM_CC_NV_ChangeAuth (TPM_CC)(0x0000013B)
+#define TPM_CC_PCR_Event (TPM_CC)(0x0000013C)
+#define TPM_CC_PCR_Reset (TPM_CC)(0x0000013D)
+#define TPM_CC_SequenceComplete (TPM_CC)(0x0000013E)
+#define TPM_CC_SetAlgorithmSet (TPM_CC)(0x0000013F)
+#define TPM_CC_SetCommandCodeAuditStatus (TPM_CC)(0x00000140)
+#define TPM_CC_FieldUpgradeData (TPM_CC)(0x00000141)
+#define TPM_CC_IncrementalSelfTest (TPM_CC)(0x00000142)
+#define TPM_CC_SelfTest (TPM_CC)(0x00000143)
+#define TPM_CC_Startup (TPM_CC)(0x00000144)
+#define TPM_CC_Shutdown (TPM_CC)(0x00000145)
+#define TPM_CC_StirRandom (TPM_CC)(0x00000146)
+#define TPM_CC_ActivateCredential (TPM_CC)(0x00000147)
+#define TPM_CC_Certify (TPM_CC)(0x00000148)
+#define TPM_CC_PolicyNV (TPM_CC)(0x00000149)
+#define TPM_CC_CertifyCreation (TPM_CC)(0x0000014A)
+#define TPM_CC_Duplicate (TPM_CC)(0x0000014B)
+#define TPM_CC_GetTime (TPM_CC)(0x0000014C)
+#define TPM_CC_GetSessionAuditDigest (TPM_CC)(0x0000014D)
+#define TPM_CC_NV_Read (TPM_CC)(0x0000014E)
+#define TPM_CC_NV_ReadLock (TPM_CC)(0x0000014F)
+#define TPM_CC_ObjectChangeAuth (TPM_CC)(0x00000150)
+#define TPM_CC_PolicySecret (TPM_CC)(0x00000151)
+#define TPM_CC_Rewrap (TPM_CC)(0x00000152)
+#define TPM_CC_Create (TPM_CC)(0x00000153)
+#define TPM_CC_ECDH_ZGen (TPM_CC)(0x00000154)
+#define TPM_CC_HMAC (TPM_CC)(0x00000155)
+#define TPM_CC_MAC (TPM_CC)(0x00000155)
+#define TPM_CC_Import (TPM_CC)(0x00000156)
+#define TPM_CC_Load (TPM_CC)(0x00000157)
+#define TPM_CC_Quote (TPM_CC)(0x00000158)
+#define TPM_CC_RSA_Decrypt (TPM_CC)(0x00000159)
+#define TPM_CC_HMAC_Start (TPM_CC)(0x0000015B)
+#define TPM_CC_MAC_Start (TPM_CC)(0x0000015B)
+#define TPM_CC_SequenceUpdate (TPM_CC)(0x0000015C)
+#define TPM_CC_Sign (TPM_CC)(0x0000015D)
+#define TPM_CC_Unseal (TPM_CC)(0x0000015E)
+#define TPM_CC_PolicySigned (TPM_CC)(0x00000160)
+#define TPM_CC_ContextLoad (TPM_CC)(0x00000161)
+#define TPM_CC_ContextSave (TPM_CC)(0x00000162)
+#define TPM_CC_ECDH_KeyGen (TPM_CC)(0x00000163)
+#define TPM_CC_EncryptDecrypt (TPM_CC)(0x00000164)
+#define TPM_CC_FlushContext (TPM_CC)(0x00000165)
+#define TPM_CC_LoadExternal (TPM_CC)(0x00000167)
+#define TPM_CC_MakeCredential (TPM_CC)(0x00000168)
+#define TPM_CC_NV_ReadPublic (TPM_CC)(0x00000169)
+#define TPM_CC_PolicyAuthorize (TPM_CC)(0x0000016A)
+#define TPM_CC_PolicyAuthValue (TPM_CC)(0x0000016B)
+#define TPM_CC_PolicyCommandCode (TPM_CC)(0x0000016C)
+#define TPM_CC_PolicyCounterTimer (TPM_CC)(0x0000016D)
+#define TPM_CC_PolicyCpHash (TPM_CC)(0x0000016E)
+#define TPM_CC_PolicyLocality (TPM_CC)(0x0000016F)
+#define TPM_CC_PolicyNameHash (TPM_CC)(0x00000170)
+#define TPM_CC_PolicyOR (TPM_CC)(0x00000171)
+#define TPM_CC_PolicyTicket (TPM_CC)(0x00000172)
+#define TPM_CC_ReadPublic (TPM_CC)(0x00000173)
+#define TPM_CC_RSA_Encrypt (TPM_CC)(0x00000174)
+#define TPM_CC_StartAuthSession (TPM_CC)(0x00000176)
+#define TPM_CC_VerifySignature (TPM_CC)(0x00000177)
+#define TPM_CC_ECC_Parameters (TPM_CC)(0x00000178)
+#define TPM_CC_FirmwareRead (TPM_CC)(0x00000179)
+#define TPM_CC_GetCapability (TPM_CC)(0x0000017A)
+#define TPM_CC_GetRandom (TPM_CC)(0x0000017B)
+#define TPM_CC_GetTestResult (TPM_CC)(0x0000017C)
+#define TPM_CC_Hash (TPM_CC)(0x0000017D)
+#define TPM_CC_PCR_Read (TPM_CC)(0x0000017E)
+#define TPM_CC_PolicyPCR (TPM_CC)(0x0000017F)
+#define TPM_CC_PolicyRestart (TPM_CC)(0x00000180)
+#define TPM_CC_ReadClock (TPM_CC)(0x00000181)
+#define TPM_CC_PCR_Extend (TPM_CC)(0x00000182)
+#define TPM_CC_PCR_SetAuthValue (TPM_CC)(0x00000183)
+#define TPM_CC_NV_Certify (TPM_CC)(0x00000184)
+#define TPM_CC_EventSequenceComplete (TPM_CC)(0x00000185)
+#define TPM_CC_HashSequenceStart (TPM_CC)(0x00000186)
+#define TPM_CC_PolicyPhysicalPresence (TPM_CC)(0x00000187)
+#define TPM_CC_PolicyDuplicationSelect (TPM_CC)(0x00000188)
+#define TPM_CC_PolicyGetDigest (TPM_CC)(0x00000189)
+#define TPM_CC_TestParms (TPM_CC)(0x0000018A)
+#define TPM_CC_Commit (TPM_CC)(0x0000018B)
+#define TPM_CC_PolicyPassword (TPM_CC)(0x0000018C)
+#define TPM_CC_ZGen_2Phase (TPM_CC)(0x0000018D)
+#define TPM_CC_EC_Ephemeral (TPM_CC)(0x0000018E)
+#define TPM_CC_PolicyNvWritten (TPM_CC)(0x0000018F)
+#define TPM_CC_PolicyTemplate (TPM_CC)(0x00000190)
+#define TPM_CC_CreateLoaded (TPM_CC)(0x00000191)
+#define TPM_CC_PolicyAuthorizeNV (TPM_CC)(0x00000192)
+#define TPM_CC_EncryptDecrypt2 (TPM_CC)(0x00000193)
+#define TPM_CC_AC_GetCapability (TPM_CC)(0x00000194)
+#define TPM_CC_AC_Send (TPM_CC)(0x00000195)
+#define TPM_CC_Policy_AC_SendSelect (TPM_CC)(0x00000196)
+#define TPM_CC_CertifyX509 (TPM_CC)(0x00000197)
+#define TPM_CC_ACT_SetTimeout (TPM_CC)(0x00000198)
+#define TPM_CC_ECC_Encrypt (TPM_CC)(0x00000199)
+#define TPM_CC_ECC_Decrypt (TPM_CC)(0x0000019A)
+#define CC_VEND 0x20000000
+#define TPM_CC_Vendor_TCG_Test (TPM_CC)(0x20000000)
+
+/* Table 2:5 - Definition of Types for Documentation Clarity */
+typedef UINT32 TPM_ALGORITHM_ID;
+#define TYPE_OF_TPM_ALGORITHM_ID UINT32
+typedef UINT32 TPM_MODIFIER_INDICATOR;
+#define TYPE_OF_TPM_MODIFIER_INDICATOR UINT32
+typedef UINT32 TPM_AUTHORIZATION_SIZE;
+#define TYPE_OF_TPM_AUTHORIZATION_SIZE UINT32
+typedef UINT32 TPM_PARAMETER_SIZE;
+#define TYPE_OF_TPM_PARAMETER_SIZE UINT32
+typedef UINT16 TPM_KEY_SIZE;
+#define TYPE_OF_TPM_KEY_SIZE UINT16
+typedef UINT16 TPM_KEY_BITS;
+#define TYPE_OF_TPM_KEY_BITS UINT16
+
+/* Table 2:6 - Definition of TPM_SPEC Constants */
+typedef UINT32 TPM_SPEC;
+#define TYPE_OF_TPM_SPEC UINT32
+#define SPEC_FAMILY 0x322E3000
+#define TPM_SPEC_FAMILY (TPM_SPEC)(SPEC_FAMILY)
+#define SPEC_LEVEL 00
+#define SPEC_LEVEL_NUM 0 // libtpms added: SPEC_LEVEL without leading zeros
+#define TPM_SPEC_LEVEL (TPM_SPEC)(SPEC_LEVEL)
+#define SPEC_VERSION 164
+#define TPM_SPEC_VERSION (TPM_SPEC)(SPEC_VERSION)
+#define SPEC_YEAR 2021
+#define TPM_SPEC_YEAR (TPM_SPEC)(SPEC_YEAR)
+#define SPEC_DAY_OF_YEAR 75
+#define TPM_SPEC_DAY_OF_YEAR (TPM_SPEC)(SPEC_DAY_OF_YEAR)
+
+/* Table 2:7 - Definition of TPM_CONSTANTS32 Constants */
+
+typedef UINT32 TPM_CONSTANTS32;
+#define TYPE_OF_TPM_CONSTANTS32 UINT32
+#define TPM_GENERATED_VALUE (TPM_CONSTANTS32)(0xFF544347)
+#define TPM_MAX_DERIVATION_BITS (TPM_CONSTANTS32)8192
+
+/* Table 2:16 - Definition of TPM_RC Constants */
+typedef UINT32 TPM_RC;
+#define TYPE_OF_TPM_RC UINT32
+#define TPM_RC_SUCCESS (TPM_RC)(0x000)
+#define TPM_RC_BAD_TAG (TPM_RC)(0x01E)
+#define RC_VER1 (TPM_RC)(0x100)
+#define TPM_RC_INITIALIZE (TPM_RC)(RC_VER1+0x000)
+#define TPM_RC_FAILURE (TPM_RC)(RC_VER1+0x001)
+#define TPM_RC_SEQUENCE (TPM_RC)(RC_VER1+0x003)
+#define TPM_RC_PRIVATE (TPM_RC)(RC_VER1+0x00B)
+#define TPM_RC_HMAC (TPM_RC)(RC_VER1+0x019)
+#define TPM_RC_DISABLED (TPM_RC)(RC_VER1+0x020)
+#define TPM_RC_EXCLUSIVE (TPM_RC)(RC_VER1+0x021)
+#define TPM_RC_AUTH_TYPE (TPM_RC)(RC_VER1+0x024)
+#define TPM_RC_AUTH_MISSING (TPM_RC)(RC_VER1+0x025)
+#define TPM_RC_POLICY (TPM_RC)(RC_VER1+0x026)
+#define TPM_RC_PCR (TPM_RC)(RC_VER1+0x027)
+#define TPM_RC_PCR_CHANGED (TPM_RC)(RC_VER1+0x028)
+#define TPM_RC_UPGRADE (TPM_RC)(RC_VER1+0x02D)
+#define TPM_RC_TOO_MANY_CONTEXTS (TPM_RC)(RC_VER1+0x02E)
+#define TPM_RC_AUTH_UNAVAILABLE (TPM_RC)(RC_VER1+0x02F)
+#define TPM_RC_REBOOT (TPM_RC)(RC_VER1+0x030)
+#define TPM_RC_UNBALANCED (TPM_RC)(RC_VER1+0x031)
+#define TPM_RC_COMMAND_SIZE (TPM_RC)(RC_VER1+0x042)
+#define TPM_RC_COMMAND_CODE (TPM_RC)(RC_VER1+0x043)
+#define TPM_RC_AUTHSIZE (TPM_RC)(RC_VER1+0x044)
+#define TPM_RC_AUTH_CONTEXT (TPM_RC)(RC_VER1+0x045)
+#define TPM_RC_NV_RANGE (TPM_RC)(RC_VER1+0x046)
+#define TPM_RC_NV_SIZE (TPM_RC)(RC_VER1+0x047)
+#define TPM_RC_NV_LOCKED (TPM_RC)(RC_VER1+0x048)
+#define TPM_RC_NV_AUTHORIZATION (TPM_RC)(RC_VER1+0x049)
+#define TPM_RC_NV_UNINITIALIZED (TPM_RC)(RC_VER1+0x04A)
+#define TPM_RC_NV_SPACE (TPM_RC)(RC_VER1+0x04B)
+#define TPM_RC_NV_DEFINED (TPM_RC)(RC_VER1+0x04C)
+#define TPM_RC_BAD_CONTEXT (TPM_RC)(RC_VER1+0x050)
+#define TPM_RC_CPHASH (TPM_RC)(RC_VER1+0x051)
+#define TPM_RC_PARENT (TPM_RC)(RC_VER1+0x052)
+#define TPM_RC_NEEDS_TEST (TPM_RC)(RC_VER1+0x053)
+#define TPM_RC_NO_RESULT (TPM_RC)(RC_VER1+0x054)
+#define TPM_RC_SENSITIVE (TPM_RC)(RC_VER1+0x055)
+#define RC_MAX_FM0 (TPM_RC)(RC_VER1+0x07F)
+#define RC_FMT1 (TPM_RC)(0x080)
+#define TPM_RC_ASYMMETRIC (TPM_RC)(RC_FMT1+0x001)
+#define TPM_RCS_ASYMMETRIC (TPM_RC)(RC_FMT1+0x001)
+#define TPM_RC_ATTRIBUTES (TPM_RC)(RC_FMT1+0x002)
+#define TPM_RCS_ATTRIBUTES (TPM_RC)(RC_FMT1+0x002)
+#define TPM_RC_HASH (TPM_RC)(RC_FMT1+0x003)
+#define TPM_RCS_HASH (TPM_RC)(RC_FMT1+0x003)
+#define TPM_RC_VALUE (TPM_RC)(RC_FMT1+0x004)
+#define TPM_RCS_VALUE (TPM_RC)(RC_FMT1+0x004)
+#define TPM_RC_HIERARCHY (TPM_RC)(RC_FMT1+0x005)
+#define TPM_RCS_HIERARCHY (TPM_RC)(RC_FMT1+0x005)
+#define TPM_RC_KEY_SIZE (TPM_RC)(RC_FMT1+0x007)
+#define TPM_RCS_KEY_SIZE (TPM_RC)(RC_FMT1+0x007)
+#define TPM_RC_MGF (TPM_RC)(RC_FMT1+0x008)
+#define TPM_RCS_MGF (TPM_RC)(RC_FMT1+0x008)
+#define TPM_RC_MODE (TPM_RC)(RC_FMT1+0x009)
+#define TPM_RCS_MODE (TPM_RC)(RC_FMT1+0x009)
+#define TPM_RC_TYPE (TPM_RC)(RC_FMT1+0x00A)
+#define TPM_RCS_TYPE (TPM_RC)(RC_FMT1+0x00A)
+#define TPM_RC_HANDLE (TPM_RC)(RC_FMT1+0x00B)
+#define TPM_RCS_HANDLE (TPM_RC)(RC_FMT1+0x00B)
+#define TPM_RC_KDF (TPM_RC)(RC_FMT1+0x00C)
+#define TPM_RCS_KDF (TPM_RC)(RC_FMT1+0x00C)
+#define TPM_RC_RANGE (TPM_RC)(RC_FMT1+0x00D)
+#define TPM_RCS_RANGE (TPM_RC)(RC_FMT1+0x00D)
+#define TPM_RC_AUTH_FAIL (TPM_RC)(RC_FMT1+0x00E)
+#define TPM_RCS_AUTH_FAIL (TPM_RC)(RC_FMT1+0x00E)
+#define TPM_RC_NONCE (TPM_RC)(RC_FMT1+0x00F)
+#define TPM_RCS_NONCE (TPM_RC)(RC_FMT1+0x00F)
+#define TPM_RC_PP (TPM_RC)(RC_FMT1+0x010)
+#define TPM_RCS_PP (TPM_RC)(RC_FMT1+0x010)
+#define TPM_RC_SCHEME (TPM_RC)(RC_FMT1+0x012)
+#define TPM_RCS_SCHEME (TPM_RC)(RC_FMT1+0x012)
+#define TPM_RC_SIZE (TPM_RC)(RC_FMT1+0x015)
+#define TPM_RCS_SIZE (TPM_RC)(RC_FMT1+0x015)
+#define TPM_RC_SYMMETRIC (TPM_RC)(RC_FMT1+0x016)
+#define TPM_RCS_SYMMETRIC (TPM_RC)(RC_FMT1+0x016)
+#define TPM_RC_TAG (TPM_RC)(RC_FMT1+0x017)
+#define TPM_RCS_TAG (TPM_RC)(RC_FMT1+0x017)
+#define TPM_RC_SELECTOR (TPM_RC)(RC_FMT1+0x018)
+#define TPM_RCS_SELECTOR (TPM_RC)(RC_FMT1+0x018)
+#define TPM_RC_INSUFFICIENT (TPM_RC)(RC_FMT1+0x01A)
+#define TPM_RCS_INSUFFICIENT (TPM_RC)(RC_FMT1+0x01A)
+#define TPM_RC_SIGNATURE (TPM_RC)(RC_FMT1+0x01B)
+#define TPM_RCS_SIGNATURE (TPM_RC)(RC_FMT1+0x01B)
+#define TPM_RC_KEY (TPM_RC)(RC_FMT1+0x01C)
+#define TPM_RCS_KEY (TPM_RC)(RC_FMT1+0x01C)
+#define TPM_RC_POLICY_FAIL (TPM_RC)(RC_FMT1+0x01D)
+#define TPM_RCS_POLICY_FAIL (TPM_RC)(RC_FMT1+0x01D)
+#define TPM_RC_INTEGRITY (TPM_RC)(RC_FMT1+0x01F)
+#define TPM_RCS_INTEGRITY (TPM_RC)(RC_FMT1+0x01F)
+#define TPM_RC_TICKET (TPM_RC)(RC_FMT1+0x020)
+#define TPM_RCS_TICKET (TPM_RC)(RC_FMT1+0x020)
+#define TPM_RC_RESERVED_BITS (TPM_RC)(RC_FMT1+0x021)
+#define TPM_RCS_RESERVED_BITS (TPM_RC)(RC_FMT1+0x021)
+#define TPM_RC_BAD_AUTH (TPM_RC)(RC_FMT1+0x022)
+#define TPM_RCS_BAD_AUTH (TPM_RC)(RC_FMT1+0x022)
+#define TPM_RC_EXPIRED (TPM_RC)(RC_FMT1+0x023)
+#define TPM_RCS_EXPIRED (TPM_RC)(RC_FMT1+0x023)
+#define TPM_RC_POLICY_CC (TPM_RC)(RC_FMT1+0x024)
+#define TPM_RCS_POLICY_CC (TPM_RC)(RC_FMT1+0x024)
+#define TPM_RC_BINDING (TPM_RC)(RC_FMT1+0x025)
+#define TPM_RCS_BINDING (TPM_RC)(RC_FMT1+0x025)
+#define TPM_RC_CURVE (TPM_RC)(RC_FMT1+0x026)
+#define TPM_RCS_CURVE (TPM_RC)(RC_FMT1+0x026)
+#define TPM_RC_ECC_POINT (TPM_RC)(RC_FMT1+0x027)
+#define TPM_RCS_ECC_POINT (TPM_RC)(RC_FMT1+0x027)
+#define RC_WARN (TPM_RC)(0x900)
+#define TPM_RC_CONTEXT_GAP (TPM_RC)(RC_WARN+0x001)
+#define TPM_RC_OBJECT_MEMORY (TPM_RC)(RC_WARN+0x002)
+#define TPM_RC_SESSION_MEMORY (TPM_RC)(RC_WARN+0x003)
+#define TPM_RC_MEMORY (TPM_RC)(RC_WARN+0x004)
+#define TPM_RC_SESSION_HANDLES (TPM_RC)(RC_WARN+0x005)
+#define TPM_RC_OBJECT_HANDLES (TPM_RC)(RC_WARN+0x006)
+#define TPM_RC_LOCALITY (TPM_RC)(RC_WARN+0x007)
+#define TPM_RC_YIELDED (TPM_RC)(RC_WARN+0x008)
+#define TPM_RC_CANCELED (TPM_RC)(RC_WARN+0x009)
+#define TPM_RC_TESTING (TPM_RC)(RC_WARN+0x00A)
+#define TPM_RC_REFERENCE_H0 (TPM_RC)(RC_WARN+0x010)
+#define TPM_RC_REFERENCE_H1 (TPM_RC)(RC_WARN+0x011)
+#define TPM_RC_REFERENCE_H2 (TPM_RC)(RC_WARN+0x012)
+#define TPM_RC_REFERENCE_H3 (TPM_RC)(RC_WARN+0x013)
+#define TPM_RC_REFERENCE_H4 (TPM_RC)(RC_WARN+0x014)
+#define TPM_RC_REFERENCE_H5 (TPM_RC)(RC_WARN+0x015)
+#define TPM_RC_REFERENCE_H6 (TPM_RC)(RC_WARN+0x016)
+#define TPM_RC_REFERENCE_S0 (TPM_RC)(RC_WARN+0x018)
+#define TPM_RC_REFERENCE_S1 (TPM_RC)(RC_WARN+0x019)
+#define TPM_RC_REFERENCE_S2 (TPM_RC)(RC_WARN+0x01A)
+#define TPM_RC_REFERENCE_S3 (TPM_RC)(RC_WARN+0x01B)
+#define TPM_RC_REFERENCE_S4 (TPM_RC)(RC_WARN+0x01C)
+#define TPM_RC_REFERENCE_S5 (TPM_RC)(RC_WARN+0x01D)
+#define TPM_RC_REFERENCE_S6 (TPM_RC)(RC_WARN+0x01E)
+#define TPM_RC_NV_RATE (TPM_RC)(RC_WARN+0x020)
+#define TPM_RC_LOCKOUT (TPM_RC)(RC_WARN+0x021)
+#define TPM_RC_RETRY (TPM_RC)(RC_WARN+0x022)
+#define TPM_RC_NV_UNAVAILABLE (TPM_RC)(RC_WARN+0x023)
+#define TPM_RC_NOT_USED (TPM_RC)(RC_WARN+0x7F)
+#define TPM_RC_H (TPM_RC)(0x000)
+#define TPM_RC_P (TPM_RC)(0x040)
+#define TPM_RC_S (TPM_RC)(0x800)
+#define TPM_RC_1 (TPM_RC)(0x100)
+#define TPM_RC_2 (TPM_RC)(0x200)
+#define TPM_RC_3 (TPM_RC)(0x300)
+#define TPM_RC_4 (TPM_RC)(0x400)
+#define TPM_RC_5 (TPM_RC)(0x500)
+#define TPM_RC_6 (TPM_RC)(0x600)
+#define TPM_RC_7 (TPM_RC)(0x700)
+#define TPM_RC_8 (TPM_RC)(0x800)
+#define TPM_RC_9 (TPM_RC)(0x900)
+#define TPM_RC_A (TPM_RC)(0xA00)
+#define TPM_RC_B (TPM_RC)(0xB00)
+#define TPM_RC_C (TPM_RC)(0xC00)
+#define TPM_RC_D (TPM_RC)(0xD00)
+#define TPM_RC_E (TPM_RC)(0xE00)
+#define TPM_RC_F (TPM_RC)(0xF00)
+#define TPM_RC_N_MASK (TPM_RC)(0xF00)
+
+/* Table 2:17 - Definition of TPM_CLOCK_ADJUST Constants */
+typedef INT8 TPM_CLOCK_ADJUST;
+#define TYPE_OF_TPM_CLOCK_ADJUST UINT8
+#define TPM_CLOCK_COARSE_SLOWER (TPM_CLOCK_ADJUST)(-3)
+#define TPM_CLOCK_MEDIUM_SLOWER (TPM_CLOCK_ADJUST)(-2)
+#define TPM_CLOCK_FINE_SLOWER (TPM_CLOCK_ADJUST)(-1)
+#define TPM_CLOCK_NO_CHANGE (TPM_CLOCK_ADJUST)(0)
+#define TPM_CLOCK_FINE_FASTER (TPM_CLOCK_ADJUST)(1)
+#define TPM_CLOCK_MEDIUM_FASTER (TPM_CLOCK_ADJUST)(2)
+#define TPM_CLOCK_COARSE_FASTER (TPM_CLOCK_ADJUST)(3)
+
+/* Table 2:18 - Definition of TPM_EO Constants */
+typedef UINT16 TPM_EO;
+#define TYPE_OF_TPM_EO UINT16
+#define TPM_EO_EQ (TPM_EO)(0x0000)
+#define TPM_EO_NEQ (TPM_EO)(0x0001)
+#define TPM_EO_SIGNED_GT (TPM_EO)(0x0002)
+#define TPM_EO_UNSIGNED_GT (TPM_EO)(0x0003)
+#define TPM_EO_SIGNED_LT (TPM_EO)(0x0004)
+#define TPM_EO_UNSIGNED_LT (TPM_EO)(0x0005)
+#define TPM_EO_SIGNED_GE (TPM_EO)(0x0006)
+#define TPM_EO_UNSIGNED_GE (TPM_EO)(0x0007)
+#define TPM_EO_SIGNED_LE (TPM_EO)(0x0008)
+#define TPM_EO_UNSIGNED_LE (TPM_EO)(0x0009)
+#define TPM_EO_BITSET (TPM_EO)(0x000A)
+#define TPM_EO_BITCLEAR (TPM_EO)(0x000B)
+/* Table 2:19 - Definition of TPM_ST Constants */
+
+typedef UINT16 TPM_ST;
+#define TYPE_OF_TPM_ST UINT16
+#define TPM_ST_RSP_COMMAND (TPM_ST)(0x00C4)
+#define TPM_ST_NULL (TPM_ST)(0x8000)
+#define TPM_ST_NO_SESSIONS (TPM_ST)(0x8001)
+#define TPM_ST_SESSIONS (TPM_ST)(0x8002)
+#define TPM_ST_ATTEST_NV (TPM_ST)(0x8014)
+#define TPM_ST_ATTEST_COMMAND_AUDIT (TPM_ST)(0x8015)
+#define TPM_ST_ATTEST_SESSION_AUDIT (TPM_ST)(0x8016)
+#define TPM_ST_ATTEST_CERTIFY (TPM_ST)(0x8017)
+#define TPM_ST_ATTEST_QUOTE (TPM_ST)(0x8018)
+#define TPM_ST_ATTEST_TIME (TPM_ST)(0x8019)
+#define TPM_ST_ATTEST_CREATION (TPM_ST)(0x801A)
+#define TPM_ST_ATTEST_NV_DIGEST (TPM_ST)(0x801C)
+#define TPM_ST_CREATION (TPM_ST)(0x8021)
+#define TPM_ST_VERIFIED (TPM_ST)(0x8022)
+#define TPM_ST_AUTH_SECRET (TPM_ST)(0x8023)
+#define TPM_ST_HASHCHECK (TPM_ST)(0x8024)
+#define TPM_ST_AUTH_SIGNED (TPM_ST)(0x8025)
+#define TPM_ST_FU_MANIFEST (TPM_ST)(0x8029)
+
+/* Table 2:20 - Definition of TPM_SU Constants */
+typedef UINT16 TPM_SU;
+#define TYPE_OF_TPM_SU UINT16
+#define TPM_SU_CLEAR (TPM_SU)(0x0000)
+#define TPM_SU_STATE (TPM_SU)(0x0001)
+
+/* Table 2:21 - Definition of TPM_SE Constants */
+typedef UINT8 TPM_SE;
+#define TYPE_OF_TPM_SE UINT8
+#define TPM_SE_HMAC (TPM_SE)(0x00)
+#define TPM_SE_POLICY (TPM_SE)(0x01)
+#define TPM_SE_TRIAL (TPM_SE)(0x03)
+
+/* Table 2:22 - Definition of TPM_CAP Constants */
+typedef UINT32 TPM_CAP;
+#define TYPE_OF_TPM_CAP UINT32
+#define TPM_CAP_FIRST (TPM_CAP)(0x00000000)
+#define TPM_CAP_ALGS (TPM_CAP)(0x00000000)
+#define TPM_CAP_HANDLES (TPM_CAP)(0x00000001)
+#define TPM_CAP_COMMANDS (TPM_CAP)(0x00000002)
+#define TPM_CAP_PP_COMMANDS (TPM_CAP)(0x00000003)
+#define TPM_CAP_AUDIT_COMMANDS (TPM_CAP)(0x00000004)
+#define TPM_CAP_PCRS (TPM_CAP)(0x00000005)
+#define TPM_CAP_TPM_PROPERTIES (TPM_CAP)(0x00000006)
+#define TPM_CAP_PCR_PROPERTIES (TPM_CAP)(0x00000007)
+#define TPM_CAP_ECC_CURVES (TPM_CAP)(0x00000008)
+#define TPM_CAP_AUTH_POLICIES (TPM_CAP)(0x00000009)
+#define TPM_CAP_ACT (TPM_CAP)(0x0000000a)
+#define TPM_CAP_LAST (TPM_CAP)(0x0000000a)
+#define TPM_CAP_VENDOR_PROPERTY (TPM_CAP)(0x00000100)
+
+/* Table 2:23 - Definition of TPM_PT Constants */
+typedef UINT32 TPM_PT;
+#define TYPE_OF_TPM_PT UINT32
+#define TPM_PT_NONE (TPM_PT)(0x00000000)
+#define PT_GROUP (TPM_PT)(0x00000100)
+#define PT_FIXED (TPM_PT)(PT_GROUP*1)
+#define TPM_PT_FAMILY_INDICATOR (TPM_PT)(PT_FIXED+0)
+#define TPM_PT_LEVEL (TPM_PT)(PT_FIXED+1)
+#define TPM_PT_REVISION (TPM_PT)(PT_FIXED+2)
+#define TPM_PT_DAY_OF_YEAR (TPM_PT)(PT_FIXED+3)
+#define TPM_PT_YEAR (TPM_PT)(PT_FIXED+4)
+#define TPM_PT_MANUFACTURER (TPM_PT)(PT_FIXED+5)
+#define TPM_PT_VENDOR_STRING_1 (TPM_PT)(PT_FIXED+6)
+#define TPM_PT_VENDOR_STRING_2 (TPM_PT)(PT_FIXED+7)
+#define TPM_PT_VENDOR_STRING_3 (TPM_PT)(PT_FIXED+8)
+#define TPM_PT_VENDOR_STRING_4 (TPM_PT)(PT_FIXED+9)
+#define TPM_PT_VENDOR_TPM_TYPE (TPM_PT)(PT_FIXED+10)
+#define TPM_PT_FIRMWARE_VERSION_1 (TPM_PT)(PT_FIXED+11)
+#define TPM_PT_FIRMWARE_VERSION_2 (TPM_PT)(PT_FIXED+12)
+#define TPM_PT_INPUT_BUFFER (TPM_PT)(PT_FIXED+13)
+#define TPM_PT_HR_TRANSIENT_MIN (TPM_PT)(PT_FIXED+14)
+#define TPM_PT_HR_PERSISTENT_MIN (TPM_PT)(PT_FIXED+15)
+#define TPM_PT_HR_LOADED_MIN (TPM_PT)(PT_FIXED+16)
+#define TPM_PT_ACTIVE_SESSIONS_MAX (TPM_PT)(PT_FIXED+17)
+#define TPM_PT_PCR_COUNT (TPM_PT)(PT_FIXED+18)
+#define TPM_PT_PCR_SELECT_MIN (TPM_PT)(PT_FIXED+19)
+#define TPM_PT_CONTEXT_GAP_MAX (TPM_PT)(PT_FIXED+20)
+#define TPM_PT_NV_COUNTERS_MAX (TPM_PT)(PT_FIXED+22)
+#define TPM_PT_NV_INDEX_MAX (TPM_PT)(PT_FIXED+23)
+#define TPM_PT_MEMORY (TPM_PT)(PT_FIXED+24)
+#define TPM_PT_CLOCK_UPDATE (TPM_PT)(PT_FIXED+25)
+#define TPM_PT_CONTEXT_HASH (TPM_PT)(PT_FIXED+26)
+#define TPM_PT_CONTEXT_SYM (TPM_PT)(PT_FIXED+27)
+#define TPM_PT_CONTEXT_SYM_SIZE (TPM_PT)(PT_FIXED+28)
+#define TPM_PT_ORDERLY_COUNT (TPM_PT)(PT_FIXED+29)
+#define TPM_PT_MAX_COMMAND_SIZE (TPM_PT)(PT_FIXED+30)
+#define TPM_PT_MAX_RESPONSE_SIZE (TPM_PT)(PT_FIXED+31)
+#define TPM_PT_MAX_DIGEST (TPM_PT)(PT_FIXED+32)
+#define TPM_PT_MAX_OBJECT_CONTEXT (TPM_PT)(PT_FIXED+33)
+#define TPM_PT_MAX_SESSION_CONTEXT (TPM_PT)(PT_FIXED+34)
+#define TPM_PT_PS_FAMILY_INDICATOR (TPM_PT)(PT_FIXED+35)
+#define TPM_PT_PS_LEVEL (TPM_PT)(PT_FIXED+36)
+#define TPM_PT_PS_REVISION (TPM_PT)(PT_FIXED+37)
+#define TPM_PT_PS_DAY_OF_YEAR (TPM_PT)(PT_FIXED+38)
+#define TPM_PT_PS_YEAR (TPM_PT)(PT_FIXED+39)
+#define TPM_PT_SPLIT_MAX (TPM_PT)(PT_FIXED+40)
+#define TPM_PT_TOTAL_COMMANDS (TPM_PT)(PT_FIXED+41)
+#define TPM_PT_LIBRARY_COMMANDS (TPM_PT)(PT_FIXED+42)
+#define TPM_PT_VENDOR_COMMANDS (TPM_PT)(PT_FIXED+43)
+#define TPM_PT_NV_BUFFER_MAX (TPM_PT)(PT_FIXED+44)
+#define TPM_PT_MODES (TPM_PT)(PT_FIXED+45)
+#define TPM_PT_MAX_CAP_BUFFER (TPM_PT)(PT_FIXED+46)
+#define PT_VAR (TPM_PT)(PT_GROUP*2)
+#define TPM_PT_PERMANENT (TPM_PT)(PT_VAR+0)
+#define TPM_PT_STARTUP_CLEAR (TPM_PT)(PT_VAR+1)
+#define TPM_PT_HR_NV_INDEX (TPM_PT)(PT_VAR+2)
+#define TPM_PT_HR_LOADED (TPM_PT)(PT_VAR+3)
+#define TPM_PT_HR_LOADED_AVAIL (TPM_PT)(PT_VAR+4)
+#define TPM_PT_HR_ACTIVE (TPM_PT)(PT_VAR+5)
+#define TPM_PT_HR_ACTIVE_AVAIL (TPM_PT)(PT_VAR+6)
+#define TPM_PT_HR_TRANSIENT_AVAIL (TPM_PT)(PT_VAR+7)
+#define TPM_PT_HR_PERSISTENT (TPM_PT)(PT_VAR+8)
+#define TPM_PT_HR_PERSISTENT_AVAIL (TPM_PT)(PT_VAR+9)
+#define TPM_PT_NV_COUNTERS (TPM_PT)(PT_VAR+10)
+#define TPM_PT_NV_COUNTERS_AVAIL (TPM_PT)(PT_VAR+11)
+#define TPM_PT_ALGORITHM_SET (TPM_PT)(PT_VAR+12)
+#define TPM_PT_LOADED_CURVES (TPM_PT)(PT_VAR+13)
+#define TPM_PT_LOCKOUT_COUNTER (TPM_PT)(PT_VAR+14)
+#define TPM_PT_MAX_AUTH_FAIL (TPM_PT)(PT_VAR+15)
+#define TPM_PT_LOCKOUT_INTERVAL (TPM_PT)(PT_VAR+16)
+#define TPM_PT_LOCKOUT_RECOVERY (TPM_PT)(PT_VAR+17)
+#define TPM_PT_NV_WRITE_RECOVERY (TPM_PT)(PT_VAR+18)
+#define TPM_PT_AUDIT_COUNTER_0 (TPM_PT)(PT_VAR+19)
+#define TPM_PT_AUDIT_COUNTER_1 (TPM_PT)(PT_VAR+20)
+
+/* Table 2:24 - Definition of TPM_PT_PCR Constants */
+typedef UINT32 TPM_PT_PCR;
+#define TYPE_OF_TPM_PT_PCR UINT32
+#define TPM_PT_PCR_FIRST (TPM_PT_PCR)(0x00000000)
+#define TPM_PT_PCR_SAVE (TPM_PT_PCR)(0x00000000)
+#define TPM_PT_PCR_EXTEND_L0 (TPM_PT_PCR)(0x00000001)
+#define TPM_PT_PCR_RESET_L0 (TPM_PT_PCR)(0x00000002)
+#define TPM_PT_PCR_EXTEND_L1 (TPM_PT_PCR)(0x00000003)
+#define TPM_PT_PCR_RESET_L1 (TPM_PT_PCR)(0x00000004)
+#define TPM_PT_PCR_EXTEND_L2 (TPM_PT_PCR)(0x00000005)
+#define TPM_PT_PCR_RESET_L2 (TPM_PT_PCR)(0x00000006)
+#define TPM_PT_PCR_EXTEND_L3 (TPM_PT_PCR)(0x00000007)
+#define TPM_PT_PCR_RESET_L3 (TPM_PT_PCR)(0x00000008)
+#define TPM_PT_PCR_EXTEND_L4 (TPM_PT_PCR)(0x00000009)
+#define TPM_PT_PCR_RESET_L4 (TPM_PT_PCR)(0x0000000A)
+#define TPM_PT_PCR_NO_INCREMENT (TPM_PT_PCR)(0x00000011)
+#define TPM_PT_PCR_DRTM_RESET (TPM_PT_PCR)(0x00000012)
+#define TPM_PT_PCR_POLICY (TPM_PT_PCR)(0x00000013)
+#define TPM_PT_PCR_AUTH (TPM_PT_PCR)(0x00000014)
+#define TPM_PT_PCR_LAST (TPM_PT_PCR)(0x00000014)
+
+/* Table 2:25 - Definition of TPM_PS Constants */
+typedef UINT32 TPM_PS;
+#define TYPE_OF_TPM_PS UINT32
+#define TPM_PS_MAIN (TPM_PS)(0x00000000)
+#define TPM_PS_PC (TPM_PS)(0x00000001)
+#define TPM_PS_PDA (TPM_PS)(0x00000002)
+#define TPM_PS_CELL_PHONE (TPM_PS)(0x00000003)
+#define TPM_PS_SERVER (TPM_PS)(0x00000004)
+#define TPM_PS_PERIPHERAL (TPM_PS)(0x00000005)
+#define TPM_PS_TSS (TPM_PS)(0x00000006)
+#define TPM_PS_STORAGE (TPM_PS)(0x00000007)
+#define TPM_PS_AUTHENTICATION (TPM_PS)(0x00000008)
+#define TPM_PS_EMBEDDED (TPM_PS)(0x00000009)
+#define TPM_PS_HARDCOPY (TPM_PS)(0x0000000A)
+#define TPM_PS_INFRASTRUCTURE (TPM_PS)(0x0000000B)
+#define TPM_PS_VIRTUALIZATION (TPM_PS)(0x0000000C)
+#define TPM_PS_TNC (TPM_PS)(0x0000000D)
+#define TPM_PS_MULTI_TENANT (TPM_PS)(0x0000000E)
+#define TPM_PS_TC (TPM_PS)(0x0000000F)
+
+/* Table 2:26 - Definition of Types for Handles */
+typedef UINT32 TPM_HANDLE;
+#define TYPE_OF_TPM_HANDLE UINT32
+
+/* Table 2:27 - Definition of TPM_HT Constants */
+typedef UINT8 TPM_HT;
+#define TYPE_OF_TPM_HT UINT8
+#define TPM_HT_PCR (TPM_HT)(0x00)
+#define TPM_HT_NV_INDEX (TPM_HT)(0x01)
+#define TPM_HT_HMAC_SESSION (TPM_HT)(0x02)
+#define TPM_HT_LOADED_SESSION (TPM_HT)(0x02)
+#define TPM_HT_POLICY_SESSION (TPM_HT)(0x03)
+#define TPM_HT_SAVED_SESSION (TPM_HT)(0x03)
+#define TPM_HT_PERMANENT (TPM_HT)(0x40)
+#define TPM_HT_TRANSIENT (TPM_HT)(0x80)
+#define TPM_HT_PERSISTENT (TPM_HT)(0x81)
+#define TPM_HT_AC (TPM_HT)(0x90)
+
+/* Table 2:28 - Definition of TPM_RH Constants */
+typedef TPM_HANDLE TPM_RH;
+#define TPM_RH_FIRST (TPM_RH)(0x40000000)
+#define TPM_RH_SRK (TPM_RH)(0x40000000)
+#define TPM_RH_OWNER (TPM_RH)(0x40000001)
+#define TPM_RH_REVOKE (TPM_RH)(0x40000002)
+#define TPM_RH_TRANSPORT (TPM_RH)(0x40000003)
+#define TPM_RH_OPERATOR (TPM_RH)(0x40000004)
+#define TPM_RH_ADMIN (TPM_RH)(0x40000005)
+#define TPM_RH_EK (TPM_RH)(0x40000006)
+#define TPM_RH_NULL (TPM_RH)(0x40000007)
+#define TPM_RH_UNASSIGNED (TPM_RH)(0x40000008)
+#define TPM_RS_PW (TPM_RH)(0x40000009)
+#define TPM_RH_LOCKOUT (TPM_RH)(0x4000000A)
+#define TPM_RH_ENDORSEMENT (TPM_RH)(0x4000000B)
+#define TPM_RH_PLATFORM (TPM_RH)(0x4000000C)
+#define TPM_RH_PLATFORM_NV (TPM_RH)(0x4000000D)
+#define TPM_RH_AUTH_00 (TPM_RH)(0x40000010)
+#define TPM_RH_AUTH_FF (TPM_RH)(0x4000010F)
+#define TPM_RH_ACT_0 (TPM_RH)(0x40000110)
+#define TPM_RH_ACT_F (TPM_RH)(0x4000011F)
+#define TPM_RH_LAST (TPM_RH)(0x4000011F)
+/* Table 2:29 - Definition of TPM_HC Constants */
+typedef TPM_HANDLE TPM_HC;
+#define HR_HANDLE_MASK (TPM_HC)(0x00FFFFFF)
+#define HR_RANGE_MASK (TPM_HC)(0xFF000000)
+#define HR_SHIFT (TPM_HC)(24)
+#define HR_PCR (TPM_HC)((TPM_HT_PCR<<HR_SHIFT))
+#define HR_HMAC_SESSION (TPM_HC)((TPM_HT_HMAC_SESSION<<HR_SHIFT))
+#define HR_POLICY_SESSION (TPM_HC)((TPM_HT_POLICY_SESSION<<HR_SHIFT))
+#define HR_TRANSIENT (TPM_HC)(((UINT32)TPM_HT_TRANSIENT<<HR_SHIFT)) /* libtpms cast (ubsan) */
+#define HR_PERSISTENT (TPM_HC)(((UINT32)TPM_HT_PERSISTENT<<HR_SHIFT)) /* libtpms cast (ubsan) */
+#define HR_NV_INDEX (TPM_HC)((TPM_HT_NV_INDEX<<HR_SHIFT))
+#define HR_PERMANENT (TPM_HC)((TPM_HT_PERMANENT<<HR_SHIFT))
+#define PCR_FIRST (TPM_HC)((HR_PCR+0))
+#define PCR_LAST (TPM_HC)((PCR_FIRST+IMPLEMENTATION_PCR-1))
+#define HMAC_SESSION_FIRST (TPM_HC)((HR_HMAC_SESSION+0))
+#define HMAC_SESSION_LAST (TPM_HC)((HMAC_SESSION_FIRST + MAX_ACTIVE_SESSIONS-1))
+#define LOADED_SESSION_FIRST (TPM_HC)(HMAC_SESSION_FIRST)
+#define LOADED_SESSION_LAST (TPM_HC)(HMAC_SESSION_LAST)
+#define POLICY_SESSION_FIRST (TPM_HC)((HR_POLICY_SESSION+0))
+#define POLICY_SESSION_LAST (TPM_HC)((POLICY_SESSION_FIRST + MAX_ACTIVE_SESSIONS-1))
+#define TRANSIENT_FIRST (TPM_HC)((HR_TRANSIENT+0))
+#define ACTIVE_SESSION_FIRST (TPM_HC)(POLICY_SESSION_FIRST)
+#define ACTIVE_SESSION_LAST (TPM_HC)(POLICY_SESSION_LAST)
+#define TRANSIENT_LAST (TPM_HC)((TRANSIENT_FIRST+MAX_LOADED_OBJECTS-1))
+#define PERSISTENT_FIRST (TPM_HC)((HR_PERSISTENT+0))
+#define PERSISTENT_LAST (TPM_HC)((PERSISTENT_FIRST+0x00FFFFFF))
+#define PLATFORM_PERSISTENT (TPM_HC)((PERSISTENT_FIRST+0x00800000))
+#define NV_INDEX_FIRST (TPM_HC)((HR_NV_INDEX+0))
+#define NV_INDEX_LAST (TPM_HC)((NV_INDEX_FIRST+0x00FFFFFF))
+#define PERMANENT_FIRST (TPM_HC)(TPM_RH_FIRST)
+#define PERMANENT_LAST (TPM_HC)(TPM_RH_LAST)
+#define HR_NV_AC (TPM_HC)(((TPM_HT_NV_INDEX<<HR_SHIFT)+0xD00000))
+#define NV_AC_FIRST (TPM_HC)((HR_NV_AC+0))
+#define NV_AC_LAST (TPM_HC)((HR_NV_AC+0x0000FFFF))
+#define HR_AC (TPM_HC)((TPM_HT_AC<<HR_SHIFT))
+#define AC_FIRST (TPM_HC)((HR_AC+0))
+#define AC_LAST (TPM_HC)((HR_AC+0x0000FFFF))
+
+#define TYPE_OF_TPMA_ALGORITHM UINT32
+#define TPMA_ALGORITHM_TO_UINT32(a) (*((UINT32 *)&(a)))
+#define UINT32_TO_TPMA_ALGORITHM(a) (*((TPMA_ALGORITHM *)&(a)))
+
+#define TPMA_ALGORITHM_TO_BYTE_ARRAY(i, a) \
+ UINT32_TO_BYTE_ARRAY((TPMA_ALGORITHM_TO_UINT32(i)), (a))
+
+#define BYTE_ARRAY_TO_TPMA_ALGORITHM(i, a) \
+ {UINT32 x = BYTE_ARRAY_TO_UINT32(a); \
+ i = UINT32_TO_TPMA_ALGORITHM(x); \
+ }
+
+/* Table 2:30 - Definition of TPMA_ALGORITHM Bits */
+#if USE_BIT_FIELD_STRUCTURES
+typedef struct TPMA_ALGORITHM{
+ unsigned asymmetric : 1 ;
+ unsigned symmetric : 1 ;
+ unsigned hash : 1 ;
+ unsigned object : 1 ;
+ unsigned Reserved_bits_at_4 : 4 ;
+ unsigned signing : 1 ;
+ unsigned encrypting : 1 ;
+ unsigned method : 1 ;
+ unsigned Reserved_bits_at_11 : 21;
+} TPMA_ALGORITHM;
+/* This is the initializer for a TPMA_ALGORITHM structure. */
+#define TPMA_ALGORITHM_INITIALIZER( \
+ asymmetric, symmetric, hash, object, bits_at_4, \
+ signing, encrypting, method, bits_at_11) \
+ {asymmetric, symmetric, hash, object, bits_at_4, \
+ signing, encrypting, method, bits_at_11}
+#else // USE_BIT_FIELD_STRUCTURES
+
+typedef UINT32 TPMA_ALGORITHM;
+#define TYPE_OF_TPMA_ALGORITHM UINT32
+#define TPMA_ALGORITHM_asymmetric ((TPMA_ALGORITHM)1 << 0)
+#define TPMA_ALGORITHM_symmetric ((TPMA_ALGORITHM)1 << 1)
+#define TPMA_ALGORITHM_hash ((TPMA_ALGORITHM)1 << 2)
+#define TPMA_ALGORITHM_object ((TPMA_ALGORITHM)1 << 3)
+#define TPMA_ALGORITHM_signing ((TPMA_ALGORITHM)1 << 8)
+#define TPMA_ALGORITHM_encrypting ((TPMA_ALGORITHM)1 << 9)
+#define TPMA_ALGORITHM_method ((TPMA_ALGORITHM)1 << 10)
+#define TPMA_ALGORITHM_reserved 0xfffff8f0
+
+// This is the initializer for a TPMA_ALGORITHM bit array.
+#define TPMA_ALGORITHM_INITIALIZER( \
+ asymmetric, symmetric, hash, object, bits_at_4, \
+ signing, encrypting, method, bits_at_11) \
+ (TPMA_ALGORITHM) ( \
+ (asymmetric << 0) + (symmetric << 1) + (hash << 2) + \
+ (object << 3) + (signing << 8) + (encrypting << 9) + \
+ (method << 10))
+#endif // USE_BIT_FIELD_STRUCTURES
+
+#define TYPE_OF_TPMA_OBJECT UINT32
+#define TPMA_OBJECT_TO_UINT32(a) (*((UINT32 *)&(a)))
+#define UINT32_TO_TPMA_OBJECT(a) (*((TPMA_OBJECT *)&(a)))
+#define TPMA_OBJECT_TO_BYTE_ARRAY(i, a) \
+ UINT32_TO_BYTE_ARRAY((TPMA_OBJECT_TO_UINT32(i)), (a))
+#define BYTE_ARRAY_TO_TPMA_OBJECT(i, a) \
+ { UINT32 x = BYTE_ARRAY_TO_UINT32(a); i = UINT32_TO_TPMA_OBJECT(x); }
+
+/* This is the initializer for a TPMA_OBJECT structure. */
+#if USE_BIT_FIELD_STRUCTURES
+typedef struct TPMA_OBJECT { // Table 2:31
+ unsigned Reserved_bit_at_0 : 1;
+ unsigned fixedTPM : 1;
+ unsigned stClear : 1;
+ unsigned Reserved_bit_at_3 : 1;
+ unsigned fixedParent : 1;
+ unsigned sensitiveDataOrigin : 1;
+ unsigned userWithAuth : 1;
+ unsigned adminWithPolicy : 1;
+ unsigned Reserved_bits_at_8 : 2;
+ unsigned noDA : 1;
+ unsigned encryptedDuplication : 1;
+ unsigned Reserved_bits_at_12 : 4;
+ unsigned restricted : 1;
+ unsigned decrypt : 1;
+ unsigned sign : 1;
+ unsigned x509sign : 1;
+ unsigned Reserved_bits_at_20 : 12;
+} TPMA_OBJECT;
+// This is the initializer for a TPMA_OBJECT structure
+#define TPMA_OBJECT_INITIALIZER( \
+ bit_at_0, fixedtpm, stclear, \
+ bit_at_3, fixedparent, sensitivedataorigin, \
+ userwithauth, adminwithpolicy, bits_at_8, \
+ noda, encryptedduplication, bits_at_12, \
+ restricted, decrypt, sign, \
+ x509sign, bits_at_20) \
+ {bit_at_0, fixedtpm, stclear, \
+ bit_at_3, fixedparent, sensitivedataorigin, \
+ userwithauth, adminwithpolicy, bits_at_8, \
+ noda, encryptedduplication, bits_at_12, \
+ restricted, decrypt, sign, \
+ x509sign, bits_at_20}
+#else // USE_BIT_FIELD_STRUCTURES
+// This implements Table 2:31 TPMA_OBJECT using bit masking
+typedef UINT32 TPMA_OBJECT;
+#define TYPE_OF_TPMA_OBJECT UINT32
+#define TPMA_OBJECT_Reserved_bit_at_0 ((TPMA_OBJECT)1 << 0)
+#define TPMA_OBJECT_fixedTPM ((TPMA_OBJECT)1 << 1)
+#define TPMA_OBJECT_stClear ((TPMA_OBJECT)1 << 2)
+#define TPMA_OBJECT_fixedParent ((TPMA_OBJECT)1 << 4)
+#define TPMA_OBJECT_sensitiveDataOrigin ((TPMA_OBJECT)1 << 5)
+#define TPMA_OBJECT_userWithAuth ((TPMA_OBJECT)1 << 6)
+#define TPMA_OBJECT_adminWithPolicy ((TPMA_OBJECT)1 << 7)
+#define TPMA_OBJECT_noDA ((TPMA_OBJECT)1 << 10)
+#define TPMA_OBJECT_encryptedDuplication ((TPMA_OBJECT)1 << 11)
+#define TPMA_OBJECT_restricted ((TPMA_OBJECT)1 << 16)
+#define TPMA_OBJECT_decrypt ((TPMA_OBJECT)1 << 17)
+#define TPMA_OBJECT_sign ((TPMA_OBJECT)1 << 18)
+#define TPMA_OBJECT_x509sign ((TPMA_OBJECT)1 << 19)
+#define TPMA_OBJECT_reserved ((TPMA_OBJECT)0xfff0f309)
+// This is the initializer for a TPMA_OBJECT bit array.
+#define TPMA_OBJECT_INITIALIZER( \
+ bit_at_0, fixedtpm, stclear, \
+ bit_at_3, fixedparent, sensitivedataorigin, \
+ userwithauth, adminwithpolicy, bits_at_8, \
+ noda, encryptedduplication, bits_at_12, \
+ restricted, decrypt, sign, \
+ x509sign, bits_at_20) \
+ (TPMA_OBJECT)( \
+ (fixedtpm << 1) + (stclear << 2) + \
+ (fixedparent << 4) + (sensitivedataorigin << 5) + \
+ (userwithauth << 6) + (adminwithpolicy << 7) + \
+ (noda << 10) + (encryptedduplication << 11) + \
+ (restricted << 16) + (decrypt << 17) + \
+ (sign << 18) + (x509sign << 19))
+#endif // USE_BIT_FIELD_STRUCTURES
+
+#define TYPE_OF_TPMA_SESSION UINT8
+#define TPMA_SESSION_TO_UINT8(a) (*((UINT8 *)&(a)))
+#define UINT8_TO_TPMA_SESSION(a) (*((TPMA_SESSION *)&(a)))
+#define TPMA_SESSION_TO_BYTE_ARRAY(i, a) \
+ UINT8_TO_BYTE_ARRAY((TPMA_SESSION_TO_UINT8(i)), (a))
+#define BYTE_ARRAY_TO_TPMA_SESSION(i, a) \
+ { UINT8 x = BYTE_ARRAY_TO_UINT8(a); i = UINT8_TO_TPMA_SESSION(x); }
+#if USE_BIT_FIELD_STRUCTURES
+typedef struct TPMA_SESSION { // Table 2:32
+ unsigned continueSession : 1;
+ unsigned auditExclusive : 1;
+ unsigned auditReset : 1;
+ unsigned Reserved_bits_at_3 : 2;
+ unsigned decrypt : 1;
+ unsigned encrypt : 1;
+ unsigned audit : 1;
+} TPMA_SESSION;
+// This is the initializer for a TPMA_SESSION structure
+#define TPMA_SESSION_INITIALIZER( \
+ continuesession, auditexclusive, auditreset, bits_at_3, \
+ decrypt, encrypt, audit) \
+ {continuesession, auditexclusive, auditreset, bits_at_3, \
+ decrypt, encrypt, audit}
+#else // USE_BIT_FIELD_STRUCTURES
+// This implements Table 2:32 TPMA_SESSION using bit masking
+typedef UINT8 TPMA_SESSION;
+#define TYPE_OF_TPMA_SESSION UINT8
+#define TPMA_SESSION_continueSession ((TPMA_SESSION)1 << 0)
+#define TPMA_SESSION_auditExclusive ((TPMA_SESSION)1 << 1)
+#define TPMA_SESSION_auditReset ((TPMA_SESSION)1 << 2)
+#define TPMA_SESSION_decrypt ((TPMA_SESSION)1 << 5)
+#define TPMA_SESSION_encrypt ((TPMA_SESSION)1 << 6)
+#define TPMA_SESSION_audit ((TPMA_SESSION)1 << 7)
+#define TPMA_SESSION_reserved 0x18
+// This is the initializer for a TPMA_SESSION bit array.
+#define TPMA_SESSION_INITIALIZER( \
+ continuesession, auditexclusive, auditreset, bits_at_3, \
+ decrypt, encrypt, audit) \
+ (TPMA_SESSION) ( \
+ (continuesession << 0) + (auditexclusive << 1) + \
+ (auditreset << 2) + (decrypt << 5) + \
+ (encrypt << 6) + (audit << 7))
+#endif // USE_BIT_FIELD_STRUCTURES
+
+#define TYPE_OF_TPMA_LOCALITY UINT8
+#define TPMA_LOCALITY_TO_UINT8(a) (*((UINT8 *)&(a)))
+#define UINT8_TO_TPMA_LOCALITY(a) (*((TPMA_LOCALITY *)&(a)))
+#define TPMA_LOCALITY_TO_BYTE_ARRAY(i, a) \
+ UINT8_TO_BYTE_ARRAY((TPMA_LOCALITY_TO_UINT8(i)), (a))
+#define BYTE_ARRAY_TO_TPMA_LOCALITY(i, a) \
+ { UINT8 x = BYTE_ARRAY_TO_UINT8(a); i = UINT8_TO_TPMA_LOCALITY(x); }
+#if USE_BIT_FIELD_STRUCTURES
+typedef struct TPMA_LOCALITY { // Table 2:33
+ unsigned TPM_LOC_ZERO : 1;
+ unsigned TPM_LOC_ONE : 1;
+ unsigned TPM_LOC_TWO : 1;
+ unsigned TPM_LOC_THREE : 1;
+ unsigned TPM_LOC_FOUR : 1;
+ unsigned Extended : 3;
+} TPMA_LOCALITY;
+// This is the initializer for a TPMA_LOCALITY structure
+#define TPMA_LOCALITY_INITIALIZER( \
+ tpm_loc_zero, tpm_loc_one, tpm_loc_two, tpm_loc_three, \
+ tpm_loc_four, extended) \
+ {tpm_loc_zero, tpm_loc_one, tpm_loc_two, tpm_loc_three, \
+ tpm_loc_four, extended}
+#else // USE_BIT_FIELD_STRUCTURES
+// This implements Table 2:33 TPMA_LOCALITY using bit masking
+typedef UINT8 TPMA_LOCALITY;
+#define TYPE_OF_TPMA_LOCALITY UINT8
+#define TPMA_LOCALITY_TPM_LOC_ZERO ((TPMA_LOCALITY)1 << 0)
+#define TPMA_LOCALITY_TPM_LOC_ONE ((TPMA_LOCALITY)1 << 1)
+#define TPMA_LOCALITY_TPM_LOC_TWO ((TPMA_LOCALITY)1 << 2)
+#define TPMA_LOCALITY_TPM_LOC_THREE ((TPMA_LOCALITY)1 << 3)
+#define TPMA_LOCALITY_TPM_LOC_FOUR ((TPMA_LOCALITY)1 << 4)
+#define TPMA_LOCALITY_Extended_SHIFT 5
+#define TPMA_LOCALITY_Extended ((TPMA_LOCALITY)0x7 << 5)
+// This is the initializer for a TPMA_LOCALITY bit array.
+#define TPMA_LOCALITY_INITIALIZER( \
+ tpm_loc_zero, tpm_loc_one, tpm_loc_two, tpm_loc_three, \
+ tpm_loc_four, extended) \
+ (TPMA_LOCALITY)( \
+ (tpm_loc_zero << 0) + (tpm_loc_one << 1) + (tpm_loc_two << 2) + \
+ (tpm_loc_three << 3) + (tpm_loc_four << 4) + (extended << 5))
+#endif // USE_BIT_FIELD_STRUCTURES
+
+#define TYPE_OF_TPMA_PERMANENT UINT32
+#define TPMA_PERMANENT_TO_UINT32(a) (*((UINT32 *)&(a)))
+#define UINT32_TO_TPMA_PERMANENT(a) (*((TPMA_PERMANENT *)&(a)))
+#define TPMA_PERMANENT_TO_BYTE_ARRAY(i, a) \
+ UINT32_TO_BYTE_ARRAY((TPMA_PERMANENT_TO_UINT32(i)), (a))
+#define BYTE_ARRAY_TO_TPMA_PERMANENT(i, a) \
+ {UINT32 x = BYTE_ARRAY_TO_UINT32(a); \
+ i = UINT32_TO_TPMA_PERMANENT(x); \
+ }
+
+/* Table 2:34 - Definition of TPMA_PERMANENT Bits (BitsTable()) */
+#if USE_BIT_FIELD_STRUCTURES
+typedef struct TPMA_PERMANENT { // Table 2:34
+ unsigned ownerAuthSet : 1;
+ unsigned endorsementAuthSet : 1;
+ unsigned lockoutAuthSet : 1;
+ unsigned Reserved_bits_at_3 : 5;
+ unsigned disableClear : 1;
+ unsigned inLockout : 1;
+ unsigned tpmGeneratedEPS : 1;
+ unsigned Reserved_bits_at_11 : 21;
+} TPMA_PERMANENT;
+// This is the initializer for a TPMA_PERMANENT structure
+#define TPMA_PERMANENT_INITIALIZER( \
+ ownerauthset, endorsementauthset, lockoutauthset, \
+ bits_at_3, disableclear, inlockout, \
+ tpmgeneratedeps, bits_at_11) \
+ {ownerauthset, endorsementauthset, lockoutauthset, \
+ bits_at_3, disableclear, inlockout, \
+ tpmgeneratedeps, bits_at_11}
+#else // USE_BIT_FIELD_STRUCTURES
+// This implements Table 2:34 TPMA_PERMANENT using bit masking
+typedef UINT32 TPMA_PERMANENT;
+#define TYPE_OF_TPMA_PERMANENT UINT32
+#define TPMA_PERMANENT_ownerAuthSet ((TPMA_PERMANENT)1 << 0)
+#define TPMA_PERMANENT_endorsementAuthSet ((TPMA_PERMANENT)1 << 1)
+#define TPMA_PERMANENT_lockoutAuthSet ((TPMA_PERMANENT)1 << 2)
+#define TPMA_PERMANENT_disableClear ((TPMA_PERMANENT)1 << 8)
+#define TPMA_PERMANENT_inLockout ((TPMA_PERMANENT)1 << 9)
+#define TPMA_PERMANENT_tpmGeneratedEPS ((TPMA_PERMANENT)1 << 10)
+// This is the initializer for a TPMA_PERMANENT bit array.
+#define TPMA_PERMANENT_INITIALIZER( \
+ ownerauthset, endorsementauthset, lockoutauthset, \
+ bits_at_3, disableclear, inlockout, \
+ tpmgeneratedeps, bits_at_11) \
+ (TPMA_PERMANENT) ( \
+ (ownerauthset << 0) + (endorsementauthset << 1) + \
+ (lockoutauthset << 2) + (disableclear << 8) + \
+ (inlockout << 9) + (tpmgeneratedeps << 10))
+#endif // USE_BIT_FIELD_STRUCTURES
+
+#define TYPE_OF_TPMA_STARTUP_CLEAR UINT32
+#define TPMA_STARTUP_CLEAR_TO_UINT32(a) (*((UINT32 *)&(a)))
+#define UINT32_TO_TPMA_STARTUP_CLEAR(a) (*((TPMA_STARTUP_CLEAR *)&(a)))
+#define TPMA_STARTUP_CLEAR_TO_BYTE_ARRAY(i, a) \
+ UINT32_TO_BYTE_ARRAY((TPMA_STARTUP_CLEAR_TO_UINT32(i)), (a))
+#define BYTE_ARRAY_TO_TPMA_STARTUP_CLEAR(i, a) \
+ {UINT32 x = BYTE_ARRAY_TO_UINT32(a); \
+ i = UINT32_TO_TPMA_STARTUP_CLEAR(x); \
+ }
+
+/* Table 2:35 - Definition of TPMA_STARTUP_CLEAR Bits */
+#if USE_BIT_FIELD_STRUCTURES
+typedef struct TPMA_STARTUP_CLEAR { // Table 2:35
+ unsigned phEnable : 1;
+ unsigned shEnable : 1;
+ unsigned ehEnable : 1;
+ unsigned phEnableNV : 1;
+ unsigned Reserved_bits_at_4 : 27;
+ unsigned orderly : 1;
+} TPMA_STARTUP_CLEAR;
+// This is the initializer for a TPMA_STARTUP_CLEAR structure
+#define TPMA_STARTUP_CLEAR_INITIALIZER( \
+ phenable, shenable, ehenable, phenablenv, bits_at_4, orderly) \
+ {phenable, shenable, ehenable, phenablenv, bits_at_4, orderly}
+#else // USE_BIT_FIELD_STRUCTURES
+// This implements Table 2:35 TPMA_STARTUP_CLEAR using bit masking
+typedef UINT32 TPMA_STARTUP_CLEAR;
+#define TYPE_OF_TPMA_STARTUP_CLEAR UINT32
+#define TPMA_STARTUP_CLEAR_phEnable ((TPMA_STARTUP_CLEAR)1 << 0)
+#define TPMA_STARTUP_CLEAR_shEnable ((TPMA_STARTUP_CLEAR)1 << 1)
+#define TPMA_STARTUP_CLEAR_ehEnable ((TPMA_STARTUP_CLEAR)1 << 2)
+#define TPMA_STARTUP_CLEAR_phEnableNV ((TPMA_STARTUP_CLEAR)1 << 3)
+#define TPMA_STARTUP_CLEAR_orderly ((TPMA_STARTUP_CLEAR)1 << 31)
+// This is the initializer for a TPMA_STARTUP_CLEAR bit array.
+#define TPMA_STARTUP_CLEAR_INITIALIZER( \
+ phenable, shenable, ehenable, phenablenv, bits_at_4, orderly) \
+ (TPMA_STARTUP_CLEAR) ( \
+ (phenable << 0) + (shenable << 1) + (ehenable << 2) + \
+ (phenablenv << 3) + (orderly << 31))
+#endif // USE_BIT_FIELD_STRUCTURES
+
+#define TYPE_OF_TPMA_MEMORY UINT32
+#define TPMA_MEMORY_TO_UINT32(a) (*((UINT32 *)&(a)))
+#define UINT32_TO_TPMA_MEMORY(a) (*((TPMA_MEMORY *)&(a)))
+#define TPMA_MEMORY_TO_BYTE_ARRAY(i, a) \
+ UINT32_TO_BYTE_ARRAY((TPMA_MEMORY_TO_UINT32(i)), (a))
+#define BYTE_ARRAY_TO_TPMA_MEMORY(i, a) \
+ { UINT32 x = BYTE_ARRAY_TO_UINT32(a); i = UINT32_TO_TPMA_MEMORY(x); }
+#if USE_BIT_FIELD_STRUCTURES
+typedef struct TPMA_MEMORY { // Table 2:36
+ unsigned sharedRAM : 1;
+ unsigned sharedNV : 1;
+ unsigned objectCopiedToRam : 1;
+ unsigned Reserved_bits_at_3 : 29;
+} TPMA_MEMORY;
+// This is the initializer for a TPMA_MEMORY structure
+#define TPMA_MEMORY_INITIALIZER( \
+ sharedram, sharednv, objectcopiedtoram, bits_at_3) \
+ {sharedram, sharednv, objectcopiedtoram, bits_at_3}
+#else // USE_BIT_FIELD_STRUCTURES
+// This implements Table 2:36 TPMA_MEMORY using bit masking
+typedef UINT32 TPMA_MEMORY;
+#define TYPE_OF_TPMA_MEMORY UINT32
+#define TPMA_MEMORY_sharedRAM ((TPMA_MEMORY)1 << 0)
+#define TPMA_MEMORY_sharedNV ((TPMA_MEMORY)1 << 1)
+#define TPMA_MEMORY_objectCopiedToRam ((TPMA_MEMORY)1 << 2)
+// This is the initializer for a TPMA_MEMORY bit array.
+#define TPMA_MEMORY_INITIALIZER( \
+ sharedram, sharednv, objectcopiedtoram, bits_at_3) \
+ (TPMA_MEMORY)( \
+ (sharedram << 0) + (sharednv << 1) + (objectcopiedtoram << 2))
+#endif // USE_BIT_FIELD_STRUCTURES
+
+#define TYPE_OF_TPMA_CC UINT32
+#define TPMA_CC_TO_UINT32(a) (*((UINT32 *)&(a)))
+#define UINT32_TO_TPMA_CC(a) (*((TPMA_CC *)&(a)))
+#define TPMA_CC_TO_BYTE_ARRAY(i, a) \
+ UINT32_TO_BYTE_ARRAY((TPMA_CC_TO_UINT32(i)), (a))
+#define BYTE_ARRAY_TO_TPMA_CC(i, a) \
+ { UINT32 x = BYTE_ARRAY_TO_UINT32(a); i = UINT32_TO_TPMA_CC(x); }
+#if USE_BIT_FIELD_STRUCTURES
+typedef struct TPMA_CC { // Table 2:37
+ unsigned commandIndex : 16;
+ unsigned Reserved_bits_at_16 : 6;
+ unsigned nv : 1;
+ unsigned extensive : 1;
+ unsigned flushed : 1;
+ unsigned cHandles : 3;
+ unsigned rHandle : 1;
+ unsigned V : 1;
+ unsigned Reserved_bits_at_30 : 2;
+} TPMA_CC;
+// This is the initializer for a TPMA_CC structure
+#define TPMA_CC_INITIALIZER( \
+ commandindex, bits_at_16, nv, extensive, flushed, \
+ chandles, rhandle, v, bits_at_30) \
+ {commandindex, bits_at_16, nv, extensive, flushed, \
+ chandles, rhandle, v, bits_at_30}
+#else // USE_BIT_FIELD_STRUCTURES
+// This implements Table 2:37 TPMA_CC using bit masking
+typedef UINT32 TPMA_CC;
+#define TYPE_OF_TPMA_CC UINT32
+#define TPMA_CC_commandIndex_SHIFT 0
+#define TPMA_CC_commandIndex ((TPMA_CC)0xffff << 0)
+#define TPMA_CC_nv ((TPMA_CC)1 << 22)
+#define TPMA_CC_extensive ((TPMA_CC)1 << 23)
+#define TPMA_CC_flushed ((TPMA_CC)1 << 24)
+#define TPMA_CC_cHandles_SHIFT 25
+#define TPMA_CC_cHandles ((TPMA_CC)0x7 << 25)
+#define TPMA_CC_rHandle ((TPMA_CC)1 << 28)
+#define TPMA_CC_V ((TPMA_CC)1 << 29)
+#define TPMA_CC_reserved 0xc03f0000
+// This is the initializer for a TPMA_CC bit array.
+#define TPMA_CC_INITIALIZER( \
+ commandindex, bits_at_16, nv, extensive, flushed, \
+ chandles, rhandle, v, bits_at_30) \
+ (TPMA_CC)( \
+ (commandindex << 0) + (nv << 22) + (extensive << 23) + \
+ (flushed << 24) + (chandles << 25) + (rhandle << 28) + \
+ (v << 29))
+#endif // USE_BIT_FIELD_STRUCTURES
+
+#define TYPE_OF_TPMA_MODES UINT32
+#define TPMA_MODES_TO_UINT32(a) (*((UINT32 *)&(a)))
+#define UINT32_TO_TPMA_MODES(a) (*((TPMA_MODES *)&(a)))
+#define TPMA_MODES_TO_BYTE_ARRAY(i, a) \
+ UINT32_TO_BYTE_ARRAY((TPMA_MODES_TO_UINT32(i)), (a))
+#define BYTE_ARRAY_TO_TPMA_MODES(i, a) \
+ { UINT32 x = BYTE_ARRAY_TO_UINT32(a); i = UINT32_TO_TPMA_MODES(x); }
+#if USE_BIT_FIELD_STRUCTURES
+typedef struct TPMA_MODES { // Table 2:38
+ unsigned FIPS_140_2 : 1;
+ unsigned Reserved_bits_at_1 : 31;
+} TPMA_MODES;
+// This is the initializer for a TPMA_MODES structure
+#define TPMA_MODES_INITIALIZER(fips_140_2, bits_at_1) {fips_140_2, bits_at_1}
+#else // USE_BIT_FIELD_STRUCTURES
+// This implements Table 2:38 TPMA_MODES using bit masking
+typedef UINT32 TPMA_MODES;
+#define TYPE_OF_TPMA_MODES UINT32
+#define TPMA_MODES_FIPS_140_2 ((TPMA_MODES)1 << 0)
+// This is the initializer for a TPMA_MODES bit array.
+#define TPMA_MODES_INITIALIZER(fips_140_2, bits_at_1) \
+ (TPMA_MODES)( \
+ ((fips_140_2 << 0))
+#endif // USE_BIT_FIELD_STRUCTURES
+
+#define TYPE_OF_TPMA_X509_KEY_USAGE UINT32
+#define TPMA_X509_KEY_USAGE_TO_UINT32(a) (*((UINT32 *)&(a)))
+#define UINT32_TO_TPMA_X509_KEY_USAGE(a) (*((TPMA_X509_KEY_USAGE *)&(a)))
+#define TPMA_X509_KEY_USAGE_TO_BYTE_ARRAY(i, a) \
+ UINT32_TO_BYTE_ARRAY((TPMA_X509_KEY_USAGE_TO_UINT32(i)), (a))
+#define BYTE_ARRAY_TO_TPMA_X509_KEY_USAGE(i, a) \
+ {UINT32 x = BYTE_ARRAY_TO_UINT32(a); \
+ i = UINT32_TO_TPMA_X509_KEY_USAGE(x); \
+ }
+#if USE_BIT_FIELD_STRUCTURES
+typedef struct TPMA_X509_KEY_USAGE { // Table 2:39
+ unsigned Reserved_bits_at_0 : 23;
+ unsigned decipherOnly : 1;
+ unsigned encipherOnly : 1;
+ unsigned cRLSign : 1;
+ unsigned keyCertSign : 1;
+ unsigned keyAgreement : 1;
+ unsigned dataEncipherment : 1;
+ unsigned keyEncipherment : 1;
+ unsigned nonrepudiation : 1;
+ unsigned digitalSignature : 1;
+} TPMA_X509_KEY_USAGE; /* Bits */
+// This is the initializer for a TPMA_X509_KEY_USAGE structure
+#define TPMA_X509_KEY_USAGE_INITIALIZER( \
+ bits_at_0, decipheronly, encipheronly, \
+ cRLSign, keycertsign, keyagreement, \
+ dataencipherment, keyencipherment, nonrepudiation, \
+ digitalsignature) \
+ {bits_at_0, decipheronly, encipheronly, \
+ cRLSign, keycertsign, keyagreement, \
+ dataencipherment, keyencipherment, nonrepudiation, \
+ digitalsignature}
+#else // USE_BIT_FIELD_STRUCTURES
+/* This implements Table 2:39 TPMA_X509_KEY_USAGE using bit masking */
+typedef UINT32 TPMA_X509_KEY_USAGE;
+#define TYPE_OF_TPMA_X509_KEY_USAGE UINT32
+#define TPMA_X509_KEY_USAGE_decipherOnly ((TPMA_X509_KEY_USAGE)1 << 23)
+#define TPMA_X509_KEY_USAGE_encipherOnly ((TPMA_X509_KEY_USAGE)1 << 24)
+#define TPMA_X509_KEY_USAGE_cRLSign ((TPMA_X509_KEY_USAGE)1 << 25)
+#define TPMA_X509_KEY_USAGE_keyCertSign ((TPMA_X509_KEY_USAGE)1 << 26)
+#define TPMA_X509_KEY_USAGE_keyAgreement ((TPMA_X509_KEY_USAGE)1 << 27)
+#define TPMA_X509_KEY_USAGE_dataEncipherment ((TPMA_X509_KEY_USAGE)1 << 28)
+#define TPMA_X509_KEY_USAGE_keyEncipherment ((TPMA_X509_KEY_USAGE)1 << 29)
+#define TPMA_X509_KEY_USAGE_nonrepudiation ((TPMA_X509_KEY_USAGE)1 << 30)
+#define TPMA_X509_KEY_USAGE_digitalSignature ((TPMA_X509_KEY_USAGE)1 << 31)
+// This is the initializer for a TPMA_X509_KEY_USAGE bit array.
+#define TPMA_X509_KEY_USAGE_INITIALIZER( \
+ bits_at_0, decipheronly, encipheronly, \
+ cRLSign, keycertsign, keyagreement, \
+ dataencipherment, keyencipherment, nonrepudiation, \
+ digitalsignature) \
+ (TPMA_X509_KEY_USAGE)( \
+ (decipheronly << 23) + (encipheronly << 24) + \
+ (cRLSign << 25) + (keycertsign << 26) + \
+ (keyagreement << 27) + (dataencipherment << 28) + \
+ (keyencipherment << 29) + (nonrepudiation << 30) + \
+ (digitalsignature << 31))
+#endif // USE_BIT_FIELD_STRUCTURES
+
+#define TYPE_OF_TPMA_ACT UINT32
+#define TPMA_ACT_TO_UINT32(a) (*((UINT32 *)&(a)))
+#define UINT32_TO_TPMA_ACT(a) (*((TPMA_ACT *)&(a)))
+#define TPMA_ACT_TO_BYTE_ARRAY(i, a) \
+ UINT32_TO_BYTE_ARRAY((TPMA_ACT_TO_UINT32(i)), (a))
+#define BYTE_ARRAY_TO_TPMA_ACT(i, a) \
+ { UINT32 x = BYTE_ARRAY_TO_UINT32(a); i = UINT32_TO_TPMA_ACT(x); }
+#if USE_BIT_FIELD_STRUCTURES
+typedef struct TPMA_ACT { // Table 2:40
+ unsigned signaled : 1;
+ unsigned preserveSignaled : 1;
+ unsigned Reserved_bits_at_2 : 30;
+} TPMA_ACT; /* Bits */
+// This is the initializer for a TPMA_ACT structure
+#define TPMA_ACT_INITIALIZER(signaled, preservesignaled, bits_at_2) \
+ {signaled, preservesignaled, bits_at_2}
+#else // USE_BIT_FIELD_STRUCTURES
+// This implements Table 2:40 TPMA_ACT using bit masking
+typedef UINT32 TPMA_ACT;
+#define TYPE_OF_TPMA_ACT UINT32
+#define TPMA_ACT_signaled ((TPMA_ACT)1 << 0)
+#define TPMA_ACT_preserveSignaled ((TPMA_ACT)1 << 1)
+// This is the initializer for a TPMA_ACT bit array.
+#define TPMA_ACT_INITIALIZER(signaled, preservesignaled, bits_at_2) \
+ (TPMA_ACT)( \
+ (signaled << 0) + (preservesignaled << 1))
+#endif // USE_BIT_FIELD_STRUCTURES
+
+/* Table 2:39 - Definition of TPMI_YES_NO Type */
+typedef BYTE TPMI_YES_NO;
+/* Table 2:40 - Definition of TPMI_DH_OBJECT Type */
+typedef TPM_HANDLE TPMI_DH_OBJECT;
+/* Table 2:41 - Definition of TPMI_DH_PARENT Type */
+typedef TPM_HANDLE TPMI_DH_PARENT;
+/* Table 2:42 - Definition of TPMI_DH_PERSISTENT Type */
+typedef TPM_HANDLE TPMI_DH_PERSISTENT;
+/* Table 2:43 - Definition of TPMI_DH_ENTITY Type */
+typedef TPM_HANDLE TPMI_DH_ENTITY;
+/* Table 2:44 - Definition of TPMI_DH_PCR Type */
+typedef TPM_HANDLE TPMI_DH_PCR;
+/* Table 2:45 - Definition of TPMI_SH_AUTH_SESSION Type */
+typedef TPM_HANDLE TPMI_SH_AUTH_SESSION;
+/* Table 2:46 - Definition of TPMI_SH_HMAC Type */
+typedef TPM_HANDLE TPMI_SH_HMAC;
+/* Table 2:47 - Definition of TPMI_SH_POLICY Type */
+typedef TPM_HANDLE TPMI_SH_POLICY;
+/* Table 2:48 - Definition of TPMI_DH_CONTEXT Type */
+typedef TPM_HANDLE TPMI_DH_CONTEXT;
+/* Table 49 - Definition of (TPM_HANDLE) TPMI_DH_SAVED Type */
+typedef TPM_HANDLE TPMI_DH_SAVED;
+/* Table 2:49 - Definition of TPMI_RH_HIERARCHY Type */
+typedef TPM_HANDLE TPMI_RH_HIERARCHY;
+/* Table 2:50 - Definition of TPMI_RH_ENABLES Type */
+typedef TPM_HANDLE TPMI_RH_ENABLES;
+/* Table 2:51 - Definition of TPMI_RH_HIERARCHY_AUTH Type */
+typedef TPM_HANDLE TPMI_RH_HIERARCHY_AUTH;
+/* Table 2:55 - Definition of TPMI_RH_HIERARCHY_POLICY Type */
+typedef TPM_HANDLE TPMI_RH_HIERARCHY_POLICY;
+/* Table 2:52 - Definition of TPMI_RH_PLATFORM Type */
+typedef TPM_HANDLE TPMI_RH_PLATFORM;
+/* Table 2:53 - Definition of TPMI_RH_OWNER Type */
+typedef TPM_HANDLE TPMI_RH_OWNER;
+/* Table 2:54 - Definition of TPMI_RH_ENDORSEMENT Type */
+typedef TPM_HANDLE TPMI_RH_ENDORSEMENT;
+/* Table 2:55 - Definition of TPMI_RH_PROVISION Type */
+typedef TPM_HANDLE TPMI_RH_PROVISION;
+/* Table 2:56 - Definition of TPMI_RH_CLEAR Type */
+typedef TPM_HANDLE TPMI_RH_CLEAR;
+/* Table 2:57 - Definition of TPMI_RH_NV_AUTH Type */
+typedef TPM_HANDLE TPMI_RH_NV_AUTH;
+/* Table 2:58 - Definition of TPMI_RH_LOCKOUT Type */
+typedef TPM_HANDLE TPMI_RH_LOCKOUT;
+/* Table 2:59 - Definition of TPMI_RH_NV_INDEX Type */
+typedef TPM_HANDLE TPMI_RH_NV_INDEX;
+/* Table 2:60 - Definition of TPMI_RH_AC Type */
+typedef TPM_HANDLE TPMI_RH_AC;
+/* Table 2:65 - Definition of TPMI_RH_ACT Type */
+typedef TPM_HANDLE TPMI_RH_ACT;
+/* Table 2:61 - Definition of TPMI_ALG_HASH Type */
+typedef TPM_ALG_ID TPMI_ALG_HASH;
+/* Table 2:62 - Definition of TPMI_ALG_ASYM Type */
+typedef TPM_ALG_ID TPMI_ALG_ASYM;
+/* Table 2:63 - Definition of TPMI_ALG_SYM Type */
+typedef TPM_ALG_ID TPMI_ALG_SYM;
+/* Table 2:64 - Definition of TPMI_ALG_SYM_OBJECT Type */
+typedef TPM_ALG_ID TPMI_ALG_SYM_OBJECT;
+/* Table 2:65 - Definition of TPMI_ALG_SYM_MODE Type */
+typedef TPM_ALG_ID TPMI_ALG_SYM_MODE;
+/* Table 2:66 - Definition of TPMI_ALG_KDF Type */
+typedef TPM_ALG_ID TPMI_ALG_KDF;
+/* Table 2:67 - Definition of TPMI_ALG_SIG_SCHEME Type */
+typedef TPM_ALG_ID TPMI_ALG_SIG_SCHEME;
+/* Table 2:68 - Definition of TPMI_ECC_KEY_EXCHANGE Type */
+typedef TPM_ALG_ID TPMI_ECC_KEY_EXCHANGE;
+/* Table 2:69 - Definition of TPMI_ST_COMMAND_TAG Type */
+typedef TPM_ST TPMI_ST_COMMAND_TAG;
+/* Table 2:70 - Definition of TPMI_ALG_MAC_SCHEME Type */
+typedef TPM_ALG_ID TPMI_ALG_MAC_SCHEME;
+/* le 2:70 - Definition of TPMI_ALG_CIPHER_MODE Type */
+typedef TPM_ALG_ID TPMI_ALG_CIPHER_MODE;
+/* Table 2:70 - Definition of TPMS_EMPTY Structure */
+typedef BYTE TPMS_EMPTY;
+/* Table 2:71 - Definition of TPMS_ALGORITHM_DESCRIPTION Structure */
+typedef struct {
+ TPM_ALG_ID alg;
+ TPMA_ALGORITHM attributes;
+} TPMS_ALGORITHM_DESCRIPTION;
+/* Table 2:71 - Definition of TPMU_HA Union */
+typedef union {
+#if ALG_SHA1
+ BYTE sha1[SHA1_DIGEST_SIZE];
+#endif // ALG_SHA1
+#if ALG_SHA256
+ BYTE sha256[SHA256_DIGEST_SIZE];
+#endif // ALG_SHA256
+#if ALG_SHA384
+ BYTE sha384[SHA384_DIGEST_SIZE];
+#endif // ALG_SHA384
+#if ALG_SHA512
+ BYTE sha512[SHA512_DIGEST_SIZE];
+#endif // ALG_SHA512
+#if ALG_SM3_256
+ BYTE sm3_256[SM3_256_DIGEST_SIZE];
+#endif // ALG_SM3_256
+#if ALG_SHA3_256
+ BYTE sha3_256[SHA3_256_DIGEST_SIZE];
+#endif // ALG_SHA3_256
+#if ALG_SHA3_384
+ BYTE sha3_384[SHA3_384_DIGEST_SIZE];
+#endif // ALG_SHA3_384
+#if ALG_SHA3_512
+ BYTE sha3_512[SHA3_512_DIGEST_SIZE];
+#endif // ALG_SHA3_512
+} TPMU_HA;
+/* Table 2:72 - Definition of TPMT_HA Structure */
+typedef struct {
+ TPMI_ALG_HASH hashAlg;
+ TPMU_HA digest;
+} TPMT_HA;
+/* Table 2:73 - Definition of TPM2B_DIGEST Structure */
+typedef union {
+ struct {
+ UINT16 size;
+ BYTE buffer[sizeof(TPMU_HA)];
+ } t;
+ TPM2B b;
+} TPM2B_DIGEST;
+/* Table 2:74 - Definition of TPM2B_DATA Structure */
+typedef union {
+ struct {
+ UINT16 size;
+ BYTE buffer[sizeof(TPMT_HA)];
+ } t;
+ TPM2B b;
+} TPM2B_DATA;
+/* Table 2:75 - Definition of Types for TPM2B_NONCE */
+typedef TPM2B_DIGEST TPM2B_NONCE;
+/* Table 2:76 - Definition of Types for TPM2B_AUTH */
+typedef TPM2B_DIGEST TPM2B_AUTH;
+/* Table 2:77 - Definition of Types for TPM2B_OPERAND */
+typedef TPM2B_DIGEST TPM2B_OPERAND;
+/* Table 2:78 - Definition of TPM2B_EVENT Structure */
+typedef union {
+ struct {
+ UINT16 size;
+ BYTE buffer[1024];
+ } t;
+ TPM2B b;
+} TPM2B_EVENT;
+/* Table 2:79 - Definition of TPM2B_MAX_BUFFER Structure */
+typedef union {
+ struct {
+ UINT16 size;
+ BYTE buffer[MAX_DIGEST_BUFFER];
+ } t;
+ TPM2B b;
+} TPM2B_MAX_BUFFER;
+/* Table 2:80 - Definition of TPM2B_MAX_NV_BUFFER Structure */
+typedef union {
+ struct {
+ UINT16 size;
+ BYTE buffer[MAX_NV_BUFFER_SIZE];
+ } t;
+ TPM2B b;
+} TPM2B_MAX_NV_BUFFER;
+/* Table 2:82 - Definition of TPM2B_TIMEOUT Structure */
+typedef union {
+ struct {
+ UINT16 size;
+ BYTE buffer[sizeof(UINT64)];
+ } t;
+ TPM2B b;
+} TPM2B_TIMEOUT;
+/* Table 2:82 - Definition of TPM2B_IV Structure */
+typedef union {
+ struct {
+ UINT16 size;
+ BYTE buffer[MAX_SYM_BLOCK_SIZE];
+ } t;
+ TPM2B b;
+} TPM2B_IV;
+/* Table 2:83 - Definition of TPMU_NAME Union */
+typedef union {
+ TPMT_HA digest;
+ TPM_HANDLE handle;
+} TPMU_NAME;
+/* Table 2:84 - Definition of TPM2B_NAME Structure */
+typedef union {
+ struct {
+ UINT16 size;
+ BYTE name[sizeof(TPMU_NAME)];
+ } t;
+ TPM2B b;
+} TPM2B_NAME;
+/* Table 2:85 - Definition of TPMS_PCR_SELECT Structure */
+typedef struct {
+ UINT8 sizeofSelect;
+ BYTE pcrSelect[PCR_SELECT_MAX];
+} TPMS_PCR_SELECT;
+/* Table 2:86 - Definition of TPMS_PCR_SELECTION Structure */
+typedef struct {
+ TPMI_ALG_HASH hash;
+ UINT8 sizeofSelect;
+ BYTE pcrSelect[PCR_SELECT_MAX];
+} TPMS_PCR_SELECTION;
+/* Table 2:89 - Definition of TPMT_TK_CREATION Structure */
+typedef struct {
+ TPM_ST tag;
+ TPMI_RH_HIERARCHY hierarchy;
+ TPM2B_DIGEST digest;
+} TPMT_TK_CREATION;
+/* Table 2:90 - Definition of TPMT_TK_VERIFIED Structure */
+typedef struct {
+ TPM_ST tag;
+ TPMI_RH_HIERARCHY hierarchy;
+ TPM2B_DIGEST digest;
+} TPMT_TK_VERIFIED;
+/* Table 2:91 - Definition of TPMT_TK_AUTH Structure */
+typedef struct {
+ TPM_ST tag;
+ TPMI_RH_HIERARCHY hierarchy;
+ TPM2B_DIGEST digest;
+} TPMT_TK_AUTH;
+/* Table 2:92 - Definition of TPMT_TK_HASHCHECK Structure */
+typedef struct {
+ TPM_ST tag;
+ TPMI_RH_HIERARCHY hierarchy;
+ TPM2B_DIGEST digest;
+} TPMT_TK_HASHCHECK;
+/* Table 2:93 - Definition of TPMS_ALG_PROPERTY Structure */
+typedef struct {
+ TPM_ALG_ID alg;
+ TPMA_ALGORITHM algProperties;
+} TPMS_ALG_PROPERTY;
+/* Table 2:94 - Definition of TPMS_TAGGED_PROPERTY Structure */
+typedef struct {
+ TPM_PT property;
+ UINT32 value;
+} TPMS_TAGGED_PROPERTY;
+/* Table 2:95 - Definition of TPMS_TAGGED_PCR_SELECT Structure */
+typedef struct {
+ TPM_PT_PCR tag;
+ UINT8 sizeofSelect;
+ BYTE pcrSelect[PCR_SELECT_MAX];
+} TPMS_TAGGED_PCR_SELECT;
+/* Table 2:96 - Definition of TPMS_TAGGED_POLICY Structure */
+typedef struct {
+ TPM_HANDLE handle;
+ TPMT_HA policyHash;
+} TPMS_TAGGED_POLICY;
+/* Table 105 - Definition of TPMS_ACT_DATA Structure <OUT> */
+typedef struct {
+ TPM_HANDLE handle;
+ UINT32 timeout;
+ TPMA_ACT attributes;
+} TPMS_ACT_DATA;
+/* Table 2:97 - Definition of TPML_CC Structure */
+typedef struct {
+ UINT32 count;
+ TPM_CC commandCodes[MAX_CAP_CC];
+} TPML_CC;
+/* Table 2:98 - Definition of TPML_CCA Structure */
+typedef struct {
+ UINT32 count;
+ TPMA_CC commandAttributes[MAX_CAP_CC];
+} TPML_CCA;
+/* Table 2:99 - Definition of TPML_ALG Structure */
+typedef struct {
+ UINT32 count;
+ TPM_ALG_ID algorithms[MAX_ALG_LIST_SIZE];
+} TPML_ALG;
+/* Table 2:100 - Definition of TPML_HANDLE Structure */
+typedef struct {
+ UINT32 count;
+ TPM_HANDLE handle[MAX_CAP_HANDLES];
+} TPML_HANDLE;
+/* Table 2:101 - Definition of TPML_DIGEST Structure */
+typedef struct {
+ UINT32 count;
+ TPM2B_DIGEST digests[8];
+} TPML_DIGEST;
+/* Table 2:102 - Definition of TPML_DIGEST_VALUES Structure */
+typedef struct {
+ UINT32 count;
+ TPMT_HA digests[HASH_COUNT];
+} TPML_DIGEST_VALUES;
+/* Table 2:104 - Definition of TPML_PCR_SELECTION Structure */
+typedef struct {
+ UINT32 count;
+ TPMS_PCR_SELECTION pcrSelections[HASH_COUNT];
+} TPML_PCR_SELECTION;
+/* Table 2:105 - Definition of TPML_ALG_PROPERTY Structure */
+typedef struct {
+ UINT32 count;
+ TPMS_ALG_PROPERTY algProperties[MAX_CAP_ALGS];
+} TPML_ALG_PROPERTY;
+/* Table 2:106 - Definition of TPML_TAGGED_TPM_PROPERTY Structure */
+typedef struct {
+ UINT32 count;
+ TPMS_TAGGED_PROPERTY tpmProperty[MAX_TPM_PROPERTIES];
+} TPML_TAGGED_TPM_PROPERTY;
+/* Table 2:107 - Definition of TPML_TAGGED_PCR_PROPERTY Structure */
+typedef struct {
+ UINT32 count;
+ TPMS_TAGGED_PCR_SELECT pcrProperty[MAX_PCR_PROPERTIES];
+} TPML_TAGGED_PCR_PROPERTY;
+/* Table 2:108 - Definition of TPML_ECC_CURVE Structure */
+typedef struct {
+ UINT32 count;
+ TPM_ECC_CURVE eccCurves[MAX_ECC_CURVES];
+} TPML_ECC_CURVE;
+/* Table 2:109 - Definition of TPML_TAGGED_POLICY Structure */
+typedef struct {
+ UINT32 count;
+ TPMS_TAGGED_POLICY policies[MAX_TAGGED_POLICIES];
+} TPML_TAGGED_POLICY;
+/* Table 2:118 - Definition of TPML_ACT_DATA Structure <OUT> */
+typedef struct {
+ UINT32 count;
+ TPMS_ACT_DATA actData[MAX_ACT_DATA];
+} TPML_ACT_DATA;
+/* Table 2:110 - Definition of TPMU_CAPABILITIES Union */
+typedef union {
+ TPML_ALG_PROPERTY algorithms;
+ TPML_HANDLE handles;
+ TPML_CCA command;
+ TPML_CC ppCommands;
+ TPML_CC auditCommands;
+ TPML_PCR_SELECTION assignedPCR;
+ TPML_TAGGED_TPM_PROPERTY tpmProperties;
+ TPML_TAGGED_PCR_PROPERTY pcrProperties;
+#if ALG_ECC
+ TPML_ECC_CURVE eccCurves;
+#endif // ALG_ECC
+ TPML_TAGGED_POLICY authPolicies;
+ TPML_ACT_DATA actData;
+} TPMU_CAPABILITIES;
+/* Table 2:111 - Definition of TPMS_CAPABILITY_DATA Structure */
+typedef struct {
+ TPM_CAP capability;
+ TPMU_CAPABILITIES data;
+} TPMS_CAPABILITY_DATA;
+/* Table 2:112 - Definition of TPMS_CLOCK_INFO Structure */
+typedef struct {
+ UINT64 clock;
+ UINT32 resetCount;
+ UINT32 restartCount;
+ TPMI_YES_NO safe;
+} TPMS_CLOCK_INFO;
+/* Table 2:113 - Definition of TPMS_TIME_INFO Structure */
+typedef struct {
+ UINT64 time;
+ TPMS_CLOCK_INFO clockInfo;
+} TPMS_TIME_INFO;
+/* Table 2:114 - Definition of TPMS_TIME_ATTEST_INFO Structure */
+typedef struct {
+ TPMS_TIME_INFO time;
+ UINT64 firmwareVersion;
+} TPMS_TIME_ATTEST_INFO;
+/* Table 2:115 - Definition of TPMS_CERTIFY_INFO Structure */
+typedef struct {
+ TPM2B_NAME name;
+ TPM2B_NAME qualifiedName;
+} TPMS_CERTIFY_INFO;
+/* Table 2:116 - Definition of TPMS_QUOTE_INFO Structure */
+typedef struct {
+ TPML_PCR_SELECTION pcrSelect;
+ TPM2B_DIGEST pcrDigest;
+} TPMS_QUOTE_INFO;
+/* Table 2:117 - Definition of TPMS_COMMAND_AUDIT_INFO Structure */
+typedef struct {
+ UINT64 auditCounter;
+ TPM_ALG_ID digestAlg;
+ TPM2B_DIGEST auditDigest;
+ TPM2B_DIGEST commandDigest;
+} TPMS_COMMAND_AUDIT_INFO;
+/* Table 2:118 - Definition of TPMS_SESSION_AUDIT_INFO Structure */
+typedef struct {
+ TPMI_YES_NO exclusiveSession;
+ TPM2B_DIGEST sessionDigest;
+} TPMS_SESSION_AUDIT_INFO;
+/* Table 2:119 - Definition of TPMS_CREATION_INFO Structure */
+typedef struct {
+ TPM2B_NAME objectName;
+ TPM2B_DIGEST creationHash;
+} TPMS_CREATION_INFO;
+/* Table 2:120 - Definition of TPMS_NV_CERTIFY_INFO Structure */
+typedef struct {
+ TPM2B_NAME indexName;
+ UINT16 offset;
+ TPM2B_MAX_NV_BUFFER nvContents;
+} TPMS_NV_CERTIFY_INFO;
+/* Table 125 - Definition of TPMS_NV_DIGEST_CERTIFY_INFO Structure <OUT> */
+typedef struct {
+ TPM2B_NAME indexName;
+ TPM2B_DIGEST nvDigest;
+} TPMS_NV_DIGEST_CERTIFY_INFO;
+/* Table 2:121 - Definition of TPMI_ST_ATTEST Type */
+typedef TPM_ST TPMI_ST_ATTEST;
+/* Table 2:122 - Definition of TPMU_ATTEST Union */
+typedef union {
+ TPMS_CERTIFY_INFO certify;
+ TPMS_CREATION_INFO creation;
+ TPMS_QUOTE_INFO quote;
+ TPMS_COMMAND_AUDIT_INFO commandAudit;
+ TPMS_SESSION_AUDIT_INFO sessionAudit;
+ TPMS_TIME_ATTEST_INFO time;
+ TPMS_NV_CERTIFY_INFO nv;
+ TPMS_NV_DIGEST_CERTIFY_INFO nvDigest;
+} TPMU_ATTEST;
+/* Table 2:123 - Definition of TPMS_ATTEST Structure */
+typedef struct {
+ TPM_CONSTANTS32 magic;
+ TPMI_ST_ATTEST type;
+ TPM2B_NAME qualifiedSigner;
+ TPM2B_DATA extraData;
+ TPMS_CLOCK_INFO clockInfo;
+ UINT64 firmwareVersion;
+ TPMU_ATTEST attested;
+} TPMS_ATTEST;
+/* Table 2:124 - Definition of TPM2B_ATTEST Structure */
+typedef union {
+ struct {
+ UINT16 size;
+ BYTE attestationData[sizeof(TPMS_ATTEST)];
+ } t;
+ TPM2B b;
+} TPM2B_ATTEST;
+/* Table 2:125 - Definition of TPMS_AUTH_COMMAND Structure */
+typedef struct {
+ TPMI_SH_AUTH_SESSION sessionHandle;
+ TPM2B_NONCE nonce;
+ TPMA_SESSION sessionAttributes;
+ TPM2B_AUTH hmac;
+} TPMS_AUTH_COMMAND;
+/* Table 2:126 - Definition of TPMS_AUTH_RESPONSE Structure */
+typedef struct {
+ TPM2B_NONCE nonce;
+ TPMA_SESSION sessionAttributes;
+ TPM2B_AUTH hmac;
+} TPMS_AUTH_RESPONSE;
+/* Table 2:127 - Definition of TPMI_TDES_KEY_BITS Type */
+typedef TPM_KEY_BITS TPMI_TDES_KEY_BITS;
+/* Table 2:127 - Definition of TPMI_AES_KEY_BITS Type */
+typedef TPM_KEY_BITS TPMI_AES_KEY_BITS;
+/* Table 2:127 - Definition of TPMI_SM4_KEY_BITS Type */
+typedef TPM_KEY_BITS TPMI_SM4_KEY_BITS;
+/* Table 2:127 - Definition of TPMI_CAMELLIA_KEY_BITS Type */
+typedef TPM_KEY_BITS TPMI_CAMELLIA_KEY_BITS;
+/* Table 2:128 - Definition of TPMU_SYM_KEY_BITS Union */
+typedef union {
+#if ALG_TDES
+ TPMI_TDES_KEY_BITS tdes;
+#endif // ALG_TDES
+#if ALG_AES
+ TPMI_AES_KEY_BITS aes;
+#endif // ALG_AES
+#if ALG_SM4
+ TPMI_SM4_KEY_BITS sm4;
+#endif // ALG_SM4
+#if ALG_CAMELLIA
+ TPMI_CAMELLIA_KEY_BITS camellia;
+#endif // ALG_CAMELLIA
+ TPM_KEY_BITS sym;
+#if ALG_XOR
+ TPMI_ALG_HASH xorr;
+#endif // ALG_XOR
+} TPMU_SYM_KEY_BITS;
+/* Table 2:129 - Definition of TPMU_SYM_MODE Union */
+typedef union {
+#if ALG_TDES
+ TPMI_ALG_SYM_MODE tdes;
+#endif // ALG_TDES
+#if ALG_AES
+ TPMI_ALG_SYM_MODE aes;
+#endif // ALG_AES
+#if ALG_SM4
+ TPMI_ALG_SYM_MODE sm4;
+#endif // ALG_SM4
+#if ALG_CAMELLIA
+ TPMI_ALG_SYM_MODE camellia;
+#endif // ALG_CAMELLIA
+ TPMI_ALG_SYM_MODE sym;
+} TPMU_SYM_MODE;
+/* Table 2:131 - Definition of TPMT_SYM_DEF Structure */
+typedef struct {
+ TPMI_ALG_SYM algorithm;
+ TPMU_SYM_KEY_BITS keyBits;
+ TPMU_SYM_MODE mode;
+} TPMT_SYM_DEF;
+/* Table 2:132 - Definition of TPMT_SYM_DEF_OBJECT Structure */
+typedef struct {
+ TPMI_ALG_SYM_OBJECT algorithm;
+ TPMU_SYM_KEY_BITS keyBits;
+ TPMU_SYM_MODE mode;
+} TPMT_SYM_DEF_OBJECT;
+/* Table 2:133 - Definition of TPM2B_SYM_KEY Structure */
+typedef union {
+ struct {
+ UINT16 size;
+ BYTE buffer[MAX_SYM_KEY_BYTES];
+ } t;
+ TPM2B b;
+} TPM2B_SYM_KEY;
+/* Table 2:134 - Definition of TPMS_SYMCIPHER_PARMS Structure */
+typedef struct {
+ TPMT_SYM_DEF_OBJECT sym;
+} TPMS_SYMCIPHER_PARMS;
+/* Table 2:135 - Definition of TPM2B_LABEL Structure */
+typedef union {
+ struct {
+ UINT16 size;
+ BYTE buffer[LABEL_MAX_BUFFER];
+ } t;
+ TPM2B b;
+} TPM2B_LABEL;
+/* Table 2:136 - Definition of TPMS_DERIVE Structure */
+typedef struct {
+ TPM2B_LABEL label;
+ TPM2B_LABEL context;
+} TPMS_DERIVE;
+/* Table 2:137 - Definition of TPM2B_DERIVE Structure */
+typedef union {
+ struct {
+ UINT16 size;
+ BYTE buffer[sizeof(TPMS_DERIVE)];
+ } t;
+ TPM2B b;
+} TPM2B_DERIVE;
+/* Table 2:138 - Definition of TPMU_SENSITIVE_CREATE Union */
+typedef union {
+ BYTE create[MAX_SYM_DATA];
+ TPMS_DERIVE derive;
+} TPMU_SENSITIVE_CREATE;
+/* Table 2:139 - Definition of TPM2B_SENSITIVE_DATA Structure */
+typedef union {
+ struct {
+ UINT16 size;
+ BYTE buffer[sizeof(TPMU_SENSITIVE_CREATE)];
+ } t;
+ TPM2B b;
+} TPM2B_SENSITIVE_DATA;
+/* Table 2:140 - Definition of TPMS_SENSITIVE_CREATE Structure */
+typedef struct {
+ TPM2B_AUTH userAuth;
+ TPM2B_SENSITIVE_DATA data;
+} TPMS_SENSITIVE_CREATE;
+/* Table 2:141 - Definition of TPM2B_SENSITIVE_CREATE Structure */
+typedef struct {
+ UINT16 size;
+ TPMS_SENSITIVE_CREATE sensitive;
+} TPM2B_SENSITIVE_CREATE;
+/* Table 2:142 - Definition of TPMS_SCHEME_HASH Structure */
+typedef struct {
+ TPMI_ALG_HASH hashAlg;
+} TPMS_SCHEME_HASH;
+/* Table 2:143 - Definition of TPMS_SCHEME_ECDAA Structure */
+typedef struct {
+ TPMI_ALG_HASH hashAlg;
+ UINT16 count;
+} TPMS_SCHEME_ECDAA;
+/* Table 2:144 - Definition of TPMI_ALG_KEYEDHASH_SCHEME Type */
+typedef TPM_ALG_ID TPMI_ALG_KEYEDHASH_SCHEME;
+/* Table 2:145 - Definition of Types for HMAC_SIG_SCHEME */
+typedef TPMS_SCHEME_HASH TPMS_SCHEME_HMAC;
+/* Table 2:146 - Definition of TPMS_SCHEME_XOR Structure */
+typedef struct {
+ TPMI_ALG_HASH hashAlg;
+ TPMI_ALG_KDF kdf;
+} TPMS_SCHEME_XOR;
+/* Table 2:147 - Definition of TPMU_SCHEME_KEYEDHASH Union */
+typedef union {
+#if ALG_HMAC
+ TPMS_SCHEME_HMAC hmac;
+#endif // ALG_HMAC
+#if ALG_XOR
+ TPMS_SCHEME_XOR xorr;
+#endif // ALG_XOR
+} TPMU_SCHEME_KEYEDHASH;
+/* Table 2:148 - Definition of TPMT_KEYEDHASH_SCHEME Structure */
+typedef struct {
+ TPMI_ALG_KEYEDHASH_SCHEME scheme;
+ TPMU_SCHEME_KEYEDHASH details;
+} TPMT_KEYEDHASH_SCHEME;
+/* Table 2:149 - Definition of Types for RSA Signature Schemes */
+typedef TPMS_SCHEME_HASH TPMS_SIG_SCHEME_RSASSA;
+typedef TPMS_SCHEME_HASH TPMS_SIG_SCHEME_RSAPSS;
+/* Table 2:150 - Definition of Types for ECC Signature Schemes */
+typedef TPMS_SCHEME_HASH TPMS_SIG_SCHEME_ECDSA;
+typedef TPMS_SCHEME_HASH TPMS_SIG_SCHEME_SM2;
+typedef TPMS_SCHEME_HASH TPMS_SIG_SCHEME_ECSCHNORR;
+typedef TPMS_SCHEME_ECDAA TPMS_SIG_SCHEME_ECDAA;
+/* Table 2:151 - Definition of TPMU_SIG_SCHEME Union */
+typedef union {
+#if ALG_ECC
+ TPMS_SIG_SCHEME_ECDAA ecdaa;
+#endif // ALG_ECC
+#if ALG_RSASSA
+ TPMS_SIG_SCHEME_RSASSA rsassa;
+#endif // ALG_RSASSA
+#if ALG_RSAPSS
+ TPMS_SIG_SCHEME_RSAPSS rsapss;
+#endif // ALG_RSAPSS
+#if ALG_ECDSA
+ TPMS_SIG_SCHEME_ECDSA ecdsa;
+#endif // ALG_ECDSA
+#if ALG_SM2
+ TPMS_SIG_SCHEME_SM2 sm2;
+#endif // ALG_SM2
+#if ALG_ECSCHNORR
+ TPMS_SIG_SCHEME_ECSCHNORR ecschnorr;
+#endif // ALG_ECSCHNORR
+#if ALG_HMAC
+ TPMS_SCHEME_HMAC hmac;
+#endif // ALG_HMAC
+ TPMS_SCHEME_HASH any;
+} TPMU_SIG_SCHEME;
+/* Table 2:152 - Definition of TPMT_SIG_SCHEME Structure */
+typedef struct {
+ TPMI_ALG_SIG_SCHEME scheme;
+ TPMU_SIG_SCHEME details;
+} TPMT_SIG_SCHEME;
+/* Table 2:153 - Definition of Types for Encryption Schemes */
+typedef TPMS_SCHEME_HASH TPMS_ENC_SCHEME_OAEP;
+typedef TPMS_EMPTY TPMS_ENC_SCHEME_RSAES;
+/* Table 2:154 - Definition of Types for ECC Key Exchange */
+typedef TPMS_SCHEME_HASH TPMS_KEY_SCHEME_ECDH;
+typedef TPMS_SCHEME_HASH TPMS_KEY_SCHEME_ECMQV;
+/* Table 2:155 - Definition of Types for KDF Schemes */
+typedef TPMS_SCHEME_HASH TPMS_KDF_SCHEME_MGF1;
+typedef TPMS_SCHEME_HASH TPMS_KDF_SCHEME_KDF1_SP800_56A;
+typedef TPMS_SCHEME_HASH TPMS_KDF_SCHEME_KDF2;
+typedef TPMS_SCHEME_HASH TPMS_KDF_SCHEME_KDF1_SP800_108;
+/* Table 2:156 - Definition of TPMU_KDF_SCHEME Union */
+typedef union {
+#if ALG_MGF1
+ TPMS_KDF_SCHEME_MGF1 mgf1;
+#endif // ALG_MGF1
+#if ALG_KDF1_SP800_56A
+ TPMS_KDF_SCHEME_KDF1_SP800_56A kdf1_sp800_56a;
+#endif // ALG_KDF1_SP800_56A
+#if ALG_KDF2
+ TPMS_KDF_SCHEME_KDF2 kdf2;
+#endif // ALG_KDF2
+#if ALG_KDF1_SP800_108
+ TPMS_KDF_SCHEME_KDF1_SP800_108 kdf1_sp800_108;
+#endif // ALG_KDF1_SP800_108
+ TPMS_SCHEME_HASH anyKdf;
+} TPMU_KDF_SCHEME;
+/* Table 2:157 - Definition of TPMT_KDF_SCHEME Structure */
+typedef struct {
+ TPMI_ALG_KDF scheme;
+ TPMU_KDF_SCHEME details;
+} TPMT_KDF_SCHEME;
+/* Table 2:158 - Definition of TPMI_ALG_ASYM_SCHEME Type */
+typedef TPM_ALG_ID TPMI_ALG_ASYM_SCHEME;
+/* Table 2:159 - Definition of TPMU_ASYM_SCHEME Union */
+typedef union {
+#if ALG_ECDH
+ TPMS_KEY_SCHEME_ECDH ecdh;
+#endif // ALG_ECDH
+#if ALG_ECMQV
+ TPMS_KEY_SCHEME_ECMQV ecmqv;
+#endif // ALG_ECMQV
+#if ALG_ECC
+ TPMS_SIG_SCHEME_ECDAA ecdaa;
+#endif // ALG_ECC
+#if ALG_RSASSA
+ TPMS_SIG_SCHEME_RSASSA rsassa;
+#endif // ALG_RSASSA
+#if ALG_RSAPSS
+ TPMS_SIG_SCHEME_RSAPSS rsapss;
+#endif // ALG_RSAPSS
+#if ALG_ECDSA
+ TPMS_SIG_SCHEME_ECDSA ecdsa;
+#endif // ALG_ECDSA
+#if ALG_SM2
+ TPMS_SIG_SCHEME_SM2 sm2;
+#endif // ALG_SM2
+#if ALG_ECSCHNORR
+ TPMS_SIG_SCHEME_ECSCHNORR ecschnorr;
+#endif // ALG_ECSCHNORR
+#if ALG_RSAES
+ TPMS_ENC_SCHEME_RSAES rsaes;
+#endif // ALG_RSAES
+#if ALG_OAEP
+ TPMS_ENC_SCHEME_OAEP oaep;
+#endif // ALG_OAEP
+ TPMS_SCHEME_HASH anySig;
+} TPMU_ASYM_SCHEME;
+/* Table 2:160 - Definition of TPMT_ASYM_SCHEME Structure */
+typedef struct {
+ TPMI_ALG_ASYM_SCHEME scheme;
+ TPMU_ASYM_SCHEME details;
+} TPMT_ASYM_SCHEME;
+/* Table 2:161 - Definition of TPMI_ALG_RSA_SCHEME Type */
+typedef TPM_ALG_ID TPMI_ALG_RSA_SCHEME;
+/* Table 2:162 - Definition of TPMT_RSA_SCHEME Structure */
+typedef struct {
+ TPMI_ALG_RSA_SCHEME scheme;
+ TPMU_ASYM_SCHEME details;
+} TPMT_RSA_SCHEME;
+/* Table 2:163 - Definition of TPMI_ALG_RSA_DECRYPT Type */
+typedef TPM_ALG_ID TPMI_ALG_RSA_DECRYPT;
+/* Table 2:164 - Definition of TPMT_RSA_DECRYPT Structure */
+typedef struct {
+ TPMI_ALG_RSA_DECRYPT scheme;
+ TPMU_ASYM_SCHEME details;
+} TPMT_RSA_DECRYPT;
+/* Table 2:165 - Definition of TPM2B_PUBLIC_KEY_RSA Structure */
+typedef union {
+ struct {
+ UINT16 size;
+ BYTE buffer[MAX_RSA_KEY_BYTES];
+ } t;
+ TPM2B b;
+} TPM2B_PUBLIC_KEY_RSA;
+/* Table 2:166 - Definition of TPMI_RSA_KEY_BITS Type */
+typedef TPM_KEY_BITS TPMI_RSA_KEY_BITS;
+/* Table 2:167 - Definition of TPM2B_PRIVATE_KEY_RSA Structure */
+typedef union {
+ struct {
+ UINT16 size;
+ BYTE buffer[RSA_PRIVATE_SIZE];
+ } t;
+ TPM2B b;
+} TPM2B_PRIVATE_KEY_RSA;
+/* Table 2:168 - Definition of TPM2B_ECC_PARAMETER Structure */
+typedef union {
+ struct {
+ UINT16 size;
+ BYTE buffer[MAX_ECC_KEY_BYTES];
+ } t;
+ TPM2B b;
+} TPM2B_ECC_PARAMETER;
+/* Table 2:169 - Definition of TPMS_ECC_POINT Structure */
+typedef struct {
+ TPM2B_ECC_PARAMETER x;
+ TPM2B_ECC_PARAMETER y;
+} TPMS_ECC_POINT;
+/* Table 2:170 - Definition of TPM2B_ECC_POINT Structure */
+typedef struct {
+ UINT16 size;
+ TPMS_ECC_POINT point;
+} TPM2B_ECC_POINT;
+/* Table 2:171 - Definition of TPMI_ALG_ECC_SCHEME Type */
+typedef TPM_ALG_ID TPMI_ALG_ECC_SCHEME;
+/* Table 2:172 - Definition of TPMI_ECC_CURVE Type */
+typedef TPM_ECC_CURVE TPMI_ECC_CURVE;
+/* Table 2:173 - Definition of TPMT_ECC_SCHEME Structure */
+typedef struct {
+ TPMI_ALG_ECC_SCHEME scheme;
+ TPMU_ASYM_SCHEME details;
+} TPMT_ECC_SCHEME;
+/* Table 2:174 - Definition of TPMS_ALGORITHM_DETAIL_ECC Structure */
+typedef struct {
+ TPM_ECC_CURVE curveID;
+ UINT16 keySize;
+ TPMT_KDF_SCHEME kdf;
+ TPMT_ECC_SCHEME sign;
+ TPM2B_ECC_PARAMETER p;
+ TPM2B_ECC_PARAMETER a;
+ TPM2B_ECC_PARAMETER b;
+ TPM2B_ECC_PARAMETER gX;
+ TPM2B_ECC_PARAMETER gY;
+ TPM2B_ECC_PARAMETER n;
+ TPM2B_ECC_PARAMETER h;
+} TPMS_ALGORITHM_DETAIL_ECC;
+/* Table 2:175 - Definition of TPMS_SIGNATURE_RSA Structure */
+typedef struct {
+ TPMI_ALG_HASH hash;
+ TPM2B_PUBLIC_KEY_RSA sig;
+} TPMS_SIGNATURE_RSA;
+/* Table 2:176 - Definition of Types for Signature */
+typedef TPMS_SIGNATURE_RSA TPMS_SIGNATURE_RSASSA;
+typedef TPMS_SIGNATURE_RSA TPMS_SIGNATURE_RSAPSS;
+/* Table 2:177 - Definition of TPMS_SIGNATURE_ECC Structure */
+typedef struct {
+ TPMI_ALG_HASH hash;
+ TPM2B_ECC_PARAMETER signatureR;
+ TPM2B_ECC_PARAMETER signatureS;
+} TPMS_SIGNATURE_ECC;
+/* Table 2:178 - Definition of Types for TPMS_SIGNATURE_ECC */
+typedef TPMS_SIGNATURE_ECC TPMS_SIGNATURE_ECDAA;
+typedef TPMS_SIGNATURE_ECC TPMS_SIGNATURE_ECDSA;
+typedef TPMS_SIGNATURE_ECC TPMS_SIGNATURE_SM2;
+typedef TPMS_SIGNATURE_ECC TPMS_SIGNATURE_ECSCHNORR;
+/* Table 2:179 - Definition of TPMU_SIGNATURE Union */
+typedef union {
+#if ALG_ECC
+ TPMS_SIGNATURE_ECDAA ecdaa;
+#endif // ALG_ECC
+#if ALG_RSA
+ TPMS_SIGNATURE_RSASSA rsassa;
+#endif // ALG_RSA
+#if ALG_RSA
+ TPMS_SIGNATURE_RSAPSS rsapss;
+#endif // ALG_RSA
+#if ALG_ECC
+ TPMS_SIGNATURE_ECDSA ecdsa;
+#endif // ALG_ECC
+#if ALG_ECC
+ TPMS_SIGNATURE_SM2 sm2;
+#endif // ALG_ECC
+#if ALG_ECC
+ TPMS_SIGNATURE_ECSCHNORR ecschnorr;
+#endif // ALG_ECC
+#if ALG_HMAC
+ TPMT_HA hmac;
+#endif // ALG_HMAC
+ TPMS_SCHEME_HASH any;
+} TPMU_SIGNATURE;
+/* Table 2:180 - Definition of TPMT_SIGNATURE Structure */
+typedef struct {
+ TPMI_ALG_SIG_SCHEME sigAlg;
+ TPMU_SIGNATURE signature;
+} TPMT_SIGNATURE;
+/* Table 2:181 - Definition of TPMU_ENCRYPTED_SECRET Union */
+typedef union {
+#if ALG_ECC
+ BYTE ecc[sizeof(TPMS_ECC_POINT)];
+#endif // ALG_ECC
+#if ALG_RSA
+ BYTE rsa[MAX_RSA_KEY_BYTES];
+#endif // ALG_RSA
+#if ALG_SYMCIPHER
+ BYTE symmetric[sizeof(TPM2B_DIGEST)];
+#endif // ALG_SYMCIPHER
+#if ALG_KEYEDHASH
+ BYTE keyedHash[sizeof(TPM2B_DIGEST)];
+#endif // ALG_KEYEDHASH
+} TPMU_ENCRYPTED_SECRET;
+/* Table 2:182 - Definition of TPM2B_ENCRYPTED_SECRET Structure */
+typedef union {
+ struct {
+ UINT16 size;
+ BYTE secret[sizeof(TPMU_ENCRYPTED_SECRET)];
+ } t;
+ TPM2B b;
+} TPM2B_ENCRYPTED_SECRET;
+/* Table 2:183 - Definition of TPMI_ALG_PUBLIC Type */
+typedef TPM_ALG_ID TPMI_ALG_PUBLIC;
+/* Table 2:184 - Definition of TPMU_PUBLIC_ID Union */
+typedef union {
+#if ALG_KEYEDHASH
+ TPM2B_DIGEST keyedHash;
+#endif // ALG_KEYEDHASH
+#if ALG_SYMCIPHER
+ TPM2B_DIGEST sym;
+#endif // ALG_SYMCIPHER
+#if ALG_RSA
+ TPM2B_PUBLIC_KEY_RSA rsa;
+#endif // ALG_RSA
+#if ALG_ECC
+ TPMS_ECC_POINT ecc;
+#endif // ALG_ECC
+ TPMS_DERIVE derive;
+} TPMU_PUBLIC_ID;
+/* Table 2:185 - Definition of TPMS_KEYEDHASH_PARMS Structure */
+typedef struct {
+ TPMT_KEYEDHASH_SCHEME scheme;
+} TPMS_KEYEDHASH_PARMS;
+/* Table 2:186 - Definition of TPMS_ASYM_PARMS Structure */
+typedef struct {
+ TPMT_SYM_DEF_OBJECT symmetric;
+ TPMT_ASYM_SCHEME scheme;
+} TPMS_ASYM_PARMS;
+/* Table 2:187 - Definition of TPMS_RSA_PARMS Structure */
+typedef struct {
+ TPMT_SYM_DEF_OBJECT symmetric;
+ TPMT_RSA_SCHEME scheme;
+ TPMI_RSA_KEY_BITS keyBits;
+ UINT32 exponent;
+} TPMS_RSA_PARMS;
+/* Table 2:188 - Definition of TPMS_ECC_PARMS Structure */
+typedef struct {
+ TPMT_SYM_DEF_OBJECT symmetric;
+ TPMT_ECC_SCHEME scheme;
+ TPMI_ECC_CURVE curveID;
+ TPMT_KDF_SCHEME kdf;
+} TPMS_ECC_PARMS;
+/* Table 2:189 - Definition of TPMU_PUBLIC_PARMS Union */
+typedef union {
+#if ALG_KEYEDHASH
+ TPMS_KEYEDHASH_PARMS keyedHashDetail;
+#endif // ALG_KEYEDHASH
+#if ALG_SYMCIPHER
+ TPMS_SYMCIPHER_PARMS symDetail;
+#endif // ALG_SYMCIPHER
+#if ALG_RSA
+ TPMS_RSA_PARMS rsaDetail;
+#endif // ALG_RSA
+#if ALG_ECC
+ TPMS_ECC_PARMS eccDetail;
+#endif // ALG_ECC
+ TPMS_ASYM_PARMS asymDetail;
+} TPMU_PUBLIC_PARMS;
+/* Table 2:190 - Definition of TPMT_PUBLIC_PARMS Structure */
+typedef struct {
+ TPMI_ALG_PUBLIC type;
+ TPMU_PUBLIC_PARMS parameters;
+} TPMT_PUBLIC_PARMS;
+/* Table 2:191 - Definition of TPMT_PUBLIC Structure */
+typedef struct {
+ TPMI_ALG_PUBLIC type;
+ TPMI_ALG_HASH nameAlg;
+ TPMA_OBJECT objectAttributes;
+ TPM2B_DIGEST authPolicy;
+ TPMU_PUBLIC_PARMS parameters;
+ TPMU_PUBLIC_ID unique;
+} TPMT_PUBLIC;
+/* Table 2:192 - Definition of TPM2B_PUBLIC Structure */
+typedef struct {
+ UINT16 size;
+ TPMT_PUBLIC publicArea;
+} TPM2B_PUBLIC;
+/* Table 2:193 - Definition of TPM2B_TEMPLATE Structure */
+typedef union {
+ struct {
+ UINT16 size;
+ BYTE buffer[sizeof(TPMT_PUBLIC)];
+ } t;
+ TPM2B b;
+} TPM2B_TEMPLATE;
+/* Table 2:194 - Definition of TPM2B_PRIVATE_VENDOR_SPECIFIC Structure */
+typedef union {
+ struct {
+ UINT16 size;
+ BYTE buffer[PRIVATE_VENDOR_SPECIFIC_BYTES];
+ } t;
+ TPM2B b;
+} TPM2B_PRIVATE_VENDOR_SPECIFIC;
+/* Table 2:195 - Definition of TPMU_SENSITIVE_COMPOSITE Union */
+typedef union {
+#if ALG_RSA
+ TPM2B_PRIVATE_KEY_RSA rsa;
+#endif // ALG_RSA
+#if ALG_ECC
+ TPM2B_ECC_PARAMETER ecc;
+#endif // ALG_ECC
+#if ALG_KEYEDHASH
+ TPM2B_SENSITIVE_DATA bits;
+#endif // ALG_KEYEDHASH
+#if ALG_SYMCIPHER
+ TPM2B_SYM_KEY sym;
+#endif // ALG_SYMCIPHER
+ TPM2B_PRIVATE_VENDOR_SPECIFIC any;
+} TPMU_SENSITIVE_COMPOSITE;
+/* Table 2:196 - Definition of TPMT_SENSITIVE Structure */
+typedef struct {
+ TPMI_ALG_PUBLIC sensitiveType;
+ TPM2B_AUTH authValue;
+ TPM2B_DIGEST seedValue;
+ TPMU_SENSITIVE_COMPOSITE sensitive;
+} TPMT_SENSITIVE;
+/* Table 2:197 - Definition of TPM2B_SENSITIVE Structure */
+typedef struct {
+ UINT16 size;
+ TPMT_SENSITIVE sensitiveArea;
+} TPM2B_SENSITIVE;
+/* Table 2:198 - Definition of _PRIVATE Structure */
+typedef struct {
+ TPM2B_DIGEST integrityOuter;
+ TPM2B_DIGEST integrityInner;
+ TPM2B_SENSITIVE sensitive;
+} _PRIVATE;
+/* Table 2:199 - Definition of TPM2B_PRIVATE Structure */
+typedef union {
+ struct {
+ UINT16 size;
+ BYTE buffer[sizeof(_PRIVATE)];
+ } t;
+ TPM2B b;
+} TPM2B_PRIVATE;
+/* Table 2:203 - Definition of TPMS_ID_OBJECT Structure */
+typedef struct {
+ TPM2B_DIGEST integrityHMAC;
+ TPM2B_DIGEST encIdentity;
+} TPMS_ID_OBJECT;
+/* Table 204 - Definition of TPM2B_ID_OBJECT Structure <IN/OUT> */
+typedef union {
+ struct {
+ UINT16 size;
+ BYTE credential[sizeof(TPMS_ID_OBJECT)];
+ } t;
+ TPM2B b;
+} TPM2B_ID_OBJECT;
+
+#define TYPE_OF_TPM_NV_INDEX UINT32
+#define TPM_NV_INDEX_TO_UINT32(a) (*((UINT32 *)&(a)))
+#define UINT32_TO_TPM_NV_INDEX(a) (*((TPM_NV_INDEX *)&(a)))
+#define TPM_NV_INDEX_TO_BYTE_ARRAY(i, a) \
+ UINT32_TO_BYTE_ARRAY((TPM_NV_INDEX_TO_UINT32(i)), (a))
+#define BYTE_ARRAY_TO_TPM_NV_INDEX(i, a) \
+ { UINT32 x = BYTE_ARRAY_TO_UINT32(a); i = UINT32_TO_TPM_NV_INDEX(x); }
+#if USE_BIT_FIELD_STRUCTURES
+typedef struct TPM_NV_INDEX { // Table 2:205
+ unsigned index : 24;
+ unsigned RH_NV : 8;
+} TPM_NV_INDEX;
+// This is the initializer for a TPM_NV_INDEX structure
+#define TPM_NV_INDEX_INITIALIZER(index, rh_nv) {index, rh_nv}
+#else // USE_BIT_FIELD_STRUCTURES
+// This implements Table 2:205 TPM_NV_INDEX using bit masking
+typedef UINT32 TPM_NV_INDEX;
+#define TPM_NV_INDEX_index_SHIFT 0
+#define TPM_NV_INDEX_index ((TPM_NV_INDEX)0xffffff << 0)
+#define TPM_NV_INDEX_RH_NV_SHIFT 24
+#define TPM_NV_INDEX_RH_NV ((TPM_NV_INDEX)0xff << 24)
+// This is the initializer for a TPM_NV_INDEX bit array.
+#define TPM_NV_INDEX_INITIALIZER(index, rh_nv) \
+ (TPM_NV_INDEX)( \
+ (index << 0) + (rh_nv << 24))
+#endif // USE_BIT_FIELD_STRUCTURES
+
+// Table 2:206 - Definition of TPM_NT Constants
+typedef UINT32 TPM_NT;
+#define TYPE_OF_TPM_NT UINT32
+#define TPM_NT_ORDINARY (TPM_NT)(0x0)
+#define TPM_NT_COUNTER (TPM_NT)(0x1)
+#define TPM_NT_BITS (TPM_NT)(0x2)
+#define TPM_NT_EXTEND (TPM_NT)(0x4)
+#define TPM_NT_PIN_FAIL (TPM_NT)(0x8)
+#define TPM_NT_PIN_PASS (TPM_NT)(0x9)
+// Table 2:207
+typedef struct {
+ UINT32 pinCount;
+ UINT32 pinLimit;
+} TPMS_NV_PIN_COUNTER_PARAMETERS;
+
+#define TYPE_OF_TPMA_NV UINT32
+#define TPMA_NV_TO_UINT32(a) (*((UINT32 *)&(a)))
+#define UINT32_TO_TPMA_NV(a) (*((TPMA_NV *)&(a)))
+#define TPMA_NV_TO_BYTE_ARRAY(i, a) \
+ UINT32_TO_BYTE_ARRAY((TPMA_NV_TO_UINT32(i)), (a))
+#define BYTE_ARRAY_TO_TPMA_NV(i, a) \
+ { UINT32 x = BYTE_ARRAY_TO_UINT32(a); i = UINT32_TO_TPMA_NV(x); }
+#if USE_BIT_FIELD_STRUCTURES
+typedef struct TPMA_NV { // Table 2:208
+ unsigned PPWRITE : 1;
+ unsigned OWNERWRITE : 1;
+ unsigned AUTHWRITE : 1;
+ unsigned POLICYWRITE : 1;
+ unsigned TPM_NT : 4;
+ unsigned Reserved_bits_at_8 : 2;
+ unsigned POLICY_DELETE : 1;
+ unsigned WRITELOCKED : 1;
+ unsigned WRITEALL : 1;
+ unsigned WRITEDEFINE : 1;
+ unsigned WRITE_STCLEAR : 1;
+ unsigned GLOBALLOCK : 1;
+ unsigned PPREAD : 1;
+ unsigned OWNERREAD : 1;
+ unsigned AUTHREAD : 1;
+ unsigned POLICYREAD : 1;
+ unsigned Reserved_bits_at_20 : 5;
+ unsigned NO_DA : 1;
+ unsigned ORDERLY : 1;
+ unsigned CLEAR_STCLEAR : 1;
+ unsigned READLOCKED : 1;
+ unsigned WRITTEN : 1;
+ unsigned PLATFORMCREATE : 1;
+ unsigned READ_STCLEAR : 1;
+} TPMA_NV;
+// This is the initializer for a TPMA_NV structure
+#define TPMA_NV_INITIALIZER( \
+ ppwrite, ownerwrite, authwrite, policywrite, \
+ tpm_nt, bits_at_8, policy_delete, writelocked, \
+ writeall, writedefine, write_stclear, globallock, \
+ ppread, ownerread, authread, policyread, \
+ bits_at_20, no_da, orderly, clear_stclear, \
+ readlocked, written, platformcreate, read_stclear) \
+ {ppwrite, ownerwrite, authwrite, policywrite, \
+ tpm_nt, bits_at_8, policy_delete, writelocked, \
+ writeall, writedefine, write_stclear, globallock, \
+ ppread, ownerread, authread, policyread, \
+ bits_at_20, no_da, orderly, clear_stclear, \
+ readlocked, written, platformcreate, read_stclear}
+#else // USE_BIT_FIELD_STRUCTURES
+// This implements Table 2:208 TPMA_NV using bit masking
+typedef UINT32 TPMA_NV;
+#define TYPE_OF_TPMA_NV UINT32
+#define TPMA_NV_PPWRITE ((TPMA_NV)1 << 0)
+#define TPMA_NV_OWNERWRITE ((TPMA_NV)1 << 1)
+#define TPMA_NV_AUTHWRITE ((TPMA_NV)1 << 2)
+#define TPMA_NV_POLICYWRITE ((TPMA_NV)1 << 3)
+#define TPMA_NV_TPM_NT_SHIFT 4
+#define TPMA_NV_TPM_NT ((TPMA_NV)0xf << 4)
+#define TPMA_NV_POLICY_DELETE ((TPMA_NV)1 << 10)
+#define TPMA_NV_WRITELOCKED ((TPMA_NV)1 << 11)
+#define TPMA_NV_WRITEALL ((TPMA_NV)1 << 12)
+#define TPMA_NV_WRITEDEFINE ((TPMA_NV)1 << 13)
+#define TPMA_NV_WRITE_STCLEAR ((TPMA_NV)1 << 14)
+#define TPMA_NV_GLOBALLOCK ((TPMA_NV)1 << 15)
+#define TPMA_NV_PPREAD ((TPMA_NV)1 << 16)
+#define TPMA_NV_OWNERREAD ((TPMA_NV)1 << 17)
+#define TPMA_NV_AUTHREAD ((TPMA_NV)1 << 18)
+#define TPMA_NV_POLICYREAD ((TPMA_NV)1 << 19)
+#define TPMA_NV_NO_DA ((TPMA_NV)1 << 25)
+#define TPMA_NV_ORDERLY ((TPMA_NV)1 << 26)
+#define TPMA_NV_CLEAR_STCLEAR ((TPMA_NV)1 << 27)
+#define TPMA_NV_READLOCKED ((TPMA_NV)1 << 28)
+#define TPMA_NV_WRITTEN ((TPMA_NV)1 << 29)
+#define TPMA_NV_PLATFORMCREATE ((TPMA_NV)1 << 30)
+#define TPMA_NV_READ_STCLEAR ((TPMA_NV)1 << 31)
+#define TPMA_NV_RESERVED (0x00000300 | 0x01f00000)
+// This is the initializer for a TPMA_NV bit array.
+#define TPMA_NV_INITIALIZER( \
+ ppwrite, ownerwrite, authwrite, policywrite, \
+ tpm_nt, bits_at_8, policy_delete, writelocked, \
+ writeall, writedefine, write_stclear, globallock, \
+ ppread, ownerread, authread, policyread, \
+ bits_at_20, no_da, orderly, clear_stclear, \
+ readlocked, written, platformcreate, read_stclear) \
+ (TPMA_NV)( \
+ (ppwrite << 0) + (ownerwrite << 1) + \
+ (authwrite << 2) + (policywrite << 3) + \
+ (tpm_nt << 4) + (policy_delete << 10) + \
+ (writelocked << 11) + (writeall << 12) + \
+ (writedefine << 13) + (write_stclear << 14) + \
+ (globallock << 15) + (ppread << 16) + \
+ (ownerread << 17) + (authread << 18) + \
+ (policyread << 19) + (no_da << 25) + \
+ (orderly << 26) + (clear_stclear << 27) + \
+ (readlocked << 28) + (written << 29) + \
+ (platformcreate << 30) + (read_stclear << 31))
+#endif // USE_BIT_FIELD_STRUCTURES
+
+/* Table 2:209 - Definition of TPMS_NV_PUBLIC Structure */
+typedef struct {
+ TPMI_RH_NV_INDEX nvIndex;
+ TPMI_ALG_HASH nameAlg;
+ TPMA_NV attributes;
+ TPM2B_DIGEST authPolicy;
+ UINT16 dataSize;
+} TPMS_NV_PUBLIC;
+/* Table 2:207 - Definition of TPM2B_NV_PUBLIC Structure */
+typedef struct {
+ UINT16 size;
+ TPMS_NV_PUBLIC nvPublic;
+} TPM2B_NV_PUBLIC;
+/* Table 2:208 - Definition of TPM2B_CONTEXT_SENSITIVE Structure */
+typedef union {
+ struct {
+ UINT16 size;
+ BYTE buffer[MAX_CONTEXT_SIZE];
+ } t;
+ TPM2B b;
+} TPM2B_CONTEXT_SENSITIVE;
+/* Table 2:209 - Definition of TPMS_CONTEXT_DATA Structure */
+typedef struct {
+ TPM2B_DIGEST integrity;
+ TPM2B_CONTEXT_SENSITIVE encrypted;
+} TPMS_CONTEXT_DATA;
+/* Table 2:210 - Definition of TPM2B_CONTEXT_DATA Structure */
+typedef union {
+ struct {
+ UINT16 size;
+ BYTE buffer[sizeof(TPMS_CONTEXT_DATA)];
+ } t;
+ TPM2B b;
+} TPM2B_CONTEXT_DATA;
+/* Table 2:211 - Definition of TPMS_CONTEXT Structure */
+typedef struct {
+ UINT64 sequence;
+ TPMI_DH_SAVED savedHandle;
+ TPMI_RH_HIERARCHY hierarchy;
+ TPM2B_CONTEXT_DATA contextBlob;
+} TPMS_CONTEXT;
+/* Table 2:213 - Definition of TPMS_CREATION_DATA Structure */
+typedef struct {
+ TPML_PCR_SELECTION pcrSelect;
+ TPM2B_DIGEST pcrDigest;
+ TPMA_LOCALITY locality;
+ TPM_ALG_ID parentNameAlg;
+ TPM2B_NAME parentName;
+ TPM2B_NAME parentQualifiedName;
+ TPM2B_DATA outsideInfo;
+} TPMS_CREATION_DATA;
+/* Table 2:214 - Definition of TPM2B_CREATION_DATA Structure */
+typedef struct {
+ UINT16 size;
+ TPMS_CREATION_DATA creationData;
+} TPM2B_CREATION_DATA; /* Structure */
+
+// Table 2:220 - Definition of TPM_AT Constants
+typedef UINT32 TPM_AT;
+#define TYPE_OF_TPM_AT UINT32
+#define TPM_AT_ANY (TPM_AT)(0x00000000)
+#define TPM_AT_ERROR (TPM_AT)(0x00000001)
+#define TPM_AT_PV1 (TPM_AT)(0x00000002)
+#define TPM_AT_VEND (TPM_AT)(0x80000000)
+
+// Table 2:221 - Definition of TPM_AE Constants
+typedef UINT32 TPM_AE;
+#define TYPE_OF_TPM_AE UINT32
+#define TPM_AE_NONE (TPM_AE)(0x00000000)
+
+typedef struct { // Table 2:222
+ TPM_AT tag;
+ UINT32 data;
+} TPMS_AC_OUTPUT;
+
+/* Table 2:218 - Definition of TPML_AC_CAPABILITIES Structure */
+typedef struct {
+ UINT32 count;
+ TPMS_AC_OUTPUT acCapabilities[MAX_AC_CAPABILITIES];
+} TPML_AC_CAPABILITIES;
+
+
+#endif
diff --git a/src/tpm2/Unique.c b/src/tpm2/Unique.c
new file mode 100644
index 0000000..272d106
--- /dev/null
+++ b/src/tpm2/Unique.c
@@ -0,0 +1,109 @@
+/********************************************************************************/
+/* */
+/* Secret Value to the TPM */
+/* Written by Ken Goldman */
+/* IBM Thomas J. Watson Research Center */
+/* $Id: Unique.c 1490 2019-07-26 21:13:22Z kgoldman $ */
+/* */
+/* Licenses and Notices */
+/* */
+/* 1. Copyright Licenses: */
+/* */
+/* - Trusted Computing Group (TCG) grants to the user of the source code in */
+/* this specification (the "Source Code") a worldwide, irrevocable, */
+/* nonexclusive, royalty free, copyright license to reproduce, create */
+/* derivative works, distribute, display and perform the Source Code and */
+/* derivative works thereof, and to grant others the rights granted herein. */
+/* */
+/* - The TCG grants to the user of the other parts of the specification */
+/* (other than the Source Code) the rights to reproduce, distribute, */
+/* display, and perform the specification solely for the purpose of */
+/* developing products based on such documents. */
+/* */
+/* 2. Source Code Distribution Conditions: */
+/* */
+/* - Redistributions of Source Code must retain the above copyright licenses, */
+/* this list of conditions and the following disclaimers. */
+/* */
+/* - Redistributions in binary form must reproduce the above copyright */
+/* licenses, this list of conditions and the following disclaimers in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* 3. Disclaimers: */
+/* */
+/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
+/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
+/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
+/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
+/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
+/* information on specification licensing rights available through TCG */
+/* membership agreements. */
+/* */
+/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
+/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
+/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
+/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
+/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
+/* */
+/* - Without limitation, TCG and its members and licensors disclaim all */
+/* liability, including liability for infringement of any proprietary */
+/* rights, relating to use of information in this specification and to the */
+/* implementation of this specification, and TCG disclaims all liability for */
+/* cost of procurement of substitute goods or services, lost profits, loss */
+/* of use, loss of data or any incidental, consequential, direct, indirect, */
+/* or special damages, whether under contract, tort, warranty or otherwise, */
+/* arising in any way out of use or reliance upon this specification or any */
+/* information herein. */
+/* */
+/* (c) Copyright IBM Corp. and others, 2016 - 2019 */
+/* */
+/********************************************************************************/
+
+/* C.12 Unique.c */
+/* C.12.1. Introduction */
+/* In some implementations of the TPM, the hardware can provide a secret value to the TPM. This
+ secret value is statistically unique to the instance of the TPM. Typical uses of this value are
+ to provide personalization to the random number generation and as a shared secret between the TPM
+ and the manufacturer. */
+/* C.12.2. Includes */
+#include "Platform.h"
+const char notReallyUnique[] =
+ "This is not really a unique value. A real unique value should"
+ " be generated by the platform.";
+/* C.12.3. _plat__GetUnique() */
+/* This function is used to access the platform-specific unique value. This function places the
+ unique value in the provided buffer (b) and returns the number of bytes transferred. The function
+ will not copy more data than bSize. */
+/* NOTE: If a platform unique value has unequal distribution of uniqueness and bSize is smaller than
+ the size of the unique value, the bSize portion with the most uniqueness should be returned. */
+LIB_EXPORT uint32_t
+_plat__GetUnique(
+ uint32_t which, // authorities (0) or details
+ uint32_t bSize, // size of the buffer
+ unsigned char *b // output buffer
+ )
+{
+ const char *from = notReallyUnique;
+ uint32_t retVal = 0;
+ if(which == 0) // the authorities value
+ {
+ for(retVal = 0;
+ *from != 0 && retVal < bSize;
+ retVal++)
+ {
+ *b++ = *from++;
+ }
+ }
+ else
+ {
+#define uSize sizeof(notReallyUnique)
+ b = &b[((bSize < uSize) ? bSize : uSize) - 1];
+ for(retVal = 0;
+ *from != 0 && retVal < bSize;
+ retVal++)
+ {
+ *b-- = *from++;
+ }
+ }
+ return retVal;
+}
diff --git a/src/tpm2/Unmarshal.c b/src/tpm2/Unmarshal.c
new file mode 100644
index 0000000..e2395c3
--- /dev/null
+++ b/src/tpm2/Unmarshal.c
@@ -0,0 +1,4532 @@
+/********************************************************************************/
+/* */
+/* Parameter Unmarshaling */
+/* Written by Ken Goldman */
+/* IBM Thomas J. Watson Research Center */
+/* $Id: Unmarshal.c 1635 2020-06-12 21:48:27Z kgoldman $ */
+/* */
+/* (c) Copyright IBM Corporation 2015 - 2018 */
+/* */
+/* All rights reserved. */
+/* */
+/* Redistribution and use in source and binary forms, with or without */
+/* modification, are permitted provided that the following conditions are */
+/* met: */
+/* */
+/* Redistributions of source code must retain the above copyright notice, */
+/* this list of conditions and the following disclaimer. */
+/* */
+/* Redistributions in binary form must reproduce the above copyright */
+/* notice, this list of conditions and the following disclaimer in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* Neither the names of the IBM Corporation nor the names of its */
+/* contributors may be used to endorse or promote products derived from */
+/* this software without specific prior written permission. */
+/* */
+/* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS */
+/* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT */
+/* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR */
+/* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT */
+/* HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, */
+/* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT */
+/* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, */
+/* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY */
+/* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT */
+/* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE */
+/* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */
+/********************************************************************************/
+
+/* rev 136 */
+
+#include <string.h>
+
+#include "Unmarshal_fp.h"
+#include "CryptEccMain_fp.h" // libtpms added
+
+TPM_RC
+UINT8_Unmarshal(UINT8 *target, BYTE **buffer, INT32 *size)
+{
+ if ((UINT32)*size < sizeof(UINT8)) {
+ return TPM_RC_INSUFFICIENT;
+ }
+ *target = (*buffer)[0];
+ *buffer += sizeof(UINT8);
+ *size -= sizeof(UINT8);
+ return TPM_RC_SUCCESS;
+}
+
+TPM_RC
+INT8_Unmarshal(INT8 *target, BYTE **buffer, INT32 *size)
+{
+ return UINT8_Unmarshal((UINT8 *)target, buffer, size);
+}
+
+TPM_RC
+UINT16_Unmarshal(UINT16 *target, BYTE **buffer, INT32 *size)
+{
+ if ((UINT32)*size < sizeof(UINT16)) {
+ return TPM_RC_INSUFFICIENT;
+ }
+ *target = ((UINT16)((*buffer)[0]) << 8) |
+ ((UINT16)((*buffer)[1]) << 0);
+ *buffer += sizeof(UINT16);
+ *size -= sizeof(UINT16);
+ return TPM_RC_SUCCESS;
+}
+
+TPM_RC
+UINT32_Unmarshal(UINT32 *target, BYTE **buffer, INT32 *size)
+{
+ if ((UINT32)*size < sizeof(UINT32)) {
+ return TPM_RC_INSUFFICIENT;
+ }
+ *target = ((UINT32)((*buffer)[0]) << 24) |
+ ((UINT32)((*buffer)[1]) << 16) |
+ ((UINT32)((*buffer)[2]) << 8) |
+ ((UINT32)((*buffer)[3]) << 0);
+ *buffer += sizeof(UINT32);
+ *size -= sizeof(UINT32);
+ return TPM_RC_SUCCESS;
+}
+
+TPM_RC
+UINT64_Unmarshal(UINT64 *target, BYTE **buffer, INT32 *size)
+{
+ if ((UINT32)*size < sizeof(UINT64)) {
+ return TPM_RC_INSUFFICIENT;
+ }
+ *target = ((UINT64)((*buffer)[0]) << 56) |
+ ((UINT64)((*buffer)[1]) << 48) |
+ ((UINT64)((*buffer)[2]) << 40) |
+ ((UINT64)((*buffer)[3]) << 32) |
+ ((UINT64)((*buffer)[4]) << 24) |
+ ((UINT64)((*buffer)[5]) << 16) |
+ ((UINT64)((*buffer)[6]) << 8) |
+ ((UINT64)((*buffer)[7]) << 0);
+ *buffer += sizeof(UINT64);
+ *size -= sizeof(UINT64);
+ return TPM_RC_SUCCESS;
+}
+
+TPM_RC
+Array_Unmarshal(BYTE *targetBuffer, UINT16 targetSize, BYTE **buffer, INT32 *size)
+{
+ TPM_RC rc = TPM_RC_SUCCESS;
+
+ if (targetSize > *size) {
+ rc = TPM_RC_INSUFFICIENT;
+ }
+ else {
+ memcpy(targetBuffer, *buffer, targetSize);
+ *buffer += targetSize;
+ *size -= targetSize;
+ }
+ return rc;
+}
+
+TPM_RC
+TPM2B_Unmarshal(TPM2B *target, UINT16 targetSize, BYTE **buffer, INT32 *size)
+{
+ TPM_RC rc = TPM_RC_SUCCESS;
+
+ if (rc == TPM_RC_SUCCESS) {
+ rc = UINT16_Unmarshal(&target->size, buffer, size);
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ if (target->size > targetSize) {
+ rc = TPM_RC_SIZE;
+ target->size = 0; // libtpms added
+ }
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ rc = Array_Unmarshal(target->buffer, target->size, buffer, size);
+ }
+ return rc;
+}
+
+/* Table 5 - Definition of Types for Documentation Clarity */
+
+TPM_RC
+TPM_KEY_BITS_Unmarshal(TPM_KEY_BITS *target, BYTE **buffer, INT32 *size)
+{
+ TPM_RC rc = TPM_RC_SUCCESS;
+
+ if (rc == TPM_RC_SUCCESS) {
+ rc = UINT16_Unmarshal(target, buffer, size);
+ }
+ return rc;
+}
+
+/* Table 7 - Definition of (UINT32) TPM_GENERATED Constants <O> */
+
+#if 0
+TPM_RC
+TPM_GENERATED_Unmarshal(TPM_GENERATED *target, BYTE **buffer, INT32 *size)
+{
+ TPM_RC rc = TPM_RC_SUCCESS;
+ TPM_GENERATED orig_target = *target; // libtpms added
+
+ if (rc == TPM_RC_SUCCESS) {
+ rc = UINT32_Unmarshal(target, buffer, size);
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ if (*target != TPM_GENERATED_VALUE) {
+ rc = TPM_RC_VALUE;
+ *target = orig_target; // libtpms added
+ }
+ }
+ return rc;
+}
+#endif
+
+/* Table 9 - Definition of (UINT16) TPM_ALG_ID Constants <IN/OUT, S> */
+
+TPM_RC
+TPM_ALG_ID_Unmarshal(TPM_ALG_ID *target, BYTE **buffer, INT32 *size)
+{
+ TPM_RC rc = TPM_RC_SUCCESS;
+
+ if (rc == TPM_RC_SUCCESS) {
+ rc = UINT16_Unmarshal(target, buffer, size);
+ }
+ return rc;
+}
+
+/* Table 10 - Definition of (UINT16) {ECC} TPM_ECC_CURVE Constants <IN/OUT, S> */
+
+#if ALG_ECC
+TPM_RC
+TPM_ECC_CURVE_Unmarshal(TPM_ECC_CURVE *target, BYTE **buffer, INT32 *size)
+{
+ TPM_RC rc = TPM_RC_SUCCESS;
+ TPM_ECC_CURVE orig_target = *target; // libtpms added
+
+ if (rc == TPM_RC_SUCCESS) {
+ rc = UINT16_Unmarshal(target, buffer, size);
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ switch (*target) {
+ case TPM_ECC_NONE:
+ case TPM_ECC_NIST_P192:
+ case TPM_ECC_NIST_P224:
+ case TPM_ECC_NIST_P256:
+ case TPM_ECC_NIST_P384:
+ case TPM_ECC_NIST_P521:
+ case TPM_ECC_BN_P256:
+ case TPM_ECC_BN_P638:
+ case TPM_ECC_SM2_P256:
+ break;
+ default:
+ rc = TPM_RC_CURVE;
+ *target = orig_target; // libtpms added
+ }
+ }
+ return rc;
+}
+#endif
+
+/* Table 13 - Definition of (UINT32) TPM_CC Constants (Numeric Order) <IN/OUT, S> */
+
+TPM_RC
+TPM_CC_Unmarshal(TPM_RC *target, BYTE **buffer, INT32 *size)
+{
+ TPM_RC rc = TPM_RC_SUCCESS;
+
+ if (rc == TPM_RC_SUCCESS) {
+ rc = UINT32_Unmarshal(target, buffer, size);
+ }
+ return rc;
+}
+
+/* Table 18 - Definition of (INT8) TPM_CLOCK_ADJUST Constants <IN> */
+
+TPM_RC
+TPM_CLOCK_ADJUST_Unmarshal(TPM_CLOCK_ADJUST *target, BYTE **buffer, INT32 *size)
+{
+ TPM_RC rc = TPM_RC_SUCCESS;
+ TPM_CLOCK_ADJUST orig_target = *target; // libtpms added
+
+ if (rc == TPM_RC_SUCCESS) {
+ rc = INT8_Unmarshal(target, buffer, size);
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ switch (*target) {
+ case TPM_CLOCK_COARSE_SLOWER:
+ case TPM_CLOCK_MEDIUM_SLOWER:
+ case TPM_CLOCK_FINE_SLOWER:
+ case TPM_CLOCK_NO_CHANGE:
+ case TPM_CLOCK_FINE_FASTER:
+ case TPM_CLOCK_MEDIUM_FASTER:
+ case TPM_CLOCK_COARSE_FASTER:
+ break;
+ default:
+ rc = TPM_RC_VALUE;
+ *target = orig_target; // libtpms added
+ }
+ }
+ return rc;
+}
+
+/* Table 19 - Definition of (UINT16) TPM_EO Constants <IN/OUT> */
+
+TPM_RC
+TPM_EO_Unmarshal(TPM_EO *target, BYTE **buffer, INT32 *size)
+{
+ TPM_RC rc = TPM_RC_SUCCESS;
+ TPM_EO orig_target = *target; // libtpms added
+
+ if (rc == TPM_RC_SUCCESS) {
+ rc = UINT16_Unmarshal(target, buffer, size);
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ switch (*target) {
+ case TPM_EO_EQ:
+ case TPM_EO_NEQ:
+ case TPM_EO_SIGNED_GT:
+ case TPM_EO_UNSIGNED_GT:
+ case TPM_EO_SIGNED_LT:
+ case TPM_EO_UNSIGNED_LT:
+ case TPM_EO_SIGNED_GE:
+ case TPM_EO_UNSIGNED_GE:
+ case TPM_EO_SIGNED_LE:
+ case TPM_EO_UNSIGNED_LE:
+ case TPM_EO_BITSET:
+ case TPM_EO_BITCLEAR:
+ break;
+ default:
+ rc = TPM_RC_VALUE;
+ *target = orig_target; // libtpms added
+ }
+ }
+ return rc;
+}
+
+/* Table 20 - Definition of (UINT16) TPM_ST Constants <IN/OUT, S> */
+
+TPM_RC
+TPM_ST_Unmarshal(TPM_ST *target, BYTE **buffer, INT32 *size)
+{
+ TPM_RC rc = TPM_RC_SUCCESS;
+ TPM_ST orig_target = *target; // libtpms added
+
+ if (rc == TPM_RC_SUCCESS) {
+ rc = UINT16_Unmarshal(target, buffer, size);
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ switch (*target) {
+ case TPM_ST_RSP_COMMAND:
+ case TPM_ST_NULL:
+ case TPM_ST_NO_SESSIONS:
+ case TPM_ST_SESSIONS:
+ case TPM_ST_ATTEST_NV:
+ case TPM_ST_ATTEST_COMMAND_AUDIT:
+ case TPM_ST_ATTEST_SESSION_AUDIT:
+ case TPM_ST_ATTEST_CERTIFY:
+ case TPM_ST_ATTEST_QUOTE:
+ case TPM_ST_ATTEST_TIME:
+ case TPM_ST_ATTEST_CREATION:
+ case TPM_ST_CREATION:
+ case TPM_ST_VERIFIED:
+ case TPM_ST_AUTH_SECRET:
+ case TPM_ST_HASHCHECK:
+ case TPM_ST_AUTH_SIGNED:
+ break;
+ default:
+ rc = TPM_RC_VALUE;
+ *target = orig_target; // libtpms added
+ }
+ }
+ return rc;
+}
+
+/* Table 20 - Definition of (UINT16) TPM_SU Constants <IN> */
+
+TPM_RC
+TPM_SU_Unmarshal(TPM_SU *target, BYTE **buffer, INT32 *size)
+{
+ TPM_RC rc = TPM_RC_SUCCESS;
+ TPM_SU orig_target = *target; // libtpms added
+
+ if (rc == TPM_RC_SUCCESS) {
+ rc = UINT16_Unmarshal(target, buffer, size);
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ switch (*target) {
+ case TPM_SU_CLEAR:
+ case TPM_SU_STATE:
+ break;
+ default:
+ rc = TPM_RC_VALUE;
+ *target = orig_target; // libtpms added
+ }
+ }
+ return rc;
+}
+
+/* Table 21 - Definition of (UINT8) TPM_SE Constants <IN> */
+
+TPM_RC
+TPM_SE_Unmarshal(TPM_SE *target, BYTE **buffer, INT32 *size)
+{
+ TPM_RC rc = TPM_RC_SUCCESS;
+ TPM_SE orig_target = *target; // libtpms added
+
+ if (rc == TPM_RC_SUCCESS) {
+ rc = UINT8_Unmarshal(target, buffer, size);
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ switch (*target) {
+ case TPM_SE_HMAC:
+ case TPM_SE_POLICY:
+ case TPM_SE_TRIAL:
+ break;
+ default:
+ rc = TPM_RC_VALUE;
+ *target = orig_target; // libtpms added
+ }
+ }
+ return rc;
+}
+
+/* Table 22 - Definition of (UINT32) TPM_CAP Constants */
+
+TPM_RC
+TPM_CAP_Unmarshal(TPM_CAP *target, BYTE **buffer, INT32 *size)
+{
+ TPM_RC rc = TPM_RC_SUCCESS;
+ TPM_CAP orig_target = *target; // libtpms added
+
+ if (rc == TPM_RC_SUCCESS) {
+ rc = UINT32_Unmarshal(target, buffer, size);
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ switch (*target) {
+ case TPM_CAP_ALGS:
+ case TPM_CAP_HANDLES:
+ case TPM_CAP_COMMANDS:
+ case TPM_CAP_PP_COMMANDS:
+ case TPM_CAP_AUDIT_COMMANDS:
+ case TPM_CAP_PCRS:
+ case TPM_CAP_TPM_PROPERTIES:
+ case TPM_CAP_PCR_PROPERTIES:
+ case TPM_CAP_ECC_CURVES:
+ case TPM_CAP_AUTH_POLICIES:
+ case TPM_CAP_ACT:
+ case TPM_CAP_VENDOR_PROPERTY:
+ break;
+ default:
+ rc = TPM_RC_VALUE;
+ *target = orig_target; // libtpms added
+ }
+ }
+ return rc;
+}
+
+/* Table 24 - Definition of (UINT32) TPM_PT Constants <IN/OUT, S> */
+
+TPM_RC
+TPM_PT_Unmarshal(TPM_HANDLE *target, BYTE **buffer, INT32 *size)
+{
+ TPM_RC rc = TPM_RC_SUCCESS;
+
+ if (rc == TPM_RC_SUCCESS) {
+ rc = UINT32_Unmarshal(target, buffer, size);
+ }
+ return rc;
+}
+
+/* Table 25 - Definition of (UINT32) TPM_PT_PCR Constants <IN/OUT, S> */
+
+TPM_RC
+TPM_PT_PCR_Unmarshal(TPM_PT_PCR *target, BYTE **buffer, INT32 *size)
+{
+ TPM_RC rc = TPM_RC_SUCCESS;
+
+ if (rc == TPM_RC_SUCCESS) {
+ rc = UINT32_Unmarshal(target, buffer, size);
+ }
+ return rc;
+}
+
+/* Table 27 - Definition of Types for Handles */
+
+TPM_RC
+TPM_HANDLE_Unmarshal(TPM_HANDLE *target, BYTE **buffer, INT32 *size)
+{
+ TPM_RC rc = TPM_RC_SUCCESS;
+
+ if (rc == TPM_RC_SUCCESS) {
+ rc = UINT32_Unmarshal(target, buffer, size);
+ }
+ return rc;
+}
+
+/* Table 31 - Definition of (UINT32) TPMA_ALGORITHM Bits */
+
+TPM_RC
+TPMA_ALGORITHM_Unmarshal(TPMA_ALGORITHM *target, BYTE **buffer, INT32 *size)
+{
+ TPM_RC rc = TPM_RC_SUCCESS;
+ TPMA_ALGORITHM orig_target = *target; // libtpms added
+
+ if (rc == TPM_RC_SUCCESS) {
+ rc = UINT32_Unmarshal((UINT32 *)target, buffer, size); /* libtpms changed */
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ if (*target & TPMA_ALGORITHM_reserved) {
+ rc = TPM_RC_RESERVED_BITS;
+ *target = orig_target; // libtpms added
+ }
+ }
+ return rc;
+}
+
+/* Table 32 - Definition of (UINT32) TPMA_OBJECT Bits */
+
+TPM_RC
+TPMA_OBJECT_Unmarshal(TPMA_OBJECT *target, BYTE **buffer, INT32 *size)
+{
+ TPM_RC rc = TPM_RC_SUCCESS;
+ TPMA_OBJECT orig_target = *target; // libtpms added
+
+ if (rc == TPM_RC_SUCCESS) {
+ rc = UINT32_Unmarshal((UINT32 *)target, buffer, size); /* libtpms changed */
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ if (*target & TPMA_OBJECT_reserved) {
+ rc = TPM_RC_RESERVED_BITS;
+ *target = orig_target; // libtpms added
+ }
+ }
+ return rc;
+}
+
+/* Table 33 - Definition of (UINT8) TPMA_SESSION Bits <IN/OUT> */
+
+TPM_RC
+TPMA_SESSION_Unmarshal(TPMA_SESSION *target, BYTE **buffer, INT32 *size)
+{
+ TPM_RC rc = TPM_RC_SUCCESS;
+ TPMA_SESSION orig_target = *target; // libtpms added
+
+ if (rc == TPM_RC_SUCCESS) {
+ rc = UINT8_Unmarshal((UINT8 *)target, buffer, size); /* libtpms changed */
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ if (*target & TPMA_SESSION_reserved) {
+ rc = TPM_RC_RESERVED_BITS;
+ *target = orig_target; // libtpms added
+ }
+ }
+ return rc;
+}
+
+/* Table 34 - Definition of (UINT8) TPMA_LOCALITY Bits <IN/OUT> */
+
+TPM_RC
+TPMA_LOCALITY_Unmarshal(TPMA_LOCALITY *target, BYTE **buffer, INT32 *size)
+{
+ TPM_RC rc = TPM_RC_SUCCESS;
+
+ if (rc == TPM_RC_SUCCESS) {
+ rc = UINT8_Unmarshal((UINT8 *)target, buffer, size); /* libtpms changed */
+ }
+ return rc;
+}
+
+/* Table 38 - Definition of (TPM_CC) TPMA_CC Bits <OUT> */
+
+TPM_RC
+TPMA_CC_Unmarshal(TPMA_CC *target, BYTE **buffer, INT32 *size)
+{
+ TPM_RC rc = TPM_RC_SUCCESS;
+ TPMA_CC orig_target = *target; // libtpms added
+
+ if (rc == TPM_RC_SUCCESS) {
+ rc = UINT32_Unmarshal((UINT32 *)target, buffer, size); /* libtpms changed */
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ if (*target & TPMA_CC_reserved) {
+ rc = TPM_RC_RESERVED_BITS;
+ *target = orig_target; // libtpms added
+ }
+ }
+ return rc;
+}
+
+/* Table 39 - Definition of (BYTE) TPMI_YES_NO Type */
+
+TPM_RC
+TPMI_YES_NO_Unmarshal(TPMI_YES_NO *target, BYTE **buffer, INT32 *size)
+{
+ TPM_RC rc = TPM_RC_SUCCESS;
+ TPMI_YES_NO orig_target = *target; // libtpms added
+
+ if (rc == TPM_RC_SUCCESS) {
+ rc = UINT8_Unmarshal(target, buffer, size);
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ switch (*target) {
+ case NO:
+ case YES:
+ break;
+ default:
+ rc = TPM_RC_VALUE;
+ *target = orig_target; // libtpms added
+ }
+ }
+ return rc;
+}
+
+/* Table 40 - Definition of (TPM_HANDLE) TPMI_DH_OBJECT Type */
+
+TPM_RC
+TPMI_DH_OBJECT_Unmarshal(TPMI_DH_OBJECT *target, BYTE **buffer, INT32 *size, BOOL allowNull)
+{
+ TPM_RC rc = TPM_RC_SUCCESS;
+ TPMI_DH_OBJECT orig_target = *target; // libtpms added
+
+ if (rc == TPM_RC_SUCCESS) {
+ rc = TPM_HANDLE_Unmarshal(target, buffer, size);
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ BOOL isNotTransient = (*target < TRANSIENT_FIRST) || (*target > TRANSIENT_LAST);
+ BOOL isNotPersistent = (*target < PERSISTENT_FIRST) || (*target > PERSISTENT_LAST);
+ BOOL isNotLegalNull = (*target != TPM_RH_NULL) || !allowNull;
+ if (isNotTransient &&
+ isNotPersistent &&
+ isNotLegalNull) {
+ rc = TPM_RC_VALUE;
+ *target = orig_target; // libtpms added
+ }
+ }
+ return rc;
+}
+
+/* Table 2:41 - Definition of TPMI_DH_PARENT Type (InterfaceTable()) */
+
+TPM_RC
+TPMI_DH_PARENT_Unmarshal(TPMI_DH_PARENT *target, BYTE **buffer, INT32 *size, BOOL allowNull)
+{
+ TPM_RC rc = TPM_RC_SUCCESS;
+ TPMI_DH_PARENT orig_target = *target; // libtpms added
+
+ if (rc == TPM_RC_SUCCESS) {
+ rc = TPM_HANDLE_Unmarshal(target, buffer, size);
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ BOOL isNotTransient = (*target < TRANSIENT_FIRST) || (*target > TRANSIENT_LAST);
+ BOOL isNotPersistent = (*target < PERSISTENT_FIRST) || (*target > PERSISTENT_LAST);
+ BOOL isNotOwner = *target != TPM_RH_OWNER;
+ BOOL isNotPlatform = *target != TPM_RH_PLATFORM;
+ BOOL isNotEndorsement = *target != TPM_RH_ENDORSEMENT;
+ BOOL isNotLegalNull = (*target != TPM_RH_NULL) || !allowNull;
+ if (isNotTransient &&
+ isNotPersistent &&
+ isNotOwner &&
+ isNotPlatform &&
+ isNotEndorsement &&
+ isNotLegalNull) {
+ rc = TPM_RC_VALUE;
+ *target = orig_target; // libtpms added
+ }
+ }
+ return rc;
+}
+
+/* Table 41 - Definition of (TPM_HANDLE) TPMI_DH_PERSISTENT Type */
+
+TPM_RC
+TPMI_DH_PERSISTENT_Unmarshal(TPMI_DH_PERSISTENT *target, BYTE **buffer, INT32 *size)
+{
+ TPM_RC rc = TPM_RC_SUCCESS;
+ TPMI_DH_PERSISTENT orig_target = *target; // libtpms added
+
+ if (rc == TPM_RC_SUCCESS) {
+ rc = TPM_HANDLE_Unmarshal(target, buffer, size);
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ BOOL isNotPersistent = (*target < PERSISTENT_FIRST) || (*target > PERSISTENT_LAST);
+ if (isNotPersistent) {
+ rc = TPM_RC_VALUE;
+ *target = orig_target; // libtpms added
+ }
+ }
+ return rc;
+}
+
+/* Table 42 - Definition of (TPM_HANDLE) TPMI_DH_ENTITY Type <IN> */
+
+TPM_RC
+TPMI_DH_ENTITY_Unmarshal(TPMI_DH_ENTITY *target, BYTE **buffer, INT32 *size, BOOL allowNull)
+{
+ TPM_RC rc = TPM_RC_SUCCESS;
+ TPMI_DH_ENTITY orig_target = *target; // libtpms added
+
+ if (rc == TPM_RC_SUCCESS) {
+ rc = TPM_HANDLE_Unmarshal(target, buffer, size);
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ BOOL isNotOwner = *target != TPM_RH_OWNER;
+ BOOL isNotEndorsement = *target != TPM_RH_ENDORSEMENT;
+ BOOL isNotPlatform = *target != TPM_RH_PLATFORM;
+ BOOL isNotLockout = *target != TPM_RH_LOCKOUT;
+ BOOL isNotTransient = (*target < TRANSIENT_FIRST) || (*target > TRANSIENT_LAST);
+ BOOL isNotPersistent = (*target < PERSISTENT_FIRST) || (*target > PERSISTENT_LAST);
+ BOOL isNotNv = (*target < NV_INDEX_FIRST) || (*target > NV_INDEX_LAST);
+ BOOL isNotPcr = (*target > PCR_LAST);
+ BOOL isNotAuth = (*target < TPM_RH_AUTH_00) || (*target > TPM_RH_AUTH_FF);
+ BOOL isNotLegalNull = (*target != TPM_RH_NULL) || !allowNull;
+ if (isNotOwner &&
+ isNotEndorsement &&
+ isNotPlatform &&
+ isNotLockout &&
+ isNotTransient &&
+ isNotPersistent &&
+ isNotNv &&
+ isNotPcr &&
+ isNotAuth &&
+ isNotLegalNull) {
+ rc = TPM_RC_VALUE;
+ *target = orig_target; // libtpms added
+ }
+ }
+ return rc;
+}
+
+/* Table 43 - Definition of (TPM_HANDLE) TPMI_DH_PCR Type <IN> */
+
+TPM_RC
+TPMI_DH_PCR_Unmarshal(TPMI_DH_PCR *target, BYTE **buffer, INT32 *size, BOOL allowNull)
+{
+ TPM_RC rc = TPM_RC_SUCCESS;
+ TPMI_DH_PCR orig_target = *target; // libtpms added
+
+ if (rc == TPM_RC_SUCCESS) {
+ rc = TPM_HANDLE_Unmarshal(target, buffer, size);
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ BOOL isNotPcr = (*target > PCR_LAST);
+ BOOL isNotLegalNull = (*target != TPM_RH_NULL) || !allowNull;
+ if (isNotPcr &&
+ isNotLegalNull) {
+ rc = TPM_RC_VALUE;
+ *target = orig_target; // libtpms added
+ }
+ }
+ return rc;
+}
+
+/* Table 44 - Definition of (TPM_HANDLE) TPMI_SH_AUTH_SESSION Type <IN/OUT> */
+
+TPM_RC
+TPMI_SH_AUTH_SESSION_Unmarshal(TPMI_SH_AUTH_SESSION *target, BYTE **buffer, INT32 *size, BOOL allowPwd)
+{
+ TPM_RC rc = TPM_RC_SUCCESS;
+ TPMI_SH_AUTH_SESSION orig_target = *target; // libtpms added
+
+ if (rc == TPM_RC_SUCCESS) {
+ rc = TPM_HANDLE_Unmarshal(target, buffer, size);
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ BOOL isNotHmacSession = (*target < HMAC_SESSION_FIRST ) || (*target > HMAC_SESSION_LAST);
+ BOOL isNotPolicySession = (*target < POLICY_SESSION_FIRST) || (*target > POLICY_SESSION_LAST);
+ BOOL isNotLegalPwd = (*target != TPM_RS_PW) || !allowPwd;
+ if (isNotHmacSession &&
+ isNotPolicySession &&
+ isNotLegalPwd) {
+ rc = TPM_RC_VALUE;
+ *target = orig_target; // libtpms added
+ }
+ }
+ return rc;
+}
+
+/* Table 45 - Definition of (TPM_HANDLE) TPMI_SH_HMAC Type <IN/OUT> */
+
+TPM_RC
+TPMI_SH_HMAC_Unmarshal(TPMI_SH_HMAC *target, BYTE **buffer, INT32 *size)
+{
+ TPM_RC rc = TPM_RC_SUCCESS;
+ TPMI_SH_HMAC orig_target = *target; // libtpms added
+
+ if (rc == TPM_RC_SUCCESS) {
+ rc = TPM_HANDLE_Unmarshal(target, buffer, size);
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ BOOL isNotHmacSession = (*target < HMAC_SESSION_FIRST ) || (*target > HMAC_SESSION_LAST);
+ if (isNotHmacSession) {
+ rc = TPM_RC_VALUE;
+ *target = orig_target; // libtpms added
+ }
+ }
+ return rc;
+}
+
+/* Table 46 - Definition of (TPM_HANDLE) TPMI_SH_POLICY Type <IN/OUT> */
+
+TPM_RC
+TPMI_SH_POLICY_Unmarshal(TPMI_SH_POLICY *target, BYTE **buffer, INT32 *size)
+{
+ TPM_RC rc = TPM_RC_SUCCESS;
+ TPMI_SH_POLICY orig_target = *target; // libtpms added
+
+ if (rc == TPM_RC_SUCCESS) {
+ rc = TPM_HANDLE_Unmarshal(target, buffer, size);
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ BOOL isNotPolicySession = (*target < POLICY_SESSION_FIRST) || (*target > POLICY_SESSION_LAST);
+ if (isNotPolicySession) {
+ rc = TPM_RC_VALUE;
+ *target = orig_target; // libtpms added
+ }
+ }
+ return rc;
+}
+
+/* Table 47 - Definition of (TPM_HANDLE) TPMI_DH_CONTEXT Type */
+
+TPM_RC
+TPMI_DH_CONTEXT_Unmarshal(TPMI_DH_CONTEXT *target, BYTE **buffer, INT32 *size)
+{
+ TPM_RC rc = TPM_RC_SUCCESS;
+ TPMI_DH_CONTEXT orig_target = *target; // libtpms added
+
+ if (rc == TPM_RC_SUCCESS) {
+ rc = TPM_HANDLE_Unmarshal(target, buffer, size);
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ BOOL isNotHmacSession = (*target < HMAC_SESSION_FIRST ) || (*target > HMAC_SESSION_LAST);
+ BOOL isNotPolicySession = (*target < POLICY_SESSION_FIRST) || (*target > POLICY_SESSION_LAST);
+ BOOL isNotTransient = (*target < TRANSIENT_FIRST) || (*target > TRANSIENT_LAST);
+ if (isNotHmacSession &&
+ isNotPolicySession &&
+ isNotTransient) {
+ rc = TPM_RC_VALUE;
+ *target = orig_target; // libtpms added
+ }
+ }
+ return rc;
+}
+
+/* Table 49 - Definition of (TPM_HANDLE) TPMI_DH_SAVED Type */
+
+TPM_RC
+TPMI_DH_SAVED_Unmarshal(TPMI_DH_SAVED *target, BYTE **buffer, INT32 *size, BOOL allowNull)
+{
+ TPM_RC rc = TPM_RC_SUCCESS;
+ TPMI_DH_SAVED orig_target = *target; // libtpms added
+ allowNull = allowNull;
+
+ if (rc == TPM_RC_SUCCESS) {
+ rc = TPM_HANDLE_Unmarshal(target, buffer, size);
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ BOOL isNotHmacSession = (*target < HMAC_SESSION_FIRST ) || (*target > HMAC_SESSION_LAST);
+ BOOL isNotPolicySession = (*target < POLICY_SESSION_FIRST) || (*target > POLICY_SESSION_LAST);
+ BOOL isNotTransientObject = (*target != 0x80000000);
+ BOOL isNotSequenceObject = (*target != 0x80000001);
+ BOOL isNotTransientStClear = (*target != 0x80000002);
+ if (isNotHmacSession &&
+ isNotPolicySession &&
+ isNotTransientObject &&
+ isNotSequenceObject &&
+ isNotTransientStClear) {
+ rc = TPM_RC_VALUE;
+ *target = orig_target; // libtpms added
+ }
+ }
+ return rc;
+}
+
+/* Table 48 - Definition of (TPM_HANDLE) TPMI_RH_HIERARCHY Type */
+
+TPM_RC
+TPMI_RH_HIERARCHY_Unmarshal(TPMI_RH_HIERARCHY *target, BYTE **buffer, INT32 *size, BOOL allowNull)
+{
+ TPM_RC rc = TPM_RC_SUCCESS;
+ TPMI_RH_HIERARCHY orig_target = *target; // libtpms added
+
+ if (rc == TPM_RC_SUCCESS) {
+ rc = TPM_HANDLE_Unmarshal(target, buffer, size);
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ switch (*target) {
+ case TPM_RH_OWNER:
+ case TPM_RH_PLATFORM:
+ case TPM_RH_ENDORSEMENT:
+ break;
+ case TPM_RH_NULL:
+ if (allowNull) {
+ break;
+ }
+ default:
+ rc = TPM_RC_VALUE;
+ *target = orig_target; // libtpms added
+ }
+ }
+ return rc;
+}
+
+/* Table 49 - Definition of (TPM_HANDLE) TPMI_RH_ENABLES Type */
+
+TPM_RC
+TPMI_RH_ENABLES_Unmarshal(TPMI_RH_ENABLES *target, BYTE **buffer, INT32 *size, BOOL allowNull)
+{
+ TPM_RC rc = TPM_RC_SUCCESS;
+ TPMI_RH_ENABLES orig_target = *target; // libtpms added
+
+ if (rc == TPM_RC_SUCCESS) {
+ rc = TPM_HANDLE_Unmarshal(target, buffer, size);
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ switch (*target) {
+ case TPM_RH_OWNER:
+ case TPM_RH_PLATFORM:
+ case TPM_RH_ENDORSEMENT:
+ case TPM_RH_PLATFORM_NV:
+ break;
+ case TPM_RH_NULL:
+ if (allowNull) {
+ break;
+ }
+ default:
+ rc = TPM_RC_VALUE;
+ *target = orig_target; // libtpms added
+ }
+ }
+ return rc;
+}
+
+/* Table 50 - Definition of (TPM_HANDLE) TPMI_RH_HIERARCHY_AUTH Type <IN> */
+
+TPM_RC
+TPMI_RH_HIERARCHY_AUTH_Unmarshal(TPMI_RH_HIERARCHY_AUTH *target, BYTE **buffer, INT32 *size)
+{
+ TPM_RC rc = TPM_RC_SUCCESS;
+ TPMI_RH_HIERARCHY_AUTH orig_target = *target; // libtpms added
+
+ if (rc == TPM_RC_SUCCESS) {
+ rc = TPM_HANDLE_Unmarshal(target, buffer, size);
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ switch (*target) {
+ case TPM_RH_OWNER:
+ case TPM_RH_PLATFORM:
+ case TPM_RH_ENDORSEMENT:
+ case TPM_RH_LOCKOUT:
+ break;
+ default:
+ rc = TPM_RC_VALUE;
+ *target = orig_target; // libtpms added
+ }
+ }
+ return rc;
+}
+
+/* Table 50 - Definition of (TPM_HANDLE) TPMI_RH_HIERARCHY_POLICY Type <IN> */
+
+TPM_RC
+TPMI_RH_HIERARCHY_POLICY_Unmarshal(TPMI_RH_HIERARCHY_POLICY *target, BYTE **buffer, INT32 *size)
+{
+ TPM_RC rc = TPM_RC_SUCCESS;
+ TPMI_RH_HIERARCHY_POLICY orig_target = *target; // libtpms added
+
+ if (rc == TPM_RC_SUCCESS) {
+ rc = TPM_HANDLE_Unmarshal(target, buffer, size);
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ switch (*target) {
+ case TPM_RH_OWNER:
+ case TPM_RH_PLATFORM:
+ case TPM_RH_ENDORSEMENT:
+ case TPM_RH_LOCKOUT:
+ break;
+ default:
+ {
+ BOOL isNotHP = (*target < TPM_RH_ACT_0) || (*target > TPM_RH_ACT_F);
+ if (isNotHP) {
+ rc = TPM_RC_VALUE;
+ *target = orig_target; // libtpms added
+ }
+ }
+ }
+ }
+ return rc;
+}
+
+/* Table 51 - Definition of (TPM_HANDLE) TPMI_RH_PLATFORM Type <IN> */
+
+TPM_RC
+TPMI_RH_PLATFORM_Unmarshal(TPMI_RH_PLATFORM *target, BYTE **buffer, INT32 *size)
+{
+ TPM_RC rc = TPM_RC_SUCCESS;
+ TPMI_RH_PLATFORM orig_target = *target; // libtpms added
+
+ if (rc == TPM_RC_SUCCESS) {
+ rc = TPM_HANDLE_Unmarshal(target, buffer, size);
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ switch (*target) {
+ case TPM_RH_PLATFORM:
+ break;
+ default:
+ rc = TPM_RC_VALUE;
+ *target = orig_target; // libtpms added
+ }
+ }
+ return rc;
+}
+
+/* Table 53 - Definition of (TPM_HANDLE) TPMI_RH_ENDORSEMENT Type <IN> */
+
+TPM_RC
+TPMI_RH_ENDORSEMENT_Unmarshal(TPMI_RH_ENDORSEMENT *target, BYTE **buffer, INT32 *size, BOOL allowNull)
+{
+ TPM_RC rc = TPM_RC_SUCCESS;
+ TPMI_RH_ENDORSEMENT orig_target = *target; // libtpms added
+
+ if (rc == TPM_RC_SUCCESS) {
+ rc = TPM_HANDLE_Unmarshal(target, buffer, size);
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ switch (*target) {
+ case TPM_RH_ENDORSEMENT:
+ break;
+ case TPM_RH_NULL:
+ if (allowNull) {
+ break;
+ }
+ default:
+ rc = TPM_RC_VALUE;
+ *target = orig_target; // libtpms added
+ }
+ }
+ return rc;
+}
+
+/* Table 54 - Definition of (TPM_HANDLE) TPMI_RH_PROVISION Type <IN> */
+
+TPM_RC
+TPMI_RH_PROVISION_Unmarshal(TPMI_RH_PROVISION *target, BYTE **buffer, INT32 *size)
+{
+ TPM_RC rc = TPM_RC_SUCCESS;
+ TPMI_RH_PROVISION orig_target = *target; // libtpms added
+
+ if (rc == TPM_RC_SUCCESS) {
+ rc = TPM_HANDLE_Unmarshal(target, buffer, size);
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ switch (*target) {
+ case TPM_RH_OWNER:
+ case TPM_RH_PLATFORM:
+ break;
+ default:
+ rc = TPM_RC_VALUE;
+ *target = orig_target; // libtpms added
+ }
+ }
+ return rc;
+}
+
+/* Table 55 - Definition of (TPM_HANDLE) TPMI_RH_CLEAR Type <IN> */
+
+TPM_RC
+TPMI_RH_CLEAR_Unmarshal(TPMI_RH_CLEAR *target, BYTE **buffer, INT32 *size)
+{
+ TPM_RC rc = TPM_RC_SUCCESS;
+ TPMI_RH_CLEAR orig_target = *target; // libtpms added
+
+ if (rc == TPM_RC_SUCCESS) {
+ rc = TPM_HANDLE_Unmarshal(target, buffer, size);
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ switch (*target) {
+ case TPM_RH_LOCKOUT:
+ case TPM_RH_PLATFORM:
+ break;
+ default:
+ rc = TPM_RC_VALUE;
+ *target = orig_target; // libtpms added
+ }
+ }
+ return rc;
+}
+
+/* Table 56 - Definition of (TPM_HANDLE) TPMI_RH_NV_AUTH Type <IN> */
+
+TPM_RC
+TPMI_RH_NV_AUTH_Unmarshal(TPMI_RH_NV_AUTH *target, BYTE **buffer, INT32 *size)
+{
+ TPM_RC rc = TPM_RC_SUCCESS;
+ TPMI_RH_NV_AUTH orig_target = *target; // libtpms added
+
+ if (rc == TPM_RC_SUCCESS) {
+ rc = TPM_HANDLE_Unmarshal(target, buffer, size);
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ switch (*target) {
+ case TPM_RH_OWNER:
+ case TPM_RH_PLATFORM:
+ break;
+ default:
+ {
+ BOOL isNotNv = (*target < NV_INDEX_FIRST) || (*target > NV_INDEX_LAST);
+ if (isNotNv) {
+ rc = TPM_RC_VALUE;
+ *target = orig_target; // libtpms added
+ }
+ }
+ }
+ }
+ return rc;
+}
+
+/* Table 57 - Definition of (TPM_HANDLE) TPMI_RH_LOCKOUT Type <IN> */
+
+TPM_RC
+TPMI_RH_LOCKOUT_Unmarshal(TPMI_RH_LOCKOUT *target, BYTE **buffer, INT32 *size)
+{
+ TPM_RC rc = TPM_RC_SUCCESS;
+ TPMI_RH_LOCKOUT orig_target = *target; // libtpms added
+
+ if (rc == TPM_RC_SUCCESS) {
+ rc = TPM_HANDLE_Unmarshal(target, buffer, size);
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ switch (*target) {
+ case TPM_RH_LOCKOUT:
+ break;
+ default:
+ rc = TPM_RC_VALUE;
+ *target = orig_target; // libtpms added
+ }
+ }
+ return rc;
+}
+
+/* Table 58 - Definition of (TPM_HANDLE) TPMI_RH_NV_INDEX Type <IN/OUT> */
+
+TPM_RC
+TPMI_RH_NV_INDEX_Unmarshal(TPMI_RH_NV_INDEX *target, BYTE **buffer, INT32 *size)
+{
+ TPM_RC rc = TPM_RC_SUCCESS;
+ TPMI_RH_NV_INDEX orig_target = *target; // libtpms added
+
+ if (rc == TPM_RC_SUCCESS) {
+ rc = TPM_HANDLE_Unmarshal(target, buffer, size);
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ BOOL isNotNv = (*target < NV_INDEX_FIRST) || (*target > NV_INDEX_LAST);
+ if (isNotNv) {
+ rc = TPM_RC_VALUE;
+ *target = orig_target; // libtpms added
+ }
+ }
+ return rc;
+}
+
+/* Table 64 - Definition of (TPM_HANDLE) TPMI_RH_AC Type <IN> */
+
+TPM_RC
+TPMI_RH_AC_Unmarshal(TPMI_RH_AC *target, BYTE **buffer, INT32 *size)
+{
+ TPM_RC rc = TPM_RC_SUCCESS;
+ TPMI_RH_AC orig_target = *target; // libtpms added
+
+ if (rc == TPM_RC_SUCCESS) {
+ rc = TPM_HANDLE_Unmarshal(target, buffer, size);
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ BOOL isNotAC = (*target < AC_FIRST) || (*target > AC_LAST);
+ if (isNotAC) {
+ rc = TPM_RC_VALUE;
+ *target = orig_target; // libtpms added
+ }
+ }
+ return rc;
+}
+
+/* Table 65 - Definition of (TPM_HANDLE) TPMI_RH_ACT Type <IN> */
+
+TPM_RC
+TPMI_RH_ACT_Unmarshal( TPMI_RH_ACT *target, BYTE **buffer, INT32 *size)
+{
+ TPM_RC rc = TPM_RC_SUCCESS;
+ TPMI_RH_ACT orig_target = *target; // libtpms added
+
+ if (rc == TPM_RC_SUCCESS) {
+ rc = TPM_HANDLE_Unmarshal(target, buffer, size);
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ BOOL isNotACT = (*target < TPM_RH_ACT_0) || (*target > TPM_RH_ACT_F);
+ if (isNotACT) {
+ rc = TPM_RC_VALUE;
+ *target = orig_target; // libtpms added
+ }
+ }
+ return rc;
+}
+
+/* Table 59 - Definition of (TPM_ALG_ID) TPMI_ALG_HASH Type */
+
+TPM_RC
+TPMI_ALG_HASH_Unmarshal(TPMI_ALG_HASH *target, BYTE **buffer, INT32 *size, BOOL allowNull)
+{
+ TPM_RC rc = TPM_RC_SUCCESS;
+ TPMI_ALG_HASH orig_target = *target; // libtpms added
+
+ if (rc == TPM_RC_SUCCESS) {
+ rc = TPM_ALG_ID_Unmarshal(target, buffer, size);
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ switch (*target) {
+#if ALG_SHA1
+ case TPM_ALG_SHA1:
+#endif
+#if ALG_SHA256
+ case TPM_ALG_SHA256:
+#endif
+#if ALG_SHA384
+ case TPM_ALG_SHA384:
+#endif
+#if ALG_SHA512
+ case TPM_ALG_SHA512:
+#endif
+#if ALG_SM3_256
+ case TPM_ALG_SM3_256:
+#endif
+ break;
+ case TPM_ALG_NULL:
+ if (allowNull) {
+ break;
+ }
+ default:
+ rc = TPM_RC_HASH;
+ *target = orig_target; // libtpms added
+ }
+ }
+ return rc;
+}
+
+/* Table 61 - Definition of (TPM_ALG_ID) TPMI_ALG_SYM Type */
+
+TPM_RC
+TPMI_ALG_SYM_Unmarshal(TPMI_ALG_SYM *target, BYTE **buffer, INT32 *size, BOOL allowNull)
+{
+ TPM_RC rc = TPM_RC_SUCCESS;
+ TPMI_ALG_SYM orig_target = *target; // libtpms added
+
+ if (rc == TPM_RC_SUCCESS) {
+ rc = TPM_ALG_ID_Unmarshal(target, buffer, size);
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ switch (*target) {
+#if ALG_AES
+ case TPM_ALG_AES:
+#endif
+#if ALG_SM4
+ case TPM_ALG_SM4:
+#endif
+#if ALG_CAMELLIA
+ case TPM_ALG_CAMELLIA:
+#endif
+#if ALG_TDES // libtpms added begin
+ case TPM_ALG_TDES:
+#endif // libtpms added end
+#if ALG_XOR
+ case TPM_ALG_XOR:
+#endif
+ break;
+ case TPM_ALG_NULL:
+ if (allowNull) {
+ break;
+ }
+ default:
+ rc = TPM_RC_SYMMETRIC;
+ *target = orig_target; // libtpms added
+ }
+ }
+ return rc;
+}
+
+/* Table 62 - Definition of (TPM_ALG_ID) TPMI_ALG_SYM_OBJECT Type */
+
+TPM_RC
+TPMI_ALG_SYM_OBJECT_Unmarshal(TPMI_ALG_SYM_OBJECT *target, BYTE **buffer, INT32 *size, BOOL allowNull)
+{
+ TPM_RC rc = TPM_RC_SUCCESS;
+ TPMI_ALG_SYM_OBJECT orig_target = *target; // libtpms added
+
+ if (rc == TPM_RC_SUCCESS) {
+ rc = TPM_ALG_ID_Unmarshal(target, buffer, size);
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ switch (*target) {
+#if ALG_AES
+ case TPM_ALG_AES:
+#endif
+#if ALG_SM4
+ case TPM_ALG_SM4:
+#endif
+#if ALG_CAMELLIA
+ case TPM_ALG_CAMELLIA:
+#endif
+#if ALG_TDES // libtpms added begin
+ case TPM_ALG_TDES:
+#endif // iibtpms added end
+ break;
+ case TPM_ALG_NULL:
+ if (allowNull) {
+ break;
+ }
+ default:
+ rc = TPM_RC_SYMMETRIC;
+ *target = orig_target; // libtpms added
+ }
+ }
+ return rc;
+}
+
+/* Table 63 - Definition of (TPM_ALG_ID) TPMI_ALG_SYM_MODE Type */
+
+TPM_RC
+TPMI_ALG_SYM_MODE_Unmarshal(TPMI_ALG_SYM_MODE *target, BYTE **buffer, INT32 *size, BOOL allowNull)
+{
+ TPM_RC rc = TPM_RC_SUCCESS;
+ TPMI_ALG_SYM_MODE orig_target = *target; // libtpms added
+
+ if (rc == TPM_RC_SUCCESS) {
+ rc = TPM_ALG_ID_Unmarshal(target, buffer, size);
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ switch (*target) {
+#if ALG_CTR
+ case TPM_ALG_CTR:
+#endif
+#if ALG_OFB
+ case TPM_ALG_OFB:
+#endif
+#if ALG_CBC
+ case TPM_ALG_CBC:
+#endif
+#if ALG_CFB
+ case TPM_ALG_CFB:
+#endif
+#if ALG_ECB
+ case TPM_ALG_ECB:
+#endif
+#if ALG_CMAC
+ case TPM_ALG_CMAC:
+#endif
+ break;
+ case TPM_ALG_NULL:
+ if (allowNull) {
+ break;
+ }
+ default:
+ rc = TPM_RC_MODE;
+ *target = orig_target; // libtpms added
+ }
+ }
+ return rc;
+}
+
+/* Table 64 - Definition of (TPM_ALG_ID) TPMI_ALG_KDF Type */
+
+TPM_RC
+TPMI_ALG_KDF_Unmarshal(TPMI_ALG_KDF *target, BYTE **buffer, INT32 *size, BOOL allowNull)
+{
+ TPM_RC rc = TPM_RC_SUCCESS;
+ TPMI_ALG_KDF orig_target = *target; // libtpms added
+
+ if (rc == TPM_RC_SUCCESS) {
+ rc = TPM_ALG_ID_Unmarshal(target, buffer, size);
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ switch (*target) {
+#if ALG_MGF1
+ case TPM_ALG_MGF1:
+#endif
+#if ALG_KDF1_SP800_56A
+ case TPM_ALG_KDF1_SP800_56A:
+#endif
+#if ALG_KDF2
+ case TPM_ALG_KDF2:
+#endif
+#if ALG_KDF1_SP800_108
+ case TPM_ALG_KDF1_SP800_108:
+#endif
+ break;
+ case TPM_ALG_NULL:
+ if (allowNull) {
+ break;
+ }
+ default:
+ rc = TPM_RC_KDF;
+ *target = orig_target; // libtpms added
+ }
+ }
+ return rc;
+}
+
+/* Table 65 - Definition of (TPM_ALG_ID) TPMI_ALG_SIG_SCHEME Type */
+
+TPM_RC
+TPMI_ALG_SIG_SCHEME_Unmarshal(TPMI_ALG_SIG_SCHEME *target, BYTE **buffer, INT32 *size, BOOL allowNull)
+{
+ TPM_RC rc = TPM_RC_SUCCESS;
+ TPMI_ALG_SIG_SCHEME orig_target = *target; // libtpms added
+
+ if (rc == TPM_RC_SUCCESS) {
+ rc = TPM_ALG_ID_Unmarshal(target, buffer, size);
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ switch (*target) {
+#if ALG_HMAC
+ case TPM_ALG_HMAC:
+#endif
+#if ALG_RSASSA
+ case TPM_ALG_RSASSA:
+#endif
+#if ALG_RSAPSS
+ case TPM_ALG_RSAPSS:
+#endif
+#if ALG_ECDSA
+ case TPM_ALG_ECDSA:
+#endif
+#if ALG_ECDAA
+ case TPM_ALG_ECDAA:
+#endif
+#if ALG_SM2
+ case TPM_ALG_SM2:
+#endif
+#if ALG_ECSCHNORR
+ case TPM_ALG_ECSCHNORR:
+#endif
+ break;
+ case TPM_ALG_NULL:
+ if (allowNull) {
+ break;
+ }
+ default:
+ rc = TPM_RC_SCHEME;
+ *target = orig_target; // libtpms added
+ }
+ }
+ return rc;
+}
+
+/* Table 66 - Definition of (TPM_ALG_ID) TPMI_ECC_KEY_EXCHANGE Type */
+
+TPM_RC
+TPMI_ECC_KEY_EXCHANGE_Unmarshal(TPMI_ECC_KEY_EXCHANGE *target, BYTE **buffer, INT32 *size, BOOL allowNull)
+{
+ TPM_RC rc = TPM_RC_SUCCESS;
+ TPMI_ECC_KEY_EXCHANGE orig_target = *target; // libtpms added
+
+ if (rc == TPM_RC_SUCCESS) {
+ rc = TPM_ALG_ID_Unmarshal(target, buffer, size);
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ switch (*target) {
+#if ALG_ECDH
+ case TPM_ALG_ECDH:
+#endif
+#if ALG_ECMQV
+ case TPM_ALG_ECMQV:
+#endif
+#if ALG_SM2
+ case TPM_ALG_SM2:
+#endif
+ break;
+ case TPM_ALG_NULL:
+ if (allowNull) {
+ break;
+ }
+ default:
+ rc = TPM_RC_SCHEME;
+ *target = orig_target; // libtpms added
+ }
+ }
+ return rc;
+}
+
+
+/* Table 67 - Definition of (TPM_ST) TPMI_ST_COMMAND_TAG Type */
+
+TPM_RC
+TPMI_ST_COMMAND_TAG_Unmarshal(TPMI_ST_COMMAND_TAG *target, BYTE **buffer, INT32 *size)
+{
+ TPM_RC rc = TPM_RC_SUCCESS;
+ TPMI_ST_COMMAND_TAG orig_target = *target; // libtpms added
+
+ if (rc == TPM_RC_SUCCESS) {
+ rc = TPM_ST_Unmarshal(target, buffer, size);
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ switch (*target) {
+ case TPM_ST_NO_SESSIONS:
+ case TPM_ST_SESSIONS:
+ break;
+ default:
+ rc = TPM_RC_BAD_TAG;
+ *target = orig_target; // libtpms added
+ }
+ }
+ return rc;
+}
+
+/* Table 70 TPMI_ALG_MAC_SCHEME */
+
+TPM_RC
+TPMI_ALG_MAC_SCHEME_Unmarshal(TPMI_ALG_MAC_SCHEME *target, BYTE **buffer, INT32 *size, BOOL allowNull)
+{
+ TPM_RC rc = TPM_RC_SUCCESS;
+ TPMI_ALG_MAC_SCHEME orig_target = *target; // libtpms added
+
+ if (rc == TPM_RC_SUCCESS) {
+ rc = TPM_ALG_ID_Unmarshal(target, buffer, size);
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ switch (*target) {
+#if ALG_SHA1
+ case TPM_ALG_SHA1:
+#endif
+#if ALG_SHA256
+ case TPM_ALG_SHA256:
+#endif
+#if ALG_SHA384
+ case TPM_ALG_SHA384:
+#endif
+#if ALG_SHA512
+ case TPM_ALG_SHA512:
+#endif
+#if ALG_SM3_256
+ case TPM_ALG_SM3_256:
+#endif
+#if ALG_CMAC
+ case TPM_ALG_CMAC:
+#endif
+ break;
+ case TPM_ALG_NULL:
+ if (allowNull) {
+ break;
+ }
+ default:
+ rc = TPM_RC_SYMMETRIC;
+ *target = orig_target; // libtpms added
+ }
+ }
+ return rc;
+}
+
+/* Table 70 TPMI_ALG_CIPHER_MODE */
+
+TPM_RC
+TPMI_ALG_CIPHER_MODE_Unmarshal(TPMI_ALG_CIPHER_MODE*target, BYTE **buffer, INT32 *size, BOOL allowNull)
+{
+ TPM_RC rc = TPM_RC_SUCCESS;
+ TPMI_ALG_CIPHER_MODE orig_target = *target; // libtpms added
+
+ if (rc == TPM_RC_SUCCESS) {
+ rc = TPM_ALG_ID_Unmarshal(target, buffer, size);
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ switch (*target) {
+#if ALG_CTR
+ case TPM_ALG_CTR:
+#endif
+#if ALG_OFB
+ case TPM_ALG_OFB:
+#endif
+#if ALG_CBC
+ case TPM_ALG_CBC:
+#endif
+#if ALG_CFB
+ case TPM_ALG_CFB:
+#endif
+#if ALG_ECB
+ case TPM_ALG_ECB:
+#endif
+ break;
+ case TPM_ALG_NULL:
+ if (allowNull) {
+ break;
+ }
+ default:
+ rc = TPM_RC_MODE;
+ *target = orig_target; // libtpms added
+ }
+ }
+ return rc;
+}
+
+/* Table 68 - Definition of TPMS_EMPTY Structure <IN/OUT> */
+
+TPM_RC
+TPMS_EMPTY_Unmarshal(TPMS_EMPTY *target, BYTE **buffer, INT32 *size)
+{
+ TPM_RC rc = TPM_RC_SUCCESS;
+ target = target;
+ buffer = buffer;
+ size = size;
+ return rc;
+}
+
+/* Table 70 - Definition of TPMU_HA Union <IN/OUT, S> */
+
+TPM_RC
+TPMU_HA_Unmarshal(TPMU_HA *target, BYTE **buffer, INT32 *size, UINT32 selector)
+{
+ TPM_RC rc = TPM_RC_SUCCESS;
+
+ switch (selector) {
+#if ALG_SHA1
+ case TPM_ALG_SHA1:
+ rc = Array_Unmarshal(target->sha1, SHA1_DIGEST_SIZE, buffer, size);
+ break;
+#endif
+#if ALG_SHA256
+ case TPM_ALG_SHA256:
+ rc = Array_Unmarshal(target->sha256, SHA256_DIGEST_SIZE, buffer, size);
+ break;
+#endif
+#if ALG_SHA384
+ case TPM_ALG_SHA384:
+ rc = Array_Unmarshal(target->sha384, SHA384_DIGEST_SIZE, buffer, size);
+ break;
+#endif
+#if ALG_SHA512
+ case TPM_ALG_SHA512:
+ rc = Array_Unmarshal(target->sha512, SHA512_DIGEST_SIZE, buffer, size);
+ break;
+#endif
+#if ALG_SM3_256
+ case TPM_ALG_SM3_256:
+ rc = Array_Unmarshal(target->sm3_256, SM3_256_DIGEST_SIZE, buffer, size);
+ break;
+#endif
+ case TPM_ALG_NULL:
+ break;
+ default:
+ rc = TPM_RC_SELECTOR;
+ }
+ return rc;
+}
+
+/* Table 71 - Definition of TPMT_HA Structure <IN/OUT> */
+
+TPM_RC
+TPMT_HA_Unmarshal(TPMT_HA *target, BYTE **buffer, INT32 *size, BOOL allowNull)
+{
+ TPM_RC rc = TPM_RC_SUCCESS;
+
+ if (rc == TPM_RC_SUCCESS) {
+ rc = TPMI_ALG_HASH_Unmarshal(&target->hashAlg, buffer, size, allowNull);
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ rc = TPMU_HA_Unmarshal(&target->digest, buffer, size, target->hashAlg);
+ }
+ return rc;
+}
+
+/* Table 72 - Definition of TPM2B_DIGEST Structure */
+
+TPM_RC
+TPM2B_DIGEST_Unmarshal(TPM2B_DIGEST *target, BYTE **buffer, INT32 *size)
+{
+ TPM_RC rc = TPM_RC_SUCCESS;
+
+ if (rc == TPM_RC_SUCCESS) {
+ rc = TPM2B_Unmarshal(&target->b, sizeof(TPMU_HA), buffer, size);
+ }
+ return rc;
+}
+
+/* Table 73 - Definition of TPM2B_DATA Structure */
+
+TPM_RC
+TPM2B_DATA_Unmarshal(TPM2B_DATA *target, BYTE **buffer, INT32 *size)
+{
+ TPM_RC rc = TPM_RC_SUCCESS;
+
+ if (rc == TPM_RC_SUCCESS) {
+ rc = TPM2B_Unmarshal(&target->b, sizeof(TPMT_HA), buffer, size);
+ }
+ return rc;
+}
+
+/* Table 74 - Definition of Types for TPM2B_NONCE */
+
+TPM_RC
+TPM2B_NONCE_Unmarshal(TPM2B_NONCE *target, BYTE **buffer, INT32 *size)
+{
+ TPM_RC rc = TPM_RC_SUCCESS;
+
+ if (rc == TPM_RC_SUCCESS) {
+ rc = TPM2B_DIGEST_Unmarshal(target, buffer, size);
+ }
+ return rc;
+}
+
+/* Table 75 - Definition of Types for TPM2B_AUTH */
+
+TPM_RC
+TPM2B_AUTH_Unmarshal(TPM2B_AUTH *target, BYTE **buffer, INT32 *size)
+{
+ TPM_RC rc = TPM_RC_SUCCESS;
+
+ if (rc == TPM_RC_SUCCESS) {
+ rc = TPM2B_DIGEST_Unmarshal(target, buffer, size);
+ }
+ return rc;
+}
+
+/* Table 77 - Definition of TPM2B_EVENT Structure */
+
+TPM_RC
+TPM2B_EVENT_Unmarshal(TPM2B_EVENT *target, BYTE **buffer, INT32 *size)
+{
+ TPM_RC rc = TPM_RC_SUCCESS;
+
+ if (rc == TPM_RC_SUCCESS) {
+ rc = TPM2B_Unmarshal(&target->b, sizeof(TPM2B_EVENT) - sizeof(UINT16), buffer, size);
+ }
+ return rc;
+}
+
+/* Table 78 - Definition of TPM2B_MAX_BUFFER Structure */
+
+TPM_RC
+TPM2B_MAX_BUFFER_Unmarshal(TPM2B_MAX_BUFFER *target, BYTE **buffer, INT32 *size)
+{
+ TPM_RC rc = TPM_RC_SUCCESS;
+
+ if (rc == TPM_RC_SUCCESS) {
+ rc = TPM2B_Unmarshal(&target->b, MAX_DIGEST_BUFFER, buffer, size);
+ }
+ return rc;
+}
+
+/* Table 79 - Definition of TPM2B_MAX_NV_BUFFER Structure */
+
+TPM_RC
+TPM2B_MAX_NV_BUFFER_Unmarshal(TPM2B_MAX_NV_BUFFER *target, BYTE **buffer, INT32 *size)
+{
+ TPM_RC rc = TPM_RC_SUCCESS;
+
+ if (rc == TPM_RC_SUCCESS) {
+ rc = TPM2B_Unmarshal(&target->b, MAX_NV_BUFFER_SIZE, buffer, size);
+ }
+ return rc;
+}
+
+/* Table 80 - Definition of TPM2B_TIMEOUT Structure <IN/OUT> */
+
+TPM_RC
+TPM2B_TIMEOUT_Unmarshal(TPM2B_TIMEOUT *target, BYTE **buffer, INT32 *size)
+{
+ TPM_RC rc = TPM_RC_SUCCESS;
+
+ if (rc == TPM_RC_SUCCESS) {
+ rc = TPM2B_Unmarshal(&target->b, sizeof(target->t.buffer), buffer, size);
+ }
+ return rc;
+}
+
+/* Table 81 - Definition of TPM2B_IV Structure <IN/OUT> */
+
+TPM_RC
+TPM2B_IV_Unmarshal(TPM2B_IV *target, BYTE **buffer, INT32 *size)
+{
+ TPM_RC rc = TPM_RC_SUCCESS;
+
+ if (rc == TPM_RC_SUCCESS) {
+ rc = TPM2B_Unmarshal(&target->b, MAX_SYM_BLOCK_SIZE, buffer, size);
+ }
+ return rc;
+}
+
+/* Table 83 - Definition of TPM2B_NAME Structure */
+
+TPM_RC
+TPM2B_NAME_Unmarshal(TPM2B_NAME *target, BYTE **buffer, INT32 *size)
+{
+ TPM_RC rc = TPM_RC_SUCCESS;
+
+ if (rc == TPM_RC_SUCCESS) {
+ rc = TPM2B_Unmarshal(&target->b, sizeof(TPMU_NAME), buffer, size);
+ }
+ return rc;
+}
+
+/* Table 85 - Definition of TPMS_PCR_SELECTION Structure */
+
+TPM_RC
+TPMS_PCR_SELECTION_Unmarshal(TPMS_PCR_SELECTION *target, BYTE **buffer, INT32 *size)
+{
+ TPM_RC rc = TPM_RC_SUCCESS;
+
+ if (rc == TPM_RC_SUCCESS) {
+ rc = TPMI_ALG_HASH_Unmarshal(&target->hash, buffer, size, NO);
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ rc = UINT8_Unmarshal(&target->sizeofSelect, buffer, size);
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ if ((target->sizeofSelect < PCR_SELECT_MIN) ||
+ (target->sizeofSelect > PCR_SELECT_MAX)) {
+ rc = TPM_RC_VALUE;
+ target->sizeofSelect = 0; // libtpms added
+ }
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ rc = Array_Unmarshal(target->pcrSelect, target->sizeofSelect, buffer, size);
+ }
+ return rc;
+}
+
+/* Table 88 - Definition of TPMT_TK_CREATION Structure */
+
+TPM_RC
+TPMT_TK_CREATION_Unmarshal(TPMT_TK_CREATION *target, BYTE **buffer, INT32 *size)
+{
+ TPM_RC rc = TPM_RC_SUCCESS;
+ TPM_ST orig_tag = target->tag; // libtpms added
+
+ if (rc == TPM_RC_SUCCESS) {
+ rc = TPM_ST_Unmarshal(&target->tag, buffer, size);
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ if (target->tag != TPM_ST_CREATION) {
+ rc = TPM_RC_TAG;
+ target->tag = orig_tag; // libtpms added
+ }
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ rc = TPMI_RH_HIERARCHY_Unmarshal(&target->hierarchy, buffer, size, YES);
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ rc = TPM2B_DIGEST_Unmarshal(&target->digest, buffer, size);
+ }
+ return rc;
+}
+
+/* Table 89 - Definition of TPMT_TK_VERIFIED Structure */
+
+TPM_RC
+TPMT_TK_VERIFIED_Unmarshal(TPMT_TK_VERIFIED *target, BYTE **buffer, INT32 *size)
+{
+ TPM_RC rc = TPM_RC_SUCCESS;
+ TPM_ST orig_tag = target->tag; // libtpms added
+
+ if (rc == TPM_RC_SUCCESS) {
+ rc = TPM_ST_Unmarshal(&target->tag, buffer, size);
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ if (target->tag != TPM_ST_VERIFIED) {
+ rc = TPM_RC_TAG;
+ target->tag = orig_tag; // libtpms added
+ }
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ rc = TPMI_RH_HIERARCHY_Unmarshal(&target->hierarchy, buffer, size, YES);
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ rc = TPM2B_DIGEST_Unmarshal(&target->digest, buffer, size);
+ }
+ return rc;
+}
+
+/* Table 90 - Definition of TPMT_TK_AUTH Structure */
+
+TPM_RC
+TPMT_TK_AUTH_Unmarshal(TPMT_TK_AUTH *target, BYTE **buffer, INT32 *size)
+{
+ TPM_RC rc = TPM_RC_SUCCESS;
+ TPM_ST orig_tag = target->tag; // libtpms added
+
+ if (rc == TPM_RC_SUCCESS) {
+ rc = TPM_ST_Unmarshal(&target->tag, buffer, size);
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ if ((target->tag != TPM_ST_AUTH_SIGNED) &&
+ (target->tag != TPM_ST_AUTH_SECRET)) {
+ rc = TPM_RC_TAG;
+ target->tag = orig_tag; // libtpms added
+ }
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ rc = TPMI_RH_HIERARCHY_Unmarshal(&target->hierarchy, buffer, size, YES);
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ rc = TPM2B_DIGEST_Unmarshal(&target->digest, buffer, size);
+ }
+ return rc;
+}
+
+/* Table 91 - Definition of TPMT_TK_HASHCHECK Structure */
+
+TPM_RC
+TPMT_TK_HASHCHECK_Unmarshal(TPMT_TK_HASHCHECK *target, BYTE **buffer, INT32 *size)
+{
+ TPM_RC rc = TPM_RC_SUCCESS;
+ TPM_ST orig_tag = target->tag; // libtpms added
+
+ if (rc == TPM_RC_SUCCESS) {
+ rc = TPM_ST_Unmarshal(&target->tag, buffer, size);
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ if (target->tag != TPM_ST_HASHCHECK) {
+ rc = TPM_RC_TAG;
+ target->tag = orig_tag; // libtpms added
+ }
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ rc = TPMI_RH_HIERARCHY_Unmarshal(&target->hierarchy, buffer, size, YES);
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ rc = TPM2B_DIGEST_Unmarshal(&target->digest, buffer, size);
+ }
+ return rc;
+}
+
+/* Table 92 - Definition of TPMS_ALG_PROPERTY Structure <OUT> */
+
+#if 0 // libtpms added
+TPM_RC
+TPMS_ALG_PROPERTY_Unmarshal(TPMS_ALG_PROPERTY *target, BYTE **buffer, INT32 *size)
+{
+ TPM_RC rc = TPM_RC_SUCCESS;
+
+ if (rc == TPM_RC_SUCCESS) {
+ rc = TPM_ALG_ID_Unmarshal(&target->alg, buffer, size);
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ rc = TPMA_ALGORITHM_Unmarshal(&target->algProperties, buffer, size);
+ }
+ return rc;
+}
+#endif // libtpms added
+
+/* Table 93 - Definition of TPMS_TAGGED_PROPERTY Structure <OUT> */
+
+#if 0 // libtpms added
+TPM_RC
+TPMS_TAGGED_PROPERTY_Unmarshal(TPMS_TAGGED_PROPERTY *target, BYTE **buffer, INT32 *size)
+{
+ TPM_RC rc = TPM_RC_SUCCESS;
+
+ if (rc == TPM_RC_SUCCESS) {
+ rc = TPM_PT_Unmarshal(&target->property, buffer, size);
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ rc = UINT32_Unmarshal(&target->value, buffer, size);
+ }
+ return rc;
+}
+#endif // libtpms added
+
+/* Table 94 - Definition of TPMS_TAGGED_PCR_SELECT Structure <OUT> */
+
+#if 0 // libtpms added
+TPM_RC
+TPMS_TAGGED_PCR_SELECT_Unmarshal(TPMS_TAGGED_PCR_SELECT *target, BYTE **buffer, INT32 *size)
+{
+ TPM_RC rc = TPM_RC_SUCCESS;
+
+ if (rc == TPM_RC_SUCCESS) {
+ rc = TPM_PT_PCR_Unmarshal(&target->tag, buffer, size);
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ rc = UINT8_Unmarshal(&target->sizeofSelect, buffer, size);
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ rc = Array_Unmarshal(target->pcrSelect, target->sizeofSelect, buffer, size);
+ }
+ return rc;
+}
+#endif // libtpms added
+
+/* Table 95 - Definition of TPML_CC Structure */
+
+TPM_RC
+TPML_CC_Unmarshal(TPML_CC *target, BYTE **buffer, INT32 *size)
+{
+ TPM_RC rc = TPM_RC_SUCCESS;
+
+ UINT32 i;
+ if (rc == TPM_RC_SUCCESS) {
+ rc = UINT32_Unmarshal(&target->count, buffer, size);
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ if (target->count > MAX_CAP_CC) {
+ rc = TPM_RC_SIZE;
+ target->count = 0; // libtpms added
+ }
+ }
+ for (i = 0 ; (rc == TPM_RC_SUCCESS) && (i < target->count) ; i++) {
+ rc = TPM_CC_Unmarshal(&target->commandCodes[i], buffer, size);
+ }
+ return rc;
+}
+
+/* Table 2:96 - Definition of TPMS_TAGGED_POLICY Structure (StructuresTable()) */
+
+#if 0 // libtpms added
+TPM_RC
+TPMS_TAGGED_POLICY_Unmarshal(TPMS_TAGGED_POLICY *target, BYTE **buffer, INT32 *size)
+{
+ TPM_RC rc = TPM_RC_SUCCESS;
+ if (rc == TPM_RC_SUCCESS) {
+ rc = TPM_HANDLE_Unmarshal(&target->handle, buffer, size);
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ rc = TPMT_HA_Unmarshal(&target->policyHash, buffer, size, NO);
+ }
+ return rc;
+}
+#endif // libtpms added
+
+/* Table 96 - Definition of TPML_CCA Structure <OUT> */
+
+#if 0 // libtpms added
+TPM_RC
+TPML_CCA_Unmarshal(TPML_CCA *target, BYTE **buffer, INT32 *size)
+{
+ TPM_RC rc = TPM_RC_SUCCESS;
+
+ UINT32 i;
+ if (rc == TPM_RC_SUCCESS) {
+ rc = UINT32_Unmarshal(&target->count, buffer, size);
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ if (target->count > MAX_CAP_CC) {
+ rc = TPM_RC_SIZE;
+ target->count = 0; // libtpms added
+ }
+ }
+ for (i = 0 ; (rc == TPM_RC_SUCCESS) && (i < target->count) ; i++) {
+ rc = TPMA_CC_Unmarshal(&target->commandAttributes[i], buffer, size);
+ }
+ return rc;
+}
+#endif // libtpms added
+
+/* Table 97 - Definition of TPML_ALG Structure */
+
+TPM_RC
+TPML_ALG_Unmarshal(TPML_ALG *target, BYTE **buffer, INT32 *size)
+{
+ TPM_RC rc = TPM_RC_SUCCESS;
+
+ UINT32 i;
+ if (rc == TPM_RC_SUCCESS) {
+ rc = UINT32_Unmarshal(&target->count, buffer, size);
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ if (target->count > MAX_ALG_LIST_SIZE) {
+ rc = TPM_RC_SIZE;
+ target->count = 0; // libtpms added
+ }
+ }
+ for (i = 0 ; (rc == TPM_RC_SUCCESS) && (i < target->count) ; i++) {
+ rc = TPM_ALG_ID_Unmarshal(&target->algorithms[i], buffer, size);
+ }
+ return rc;
+}
+
+/* Table 98 - Definition of TPML_HANDLE Structure <OUT> */
+
+#if 0 // libtpms added
+TPM_RC
+TPML_HANDLE_Unmarshal(TPML_HANDLE *target, BYTE **buffer, INT32 *size)
+{
+ TPM_RC rc = TPM_RC_SUCCESS;
+
+ UINT32 i;
+ if (rc == TPM_RC_SUCCESS) {
+ rc = UINT32_Unmarshal(&target->count, buffer, size);
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ if (target->count > MAX_CAP_HANDLES) {
+ rc = TPM_RC_SIZE;
+ target->count = 0; // libtpms added
+ }
+ }
+ for (i = 0 ; (rc == TPM_RC_SUCCESS) && (i < target->count) ; i++) {
+ rc = TPM_HANDLE_Unmarshal(&target->handle[i], buffer, size);
+ }
+ return rc;
+}
+#endif // libtpms added
+
+/* Table 99 - Definition of TPML_DIGEST Structure */
+
+/* PolicyOr has a restriction of at least a count of two. This function is also used to unmarshal
+ PCR_Read, where a count of one is permitted.
+*/
+
+TPM_RC
+TPML_DIGEST_Unmarshal(TPML_DIGEST *target, BYTE **buffer, INT32 *size)
+{
+ TPM_RC rc = TPM_RC_SUCCESS;
+
+ UINT32 i;
+ if (rc == TPM_RC_SUCCESS) {
+ rc = UINT32_Unmarshal(&target->count, buffer, size);
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ /* TPM side is hard coded to 2 minimum */
+ if (target->count < 2) {
+ rc = TPM_RC_SIZE;
+ target->count = 0; // libtpms added
+ }
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ if (target->count > 8) {
+ rc = TPM_RC_SIZE;
+ target->count = 0; // libtpms added
+ }
+ }
+ for (i = 0 ; (rc == TPM_RC_SUCCESS) && (i < target->count) ; i++) {
+ rc = TPM2B_DIGEST_Unmarshal(&target->digests[i], buffer, size);
+ }
+ return rc;
+}
+
+/* Table 100 - Definition of TPML_DIGEST_VALUES Structure */
+
+TPM_RC
+TPML_DIGEST_VALUES_Unmarshal(TPML_DIGEST_VALUES *target, BYTE **buffer, INT32 *size)
+{
+ TPM_RC rc = TPM_RC_SUCCESS;
+
+ UINT32 i;
+ if (rc == TPM_RC_SUCCESS) {
+ rc = UINT32_Unmarshal(&target->count, buffer, size);
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ if (target->count > HASH_COUNT) {
+ rc = TPM_RC_SIZE;
+ target->count = 0; // libtpms added
+ }
+ }
+ for (i = 0 ; (rc == TPM_RC_SUCCESS) && (i < target->count) ; i++) {
+ rc = TPMT_HA_Unmarshal(&target->digests[i], buffer, size, NO);
+ }
+ return rc;
+}
+
+/* Table 102 - Definition of TPML_PCR_SELECTION Structure */
+
+TPM_RC
+TPML_PCR_SELECTION_Unmarshal(TPML_PCR_SELECTION *target, BYTE **buffer, INT32 *size)
+{
+ TPM_RC rc = TPM_RC_SUCCESS;
+
+ UINT32 i;
+ if (rc == TPM_RC_SUCCESS) {
+ rc = UINT32_Unmarshal(&target->count, buffer, size);
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ if (target->count > HASH_COUNT) {
+ rc = TPM_RC_SIZE;
+ target->count = 0; // libtpms added
+ }
+ }
+ for (i = 0 ; (rc == TPM_RC_SUCCESS) && (i < target->count) ; i++) {
+ rc = TPMS_PCR_SELECTION_Unmarshal(&target->pcrSelections[i], buffer, size);
+ }
+ return rc;
+}
+
+
+#if 0
+
+/* Table 103 - Definition of TPML_ALG_PROPERTY Structure <OUT> */
+
+TPM_RC
+TPML_ALG_PROPERTY_Unmarshal(TPML_ALG_PROPERTY *target, BYTE **buffer, INT32 *size)
+{
+ TPM_RC rc = TPM_RC_SUCCESS;
+
+ UINT32 i;
+ if (rc == TPM_RC_SUCCESS) {
+ rc = UINT32_Unmarshal(&target->count, buffer, size);
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ if (target->count > MAX_CAP_ALGS) {
+ rc = TPM_RC_SIZE;
+ target->count = 0; // libtpms added
+ }
+ }
+ for (i = 0 ; (rc == TPM_RC_SUCCESS) && (i < target->count) ; i++) {
+ rc = TPMS_ALG_PROPERTY_Unmarshal(&target->algProperties[i], buffer, size);
+ }
+ return rc;
+}
+
+/* Table 104 - Definition of TPML_TAGGED_TPM_PROPERTY Structure <OUT> */
+
+TPM_RC
+TPML_TAGGED_TPM_PROPERTY_Unmarshal(TPML_TAGGED_TPM_PROPERTY *target, BYTE **buffer, INT32 *size)
+{
+ TPM_RC rc = TPM_RC_SUCCESS;
+
+ UINT32 i;
+ if (rc == TPM_RC_SUCCESS) {
+ rc = UINT32_Unmarshal(&target->count, buffer, size);
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ if (target->count > MAX_TPM_PROPERTIES) {
+ rc = TPM_RC_SIZE;
+ target->count = 0; // libtpms added
+ }
+ }
+ for (i = 0 ; (rc == TPM_RC_SUCCESS) && (i < target->count) ; i++) {
+ rc = TPMS_TAGGED_PROPERTY_Unmarshal(&target->tpmProperty[i], buffer, size);
+ }
+ return rc;
+}
+
+/* Table 105 - Definition of TPML_TAGGED_PCR_PROPERTY Structure <OUT> */
+
+TPM_RC
+TPML_TAGGED_PCR_PROPERTY_Unmarshal(TPML_TAGGED_PCR_PROPERTY *target, BYTE **buffer, INT32 *size)
+{
+ TPM_RC rc = TPM_RC_SUCCESS;
+
+ UINT32 i;
+ if (rc == TPM_RC_SUCCESS) {
+ rc = UINT32_Unmarshal(&target->count, buffer, size);
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ if (target->count > MAX_PCR_PROPERTIES) {
+ rc = TPM_RC_SIZE;
+ target->count = 0; // libtpms added
+ }
+ }
+ for (i = 0 ; (rc == TPM_RC_SUCCESS) && (i < target->count) ; i++) {
+ rc = TPMS_TAGGED_PCR_SELECT_Unmarshal(&target->pcrProperty[i], buffer, size);
+ }
+ return rc;
+}
+
+/* Table 106 - Definition of {ECC} TPML_ECC_CURVE Structure <OUT> */
+
+TPM_RC
+TPML_ECC_CURVE_Unmarshal(TPML_ECC_CURVE *target, BYTE **buffer, INT32 *size)
+{
+ TPM_RC rc = TPM_RC_SUCCESS;
+
+ UINT32 i;
+ if (rc == TPM_RC_SUCCESS) {
+ rc = UINT32_Unmarshal(&target->count, buffer, size);
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ if (target->count > MAX_ECC_CURVES) {
+ rc = TPM_RC_SIZE;
+ target->count = 0; // libtpms added
+ }
+ }
+ for (i = 0 ; (rc == TPM_RC_SUCCESS) && (i < target->count) ; i++) {
+ rc = TPM_ECC_CURVE_Unmarshal(&target->eccCurves[i], buffer, size);
+ }
+ return rc;
+}
+
+/* Table 2:109 - Definition of TPML_TAGGED_POLICY Structure (StructuresTable()) */
+
+TPM_RC
+TPML_TAGGED_POLICY_Unmarshal(TPML_TAGGED_POLICY *target, BYTE **buffer, INT32 *size)
+{
+ TPM_RC rc = TPM_RC_SUCCESS;
+
+ UINT32 i;
+ if (rc == TPM_RC_SUCCESS) {
+ rc = UINT32_Unmarshal(&target->count, buffer, size);
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ if (target->count > MAX_TAGGED_POLICIES) {
+ rc = TPM_RC_SIZE;
+ target->count = 0; // libtpms added
+ }
+ }
+ for (i = 0 ; (rc == TPM_RC_SUCCESS) && (i < target->count) ; i++) {
+ rc = TPMS_TAGGED_POLICY_Unmarshal(&target->policies[i], buffer, size);
+ }
+ return rc;
+}
+
+/* Table 2:110 - Definition of TPMU_CAPABILITIES Union (StructuresTable()) */
+
+TPM_RC
+TPMU_CAPABILITIES_Unmarshal(TPMU_CAPABILITIES *target, BYTE **buffer, INT32 *size, UINT32 selector)
+{
+ TPM_RC rc = TPM_RC_SUCCESS;
+
+ switch (selector) {
+ case TPM_CAP_ALGS:
+ rc = TPML_ALG_PROPERTY_Unmarshal(&target->algorithms, buffer, size);
+ break;
+ case TPM_CAP_HANDLES:
+ rc = TPML_HANDLE_Unmarshal(&target->handles, buffer, size);
+ break;
+ case TPM_CAP_COMMANDS:
+ rc = TPML_CCA_Unmarshal(&target->command, buffer, size);
+ break;
+ case TPM_CAP_PP_COMMANDS:
+ rc = TPML_CC_Unmarshal(&target->ppCommands, buffer, size);
+ break;
+ case TPM_CAP_AUDIT_COMMANDS:
+ rc = TPML_CC_Unmarshal(&target->auditCommands, buffer, size);
+ break;
+ case TPM_CAP_PCRS:
+ rc = TPML_PCR_SELECTION_Unmarshal(&target->assignedPCR, buffer, size);
+ break;
+ case TPM_CAP_TPM_PROPERTIES:
+ rc = TPML_TAGGED_TPM_PROPERTY_Unmarshal(&target->tpmProperties, buffer, size);
+ break;
+ case TPM_CAP_PCR_PROPERTIES:
+ rc = TPML_TAGGED_PCR_PROPERTY_Unmarshal(&target->pcrProperties, buffer, size);
+ break;
+ case TPM_CAP_ECC_CURVES:
+ rc = TPML_ECC_CURVE_Unmarshal(&target->eccCurves, buffer, size);
+ break;
+ case TPM_CAP_AUTH_POLICIES:
+ rc = TPML_TAGGED_POLICY_Unmarshal(&target->authPolicies, buffer, size);
+ break;
+ default:
+ rc = TPM_RC_SELECTOR;
+ }
+ return rc;
+}
+
+/* Table 2:111 - Definition of TPMS_CAPABILITY_DATA Structure (StructuresTable()) */
+
+TPM_RC
+TPMS_CAPABILITY_DATA_Unmarshal(TPMS_CAPABILITY_DATA *target, BYTE **buffer, INT32 *size)
+{
+ TPM_RC rc = TPM_RC_SUCCESS;
+
+ if (rc == TPM_RC_SUCCESS) {
+ rc = TPM_CAP_Unmarshal(&target->capability, buffer, size);
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ rc = TPMU_CAPABILITIES_Unmarshal(&target->data, buffer, size, target->capability);
+ }
+ return rc;
+}
+
+/* Table 109 - Definition of TPMS_CLOCK_INFO Structure */
+
+TPM_RC
+TPMS_CLOCK_INFO_Unmarshal(TPMS_CLOCK_INFO *target, BYTE **buffer, INT32 *size)
+{
+ TPM_RC rc = TPM_RC_SUCCESS;
+
+ if (rc == TPM_RC_SUCCESS) {
+ rc = UINT64_Unmarshal(&target->clock, buffer, size);
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ rc = UINT32_Unmarshal(&target->resetCount, buffer, size);
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ rc = UINT32_Unmarshal(&target->restartCount, buffer, size);
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ rc = TPMI_YES_NO_Unmarshal(&target->safe, buffer, size);
+ }
+ return rc;
+}
+
+/* Table 110 - Definition of TPMS_TIME_INFO Structure */
+
+TPM_RC
+TPMS_TIME_INFO_Unmarshal(TPMS_TIME_INFO *target, BYTE **buffer, INT32 *size)
+{
+ TPM_RC rc = TPM_RC_SUCCESS;
+
+ if (rc == TPM_RC_SUCCESS) {
+ rc = UINT64_Unmarshal(&target->time, buffer, size);
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ rc = TPMS_CLOCK_INFO_Unmarshal(&target->clockInfo, buffer, size);
+ }
+ return rc;
+}
+
+/* Table 111 - Definition of TPMS_TIME_ATTEST_INFO Structure <OUT> */
+
+TPM_RC
+TPMS_TIME_ATTEST_INFO_Unmarshal(TPMS_TIME_ATTEST_INFO *target, BYTE **buffer, INT32 *size)
+{
+ TPM_RC rc = TPM_RC_SUCCESS;
+
+ if (rc == TPM_RC_SUCCESS) {
+ rc = TPMS_TIME_INFO_Unmarshal(&target->time, buffer, size);
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ rc = UINT64_Unmarshal(&target->firmwareVersion, buffer, size);
+ }
+ return rc;
+}
+
+/* Table 112 - Definition of TPMS_CERTIFY_INFO Structure <OUT> */
+
+TPM_RC
+TPMS_CERTIFY_INFO_Unmarshal(TPMS_CERTIFY_INFO *target, BYTE **buffer, INT32 *size)
+{
+ TPM_RC rc = TPM_RC_SUCCESS;
+
+ if (rc == TPM_RC_SUCCESS) {
+ rc = TPM2B_NAME_Unmarshal(&target->name, buffer, size);
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ rc = TPM2B_NAME_Unmarshal(&target->qualifiedName, buffer, size);
+ }
+ return rc;
+}
+
+/* Table 113 - Definition of TPMS_QUOTE_INFO Structure <OUT> */
+
+TPM_RC
+TPMS_QUOTE_INFO_Unmarshal(TPMS_QUOTE_INFO *target, BYTE **buffer, INT32 *size)
+{
+ TPM_RC rc = TPM_RC_SUCCESS;
+
+ if (rc == TPM_RC_SUCCESS) {
+ rc = TPML_PCR_SELECTION_Unmarshal(&target->pcrSelect, buffer, size);
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ rc = TPM2B_DIGEST_Unmarshal(&target->pcrDigest, buffer, size);
+ }
+ return rc;
+}
+
+/* Table 114 - Definition of TPMS_COMMAND_AUDIT_INFO Structure <OUT> */
+
+TPM_RC
+TPMS_COMMAND_AUDIT_INFO_Unmarshal(TPMS_COMMAND_AUDIT_INFO *target, BYTE **buffer, INT32 *size)
+{
+ TPM_RC rc = TPM_RC_SUCCESS;
+
+ if (rc == TPM_RC_SUCCESS) {
+ rc = UINT64_Unmarshal(&target->auditCounter, buffer, size);
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ rc = TPM_ALG_ID_Unmarshal(&target->digestAlg, buffer, size);
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ rc = TPM2B_DIGEST_Unmarshal(&target->auditDigest, buffer, size);
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ rc = TPM2B_DIGEST_Unmarshal(&target->commandDigest, buffer, size);
+ }
+ return rc;
+}
+
+/* Table 115 - Definition of TPMS_SESSION_AUDIT_INFO Structure <OUT> */
+
+TPM_RC
+TPMS_SESSION_AUDIT_INFO_Unmarshal(TPMS_SESSION_AUDIT_INFO *target, BYTE **buffer, INT32 *size)
+{
+ TPM_RC rc = TPM_RC_SUCCESS;
+
+ if (rc == TPM_RC_SUCCESS) {
+ rc = TPMI_YES_NO_Unmarshal(&target->exclusiveSession, buffer, size);
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ rc = TPM2B_DIGEST_Unmarshal(&target->sessionDigest, buffer, size);
+ }
+ return rc;
+}
+
+/* Table 116 - Definition of TPMS_CREATION_INFO Structure <OUT> */
+
+TPM_RC
+TPMS_CREATION_INFO_Unmarshal(TPMS_CREATION_INFO *target, BYTE **buffer, INT32 *size)
+{
+ TPM_RC rc = TPM_RC_SUCCESS;
+
+ if (rc == TPM_RC_SUCCESS) {
+ rc = TPM2B_NAME_Unmarshal(&target->objectName, buffer, size);
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ rc = TPM2B_DIGEST_Unmarshal(&target->creationHash, buffer, size);
+ }
+ return rc;
+}
+
+/* Table 117 - Definition of TPMS_NV_CERTIFY_INFO Structure <OUT> */
+
+TPM_RC
+TPMS_NV_CERTIFY_INFO_Unmarshal(TPMS_NV_CERTIFY_INFO *target, BYTE **buffer, INT32 *size)
+{
+ TPM_RC rc = TPM_RC_SUCCESS;
+
+ if (rc == TPM_RC_SUCCESS) {
+ rc = TPM2B_NAME_Unmarshal(&target->indexName, buffer, size);
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ rc = UINT16_Unmarshal(&target->offset, buffer, size);
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ rc = TPM2B_MAX_NV_BUFFER_Unmarshal(&target->nvContents, buffer, size);
+ }
+ return rc;
+}
+
+/* Table 118 - Definition of (TPM_ST) TPMI_ST_ATTEST Type <OUT> */
+
+TPM_RC
+TPMI_ST_ATTEST_Unmarshal(TPMI_ST_ATTEST *target, BYTE **buffer, INT32 *size)
+{
+ TPM_RC rc = TPM_RC_SUCCESS;
+ TPMI_ST_ATTEST orig_target = *target; // libtpms added
+
+ if (rc == TPM_RC_SUCCESS) {
+ rc = TPM_ST_Unmarshal(target, buffer, size);
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ switch (*target) {
+ case TPM_ST_ATTEST_CERTIFY:
+ case TPM_ST_ATTEST_CREATION:
+ case TPM_ST_ATTEST_QUOTE:
+ case TPM_ST_ATTEST_COMMAND_AUDIT:
+ case TPM_ST_ATTEST_SESSION_AUDIT:
+ case TPM_ST_ATTEST_TIME:
+ case TPM_ST_ATTEST_NV:
+ break;
+ default:
+ rc = TPM_RC_SELECTOR;
+ *target = orig_target; // libtpms added
+ }
+ }
+ return rc;
+}
+
+/* Table 119 - Definition of TPMU_ATTEST Union <OUT> */
+
+TPM_RC
+TPMU_ATTEST_Unmarshal(TPMU_ATTEST *target, BYTE **buffer, INT32 *size, UINT32 selector)
+{
+ TPM_RC rc = TPM_RC_SUCCESS;
+
+ switch (selector) {
+ case TPM_ST_ATTEST_CERTIFY:
+ rc = TPMS_CERTIFY_INFO_Unmarshal(&target->certify, buffer, size);
+ break;
+ case TPM_ST_ATTEST_CREATION:
+ rc = TPMS_CREATION_INFO_Unmarshal(&target->creation, buffer, size);
+ break;
+ case TPM_ST_ATTEST_QUOTE:
+ rc = TPMS_QUOTE_INFO_Unmarshal(&target->quote, buffer, size);
+ break;
+ case TPM_ST_ATTEST_COMMAND_AUDIT:
+ rc = TPMS_COMMAND_AUDIT_INFO_Unmarshal(&target->commandAudit, buffer, size);
+ break;
+ case TPM_ST_ATTEST_SESSION_AUDIT:
+ rc = TPMS_SESSION_AUDIT_INFO_Unmarshal(&target->sessionAudit, buffer, size);
+ break;
+ case TPM_ST_ATTEST_TIME:
+ rc = TPMS_TIME_ATTEST_INFO_Unmarshal(&target->time, buffer, size);
+ break;
+ case TPM_ST_ATTEST_NV:
+ rc = TPMS_NV_CERTIFY_INFO_Unmarshal(&target->nv, buffer, size);
+ break;
+ default:
+ rc = TPM_RC_SELECTOR;
+
+ }
+ return rc;
+}
+
+/* Table 120 - Definition of TPMS_ATTEST Structure <OUT> */
+
+TPM_RC
+TPMS_ATTEST_Unmarshal(TPMS_ATTEST *target, BYTE **buffer, INT32 *size)
+{
+ TPM_RC rc = TPM_RC_SUCCESS;
+
+ if (rc == TPM_RC_SUCCESS) {
+ rc = TPM_GENERATED_Unmarshal(&target->magic, buffer, size);
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ rc = TPMI_ST_ATTEST_Unmarshal(&target->type, buffer, size);
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ rc = TPM2B_NAME_Unmarshal(&target->qualifiedSigner, buffer, size);
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ rc = TPM2B_DATA_Unmarshal(&target->extraData, buffer, size);
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ rc = TPMS_CLOCK_INFO_Unmarshal(&target->clockInfo, buffer, size);
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ rc = UINT64_Unmarshal(&target->firmwareVersion, buffer, size);
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ rc = TPMU_ATTEST_Unmarshal(&target->attested, buffer, size, target->type);
+ }
+ return rc;
+}
+
+/* Table 121 - Definition of TPM2B_ATTEST Structure <OUT> */
+
+TPM_RC
+TPM2B_ATTEST_Unmarshal(TPM2B_ATTEST *target, BYTE **buffer, INT32 *size)
+{
+ TPM_RC rc = TPM_RC_SUCCESS;
+
+ if (rc == TPM_RC_SUCCESS) {
+ rc = TPM2B_Unmarshal(&target->b, sizeof(TPMS_ATTEST), buffer, size);
+ }
+ return rc;
+}
+
+#endif
+
+/* Table 124 - Definition of {!ALG.S} (TPM_KEY_BITS) TPMI_!ALG.S_KEY_BITS Type */
+
+#if ALG_AES
+TPM_RC
+TPMI_AES_KEY_BITS_Unmarshal(TPMI_AES_KEY_BITS *target, BYTE **buffer, INT32 *size)
+{
+ TPM_RC rc = TPM_RC_SUCCESS;
+ TPMI_AES_KEY_BITS orig_target = *target; // libtpms added
+
+ if (rc == TPM_RC_SUCCESS) {
+ rc = TPM_KEY_BITS_Unmarshal(target, buffer, size);
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ switch (*target) {
+#if AES_128 // libtpms added
+ case 128:
+#endif // libtpms added begin
+#if AES_192
+ case 192:
+#endif
+#if AES_256 // libtpms added end
+ case 256:
+#endif // libtpms added
+ break;
+ default:
+ rc = TPM_RC_VALUE;
+ *target = orig_target; // libtpms added
+ }
+ }
+ return rc;
+}
+#endif
+
+#if ALG_CAMELLIA
+TPM_RC
+TPMI_CAMELLIA_KEY_BITS_Unmarshal(TPMI_CAMELLIA_KEY_BITS *target, BYTE **buffer, INT32 *size)
+{
+ TPM_RC rc = TPM_RC_SUCCESS;
+ TPMI_CAMELLIA_KEY_BITS orig_target = *target; // libtpms added
+
+ if (rc == TPM_RC_SUCCESS) {
+ rc = TPM_KEY_BITS_Unmarshal(target, buffer, size);
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ switch (*target) {
+#if CAMELLIA_128 // libtpms added
+ case 128:
+#endif // libtpms added begin
+#if CAMELLIA_192
+ case 192:
+#endif
+#if CAMELLIA_256
+ case 256:
+#endif // libtpms added end
+ break;
+ default:
+ rc = TPM_RC_VALUE;
+ *target = orig_target; // libtpms added
+ }
+ }
+ return rc;
+}
+#endif
+
+#if ALG_SM4
+TPM_RC
+TPMI_SM4_KEY_BITS_Unmarshal(TPMI_SM4_KEY_BITS *target, BYTE **buffer, INT32 *size)
+{
+ TPM_RC rc = TPM_RC_SUCCESS;
+ TPMI_SM4_KEY_BITS orig_target = *target; // libtpms added
+
+ if (rc == TPM_RC_SUCCESS) {
+ rc = TPM_KEY_BITS_Unmarshal(target, buffer, size);
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ switch (*target) {
+ case 128:
+ break;
+ default:
+ rc = TPM_RC_VALUE;
+ *target = orig_target; // libtpms added
+ }
+ }
+ return rc;
+}
+#endif
+
+#if ALG_TDES // libtpms added begin
+TPM_RC
+TPMI_TDES_KEY_BITS_Unmarshal(TPMI_SM4_KEY_BITS *target, BYTE **buffer, INT32 *size)
+{
+ TPM_RC rc = TPM_RC_SUCCESS;
+ TPMI_SM4_KEY_BITS orig_target = *target; // libtpms added
+
+ if (rc == TPM_RC_SUCCESS) {
+ rc = TPM_KEY_BITS_Unmarshal(target, buffer, size);
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ switch (*target) {
+ case 128:
+ case 192:
+ break;
+ default:
+ rc = TPM_RC_VALUE;
+ *target = orig_target; // libtpms added
+ }
+ }
+ return rc;
+}
+#endif // libtpms added end
+
+/* Table 125 - Definition of TPMU_SYM_KEY_BITS Union */
+
+TPM_RC
+TPMU_SYM_KEY_BITS_Unmarshal(TPMU_SYM_KEY_BITS *target, BYTE **buffer, INT32 *size, UINT32 selector)
+{
+ TPM_RC rc = TPM_RC_SUCCESS;
+
+ switch (selector) {
+#if ALG_AES
+ case TPM_ALG_AES:
+ rc = TPMI_AES_KEY_BITS_Unmarshal(&target->aes, buffer, size);
+ break;
+#endif
+#if ALG_SM4
+ case TPM_ALG_SM4:
+ rc = TPMI_SM4_KEY_BITS_Unmarshal(&target->sm4, buffer, size);
+ break;
+#endif
+#if ALG_CAMELLIA
+ case TPM_ALG_CAMELLIA:
+ rc = TPMI_CAMELLIA_KEY_BITS_Unmarshal(&target->camellia, buffer, size);
+ break;
+#endif
+#if ALG_TDES // libtpms added beging
+ case TPM_ALG_TDES:
+ rc = TPMI_TDES_KEY_BITS_Unmarshal(&target->tdes, buffer, size);
+ break;
+#endif // libtpms added end
+#if ALG_XOR
+ case TPM_ALG_XOR:
+ rc = TPMI_ALG_HASH_Unmarshal(&target->xorr, buffer, size, NO);
+ break;
+#endif
+ case TPM_ALG_NULL:
+ break;
+ default:
+ rc = TPM_RC_SELECTOR;
+ }
+ return rc;
+}
+
+/* Table 126 - Definition of TPMU_SYM_MODE Union */
+
+TPM_RC
+TPMU_SYM_MODE_Unmarshal(TPMU_SYM_MODE *target, BYTE **buffer, INT32 *size, UINT32 selector)
+{
+ TPM_RC rc = TPM_RC_SUCCESS;
+
+ switch (selector) {
+#if ALG_AES
+ case TPM_ALG_AES:
+ rc = TPMI_ALG_SYM_MODE_Unmarshal(&target->aes, buffer, size, YES);
+ break;
+#endif
+#if ALG_SM4
+ case TPM_ALG_SM4:
+ rc = TPMI_ALG_SYM_MODE_Unmarshal(&target->sm4, buffer, size, YES);
+ break;
+#endif
+#if ALG_CAMELLIA
+ case TPM_ALG_CAMELLIA:
+ rc = TPMI_ALG_SYM_MODE_Unmarshal(&target->camellia, buffer, size, YES);
+ break;
+#endif
+#if ALG_TDES // libtpms added begin
+ case TPM_ALG_TDES:
+ rc = TPMI_ALG_SYM_MODE_Unmarshal(&target->tdes, buffer, size, YES);
+ break;
+#endif // libtpms added end
+ case TPM_ALG_XOR:
+ case TPM_ALG_NULL:
+ break;
+ default:
+ rc = TPM_RC_SELECTOR;
+ }
+ return rc;
+}
+
+/* Table 131 - Definition of TPMT_SYM_DEF Structure */
+
+TPM_RC
+TPMT_SYM_DEF_Unmarshal(TPMT_SYM_DEF *target, BYTE **buffer, INT32 *size, BOOL allowNull)
+{
+ TPM_RC rc = TPM_RC_SUCCESS;
+
+ if (rc == TPM_RC_SUCCESS) {
+ rc = TPMI_ALG_SYM_Unmarshal(&target->algorithm, buffer, size, allowNull);
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ rc = TPMU_SYM_KEY_BITS_Unmarshal(&target->keyBits, buffer, size, target->algorithm);
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ rc = TPMU_SYM_MODE_Unmarshal(&target->mode, buffer, size, target->algorithm);
+ }
+ return rc;
+}
+
+/* Table 132 - Definition of TPMT_SYM_DEF_OBJECT Structure */
+
+TPM_RC
+TPMT_SYM_DEF_OBJECT_Unmarshal(TPMT_SYM_DEF_OBJECT *target, BYTE **buffer, INT32 *size, BOOL allowNull)
+{
+ TPM_RC rc = TPM_RC_SUCCESS;
+
+ if (rc == TPM_RC_SUCCESS) {
+ rc = TPMI_ALG_SYM_OBJECT_Unmarshal(&target->algorithm, buffer, size, allowNull);
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ rc = TPMU_SYM_KEY_BITS_Unmarshal(&target->keyBits, buffer, size, target->algorithm);
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ rc = TPMU_SYM_MODE_Unmarshal(&target->mode, buffer, size, target->algorithm);
+ }
+ return rc;
+}
+
+/* Table 133 - Definition of TPM2B_SYM_KEY Structure */
+
+TPM_RC
+TPM2B_SYM_KEY_Unmarshal(TPM2B_SYM_KEY *target, BYTE **buffer, INT32 *size)
+{
+ TPM_RC rc = TPM_RC_SUCCESS;
+
+ if (rc == TPM_RC_SUCCESS) {
+ rc = TPM2B_Unmarshal(&target->b, MAX_SYM_KEY_BYTES, buffer, size);
+ }
+ return rc;
+}
+
+/* Table 134 - Definition of TPMS_SYMCIPHER_PARMS Structure */
+
+TPM_RC
+TPMS_SYMCIPHER_PARMS_Unmarshal(TPMS_SYMCIPHER_PARMS *target, BYTE **buffer, INT32 *size)
+{
+ TPM_RC rc = TPM_RC_SUCCESS;
+
+ if (rc == TPM_RC_SUCCESS) {
+ rc = TPMT_SYM_DEF_OBJECT_Unmarshal(&target->sym, buffer, size, NO);
+ }
+ return rc;
+}
+
+/* Table 2:135 - Definition of TPM2B_LABEL Structure (StructuresTable()) */
+
+TPM_RC
+TPM2B_LABEL_Unmarshal(TPM2B_LABEL *target, BYTE **buffer, INT32 *size)
+{
+ TPM_RC rc = TPM_RC_SUCCESS;
+
+ if (rc == TPM_RC_SUCCESS) {
+ rc = TPM2B_Unmarshal(&target->b, LABEL_MAX_BUFFER, buffer, size);
+ }
+ return rc;
+}
+
+/* Table 2:136 - Definition of TPMS_DERIVE Structure (StructuresTable()) */
+
+TPM_RC
+TPMS_DERIVE_Unmarshal(TPMS_DERIVE *target, BYTE **buffer, INT32 *size)
+{
+ TPM_RC rc = TPM_RC_SUCCESS;
+
+ if (rc == TPM_RC_SUCCESS) {
+ rc = TPM2B_LABEL_Unmarshal(&target->label, buffer, size);
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ rc = TPM2B_LABEL_Unmarshal(&target->context, buffer, size);
+ }
+ return rc;
+}
+
+/* Table 139 - Definition of TPM2B_SENSITIVE_DATA Structure */
+
+TPM_RC
+TPM2B_SENSITIVE_DATA_Unmarshal(TPM2B_SENSITIVE_DATA *target, BYTE **buffer, INT32 *size)
+{
+ TPM_RC rc = TPM_RC_SUCCESS;
+
+ if (rc == TPM_RC_SUCCESS) {
+ rc = TPM2B_Unmarshal(&target->b, MAX_SYM_DATA, buffer, size);
+ }
+ return rc;
+}
+
+/* Table 133 - Definition of TPMS_SENSITIVE_CREATE Structure <IN> */
+
+TPM_RC
+TPMS_SENSITIVE_CREATE_Unmarshal(TPMS_SENSITIVE_CREATE *target, BYTE **buffer, INT32 *size)
+{
+ TPM_RC rc = TPM_RC_SUCCESS;
+
+ if (rc == TPM_RC_SUCCESS) {
+ rc = TPM2B_AUTH_Unmarshal(&target->userAuth, buffer, size);
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ rc = TPM2B_SENSITIVE_DATA_Unmarshal(&target->data, buffer, size);
+ }
+ return rc;
+}
+
+/* Table 134 - Definition of TPM2B_SENSITIVE_CREATE Structure <IN, S> */
+
+TPM_RC
+TPM2B_SENSITIVE_CREATE_Unmarshal(TPM2B_SENSITIVE_CREATE *target, BYTE **buffer, INT32 *size)
+{
+ TPM_RC rc = TPM_RC_SUCCESS;
+
+ INT32 startSize;
+ if (rc == TPM_RC_SUCCESS) {
+ rc = UINT16_Unmarshal(&target->size, buffer, size);
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ if (target->size == 0) {
+ rc = TPM_RC_SIZE;
+ }
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ startSize = *size;
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ rc = TPMS_SENSITIVE_CREATE_Unmarshal(&target->sensitive, buffer, size);
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ if (target->size != startSize - *size) {
+ rc = TPM_RC_SIZE;
+ target->size = 0; // libtpms added
+ }
+ }
+ return rc;
+}
+
+/* Table 135 - Definition of TPMS_SCHEME_HASH Structure */
+
+TPM_RC
+TPMS_SCHEME_HASH_Unmarshal(TPMS_SCHEME_HASH *target, BYTE **buffer, INT32 *size)
+{
+ TPM_RC rc = TPM_RC_SUCCESS;
+
+ if (rc == TPM_RC_SUCCESS) {
+ rc = TPMI_ALG_HASH_Unmarshal(&target->hashAlg, buffer, size, NO);
+ }
+ return rc;
+}
+
+/* Table 136 - Definition of {ECC} TPMS_SCHEME_ECDAA Structure */
+
+TPM_RC
+TPMS_SCHEME_ECDAA_Unmarshal(TPMS_SCHEME_ECDAA *target, BYTE **buffer, INT32 *size)
+{
+ TPM_RC rc = TPM_RC_SUCCESS;
+
+ if (rc == TPM_RC_SUCCESS) {
+ rc = TPMI_ALG_HASH_Unmarshal(&target->hashAlg, buffer, size, NO);
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ rc = UINT16_Unmarshal(&target->count, buffer, size);
+ }
+ return rc;
+}
+
+/* Table 137 - Definition of (TPM_ALG_ID) TPMI_ALG_KEYEDHASH_SCHEME Type */
+
+TPM_RC
+TPMI_ALG_KEYEDHASH_SCHEME_Unmarshal(TPMI_ALG_KEYEDHASH_SCHEME *target, BYTE **buffer, INT32 *size, BOOL allowNull)
+{
+ TPM_RC rc = TPM_RC_SUCCESS;
+ TPMI_ALG_KEYEDHASH_SCHEME orig_target = *target; // libtpms added
+
+ if (rc == TPM_RC_SUCCESS) {
+ rc = TPM_ALG_ID_Unmarshal(target, buffer, size);
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ switch (*target) {
+#if ALG_HMAC
+ case TPM_ALG_HMAC:
+#endif
+#if ALG_XOR
+ case TPM_ALG_XOR:
+#endif
+ break;
+ case TPM_ALG_NULL:
+ if (allowNull) {
+ break;
+ }
+ default:
+ rc = TPM_RC_VALUE;
+ *target = orig_target; // libtpms added
+ }
+ }
+ return rc;
+}
+
+/* Table 138 - Definition of Types for HMAC_SIG_SCHEME */
+
+TPM_RC
+TPMS_SCHEME_HMAC_Unmarshal(TPMS_SCHEME_HMAC *target, BYTE **buffer, INT32 *size)
+{
+ TPM_RC rc = TPM_RC_SUCCESS;
+
+ if (rc == TPM_RC_SUCCESS) {
+ rc = TPMS_SCHEME_HASH_Unmarshal(target, buffer, size);
+ }
+ return rc;
+}
+
+/* Table 139 - Definition of TPMS_SCHEME_XOR Structure */
+
+TPM_RC
+TPMS_SCHEME_XOR_Unmarshal(TPMS_SCHEME_XOR *target, BYTE **buffer, INT32 *size)
+{
+ TPM_RC rc = TPM_RC_SUCCESS;
+
+ if (rc == TPM_RC_SUCCESS) {
+ rc = TPMI_ALG_HASH_Unmarshal(&target->hashAlg, buffer, size, NO); /* as of rev 147 */
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ rc = TPMI_ALG_KDF_Unmarshal(&target->kdf, buffer, size, YES);
+ }
+ return rc;
+}
+
+/* Table 140 - Definition of TPMU_SCHEME_KEYEDHASH Union <IN/OUT, S> */
+
+TPM_RC
+TPMU_SCHEME_KEYEDHASH_Unmarshal(TPMU_SCHEME_KEYEDHASH *target, BYTE **buffer, INT32 *size, UINT32 selector)
+{
+ TPM_RC rc = TPM_RC_SUCCESS;
+
+ switch (selector) {
+#if ALG_HMAC
+ case TPM_ALG_HMAC:
+ rc = TPMS_SCHEME_HMAC_Unmarshal(&target->hmac, buffer, size);
+ break;
+#endif
+#if ALG_XOR
+ case TPM_ALG_XOR:
+ rc = TPMS_SCHEME_XOR_Unmarshal(&target->xorr, buffer, size);
+ break;
+#endif
+ case TPM_ALG_NULL:
+ break;
+ default:
+ rc = TPM_RC_SELECTOR;
+ }
+ return rc;
+}
+
+/* Table 141 - Definition of TPMT_KEYEDHASH_SCHEME Structure */
+
+TPM_RC
+TPMT_KEYEDHASH_SCHEME_Unmarshal(TPMT_KEYEDHASH_SCHEME *target, BYTE **buffer, INT32 *size, BOOL allowNull)
+{
+ TPM_RC rc = TPM_RC_SUCCESS;
+
+ if (rc == TPM_RC_SUCCESS) {
+ rc = TPMI_ALG_KEYEDHASH_SCHEME_Unmarshal(&target->scheme, buffer, size, allowNull);
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ rc = TPMU_SCHEME_KEYEDHASH_Unmarshal(&target->details, buffer, size, target->scheme);
+ }
+ return rc;
+}
+
+/* Table 142 - Definition of {RSA} Types for RSA Signature Schemes */
+
+TPM_RC
+TPMS_SIG_SCHEME_RSAPSS_Unmarshal(TPMS_SIG_SCHEME_RSAPSS *target, BYTE **buffer, INT32 *size)
+{
+ TPM_RC rc = TPM_RC_SUCCESS;
+
+ if (rc == TPM_RC_SUCCESS) {
+ rc = TPMS_SCHEME_HASH_Unmarshal(target, buffer, size);
+ }
+ return rc;
+}
+
+/* Table 142 - Definition of {RSA} Types for RSA Signature Schemes */
+
+TPM_RC
+TPMS_SIG_SCHEME_RSASSA_Unmarshal(TPMS_SIG_SCHEME_RSASSA *target, BYTE **buffer, INT32 *size)
+{
+ TPM_RC rc = TPM_RC_SUCCESS;
+
+ if (rc == TPM_RC_SUCCESS) {
+ rc = TPMS_SCHEME_HASH_Unmarshal(target, buffer, size);
+ }
+ return rc;
+}
+
+/* Table 143 - Definition of {ECC} Types for ECC Signature Schemes */
+
+TPM_RC
+TPMS_SIG_SCHEME_ECDAA_Unmarshal(TPMS_SIG_SCHEME_ECDAA *target, BYTE **buffer, INT32 *size)
+{
+ TPM_RC rc = TPM_RC_SUCCESS;
+
+ if (rc == TPM_RC_SUCCESS) {
+ rc = TPMS_SCHEME_ECDAA_Unmarshal(target, buffer, size);
+ }
+ return rc;
+}
+
+/* Table 143 - Definition of {ECC} Types for ECC Signature Schemes */
+
+TPM_RC
+TPMS_SIG_SCHEME_ECDSA_Unmarshal(TPMS_SIG_SCHEME_ECDSA *target, BYTE **buffer, INT32 *size)
+{
+ TPM_RC rc = TPM_RC_SUCCESS;
+
+ if (rc == TPM_RC_SUCCESS) {
+ rc = TPMS_SCHEME_HASH_Unmarshal(target, buffer, size);
+ }
+ return rc;
+}
+
+/* Table 143 - Definition of {ECC} Types for ECC Signature Schemes */
+
+TPM_RC
+TPMS_SIG_SCHEME_ECSCHNORR_Unmarshal(TPMS_SIG_SCHEME_ECSCHNORR *target, BYTE **buffer, INT32 *size)
+{
+ TPM_RC rc = TPM_RC_SUCCESS;
+
+ if (rc == TPM_RC_SUCCESS) {
+ rc = TPMS_SCHEME_HASH_Unmarshal(target, buffer, size);
+ }
+ return rc;
+}
+
+/* Table 143 - Definition of {ECC} Types for ECC Signature Schemes */
+
+TPM_RC
+TPMS_SIG_SCHEME_SM2_Unmarshal(TPMS_SIG_SCHEME_SM2 *target, BYTE **buffer, INT32 *size)
+{
+ TPM_RC rc = TPM_RC_SUCCESS;
+
+ if (rc == TPM_RC_SUCCESS) {
+ rc = TPMS_SCHEME_HASH_Unmarshal(target, buffer, size);
+ }
+ return rc;
+}
+
+/* Table 144 - Definition of TPMU_SIG_SCHEME Union <IN/OUT, S> */
+
+TPM_RC
+TPMU_SIG_SCHEME_Unmarshal(TPMU_SIG_SCHEME *target, BYTE **buffer, INT32 *size, UINT32 selector)
+{
+ TPM_RC rc = TPM_RC_SUCCESS;
+
+ switch (selector) {
+#if ALG_RSASSA
+ case TPM_ALG_RSASSA:
+ rc = TPMS_SIG_SCHEME_RSASSA_Unmarshal(&target->rsassa, buffer, size);
+ break;
+#endif
+#if ALG_RSAPSS
+ case TPM_ALG_RSAPSS:
+ rc = TPMS_SIG_SCHEME_RSAPSS_Unmarshal(&target->rsapss, buffer, size);
+ break;
+#endif
+#if ALG_ECDSA
+ case TPM_ALG_ECDSA:
+ rc = TPMS_SIG_SCHEME_ECDSA_Unmarshal(&target->ecdsa, buffer, size);
+ break;
+#endif
+#if ALG_ECDAA
+ case TPM_ALG_ECDAA:
+ rc = TPMS_SIG_SCHEME_ECDAA_Unmarshal(&target->ecdaa, buffer, size);
+ break;
+#endif
+#if ALG_SM2
+ case TPM_ALG_SM2:
+ rc = TPMS_SIG_SCHEME_SM2_Unmarshal(&target->sm2, buffer, size);
+ break;
+#endif
+#if ALG_ECSCHNORR
+ case TPM_ALG_ECSCHNORR:
+ rc = TPMS_SIG_SCHEME_ECSCHNORR_Unmarshal(&target->ecschnorr, buffer, size);
+ break;
+#endif
+#if ALG_HMAC
+ case TPM_ALG_HMAC:
+ rc = TPMS_SCHEME_HMAC_Unmarshal(&target->hmac, buffer, size);
+ break;
+#endif
+ case TPM_ALG_NULL:
+ break;
+ default:
+ rc = TPM_RC_SELECTOR;
+ }
+ return rc;
+}
+
+/* Table 145 - Definition of TPMT_SIG_SCHEME Structure */
+
+TPM_RC
+TPMT_SIG_SCHEME_Unmarshal(TPMT_SIG_SCHEME *target, BYTE **buffer, INT32 *size, BOOL allowNull)
+{
+ TPM_RC rc = TPM_RC_SUCCESS;
+
+ if (rc == TPM_RC_SUCCESS) {
+ rc = TPMI_ALG_SIG_SCHEME_Unmarshal(&target->scheme, buffer, size, allowNull);
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ rc = TPMU_SIG_SCHEME_Unmarshal(&target->details, buffer, size, target->scheme);
+ }
+ return rc;
+}
+
+/* Table 146 - Definition of Types for {RSA} Encryption Schemes */
+
+TPM_RC
+TPMS_ENC_SCHEME_OAEP_Unmarshal(TPMS_ENC_SCHEME_OAEP *target, BYTE **buffer, INT32 *size)
+{
+ TPM_RC rc = TPM_RC_SUCCESS;
+
+ if (rc == TPM_RC_SUCCESS) {
+ rc = TPMS_SCHEME_HASH_Unmarshal(target, buffer, size);
+ }
+ return rc;
+}
+
+/* Table 146 - Definition of Types for {RSA} Encryption Schemes */
+
+TPM_RC
+TPMS_ENC_SCHEME_RSAES_Unmarshal(TPMS_ENC_SCHEME_RSAES *target, BYTE **buffer, INT32 *size)
+{
+ TPM_RC rc = TPM_RC_SUCCESS;
+
+ if (rc == TPM_RC_SUCCESS) {
+ rc = TPMS_EMPTY_Unmarshal(target, buffer, size);
+ }
+ return rc;
+}
+
+/* Table 147 - Definition of Types for {ECC} ECC Key Exchange */
+
+TPM_RC
+TPMS_KEY_SCHEME_ECDH_Unmarshal(TPMS_KEY_SCHEME_ECDH *target, BYTE **buffer, INT32 *size)
+{
+ TPM_RC rc = TPM_RC_SUCCESS;
+
+ if (rc == TPM_RC_SUCCESS) {
+ rc = TPMS_SCHEME_HASH_Unmarshal(target, buffer, size);
+ }
+ return rc;
+}
+
+/* Table 147 - Definition of Types for {ECC} ECC Key Exchange */
+
+TPM_RC
+TPMS_KEY_SCHEME_ECMQV_Unmarshal(TPMS_KEY_SCHEME_ECMQV *target, BYTE **buffer, INT32 *size)
+{
+ TPM_RC rc = TPM_RC_SUCCESS;
+
+ if (rc == TPM_RC_SUCCESS) {
+ rc = TPMS_SCHEME_HASH_Unmarshal(target, buffer, size);
+ }
+ return rc;
+}
+
+/* Table 148 - Definition of Types for KDF Schemes, hash-based key- or mask-generation functions */
+
+TPM_RC
+TPMS_KDF_SCHEME_KDF1_SP800_108_Unmarshal(TPMS_KDF_SCHEME_KDF1_SP800_108 *target, BYTE **buffer, INT32 *size)
+{
+ TPM_RC rc = TPM_RC_SUCCESS;
+
+ if (rc == TPM_RC_SUCCESS) {
+ rc = TPMS_SCHEME_HASH_Unmarshal(target, buffer, size);
+ }
+ return rc;
+}
+
+/* Table 148 - Definition of Types for KDF Schemes, hash-based key- or mask-generation functions */
+
+TPM_RC
+TPMS_KDF_SCHEME_KDF1_SP800_56A_Unmarshal(TPMS_KDF_SCHEME_KDF1_SP800_56A *target, BYTE **buffer, INT32 *size)
+{
+ TPM_RC rc = TPM_RC_SUCCESS;
+
+ if (rc == TPM_RC_SUCCESS) {
+ rc = TPMS_SCHEME_HASH_Unmarshal(target, buffer, size);
+ }
+ return rc;
+}
+
+/* Table 148 - Definition of Types for KDF Schemes, hash-based key- or mask-generation functions */
+
+TPM_RC
+TPMS_KDF_SCHEME_KDF2_Unmarshal(TPMS_KDF_SCHEME_KDF2 *target, BYTE **buffer, INT32 *size)
+{
+ TPM_RC rc = TPM_RC_SUCCESS;
+
+ if (rc == TPM_RC_SUCCESS) {
+ rc = TPMS_SCHEME_HASH_Unmarshal(target, buffer, size);
+ }
+ return rc;
+}
+
+/* Table 148 - Definition of Types for KDF Schemes, hash-based key- or mask-generation functions */
+
+TPM_RC
+TPMS_KDF_SCHEME_MGF1_Unmarshal(TPMS_KDF_SCHEME_MGF1 *target, BYTE **buffer, INT32 *size)
+{
+ TPM_RC rc = TPM_RC_SUCCESS;
+
+ if (rc == TPM_RC_SUCCESS) {
+ rc = TPMS_SCHEME_HASH_Unmarshal(target, buffer, size);
+ }
+ return rc;
+}
+
+/* Table 149 - Definition of TPMU_KDF_SCHEME Union <IN/OUT, S> */
+
+TPM_RC
+TPMU_KDF_SCHEME_Unmarshal(TPMU_KDF_SCHEME *target, BYTE **buffer, INT32 *size, UINT32 selector)
+{
+ TPM_RC rc = TPM_RC_SUCCESS;
+
+ switch (selector) {
+#if ALG_MGF1
+ case TPM_ALG_MGF1:
+ rc = TPMS_KDF_SCHEME_MGF1_Unmarshal(&target->mgf1, buffer, size);
+ break;
+#endif
+#if ALG_KDF1_SP800_56A
+ case TPM_ALG_KDF1_SP800_56A:
+ rc = TPMS_KDF_SCHEME_KDF1_SP800_56A_Unmarshal(&target->kdf1_sp800_56a, buffer, size);
+ break;
+#endif
+#if ALG_KDF2
+ case TPM_ALG_KDF2:
+ rc = TPMS_KDF_SCHEME_KDF2_Unmarshal(&target->kdf2, buffer, size);
+ break;
+#endif
+#if ALG_KDF1_SP800_108
+ case TPM_ALG_KDF1_SP800_108:
+ rc = TPMS_KDF_SCHEME_KDF1_SP800_108_Unmarshal(&target->kdf1_sp800_108, buffer, size);
+ break;
+#endif
+ case TPM_ALG_NULL:
+ break;
+ default:
+ rc = TPM_RC_SELECTOR;
+ }
+ return rc;
+}
+
+/* Table 150 - Definition of TPMT_KDF_SCHEME Structure */
+
+TPM_RC
+TPMT_KDF_SCHEME_Unmarshal(TPMT_KDF_SCHEME *target, BYTE **buffer, INT32 *size, BOOL allowNull)
+{
+ TPM_RC rc = TPM_RC_SUCCESS;
+
+ if (rc == TPM_RC_SUCCESS) {
+ rc = TPMI_ALG_KDF_Unmarshal(&target->scheme, buffer, size, allowNull);
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ rc = TPMU_KDF_SCHEME_Unmarshal(&target->details, buffer, size, target->scheme);
+ }
+ return rc;
+}
+
+/* Table 151 - Definition of (TPM_ALG_ID) TPMI_ALG_ASYM_SCHEME Type <> */
+
+#if 0
+TPM_RC
+TPMI_ALG_ASYM_SCHEME_Unmarshal(TPMI_ALG_ASYM_SCHEME *target, BYTE **buffer, INT32 *size, BOOL allowNull)
+{
+ TPM_RC rc = TPM_RC_SUCCESS;
+ TPMI_ALG_ASYM_SCHEME orig_target = *target; // libtpms added
+
+ if (rc == TPM_RC_SUCCESS) {
+ rc = TPM_ALG_ID_Unmarshal(target, buffer, size);
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ switch (*target) {
+#if ALG_ECDH
+ case TPM_ALG_ECDH:
+#endif
+#if ALG_ECMQV
+ case TPM_ALG_ECMQV:
+#endif
+#if ALG_RSASSA
+ case TPM_ALG_RSASSA:
+#endif
+#if ALG_RSAPSS
+ case TPM_ALG_RSAPSS:
+#endif
+#if ALG_ECDSA
+ case TPM_ALG_ECDSA:
+#endif
+#if ALG_ECDAA
+ case TPM_ALG_ECDAA:
+#endif
+#if ALG_SM2
+ case TPM_ALG_SM2:
+#endif
+#if ALG_ECSCHNORR
+ case TPM_ALG_ECSCHNORR:
+#endif
+#if ALG_RSAES
+ case TPM_ALG_RSAES:
+#endif
+#if ALG_OAEP
+ case TPM_ALG_OAEP:
+#endif
+ break;
+ case TPM_ALG_NULL:
+ if (allowNull) {
+ break;
+ }
+ default:
+ rc = TPM_RC_VALUE;
+ *target = orig_target; // libtpms added
+ }
+ }
+ return rc;
+}
+#endif
+
+/* Table 152 - Definition of TPMU_ASYM_SCHEME Union */
+
+TPM_RC
+TPMU_ASYM_SCHEME_Unmarshal(TPMU_ASYM_SCHEME *target, BYTE **buffer, INT32 *size, UINT32 selector)
+{
+ TPM_RC rc = TPM_RC_SUCCESS;
+
+ switch (selector) {
+#if ALG_ECDH
+ case TPM_ALG_ECDH:
+ rc = TPMS_KEY_SCHEME_ECDH_Unmarshal(&target->ecdh, buffer, size);
+ break;
+#endif
+#if ALG_ECMQV
+ case TPM_ALG_ECMQV:
+ rc = TPMS_KEY_SCHEME_ECMQV_Unmarshal(&target->ecmqv, buffer, size);
+ break;
+#endif
+#if ALG_RSASSA
+ case TPM_ALG_RSASSA:
+ rc = TPMS_SIG_SCHEME_RSASSA_Unmarshal(&target->rsassa, buffer, size);
+ break;
+#endif
+#if ALG_RSAPSS
+ case TPM_ALG_RSAPSS:
+ rc = TPMS_SIG_SCHEME_RSAPSS_Unmarshal(&target->rsapss, buffer, size);
+ break;
+#endif
+#if ALG_ECDSA
+ case TPM_ALG_ECDSA:
+ rc = TPMS_SIG_SCHEME_ECDSA_Unmarshal(&target->ecdsa, buffer, size);
+ break;
+#endif
+#if ALG_ECDAA
+ case TPM_ALG_ECDAA:
+ rc = TPMS_SIG_SCHEME_ECDAA_Unmarshal(&target->ecdaa, buffer, size);
+ break;
+#endif
+#if ALG_SM2
+ case TPM_ALG_SM2:
+ rc = TPMS_SIG_SCHEME_SM2_Unmarshal(&target->sm2, buffer, size);
+ break;
+#endif
+#if ALG_ECSCHNORR
+ case TPM_ALG_ECSCHNORR:
+ rc = TPMS_SIG_SCHEME_ECSCHNORR_Unmarshal(&target->ecschnorr, buffer, size);
+ break;
+#endif
+#if ALG_RSAES
+ case TPM_ALG_RSAES:
+ rc = TPMS_ENC_SCHEME_RSAES_Unmarshal(&target->rsaes, buffer, size);
+ break;
+#endif
+#if ALG_OAEP
+ case TPM_ALG_OAEP:
+ rc = TPMS_ENC_SCHEME_OAEP_Unmarshal(&target->oaep, buffer, size);
+ break;
+#endif
+ case TPM_ALG_NULL:
+ break;
+ default:
+ rc = TPM_RC_SELECTOR;
+ }
+ return rc;
+}
+
+/* Table 154 - Definition of (TPM_ALG_ID) {RSA} TPMI_ALG_RSA_SCHEME Type */
+
+TPM_RC
+TPMI_ALG_RSA_SCHEME_Unmarshal(TPMI_ALG_RSA_SCHEME *target, BYTE **buffer, INT32 *size, BOOL allowNull)
+{
+ TPM_RC rc = TPM_RC_SUCCESS;
+ TPMI_ALG_RSA_SCHEME orig_target = *target; // libtpms added
+
+ if (rc == TPM_RC_SUCCESS) {
+ rc = TPM_ALG_ID_Unmarshal(target, buffer, size);
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ switch (*target) {
+#if ALG_RSASSA
+ case TPM_ALG_RSASSA:
+#endif
+#if ALG_RSAPSS
+ case TPM_ALG_RSAPSS:
+#endif
+#if ALG_RSAES
+ case TPM_ALG_RSAES:
+#endif
+#if ALG_OAEP
+ case TPM_ALG_OAEP:
+#endif
+ break;
+ case TPM_ALG_NULL:
+ if (allowNull) {
+ break;
+ }
+ default:
+ rc = TPM_RC_VALUE;
+ *target = orig_target; // libtpms added
+ }
+ }
+ return rc;
+}
+
+/* Table 155 - Definition of {RSA} TPMT_RSA_SCHEME Structure */
+
+TPM_RC
+TPMT_RSA_SCHEME_Unmarshal(TPMT_RSA_SCHEME *target, BYTE **buffer, INT32 *size, BOOL allowNull)
+{
+ TPM_RC rc = TPM_RC_SUCCESS;
+
+ if (rc == TPM_RC_SUCCESS) {
+ rc = TPMI_ALG_RSA_SCHEME_Unmarshal(&target->scheme, buffer, size, allowNull);
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ rc = TPMU_ASYM_SCHEME_Unmarshal(&target->details, buffer, size, target->scheme);
+ }
+ return rc;
+}
+
+/* Table 156 - Definition of (TPM_ALG_ID) {RSA} TPMI_ALG_RSA_DECRYPT Type */
+
+TPM_RC
+TPMI_ALG_RSA_DECRYPT_Unmarshal(TPMI_ALG_RSA_DECRYPT *target, BYTE **buffer, INT32 *size, BOOL allowNull)
+{
+ TPM_RC rc = TPM_RC_SUCCESS;
+ TPMI_ALG_RSA_DECRYPT orig_target = *target; // libtpms added
+
+ if (rc == TPM_RC_SUCCESS) {
+ rc = TPM_ALG_ID_Unmarshal(target, buffer, size);
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ switch (*target) {
+#if ALG_RSAES
+ case TPM_ALG_RSAES:
+#endif
+#if ALG_OAEP
+ case TPM_ALG_OAEP:
+#endif
+ break;
+ case TPM_ALG_NULL:
+ if (allowNull) {
+ break;
+ }
+ default:
+ rc = TPM_RC_VALUE;
+ *target = orig_target; // libtpms added
+ }
+ }
+ return rc;
+}
+
+/* Table 157 - Definition of {RSA} TPMT_RSA_DECRYPT Structure */
+
+TPM_RC
+TPMT_RSA_DECRYPT_Unmarshal(TPMT_RSA_DECRYPT *target, BYTE **buffer, INT32 *size, BOOL allowNull)
+{
+ TPM_RC rc = TPM_RC_SUCCESS;
+
+ if (rc == TPM_RC_SUCCESS) {
+ rc = TPMI_ALG_RSA_DECRYPT_Unmarshal(&target->scheme, buffer, size, allowNull);
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ rc = TPMU_ASYM_SCHEME_Unmarshal(&target->details, buffer, size, target->scheme);
+ }
+ return rc;
+}
+
+/* Table 158 - Definition of {RSA} TPM2B_PUBLIC_KEY_RSA Structure */
+
+TPM_RC
+TPM2B_PUBLIC_KEY_RSA_Unmarshal(TPM2B_PUBLIC_KEY_RSA *target, BYTE **buffer, INT32 *size)
+{
+ TPM_RC rc = TPM_RC_SUCCESS;
+
+ if (rc == TPM_RC_SUCCESS) {
+ rc = TPM2B_Unmarshal(&target->b, MAX_RSA_KEY_BYTES, buffer, size);
+ }
+ return rc;
+}
+
+/* Table 159 - Definition of {RSA} (TPM_KEY_BITS) TPMI_RSA_KEY_BITS Type */
+
+TPM_RC
+TPMI_RSA_KEY_BITS_Unmarshal(TPMI_RSA_KEY_BITS *target, BYTE **buffer, INT32 *size)
+{
+ TPM_RC rc = TPM_RC_SUCCESS;
+ TPMI_RSA_KEY_BITS orig_target = *target; // libtpms added
+
+ if (rc == TPM_RC_SUCCESS) {
+ rc = TPM_KEY_BITS_Unmarshal(target, buffer, size);
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ switch (*target) {
+ case 1024:
+ case 2048:
+ case 3072:
+ break;
+ default:
+ rc = TPM_RC_VALUE;
+ *target = orig_target; // libtpms added
+ }
+ }
+ return rc;
+}
+
+/* Table 160 - Definition of {RSA} TPM2B_PRIVATE_KEY_RSA Structure */
+
+TPM_RC
+TPM2B_PRIVATE_KEY_RSA_Unmarshal(TPM2B_PRIVATE_KEY_RSA *target, BYTE **buffer, INT32 *size)
+{
+ TPM_RC rc = TPM_RC_SUCCESS;
+
+ if (rc == TPM_RC_SUCCESS) {
+ rc = TPM2B_Unmarshal(&target->b, MAX_RSA_KEY_BYTES/2, buffer, size);
+ }
+ return rc;
+}
+
+/* Table 161 - Definition of {ECC} TPM2B_ECC_PARAMETER Structure */
+
+TPM_RC
+TPM2B_ECC_PARAMETER_Unmarshal(TPM2B_ECC_PARAMETER *target, BYTE **buffer, INT32 *size)
+{
+ TPM_RC rc = TPM_RC_SUCCESS;
+
+ if (rc == TPM_RC_SUCCESS) {
+ rc = TPM2B_Unmarshal(&target->b, MAX_ECC_KEY_BYTES, buffer, size);
+ }
+ return rc;
+}
+
+/* Table 162 - Definition of {ECC} TPMS_ECC_POINT Structure */
+
+TPM_RC
+TPMS_ECC_POINT_Unmarshal(TPMS_ECC_POINT *target, BYTE **buffer, INT32 *size)
+{
+ TPM_RC rc = TPM_RC_SUCCESS;
+
+ if (rc == TPM_RC_SUCCESS) {
+ rc = TPM2B_ECC_PARAMETER_Unmarshal(&target->x, buffer, size);
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ rc = TPM2B_ECC_PARAMETER_Unmarshal(&target->y, buffer, size);
+ }
+ return rc;
+}
+
+/* Table 163 - Definition of {ECC} TPM2B_ECC_POINT Structure */
+
+TPM_RC
+TPM2B_ECC_POINT_Unmarshal(TPM2B_ECC_POINT *target, BYTE **buffer, INT32 *size)
+{
+ TPM_RC rc = TPM_RC_SUCCESS;
+
+ INT32 startSize;
+ if (rc == TPM_RC_SUCCESS) {
+ rc = UINT16_Unmarshal(&target->size, buffer, size);
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ if (target->size == 0) {
+ rc = TPM_RC_SIZE;
+ }
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ startSize = *size;
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ rc = TPMS_ECC_POINT_Unmarshal(&target->point, buffer, size);
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ if (target->size != startSize - *size) {
+ rc = TPM_RC_SIZE;
+ target->size = 0; // libtpms added
+ }
+ }
+ return rc;
+}
+
+/* Table 164 - Definition of (TPM_ALG_ID) {ECC} TPMI_ALG_ECC_SCHEME Type */
+
+TPM_RC
+TPMI_ALG_ECC_SCHEME_Unmarshal(TPMI_ALG_ECC_SCHEME *target, BYTE **buffer, INT32 *size, BOOL allowNull)
+{
+ TPM_RC rc = TPM_RC_SUCCESS;
+ TPMI_ALG_ECC_SCHEME orig_target = *target; // libtpms added
+
+ if (rc == TPM_RC_SUCCESS) {
+ rc = TPM_ALG_ID_Unmarshal(target, buffer, size);
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ switch (*target) {
+#if ALG_ECDSA
+ case TPM_ALG_ECDSA:
+#endif
+#if ALG_SM2
+ case TPM_ALG_SM2:
+#endif
+#if ALG_ECDAA
+ case TPM_ALG_ECDAA:
+#endif
+#if ALG_ECSCHNORR
+ case TPM_ALG_ECSCHNORR:
+#endif
+#if ALG_ECDH
+ case TPM_ALG_ECDH:
+#endif
+#if ALG_ECMQV
+ case TPM_ALG_ECMQV:
+#endif
+ break;
+ case TPM_ALG_NULL:
+ if (allowNull) {
+ break;
+ }
+ default:
+ rc = TPM_RC_SCHEME;
+ *target = orig_target; // libtpms added
+ }
+ }
+ return rc;
+}
+
+/* Table 165 - Definition of {ECC} (TPM_ECC_CURVE) TPMI_ECC_CURVE Type */
+
+TPM_RC
+TPMI_ECC_CURVE_Unmarshal(TPMI_ECC_CURVE *target, BYTE **buffer, INT32 *size)
+{
+ TPM_RC rc = TPM_RC_SUCCESS;
+ TPMI_ECC_CURVE orig_target = *target; // libtpms added
+
+ if (rc == TPM_RC_SUCCESS) {
+ rc = TPM_ECC_CURVE_Unmarshal(target, buffer, size);
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ switch (*target) {
+#if ECC_BN_P256
+ case TPM_ECC_BN_P256:
+#endif
+#if ECC_BN_P638 // libtpms added begin
+ case TPM_ECC_BN_P638:
+#endif
+#if ECC_NIST_P192
+ case TPM_ECC_NIST_P192:
+#endif
+#if ECC_NIST_P224
+ case TPM_ECC_NIST_P224:
+#endif // libtpms added end
+#if ECC_NIST_P256
+ case TPM_ECC_NIST_P256:
+#endif
+#if ECC_NIST_P384
+ case TPM_ECC_NIST_P384:
+#endif
+#if ECC_NIST_P521 // libtpms added begin
+ case TPM_ECC_NIST_P521:
+#endif
+#if ECC_SM2_P256
+ case TPM_ECC_SM2_P256:
+#endif
+ if (!CryptEccIsCurveRuntimeUsable(*target))
+ rc = TPM_RC_CURVE;
+ // libtpms added end
+ break;
+ default:
+ rc = TPM_RC_CURVE;
+ *target = orig_target; // libtpms added
+ }
+ }
+ return rc;
+}
+
+/* Table 166 - Definition of (TPMT_SIG_SCHEME) {ECC} TPMT_ECC_SCHEME Structure */
+
+TPM_RC
+TPMT_ECC_SCHEME_Unmarshal(TPMT_ECC_SCHEME *target, BYTE **buffer, INT32 *size, BOOL allowNull)
+{
+ TPM_RC rc = TPM_RC_SUCCESS;
+
+ if (rc == TPM_RC_SUCCESS) {
+ rc = TPMI_ALG_ECC_SCHEME_Unmarshal(&target->scheme, buffer, size, allowNull);
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ rc = TPMU_ASYM_SCHEME_Unmarshal(&target->details, buffer, size, target->scheme);
+ }
+ return rc;
+}
+
+/* Table 168 - Definition of {RSA} TPMS_SIGNATURE_RSA Structure */
+
+TPM_RC
+TPMS_SIGNATURE_RSA_Unmarshal(TPMS_SIGNATURE_RSA *target, BYTE **buffer, INT32 *size)
+{
+ TPM_RC rc = TPM_RC_SUCCESS;
+
+ if (rc == TPM_RC_SUCCESS) {
+ rc = TPMI_ALG_HASH_Unmarshal(&target->hash, buffer, size, NO);
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ rc = TPM2B_PUBLIC_KEY_RSA_Unmarshal(&target->sig, buffer, size);
+ }
+ return rc;
+}
+
+/* Table 169 - Definition of Types for {RSA} Signature */
+
+TPM_RC
+TPMS_SIGNATURE_RSASSA_Unmarshal(TPMS_SIGNATURE_RSASSA *target, BYTE **buffer, INT32 *size)
+{
+ TPM_RC rc = TPM_RC_SUCCESS;
+
+ if (rc == TPM_RC_SUCCESS) {
+ rc = TPMS_SIGNATURE_RSA_Unmarshal(target, buffer, size);
+ }
+ return rc;
+}
+
+/* Table 169 - Definition of Types for {RSA} Signature */
+
+TPM_RC
+TPMS_SIGNATURE_RSAPSS_Unmarshal(TPMS_SIGNATURE_RSAPSS *target, BYTE **buffer, INT32 *size)
+{
+ TPM_RC rc = TPM_RC_SUCCESS;
+
+ if (rc == TPM_RC_SUCCESS) {
+ rc = TPMS_SIGNATURE_RSA_Unmarshal(target, buffer, size);
+ }
+ return rc;
+}
+
+/* Table 170 - Definition of {ECC} TPMS_SIGNATURE_ECC Structure */
+
+TPM_RC
+TPMS_SIGNATURE_ECC_Unmarshal(TPMS_SIGNATURE_ECC *target, BYTE **buffer, INT32 *size)
+{
+ TPM_RC rc = TPM_RC_SUCCESS;
+
+ if (rc == TPM_RC_SUCCESS) {
+ rc = TPMI_ALG_HASH_Unmarshal(&target->hash, buffer, size, NO);
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ rc = TPM2B_ECC_PARAMETER_Unmarshal(&target->signatureR, buffer, size);
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ rc = TPM2B_ECC_PARAMETER_Unmarshal(&target->signatureS, buffer, size);
+ }
+ return rc;
+}
+
+/* Table 171 - Definition of Types for {ECC} TPMS_SIGNATURE_ECC */
+
+TPM_RC
+TPMS_SIGNATURE_ECDSA_Unmarshal(TPMS_SIGNATURE_ECDSA *target, BYTE **buffer, INT32 *size)
+{
+ TPM_RC rc = TPM_RC_SUCCESS;
+
+ if (rc == TPM_RC_SUCCESS) {
+ rc = TPMS_SIGNATURE_ECC_Unmarshal(target, buffer, size);
+ }
+ return rc;
+}
+
+TPM_RC
+TPMS_SIGNATURE_ECDAA_Unmarshal(TPMS_SIGNATURE_ECDAA *target, BYTE **buffer, INT32 *size)
+{
+ TPM_RC rc = TPM_RC_SUCCESS;
+
+ if (rc == TPM_RC_SUCCESS) {
+ rc = TPMS_SIGNATURE_ECC_Unmarshal(target, buffer, size);
+ }
+ return rc;
+}
+
+TPM_RC
+TPMS_SIGNATURE_SM2_Unmarshal(TPMS_SIGNATURE_SM2 *target, BYTE **buffer, INT32 *size)
+{
+ TPM_RC rc = TPM_RC_SUCCESS;
+
+ if (rc == TPM_RC_SUCCESS) {
+ rc = TPMS_SIGNATURE_ECC_Unmarshal(target, buffer, size);
+ }
+ return rc;
+}
+
+TPM_RC
+TPMS_SIGNATURE_ECSCHNORR_Unmarshal(TPMS_SIGNATURE_ECSCHNORR *target, BYTE **buffer, INT32 *size)
+{
+ TPM_RC rc = TPM_RC_SUCCESS;
+
+ if (rc == TPM_RC_SUCCESS) {
+ rc = TPMS_SIGNATURE_ECC_Unmarshal(target, buffer, size);
+ }
+ return rc;
+}
+
+/* Table 172 - Definition of TPMU_SIGNATURE Union <IN/OUT, S> */
+
+TPM_RC
+TPMU_SIGNATURE_Unmarshal(TPMU_SIGNATURE *target, BYTE **buffer, INT32 *size, UINT32 selector)
+{
+ TPM_RC rc = TPM_RC_SUCCESS;
+
+ switch (selector) {
+#if ALG_RSASSA
+ case TPM_ALG_RSASSA:
+ rc = TPMS_SIGNATURE_RSASSA_Unmarshal(&target->rsassa, buffer, size);
+ break;
+#endif
+#if ALG_RSAPSS
+ case TPM_ALG_RSAPSS:
+ rc = TPMS_SIGNATURE_RSAPSS_Unmarshal(&target->rsapss, buffer, size);
+ break;
+#endif
+#if ALG_ECDSA
+ case TPM_ALG_ECDSA:
+ rc = TPMS_SIGNATURE_ECDSA_Unmarshal(&target->ecdsa, buffer, size);
+ break;
+#endif
+#if ALG_ECDAA
+ case TPM_ALG_ECDAA:
+ rc = TPMS_SIGNATURE_ECDAA_Unmarshal(&target->ecdaa, buffer, size);
+ break;
+#endif
+#if ALG_SM2
+ case TPM_ALG_SM2:
+ rc = TPMS_SIGNATURE_SM2_Unmarshal(&target->sm2, buffer, size);
+ break;
+#endif
+#if ALG_ECSCHNORR
+ case TPM_ALG_ECSCHNORR:
+ rc = TPMS_SIGNATURE_ECSCHNORR_Unmarshal(&target->ecschnorr, buffer, size);
+ break;
+#endif
+#if ALG_HMAC
+ case TPM_ALG_HMAC:
+ rc = TPMT_HA_Unmarshal(&target->hmac, buffer, size, NO);
+ break;
+#endif
+ case TPM_ALG_NULL:
+ break;
+ default:
+ rc = TPM_RC_SELECTOR;
+ }
+ return rc;
+}
+
+/* Table 173 - Definition of TPMT_SIGNATURE Structure */
+
+TPM_RC
+TPMT_SIGNATURE_Unmarshal(TPMT_SIGNATURE *target, BYTE **buffer, INT32 *size, BOOL allowNull)
+{
+ TPM_RC rc = TPM_RC_SUCCESS;
+
+ if (rc == TPM_RC_SUCCESS) {
+ rc = TPMI_ALG_SIG_SCHEME_Unmarshal(&target->sigAlg, buffer, size, allowNull);
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ rc = TPMU_SIGNATURE_Unmarshal(&target->signature, buffer, size, target->sigAlg);
+ }
+ return rc;
+}
+
+/* Table 175 - Definition of TPM2B_ENCRYPTED_SECRET Structure */
+
+TPM_RC
+TPM2B_ENCRYPTED_SECRET_Unmarshal(TPM2B_ENCRYPTED_SECRET *target, BYTE **buffer, INT32 *size)
+{
+ TPM_RC rc = TPM_RC_SUCCESS;
+
+ if (rc == TPM_RC_SUCCESS) {
+ rc = TPM2B_Unmarshal(&target->b, sizeof(TPMU_ENCRYPTED_SECRET), buffer, size);
+ }
+ return rc;
+}
+
+/* Table 176 - Definition of (TPM_ALG_ID) TPMI_ALG_PUBLIC Type */
+
+TPM_RC
+TPMI_ALG_PUBLIC_Unmarshal(TPMI_ALG_PUBLIC *target, BYTE **buffer, INT32 *size)
+{
+ TPM_RC rc = TPM_RC_SUCCESS;
+ TPMI_ALG_PUBLIC orig_target = *target; // libtpms added
+
+ if (rc == TPM_RC_SUCCESS) {
+ rc = TPM_ALG_ID_Unmarshal(target, buffer, size);
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ switch (*target) {
+#if ALG_KEYEDHASH
+ case TPM_ALG_KEYEDHASH:
+#endif
+#if ALG_RSA
+ case TPM_ALG_RSA:
+#endif
+#if ALG_ECC
+ case TPM_ALG_ECC:
+#endif
+#if ALG_SYMCIPHER
+ case TPM_ALG_SYMCIPHER:
+#endif
+ break;
+ default:
+ rc = TPM_RC_TYPE;
+ *target = orig_target; // libtpms added
+ }
+ }
+ return rc;
+}
+
+/* Table 177 - Definition of TPMU_PUBLIC_ID Union <IN/OUT, S> */
+
+TPM_RC
+TPMU_PUBLIC_ID_Unmarshal(TPMU_PUBLIC_ID *target, BYTE **buffer, INT32 *size, UINT32 selector)
+{
+ TPM_RC rc = TPM_RC_SUCCESS;
+
+ switch (selector) {
+#if ALG_KEYEDHASH
+ case TPM_ALG_KEYEDHASH:
+ rc = TPM2B_DIGEST_Unmarshal(&target->keyedHash, buffer, size);
+ break;
+#endif
+#if ALG_SYMCIPHER
+ case TPM_ALG_SYMCIPHER:
+ rc = TPM2B_DIGEST_Unmarshal(&target->sym, buffer, size);
+ break;
+#endif
+#if ALG_RSA
+ case TPM_ALG_RSA:
+ rc = TPM2B_PUBLIC_KEY_RSA_Unmarshal(&target->rsa, buffer, size);
+ break;
+#endif
+#if ALG_ECC
+ case TPM_ALG_ECC:
+ rc = TPMS_ECC_POINT_Unmarshal(&target->ecc, buffer, size);
+ break;
+#endif
+ default:
+ rc = TPM_RC_SELECTOR;
+ }
+ return rc;
+}
+
+/* Table 178 - Definition of TPMS_KEYEDHASH_PARMS Structure */
+
+TPM_RC
+TPMS_KEYEDHASH_PARMS_Unmarshal(TPMS_KEYEDHASH_PARMS *target, BYTE **buffer, INT32 *size)
+{
+ TPM_RC rc = TPM_RC_SUCCESS;
+
+ if (rc == TPM_RC_SUCCESS) {
+ rc = TPMT_KEYEDHASH_SCHEME_Unmarshal(&target->scheme, buffer, size, YES);
+ }
+ return rc;
+}
+
+/* Table 180 - Definition of {RSA} TPMS_RSA_PARMS Structure */
+
+TPM_RC
+TPMS_RSA_PARMS_Unmarshal(TPMS_RSA_PARMS *target, BYTE **buffer, INT32 *size)
+{
+ TPM_RC rc = TPM_RC_SUCCESS;
+
+ if (rc == TPM_RC_SUCCESS) {
+ rc = TPMT_SYM_DEF_OBJECT_Unmarshal(&target->symmetric, buffer, size, YES);
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ rc = TPMT_RSA_SCHEME_Unmarshal(&target->scheme, buffer, size, YES);
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ rc = TPMI_RSA_KEY_BITS_Unmarshal(&target->keyBits, buffer, size);
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ rc = UINT32_Unmarshal(&target->exponent, buffer, size);
+ }
+ return rc;
+}
+
+/* Table 181 - Definition of {ECC} TPMS_ECC_PARMS Structure */
+
+TPM_RC
+TPMS_ECC_PARMS_Unmarshal(TPMS_ECC_PARMS *target, BYTE **buffer, INT32 *size)
+{
+ TPM_RC rc = TPM_RC_SUCCESS;
+
+ if (rc == TPM_RC_SUCCESS) {
+ rc = TPMT_SYM_DEF_OBJECT_Unmarshal(&target->symmetric, buffer, size, YES);
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ rc = TPMT_ECC_SCHEME_Unmarshal(&target->scheme, buffer, size, YES);
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ rc = TPMI_ECC_CURVE_Unmarshal(&target->curveID, buffer, size);
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ rc = TPMT_KDF_SCHEME_Unmarshal(&target->kdf, buffer, size, YES);
+ }
+ return rc;
+}
+
+/* Table 182 - Definition of TPMU_PUBLIC_PARMS Union <IN/OUT, S> */
+
+TPM_RC
+TPMU_PUBLIC_PARMS_Unmarshal(TPMU_PUBLIC_PARMS *target, BYTE **buffer, INT32 *size, UINT32 selector)
+{
+ TPM_RC rc = TPM_RC_SUCCESS;
+
+ switch (selector) {
+#if ALG_KEYEDHASH
+ case TPM_ALG_KEYEDHASH:
+ rc = TPMS_KEYEDHASH_PARMS_Unmarshal(&target->keyedHashDetail, buffer, size);
+ break;
+#endif
+#if ALG_SYMCIPHER
+ case TPM_ALG_SYMCIPHER:
+ rc = TPMS_SYMCIPHER_PARMS_Unmarshal(&target->symDetail, buffer, size);
+ break;
+#endif
+#if ALG_RSA
+ case TPM_ALG_RSA:
+ rc = TPMS_RSA_PARMS_Unmarshal(&target->rsaDetail, buffer, size);
+ break;
+#endif
+#if ALG_ECC
+ case TPM_ALG_ECC:
+ rc = TPMS_ECC_PARMS_Unmarshal(&target->eccDetail, buffer, size);
+ break;
+#endif
+ default:
+ rc = TPM_RC_SELECTOR;
+ }
+ return rc;
+}
+
+/* Table 183 - Definition of TPMT_PUBLIC_PARMS Structure */
+
+TPM_RC
+TPMT_PUBLIC_PARMS_Unmarshal(TPMT_PUBLIC_PARMS *target, BYTE **buffer, INT32 *size)
+{
+ TPM_RC rc = TPM_RC_SUCCESS;
+
+ if (rc == TPM_RC_SUCCESS) {
+ rc = TPMI_ALG_PUBLIC_Unmarshal(&target->type, buffer, size);
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ rc = TPMU_PUBLIC_PARMS_Unmarshal(&target->parameters, buffer, size, target->type);
+ }
+ return rc;
+}
+
+/* Table 191 - Definition of TPMT_PUBLIC Structure */
+
+TPM_RC
+TPMT_PUBLIC_Unmarshal(TPMT_PUBLIC *target, BYTE **buffer, INT32 *size, BOOL allowNull)
+{
+ TPM_RC rc = TPM_RC_SUCCESS;
+
+ if (rc == TPM_RC_SUCCESS) {
+ rc = TPMI_ALG_PUBLIC_Unmarshal(&target->type, buffer, size);
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ rc = TPMI_ALG_HASH_Unmarshal(&target->nameAlg, buffer, size, allowNull);
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ rc = TPMA_OBJECT_Unmarshal(&target->objectAttributes, buffer, size);
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ rc = TPM2B_DIGEST_Unmarshal(&target->authPolicy, buffer, size);
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ rc = TPMU_PUBLIC_PARMS_Unmarshal(&target->parameters, buffer, size, target->type);
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ rc = TPMU_PUBLIC_ID_Unmarshal(&target->unique, buffer, size, target->type);
+ }
+ return rc;
+}
+
+/* Table 192 - Definition of TPM2B_PUBLIC Structure */
+
+TPM_RC
+TPM2B_PUBLIC_Unmarshal(TPM2B_PUBLIC *target, BYTE **buffer, INT32 *size, BOOL allowNull)
+{
+ TPM_RC rc = TPM_RC_SUCCESS;
+
+ INT32 startSize;
+ if (rc == TPM_RC_SUCCESS) {
+ rc = UINT16_Unmarshal(&target->size, buffer, size);
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ if (target->size == 0) {
+ rc = TPM_RC_SIZE;
+ }
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ startSize = *size;
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ rc = TPMT_PUBLIC_Unmarshal(&target->publicArea, buffer, size, allowNull);
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ if (target->size != startSize - *size) {
+ rc = TPM_RC_SIZE;
+ target->size = 0; // libtpms added
+ }
+ }
+ return rc;
+}
+
+/* Table 2:193 - Definition of TPM2B_TEMPLATE Structure (StructuresTable()) */
+
+TPM_RC
+TPM2B_TEMPLATE_Unmarshal(TPM2B_TEMPLATE *target, BYTE **buffer, INT32 *size)
+{
+ TPM_RC rc = TPM_RC_SUCCESS;
+
+ if (rc == TPM_RC_SUCCESS) {
+ rc = TPM2B_Unmarshal(&target->b, sizeof(TPMT_PUBLIC), buffer, size);
+ }
+ return rc;
+}
+
+/* Table 187 - Definition of TPMU_SENSITIVE_COMPOSITE Union <IN/OUT, S> */
+
+TPM_RC
+TPMU_SENSITIVE_COMPOSITE_Unmarshal(TPMU_SENSITIVE_COMPOSITE *target, BYTE **buffer, INT32 *size, UINT32 selector)
+{
+ TPM_RC rc = TPM_RC_SUCCESS;
+
+ switch (selector) {
+#if ALG_RSA
+ case TPM_ALG_RSA:
+ rc = TPM2B_PRIVATE_KEY_RSA_Unmarshal(&target->rsa, buffer, size);
+ break;
+#endif
+#if ALG_ECC
+ case TPM_ALG_ECC:
+ rc = TPM2B_ECC_PARAMETER_Unmarshal(&target->ecc, buffer, size);
+ break;
+#endif
+#if ALG_KEYEDHASH
+ case TPM_ALG_KEYEDHASH:
+ rc = TPM2B_SENSITIVE_DATA_Unmarshal(&target->bits, buffer, size);
+ break;
+#endif
+#if ALG_SYMCIPHER
+ case TPM_ALG_SYMCIPHER:
+ rc = TPM2B_SYM_KEY_Unmarshal(&target->sym, buffer, size);
+ break;
+#endif
+ default:
+ rc = TPM_RC_SELECTOR;
+ }
+ return rc;
+}
+
+/* Table 188 - Definition of TPMT_SENSITIVE Structure */
+
+TPM_RC
+TPMT_SENSITIVE_Unmarshal(TPMT_SENSITIVE *target, BYTE **buffer, INT32 *size)
+{
+ TPM_RC rc = TPM_RC_SUCCESS;
+
+ if (rc == TPM_RC_SUCCESS) {
+ rc = TPMI_ALG_PUBLIC_Unmarshal(&target->sensitiveType, buffer, size);
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ rc = TPM2B_AUTH_Unmarshal(&target->authValue, buffer, size);
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ rc = TPM2B_DIGEST_Unmarshal(&target->seedValue, buffer, size);
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ rc = TPMU_SENSITIVE_COMPOSITE_Unmarshal(&target->sensitive, buffer, size, target->sensitiveType);
+ }
+ return rc;
+}
+
+/* Table 189 - Definition of TPM2B_SENSITIVE Structure <IN/OUT> */
+
+TPM_RC
+TPM2B_SENSITIVE_Unmarshal(TPM2B_SENSITIVE *target, BYTE **buffer, INT32 *size)
+{
+ TPM_RC rc = TPM_RC_SUCCESS;
+
+ INT32 startSize;
+ if (rc == TPM_RC_SUCCESS) {
+ rc = UINT16_Unmarshal(&target->size, buffer, size);
+ }
+ if (target->size != 0) {
+ if (rc == TPM_RC_SUCCESS) {
+ startSize = *size;
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ rc = TPMT_SENSITIVE_Unmarshal(&target->sensitiveArea, buffer, size);
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ if (target->size != startSize - *size) {
+ rc = TPM_RC_SIZE;
+ target->size = 0; // libtpms added
+ }
+ }
+ }
+ return rc;
+}
+
+/* Table 191 - Definition of TPM2B_PRIVATE Structure <IN/OUT, S> */
+
+TPM_RC
+TPM2B_PRIVATE_Unmarshal(TPM2B_PRIVATE *target, BYTE **buffer, INT32 *size)
+{
+ TPM_RC rc = TPM_RC_SUCCESS;
+
+ if (rc == TPM_RC_SUCCESS) {
+ rc = TPM2B_Unmarshal(&target->b, sizeof(_PRIVATE), buffer, size);
+ }
+ return rc;
+}
+
+/* Table 193 - Definition of TPM2B_ID_OBJECT Structure <IN/OUT> */
+
+TPM_RC
+TPM2B_ID_OBJECT_Unmarshal(TPM2B_ID_OBJECT *target, BYTE **buffer, INT32 *size)
+{
+ TPM_RC rc = TPM_RC_SUCCESS;
+
+ if (rc == TPM_RC_SUCCESS) {
+ rc = TPM2B_Unmarshal(&target->b, sizeof(TPMS_ID_OBJECT), buffer, size);
+ }
+ return rc;
+}
+
+/* Table 196 - Definition of (UINT32) TPMA_NV Bits */
+
+TPM_RC
+TPMA_NV_Unmarshal(TPMA_NV *target, BYTE **buffer, INT32 *size)
+{
+ TPM_RC rc = TPM_RC_SUCCESS;
+ TPMA_NV orig_target = *target; // libtpms added
+
+ if (rc == TPM_RC_SUCCESS) {
+ rc = UINT32_Unmarshal((UINT32 *)target, buffer, size); /* libtpms changed */
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ if (*target & TPMA_NV_RESERVED) {
+ rc = TPM_RC_RESERVED_BITS;
+ *target = orig_target; // libtpms added
+ }
+ }
+ return rc;
+}
+
+/* Table 197 - Definition of TPMS_NV_PUBLIC Structure */
+
+TPM_RC
+TPMS_NV_PUBLIC_Unmarshal(TPMS_NV_PUBLIC *target, BYTE **buffer, INT32 *size)
+{
+ TPM_RC rc = TPM_RC_SUCCESS;
+
+ if (rc == TPM_RC_SUCCESS) {
+ rc = TPMI_RH_NV_INDEX_Unmarshal(&target->nvIndex, buffer, size);
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ rc = TPMI_ALG_HASH_Unmarshal(&target->nameAlg, buffer, size, NO);
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ rc = TPMA_NV_Unmarshal(&target->attributes, buffer, size);
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ rc = TPM2B_DIGEST_Unmarshal(&target->authPolicy, buffer, size);
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ rc = UINT16_Unmarshal(&target->dataSize, buffer, size);
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ if (target->dataSize > MAX_NV_INDEX_SIZE) {
+ rc = TPM_RC_SIZE;
+ target->dataSize = 0; // libtpms added
+ }
+ }
+ return rc;
+}
+
+/* Table 198 - Definition of TPM2B_NV_PUBLIC Structure */
+
+TPM_RC
+TPM2B_NV_PUBLIC_Unmarshal(TPM2B_NV_PUBLIC *target, BYTE **buffer, INT32 *size)
+{
+ TPM_RC rc = TPM_RC_SUCCESS;
+
+ INT32 startSize;
+ if (rc == TPM_RC_SUCCESS) {
+ rc = UINT16_Unmarshal(&target->size, buffer, size);
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ if (target->size == 0) {
+ rc = TPM_RC_SIZE;
+ }
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ startSize = *size;
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ rc = TPMS_NV_PUBLIC_Unmarshal(&target->nvPublic, buffer, size);
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ if (target->size != startSize - *size) {
+ rc = TPM_RC_SIZE;
+ target->size = 0; // libtpms added
+ }
+ }
+ return rc;
+}
+
+/* Table 199 - Definition of TPM2B_CONTEXT_SENSITIVE Structure <IN/OUT> */
+
+#if 0 // libtpms added
+TPM_RC
+TPM2B_CONTEXT_SENSITIVE_Unmarshal(TPM2B_CONTEXT_SENSITIVE *target, BYTE **buffer, INT32 *size)
+{
+ TPM_RC rc = TPM_RC_SUCCESS;
+
+ if (rc == TPM_RC_SUCCESS) {
+ rc = TPM2B_Unmarshal(&target->b, MAX_CONTEXT_SIZE, buffer, size);
+ }
+ return rc;
+}
+#endif // libtpms added
+
+/* Table 201 - Definition of TPM2B_CONTEXT_DATA Structure <IN/OUT> */
+
+TPM_RC
+TPM2B_CONTEXT_DATA_Unmarshal(TPM2B_CONTEXT_DATA *target, BYTE **buffer, INT32 *size)
+{
+ TPM_RC rc = TPM_RC_SUCCESS;
+
+ if (rc == TPM_RC_SUCCESS) {
+ rc = TPM2B_Unmarshal(&target->b, sizeof(TPMS_CONTEXT_DATA), buffer, size);
+ }
+ return rc;
+}
+
+/* Table 202 - Definition of TPMS_CONTEXT Structure */
+
+TPM_RC
+TPMS_CONTEXT_Unmarshal(TPMS_CONTEXT *target, BYTE **buffer, INT32 *size)
+{
+ TPM_RC rc = TPM_RC_SUCCESS;
+ INT32 orig_size = *size; // libtpms added
+
+ if (rc == TPM_RC_SUCCESS) {
+ rc = UINT64_Unmarshal(&target->sequence, buffer, size);
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ rc = TPMI_DH_SAVED_Unmarshal(&target->savedHandle, buffer, size, NO);
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ rc = TPMI_RH_HIERARCHY_Unmarshal(&target->hierarchy, buffer, size, YES);
+ }
+ if (rc == TPM_RC_SUCCESS) {
+ rc = TPM2B_CONTEXT_DATA_Unmarshal(&target->contextBlob, buffer, size);
+ }
+ // libtpms added begin
+ if (rc == TPM_RC_SUCCESS) {
+ if (*size > 0) {
+ /* Windows 2019 server pads the command TPM_ContextLoad up to the value of
+ * TPM_PT_MAX_OBJECT_CONTENT for the TPMS_CONTEXT part and we end up with
+ * left-over padding bytes here that will make the TPM2_ContextLoad command
+ * fail. This is because we don't just write an OBJECT as the context but use
+ * ANY_OBJECT_Marshal to write it, which consumes less bytes. We had to do
+ * this due to a Linux TPM resource manager bug that couldn't deal with the
+ * larger context sizes once RSA 3072 was enabled and it ran out of memory
+ * when receiving contexts.
+ * Luckily only one command needs TPMS_CONTEXT unmarshalled, so we can adjust
+ * for the left-over padding here but also ONLY do this if
+ * 'orig_size' == value(TPM_PT_MAX_OBJECT_CONTENT).
+ */
+ static UINT32 tpm_pt_max_object_context;
+
+ if (tpm_pt_max_object_context == 0) {
+ TPML_TAGGED_TPM_PROPERTY tttp;
+
+ TPMCapGetProperties(TPM_PT_MAX_OBJECT_CONTEXT, 1, &tttp);
+ if (tttp.count == 1)
+ tpm_pt_max_object_context = tttp.tpmProperty[0].value;
+ }
+ if ((UINT32)orig_size == tpm_pt_max_object_context)
+ *size = 0; /* consume the padding bytes */
+ }
+ }
+ // libtpms added end
+ return rc;
+}
+
+/* Table 225 - Definition of (UINT32) TPM_AT Constants */
+
+TPM_RC
+TPM_AT_Unmarshal(TPM_AT *target, BYTE **buffer, INT32 *size)
+{
+ TPM_RC rc = TPM_RC_SUCCESS;
+
+ if (rc == TPM_RC_SUCCESS) {
+ rc = UINT32_Unmarshal(target, buffer, size);
+ }
+ return rc;
+}
diff --git a/src/tpm2/Unmarshal_fp.h b/src/tpm2/Unmarshal_fp.h
new file mode 100644
index 0000000..e541347
--- /dev/null
+++ b/src/tpm2/Unmarshal_fp.h
@@ -0,0 +1,477 @@
+/********************************************************************************/
+/* */
+/* Unmarshal Prototypes */
+/* Written by Ken Goldman */
+/* IBM Thomas J. Watson Research Center */
+/* $Id: Unmarshal_fp.h 1603 2020-04-03 17:48:43Z kgoldman $ */
+/* */
+/* Licenses and Notices */
+/* */
+/* 1. Copyright Licenses: */
+/* */
+/* - Trusted Computing Group (TCG) grants to the user of the source code in */
+/* this specification (the "Source Code") a worldwide, irrevocable, */
+/* nonexclusive, royalty free, copyright license to reproduce, create */
+/* derivative works, distribute, display and perform the Source Code and */
+/* derivative works thereof, and to grant others the rights granted herein. */
+/* */
+/* - The TCG grants to the user of the other parts of the specification */
+/* (other than the Source Code) the rights to reproduce, distribute, */
+/* display, and perform the specification solely for the purpose of */
+/* developing products based on such documents. */
+/* */
+/* 2. Source Code Distribution Conditions: */
+/* */
+/* - Redistributions of Source Code must retain the above copyright licenses, */
+/* this list of conditions and the following disclaimers. */
+/* */
+/* - Redistributions in binary form must reproduce the above copyright */
+/* licenses, this list of conditions and the following disclaimers in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* 3. Disclaimers: */
+/* */
+/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
+/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
+/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
+/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
+/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
+/* information on specification licensing rights available through TCG */
+/* membership agreements. */
+/* */
+/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
+/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
+/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
+/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
+/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
+/* */
+/* - Without limitation, TCG and its members and licensors disclaim all */
+/* liability, including liability for infringement of any proprietary */
+/* rights, relating to use of information in this specification and to the */
+/* implementation of this specification, and TCG disclaims all liability for */
+/* cost of procurement of substitute goods or services, lost profits, loss */
+/* of use, loss of data or any incidental, consequential, direct, indirect, */
+/* or special damages, whether under contract, tort, warranty or otherwise, */
+/* arising in any way out of use or reliance upon this specification or any */
+/* information herein. */
+/* */
+/* (c) Copyright IBM Corp. and others, 2012 - 2019 */
+/* */
+/********************************************************************************/
+
+/* rev 136 */
+
+#ifndef UNMARSHAL_FP_H
+#define UNMARSHAL_FP_H
+
+#include "Tpm.h"
+#include "TpmTypes.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+ LIB_EXPORT TPM_RC
+ UINT8_Unmarshal(UINT8 *target, BYTE **buffer, INT32 *size);
+ LIB_EXPORT TPM_RC
+ INT8_Unmarshal(INT8 *target, BYTE **buffer, INT32 *size);
+ LIB_EXPORT TPM_RC
+ UINT16_Unmarshal(UINT16 *target, BYTE **buffer, INT32 *size);
+ LIB_EXPORT TPM_RC
+ UINT32_Unmarshal(UINT32 *target, BYTE **buffer, INT32 *size);
+ LIB_EXPORT TPM_RC
+ UINT64_Unmarshal(UINT64 *target, BYTE **buffer, INT32 *size);
+ LIB_EXPORT TPM_RC
+ Array_Unmarshal(BYTE *targetBuffer, UINT16 targetSize, BYTE **buffer, INT32 *size);
+ LIB_EXPORT TPM_RC
+ TPM2B_Unmarshal(TPM2B *target, UINT16 targetSize, BYTE **buffer, INT32 *size);
+ LIB_EXPORT TPM_RC
+ TPM_KEY_BITS_Unmarshal(TPM_KEY_BITS *target, BYTE **buffer, INT32 *size);
+#if 0
+ LIB_EXPORT TPM_RC
+ TPM_GENERATED_Unmarshal(TPM_GENERATED *target, BYTE **buffer, INT32 *size);
+#endif
+ LIB_EXPORT TPM_RC
+ TPM_ALG_ID_Unmarshal(TPM_ALG_ID *target, BYTE **buffer, INT32 *size);
+ LIB_EXPORT TPM_RC
+ TPM_ECC_CURVE_Unmarshal(TPM_ECC_CURVE *target, BYTE **buffer, INT32 *size);
+ LIB_EXPORT TPM_RC
+ TPM_CC_Unmarshal(TPM_RC *target, BYTE **buffer, INT32 *size);
+ LIB_EXPORT TPM_RC
+ TPM_CLOCK_ADJUST_Unmarshal(TPM_CLOCK_ADJUST *target, BYTE **buffer, INT32 *size);
+ LIB_EXPORT TPM_RC
+ TPM_EO_Unmarshal(TPM_EO *target, BYTE **buffer, INT32 *size);
+ LIB_EXPORT TPM_RC
+ TPM_ST_Unmarshal(TPM_ST *target, BYTE **buffer, INT32 *size);
+ LIB_EXPORT TPM_RC
+ TPM_SU_Unmarshal(TPM_SU *target, BYTE **buffer, INT32 *size);
+ LIB_EXPORT TPM_RC
+ TPM_SE_Unmarshal(TPM_SE *target, BYTE **buffer, INT32 *size);
+ LIB_EXPORT TPM_RC
+ TPM_CAP_Unmarshal(TPM_CAP *target, BYTE **buffer, INT32 *size);
+ LIB_EXPORT TPM_RC
+ TPM_PT_Unmarshal(TPM_HANDLE *target, BYTE **buffer, INT32 *size);
+ LIB_EXPORT TPM_RC
+ TPM_PT_PCR_Unmarshal(TPM_PT_PCR *target, BYTE **buffer, INT32 *size);
+ LIB_EXPORT TPM_RC
+ TPM_HANDLE_Unmarshal(TPM_HANDLE *target, BYTE **buffer, INT32 *size);
+ LIB_EXPORT TPM_RC
+ TPMA_ALGORITHM_Unmarshal(TPMA_ALGORITHM *target, BYTE **buffer, INT32 *size);
+ LIB_EXPORT TPM_RC
+ TPMA_OBJECT_Unmarshal(TPMA_OBJECT *target, BYTE **buffer, INT32 *size);
+ LIB_EXPORT TPM_RC
+ TPMA_SESSION_Unmarshal(TPMA_SESSION *target, BYTE **buffer, INT32 *size);
+ LIB_EXPORT TPM_RC
+ TPMA_LOCALITY_Unmarshal(TPMA_LOCALITY *target, BYTE **buffer, INT32 *size);
+ LIB_EXPORT TPM_RC
+ TPMA_CC_Unmarshal(TPMA_CC *target, BYTE **buffer, INT32 *size);
+ LIB_EXPORT TPM_RC
+ TPMI_YES_NO_Unmarshal(TPMI_YES_NO *target, BYTE **buffer, INT32 *size);
+ LIB_EXPORT TPM_RC
+ TPMI_DH_OBJECT_Unmarshal(TPMI_DH_OBJECT *target, BYTE **buffer, INT32 *size, BOOL allowNull);
+ LIB_EXPORT TPM_RC
+ TPMI_DH_PARENT_Unmarshal(TPMI_DH_PARENT *target, BYTE **buffer, INT32 *size, BOOL allowNull);
+ LIB_EXPORT TPM_RC
+ TPMI_DH_PERSISTENT_Unmarshal(TPMI_DH_PERSISTENT *target, BYTE **buffer, INT32 *size);
+ LIB_EXPORT TPM_RC
+ TPMI_DH_ENTITY_Unmarshal(TPMI_DH_ENTITY *target, BYTE **buffer, INT32 *size, BOOL allowNull);
+ LIB_EXPORT TPM_RC
+ TPMI_DH_PCR_Unmarshal(TPMI_DH_PCR *target, BYTE **buffer, INT32 *size, BOOL allowNull);
+ LIB_EXPORT TPM_RC
+ TPMI_SH_AUTH_SESSION_Unmarshal(TPMI_SH_AUTH_SESSION *target, BYTE **buffer, INT32 *size, BOOL allowPwd);
+ LIB_EXPORT TPM_RC
+ TPMI_SH_HMAC_Unmarshal(TPMI_SH_HMAC *target, BYTE **buffer, INT32 *size);
+ LIB_EXPORT TPM_RC
+ TPMI_SH_POLICY_Unmarshal(TPMI_SH_POLICY *target, BYTE **buffer, INT32 *size);
+ LIB_EXPORT TPM_RC
+ TPMI_DH_CONTEXT_Unmarshal(TPMI_DH_CONTEXT *target, BYTE **buffer, INT32 *size);
+ LIB_EXPORT TPM_RC
+ TPMI_DH_SAVED_Unmarshal(TPMI_DH_SAVED *target, BYTE **buffer, INT32 *size, BOOL allowNull);
+ LIB_EXPORT TPM_RC
+ TPMI_RH_HIERARCHY_Unmarshal(TPMI_RH_HIERARCHY *target, BYTE **buffer, INT32 *size, BOOL allowNull);
+ LIB_EXPORT TPM_RC
+ TPMI_RH_ENABLES_Unmarshal(TPMI_RH_ENABLES *target, BYTE **buffer, INT32 *size, BOOL allowNull);
+ LIB_EXPORT TPM_RC
+ TPMI_RH_HIERARCHY_AUTH_Unmarshal(TPMI_RH_HIERARCHY_AUTH *target, BYTE **buffer, INT32 *size);
+ LIB_EXPORT TPM_RC
+ TPMI_RH_HIERARCHY_POLICY_Unmarshal(TPMI_RH_HIERARCHY_POLICY *target, BYTE **buffer, INT32 *size);
+ LIB_EXPORT TPM_RC
+ TPMI_RH_PLATFORM_Unmarshal(TPMI_RH_PLATFORM *target, BYTE **buffer, INT32 *size);
+ LIB_EXPORT TPM_RC
+ TPMI_RH_ENDORSEMENT_Unmarshal(TPMI_RH_ENDORSEMENT *target, BYTE **buffer, INT32 *size, BOOL allowNull);
+ LIB_EXPORT TPM_RC
+ TPMI_RH_PROVISION_Unmarshal(TPMI_RH_PROVISION *target, BYTE **buffer, INT32 *size);
+ LIB_EXPORT TPM_RC
+ TPMI_RH_CLEAR_Unmarshal(TPMI_RH_CLEAR *target, BYTE **buffer, INT32 *size);
+ LIB_EXPORT TPM_RC
+ TPMI_RH_NV_AUTH_Unmarshal(TPMI_RH_NV_AUTH *target, BYTE **buffer, INT32 *size);
+ LIB_EXPORT TPM_RC
+ TPMI_RH_LOCKOUT_Unmarshal(TPMI_RH_LOCKOUT *target, BYTE **buffer, INT32 *size);
+ LIB_EXPORT TPM_RC
+ TPMI_RH_NV_INDEX_Unmarshal(TPMI_RH_NV_INDEX *target, BYTE **buffer, INT32 *size);
+ LIB_EXPORT TPM_RC
+ TPMI_RH_AC_Unmarshal(TPMI_RH_AC *target, BYTE **buffer, INT32 *size);
+ LIB_EXPORT TPM_RC
+ TPMI_RH_ACT_Unmarshal(TPMI_RH_ACT *target, BYTE **buffer, INT32 *size);
+ LIB_EXPORT TPM_RC
+ TPMI_ALG_HASH_Unmarshal(TPMI_ALG_HASH *target, BYTE **buffer, INT32 *size, BOOL allowNull);
+ LIB_EXPORT TPM_RC
+ TPMI_ALG_SYM_Unmarshal(TPMI_ALG_SYM *target, BYTE **buffer, INT32 *size, BOOL allowNull);
+ LIB_EXPORT TPM_RC
+ TPMI_ALG_SYM_OBJECT_Unmarshal(TPMI_ALG_SYM_OBJECT *target, BYTE **buffer, INT32 *size, BOOL allowNull);
+ LIB_EXPORT TPM_RC
+ TPMI_ALG_SYM_MODE_Unmarshal(TPMI_ALG_SYM_MODE *target, BYTE **buffer, INT32 *size, BOOL allowNull);
+ LIB_EXPORT TPM_RC
+ TPMI_ALG_KDF_Unmarshal(TPMI_ALG_KDF *target, BYTE **buffer, INT32 *size, BOOL allowNull);
+ LIB_EXPORT TPM_RC
+ TPMI_ALG_SIG_SCHEME_Unmarshal(TPMI_ALG_SIG_SCHEME *target, BYTE **buffer, INT32 *size, BOOL allowNull);
+ LIB_EXPORT TPM_RC
+ TPMI_ECC_KEY_EXCHANGE_Unmarshal(TPMI_ECC_KEY_EXCHANGE *target, BYTE **buffer, INT32 *size, BOOL allowNull);
+ LIB_EXPORT TPM_RC
+ TPMI_ST_COMMAND_TAG_Unmarshal(TPMI_ST_COMMAND_TAG *target, BYTE **buffer, INT32 *size);
+ LIB_EXPORT TPM_RC
+ TPMI_ALG_MAC_SCHEME_Unmarshal(TPMI_ALG_MAC_SCHEME *target, BYTE **buffer, INT32 *size, BOOL allowNull);
+ LIB_EXPORT TPM_RC
+ TPMI_ALG_CIPHER_MODE_Unmarshal(TPMI_ALG_CIPHER_MODE*target, BYTE **buffer, INT32 *size, BOOL allowNull);
+ LIB_EXPORT TPM_RC
+ TPMS_EMPTY_Unmarshal(TPMS_EMPTY *target, BYTE **buffer, INT32 *size);
+ LIB_EXPORT TPM_RC
+ TPMU_HA_Unmarshal(TPMU_HA *target, BYTE **buffer, INT32 *size, UINT32 selector);
+ LIB_EXPORT TPM_RC
+ TPMT_HA_Unmarshal(TPMT_HA *target, BYTE **buffer, INT32 *size, BOOL allowNull);
+ LIB_EXPORT TPM_RC
+ TPM2B_DIGEST_Unmarshal(TPM2B_DIGEST *target, BYTE **buffer, INT32 *size);
+ LIB_EXPORT TPM_RC
+ TPM2B_DATA_Unmarshal(TPM2B_DATA *target, BYTE **buffer, INT32 *size);
+ LIB_EXPORT TPM_RC
+ TPM2B_NONCE_Unmarshal(TPM2B_NONCE *target, BYTE **buffer, INT32 *size);
+ LIB_EXPORT TPM_RC
+ TPM2B_AUTH_Unmarshal(TPM2B_AUTH *target, BYTE **buffer, INT32 *size);
+ LIB_EXPORT TPM_RC
+ TPM2B_EVENT_Unmarshal(TPM2B_EVENT *target, BYTE **buffer, INT32 *size);
+ LIB_EXPORT TPM_RC
+ TPM2B_MAX_BUFFER_Unmarshal(TPM2B_MAX_BUFFER *target, BYTE **buffer, INT32 *size);
+ LIB_EXPORT TPM_RC
+ TPM2B_MAX_NV_BUFFER_Unmarshal(TPM2B_MAX_NV_BUFFER *target, BYTE **buffer, INT32 *size);
+ LIB_EXPORT TPM_RC
+ TPM2B_TIMEOUT_Unmarshal(TPM2B_TIMEOUT *target, BYTE **buffer, INT32 *size);
+ LIB_EXPORT TPM_RC
+ TPM2B_IV_Unmarshal(TPM2B_IV *target, BYTE **buffer, INT32 *size);
+ LIB_EXPORT TPM_RC
+ TPM2B_NAME_Unmarshal(TPM2B_NAME *target, BYTE **buffer, INT32 *size);
+ LIB_EXPORT TPM_RC
+ TPMS_PCR_SELECTION_Unmarshal(TPMS_PCR_SELECTION *target, BYTE **buffer, INT32 *size);
+ LIB_EXPORT TPM_RC
+ TPMT_TK_CREATION_Unmarshal(TPMT_TK_CREATION *target, BYTE **buffer, INT32 *size);
+ LIB_EXPORT TPM_RC
+ TPMT_TK_VERIFIED_Unmarshal(TPMT_TK_VERIFIED *target, BYTE **buffer, INT32 *size);
+ LIB_EXPORT TPM_RC
+ TPMT_TK_AUTH_Unmarshal(TPMT_TK_AUTH *target, BYTE **buffer, INT32 *size);
+ LIB_EXPORT TPM_RC
+ TPMT_TK_HASHCHECK_Unmarshal(TPMT_TK_HASHCHECK *target, BYTE **buffer, INT32 *size);
+ LIB_EXPORT TPM_RC
+ TPMS_ALG_PROPERTY_Unmarshal(TPMS_ALG_PROPERTY *target, BYTE **buffer, INT32 *size);
+ LIB_EXPORT TPM_RC
+ TPMS_TAGGED_PROPERTY_Unmarshal(TPMS_TAGGED_PROPERTY *target, BYTE **buffer, INT32 *size);
+ LIB_EXPORT TPM_RC
+ TPMS_TAGGED_PCR_SELECT_Unmarshal(TPMS_TAGGED_PCR_SELECT *target, BYTE **buffer, INT32 *size);
+ LIB_EXPORT TPM_RC
+ TPML_CC_Unmarshal(TPML_CC *target, BYTE **buffer, INT32 *size);
+ LIB_EXPORT TPM_RC
+ TPMS_TAGGED_POLICY_Unmarshal(TPMS_TAGGED_POLICY *target, BYTE **buffer, INT32 *size);
+ LIB_EXPORT TPM_RC
+ TPML_CCA_Unmarshal(TPML_CCA *target, BYTE **buffer, INT32 *size);
+ LIB_EXPORT TPM_RC
+ TPML_ALG_Unmarshal(TPML_ALG *target, BYTE **buffer, INT32 *size);
+ LIB_EXPORT TPM_RC
+ TPML_HANDLE_Unmarshal(TPML_HANDLE *target, BYTE **buffer, INT32 *size);
+ LIB_EXPORT TPM_RC
+ TPML_DIGEST_Unmarshal(TPML_DIGEST *target, BYTE **buffer, INT32 *size);
+ LIB_EXPORT TPM_RC
+ TPML_DIGEST_VALUES_Unmarshal(TPML_DIGEST_VALUES *target, BYTE **buffer, INT32 *size);
+ LIB_EXPORT TPM_RC
+ TPML_PCR_SELECTION_Unmarshal(TPML_PCR_SELECTION *target, BYTE **buffer, INT32 *size);
+#if 0 /* libtpms added */
+ LIB_EXPORT TPM_RC
+ TPML_ALG_PROPERTY_Unmarshal(TPML_ALG_PROPERTY *target, BYTE **buffer, INT32 *size);
+ LIB_EXPORT TPM_RC
+ TPML_TAGGED_TPM_PROPERTY_Unmarshal(TPML_TAGGED_TPM_PROPERTY *target, BYTE **buffer, INT32 *size);
+ LIB_EXPORT TPM_RC
+ TPML_TAGGED_PCR_PROPERTY_Unmarshal(TPML_TAGGED_PCR_PROPERTY *target, BYTE **buffer, INT32 *size);
+ LIB_EXPORT TPM_RC
+ TPML_ECC_CURVE_Unmarshal(TPML_ECC_CURVE *target, BYTE **buffer, INT32 *size);
+ LIB_EXPORT TPM_RC
+ TPML_TAGGED_POLICY_Unmarshal(TPML_TAGGED_POLICY *target, BYTE **buffer, INT32 *size);
+ LIB_EXPORT TPM_RC
+ TPMU_CAPABILITIES_Unmarshal(TPMU_CAPABILITIES *target, BYTE **buffer, INT32 *size, UINT32 selector);
+ LIB_EXPORT TPM_RC
+ TPMS_CLOCK_INFO_Unmarshal(TPMS_CLOCK_INFO *target, BYTE **buffer, INT32 *size);
+ LIB_EXPORT TPM_RC
+ TPMS_TIME_INFO_Unmarshal(TPMS_TIME_INFO *target, BYTE **buffer, INT32 *size);
+ LIB_EXPORT TPM_RC
+ TPMS_TIME_ATTEST_INFO_Unmarshal(TPMS_TIME_ATTEST_INFO *target, BYTE **buffer, INT32 *size);
+ LIB_EXPORT TPM_RC
+ TPMS_CERTIFY_INFO_Unmarshal(TPMS_CERTIFY_INFO *target, BYTE **buffer, INT32 *size);
+ LIB_EXPORT TPM_RC
+ TPMS_QUOTE_INFO_Unmarshal(TPMS_QUOTE_INFO *target, BYTE **buffer, INT32 *size);
+ LIB_EXPORT TPM_RC
+ TPMS_COMMAND_AUDIT_INFO_Unmarshal(TPMS_COMMAND_AUDIT_INFO *target, BYTE **buffer, INT32 *size);
+ LIB_EXPORT TPM_RC
+ TPMS_SESSION_AUDIT_INFO_Unmarshal(TPMS_SESSION_AUDIT_INFO *target, BYTE **buffer, INT32 *size);
+ LIB_EXPORT TPM_RC
+ TPMS_CREATION_INFO_Unmarshal(TPMS_CREATION_INFO *target, BYTE **buffer, INT32 *size);
+ LIB_EXPORT TPM_RC
+ TPMS_NV_CERTIFY_INFO_Unmarshal(TPMS_NV_CERTIFY_INFO *target, BYTE **buffer, INT32 *size);
+ LIB_EXPORT TPM_RC
+ TPMI_ST_ATTEST_Unmarshal(TPMI_ST_ATTEST *target, BYTE **buffer, INT32 *size);
+ LIB_EXPORT TPM_RC
+ TPMU_ATTEST_Unmarshal(TPMU_ATTEST *target, BYTE **buffer, INT32 *size, UINT32 selector);
+ LIB_EXPORT TPM_RC
+ TPMS_ATTEST_Unmarshal(TPMS_ATTEST *target, BYTE **buffer, INT32 *size);
+ LIB_EXPORT TPM_RC
+ TPM2B_ATTEST_Unmarshal(TPM2B_ATTEST *target, BYTE **buffer, INT32 *size);
+ LIB_EXPORT TPM_RC
+ TPMS_CAPABILITY_DATA_Unmarshal(TPMS_CAPABILITY_DATA *target, BYTE **buffer, INT32 *size);
+#endif /* libtpms added */
+ LIB_EXPORT TPM_RC
+ TPMI_AES_KEY_BITS_Unmarshal(TPMI_AES_KEY_BITS *target, BYTE **buffer, INT32 *size);
+ LIB_EXPORT TPM_RC
+ TPMI_CAMELLIA_KEY_BITS_Unmarshal(TPMI_CAMELLIA_KEY_BITS *target, BYTE **buffer, INT32 *size);
+ LIB_EXPORT TPM_RC /* libtpms added */
+ TPMI_TDES_KEY_BITS_Unmarshal(TPMI_SM4_KEY_BITS *target, BYTE **buffer, INT32 *size);
+ LIB_EXPORT TPM_RC
+ TPMU_SYM_KEY_BITS_Unmarshal(TPMU_SYM_KEY_BITS *target, BYTE **buffer, INT32 *size, UINT32 selector);
+ LIB_EXPORT TPM_RC
+ TPMU_SYM_MODE_Unmarshal(TPMU_SYM_MODE *target, BYTE **buffer, INT32 *size, UINT32 selector);
+ LIB_EXPORT TPM_RC
+ TPMT_SYM_DEF_Unmarshal(TPMT_SYM_DEF *target, BYTE **buffer, INT32 *size, BOOL allowNull);
+ LIB_EXPORT TPM_RC
+ TPMT_SYM_DEF_OBJECT_Unmarshal(TPMT_SYM_DEF_OBJECT *target, BYTE **buffer, INT32 *size, BOOL allowNull);
+ LIB_EXPORT TPM_RC
+ TPM2B_SYM_KEY_Unmarshal(TPM2B_SYM_KEY *target, BYTE **buffer, INT32 *size);
+ LIB_EXPORT TPM_RC
+ TPMS_SYMCIPHER_PARMS_Unmarshal(TPMS_SYMCIPHER_PARMS *target, BYTE **buffer, INT32 *size);
+ LIB_EXPORT TPM_RC
+ TPM2B_LABEL_Unmarshal(TPM2B_LABEL *target, BYTE **buffer, INT32 *size);
+ LIB_EXPORT TPM_RC
+ TPMS_DERIVE_Unmarshal(TPMS_DERIVE *target, BYTE **buffer, INT32 *size);
+ LIB_EXPORT TPM_RC
+ TPM2B_SENSITIVE_DATA_Unmarshal(TPM2B_SENSITIVE_DATA *target, BYTE **buffer, INT32 *size);
+ LIB_EXPORT TPM_RC
+ TPMS_SENSITIVE_CREATE_Unmarshal(TPMS_SENSITIVE_CREATE *target, BYTE **buffer, INT32 *size);
+ LIB_EXPORT TPM_RC
+ TPM2B_SENSITIVE_CREATE_Unmarshal(TPM2B_SENSITIVE_CREATE *target, BYTE **buffer, INT32 *size);
+ LIB_EXPORT TPM_RC
+ TPMS_SCHEME_HASH_Unmarshal(TPMS_SCHEME_HASH *target, BYTE **buffer, INT32 *size);
+ LIB_EXPORT TPM_RC
+ TPMS_SCHEME_ECDAA_Unmarshal(TPMS_SCHEME_ECDAA *target, BYTE **buffer, INT32 *size) ;
+ LIB_EXPORT TPM_RC
+ TPMI_ALG_KEYEDHASH_SCHEME_Unmarshal(TPMI_ALG_KEYEDHASH_SCHEME *target, BYTE **buffer, INT32 *size, BOOL allowNull);
+ LIB_EXPORT TPM_RC
+ TPMS_SCHEME_HMAC_Unmarshal(TPMS_SCHEME_HMAC *target, BYTE **buffer, INT32 *size);
+ LIB_EXPORT TPM_RC
+ TPMS_SCHEME_XOR_Unmarshal(TPMS_SCHEME_XOR *target, BYTE **buffer, INT32 *size);
+ LIB_EXPORT TPM_RC
+ TPMU_SCHEME_KEYEDHASH_Unmarshal(TPMU_SCHEME_KEYEDHASH *target, BYTE **buffer, INT32 *size, UINT32 selector);
+ LIB_EXPORT TPM_RC
+ TPMT_KEYEDHASH_SCHEME_Unmarshal(TPMT_KEYEDHASH_SCHEME *target, BYTE **buffer, INT32 *size, BOOL allowNull);
+ LIB_EXPORT TPM_RC
+ TPMS_SIG_SCHEME_ECDAA_Unmarshal(TPMS_SIG_SCHEME_ECDAA *target, BYTE **buffer, INT32 *size);
+ LIB_EXPORT TPM_RC
+ TPMS_SIG_SCHEME_ECDSA_Unmarshal(TPMS_SIG_SCHEME_ECDSA *target, BYTE **buffer, INT32 *size);
+ LIB_EXPORT TPM_RC
+ TPMS_SIG_SCHEME_ECSCHNORR_Unmarshal(TPMS_SIG_SCHEME_ECSCHNORR *target, BYTE **buffer, INT32 *size);
+ LIB_EXPORT TPM_RC
+ TPMS_SIG_SCHEME_RSAPSS_Unmarshal(TPMS_SIG_SCHEME_RSAPSS *target, BYTE **buffer, INT32 *size);
+ LIB_EXPORT TPM_RC
+ TPMS_SIG_SCHEME_RSASSA_Unmarshal(TPMS_SIG_SCHEME_RSASSA *target, BYTE **buffer, INT32 *size);
+ LIB_EXPORT TPM_RC
+ TPMS_SIG_SCHEME_SM2_Unmarshal(TPMS_SIG_SCHEME_SM2 *target, BYTE **buffer, INT32 *size);
+ LIB_EXPORT TPM_RC
+ TPMU_SIG_SCHEME_Unmarshal(TPMU_SIG_SCHEME *target, BYTE **buffer, INT32 *size, UINT32 selector);
+ LIB_EXPORT TPM_RC
+ TPMT_SIG_SCHEME_Unmarshal(TPMT_SIG_SCHEME *target, BYTE **buffer, INT32 *size, BOOL allowNull);
+ LIB_EXPORT TPM_RC
+ TPMS_ENC_SCHEME_OAEP_Unmarshal(TPMS_ENC_SCHEME_OAEP *target, BYTE **buffer, INT32 *size);
+ LIB_EXPORT TPM_RC
+ TPMS_ENC_SCHEME_RSAES_Unmarshal(TPMS_ENC_SCHEME_RSAES *target, BYTE **buffer, INT32 *size);
+ LIB_EXPORT TPM_RC
+ TPMS_KEY_SCHEME_ECDH_Unmarshal(TPMS_KEY_SCHEME_ECDH *target, BYTE **buffer, INT32 *size);
+ LIB_EXPORT TPM_RC
+ TPMS_KEY_SCHEME_ECMQV_Unmarshal(TPMS_KEY_SCHEME_ECMQV *target, BYTE **buffer, INT32 *size);
+ LIB_EXPORT TPM_RC
+ TPMS_KDF_SCHEME_KDF1_SP800_108_Unmarshal(TPMS_KDF_SCHEME_KDF1_SP800_108 *target, BYTE **buffer, INT32 *size);
+ LIB_EXPORT TPM_RC
+ TPMS_KDF_SCHEME_KDF1_SP800_56A_Unmarshal(TPMS_KDF_SCHEME_KDF1_SP800_56A *target, BYTE **buffer, INT32 *size);
+ LIB_EXPORT TPM_RC
+ TPMS_KDF_SCHEME_KDF2_Unmarshal(TPMS_KDF_SCHEME_KDF2 *target, BYTE **buffer, INT32 *size);
+ LIB_EXPORT TPM_RC
+ TPMS_KDF_SCHEME_MGF1_Unmarshal(TPMS_KDF_SCHEME_MGF1 *target, BYTE **buffer, INT32 *size);
+ LIB_EXPORT TPM_RC
+ TPMU_KDF_SCHEME_Unmarshal(TPMU_KDF_SCHEME *target, BYTE **buffer, INT32 *size, UINT32 selector);
+ LIB_EXPORT TPM_RC
+ TPMT_KDF_SCHEME_Unmarshal(TPMT_KDF_SCHEME *target, BYTE **buffer, INT32 *size, BOOL allowNull);
+#if 0 /* libtpms added */
+ LIB_EXPORT TPM_RC
+ TPMI_ALG_ASYM_SCHEME_Unmarshal(TPMI_ALG_ASYM_SCHEME *target, BYTE **buffer, INT32 *size, BOOL allowNull);
+#endif /* libtpms added */
+ LIB_EXPORT TPM_RC
+ TPMU_ASYM_SCHEME_Unmarshal(TPMU_ASYM_SCHEME *target, BYTE **buffer, INT32 *size, UINT32 selector);
+ LIB_EXPORT TPM_RC
+ TPMI_ALG_RSA_SCHEME_Unmarshal(TPMI_ALG_RSA_SCHEME *target, BYTE **buffer, INT32 *size, BOOL allowNull);
+ LIB_EXPORT TPM_RC
+ TPMT_RSA_SCHEME_Unmarshal(TPMT_RSA_SCHEME *target, BYTE **buffer, INT32 *size, BOOL allowNull);
+ LIB_EXPORT TPM_RC
+ TPMI_ALG_RSA_DECRYPT_Unmarshal(TPMI_ALG_RSA_DECRYPT *target, BYTE **buffer, INT32 *size, BOOL allowNull);
+ LIB_EXPORT TPM_RC
+ TPMT_RSA_DECRYPT_Unmarshal(TPMT_RSA_DECRYPT *target, BYTE **buffer, INT32 *size, BOOL allowNull);
+ LIB_EXPORT TPM_RC
+ TPM2B_PUBLIC_KEY_RSA_Unmarshal(TPM2B_PUBLIC_KEY_RSA *target, BYTE **buffer, INT32 *size);
+ LIB_EXPORT TPM_RC
+ TPMI_RSA_KEY_BITS_Unmarshal(TPMI_RSA_KEY_BITS *target, BYTE **buffer, INT32 *size);
+ LIB_EXPORT TPM_RC
+ TPM2B_PRIVATE_KEY_RSA_Unmarshal(TPM2B_PRIVATE_KEY_RSA *target, BYTE **buffer, INT32 *size);
+ LIB_EXPORT TPM_RC
+ TPM2B_ECC_PARAMETER_Unmarshal(TPM2B_ECC_PARAMETER *target, BYTE **buffer, INT32 *size);
+ LIB_EXPORT TPM_RC
+ TPMS_ECC_POINT_Unmarshal(TPMS_ECC_POINT *target, BYTE **buffer, INT32 *size);
+ LIB_EXPORT TPM_RC
+ TPM2B_ECC_POINT_Unmarshal(TPM2B_ECC_POINT *target, BYTE **buffer, INT32 *size);
+ LIB_EXPORT TPM_RC
+ TPMI_ALG_ECC_SCHEME_Unmarshal(TPMI_ALG_ECC_SCHEME *target, BYTE **buffer, INT32 *size, BOOL allowNull);
+ LIB_EXPORT TPM_RC
+ TPMI_ECC_CURVE_Unmarshal(TPMI_ECC_CURVE *target, BYTE **buffer, INT32 *size);
+ LIB_EXPORT TPM_RC
+ TPMT_ECC_SCHEME_Unmarshal(TPMT_ECC_SCHEME *target, BYTE **buffer, INT32 *size, BOOL allowNull);
+ LIB_EXPORT TPM_RC
+ TPMS_SIGNATURE_RSA_Unmarshal(TPMS_SIGNATURE_RSA *target, BYTE **buffer, INT32 *size);
+ LIB_EXPORT TPM_RC
+ TPMS_SIGNATURE_RSASSA_Unmarshal(TPMS_SIGNATURE_RSASSA *target, BYTE **buffer, INT32 *size);
+ LIB_EXPORT TPM_RC
+ TPMS_SIGNATURE_RSAPSS_Unmarshal(TPMS_SIGNATURE_RSAPSS *target, BYTE **buffer, INT32 *size);
+ LIB_EXPORT TPM_RC
+ TPMS_SIGNATURE_ECC_Unmarshal(TPMS_SIGNATURE_ECC *target, BYTE **buffer, INT32 *size);
+ LIB_EXPORT TPM_RC
+ TPMS_SIGNATURE_ECDSA_Unmarshal(TPMS_SIGNATURE_ECDSA *target, BYTE **buffer, INT32 *size);
+ LIB_EXPORT TPM_RC
+ TPMS_SIGNATURE_ECDAA_Unmarshal(TPMS_SIGNATURE_ECDAA *target, BYTE **buffer, INT32 *size);
+ LIB_EXPORT TPM_RC
+ TPMS_SIGNATURE_SM2_Unmarshal(TPMS_SIGNATURE_SM2 *target, BYTE **buffer, INT32 *size);
+ LIB_EXPORT TPM_RC
+ TPMS_SIGNATURE_ECSCHNORR_Unmarshal(TPMS_SIGNATURE_ECSCHNORR *target, BYTE **buffer, INT32 *size);
+ LIB_EXPORT TPM_RC
+ TPMU_SIGNATURE_Unmarshal(TPMU_SIGNATURE *target, BYTE **buffer, INT32 *size, UINT32 selector);
+ LIB_EXPORT TPM_RC
+ TPMT_SIGNATURE_Unmarshal(TPMT_SIGNATURE *target, BYTE **buffer, INT32 *size, BOOL allowNull);
+ LIB_EXPORT TPM_RC
+ TPM2B_ENCRYPTED_SECRET_Unmarshal(TPM2B_ENCRYPTED_SECRET *target, BYTE **buffer, INT32 *size);
+ LIB_EXPORT TPM_RC
+ TPMI_ALG_PUBLIC_Unmarshal(TPMI_ALG_PUBLIC *target, BYTE **buffer, INT32 *size);
+ LIB_EXPORT TPM_RC
+ TPMU_PUBLIC_ID_Unmarshal(TPMU_PUBLIC_ID *target, BYTE **buffer, INT32 *size, UINT32 selector);
+ LIB_EXPORT TPM_RC
+ TPMS_KEYEDHASH_PARMS_Unmarshal(TPMS_KEYEDHASH_PARMS *target, BYTE **buffer, INT32 *size);
+ LIB_EXPORT TPM_RC
+ TPMS_RSA_PARMS_Unmarshal(TPMS_RSA_PARMS *target, BYTE **buffer, INT32 *size);
+ LIB_EXPORT TPM_RC
+ TPMS_ECC_PARMS_Unmarshal(TPMS_ECC_PARMS *target, BYTE **buffer, INT32 *size);
+ LIB_EXPORT TPM_RC
+ TPMU_PUBLIC_PARMS_Unmarshal(TPMU_PUBLIC_PARMS *target, BYTE **buffer, INT32 *size, UINT32 selector);
+ LIB_EXPORT TPM_RC
+ TPMT_PUBLIC_PARMS_Unmarshal(TPMT_PUBLIC_PARMS *target, BYTE **buffer, INT32 *size);
+ LIB_EXPORT TPM_RC
+ TPMT_PUBLIC_Unmarshal(TPMT_PUBLIC *target, BYTE **buffer, INT32 *size, BOOL allowNull);
+ LIB_EXPORT TPM_RC
+ TPM2B_PUBLIC_Unmarshal(TPM2B_PUBLIC *target, BYTE **buffer, INT32 *size, BOOL allowNull);
+ LIB_EXPORT TPM_RC
+ TPM2B_TEMPLATE_Unmarshal(TPM2B_TEMPLATE *target, BYTE **buffer, INT32 *size);
+ LIB_EXPORT TPM_RC
+ TPMU_SENSITIVE_COMPOSITE_Unmarshal(TPMU_SENSITIVE_COMPOSITE *target, BYTE **buffer, INT32 *size, UINT32 selector);
+ LIB_EXPORT TPM_RC
+ TPMT_SENSITIVE_Unmarshal(TPMT_SENSITIVE *target, BYTE **buffer, INT32 *size);
+ LIB_EXPORT TPM_RC
+ TPM2B_SENSITIVE_Unmarshal(TPM2B_SENSITIVE *target, BYTE **buffer, INT32 *size);
+ LIB_EXPORT TPM_RC
+ TPM2B_PRIVATE_Unmarshal(TPM2B_PRIVATE *target, BYTE **buffer, INT32 *size);
+ LIB_EXPORT TPM_RC
+ TPM2B_ID_OBJECT_Unmarshal(TPM2B_ID_OBJECT *target, BYTE **buffer, INT32 *size);
+ LIB_EXPORT TPM_RC
+ TPMA_NV_Unmarshal(TPMA_NV *target, BYTE **buffer, INT32 *size);
+ LIB_EXPORT TPM_RC
+ TPMS_NV_PUBLIC_Unmarshal(TPMS_NV_PUBLIC *target, BYTE **buffer, INT32 *size);
+ LIB_EXPORT TPM_RC
+ TPM2B_NV_PUBLIC_Unmarshal(TPM2B_NV_PUBLIC *target, BYTE **buffer, INT32 *size);
+ LIB_EXPORT TPM_RC
+ TPM2B_CONTEXT_SENSITIVE_Unmarshal(TPM2B_CONTEXT_SENSITIVE *target, BYTE **buffer, INT32 *size);
+ LIB_EXPORT TPM_RC
+ TPM2B_CONTEXT_DATA_Unmarshal(TPM2B_CONTEXT_DATA *target, BYTE **buffer, INT32 *size);
+ LIB_EXPORT TPM_RC
+ TPMS_CONTEXT_Unmarshal(TPMS_CONTEXT *target, BYTE **buffer, INT32 *size);
+ LIB_EXPORT TPM_RC
+ TPM_AT_Unmarshal(TPM_AT *target, BYTE **buffer, INT32 *size);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/src/tpm2/Unseal_fp.h b/src/tpm2/Unseal_fp.h
new file mode 100644
index 0000000..84fa0a4
--- /dev/null
+++ b/src/tpm2/Unseal_fp.h
@@ -0,0 +1,83 @@
+/********************************************************************************/
+/* */
+/* */
+/* Written by Ken Goldman */
+/* IBM Thomas J. Watson Research Center */
+/* $Id: Unseal_fp.h 809 2016-11-16 18:31:54Z kgoldman $ */
+/* */
+/* Licenses and Notices */
+/* */
+/* 1. Copyright Licenses: */
+/* */
+/* - Trusted Computing Group (TCG) grants to the user of the source code in */
+/* this specification (the "Source Code") a worldwide, irrevocable, */
+/* nonexclusive, royalty free, copyright license to reproduce, create */
+/* derivative works, distribute, display and perform the Source Code and */
+/* derivative works thereof, and to grant others the rights granted herein. */
+/* */
+/* - The TCG grants to the user of the other parts of the specification */
+/* (other than the Source Code) the rights to reproduce, distribute, */
+/* display, and perform the specification solely for the purpose of */
+/* developing products based on such documents. */
+/* */
+/* 2. Source Code Distribution Conditions: */
+/* */
+/* - Redistributions of Source Code must retain the above copyright licenses, */
+/* this list of conditions and the following disclaimers. */
+/* */
+/* - Redistributions in binary form must reproduce the above copyright */
+/* licenses, this list of conditions and the following disclaimers in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* 3. Disclaimers: */
+/* */
+/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
+/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
+/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
+/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
+/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
+/* information on specification licensing rights available through TCG */
+/* membership agreements. */
+/* */
+/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
+/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
+/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
+/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
+/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
+/* */
+/* - Without limitation, TCG and its members and licensors disclaim all */
+/* liability, including liability for infringement of any proprietary */
+/* rights, relating to use of information in this specification and to the */
+/* implementation of this specification, and TCG disclaims all liability for */
+/* cost of procurement of substitute goods or services, lost profits, loss */
+/* of use, loss of data or any incidental, consequential, direct, indirect, */
+/* or special damages, whether under contract, tort, warranty or otherwise, */
+/* arising in any way out of use or reliance upon this specification or any */
+/* information herein. */
+/* */
+/* (c) Copyright IBM Corp. and others, 2012-2015 */
+/* */
+/********************************************************************************/
+
+/* rev 119 */
+
+#ifndef UNSEAL_FP_H
+#define UNSEAL_FP_H
+
+typedef struct {
+ TPMI_DH_OBJECT itemHandle;
+} Unseal_In;
+
+#define RC_Unseal_itemHandle (TPM_RC_H + TPM_RC_1)
+
+typedef struct {
+ TPM2B_SENSITIVE_DATA outData;
+} Unseal_Out;
+
+TPM_RC
+TPM2_Unseal(
+ Unseal_In *in,
+ Unseal_Out *out
+ );
+
+#endif
diff --git a/src/tpm2/Utils.h b/src/tpm2/Utils.h
new file mode 100644
index 0000000..b9becef
--- /dev/null
+++ b/src/tpm2/Utils.h
@@ -0,0 +1,54 @@
+/********************************************************************************/
+/* */
+/* Utility functions */
+/* Written by Stefan Berger */
+/* IBM Thomas J. Watson Research Center */
+/* */
+/* (c) Copyright IBM Corporation 2017,2018. */
+/* */
+/* All rights reserved. */
+/* */
+/* Redistribution and use in source and binary forms, with or without */
+/* modification, are permitted provided that the following conditions are */
+/* met: */
+/* */
+/* Redistributions of source code must retain the above copyright notice, */
+/* this list of conditions and the following disclaimer. */
+/* */
+/* Redistributions in binary form must reproduce the above copyright */
+/* notice, this list of conditions and the following disclaimer in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* Neither the names of the IBM Corporation nor the names of its */
+/* contributors may be used to endorse or promote products derived from */
+/* this software without specific prior written permission. */
+/* */
+/* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS */
+/* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT */
+/* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR */
+/* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT */
+/* HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, */
+/* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT */
+/* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, */
+/* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY */
+/* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT */
+/* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE */
+/* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */
+/********************************************************************************/
+
+#ifndef UTILS_H
+#define UTILS_H
+
+#include "Memory_fp.h"
+
+#define TPM2_ROUNDUP(VAL, SIZE) \
+ ( ( (VAL) + (SIZE) - 1) / (SIZE) ) * (SIZE)
+
+__attribute__((unused)) static inline void clear_and_free(void *ptr, size_t size) {
+ if (ptr) {
+ MemorySet(ptr, 0, size);
+ free(ptr);
+ }
+}
+
+#endif /* UTILS_H */
diff --git a/src/tpm2/VendorString.h b/src/tpm2/VendorString.h
new file mode 100644
index 0000000..e33800d
--- /dev/null
+++ b/src/tpm2/VendorString.h
@@ -0,0 +1,108 @@
+/********************************************************************************/
+/* */
+/* Vendor String */
+/* Written by Ken Goldman */
+/* IBM Thomas J. Watson Research Center */
+/* $Id: VendorString.h 1519 2019-11-15 20:43:51Z kgoldman $ */
+/* */
+/* Licenses and Notices */
+/* */
+/* 1. Copyright Licenses: */
+/* */
+/* - Trusted Computing Group (TCG) grants to the user of the source code in */
+/* this specification (the "Source Code") a worldwide, irrevocable, */
+/* nonexclusive, royalty free, copyright license to reproduce, create */
+/* derivative works, distribute, display and perform the Source Code and */
+/* derivative works thereof, and to grant others the rights granted herein. */
+/* */
+/* - The TCG grants to the user of the other parts of the specification */
+/* (other than the Source Code) the rights to reproduce, distribute, */
+/* display, and perform the specification solely for the purpose of */
+/* developing products based on such documents. */
+/* */
+/* 2. Source Code Distribution Conditions: */
+/* */
+/* - Redistributions of Source Code must retain the above copyright licenses, */
+/* this list of conditions and the following disclaimers. */
+/* */
+/* - Redistributions in binary form must reproduce the above copyright */
+/* licenses, this list of conditions and the following disclaimers in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* 3. Disclaimers: */
+/* */
+/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
+/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
+/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
+/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
+/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
+/* information on specification licensing rights available through TCG */
+/* membership agreements. */
+/* */
+/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
+/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
+/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
+/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
+/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
+/* */
+/* - Without limitation, TCG and its members and licensors disclaim all */
+/* liability, including liability for infringement of any proprietary */
+/* rights, relating to use of information in this specification and to the */
+/* implementation of this specification, and TCG disclaims all liability for */
+/* cost of procurement of substitute goods or services, lost profits, loss */
+/* of use, loss of data or any incidental, consequential, direct, indirect, */
+/* or special damages, whether under contract, tort, warranty or otherwise, */
+/* arising in any way out of use or reliance upon this specification or any */
+/* information herein. */
+/* */
+/* (c) Copyright IBM Corp. and others, 2016 - 2019 */
+/* */
+/********************************************************************************/
+
+#ifndef VENDORSTRING_H
+#define VENDORSTRING_H
+
+/* Define up to 4-byte values for MANUFACTURER. This value defines the response for
+ TPM_PT_MANUFACTURER in TPM2_GetCapability(). The following line should be un-commented and a
+ vendor specific string should be provided here. */
+#define MANUFACTURER "IBM"
+
+/* The following #if macro may be deleted after a proper MANUFACTURER is provided. */
+#ifndef MANUFACTURER
+#error MANUFACTURER is not provided. \
+ Please modify VendorString.h to provide a specific \
+ manufacturer name.
+#endif
+
+/* Define up to 4, 4-byte, vendor-specific values. The values must each be 4 bytes long and the
+ last value used may contain trailing zeros. These values define the response for
+ TPM_PT_VENDOR_STRING_(1-4) in TPM2_GetCapability(). The following line should be un-commented
+ and a vendor specific string. The vendor strings 2-4 may also be defined as appropriate. */
+
+#define VENDOR_STRING_1 "SW "
+#define VENDOR_STRING_2 " TPM"
+//#define VENDOR_STRING_3
+//#define VENDOR_STRING_4
+
+/* The following #if macro may be deleted after a proper VENDOR_STRING_1 is provided. */
+#ifndef VENDOR_STRING_1
+#error VENDOR_STRING_1 is not provided. \
+ Please modify VendorString.h to provide a vendor specific string.
+#endif
+
+/* the more significant 32-bits of a vendor-specific value indicating the version of the firmware
+ The following line should be un-commented and a vendor specific firmware V1 should be provided
+ here. The FIRMWARE_V2 may also be defined as appropriate. */
+#define FIRMWARE_V1 (0x20191023)
+
+// the less significant 32-bits of a vendor-specific value indicating the version of the firmware
+#define FIRMWARE_V2 (0x00163636)
+
+// The following #if macro may be deleted after a proper FIRMWARE_V1 is provided.
+#ifndef FIRMWARE_V1
+#error FIRMWARE_V1 is not provided. \
+ Please modify VendorString.h to provide a vendor specific firmware \
+ version
+#endif
+
+#endif
diff --git a/src/tpm2/Vendor_TCG_Test.c b/src/tpm2/Vendor_TCG_Test.c
new file mode 100644
index 0000000..74c2d11
--- /dev/null
+++ b/src/tpm2/Vendor_TCG_Test.c
@@ -0,0 +1,76 @@
+/********************************************************************************/
+/* */
+/* */
+/* Written by Ken Goldman */
+/* IBM Thomas J. Watson Research Center */
+/* $Id: Vendor_TCG_Test.c 1548 2019-12-13 23:15:40Z kgoldman $ */
+/* */
+/* Licenses and Notices */
+/* */
+/* 1. Copyright Licenses: */
+/* */
+/* - Trusted Computing Group (TCG) grants to the user of the source code in */
+/* this specification (the "Source Code") a worldwide, irrevocable, */
+/* nonexclusive, royalty free, copyright license to reproduce, create */
+/* derivative works, distribute, display and perform the Source Code and */
+/* derivative works thereof, and to grant others the rights granted herein. */
+/* */
+/* - The TCG grants to the user of the other parts of the specification */
+/* (other than the Source Code) the rights to reproduce, distribute, */
+/* display, and perform the specification solely for the purpose of */
+/* developing products based on such documents. */
+/* */
+/* 2. Source Code Distribution Conditions: */
+/* */
+/* - Redistributions of Source Code must retain the above copyright licenses, */
+/* this list of conditions and the following disclaimers. */
+/* */
+/* - Redistributions in binary form must reproduce the above copyright */
+/* licenses, this list of conditions and the following disclaimers in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* 3. Disclaimers: */
+/* */
+/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
+/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
+/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
+/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
+/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
+/* information on specification licensing rights available through TCG */
+/* membership agreements. */
+/* */
+/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
+/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
+/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
+/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
+/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
+/* */
+/* - Without limitation, TCG and its members and licensors disclaim all */
+/* liability, including liability for infringement of any proprietary */
+/* rights, relating to use of information in this specification and to the */
+/* implementation of this specification, and TCG disclaims all liability for */
+/* cost of procurement of substitute goods or services, lost profits, loss */
+/* of use, loss of data or any incidental, consequential, direct, indirect, */
+/* or special damages, whether under contract, tort, warranty or otherwise, */
+/* arising in any way out of use or reliance upon this specification or any */
+/* information herein. */
+/* */
+/* (c) Copyright IBM Corp. and others, 2016 */
+/* */
+/********************************************************************************/
+
+#include "Tpm.h"
+#include "Vendor_TCG_Test_fp.h"
+#include "Marshal_fp.h"
+#if CC_Vendor_TCG_Test
+/* A dummy function for testing. */
+TPM_RC
+TPM2_Vendor_TCG_Test(
+ Vendor_TCG_Test_In *in, // IN: input parameter list
+ Vendor_TCG_Test_Out *out // OUT: output parameter list
+ )
+{
+ out->outputData = in->inputData;
+ return TPM_RC_SUCCESS;
+}
+#endif // CC_Vendor_TCG_Test
diff --git a/src/tpm2/Vendor_TCG_Test_fp.h b/src/tpm2/Vendor_TCG_Test_fp.h
new file mode 100644
index 0000000..036ade0
--- /dev/null
+++ b/src/tpm2/Vendor_TCG_Test_fp.h
@@ -0,0 +1,79 @@
+/********************************************************************************/
+/* */
+/* Sample Vendor Specific Command */
+/* Written by Ken Goldman */
+/* IBM Thomas J. Watson Research Center */
+/* $Id: Vendor_TCG_Test_fp.h 1635 2020-06-12 21:48:27Z kgoldman $ */
+/* */
+/* Licenses and Notices */
+/* */
+/* 1. Copyright Licenses: */
+/* */
+/* - Trusted Computing Group (TCG) grants to the user of the source code in */
+/* this specification (the "Source Code") a worldwide, irrevocable, */
+/* nonexclusive, royalty free, copyright license to reproduce, create */
+/* derivative works, distribute, display and perform the Source Code and */
+/* derivative works thereof, and to grant others the rights granted herein. */
+/* */
+/* - The TCG grants to the user of the other parts of the specification */
+/* (other than the Source Code) the rights to reproduce, distribute, */
+/* display, and perform the specification solely for the purpose of */
+/* developing products based on such documents. */
+/* */
+/* 2. Source Code Distribution Conditions: */
+/* */
+/* - Redistributions of Source Code must retain the above copyright licenses, */
+/* this list of conditions and the following disclaimers. */
+/* */
+/* - Redistributions in binary form must reproduce the above copyright */
+/* licenses, this list of conditions and the following disclaimers in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* 3. Disclaimers: */
+/* */
+/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
+/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
+/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
+/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
+/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
+/* information on specification licensing rights available through TCG */
+/* membership agreements. */
+/* */
+/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
+/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
+/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
+/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
+/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
+/* */
+/* - Without limitation, TCG and its members and licensors disclaim all */
+/* liability, including liability for infringement of any proprietary */
+/* rights, relating to use of information in this specification and to the */
+/* implementation of this specification, and TCG disclaims all liability for */
+/* cost of procurement of substitute goods or services, lost profits, loss */
+/* of use, loss of data or any incidental, consequential, direct, indirect, */
+/* or special damages, whether under contract, tort, warranty or otherwise, */
+/* arising in any way out of use or reliance upon this specification or any */
+/* information herein. */
+/* */
+/* (c) Copyright IBM Corp. and others, 2016 - 2020 */
+/* */
+/********************************************************************************/
+
+#ifndef VENDOR_TCG_TEST_FP_H
+#define VENDOR_TCG_TEST_FP_H
+
+typedef struct {
+ TPM2B_DATA inputData;
+} Vendor_TCG_Test_In;
+
+typedef struct {
+ TPM2B_DATA outputData;
+} Vendor_TCG_Test_Out;
+
+TPM_RC
+TPM2_Vendor_TCG_Test(
+ Vendor_TCG_Test_In *in, // IN: input parameter list
+ Vendor_TCG_Test_Out *out // OUT: output parameter list
+ );
+
+#endif
diff --git a/src/tpm2/VerifySignature_fp.h b/src/tpm2/VerifySignature_fp.h
new file mode 100644
index 0000000..d90c83a
--- /dev/null
+++ b/src/tpm2/VerifySignature_fp.h
@@ -0,0 +1,88 @@
+/********************************************************************************/
+/* */
+/* */
+/* Written by Ken Goldman */
+/* IBM Thomas J. Watson Research Center */
+/* $Id: VerifySignature_fp.h 809 2016-11-16 18:31:54Z kgoldman $ */
+/* */
+/* Licenses and Notices */
+/* */
+/* 1. Copyright Licenses: */
+/* */
+/* - Trusted Computing Group (TCG) grants to the user of the source code in */
+/* this specification (the "Source Code") a worldwide, irrevocable, */
+/* nonexclusive, royalty free, copyright license to reproduce, create */
+/* derivative works, distribute, display and perform the Source Code and */
+/* derivative works thereof, and to grant others the rights granted herein. */
+/* */
+/* - The TCG grants to the user of the other parts of the specification */
+/* (other than the Source Code) the rights to reproduce, distribute, */
+/* display, and perform the specification solely for the purpose of */
+/* developing products based on such documents. */
+/* */
+/* 2. Source Code Distribution Conditions: */
+/* */
+/* - Redistributions of Source Code must retain the above copyright licenses, */
+/* this list of conditions and the following disclaimers. */
+/* */
+/* - Redistributions in binary form must reproduce the above copyright */
+/* licenses, this list of conditions and the following disclaimers in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* 3. Disclaimers: */
+/* */
+/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
+/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
+/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
+/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
+/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
+/* information on specification licensing rights available through TCG */
+/* membership agreements. */
+/* */
+/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
+/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
+/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
+/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
+/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
+/* */
+/* - Without limitation, TCG and its members and licensors disclaim all */
+/* liability, including liability for infringement of any proprietary */
+/* rights, relating to use of information in this specification and to the */
+/* implementation of this specification, and TCG disclaims all liability for */
+/* cost of procurement of substitute goods or services, lost profits, loss */
+/* of use, loss of data or any incidental, consequential, direct, indirect, */
+/* or special damages, whether under contract, tort, warranty or otherwise, */
+/* arising in any way out of use or reliance upon this specification or any */
+/* information herein. */
+/* */
+/* (c) Copyright IBM Corp. and others, 2012-2015 */
+/* */
+/********************************************************************************/
+
+/* rev 119 */
+
+#ifndef VERIFYSIGNATURE_FP_H
+#define VERIFYSIGNATURE_FP_H
+
+typedef struct {
+ TPMI_DH_OBJECT keyHandle;
+ TPM2B_DIGEST digest;
+ TPMT_SIGNATURE signature;
+} VerifySignature_In;
+
+#define RC_VerifySignature_keyHandle (TPM_RC_H + TPM_RC_1)
+#define RC_VerifySignature_digest (TPM_RC_P + TPM_RC_1)
+#define RC_VerifySignature_signature (TPM_RC_P + TPM_RC_2)
+
+typedef struct {
+ TPMT_TK_VERIFIED validation;
+} VerifySignature_Out;
+
+TPM_RC
+TPM2_VerifySignature(
+ VerifySignature_In *in, // IN: input parameter list
+ VerifySignature_Out *out // OUT: output parameter list
+ );
+
+
+#endif
diff --git a/src/tpm2/Volatile.c b/src/tpm2/Volatile.c
new file mode 100644
index 0000000..ff15c7f
--- /dev/null
+++ b/src/tpm2/Volatile.c
@@ -0,0 +1,119 @@
+/********************************************************************************/
+/* */
+/* Marshalling and unmarshalling of state */
+/* Written by Stefan Berger */
+/* IBM Thomas J. Watson Research Center */
+/* */
+/* (c) Copyright IBM Corporation 2017,2018. */
+/* */
+/* All rights reserved. */
+/* */
+/* Redistribution and use in source and binary forms, with or without */
+/* modification, are permitted provided that the following conditions are */
+/* met: */
+/* */
+/* Redistributions of source code must retain the above copyright notice, */
+/* this list of conditions and the following disclaimer. */
+/* */
+/* Redistributions in binary form must reproduce the above copyright */
+/* notice, this list of conditions and the following disclaimer in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* Neither the names of the IBM Corporation nor the names of its */
+/* contributors may be used to endorse or promote products derived from */
+/* this software without specific prior written permission. */
+/* */
+/* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS */
+/* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT */
+/* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR */
+/* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT */
+/* HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, */
+/* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT */
+/* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, */
+/* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY */
+/* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT */
+/* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE */
+/* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */
+/********************************************************************************/
+
+#if defined __FreeBSD__ || defined __DragonFly__
+# include <sys/endian.h>
+#elif defined __APPLE__
+# include <libkern/OSByteOrder.h>
+#else
+# include <endian.h>
+#endif
+#include <string.h>
+
+#include "config.h"
+
+#include "assert.h"
+#include "NVMarshal.h"
+#include "Volatile.h"
+
+#define TPM_HAVE_TPM2_DECLARATIONS
+#include "tpm_library_intern.h"
+
+TPM_RC
+VolatileState_Load(BYTE **buffer, INT32 *size)
+{
+ TPM_RC rc = TPM_RC_SUCCESS;
+ BYTE hash[SHA1_DIGEST_SIZE], acthash[SHA1_DIGEST_SIZE];
+ UINT16 hashAlg = TPM_ALG_SHA1;
+
+ if (rc == TPM_RC_SUCCESS) {
+ if ((UINT32)*size < sizeof(hash))
+ return TPM_RC_INSUFFICIENT;
+
+ CryptHashBlock(hashAlg, *size - sizeof(hash), *buffer,
+ sizeof(acthash), acthash);
+ rc = VolatileState_Unmarshal(buffer, size);
+ /* specific error has already been reported */
+ }
+
+ if (rc == TPM_RC_SUCCESS) {
+ /*
+ * advance pointer towards hash if we have a later version of
+ * the state that has extra data we didn't read
+ */
+ if (*size > 0 && (UINT32)*size > sizeof(hash)) {
+ *buffer += *size - sizeof(hash);
+ *size = sizeof(hash);
+ }
+ rc = Array_Unmarshal(hash, sizeof(hash), buffer, size);
+ if (rc != TPM_RC_SUCCESS)
+ TPMLIB_LogTPM2Error("Error unmarshalling volatile state hash: "
+ "0x%02x\n", rc);
+ }
+
+ if (rc == TPM_RC_SUCCESS) {
+ if (memcmp(acthash, hash, sizeof(hash))) {
+ rc = TPM_RC_HASH;
+ TPMLIB_LogTPM2Error("Volatile state checksum error: 0x%02x\n",
+ rc);
+ }
+ }
+
+ if (rc != TPM_RC_SUCCESS)
+ g_inFailureMode = TRUE;
+
+ return rc;
+}
+
+UINT16
+VolatileState_Save(BYTE **buffer, INT32 *size)
+{
+ UINT16 written;
+ const BYTE *start;
+ BYTE hash[SHA1_DIGEST_SIZE];
+ TPM_ALG_ID hashAlg = TPM_ALG_SHA1;
+
+ start = *buffer;
+ written = VolatileState_Marshal(buffer, size);
+
+ /* append the checksum */
+ CryptHashBlock(hashAlg, written, start, sizeof(hash), hash);
+ written += Array_Marshal(hash, sizeof(hash), buffer, size);
+
+ return written;
+}
diff --git a/src/tpm2/Volatile.h b/src/tpm2/Volatile.h
new file mode 100644
index 0000000..9913e8d
--- /dev/null
+++ b/src/tpm2/Volatile.h
@@ -0,0 +1,47 @@
+/********************************************************************************/
+/* */
+/* Marshalling and unmarshalling of state */
+/* Written by Stefan Berger */
+/* IBM Thomas J. Watson Research Center */
+/* */
+/* (c) Copyright IBM Corporation 2017,2018. */
+/* */
+/* All rights reserved. */
+/* */
+/* Redistribution and use in source and binary forms, with or without */
+/* modification, are permitted provided that the following conditions are */
+/* met: */
+/* */
+/* Redistributions of source code must retain the above copyright notice, */
+/* this list of conditions and the following disclaimer. */
+/* */
+/* Redistributions in binary form must reproduce the above copyright */
+/* notice, this list of conditions and the following disclaimer in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* Neither the names of the IBM Corporation nor the names of its */
+/* contributors may be used to endorse or promote products derived from */
+/* this software without specific prior written permission. */
+/* */
+/* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS */
+/* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT */
+/* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR */
+/* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT */
+/* HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, */
+/* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT */
+/* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, */
+/* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY */
+/* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT */
+/* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE */
+/* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */
+/********************************************************************************/
+
+#ifndef VOLATILE_H
+#define VOLATILE_H
+
+#include "BaseTypes.h"
+
+TPM_RC VolatileState_Load(BYTE **buffer, INT32 *size);
+UINT16 VolatileState_Save(BYTE **buffer, INT32 *size);
+
+#endif /* VOLATILE_H */
diff --git a/src/tpm2/X509.h b/src/tpm2/X509.h
new file mode 100644
index 0000000..42c46e5
--- /dev/null
+++ b/src/tpm2/X509.h
@@ -0,0 +1,142 @@
+/********************************************************************************/
+/* */
+/* Macro and Structure Definitions for the X509 Commands and Functions. */
+/* Written by Ken Goldman */
+/* IBM Thomas J. Watson Research Center */
+/* $Id: X509.h 1658 2021-01-22 23:14:01Z kgoldman $ */
+/* */
+/* Licenses and Notices */
+/* */
+/* 1. Copyright Licenses: */
+/* */
+/* - Trusted Computing Group (TCG) grants to the user of the source code in */
+/* this specification (the "Source Code") a worldwide, irrevocable, */
+/* nonexclusive, royalty free, copyright license to reproduce, create */
+/* derivative works, distribute, display and perform the Source Code and */
+/* derivative works thereof, and to grant others the rights granted herein. */
+/* */
+/* - The TCG grants to the user of the other parts of the specification */
+/* (other than the Source Code) the rights to reproduce, distribute, */
+/* display, and perform the specification solely for the purpose of */
+/* developing products based on such documents. */
+/* */
+/* 2. Source Code Distribution Conditions: */
+/* */
+/* - Redistributions of Source Code must retain the above copyright licenses, */
+/* this list of conditions and the following disclaimers. */
+/* */
+/* - Redistributions in binary form must reproduce the above copyright */
+/* licenses, this list of conditions and the following disclaimers in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* 3. Disclaimers: */
+/* */
+/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
+/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
+/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
+/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
+/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
+/* information on specification licensing rights available through TCG */
+/* membership agreements. */
+/* */
+/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
+/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
+/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
+/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
+/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
+/* */
+/* - Without limitation, TCG and its members and licensors disclaim all */
+/* liability, including liability for infringement of any proprietary */
+/* rights, relating to use of information in this specification and to the */
+/* implementation of this specification, and TCG disclaims all liability for */
+/* cost of procurement of substitute goods or services, lost profits, loss */
+/* of use, loss of data or any incidental, consequential, direct, indirect, */
+/* or special damages, whether under contract, tort, warranty or otherwise, */
+/* arising in any way out of use or reliance upon this specification or any */
+/* information herein. */
+/* */
+/* (c) Copyright IBM Corp. and others, 2019 - 2021 */
+/* */
+/********************************************************************************/
+
+// 10.1.16 X509.h
+// 10.1.16.1 Introduction
+// This file contains the macro and structure definitions for the X509 commands and functions.
+#ifndef _X509_H_
+#define _X509_H_
+// 10.1.16.2 Includes
+#include "Tpm.h"
+#include "TpmAsn1.h"
+// 10.1.16.3 Defined Constants
+// 10.1.16.3.1 X509 Application-specific types
+#define X509_SELECTION 0xA0
+#define X509_ISSUER_UNIQUE_ID 0xA1
+#define X509_SUBJECT_UNIQUE_ID 0xA2
+#define X509_EXTENSIONS 0xA3
+// These defines give the order in which values appear in the TBScertificate of an x.509
+// certificate. These values are used to index into an array of
+#define ENCODED_SIZE_REF 0
+#define VERSION_REF (ENCODED_SIZE_REF + 1)
+#define SERIAL_NUMBER_REF (VERSION_REF + 1)
+#define SIGNATURE_REF (SERIAL_NUMBER_REF + 1)
+#define ISSUER_REF (SIGNATURE_REF + 1)
+#define VALIDITY_REF (ISSUER_REF + 1)
+#define SUBJECT_KEY_REF (VALIDITY_REF + 1)
+#define SUBJECT_PUBLIC_KEY_REF (SUBJECT_KEY_REF + 1)
+#define EXTENSIONS_REF (SUBJECT_PUBLIC_KEY_REF + 1)
+#define REF_COUNT (EXTENSIONS_REF + 1)
+
+// 10.1.16.4 Structures Used to access the fields of a TBSsignature some of which are in the
+// in_CertifyX509 structure and some of which are in the out_CertifyX509 structure.
+typedef struct stringRef
+{
+ BYTE *buf;
+ INT16 len;
+} stringRef;
+// This is defined to avoid bit by bit comparisons within a UINT32
+typedef union x509KeyUsageUnion {
+ TPMA_X509_KEY_USAGE x509;
+ UINT32 integer;
+} x509KeyUsageUnion;
+
+// 10.1.16.5 Global X509 Constants
+
+// These values are instanced by X509_spt.c and referenced by other X509-related files. This is the
+// DER-encoded value for the Key Usage OID (2.5.29.15). This is the full OID, not just the numeric
+// value
+
+#define OID_KEY_USAGE_EXTENSION_VALUE 0x06, 0x03, 0x55, 0x1D, 0x0F
+MAKE_OID(_KEY_USAGE_EXTENSION);
+
+// This is the DER-encoded value for the TCG-defined TPMA_OBJECT OID (2.23.133.10.1.1.1)
+
+#define OID_TCG_TPMA_OBJECT_VALUE 0x06, 0x07, 0x67, 0x81, 0x05, 0x0a, 0x01, \
+ 0x01, 0x01
+MAKE_OID(_TCG_TPMA_OBJECT);
+
+#ifdef _X509_SPT_
+
+// If a bit is SET in KEY_USAGE_SIGN is also SET in keyUsage then the associated key has to have
+// sign SET.
+
+const x509KeyUsageUnion KEY_USAGE_SIGN =
+ {TPMA_X509_KEY_USAGE_INITIALIZER(
+ /* bits_at_0 */ 0, /* decipheronly */ 0, /* encipheronly */ 0,
+ /* crlsign */ 1, /* keycertsign */ 1, /* keyagreement */ 0,
+ /* dataencipherment */ 0, /* keyencipherment */ 0, /* nonrepudiation */ 0,
+ /* digitalsignature */ 1)};
+
+// If a bit is SET in KEY_USAGE_DECRYPT is also SET in keyUsage then the associated key has to have decrypt SET.
+
+const x509KeyUsageUnion KEY_USAGE_DECRYPT =
+ {TPMA_X509_KEY_USAGE_INITIALIZER(
+ /* bits_at_0 */ 0, /* decipheronly */ 1, /* encipheronly */ 1,
+ /* crlsign */ 0, /* keycertsign */ 0, /* keyagreement */ 1,
+ /* dataencipherment */ 1, /* keyencipherment */ 1, /* nonrepudiation */ 0,
+ /* digitalsignature */ 0)};
+#else
+extern x509KeyUsageUnion KEY_USAGE_SIGN;
+extern x509KeyUsageUnion KEY_USAGE_DECRYPT;
+#endif
+
+#endif // _X509_H_
diff --git a/src/tpm2/X509_ECC.c b/src/tpm2/X509_ECC.c
new file mode 100644
index 0000000..703b9ff
--- /dev/null
+++ b/src/tpm2/X509_ECC.c
@@ -0,0 +1,173 @@
+/********************************************************************************/
+/* */
+/* TPM X509 ECC */
+/* Written by Ken Goldman */
+/* IBM Thomas J. Watson Research Center */
+/* $Id: X509_ECC.c 1658 2021-01-22 23:14:01Z kgoldman $ */
+/* */
+/* Licenses and Notices */
+/* */
+/* 1. Copyright Licenses: */
+/* */
+/* - Trusted Computing Group (TCG) grants to the user of the source code in */
+/* this specification (the "Source Code") a worldwide, irrevocable, */
+/* nonexclusive, royalty free, copyright license to reproduce, create */
+/* derivative works, distribute, display and perform the Source Code and */
+/* derivative works thereof, and to grant others the rights granted herein. */
+/* */
+/* - The TCG grants to the user of the other parts of the specification */
+/* (other than the Source Code) the rights to reproduce, distribute, */
+/* display, and perform the specification solely for the purpose of */
+/* developing products based on such documents. */
+/* */
+/* 2. Source Code Distribution Conditions: */
+/* */
+/* - Redistributions of Source Code must retain the above copyright licenses, */
+/* this list of conditions and the following disclaimers. */
+/* */
+/* - Redistributions in binary form must reproduce the above copyright */
+/* licenses, this list of conditions and the following disclaimers in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* 3. Disclaimers: */
+/* */
+/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
+/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
+/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
+/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
+/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
+/* information on specification licensing rights available through TCG */
+/* membership agreements. */
+/* */
+/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
+/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
+/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
+/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
+/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
+/* */
+/* - Without limitation, TCG and its members and licensors disclaim all */
+/* liability, including liability for infringement of any proprietary */
+/* rights, relating to use of information in this specification and to the */
+/* implementation of this specification, and TCG disclaims all liability for */
+/* cost of procurement of substitute goods or services, lost profits, loss */
+/* of use, loss of data or any incidental, consequential, direct, indirect, */
+/* or special damages, whether under contract, tort, warranty or otherwise, */
+/* arising in any way out of use or reliance upon this specification or any */
+/* information herein. */
+/* */
+/* (c) Copyright IBM Corp. and others, 2019 - 2021 */
+/* */
+/********************************************************************************/
+
+/* 10.2.24 X509_ECC.c */
+/* 10.2.24.1 Includes */
+#include "Tpm.h"
+#include "X509.h"
+#include "OIDs.h"
+#include "TpmAsn1_fp.h"
+#include "X509_ECC_fp.h"
+#include "X509_spt_fp.h"
+#include "CryptHash_fp.h"
+
+/* 10.2.24.2 Functions */
+/* 10.2.24.2.1 X509PushPoint() */
+/* This seems like it might be used more than once so... */
+/* Return Value Meaning */
+/* > 0 number of bytes added */
+/* == 0 failure */
+INT16
+X509PushPoint(
+ ASN1MarshalContext *ctx,
+ TPMS_ECC_POINT *p
+ )
+{
+ // Push a bit string containing the public key. For now, push the x, and y
+ // coordinates of the public point, bottom up
+ ASN1StartMarshalContext(ctx); // BIT STRING
+ {
+ ASN1PushBytes(ctx, p->y.t.size, p->y.t.buffer);
+ ASN1PushBytes(ctx, p->x.t.size, p->x.t.buffer);
+ ASN1PushByte(ctx, 0x04);
+ }
+ return ASN1EndEncapsulation(ctx, ASN1_BITSTRING); // Ends BIT STRING
+}
+/* 10.2.24.2.2 X509AddSigningAlgorithmECC() */
+/* This creates the singing algorithm data. */
+/* Return Value Meaning */
+/* > 0 number of bytes added */
+/* == 0 failure */
+INT16
+X509AddSigningAlgorithmECC(
+ OBJECT *signKey,
+ TPMT_SIG_SCHEME *scheme,
+ ASN1MarshalContext *ctx
+ )
+{
+ PHASH_DEF hashDef = CryptGetHashDef(scheme->details.any.hashAlg);
+ //
+ NOT_REFERENCED(signKey);
+ // If the desired hashAlg definition wasn't found...
+ if(hashDef->hashAlg != scheme->details.any.hashAlg)
+ return 0;
+
+ switch(scheme->scheme)
+ {
+#if ALG_ECDSA
+ case TPM_ALG_ECDSA:
+ // Make sure that we have an OID for this hash and ECC
+ if((hashDef->ECDSA)[0] != ASN1_OBJECT_IDENTIFIER)
+ break;
+ // if this is just an implementation check, indicate that this
+ // combination is supported
+ if(!ctx)
+ return 1;
+ ASN1StartMarshalContext(ctx);
+ ASN1PushOID(ctx, hashDef->ECDSA);
+ return ASN1EndEncapsulation(ctx, ASN1_CONSTRUCTED_SEQUENCE);
+#endif // ALG_ECDSA
+ default:
+ break;
+ }
+ return 0;
+}
+/* 10.2.24.2.3 X509AddPublicECC() */
+/* This function will add the publicKey description to the DER data. If ctx is NULL, then no data is
+ transferred and this function will indicate if the TPM has the values for DER-encoding of the
+ public key. */
+/* Return Value Meaning */
+/* > 0 number of bytes added */
+/* == 0 failure */
+INT16
+X509AddPublicECC(
+ OBJECT *object,
+ ASN1MarshalContext *ctx
+ )
+{
+ const BYTE *curveOid =
+ CryptEccGetOID(object->publicArea.parameters.eccDetail.curveID);
+ if((curveOid == NULL) || (*curveOid != ASN1_OBJECT_IDENTIFIER))
+ return 0;
+ //
+ //
+ // SEQUENCE (2 elem) 1st
+ // SEQUENCE (2 elem) 2nd
+ // OBJECT IDENTIFIER 1.2.840.10045.2.1 ecPublicKey (ANSI X9.62 public key type)
+ // OBJECT IDENTIFIER 1.2.840.10045.3.1.7 prime256v1 (ANSI X9.62 named curve)
+ // BIT STRING (520 bit) 000001001010000111010101010111001001101101000100000010...
+ //
+ // If this is a check to see if the key can be encoded, it can.
+ // Need to mark the end sequence
+ if(ctx == NULL)
+ return 1;
+ ASN1StartMarshalContext(ctx); // SEQUENCE (2 elem) 1st
+ {
+ X509PushPoint(ctx, &object->publicArea.unique.ecc); // BIT STRING
+ ASN1StartMarshalContext(ctx); // SEQUENCE (2 elem) 2nd
+ {
+ ASN1PushOID(ctx, curveOid); // curve dependent
+ ASN1PushOID(ctx, OID_ECC_PUBLIC); // (1.2.840.10045.2.1)
+ }
+ ASN1EndEncapsulation(ctx, ASN1_CONSTRUCTED_SEQUENCE); // Ends SEQUENCE 2nd
+ }
+ return ASN1EndEncapsulation(ctx, ASN1_CONSTRUCTED_SEQUENCE); // Ends SEQUENCE 1st
+}
diff --git a/src/tpm2/X509_ECC_fp.h b/src/tpm2/X509_ECC_fp.h
new file mode 100644
index 0000000..95cf33c
--- /dev/null
+++ b/src/tpm2/X509_ECC_fp.h
@@ -0,0 +1,83 @@
+/********************************************************************************/
+/* */
+/* TPM X509 ECC */
+/* Written by Ken Goldman */
+/* IBM Thomas J. Watson Research Center */
+/* $Id: X509_ECC_fp.h 1490 2019-07-26 21:13:22Z kgoldman $ */
+/* */
+/* Licenses and Notices */
+/* */
+/* 1. Copyright Licenses: */
+/* */
+/* - Trusted Computing Group (TCG) grants to the user of the source code in */
+/* this specification (the "Source Code") a worldwide, irrevocable, */
+/* nonexclusive, royalty free, copyright license to reproduce, create */
+/* derivative works, distribute, display and perform the Source Code and */
+/* derivative works thereof, and to grant others the rights granted herein. */
+/* */
+/* - The TCG grants to the user of the other parts of the specification */
+/* (other than the Source Code) the rights to reproduce, distribute, */
+/* display, and perform the specification solely for the purpose of */
+/* developing products based on such documents. */
+/* */
+/* 2. Source Code Distribution Conditions: */
+/* */
+/* - Redistributions of Source Code must retain the above copyright licenses, */
+/* this list of conditions and the following disclaimers. */
+/* */
+/* - Redistributions in binary form must reproduce the above copyright */
+/* licenses, this list of conditions and the following disclaimers in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* 3. Disclaimers: */
+/* */
+/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
+/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
+/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
+/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
+/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
+/* information on specification licensing rights available through TCG */
+/* membership agreements. */
+/* */
+/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
+/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
+/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
+/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
+/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
+/* */
+/* - Without limitation, TCG and its members and licensors disclaim all */
+/* liability, including liability for infringement of any proprietary */
+/* rights, relating to use of information in this specification and to the */
+/* implementation of this specification, and TCG disclaims all liability for */
+/* cost of procurement of substitute goods or services, lost profits, loss */
+/* of use, loss of data or any incidental, consequential, direct, indirect, */
+/* or special damages, whether under contract, tort, warranty or otherwise, */
+/* arising in any way out of use or reliance upon this specification or any */
+/* information herein. */
+/* */
+/* (c) Copyright IBM Corp. and others, 2019 */
+/* */
+/********************************************************************************/
+
+#ifndef X509_ECC_FP_H
+#define X509_ECC_FP_H
+
+INT16
+X509PushPoint(
+ ASN1MarshalContext *ctx,
+ TPMS_ECC_POINT *p
+ );
+INT16
+X509AddSigningAlgorithmECC(
+ OBJECT *signKey,
+ TPMT_SIG_SCHEME *scheme,
+ ASN1MarshalContext *ctx
+ );
+INT16
+X509AddPublicECC(
+ OBJECT *object,
+ ASN1MarshalContext *ctx
+ );
+
+
+#endif
diff --git a/src/tpm2/X509_RSA.c b/src/tpm2/X509_RSA.c
new file mode 100644
index 0000000..3375b3d
--- /dev/null
+++ b/src/tpm2/X509_RSA.c
@@ -0,0 +1,249 @@
+/********************************************************************************/
+/* */
+/* TPM X509 RSA */
+/* Written by Ken Goldman */
+/* IBM Thomas J. Watson Research Center */
+/* $Id: X509_RSA.c 1658 2021-01-22 23:14:01Z kgoldman $ */
+/* */
+/* Licenses and Notices */
+/* */
+/* 1. Copyright Licenses: */
+/* */
+/* - Trusted Computing Group (TCG) grants to the user of the source code in */
+/* this specification (the "Source Code") a worldwide, irrevocable, */
+/* nonexclusive, royalty free, copyright license to reproduce, create */
+/* derivative works, distribute, display and perform the Source Code and */
+/* derivative works thereof, and to grant others the rights granted herein. */
+/* */
+/* - The TCG grants to the user of the other parts of the specification */
+/* (other than the Source Code) the rights to reproduce, distribute, */
+/* display, and perform the specification solely for the purpose of */
+/* developing products based on such documents. */
+/* */
+/* 2. Source Code Distribution Conditions: */
+/* */
+/* - Redistributions of Source Code must retain the above copyright licenses, */
+/* this list of conditions and the following disclaimers. */
+/* */
+/* - Redistributions in binary form must reproduce the above copyright */
+/* licenses, this list of conditions and the following disclaimers in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* 3. Disclaimers: */
+/* */
+/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
+/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
+/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
+/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
+/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
+/* information on specification licensing rights available through TCG */
+/* membership agreements. */
+/* */
+/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
+/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
+/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
+/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
+/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
+/* */
+/* - Without limitation, TCG and its members and licensors disclaim all */
+/* liability, including liability for infringement of any proprietary */
+/* rights, relating to use of information in this specification and to the */
+/* implementation of this specification, and TCG disclaims all liability for */
+/* cost of procurement of substitute goods or services, lost profits, loss */
+/* of use, loss of data or any incidental, consequential, direct, indirect, */
+/* or special damages, whether under contract, tort, warranty or otherwise, */
+/* arising in any way out of use or reliance upon this specification or any */
+/* information herein. */
+/* */
+/* (c) Copyright IBM Corp. and others, 2019 - 2021 */
+/* */
+/********************************************************************************/
+
+/* 10.2.25 X509_RSA.c */
+/* 10.2.25.1 Includes */
+#include "Tpm.h"
+#include "X509.h"
+#include "TpmAsn1_fp.h"
+#include "X509_RSA_fp.h"
+#include "X509_spt_fp.h"
+#include "CryptHash_fp.h"
+#include "CryptRsa_fp.h"
+
+/* 10.2.25.2 Functions */
+#if ALG_RSA
+/* 10.2.25.2.1 X509AddSigningAlgorithmRSA() */
+/* This creates the singing algorithm data. */
+/* Return Value Meaning */
+/* > 0 number of bytes added */
+/* == 0 failure */
+INT16
+X509AddSigningAlgorithmRSA(
+ OBJECT *signKey,
+ TPMT_SIG_SCHEME *scheme,
+ ASN1MarshalContext *ctx
+ )
+{
+ TPM_ALG_ID hashAlg = scheme->details.any.hashAlg;
+ PHASH_DEF hashDef = CryptGetHashDef(hashAlg);
+ //
+ NOT_REFERENCED(signKey);
+ // return failure if hash isn't implemented
+ if(hashDef->hashAlg != hashAlg)
+ return 0;
+ switch(scheme->scheme)
+ {
+ case TPM_ALG_RSASSA:
+ {
+ // if the hash is implemented but there is no PKCS1 OID defined
+ // then this is not a valid signing combination.
+ if(hashDef->PKCS1[0] != ASN1_OBJECT_IDENTIFIER)
+ break;
+ if(ctx == NULL)
+ return 1;
+ return X509PushAlgorithmIdentifierSequence(ctx, hashDef->PKCS1);
+ }
+ case TPM_ALG_RSAPSS:
+ // leave if this is just an implementation check
+ if(ctx == NULL)
+ return 1;
+ // In the case of SHA1, everything is default and RFC4055 says that
+ // implementations that do signature generation MUST omit the parameter
+ // when defaults are used. )-:
+ if(hashDef->hashAlg == TPM_ALG_SHA1)
+ {
+ return X509PushAlgorithmIdentifierSequence(ctx, OID_RSAPSS);
+ }
+ else
+ {
+ // Going to build something that looks like:
+ // SEQUENCE (2 elem)
+ // OBJECT IDENTIFIER 1.2.840.113549.1.1.10 rsaPSS (PKCS #1)
+ // SEQUENCE (3 elem)
+ // [0] (1 elem)
+ // SEQUENCE (2 elem)
+ // OBJECT IDENTIFIER 2.16.840.1.101.3.4.2.1 sha-256
+ // NULL
+ // [1] (1 elem)
+ // SEQUENCE (2 elem)
+ // OBJECT IDENTIFIER 1.2.840.113549.1.1.8 pkcs1-MGF
+ // SEQUENCE (2 elem)
+ // OBJECT IDENTIFIER 2.16.840.1.101.3.4.2.1 sha-256
+ // NULL
+ // [2] (1 elem) salt length
+ // INTEGER 32
+
+ // The indentation is just to keep track of where we are in the
+ // structure
+ ASN1StartMarshalContext(ctx); // SEQUENCE (2 elements)
+ {
+ ASN1StartMarshalContext(ctx); // SEQUENCE (3 elements)
+ {
+ // [2] (1 elem) salt length
+ // INTEGER 32
+ ASN1StartMarshalContext(ctx);
+ {
+ INT16 saltSize =
+ CryptRsaPssSaltSize((INT16)hashDef->digestSize,
+ (INT16)signKey->publicArea.unique.rsa.t.size);
+ ASN1PushUINT(ctx, saltSize);
+ }
+ ASN1EndEncapsulation(ctx, ASN1_APPLICAIION_SPECIFIC + 2);
+
+ // Add the mask generation algorithm
+ // [1] (1 elem)
+ // SEQUENCE (2 elem) 1st
+ // OBJECT IDENTIFIER 1.2.840.113549.1.1.8 pkcs1-MGF
+ // SEQUENCE (2 elem) 2nd
+ // OBJECT IDENTIFIER 2.16.840.1.101.3.4.2.1 sha-256
+ // NULL
+ ASN1StartMarshalContext(ctx); // mask context [1] (1 elem)
+ {
+ ASN1StartMarshalContext(ctx); // SEQUENCE (2 elem) 1st
+ // Handle the 2nd Sequence (sequence (object, null))
+ {
+ // This adds a NULL, then an OID and a SEQUENCE
+ // wrapper.
+ X509PushAlgorithmIdentifierSequence(ctx,
+ hashDef->OID);
+ // add the pkcs1-MGF OID
+ ASN1PushOID(ctx, OID_MGF1);
+ }
+ // End outer sequence
+ ASN1EndEncapsulation(ctx, ASN1_CONSTRUCTED_SEQUENCE);
+ }
+ // End the [1]
+ ASN1EndEncapsulation(ctx, ASN1_APPLICAIION_SPECIFIC + 1);
+
+ // Add the hash algorithm
+ // [0] (1 elem)
+ // SEQUENCE (2 elem) (done by
+ // X509PushAlgorithmIdentifierSequence)
+ // OBJECT IDENTIFIER 2.16.840.1.101.3.4.2.1 sha-256 (NIST)
+ // NULL
+ ASN1StartMarshalContext(ctx); // [0] (1 elem)
+ {
+ X509PushAlgorithmIdentifierSequence(ctx, hashDef->OID);
+ }
+ ASN1EndEncapsulation(ctx, (ASN1_APPLICAIION_SPECIFIC + 0));
+ }
+ // SEQUENCE (3 elements) end
+ ASN1EndEncapsulation(ctx, ASN1_CONSTRUCTED_SEQUENCE);
+
+ // RSA PSS OID
+ // OBJECT IDENTIFIER 1.2.840.113549.1.1.10 rsaPSS (PKCS #1)
+ ASN1PushOID(ctx, OID_RSAPSS);
+ }
+ // End Sequence (2 elements)
+ return ASN1EndEncapsulation(ctx, ASN1_CONSTRUCTED_SEQUENCE);
+ }
+ default:
+ break;
+ }
+ return 0;
+}
+/* 10.2.25.2.2 X509AddPublicRSA() */
+/* This function will add the publicKey description to the DER data. If fillPtr is NULL, then no
+ data is transferred and this function will indicate if the TPM has the values for DER-encoding of
+ the public key. */
+/* Return Value Meaning */
+/* > 0 number of bytes added */
+/* == 0 failure */
+INT16
+X509AddPublicRSA(
+ OBJECT *object,
+ ASN1MarshalContext *ctx
+ )
+{
+ UINT32 exp = object->publicArea.parameters.rsaDetail.exponent;
+ //
+ // If this is a check to see if the key can be encoded, it can.
+ // Need to mark the end sequence
+ if(ctx == NULL)
+ return 1;
+ ASN1StartMarshalContext(ctx); // SEQUENCE (2 elem) 1st
+ ASN1StartMarshalContext(ctx); // BIT STRING
+ ASN1StartMarshalContext(ctx); // SEQUENCE *(2 elem) 3rd
+
+ // Get public exponent in big-endian byte order.
+ if(exp == 0)
+ exp = RSA_DEFAULT_PUBLIC_EXPONENT;
+
+ // Push a 4 byte integer. This might get reduced if there are leading zeros or
+ // extended if the high order byte is negative.
+ ASN1PushUINT(ctx, exp);
+ // Push the public key as an integer
+ ASN1PushInteger(ctx, object->publicArea.unique.rsa.t.size,
+ object->publicArea.unique.rsa.t.buffer);
+ // Embed this in a SEQUENCE tag and length in for the key, exponent sequence
+ ASN1EndEncapsulation(ctx, ASN1_CONSTRUCTED_SEQUENCE); // SEQUENCE (3rd)
+
+ // Embed this in a BIT STRING
+ ASN1EndEncapsulation(ctx, ASN1_BITSTRING);
+
+ // Now add the formatted SEQUENCE for the RSA public key OID. This is a
+ // fully constructed value so it doesn't need to have a context started
+ X509PushAlgorithmIdentifierSequence(ctx, OID_PKCS1_PUB);
+
+ return ASN1EndEncapsulation(ctx, ASN1_CONSTRUCTED_SEQUENCE);
+}
+#endif // ALG_RSA
diff --git a/src/tpm2/X509_RSA_fp.h b/src/tpm2/X509_RSA_fp.h
new file mode 100644
index 0000000..a660e9c
--- /dev/null
+++ b/src/tpm2/X509_RSA_fp.h
@@ -0,0 +1,78 @@
+/********************************************************************************/
+/* */
+/* TPM X509 RSA */
+/* Written by Ken Goldman */
+/* IBM Thomas J. Watson Research Center */
+/* $Id: X509_RSA_fp.h 1490 2019-07-26 21:13:22Z kgoldman $ */
+/* */
+/* Licenses and Notices */
+/* */
+/* 1. Copyright Licenses: */
+/* */
+/* - Trusted Computing Group (TCG) grants to the user of the source code in */
+/* this specification (the "Source Code") a worldwide, irrevocable, */
+/* nonexclusive, royalty free, copyright license to reproduce, create */
+/* derivative works, distribute, display and perform the Source Code and */
+/* derivative works thereof, and to grant others the rights granted herein. */
+/* */
+/* - The TCG grants to the user of the other parts of the specification */
+/* (other than the Source Code) the rights to reproduce, distribute, */
+/* display, and perform the specification solely for the purpose of */
+/* developing products based on such documents. */
+/* */
+/* 2. Source Code Distribution Conditions: */
+/* */
+/* - Redistributions of Source Code must retain the above copyright licenses, */
+/* this list of conditions and the following disclaimers. */
+/* */
+/* - Redistributions in binary form must reproduce the above copyright */
+/* licenses, this list of conditions and the following disclaimers in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* 3. Disclaimers: */
+/* */
+/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
+/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
+/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
+/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
+/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
+/* information on specification licensing rights available through TCG */
+/* membership agreements. */
+/* */
+/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
+/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
+/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
+/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
+/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
+/* */
+/* - Without limitation, TCG and its members and licensors disclaim all */
+/* liability, including liability for infringement of any proprietary */
+/* rights, relating to use of information in this specification and to the */
+/* implementation of this specification, and TCG disclaims all liability for */
+/* cost of procurement of substitute goods or services, lost profits, loss */
+/* of use, loss of data or any incidental, consequential, direct, indirect, */
+/* or special damages, whether under contract, tort, warranty or otherwise, */
+/* arising in any way out of use or reliance upon this specification or any */
+/* information herein. */
+/* */
+/* (c) Copyright IBM Corp. and others, 2019 */
+/* */
+/********************************************************************************/
+
+#ifndef X509_RSA_FP_H
+#define X509_RSA_FP_H
+
+INT16
+X509AddSigningAlgorithmRSA(
+ OBJECT *signKey,
+ TPMT_SIG_SCHEME *scheme,
+ ASN1MarshalContext *ctx
+ );
+INT16
+X509AddPublicRSA(
+ OBJECT *object,
+ ASN1MarshalContext *ctx
+ );
+
+
+#endif
diff --git a/src/tpm2/X509_spt.c b/src/tpm2/X509_spt.c
new file mode 100644
index 0000000..564a4d3
--- /dev/null
+++ b/src/tpm2/X509_spt.c
@@ -0,0 +1,318 @@
+/********************************************************************************/
+/* */
+/* X509 Support */
+/* Written by Ken Goldman */
+/* IBM Thomas J. Watson Research Center */
+/* $Id: X509_spt.c 1658 2021-01-22 23:14:01Z kgoldman $ */
+/* */
+/* Licenses and Notices */
+/* */
+/* 1. Copyright Licenses: */
+/* */
+/* - Trusted Computing Group (TCG) grants to the user of the source code in */
+/* this specification (the "Source Code") a worldwide, irrevocable, */
+/* nonexclusive, royalty free, copyright license to reproduce, create */
+/* derivative works, distribute, display and perform the Source Code and */
+/* derivative works thereof, and to grant others the rights granted herein. */
+/* */
+/* - The TCG rants to the user of the other parts of the specification */
+/* (other than the Source Code) the rights to reproduce, distribute, */
+/* display, and perform the specification solely for the purpose of */
+/* developing products based on such documents. */
+/* */
+/* 2. Source Code Distribution Conditions: */
+/* */
+/* - Redistributions of Source Code must retain the above copyright licenses, */
+/* this list of conditions and the following disclaimers. */
+/* */
+/* - Redistributions in binary form must reproduce the above copyright */
+/* licenses, this list of conditions and the following disclaimers in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* 3. Disclaimers: */
+/* */
+/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
+/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
+/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
+/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
+/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
+/* information on specification licensing rights available through TCG */
+/* membership agreements. */
+/* */
+/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
+/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
+/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
+/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
+/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
+/* */
+/* - Without limitation, TCG and its members and licensors disclaim all */
+/* liability, including liability for infringement of any proprietary */
+/* rights, relating to use of information in this specification and to the */
+/* implementation of this specification, and TCG disclaims all liability for */
+/* cost of procurement of substitute goods or services, lost profits, loss */
+/* of use, loss of data or any incidental, consequential, direct, indirect, */
+/* or special damages, whether under contract, tort, warranty or otherwise, */
+/* arising in any way out of use or reliance upon this specification or any */
+/* information herein. */
+/* */
+/* (c) Copyright IBM Corp. and others, 2019 - 2021 */
+/* */
+/********************************************************************************/
+
+
+/* 10.2.26 X509_spt.c */
+/* 10.2.26.1 Includes */
+#include "Tpm.h"
+#include "TpmAsn1.h"
+#include "TpmAsn1_fp.h"
+#define _X509_SPT_
+#include "X509.h"
+#include "X509_spt_fp.h"
+#if ALG_RSA
+# include "X509_RSA_fp.h"
+#endif // ALG_RSA
+#if ALG_ECC
+# include "X509_ECC_fp.h"
+#endif // ALG_ECC
+#if ALG_SM2
+//# include "X509_SM2_fp.h"
+#endif // ALG_RSA
+/* 10.2.26.2 Unmarshaling Functions */
+/* 10.2.26.2.1 X509FindExtensionByOID() */
+/* This will search a list of X509 extensions to find an extension with the requested OID. If the
+ extension is found, the output context (ctx) is set up to point to the OID in the extension. */
+/* Return Value Meaning */
+/* TRUE(1) success */
+/* FALSE(0) failure (could be catastrophic) */
+BOOL
+X509FindExtensionByOID(
+ ASN1UnmarshalContext *ctxIn, // IN: the context to search
+ ASN1UnmarshalContext *ctx, // OUT: the extension context
+ const BYTE *OID // IN: oid to search for
+ )
+{
+ INT16 length;
+ //
+ pAssert(ctxIn != NULL);
+ // Make the search non-destructive of the input if ctx provided. Otherwise, use
+ // the provided context.
+ if (ctx == NULL)
+ ctx = ctxIn;
+ // if the provided search context is different from the context of the extension,
+ // then copy the search context to the search context.
+ else if(ctx != ctxIn)
+ *ctx = *ctxIn;
+ // Now, search in the extension context
+ for(;ctx->size > ctx->offset; ctx->offset += length)
+ {
+ VERIFY((length = ASN1NextTag(ctx)) >= 0);
+ // If this is not a constructed sequence, then it doesn't belong
+ // in the extensions.
+ VERIFY(ctx->tag == ASN1_CONSTRUCTED_SEQUENCE);
+ // Make sure that this entry could hold the OID
+ if (length >= OID_SIZE(OID))
+ {
+ // See if this is a match for the provided object identifier.
+ if (MemoryEqual(OID, &(ctx->buffer[ctx->offset]), OID_SIZE(OID)))
+ {
+ // Return with ' ctx' set to point to the start of the OID with the size
+ // set to be the size of the SEQUENCE
+ ctx->buffer += ctx->offset;
+ ctx->offset = 0;
+ ctx->size = length;
+ return TRUE;
+ }
+ }
+ }
+ VERIFY(ctx->offset == ctx->size);
+ return FALSE;
+ Error:
+ ctxIn->size = -1;
+ ctx->size = -1;
+ return FALSE;
+}
+/* 10.2.26.2.2 X509GetExtensionBits() */
+/* This function will extract a bit field from an extension. If the extension doesn't contain a bit
+ string, it will fail. */
+/* Return Value Meaning */
+/* TRUE(1) success */
+/* FALSE(0) failure */
+UINT32
+X509GetExtensionBits(
+ ASN1UnmarshalContext *ctx,
+ UINT32 *value
+ )
+{
+ INT16 length;
+ //
+ while (((length = ASN1NextTag(ctx)) > 0) && (ctx->size > ctx->offset))
+ {
+ // Since this is an extension, the extension value will be in an OCTET STRING
+ if (ctx->tag == ASN1_OCTET_STRING)
+ {
+ return ASN1GetBitStringValue(ctx, value);
+ }
+ ctx->offset += length;
+ }
+ ctx->size = -1;
+ return FALSE;
+}
+/* 10.2.26.2.3 X509ProcessExtensions() */
+/* This function is used to process the TPMA_OBJECT and KeyUsage() extensions. It is not in the
+ CertifyX509.c code because it makes the code harder to follow. */
+/* Error Returns Meaning */
+/* TPM_RCS_ATTRIBUTES the attributes of object are not consistent with the extension setting */
+/* TPM_RC_VALUE problem parsing the extensions */
+TPM_RC
+X509ProcessExtensions(
+ OBJECT *object, // IN: The object with the attributes to
+ // check
+ stringRef *extension // IN: The start and length of the extensions
+ )
+{
+ ASN1UnmarshalContext ctx;
+ ASN1UnmarshalContext extensionCtx;
+ INT16 length;
+ UINT32 value;
+ TPMA_OBJECT attributes = object->publicArea.objectAttributes;
+ //
+ if(!ASN1UnmarshalContextInitialize(&ctx, extension->len, extension->buf)
+ || ((length = ASN1NextTag(&ctx)) < 0)
+ || (ctx.tag != X509_EXTENSIONS))
+ return TPM_RCS_VALUE;
+ if( ((length = ASN1NextTag(&ctx)) < 0)
+ || (ctx.tag != (ASN1_CONSTRUCTED_SEQUENCE)))
+ return TPM_RCS_VALUE;
+
+ // Get the extension for the TPMA_OBJECT if there is one
+ if(X509FindExtensionByOID(&ctx, &extensionCtx, OID_TCG_TPMA_OBJECT) &&
+ X509GetExtensionBits(&extensionCtx, &value))
+ {
+ // If an keyAttributes extension was found, it must be exactly the same as the
+ // attributes of the object.
+ // NOTE: MemoryEqual() is used rather than a simple UINT32 compare to avoid
+ // type-punned pointer warning/error.
+ if(!MemoryEqual(&value, &attributes, sizeof(value)))
+ return TPM_RCS_ATTRIBUTES;
+ }
+ // Make sure the failure to find the value wasn't because of a fatal error
+ else if(extensionCtx.size < 0)
+ return TPM_RCS_VALUE;
+
+ // Get the keyUsage extension. This one is required
+ if(X509FindExtensionByOID(&ctx, &extensionCtx, OID_KEY_USAGE_EXTENSION) &&
+ X509GetExtensionBits(&extensionCtx, &value))
+ {
+ x509KeyUsageUnion keyUsage;
+ BOOL badSign;
+ BOOL badDecrypt;
+ BOOL badFixedTPM;
+ BOOL badRestricted;
+
+ keyUsage.integer = value;
+
+ // For KeyUsage:
+ // 1) 'sign' is SET if Key Usage includes signing
+ badSign = ((KEY_USAGE_SIGN.integer & keyUsage.integer) != 0)
+ && !IS_ATTRIBUTE(attributes, TPMA_OBJECT, sign);
+ // 2) 'decrypt' is SET if Key Usage includes decryption uses
+ badDecrypt = ((KEY_USAGE_DECRYPT.integer & keyUsage.integer) != 0)
+ && !IS_ATTRIBUTE(attributes, TPMA_OBJECT, decrypt);
+ // 3) 'fixedTPM' is SET if Key Usage is non-repudiation
+ badFixedTPM = IS_ATTRIBUTE(keyUsage.x509, TPMA_X509_KEY_USAGE,
+ nonrepudiation)
+ && !IS_ATTRIBUTE(attributes, TPMA_OBJECT, fixedTPM);
+ // 4)'restricted' is SET if Key Usage is for key agreement.
+ badRestricted = IS_ATTRIBUTE(keyUsage.x509, TPMA_X509_KEY_USAGE, keyAgreement)
+ && !IS_ATTRIBUTE(attributes, TPMA_OBJECT, restricted);
+ if(badSign || badDecrypt || badFixedTPM || badRestricted)
+ return TPM_RCS_VALUE;
+ }
+ else
+ // The KeyUsage extension is required
+ return TPM_RCS_VALUE;
+
+ return TPM_RC_SUCCESS;
+}
+/* 10.2.26.3 Marshaling Functions */
+/* 10.2.26.3.1 X509AddSigningAlgorithm() */
+/* This creates the singing algorithm data. */
+/* Return Value Meaning */
+/* > 0 number of octets added */
+/* <= 0 failure */
+INT16
+X509AddSigningAlgorithm(
+ ASN1MarshalContext *ctx,
+ OBJECT *signKey,
+ TPMT_SIG_SCHEME *scheme
+ )
+{
+ switch(signKey->publicArea.type)
+ {
+#if ALG_RSA
+ case TPM_ALG_RSA:
+ return X509AddSigningAlgorithmRSA(signKey, scheme, ctx);
+#endif // ALG_RSA
+#if ALG_ECC
+ case TPM_ALG_ECC:
+ return X509AddSigningAlgorithmECC(signKey, scheme, ctx);
+#endif // ALG_ECC
+#if ALG_SM2
+ case TPM_ALG_SM2:
+ break; // no signing algorithm for SM2 yet
+ // return X509AddSigningAlgorithmSM2(signKey, scheme, ctx);
+#endif // ALG_SM2
+ default:
+ break;
+ }
+ return 0;
+}
+/* 10.2.26.3.2 X509AddPublicKey() */
+/* This function will add the publicKey description to the DER data. If fillPtr is NULL, then no
+ data is transferred and this function will indicate if the TPM has the values for DER-encoding of
+ the public key. */
+/* Return Value Meaning */
+/* > 0 number of octets added */
+/* == 0 failure */
+INT16
+X509AddPublicKey(
+ ASN1MarshalContext *ctx,
+ OBJECT *object
+ )
+{
+ switch(object->publicArea.type)
+ {
+#if ALG_RSA
+ case TPM_ALG_RSA:
+ return X509AddPublicRSA(object, ctx);
+#endif
+#if ALG_ECC
+ case TPM_ALG_ECC:
+ return X509AddPublicECC(object, ctx);
+#endif
+#if ALG_SM2
+ case TPM_ALG_SM2:
+ break;
+#endif
+ default:
+ break;
+ }
+ return FALSE;
+}
+/* 10.2.26.3.3 X509PushAlgorithmIdentifierSequence() */
+/* The function adds the algorithm identifier sequence. */
+/* Return Value Meaning */
+/* > 0 number of bytes added */
+/* == 0 failure */
+INT16
+X509PushAlgorithmIdentifierSequence(
+ ASN1MarshalContext *ctx,
+ const BYTE *OID
+ )
+{
+ ASN1StartMarshalContext(ctx); // hash algorithm
+ ASN1PushNull(ctx);
+ ASN1PushOID(ctx, OID);
+ return ASN1EndEncapsulation(ctx, ASN1_CONSTRUCTED_SEQUENCE);
+}
+
diff --git a/src/tpm2/X509_spt_fp.h b/src/tpm2/X509_spt_fp.h
new file mode 100644
index 0000000..96a1587
--- /dev/null
+++ b/src/tpm2/X509_spt_fp.h
@@ -0,0 +1,98 @@
+/********************************************************************************/
+/* */
+/* X509 Support */
+/* Written by Ken Goldman */
+/* IBM Thomas J. Watson Research Center */
+/* $Id: X509_spt_fp.h 1490 2019-07-26 21:13:22Z kgoldman $ */
+/* */
+/* Licenses and Notices */
+/* */
+/* 1. Copyright Licenses: */
+/* */
+/* - Trusted Computing Group (TCG) grants to the user of the source code in */
+/* this specification (the "Source Code") a worldwide, irrevocable, */
+/* nonexclusive, royalty free, copyright license to reproduce, create */
+/* derivative works, distribute, display and perform the Source Code and */
+/* derivative works thereof, and to grant others the rights granted herein. */
+/* */
+/* - The TCG grants to the user of the other parts of the specification */
+/* (other than the Source Code) the rights to reproduce, distribute, */
+/* display, and perform the specification solely for the purpose of */
+/* developing products based on such documents. */
+/* */
+/* 2. Source Code Distribution Conditions: */
+/* */
+/* - Redistributions of Source Code must retain the above copyright licenses, */
+/* this list of conditions and the following disclaimers. */
+/* */
+/* - Redistributions in binary form must reproduce the above copyright */
+/* licenses, this list of conditions and the following disclaimers in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* 3. Disclaimers: */
+/* */
+/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
+/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
+/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
+/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
+/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
+/* information on specification licensing rights available through TCG */
+/* membership agreements. */
+/* */
+/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
+/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
+/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
+/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
+/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
+/* */
+/* - Without limitation, TCG and its members and licensors disclaim all */
+/* liability, including liability for infringement of any proprietary */
+/* rights, relating to use of information in this specification and to the */
+/* implementation of this specification, and TCG disclaims all liability for */
+/* cost of procurement of substitute goods or services, lost profits, loss */
+/* of use, loss of data or any incidental, consequential, direct, indirect, */
+/* or special damages, whether under contract, tort, warranty or otherwise, */
+/* arising in any way out of use or reliance upon this specification or any */
+/* information herein. */
+/* */
+/* (c) Copyright IBM Corp. and others, 2019. */
+/* */
+/********************************************************************************/
+
+#ifndef X509_SPT_FP_H
+#define X509_SPT_FP_H
+
+BOOL
+X509FindExtensionByOID(
+ ASN1UnmarshalContext *ctxIn, // IN: the context to search
+ ASN1UnmarshalContext *ctx, // OUT: the extension context
+ const BYTE *OID // IN: oid to search for
+ );
+UINT32
+X509GetExtensionBits(
+ ASN1UnmarshalContext *ctx,
+ UINT32 *value
+ );
+TPM_RC
+X509ProcessExtensions(
+ OBJECT *object, // IN: The object with the attributes to
+ // check
+ stringRef *extension // IN: The start and length of the extensions
+ );
+INT16
+X509AddSigningAlgorithm(
+ ASN1MarshalContext *ctx,
+ OBJECT *signKey,
+ TPMT_SIG_SCHEME *scheme
+ );
+INT16
+X509AddPublicKey(
+ ASN1MarshalContext *ctx,
+ OBJECT *object
+ );
+INT16
+X509PushAlgorithmIdentifierSequence(
+ ASN1MarshalContext *ctx,
+ const BYTE *OID
+ );
+#endif
diff --git a/src/tpm2/ZGen_2Phase_fp.h b/src/tpm2/ZGen_2Phase_fp.h
new file mode 100644
index 0000000..6bfb974
--- /dev/null
+++ b/src/tpm2/ZGen_2Phase_fp.h
@@ -0,0 +1,93 @@
+/********************************************************************************/
+/* */
+/* */
+/* Written by Ken Goldman */
+/* IBM Thomas J. Watson Research Center */
+/* $Id: ZGen_2Phase_fp.h 809 2016-11-16 18:31:54Z kgoldman $ */
+/* */
+/* Licenses and Notices */
+/* */
+/* 1. Copyright Licenses: */
+/* */
+/* - Trusted Computing Group (TCG) grants to the user of the source code in */
+/* this specification (the "Source Code") a worldwide, irrevocable, */
+/* nonexclusive, royalty free, copyright license to reproduce, create */
+/* derivative works, distribute, display and perform the Source Code and */
+/* derivative works thereof, and to grant others the rights granted herein. */
+/* */
+/* - The TCG grants to the user of the other parts of the specification */
+/* (other than the Source Code) the rights to reproduce, distribute, */
+/* display, and perform the specification solely for the purpose of */
+/* developing products based on such documents. */
+/* */
+/* 2. Source Code Distribution Conditions: */
+/* */
+/* - Redistributions of Source Code must retain the above copyright licenses, */
+/* this list of conditions and the following disclaimers. */
+/* */
+/* - Redistributions in binary form must reproduce the above copyright */
+/* licenses, this list of conditions and the following disclaimers in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* 3. Disclaimers: */
+/* */
+/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
+/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
+/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
+/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
+/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
+/* information on specification licensing rights available through TCG */
+/* membership agreements. */
+/* */
+/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
+/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
+/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
+/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
+/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
+/* */
+/* - Without limitation, TCG and its members and licensors disclaim all */
+/* liability, including liability for infringement of any proprietary */
+/* rights, relating to use of information in this specification and to the */
+/* implementation of this specification, and TCG disclaims all liability for */
+/* cost of procurement of substitute goods or services, lost profits, loss */
+/* of use, loss of data or any incidental, consequential, direct, indirect, */
+/* or special damages, whether under contract, tort, warranty or otherwise, */
+/* arising in any way out of use or reliance upon this specification or any */
+/* information herein. */
+/* */
+/* (c) Copyright IBM Corp. and others, 2012-2015 */
+/* */
+/********************************************************************************/
+
+/* rev 119 */
+
+#ifndef ZGEN_2PHASE_FP_H
+#define ZGEN_2PHASE_FP_H
+
+typedef struct {
+ TPMI_DH_OBJECT keyA;
+ TPM2B_ECC_POINT inQsB;
+ TPM2B_ECC_POINT inQeB;
+ TPMI_ECC_KEY_EXCHANGE inScheme;
+ UINT16 counter;
+} ZGen_2Phase_In;
+
+#define RC_ZGen_2Phase_keyA (TPM_RC_H + TPM_RC_1)
+#define RC_ZGen_2Phase_inQsB (TPM_RC_P + TPM_RC_1)
+#define RC_ZGen_2Phase_inQeB (TPM_RC_P + TPM_RC_2)
+#define RC_ZGen_2Phase_inScheme (TPM_RC_P + TPM_RC_3)
+#define RC_ZGen_2Phase_counter (TPM_RC_P + TPM_RC_4)
+
+typedef struct {
+ TPM2B_ECC_POINT outZ1;
+ TPM2B_ECC_POINT outZ2;
+} ZGen_2Phase_Out;
+
+TPM_RC
+TPM2_ZGen_2Phase(
+ ZGen_2Phase_In *in, // IN: input parameter list
+ ZGen_2Phase_Out *out // OUT: output parameter list
+ );
+
+
+#endif
diff --git a/src/tpm2/_TPM_Hash_Data_fp.h b/src/tpm2/_TPM_Hash_Data_fp.h
new file mode 100644
index 0000000..0da24c5
--- /dev/null
+++ b/src/tpm2/_TPM_Hash_Data_fp.h
@@ -0,0 +1,72 @@
+/********************************************************************************/
+/* */
+/* */
+/* Written by Ken Goldman */
+/* IBM Thomas J. Watson Research Center */
+/* $Id: _TPM_Hash_Data_fp.h 1521 2019-11-15 21:00:47Z kgoldman $ */
+/* */
+/* Licenses and Notices */
+/* */
+/* 1. Copyright Licenses: */
+/* */
+/* - Trusted Computing Group (TCG) grants to the user of the source code in */
+/* this specification (the "Source Code") a worldwide, irrevocable, */
+/* nonexclusive, royalty free, copyright license to reproduce, create */
+/* derivative works, distribute, display and perform the Source Code and */
+/* derivative works thereof, and to grant others the rights granted herein. */
+/* */
+/* - The TCG grants to the user of the other parts of the specification */
+/* (other than the Source Code) the rights to reproduce, distribute, */
+/* display, and perform the specification solely for the purpose of */
+/* developing products based on such documents. */
+/* */
+/* 2. Source Code Distribution Conditions: */
+/* */
+/* - Redistributions of Source Code must retain the above copyright licenses, */
+/* this list of conditions and the following disclaimers. */
+/* */
+/* - Redistributions in binary form must reproduce the above copyright */
+/* licenses, this list of conditions and the following disclaimers in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* 3. Disclaimers: */
+/* */
+/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
+/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
+/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
+/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
+/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
+/* information on specification licensing rights available through TCG */
+/* membership agreements. */
+/* */
+/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
+/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
+/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
+/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
+/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
+/* */
+/* - Without limitation, TCG and its members and licensors disclaim all */
+/* liability, including liability for infringement of any proprietary */
+/* rights, relating to use of information in this specification and to the */
+/* implementation of this specification, and TCG disclaims all liability for */
+/* cost of procurement of substitute goods or services, lost profits, loss */
+/* of use, loss of data or any incidental, consequential, direct, indirect, */
+/* or special damages, whether under contract, tort, warranty or otherwise, */
+/* arising in any way out of use or reliance upon this specification or any */
+/* information herein. */
+/* */
+/* (c) Copyright IBM Corp. and others, 2016 */
+/* */
+/********************************************************************************/
+
+#ifndef _TPM_HASH_DATA_FP_H
+#define _TPM_HASH_DATA_FP_H
+
+LIB_EXPORT void
+_TPM_Hash_Data(
+ uint32_t dataSize, // IN: size of data to be extend
+ unsigned char *data // IN: data buffer
+ );
+
+
+#endif
diff --git a/src/tpm2/_TPM_Hash_End_fp.h b/src/tpm2/_TPM_Hash_End_fp.h
new file mode 100644
index 0000000..c99c7f6
--- /dev/null
+++ b/src/tpm2/_TPM_Hash_End_fp.h
@@ -0,0 +1,71 @@
+/********************************************************************************/
+/* */
+/* */
+/* Written by Ken Goldman */
+/* IBM Thomas J. Watson Research Center */
+/* $Id: _TPM_Hash_End_fp.h 1521 2019-11-15 21:00:47Z kgoldman $ */
+/* */
+/* Licenses and Notices */
+/* */
+/* 1. Copyright Licenses: */
+/* */
+/* - Trusted Computing Group (TCG) grants to the user of the source code in */
+/* this specification (the "Source Code") a worldwide, irrevocable, */
+/* nonexclusive, royalty free, copyright license to reproduce, create */
+/* derivative works, distribute, display and perform the Source Code and */
+/* derivative works thereof, and to grant others the rights granted herein. */
+/* */
+/* - The TCG grants to the user of the other parts of the specification */
+/* (other than the Source Code) the rights to reproduce, distribute, */
+/* display, and perform the specification solely for the purpose of */
+/* developing products based on such documents. */
+/* */
+/* 2. Source Code Distribution Conditions: */
+/* */
+/* - Redistributions of Source Code must retain the above copyright licenses, */
+/* this list of conditions and the following disclaimers. */
+/* */
+/* - Redistributions in binary form must reproduce the above copyright */
+/* licenses, this list of conditions and the following disclaimers in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* 3. Disclaimers: */
+/* */
+/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
+/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
+/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
+/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
+/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
+/* information on specification licensing rights available through TCG */
+/* membership agreements. */
+/* */
+/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
+/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
+/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
+/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
+/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
+/* */
+/* - Without limitation, TCG and its members and licensors disclaim all */
+/* liability, including liability for infringement of any proprietary */
+/* rights, relating to use of information in this specification and to the */
+/* implementation of this specification, and TCG disclaims all liability for */
+/* cost of procurement of substitute goods or services, lost profits, loss */
+/* of use, loss of data or any incidental, consequential, direct, indirect, */
+/* or special damages, whether under contract, tort, warranty or otherwise, */
+/* arising in any way out of use or reliance upon this specification or any */
+/* information herein. */
+/* */
+/* (c) Copyright IBM Corp. and others, 2016 */
+/* */
+/********************************************************************************/
+
+#ifndef _TPM_HASH_END_FP_H
+#define _TPM_HASH_END_FP_H
+
+LIB_EXPORT void
+_TPM_Hash_End(
+ void
+ );
+
+
+#endif
diff --git a/src/tpm2/_TPM_Hash_Start_fp.h b/src/tpm2/_TPM_Hash_Start_fp.h
new file mode 100644
index 0000000..9980653
--- /dev/null
+++ b/src/tpm2/_TPM_Hash_Start_fp.h
@@ -0,0 +1,71 @@
+/********************************************************************************/
+/* */
+/* */
+/* Written by Ken Goldman */
+/* IBM Thomas J. Watson Research Center */
+/* $Id: _TPM_Hash_Start_fp.h 1521 2019-11-15 21:00:47Z kgoldman $ */
+/* */
+/* Licenses and Notices */
+/* */
+/* 1. Copyright Licenses: */
+/* */
+/* - Trusted Computing Group (TCG) grants to the user of the source code in */
+/* this specification (the "Source Code") a worldwide, irrevocable, */
+/* nonexclusive, royalty free, copyright license to reproduce, create */
+/* derivative works, distribute, display and perform the Source Code and */
+/* derivative works thereof, and to grant others the rights granted herein. */
+/* */
+/* - The TCG grants to the user of the other parts of the specification */
+/* (other than the Source Code) the rights to reproduce, distribute, */
+/* display, and perform the specification solely for the purpose of */
+/* developing products based on such documents. */
+/* */
+/* 2. Source Code Distribution Conditions: */
+/* */
+/* - Redistributions of Source Code must retain the above copyright licenses, */
+/* this list of conditions and the following disclaimers. */
+/* */
+/* - Redistributions in binary form must reproduce the above copyright */
+/* licenses, this list of conditions and the following disclaimers in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* 3. Disclaimers: */
+/* */
+/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
+/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
+/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
+/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
+/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
+/* information on specification licensing rights available through TCG */
+/* membership agreements. */
+/* */
+/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
+/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
+/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
+/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
+/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
+/* */
+/* - Without limitation, TCG and its members and licensors disclaim all */
+/* liability, including liability for infringement of any proprietary */
+/* rights, relating to use of information in this specification and to the */
+/* implementation of this specification, and TCG disclaims all liability for */
+/* cost of procurement of substitute goods or services, lost profits, loss */
+/* of use, loss of data or any incidental, consequential, direct, indirect, */
+/* or special damages, whether under contract, tort, warranty or otherwise, */
+/* arising in any way out of use or reliance upon this specification or any */
+/* information herein. */
+/* */
+/* (c) Copyright IBM Corp. and others, 2016 */
+/* */
+/********************************************************************************/
+
+#ifndef _TPM_HASH_START_FP_H
+#define _TPM_HASH_START_FP_H
+
+LIB_EXPORT void
+_TPM_Hash_Start(
+ void
+ );
+
+
+#endif
diff --git a/src/tpm2/_TPM_Init_fp.h b/src/tpm2/_TPM_Init_fp.h
new file mode 100644
index 0000000..29929fb
--- /dev/null
+++ b/src/tpm2/_TPM_Init_fp.h
@@ -0,0 +1,73 @@
+/********************************************************************************/
+/* */
+/* */
+/* Written by Ken Goldman */
+/* IBM Thomas J. Watson Research Center */
+/* $Id: _TPM_Init_fp.h 1490 2019-07-26 21:13:22Z kgoldman $ */
+/* */
+/* Licenses and Notices */
+/* */
+/* 1. Copyright Licenses: */
+/* */
+/* - Trusted Computing Group (TCG) grants to the user of the source code in */
+/* this specification (the "Source Code") a worldwide, irrevocable, */
+/* nonexclusive, royalty free, copyright license to reproduce, create */
+/* derivative works, distribute, display and perform the Source Code and */
+/* derivative works thereof, and to grant others the rights granted herein. */
+/* */
+/* - The TCG grants to the user of the other parts of the specification */
+/* (other than the Source Code) the rights to reproduce, distribute, */
+/* display, and perform the specification solely for the purpose of */
+/* developing products based on such documents. */
+/* */
+/* 2. Source Code Distribution Conditions: */
+/* */
+/* - Redistributions of Source Code must retain the above copyright licenses, */
+/* this list of conditions and the following disclaimers. */
+/* */
+/* - Redistributions in binary form must reproduce the above copyright */
+/* licenses, this list of conditions and the following disclaimers in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* 3. Disclaimers: */
+/* */
+/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
+/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
+/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
+/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
+/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
+/* information on specification licensing rights available through TCG */
+/* membership agreements. */
+/* */
+/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
+/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
+/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
+/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
+/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
+/* */
+/* - Without limitation, TCG and its members and licensors disclaim all */
+/* liability, including liability for infringement of any proprietary */
+/* rights, relating to use of information in this specification and to the */
+/* implementation of this specification, and TCG disclaims all liability for */
+/* cost of procurement of substitute goods or services, lost profits, loss */
+/* of use, loss of data or any incidental, consequential, direct, indirect, */
+/* or special damages, whether under contract, tort, warranty or otherwise, */
+/* arising in any way out of use or reliance upon this specification or any */
+/* information herein. */
+/* */
+/* (c) Copyright IBM Corp. and others, 2016 */
+/* */
+/********************************************************************************/
+
+#ifndef _TPM_INIT_FP_H
+#define _TPM_INIT_FP_H
+
+LIB_EXPORT void
+_TPM_Init(
+ void
+ );
+
+
+
+
+#endif
diff --git a/src/tpm2/crypto/CryptCmac_fp.h b/src/tpm2/crypto/CryptCmac_fp.h
new file mode 100644
index 0000000..f1df646
--- /dev/null
+++ b/src/tpm2/crypto/CryptCmac_fp.h
@@ -0,0 +1,86 @@
+/********************************************************************************/
+/* Message Authentication Codes Based on a Symmetric Block Cipher */
+/* Implementation of cryptographic functions for hashing. */
+/* Written by Ken Goldman */
+/* IBM Thomas J. Watson Research Center */
+/* $Id: CryptCmac_fp.h 1490 2019-07-26 21:13:22Z kgoldman $ */
+/* */
+/* Licenses and Notices */
+/* */
+/* 1. Copyright Licenses: */
+/* */
+/* - Trusted Computing Group (TCG) grants to the user of the source code in */
+/* this specification (the "Source Code") a worldwide, irrevocable, */
+/* nonexclusive, royalty free, copyright license to reproduce, create */
+/* derivative works, distribute, display and perform the Source Code and */
+/* derivative works thereof, and to grant others the rights granted herein. */
+/* */
+/* - The TCG grants to the user of the other parts of the specification */
+/* (other than the Source Code) the rights to reproduce, distribute, */
+/* display, and perform the specification solely for the purpose of */
+/* developing products based on such documents. */
+/* */
+/* 2. Source Code Distribution Conditions: */
+/* */
+/* - Redistributions of Source Code must retain the above copyright licenses, */
+/* this list of conditions and the following disclaimers. */
+/* */
+/* - Redistributions in binary form must reproduce the above copyright */
+/* licenses, this list of conditions and the following disclaimers in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* 3. Disclaimers: */
+/* */
+/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
+/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
+/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
+/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
+/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
+/* information on specification licensing rights available through TCG */
+/* membership agreements. */
+/* */
+/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
+/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
+/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
+/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
+/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
+/* */
+/* - Without limitation, TCG and its members and licensors disclaim all */
+/* liability, including liability for infringement of any proprietary */
+/* rights, relating to use of information in this specification and to the */
+/* implementation of this specification, and TCG disclaims all liability for */
+/* cost of procurement of substitute goods or services, lost profits, loss */
+/* of use, loss of data or any incidental, consequential, direct, indirect, */
+/* or special damages, whether under contract, tort, warranty or otherwise, */
+/* arising in any way out of use or reliance upon this specification or any */
+/* information herein. */
+/* */
+/* (c) Copyright IBM Corp. and others, 2018 */
+/* */
+/********************************************************************************/
+
+#ifndef CRYPTCMAC_FP_H
+#define CRYPTCMAC_FP_H
+#include "Tpm.h"
+
+UINT16
+CryptCmacStart(
+ SMAC_STATE *state,
+ TPMU_PUBLIC_PARMS *keyParms,
+ TPM_ALG_ID macAlg,
+ TPM2B *key
+ );
+void
+CryptCmacData(
+ SMAC_STATES *state,
+ UINT32 size,
+ const BYTE *buffer
+ );
+UINT16
+CryptCmacEnd(
+ SMAC_STATES *state,
+ UINT32 outSize,
+ BYTE *outBuffer
+ );
+
+#endif
diff --git a/src/tpm2/crypto/CryptDes_fp.h b/src/tpm2/crypto/CryptDes_fp.h
new file mode 100644
index 0000000..1c1c3cd
--- /dev/null
+++ b/src/tpm2/crypto/CryptDes_fp.h
@@ -0,0 +1,82 @@
+/********************************************************************************/
+/* */
+/* */
+/* Written by Ken Goldman */
+/* IBM Thomas J. Watson Research Center */
+/* $Id: CryptDes_fp.h 809 2016-11-16 18:31:54Z kgoldman $ */
+/* */
+/* Licenses and Notices */
+/* */
+/* 1. Copyright Licenses: */
+/* */
+/* - Trusted Computing Group (TCG) grants to the user of the source code in */
+/* this specification (the "Source Code") a worldwide, irrevocable, */
+/* nonexclusive, royalty free, copyright license to reproduce, create */
+/* derivative works, distribute, display and perform the Source Code and */
+/* derivative works thereof, and to grant others the rights granted herein. */
+/* */
+/* - The TCG grants to the user of the other parts of the specification */
+/* (other than the Source Code) the rights to reproduce, distribute, */
+/* display, and perform the specification solely for the purpose of */
+/* developing products based on such documents. */
+/* */
+/* 2. Source Code Distribution Conditions: */
+/* */
+/* - Redistributions of Source Code must retain the above copyright licenses, */
+/* this list of conditions and the following disclaimers. */
+/* */
+/* - Redistributions in binary form must reproduce the above copyright */
+/* licenses, this list of conditions and the following disclaimers in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* 3. Disclaimers: */
+/* */
+/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
+/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
+/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
+/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
+/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
+/* information on specification licensing rights available through TCG */
+/* membership agreements. */
+/* */
+/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
+/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
+/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
+/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
+/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
+/* */
+/* - Without limitation, TCG and its members and licensors disclaim all */
+/* liability, including liability for infringement of any proprietary */
+/* rights, relating to use of information in this specification and to the */
+/* implementation of this specification, and TCG disclaims all liability for */
+/* cost of procurement of substitute goods or services, lost profits, loss */
+/* of use, loss of data or any incidental, consequential, direct, indirect, */
+/* or special damages, whether under contract, tort, warranty or otherwise, */
+/* arising in any way out of use or reliance upon this specification or any */
+/* information herein. */
+/* */
+/* (c) Copyright IBM Corp. and others, 2016 */
+/* */
+/********************************************************************************/
+
+#ifndef CRYPTDES_FP_H
+#define CRYPTDES_FP_H
+
+UINT64
+CryptSetOddByteParity(
+ UINT64 k
+ );
+BOOL
+CryptDesValidateKey(
+ TPM2B_SYM_KEY *desKey // IN: key to validate
+ );
+TPM_RC
+CryptGenerateKeyDes(
+ TPMT_PUBLIC *publicArea, // IN/OUT: The public area template
+ // for the new key.
+ TPMT_SENSITIVE *sensitive, // OUT: sensitive area
+ RAND_STATE *rand // IN: the "entropy" source for
+ );
+
+
+#endif
diff --git a/src/tpm2/crypto/CryptEcc.h b/src/tpm2/crypto/CryptEcc.h
new file mode 100644
index 0000000..282e12f
--- /dev/null
+++ b/src/tpm2/crypto/CryptEcc.h
@@ -0,0 +1,103 @@
+/********************************************************************************/
+/* */
+/* Structure definitions used for ECC */
+/* Written by Ken Goldman */
+/* IBM Thomas J. Watson Research Center */
+/* $Id: CryptEcc.h 1594 2020-03-26 22:15:48Z kgoldman $ */
+/* */
+/* Licenses and Notices */
+/* */
+/* 1. Copyright Licenses: */
+/* */
+/* - Trusted Computing Group (TCG) grants to the user of the source code in */
+/* this specification (the "Source Code") a worldwide, irrevocable, */
+/* nonexclusive, royalty free, copyright license to reproduce, create */
+/* derivative works, distribute, display and perform the Source Code and */
+/* derivative works thereof, and to grant others the rights granted herein. */
+/* */
+/* - The TCG grants to the user of the other parts of the specification */
+/* (other than the Source Code) the rights to reproduce, distribute, */
+/* display, and perform the specification solely for the purpose of */
+/* developing products based on such documents. */
+/* */
+/* 2. Source Code Distribution Conditions: */
+/* */
+/* - Redistributions of Source Code must retain the above copyright licenses, */
+/* this list of conditions and the following disclaimers. */
+/* */
+/* - Redistributions in binary form must reproduce the above copyright */
+/* licenses, this list of conditions and the following disclaimers in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* 3. Disclaimers: */
+/* */
+/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
+/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
+/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
+/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
+/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
+/* information on specification licensing rights available through TCG */
+/* membership agreements. */
+/* */
+/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
+/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
+/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
+/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
+/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
+/* */
+/* - Without limitation, TCG and its members and licensors disclaim all */
+/* liability, including liability for infringement of any proprietary */
+/* rights, relating to use of information in this specification and to the */
+/* implementation of this specification, and TCG disclaims all liability for */
+/* cost of procurement of substitute goods or services, lost profits, loss */
+/* of use, loss of data or any incidental, consequential, direct, indirect, */
+/* or special damages, whether under contract, tort, warranty or otherwise, */
+/* arising in any way out of use or reliance upon this specification or any */
+/* information herein. */
+/* */
+/* (c) Copyright IBM Corp. and others, 2016 - 2020 */
+/* */
+/********************************************************************************/
+
+/* 10.1.2 CryptEcc.h */
+/* 10.1.2.1 Introduction */
+/* This file contains structure definitions used for ECC. The structures in this file are only used
+ internally. The ECC-related structures that cross the TPM interface are defined in TpmTypes.h */
+#ifndef _CRYPT_ECC_H
+#define _CRYPT_ECC_H
+
+/* 10.1.2.2 Structures */
+typedef struct ECC_CURVE
+{
+ const TPM_ECC_CURVE curveId;
+ const UINT16 keySizeBits;
+ const TPMT_KDF_SCHEME kdf;
+ const TPMT_ECC_SCHEME sign;
+ const ECC_CURVE_DATA *curveData; // the address of the curve data
+ const BYTE *OID;
+} ECC_CURVE;
+
+
+/* 10.1.2.2.1 Macros */
+/* This macro is used to instance an ECC_CURVE_DATA structure for the curve. This structure is
+ referenced by the ECC_CURVE structure */
+#define CURVE_DATA_DEF(CURVE) \
+ const ECC_CURVE_DATA CURVE = { \
+ (bigNum)&CURVE##_p_DATA, (bigNum)&CURVE##_n_DATA, (bigNum)&CURVE##_h_DATA, \
+ (bigNum)&CURVE##_a_DATA, (bigNum)&CURVE##_b_DATA, \
+ {(bigNum)&CURVE##_gX_DATA, (bigNum)&CURVE##_gY_DATA, (bigNum)&BN_ONE} };
+
+extern const ECC_CURVE eccCurves[ECC_CURVE_COUNT];
+
+#define CURVE_DEF(CURVE) \
+ { \
+ TPM_ECC_##CURVE, \
+ CURVE##_KEY_SIZE, \
+ CURVE##_KDF, \
+ CURVE##_SIGN, \
+ &##CURVE, \
+ OID_ECC_##CURVE \
+ }
+#define CURVE_NAME(N)
+
+#endif
diff --git a/src/tpm2/crypto/CryptEccCrypt_fp.h b/src/tpm2/crypto/CryptEccCrypt_fp.h
new file mode 100644
index 0000000..3bb52ce
--- /dev/null
+++ b/src/tpm2/crypto/CryptEccCrypt_fp.h
@@ -0,0 +1,67 @@
+/********************************************************************************/
+/* */
+/* Include Headers for Internal Routines */
+/* Written by Ken Goldman */
+/* IBM Thomas J. Watson Research Center */
+/* $Id: CryptEccCrypt_fp.h 1594 2020-03-26 22:15:48Z kgoldman $ */
+/* */
+/* Licenses and Notices */
+/* */
+/* 1. Copyright Licenses: */
+/* */
+/* - Trusted Computing Group (TCG) grants to the user of the source code in */
+/* this specification (the "Source Code") a worldwide, irrevocable, */
+/* nonexclusive, royalty free, copyright license to reproduce, create */
+/* derivative works, distribute, display and perform the Source Code and */
+/* derivative works thereof, and to grant others the rights granted herein. */
+/* */
+/* - The TCG grants to the user of the other parts of the specification */
+/* (other than the Source Code) the rights to reproduce, distribute, */
+/* display, and perform the specification solely for the purpose of */
+/* developing products based on such documents. */
+/* */
+/* 2. Source Code Distribution Conditions: */
+/* */
+/* - Redistributions of Source Code must retain the above copyright licenses, */
+/* this list of conditions and the following disclaimers. */
+/* */
+/* - Redistributions in binary form must reproduce the above copyright */
+/* licenses, this list of conditions and the following disclaimers in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* 3. Disclaimers: */
+/* */
+/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
+/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
+/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
+/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
+/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
+/* information on specification licensing rights available through TCG */
+/* membership agreements. */
+/* */
+/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
+/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
+/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
+/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
+/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
+/* */
+/* - Without limitation, TCG and its members and licensors disclaim all */
+/* liability, including liability for infringement of any proprietary */
+/* rights, relating to use of information in this specification and to the */
+/* implementation of this specification, and TCG disclaims all liability for */
+/* cost of procurement of substitute goods or services, lost profits, loss */
+/* of use, loss of data or any incidental, consequential, direct, indirect, */
+/* or special damages, whether under contract, tort, warranty or otherwise, */
+/* arising in any way out of use or reliance upon this specification or any */
+/* information herein. */
+/* */
+/* (c) Copyright IBM Corp. and others, 2020 */
+/* */
+/********************************************************************************/
+
+#ifndef CRYPTECCCRYPT_FP_H
+#define CRYPTECCCRYPT_FP_H
+
+
+
+#endif
diff --git a/src/tpm2/crypto/CryptEccKeyExchange_fp.h b/src/tpm2/crypto/CryptEccKeyExchange_fp.h
new file mode 100644
index 0000000..e4f0b5a
--- /dev/null
+++ b/src/tpm2/crypto/CryptEccKeyExchange_fp.h
@@ -0,0 +1,78 @@
+/********************************************************************************/
+/* */
+/* */
+/* Written by Ken Goldman */
+/* IBM Thomas J. Watson Research Center */
+/* $Id: CryptEccKeyExchange_fp.h 809 2016-11-16 18:31:54Z kgoldman $ */
+/* */
+/* Licenses and Notices */
+/* */
+/* 1. Copyright Licenses: */
+/* */
+/* - Trusted Computing Group (TCG) grants to the user of the source code in */
+/* this specification (the "Source Code") a worldwide, irrevocable, */
+/* nonexclusive, royalty free, copyright license to reproduce, create */
+/* derivative works, distribute, display and perform the Source Code and */
+/* derivative works thereof, and to grant others the rights granted herein. */
+/* */
+/* - The TCG grants to the user of the other parts of the specification */
+/* (other than the Source Code) the rights to reproduce, distribute, */
+/* display, and perform the specification solely for the purpose of */
+/* developing products based on such documents. */
+/* */
+/* 2. Source Code Distribution Conditions: */
+/* */
+/* - Redistributions of Source Code must retain the above copyright licenses, */
+/* this list of conditions and the following disclaimers. */
+/* */
+/* - Redistributions in binary form must reproduce the above copyright */
+/* licenses, this list of conditions and the following disclaimers in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* 3. Disclaimers: */
+/* */
+/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
+/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
+/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
+/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
+/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
+/* information on specification licensing rights available through TCG */
+/* membership agreements. */
+/* */
+/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
+/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
+/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
+/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
+/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
+/* */
+/* - Without limitation, TCG and its members and licensors disclaim all */
+/* liability, including liability for infringement of any proprietary */
+/* rights, relating to use of information in this specification and to the */
+/* implementation of this specification, and TCG disclaims all liability for */
+/* cost of procurement of substitute goods or services, lost profits, loss */
+/* of use, loss of data or any incidental, consequential, direct, indirect, */
+/* or special damages, whether under contract, tort, warranty or otherwise, */
+/* arising in any way out of use or reliance upon this specification or any */
+/* information herein. */
+/* */
+/* (c) Copyright IBM Corp. and others, 2016 */
+/* */
+/********************************************************************************/
+
+#ifndef CRYPTECCKEYEXCHANGE_FP_H
+#define CRYPTECCKEYEXCHANGE_FP_H
+
+LIB_EXPORT TPM_RC
+CryptEcc2PhaseKeyExchange(
+ TPMS_ECC_POINT *outZ1, // OUT: a computed point
+ TPMS_ECC_POINT *outZ2, // OUT: and optional second point
+ TPM_ECC_CURVE curveId, // IN: the curve for the computations
+ TPM_ALG_ID scheme, // IN: the key exchange scheme
+ TPM2B_ECC_PARAMETER *dsA, // IN: static private TPM key
+ TPM2B_ECC_PARAMETER *deA, // IN: ephemeral private TPM key
+ TPMS_ECC_POINT *QsB, // IN: static public party B key
+ TPMS_ECC_POINT *QeB // IN: ephemeral public party B key
+ );
+
+
+#endif
diff --git a/src/tpm2/crypto/CryptEccMain_fp.h b/src/tpm2/crypto/CryptEccMain_fp.h
new file mode 100644
index 0000000..2c04fc1
--- /dev/null
+++ b/src/tpm2/crypto/CryptEccMain_fp.h
@@ -0,0 +1,232 @@
+/********************************************************************************/
+/* */
+/* ECC Main */
+/* Written by Ken Goldman */
+/* IBM Thomas J. Watson Research Center */
+/* $Id: CryptEccMain_fp.h 1476 2019-06-10 19:32:03Z kgoldman $ */
+/* */
+/* Licenses and Notices */
+/* */
+/* 1. Copyright Licenses: */
+/* */
+/* - Trusted Computing Group (TCG) grants to the user of the source code in */
+/* this specification (the "Source Code") a worldwide, irrevocable, */
+/* nonexclusive, royalty free, copyright license to reproduce, create */
+/* derivative works, distribute, display and perform the Source Code and */
+/* derivative works thereof, and to grant others the rights granted herein. */
+/* */
+/* - The TCG grants to the user of the other parts of the specification */
+/* (other than the Source Code) the rights to reproduce, distribute, */
+/* display, and perform the specification solely for the purpose of */
+/* developing products based on such documents. */
+/* */
+/* 2. Source Code Distribution Conditions: */
+/* */
+/* - Redistributions of Source Code must retain the above copyright licenses, */
+/* this list of conditions and the following disclaimers. */
+/* */
+/* - Redistributions in binary form must reproduce the above copyright */
+/* licenses, this list of conditions and the following disclaimers in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* 3. Disclaimers: */
+/* */
+/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
+/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
+/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
+/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
+/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
+/* information on specification licensing rights available through TCG */
+/* membership agreements. */
+/* */
+/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
+/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
+/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
+/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
+/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
+/* */
+/* - Without limitation, TCG and its members and licensors disclaim all */
+/* liability, including liability for infringement of any proprietary */
+/* rights, relating to use of information in this specification and to the */
+/* implementation of this specification, and TCG disclaims all liability for */
+/* cost of procurement of substitute goods or services, lost profits, loss */
+/* of use, loss of data or any incidental, consequential, direct, indirect, */
+/* or special damages, whether under contract, tort, warranty or otherwise, */
+/* arising in any way out of use or reliance upon this specification or any */
+/* information herein. */
+/* */
+/* (c) Copyright IBM Corp. and others, 2016 - 2019 */
+/* */
+/********************************************************************************/
+
+#ifndef CRYPTECCMAIN_FP_H
+#define CRYPTECCMAIN_FP_H
+
+void
+EccSimulationEnd(
+ void
+ );
+BOOL
+CryptEccInit(
+ void
+ );
+BOOL
+CryptEccStartup(
+ void
+ );
+void
+ClearPoint2B(
+ TPMS_ECC_POINT *p // IN: the point
+ );
+LIB_EXPORT const ECC_CURVE *
+CryptEccGetParametersByCurveId(
+ TPM_ECC_CURVE curveId // IN: the curveID
+ );
+LIB_EXPORT UINT16
+CryptEccGetKeySizeForCurve(
+ TPM_ECC_CURVE curveId // IN: the curve
+ );
+const ECC_CURVE_DATA *
+GetCurveData(
+ TPM_ECC_CURVE curveId // IN: the curveID
+ );
+const BYTE *
+CryptEccGetOID(
+ TPM_ECC_CURVE curveId
+ );
+LIB_EXPORT TPM_ECC_CURVE
+CryptEccGetCurveByIndex(
+ UINT16 i
+ );
+LIB_EXPORT BOOL
+CryptEccGetParameter(
+ TPM2B_ECC_PARAMETER *out, // OUT: place to put parameter
+ char p, // IN: the parameter selector
+ TPM_ECC_CURVE curveId // IN: the curve id
+ );
+TPMI_YES_NO
+CryptCapGetECCCurve(
+ TPM_ECC_CURVE curveID, // IN: the starting ECC curve
+ UINT32 maxCount, // IN: count of returned curves
+ TPML_ECC_CURVE *curveList // OUT: ECC curve list
+ );
+const TPMT_ECC_SCHEME *
+CryptGetCurveSignScheme(
+ TPM_ECC_CURVE curveId // IN: The curve selector
+ );
+BOOL
+CryptGenerateR(
+ TPM2B_ECC_PARAMETER *r, // OUT: the generated random value
+ UINT16 *c, // IN/OUT: count value.
+ TPMI_ECC_CURVE curveID, // IN: the curve for the value
+ TPM2B_NAME *name // IN: optional name of a key to
+ // associate with 'r'
+ );
+UINT16
+CryptCommit(
+ void
+ );
+void
+CryptEndCommit(
+ UINT16 c // IN: the counter value of the commitment
+ );
+BOOL
+CryptEccGetParameters(
+ TPM_ECC_CURVE curveId, // IN: ECC curve ID
+ TPMS_ALGORITHM_DETAIL_ECC *parameters // OUT: ECC parameters
+ );
+const bignum_t *
+BnGetCurvePrime(
+ TPM_ECC_CURVE curveId
+ );
+const bignum_t *
+BnGetCurveOrder(
+ TPM_ECC_CURVE curveId
+ );
+BOOL
+BnIsOnCurve(
+ pointConst Q,
+ const ECC_CURVE_DATA *C
+ );
+BOOL
+BnIsValidPrivateEcc(
+ bigConst x, // IN: private key to check
+ bigCurve E // IN: the curve to check
+ );
+LIB_EXPORT BOOL
+CryptEccIsValidPrivateKey(
+ TPM2B_ECC_PARAMETER *d,
+ TPM_ECC_CURVE curveId
+ );
+TPM_RC
+BnPointMult(
+ bigPoint R, // OUT: computed point
+ pointConst S, // IN: optional point to multiply by 'd'
+ bigConst d, // IN: scalar for [d]S or [d]G
+ pointConst Q, // IN: optional second point
+ bigConst u, // IN: optional second scalar
+ bigCurve E // IN: curve parameters
+ );
+BOOL
+BnEccGetPrivate(
+ bigNum dOut, // OUT: the qualified random value
+ const ECC_CURVE_DATA *C, // IN: curve for which the private key
+#if USE_OPENSSL_FUNCTIONS_EC
+ const EC_GROUP *G, // IN: the EC_GROUP to use; must be != NULL for rand == NULL
+ BOOL noLeadingZeros, // IN: require that all bytes in the private key be set
+ // result may not have leading zero bytes
+#endif
+ // needs to be appropriate
+ RAND_STATE *rand // IN: state for DRBG
+ );
+BOOL
+BnEccGenerateKeyPair(
+ bigNum bnD, // OUT: private scalar
+ bn_point_t *ecQ, // OUT: public point
+ bigCurve E, // IN: curve for the point
+ RAND_STATE *rand // IN: DRBG state to use
+ );
+LIB_EXPORT TPM_RC
+CryptEccNewKeyPair(
+ TPMS_ECC_POINT *Qout, // OUT: the public point
+ TPM2B_ECC_PARAMETER *dOut, // OUT: the private scalar
+ TPM_ECC_CURVE curveId // IN: the curve for the key
+ );
+LIB_EXPORT TPM_RC
+CryptEccPointMultiply(
+ TPMS_ECC_POINT *Rout, // OUT: the product point R
+ TPM_ECC_CURVE curveId, // IN: the curve to use
+ TPMS_ECC_POINT *Pin, // IN: first point (can be null)
+ TPM2B_ECC_PARAMETER *dIn, // IN: scalar value for [dIn]Qin
+ // the Pin
+ TPMS_ECC_POINT *Qin, // IN: point Q
+ TPM2B_ECC_PARAMETER *uIn // IN: scalar value for the multiplier
+ // of Q
+ );
+LIB_EXPORT BOOL
+CryptEccIsPointOnCurve(
+ TPM_ECC_CURVE curveId, // IN: the curve selector
+ TPMS_ECC_POINT *Qin // IN: the point.
+ );
+LIB_EXPORT TPM_RC
+CryptEccGenerateKey(
+ TPMT_PUBLIC *publicArea, // IN/OUT: The public area template for
+ // the new key. The public key
+ // area will be replaced computed
+ // ECC public key
+ TPMT_SENSITIVE *sensitive, // OUT: the sensitive area will be
+ // updated to contain the private
+ // ECC key and the symmetric
+ // encryption key
+ RAND_STATE *rand // IN: if not NULL, the deterministic
+ // RNG state
+ );
+
+// libtpms added begin
+LIB_EXPORT BOOL
+CryptEccIsCurveRuntimeUsable(
+ TPMI_ECC_CURVE curveId
+ );
+// libtpms added end
+
+#endif
diff --git a/src/tpm2/crypto/CryptEccSignature_fp.h b/src/tpm2/crypto/CryptEccSignature_fp.h
new file mode 100644
index 0000000..5ee813e
--- /dev/null
+++ b/src/tpm2/crypto/CryptEccSignature_fp.h
@@ -0,0 +1,111 @@
+/********************************************************************************/
+/* */
+/* */
+/* Written by Ken Goldman */
+/* IBM Thomas J. Watson Research Center */
+/* $Id: CryptEccSignature_fp.h 809 2016-11-16 18:31:54Z kgoldman $ */
+/* */
+/* Licenses and Notices */
+/* */
+/* 1. Copyright Licenses: */
+/* */
+/* - Trusted Computing Group (TCG) grants to the user of the source code in */
+/* this specification (the "Source Code") a worldwide, irrevocable, */
+/* nonexclusive, royalty free, copyright license to reproduce, create */
+/* derivative works, distribute, display and perform the Source Code and */
+/* derivative works thereof, and to grant others the rights granted herein. */
+/* */
+/* - The TCG grants to the user of the other parts of the specification */
+/* (other than the Source Code) the rights to reproduce, distribute, */
+/* display, and perform the specification solely for the purpose of */
+/* developing products based on such documents. */
+/* */
+/* 2. Source Code Distribution Conditions: */
+/* */
+/* - Redistributions of Source Code must retain the above copyright licenses, */
+/* this list of conditions and the following disclaimers. */
+/* */
+/* - Redistributions in binary form must reproduce the above copyright */
+/* licenses, this list of conditions and the following disclaimers in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* 3. Disclaimers: */
+/* */
+/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
+/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
+/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
+/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
+/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
+/* information on specification licensing rights available through TCG */
+/* membership agreements. */
+/* */
+/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
+/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
+/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
+/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
+/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
+/* */
+/* - Without limitation, TCG and its members and licensors disclaim all */
+/* liability, including liability for infringement of any proprietary */
+/* rights, relating to use of information in this specification and to the */
+/* implementation of this specification, and TCG disclaims all liability for */
+/* cost of procurement of substitute goods or services, lost profits, loss */
+/* of use, loss of data or any incidental, consequential, direct, indirect, */
+/* or special damages, whether under contract, tort, warranty or otherwise, */
+/* arising in any way out of use or reliance upon this specification or any */
+/* information herein. */
+/* */
+/* (c) Copyright IBM Corp. and others, 2016 */
+/* */
+/********************************************************************************/
+
+#ifndef CRYPTECCSIGNATURE_FP_H
+#define CRYPTECCSIGNATURE_FP_H
+
+TPM_RC
+BnSignEcdsa(
+ bigNum bnR, // OUT: r component of the signature
+ bigNum bnS, // OUT: s component of the signature
+ bigCurve E, // IN: the curve used in the signature
+ // process
+ bigNum bnD, // IN: private signing key
+ const TPM2B_DIGEST *digest, // IN: the digest to sign
+ RAND_STATE *rand // IN: used in debug of signing
+ );
+LIB_EXPORT TPM_RC
+CryptEccSign(
+ TPMT_SIGNATURE *signature, // OUT: signature
+ OBJECT *signKey, // IN: ECC key to sign the hash
+ const TPM2B_DIGEST *digest, // IN: digest to sign
+ TPMT_ECC_SCHEME *scheme, // IN: signing scheme
+ RAND_STATE *rand
+ );
+TPM_RC
+BnValidateSignatureEcdsa(
+ bigNum bnR, // IN: r component of the signature
+ bigNum bnS, // IN: s component of the signature
+ bigCurve E, // IN: the curve used in the signature
+ // process
+ bn_point_t *ecQ, // IN: the public point of the key
+ const TPM2B_DIGEST *digest // IN: the digest that was signed
+ );
+LIB_EXPORT TPM_RC
+CryptEccValidateSignature(
+ TPMT_SIGNATURE *signature, // IN: signature to be verified
+ OBJECT *signKey, // IN: ECC key signed the hash
+ const TPM2B_DIGEST *digest // IN: digest that was signed
+ );
+LIB_EXPORT TPM_RC
+CryptEccCommitCompute(
+ TPMS_ECC_POINT *K, // OUT: [d]B or [r]Q
+ TPMS_ECC_POINT *L, // OUT: [r]B
+ TPMS_ECC_POINT *E, // OUT: [r]M
+ TPM_ECC_CURVE curveId, // IN: the curve for the computations
+ TPMS_ECC_POINT *M, // IN: M (optional)
+ TPMS_ECC_POINT *B, // IN: B (optional)
+ TPM2B_ECC_PARAMETER *d, // IN: d (optional)
+ TPM2B_ECC_PARAMETER *r // IN: the computed r value (required)
+ );
+
+
+#endif
diff --git a/src/tpm2/crypto/CryptHash.h b/src/tpm2/crypto/CryptHash.h
new file mode 100644
index 0000000..20f52e8
--- /dev/null
+++ b/src/tpm2/crypto/CryptHash.h
@@ -0,0 +1,343 @@
+/********************************************************************************/
+/* */
+/* Hash structure definitions */
+/* Written by Ken Goldman */
+/* IBM Thomas J. Watson Research Center */
+/* $Id: CryptHash.h 1658 2021-01-22 23:14:01Z kgoldman $ */
+/* */
+/* Licenses and Notices */
+/* */
+/* 1. Copyright Licenses: */
+/* */
+/* - Trusted Computing Group (TCG) grants to the user of the source code in */
+/* this specification (the "Source Code") a worldwide, irrevocable, */
+/* nonexclusive, royalty free, copyright license to reproduce, create */
+/* derivative works, distribute, display and perform the Source Code and */
+/* derivative works thereof, and to grant others the rights granted herein. */
+/* */
+/* - The TCG grants to the user of the other parts of the specification */
+/* (other than the Source Code) the rights to reproduce, distribute, */
+/* display, and perform the specification solely for the purpose of */
+/* developing products based on such documents. */
+/* */
+/* 2. Source Code Distribution Conditions: */
+/* */
+/* - Redistributions of Source Code must retain the above copyright licenses, */
+/* this list of conditions and the following disclaimers. */
+/* */
+/* - Redistributions in binary form must reproduce the above copyright */
+/* licenses, this list of conditions and the following disclaimers in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* 3. Disclaimers: */
+/* */
+/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
+/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
+/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
+/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
+/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
+/* information on specification licensing rights available through TCG */
+/* membership agreements. */
+/* */
+/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
+/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
+/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
+/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
+/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
+/* */
+/* - Without limitation, TCG and its members and licensors disclaim all */
+/* liability, including liability for infringement of any proprietary */
+/* rights, relating to use of information in this specification and to the */
+/* implementation of this specification, and TCG disclaims all liability for */
+/* cost of procurement of substitute goods or services, lost profits, loss */
+/* of use, loss of data or any incidental, consequential, direct, indirect, */
+/* or special damages, whether under contract, tort, warranty or otherwise, */
+/* arising in any way out of use or reliance upon this specification or any */
+/* information herein. */
+/* */
+/* (c) Copyright IBM Corp. and others, 2016 - 2021 */
+/* */
+/********************************************************************************/
+
+#ifndef CRYPTHASH_H
+#define CRYPTHASH_H
+
+/* 10.1.3.1 Introduction */
+
+/* This header contains the hash structure definitions used in the TPM code to define the amount of
+ space to be reserved for the hash state. This allows the TPM code to not have to import all of
+ the symbols used by the hash computations. This lets the build environment of the TPM code not to
+ have include the header files associated with the CryptoEngine() code. */
+
+/* 10.1.3.2 Hash-related Structures */
+
+union SMAC_STATES;
+
+/* These definitions add the high-level methods for processing state that may be an SMAC */
+typedef void(* SMAC_DATA_METHOD)(
+ union SMAC_STATES *state,
+ UINT32 size,
+ const BYTE *buffer
+ );
+typedef UINT16(* SMAC_END_METHOD)(
+ union SMAC_STATES *state,
+ UINT32 size,
+ BYTE *buffer
+ );
+typedef struct sequenceMethods {
+ SMAC_DATA_METHOD data;
+ SMAC_END_METHOD end;
+} SMAC_METHODS;
+#define SMAC_IMPLEMENTED (CC_MAC || CC_MAC_Start)
+
+/* These definitions are here because the SMAC state is in the union of hash states. */
+
+typedef struct tpmCmacState {
+ TPM_ALG_ID symAlg;
+ UINT16 keySizeBits;
+ INT16 bcount; // current count of bytes accumulated in IV
+ TPM2B_IV iv; // IV buffer
+ TPM2B_SYM_KEY symKey;
+} tpmCmacState_t;
+
+typedef union SMAC_STATES {
+#if ALG_CMAC
+ tpmCmacState_t cmac;
+#endif
+ UINT64 pad;
+} SMAC_STATES;
+
+typedef struct SMAC_STATE {
+ SMAC_METHODS smacMethods;
+ SMAC_STATES state;
+} SMAC_STATE;
+
+#if ALG_SHA1
+# define IF_IMPLEMENTED_SHA1(op) op(SHA1, Sha1)
+#else
+# define IF_IMPLEMENTED_SHA1(op)
+#endif
+#if ALG_SHA256
+# define IF_IMPLEMENTED_SHA256(op) op(SHA256, Sha256)
+#else
+# define IF_IMPLEMENTED_SHA256(op)
+#endif
+#if ALG_SHA384
+# define IF_IMPLEMENTED_SHA384(op) op(SHA384, Sha384)
+#else
+# define IF_IMPLEMENTED_SHA384(op)
+#endif
+#if ALG_SHA512
+# define IF_IMPLEMENTED_SHA512(op) op(SHA512, Sha512)
+#else
+# define IF_IMPLEMENTED_SHA512(op)
+#endif
+#if ALG_SM3_256
+# define IF_IMPLEMENTED_SM3_256(op) op(SM3_256, Sm3_256)
+#else
+# define IF_IMPLEMENTED_SM3_256(op)
+#endif
+#if ALG_SHA3_256
+# define IF_IMPLEMENTED_SHA3_256(op) op(SHA3_256, Sha3_256)
+#else
+# define IF_IMPLEMENTED_SHA3_256(op)
+#endif
+#if ALG_SHA3_384
+# define IF_IMPLEMENTED_SHA3_384(op) op(SHA3_384, Sha3_384)
+#else
+# define IF_IMPLEMENTED_SHA3_384(op)
+#endif
+#if ALG_SHA3_512
+# define IF_IMPLEMENTED_SHA3_512(op) op(SHA3_512, Sha3_512)
+#else
+# define IF_IMPLEMENTED_SHA3_512(op)
+#endif
+
+/* SHA512 added kgold */
+#define FOR_EACH_HASH(op) \
+ IF_IMPLEMENTED_SHA1(op) \
+ IF_IMPLEMENTED_SHA256(op) \
+ IF_IMPLEMENTED_SHA384(op) \
+ IF_IMPLEMENTED_SHA512(op) \
+ IF_IMPLEMENTED_SM3_256(op) \
+ IF_IMPLEMENTED_SHA3_256(op) \
+ IF_IMPLEMENTED_SHA3_384(op) \
+ IF_IMPLEMENTED_SHA3_512(op)
+
+#define HASH_TYPE(HASH, Hash) tpmHashState##HASH##_t Hash;
+
+typedef union
+{
+ FOR_EACH_HASH(HASH_TYPE)
+ // Additions for symmetric block cipher MAC
+#if SMAC_IMPLEMENTED
+ SMAC_STATE smac;
+#endif
+ // to force structure alignment to be no worse than HASH_ALIGNMENT
+#if HASH_ALIGNMENT == 8
+ uint64_t align;
+#else
+ uint32_t align;
+#endif
+} ANY_HASH_STATE;
+
+typedef ANY_HASH_STATE *PANY_HASH_STATE;
+typedef const ANY_HASH_STATE *PCANY_HASH_STATE;
+#define ALIGNED_SIZE(x, b) ((((x) + (b) - 1) / (b)) * (b))
+/* MAX_HASH_STATE_SIZE will change with each implementation. It is assumed that a hash state will
+ not be larger than twice the block size plus some overhead (in this case, 16 bytes). The overall
+ size needs to be as large as any of the hash contexts. The structure needs to start on an
+ alignment boundary and be an even multiple of the alignment */
+#define MAX_HASH_STATE_SIZE ((2 * MAX_HASH_BLOCK_SIZE) + 16)
+#define MAX_HASH_STATE_SIZE_ALIGNED \
+ ALIGNED_SIZE(MAX_HASH_STATE_SIZE, HASH_ALIGNMENT)
+/* This is an aligned byte array that will hold any of the hash contexts. */
+typedef ANY_HASH_STATE ALIGNED_HASH_STATE;
+/* The header associated with the hash library is expected to define the methods which include the
+ calling sequence. When not compiling CryptHash.c, the methods are not defined so we need
+ placeholder functions for the structures */
+#ifndef HASH_START_METHOD_DEF
+# define HASH_START_METHOD_DEF void (HASH_START_METHOD)(void)
+#endif
+#ifndef HASH_DATA_METHOD_DEF
+# define HASH_DATA_METHOD_DEF void (HASH_DATA_METHOD)(void)
+#endif
+#ifndef HASH_END_METHOD_DEF
+# define HASH_END_METHOD_DEF void (HASH_END_METHOD)(void)
+#endif
+#ifndef HASH_STATE_COPY_METHOD_DEF
+# define HASH_STATE_COPY_METHOD_DEF void (HASH_STATE_COPY_METHOD)(void)
+#endif
+#ifndef HASH_STATE_EXPORT_METHOD_DEF
+# define HASH_STATE_EXPORT_METHOD_DEF void (HASH_STATE_EXPORT_METHOD)(void)
+#endif
+#ifndef HASH_STATE_IMPORT_METHOD_DEF
+# define HASH_STATE_IMPORT_METHOD_DEF void (HASH_STATE_IMPORT_METHOD)(void)
+#endif
+/* Define the prototypical function call for each of the methods. This defines the order in which
+ the parameters are passed to the underlying function. */
+typedef HASH_START_METHOD_DEF;
+typedef HASH_DATA_METHOD_DEF;
+typedef HASH_END_METHOD_DEF;
+typedef HASH_STATE_COPY_METHOD_DEF;
+typedef HASH_STATE_EXPORT_METHOD_DEF;
+typedef HASH_STATE_IMPORT_METHOD_DEF;
+typedef struct _HASH_METHODS
+{
+ HASH_START_METHOD *start;
+ HASH_DATA_METHOD *data;
+ HASH_END_METHOD *end;
+ HASH_STATE_COPY_METHOD *copy; // Copy a hash block
+ HASH_STATE_EXPORT_METHOD *copyOut; // Copy a hash block from a hash
+ // context
+ HASH_STATE_IMPORT_METHOD *copyIn; // Copy a hash block to a proper hash
+ // context
+} HASH_METHODS, *PHASH_METHODS;
+
+#define HASH_TPM2B(HASH, Hash) TPM2B_TYPE(HASH##_DIGEST, HASH##_DIGEST_SIZE);
+
+FOR_EACH_HASH(HASH_TPM2B)
+
+/* When the TPM implements RSA, the hash-dependent OID pointers are part of the HASH_DEF. These
+ macros conditionally add the OID reference to the HASH_DEF and the HASH_DEF_TEMPLATE. */
+#if ALG_RSA
+#define PKCS1_HASH_REF const BYTE *PKCS1;
+#define PKCS1_OID(NAME) , OID_PKCS1_##NAME
+#else
+#define PKCS1_HASH_REF
+#define PKCS1_OID(NAME)
+#endif
+
+/* When the TPM implements ECC, the hash-dependent OID pointers are part of the HASH_DEF. These
+ macros conditionally add the OID reference to the HASH_DEF and the HASH_DEF_TEMPLATE. */
+#if ALG_ECDSA
+#define ECDSA_HASH_REF const BYTE *ECDSA;
+#define ECDSA_OID(NAME) , OID_ECDSA_##NAME
+#else
+#define ECDSA_HASH_REF
+#define ECDSA_OID(NAME)
+#endif
+
+typedef const struct
+{
+ HASH_METHODS method;
+ uint16_t blockSize;
+ uint16_t digestSize;
+ uint16_t contextSize;
+ uint16_t hashAlg;
+ const BYTE *OID;
+ PKCS1_HASH_REF // PKCS1 OID
+ ECDSA_HASH_REF // ECDSA OID
+} HASH_DEF, *PHASH_DEF;
+
+/* Macro to fill in the HASH_DEF for an algorithm. For SHA1, the instance would be:
+ HASH_DEF_TEMPLATE(Sha1, SHA1) This handles the difference in capitalization for the various
+ pieces. */
+
+#define HASH_DEF_TEMPLATE(HASH, Hash) \
+ HASH_DEF Hash##_Def= { \
+ {(HASH_START_METHOD *)&tpmHashStart_##HASH, \
+ (HASH_DATA_METHOD *)&tpmHashData_##HASH, \
+ (HASH_END_METHOD *)&tpmHashEnd_##HASH, \
+ (HASH_STATE_COPY_METHOD *)&tpmHashStateCopy_##HASH, \
+ (HASH_STATE_EXPORT_METHOD *)&tpmHashStateExport_##HASH, \
+ (HASH_STATE_IMPORT_METHOD *)&tpmHashStateImport_##HASH, \
+ }, \
+ HASH##_BLOCK_SIZE, /*block size */ \
+ HASH##_DIGEST_SIZE, /*data size */ \
+ sizeof(tpmHashState##HASH##_t), \
+ TPM_ALG_##HASH, OID_##HASH \
+ PKCS1_OID(HASH) ECDSA_OID(HASH)};
+
+/* These definitions are for the types that can be in a hash state structure. These types are used
+ in the cryptographic utilities. This is a define rather than an enum so that the size of this
+ field can be explicit. */
+typedef BYTE HASH_STATE_TYPE;
+#define HASH_STATE_EMPTY ((HASH_STATE_TYPE) 0)
+#define HASH_STATE_HASH ((HASH_STATE_TYPE) 1)
+#define HASH_STATE_HMAC ((HASH_STATE_TYPE) 2)
+#if CC_MAC || CC_MAC_Start
+#define HASH_STATE_SMAC ((HASH_STATE_TYPE) 3)
+#endif
+/* This is the structure that is used for passing a context into the hashing functions. It should be
+ the same size as the function context used within the hashing functions. This is checked when the
+ hash function is initialized. This version uses a new layout for the contexts and a different
+ definition. The state buffer is an array of HASH_UNIT values so that a decent compiler will put
+ the structure on a HASH_UNIT boundary. If the structure is not properly aligned, the code that
+ manipulates the structure will copy to a properly aligned structure before it is used and copy
+ the result back. This just makes things slower. */
+/* NOTE: This version of the state had the pointer to the update method in the state. This is to
+ allow the SMAC functions to use the same structure without having to replicate the entire
+ HASH_DEF structure. */
+typedef struct _HASH_STATE
+{
+ HASH_STATE_TYPE type; // type of the context
+ TPM_ALG_ID hashAlg;
+ PHASH_DEF def;
+ ANY_HASH_STATE state;
+} HASH_STATE, *PHASH_STATE;
+typedef const HASH_STATE *PCHASH_STATE;
+
+/* 10.1.3.3 HMAC State Structures */
+/* This header contains the hash structure definitions used in the TPM code to define the amount of
+ space to be reserved for the hash state. This allows the TPM code to not have to import all of
+ the symbols used by the hash computations. This lets the build environment of the TPM code not to
+ have include the header files associated with the CryptoEngine() code. */
+
+/* An HMAC_STATE structure contains an opaque HMAC stack state. A caller would use this structure
+ when performing incremental HMAC operations. This structure contains a hash state and an HMAC key
+ and allows slightly better stack optimization than adding an HMAC key to each hash state. */
+typedef struct hmacState
+{
+ HASH_STATE hashState; // the hash state
+ TPM2B_HASH_BLOCK hmacKey; // the HMAC key
+} HMAC_STATE, *PHMAC_STATE;
+/* This is for the external hash state. This implementation assumes that the size of the exported
+ hash state is no larger than the internal hash state. */
+typedef struct
+{
+ BYTE buffer[sizeof(HASH_STATE)];
+} EXPORT_HASH_STATE, *PEXPORT_HASH_STATE;
+typedef const EXPORT_HASH_STATE *PCEXPORT_HASH_STATE;
+
+#endif // _CRYPT_HASH_H
diff --git a/src/tpm2/crypto/CryptHash_fp.h b/src/tpm2/crypto/CryptHash_fp.h
new file mode 100644
index 0000000..adf1ba9
--- /dev/null
+++ b/src/tpm2/crypto/CryptHash_fp.h
@@ -0,0 +1,219 @@
+/********************************************************************************/
+/* */
+/* Implementation of cryptographic functions for hashing. */
+/* Written by Ken Goldman */
+/* IBM Thomas J. Watson Research Center */
+/* $Id: CryptHash_fp.h 1594 2020-03-26 22:15:48Z kgoldman $ */
+/* */
+/* Licenses and Notices */
+/* */
+/* 1. Copyright Licenses: */
+/* */
+/* - Trusted Computing Group (TCG) grants to the user of the source code in */
+/* this specification (the "Source Code") a worldwide, irrevocable, */
+/* nonexclusive, royalty free, copyright license to reproduce, create */
+/* derivative works, distribute, display and perform the Source Code and */
+/* derivative works thereof, and to grant others the rights granted herein. */
+/* */
+/* - The TCG grants to the user of the other parts of the specification */
+/* (other than the Source Code) the rights to reproduce, distribute, */
+/* display, and perform the specification solely for the purpose of */
+/* developing products based on such documents. */
+/* */
+/* 2. Source Code Distribution Conditions: */
+/* */
+/* - Redistributions of Source Code must retain the above copyright licenses, */
+/* this list of conditions and the following disclaimers. */
+/* */
+/* - Redistributions in binary form must reproduce the above copyright */
+/* licenses, this list of conditions and the following disclaimers in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* 3. Disclaimers: */
+/* */
+/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
+/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
+/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
+/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
+/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
+/* information on specification licensing rights available through TCG */
+/* membership agreements. */
+/* */
+/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
+/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
+/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
+/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
+/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
+/* */
+/* - Without limitation, TCG and its members and licensors disclaim all */
+/* liability, including liability for infringement of any proprietary */
+/* rights, relating to use of information in this specification and to the */
+/* implementation of this specification, and TCG disclaims all liability for */
+/* cost of procurement of substitute goods or services, lost profits, loss */
+/* of use, loss of data or any incidental, consequential, direct, indirect, */
+/* or special damages, whether under contract, tort, warranty or otherwise, */
+/* arising in any way out of use or reliance upon this specification or any */
+/* information herein. */
+/* */
+/* (c) Copyright IBM Corp. and others, 2016 - 2020 */
+/* */
+/********************************************************************************/
+
+#ifndef CRYPTHASH_FP_H
+#define CRYPTHASH_FP_H
+
+BOOL
+CryptHashInit(
+ void
+ );
+BOOL
+CryptHashStartup(
+ void
+ );
+PHASH_DEF
+CryptGetHashDef(
+ TPM_ALG_ID hashAlg
+ );
+BOOL
+CryptHashIsValidAlg(
+ TPM_ALG_ID hashAlg,
+ BOOL flag
+ );
+LIB_EXPORT TPM_ALG_ID
+CryptHashGetAlgByIndex(
+ UINT32 index // IN: the index
+ );
+LIB_EXPORT UINT16
+CryptHashGetDigestSize(
+ TPM_ALG_ID hashAlg // IN: hash algorithm to look up
+ );
+LIB_EXPORT UINT16
+CryptHashGetBlockSize(
+ TPM_ALG_ID hashAlg // IN: hash algorithm to look up
+ );
+LIB_EXPORT const BYTE *
+CryptHashGetOid(
+ TPM_ALG_ID hashAlg
+ );
+TPM_ALG_ID
+CryptHashGetContextAlg(
+ PHASH_STATE state // IN: the context to check
+ );
+LIB_EXPORT void
+CryptHashCopyState(
+ HASH_STATE *out, // OUT: destination of the state
+ const HASH_STATE *in // IN: source of the state
+ );
+void
+CryptHashExportState(
+ PCHASH_STATE internalFmt, // IN: the hash state formatted for use by
+ // library
+ PEXPORT_HASH_STATE externalFmt // OUT: the exported hash state
+ );
+void
+CryptHashImportState(
+ PHASH_STATE internalFmt, // OUT: the hash state formatted for use by
+ // the library
+ PCEXPORT_HASH_STATE externalFmt // IN: the exported hash state
+ );
+LIB_EXPORT UINT16
+CryptHashStart(
+ PHASH_STATE hashState, // OUT: the running hash state
+ TPM_ALG_ID hashAlg // IN: hash algorithm
+ );
+LIB_EXPORT void
+CryptDigestUpdate(
+ PHASH_STATE hashState, // IN: the hash context information
+ UINT32 dataSize, // IN: the size of data to be added
+ const BYTE *data // IN: data to be hashed
+ );
+LIB_EXPORT UINT16
+CryptHashEnd(
+ PHASH_STATE hashState, // IN: the state of hash stack
+ UINT32 dOutSize, // IN: size of digest buffer
+ BYTE *dOut // OUT: hash digest
+ );
+LIB_EXPORT UINT16
+CryptHashBlock(
+ TPM_ALG_ID hashAlg, // IN: The hash algorithm
+ UINT32 dataSize, // IN: size of buffer to hash
+ const BYTE *data, // IN: the buffer to hash
+ UINT32 dOutSize, // IN: size of the digest buffer
+ BYTE *dOut // OUT: digest buffer
+ );
+LIB_EXPORT void
+CryptDigestUpdate2B(
+ PHASH_STATE state, // IN: the digest state
+ const TPM2B *bIn // IN: 2B containing the data
+ );
+LIB_EXPORT UINT16
+CryptHashEnd2B(
+ PHASH_STATE state, // IN: the hash state
+ P2B digest // IN: the size of the buffer Out: requested
+ // number of bytes
+ );
+LIB_EXPORT void
+CryptDigestUpdateInt(
+ void *state, // IN: the state of hash stack
+ UINT32 intSize, // IN: the size of 'intValue' in bytes
+ UINT64 intValue // IN: integer value to be hashed
+ );
+LIB_EXPORT UINT16
+CryptHmacStart(
+ PHMAC_STATE state, // IN/OUT: the state buffer
+ TPM_ALG_ID hashAlg, // IN: the algorithm to use
+ UINT16 keySize, // IN: the size of the HMAC key
+ const BYTE *key // IN: the HMAC key
+ );
+LIB_EXPORT UINT16
+CryptHmacEnd(
+ PHMAC_STATE state, // IN: the hash state buffer
+ UINT32 dOutSize, // IN: size of digest buffer
+ BYTE *dOut // OUT: hash digest
+ );
+LIB_EXPORT UINT16
+CryptHmacStart2B(
+ PHMAC_STATE hmacState, // OUT: the state of HMAC stack. It will be used
+ // in HMAC update and completion
+ TPMI_ALG_HASH hashAlg, // IN: hash algorithm
+ P2B key // IN: HMAC key
+ );
+LIB_EXPORT UINT16
+CryptHmacEnd2B(
+ PHMAC_STATE hmacState, // IN: the state of HMAC stack
+ P2B digest // OUT: HMAC
+ );
+LIB_EXPORT UINT16
+CryptMGF_KDF(
+ UINT32 mSize, // IN: length of the mask to be produced
+ BYTE *mask, // OUT: buffer to receive the mask
+ TPM_ALG_ID hashAlg, // IN: hash to use
+ UINT32 seedSize, // IN: size of the seed
+ BYTE *seed, // IN: seed size
+ UINT32 counter // IN: counter initial value
+ );
+LIB_EXPORT UINT16
+CryptKDFa(
+ TPM_ALG_ID hashAlg, // IN: hash algorithm used in HMAC
+ const TPM2B *key, // IN: HMAC key
+ const TPM2B *label, // IN: a label for the KDF
+ const TPM2B *contextU, // IN: context U
+ const TPM2B *contextV, // IN: context V
+ UINT32 sizeInBits, // IN: size of generated key in bits
+ BYTE *keyStream, // OUT: key buffer
+ UINT32 *counterInOut, // IN/OUT: caller may provide the iteration
+ UINT16 blocks // IN: If non-zero, this is the maximum number
+ );
+LIB_EXPORT UINT16
+CryptKDFe(
+ TPM_ALG_ID hashAlg, // IN: hash algorithm used in HMAC
+ TPM2B *Z, // IN: Z
+ const TPM2B *label, // IN: a label value for the KDF
+ TPM2B *partyUInfo, // IN: PartyUInfo
+ TPM2B *partyVInfo, // IN: PartyVInfo
+ UINT32 sizeInBits, // IN: size of generated key in bits
+ BYTE *keyStream // OUT: key buffer
+ );
+
+
+#endif
diff --git a/src/tpm2/crypto/CryptPrimeSieve_fp.h b/src/tpm2/crypto/CryptPrimeSieve_fp.h
new file mode 100644
index 0000000..66639a3
--- /dev/null
+++ b/src/tpm2/crypto/CryptPrimeSieve_fp.h
@@ -0,0 +1,101 @@
+/********************************************************************************/
+/* */
+/* */
+/* Written by Ken Goldman */
+/* IBM Thomas J. Watson Research Center */
+/* $Id: CryptPrimeSieve_fp.h 809 2016-11-16 18:31:54Z kgoldman $ */
+/* */
+/* Licenses and Notices */
+/* */
+/* 1. Copyright Licenses: */
+/* */
+/* - Trusted Computing Group (TCG) grants to the user of the source code in */
+/* this specification (the "Source Code") a worldwide, irrevocable, */
+/* nonexclusive, royalty free, copyright license to reproduce, create */
+/* derivative works, distribute, display and perform the Source Code and */
+/* derivative works thereof, and to grant others the rights granted herein. */
+/* */
+/* - The TCG grants to the user of the other parts of the specification */
+/* (other than the Source Code) the rights to reproduce, distribute, */
+/* display, and perform the specification solely for the purpose of */
+/* developing products based on such documents. */
+/* */
+/* 2. Source Code Distribution Conditions: */
+/* */
+/* - Redistributions of Source Code must retain the above copyright licenses, */
+/* this list of conditions and the following disclaimers. */
+/* */
+/* - Redistributions in binary form must reproduce the above copyright */
+/* licenses, this list of conditions and the following disclaimers in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* 3. Disclaimers: */
+/* */
+/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
+/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
+/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
+/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
+/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
+/* information on specification licensing rights available through TCG */
+/* membership agreements. */
+/* */
+/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
+/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
+/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
+/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
+/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
+/* */
+/* - Without limitation, TCG and its members and licensors disclaim all */
+/* liability, including liability for infringement of any proprietary */
+/* rights, relating to use of information in this specification and to the */
+/* implementation of this specification, and TCG disclaims all liability for */
+/* cost of procurement of substitute goods or services, lost profits, loss */
+/* of use, loss of data or any incidental, consequential, direct, indirect, */
+/* or special damages, whether under contract, tort, warranty or otherwise, */
+/* arising in any way out of use or reliance upon this specification or any */
+/* information herein. */
+/* */
+/* (c) Copyright IBM Corp. and others, 2016 */
+/* */
+/********************************************************************************/
+
+#ifndef CRYPTPRIMESIEVE_FP_H
+#define CRYPTPRIMESIEVE_FP_H
+
+LIB_EXPORT void
+RsaAdjustPrimeLimit(
+ uint32_t requestedPrimes
+ );
+LIB_EXPORT uint32_t
+RsaNextPrime(
+ uint32_t lastPrime
+ );
+LIB_EXPORT int
+FindNthSetBit(
+ const UINT16 aSize, // IN: the size of the array to check
+ const BYTE *a, // IN: the array to check
+ const UINT32 n // IN, the number of the SET bit
+ );
+LIB_EXPORT UINT32
+PrimeSieve(
+ bigNum bnN, // IN/OUT: number to sieve
+ UINT32 fieldSize, // IN: size of the field area in bytes
+ BYTE *field // IN: field
+ );
+LIB_EXPORT uint32_t
+SetFieldSize(
+ uint32_t newFieldSize
+ );
+LIB_EXPORT TPM_RC
+PrimeSelectWithSieve(
+ bigNum candidate, // IN/OUT: The candidate to filter
+ UINT32 e, // IN: the exponent
+ RAND_STATE *rand // IN: the random number generator state
+ );
+void
+RsaSimulationEnd(
+ void
+ );
+
+
+#endif
diff --git a/src/tpm2/crypto/CryptPrime_fp.h b/src/tpm2/crypto/CryptPrime_fp.h
new file mode 100644
index 0000000..d9acfcb
--- /dev/null
+++ b/src/tpm2/crypto/CryptPrime_fp.h
@@ -0,0 +1,104 @@
+/********************************************************************************/
+/* */
+/* Code for prime validation */
+/* Written by Ken Goldman */
+/* IBM Thomas J. Watson Research Center */
+/* $Id: CryptPrime_fp.h 1476 2019-06-10 19:32:03Z kgoldman $ */
+/* */
+/* Licenses and Notices */
+/* */
+/* 1. Copyright Licenses: */
+/* */
+/* - Trusted Computing Group (TCG) grants to the user of the source code in */
+/* this specification (the "Source Code") a worldwide, irrevocable, */
+/* nonexclusive, royalty free, copyright license to reproduce, create */
+/* derivative works, distribute, display and perform the Source Code and */
+/* derivative works thereof, and to grant others the rights granted herein. */
+/* */
+/* - The TCG grants to the user of the other parts of the specification */
+/* (other than the Source Code) the rights to reproduce, distribute, */
+/* display, and perform the specification solely for the purpose of */
+/* developing products based on such documents. */
+/* */
+/* 2. Source Code Distribution Conditions: */
+/* */
+/* - Redistributions of Source Code must retain the above copyright licenses, */
+/* this list of conditions and the following disclaimers. */
+/* */
+/* - Redistributions in binary form must reproduce the above copyright */
+/* licenses, this list of conditions and the following disclaimers in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* 3. Disclaimers: */
+/* */
+/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
+/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
+/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
+/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
+/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
+/* information on specification licensing rights available through TCG */
+/* membership agreements. */
+/* */
+/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
+/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
+/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
+/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
+/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
+/* */
+/* - Without limitation, TCG and its members and licensors disclaim all */
+/* liability, including liability for infringement of any proprietary */
+/* rights, relating to use of information in this specification and to the */
+/* implementation of this specification, and TCG disclaims all liability for */
+/* cost of procurement of substitute goods or services, lost profits, loss */
+/* of use, loss of data or any incidental, consequential, direct, indirect, */
+/* or special damages, whether under contract, tort, warranty or otherwise, */
+/* arising in any way out of use or reliance upon this specification or any */
+/* information herein. */
+/* */
+/* (c) Copyright IBM Corp. and others, 2016 - 2019 */
+/* */
+/********************************************************************************/
+
+#ifndef CRYPTPRIME_FP_H
+#define CRYPTPRIME_FP_H
+
+BOOL
+IsPrimeInt(
+ uint32_t n
+ );
+BOOL
+BnIsProbablyPrime(
+ bigNum prime, // IN:
+ RAND_STATE *rand // IN: the random state just
+ // in case Miller-Rabin is required
+ );
+UINT32
+MillerRabinRounds(
+ UINT32 bits // IN: Number of bits in the RSA prime
+ );
+BOOL
+MillerRabin(
+ bigNum bnW,
+ RAND_STATE *rand
+ );
+TPM_RC
+RsaCheckPrime(
+ bigNum prime,
+ UINT32 exponent,
+ RAND_STATE *rand
+ );
+LIB_EXPORT void
+RsaAdjustPrimeCandidate(
+ bigNum prime,
+ SEED_COMPAT_LEVEL seedCompatLevel // IN: compatibility level; libtpms added
+ );
+TPM_RC
+BnGeneratePrimeForRSA(
+ bigNum prime,
+ UINT32 bits,
+ UINT32 exponent,
+ RAND_STATE *rand
+ );
+
+
+#endif
diff --git a/src/tpm2/crypto/CryptRand.h b/src/tpm2/crypto/CryptRand.h
new file mode 100644
index 0000000..d339285
--- /dev/null
+++ b/src/tpm2/crypto/CryptRand.h
@@ -0,0 +1,193 @@
+/********************************************************************************/
+/* */
+/* DRBG with a behavior according to SP800-90A */
+/* Written by Ken Goldman */
+/* IBM Thomas J. Watson Research Center */
+/* $Id: CryptRand.h 1594 2020-03-26 22:15:48Z kgoldman $ */
+/* */
+/* Licenses and Notices */
+/* */
+/* 1. Copyright Licenses: */
+/* */
+/* - Trusted Computing Group (TCG) grants to the user of the source code in */
+/* this specification (the "Source Code") a worldwide, irrevocable, */
+/* nonexclusive, royalty free, copyright license to reproduce, create */
+/* derivative works, distribute, display and perform the Source Code and */
+/* derivative works thereof, and to grant others the rights granted herein. */
+/* */
+/* - The TCG grants to the user of the other parts of the specification */
+/* (other than the Source Code) the rights to reproduce, distribute, */
+/* display, and perform the specification solely for the purpose of */
+/* developing products based on such documents. */
+/* */
+/* 2. Source Code Distribution Conditions: */
+/* */
+/* - Redistributions of Source Code must retain the above copyright licenses, */
+/* this list of conditions and the following disclaimers. */
+/* */
+/* - Redistributions in binary form must reproduce the above copyright */
+/* licenses, this list of conditions and the following disclaimers in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* 3. Disclaimers: */
+/* */
+/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
+/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
+/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
+/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
+/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
+/* information on specification licensing rights available through TCG */
+/* membership agreements. */
+/* */
+/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
+/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
+/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
+/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
+/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
+/* */
+/* - Without limitation, TCG and its members and licensors disclaim all */
+/* liability, including liability for infringement of any proprietary */
+/* rights, relating to use of information in this specification and to the */
+/* implementation of this specification, and TCG disclaims all liability for */
+/* cost of procurement of substitute goods or services, lost profits, loss */
+/* of use, loss of data or any incidental, consequential, direct, indirect, */
+/* or special damages, whether under contract, tort, warranty or otherwise, */
+/* arising in any way out of use or reliance upon this specification or any */
+/* information herein. */
+/* */
+/* (c) Copyright IBM Corp. and others, 2016 - 2020 */
+/* */
+/********************************************************************************/
+
+/* 10.1.4 CryptRand.h */
+/* 10.1.4.1 Introduction */
+/* This file contains constant definition shared by CryptUtil() and the parts of the Crypto
+ Engine. */
+#ifndef _CRYPT_RAND_H
+#define _CRYPT_RAND_H
+/* DRBG Structures and Defines Values and structures for the random number generator. These values
+ are defined in this header file so that the size of the RNG state can be known to TPM.lib. This
+ allows the allocation of some space in NV memory for the state to be stored on an orderly
+ shutdown. The DRBG based on a symmetric block cipher is defined by three values, */
+/* a) the key size */
+/* b) the block size (the IV size) */
+/* c) the symmetric algorithm */
+#define DRBG_KEY_SIZE_BITS AES_MAX_KEY_SIZE_BITS
+#define DRBG_IV_SIZE_BITS (AES_MAX_BLOCK_SIZE * 8)
+#define DRBG_ALGORITHM TPM_ALG_AES
+typedef tpmKeyScheduleAES DRBG_KEY_SCHEDULE;
+#define DRBG_ENCRYPT_SETUP(key, keySizeInBits, schedule) \
+ TpmCryptSetEncryptKeyAES(key, keySizeInBits, schedule)
+#define DRBG_ENCRYPT(keySchedule, in, out) \
+ TpmCryptEncryptAES(SWIZZLE(keySchedule, in, out))
+#if ((DRBG_KEY_SIZE_BITS % RADIX_BITS) != 0) \
+ || ((DRBG_IV_SIZE_BITS % RADIX_BITS) != 0)
+#error "Key size and IV for DRBG must be even multiples of the radix"
+#endif
+#if (DRBG_KEY_SIZE_BITS % DRBG_IV_SIZE_BITS) != 0
+#error "Key size for DRBG must be even multiple of the cypher block size"
+#endif
+/* Derived values */
+#define DRBG_MAX_REQUESTS_PER_RESEED (1 << 48)
+#define DRBG_MAX_REQEST_SIZE (1 << 32)
+#define pDRBG_KEY(seed) ((DRBG_KEY *)&(((BYTE *)(seed))[0]))
+#define pDRBG_IV(seed) ((DRBG_IV *)&(((BYTE *)(seed))[DRBG_KEY_SIZE_BYTES]))
+#define DRBG_KEY_SIZE_WORDS (BITS_TO_CRYPT_WORDS(DRBG_KEY_SIZE_BITS))
+#define DRBG_KEY_SIZE_BYTES (DRBG_KEY_SIZE_WORDS * RADIX_BYTES)
+#define DRBG_IV_SIZE_WORDS (BITS_TO_CRYPT_WORDS(DRBG_IV_SIZE_BITS))
+#define DRBG_IV_SIZE_BYTES (DRBG_IV_SIZE_WORDS * RADIX_BYTES)
+#define DRBG_SEED_SIZE_WORDS (DRBG_KEY_SIZE_WORDS + DRBG_IV_SIZE_WORDS)
+#define DRBG_SEED_SIZE_BYTES (DRBG_KEY_SIZE_BYTES + DRBG_IV_SIZE_BYTES)
+typedef union
+{
+ BYTE bytes[DRBG_KEY_SIZE_BYTES];
+ crypt_uword_t words[DRBG_KEY_SIZE_WORDS];
+} DRBG_KEY;
+typedef union
+{
+ BYTE bytes[DRBG_IV_SIZE_BYTES];
+ crypt_uword_t words[DRBG_IV_SIZE_WORDS];
+} DRBG_IV;
+typedef union
+{
+ BYTE bytes[DRBG_SEED_SIZE_BYTES];
+ crypt_uword_t words[DRBG_SEED_SIZE_WORDS];
+} DRBG_SEED;
+#define CTR_DRBG_MAX_REQUESTS_PER_RESEED ((UINT64)1 << 20)
+#define CTR_DRBG_MAX_BYTES_PER_REQUEST (1 << 16)
+# define CTR_DRBG_MIN_ENTROPY_INPUT_LENGTH DRBG_SEED_SIZE_BYTES
+# define CTR_DRBG_MAX_ENTROPY_INPUT_LENGTH DRBG_SEED_SIZE_BYTES
+# define CTR_DRBG_MAX_ADDITIONAL_INPUT_LENGTH DRBG_SEED_SIZE_BYTES
+#define TESTING (1 << 0)
+#define ENTROPY (1 << 1)
+#define TESTED (1 << 2)
+#define IsTestStateSet(BIT) ((g_cryptoSelfTestState.rng & BIT) != 0)
+#define SetTestStateBit(BIT) (g_cryptoSelfTestState.rng |= BIT)
+#define ClearTestStateBit(BIT) (g_cryptoSelfTestState.rng &= ~BIT)
+#define IsSelfTest() IsTestStateSet(TESTING)
+#define SetSelfTest() SetTestStateBit(TESTING)
+#define ClearSelfTest() ClearTestStateBit(TESTING)
+#define IsEntropyBad() IsTestStateSet(ENTROPY)
+#define SetEntropyBad() SetTestStateBit(ENTROPY)
+#define ClearEntropyBad() ClearTestStateBit(ENTROPY)
+#define IsDrbgTested() IsTestStateSet(TESTED)
+#define SetDrbgTested() SetTestStateBit(TESTED)
+#define ClearDrbgTested() ClearTestStateBit(TESTED)
+ typedef struct
+ {
+ UINT64 reseedCounter;
+ UINT32 magic;
+ DRBG_SEED seed; // contains the key and IV for the counter mode DRBG
+ SEED_COMPAT_LEVEL seedCompatLevel; // libtpms added: the compatibility level for keeping backwards compatibility
+ UINT32 lastValue[4]; // used when the TPM does continuous self-test
+ // for FIPS compliance of DRBG
+ } DRBG_STATE, *pDRBG_STATE;
+#define DRBG_MAGIC ((UINT32) 0x47425244) // "DRBG" backwards so that it displays
+typedef struct KDF_STATE
+{
+ UINT64 counter;
+ UINT32 magic;
+ UINT32 limit;
+ TPM2B *seed;
+ const TPM2B *label;
+ TPM2B *context;
+ TPM_ALG_ID hash;
+ TPM_ALG_ID kdf;
+ UINT16 digestSize;
+ TPM2B_DIGEST residual;
+} KDF_STATE, *pKDR_STATE;
+#define KDF_MAGIC ((UINT32) 0x4048444a) // "KDF " backwards
+/* Make sure that any other structures added to this union start with a 64-bit counter and a 32-bit
+ magic number */
+typedef union
+{
+ DRBG_STATE drbg;
+ KDF_STATE kdf;
+} RAND_STATE;
+/* This is the state used when the library uses a random number generator. A special function is
+ installed for the library to call. That function picks up the state from this location and uses
+ it for the generation of the random number. */
+extern RAND_STATE *s_random;
+/* When instrumenting RSA key sieve */
+#if RSA_INSTRUMENT
+#define PRIME_INDEX(x) ((x) == 512 ? 0 : (x) == 1024 ? 1 : 2)
+# define INSTRUMENT_SET(a, b) ((a) = (b))
+# define INSTRUMENT_ADD(a, b) (a) = (a) + (b)
+# define INSTRUMENT_INC(a) (a) = (a) + 1
+extern UINT32 PrimeIndex;
+extern UINT32 failedAtIteration[10];
+extern UINT32 PrimeCounts[3];
+extern UINT32 MillerRabinTrials[3];
+extern UINT32 totalFieldsSieved[3];
+extern UINT32 bitsInFieldAfterSieve[3];
+extern UINT32 emptyFieldsSieved[3];
+extern UINT32 noPrimeFields[3];
+extern UINT32 primesChecked[3];
+extern UINT16 lastSievePrime;
+#else
+# define INSTRUMENT_SET(a, b)
+# define INSTRUMENT_ADD(a, b)
+# define INSTRUMENT_INC(a)
+#endif
+#endif // _CRYPT_RAND_H
+
diff --git a/src/tpm2/crypto/CryptRand_fp.h b/src/tpm2/crypto/CryptRand_fp.h
new file mode 100644
index 0000000..e5dee5b
--- /dev/null
+++ b/src/tpm2/crypto/CryptRand_fp.h
@@ -0,0 +1,158 @@
+/********************************************************************************/
+/* */
+/* DRBG with a behavior according to SP800-90A */
+/* Written by Ken Goldman */
+/* IBM Thomas J. Watson Research Center */
+/* $Id: CryptRand_fp.h 1476 2019-06-10 19:32:03Z kgoldman $ */
+/* */
+/* Licenses and Notices */
+/* */
+/* 1. Copyright Licenses: */
+/* */
+/* - Trusted Computing Group (TCG) grants to the user of the source code in */
+/* this specification (the "Source Code") a worldwide, irrevocable, */
+/* nonexclusive, royalty free, copyright license to reproduce, create */
+/* derivative works, distribute, display and perform the Source Code and */
+/* derivative works thereof, and to grant others the rights granted herein. */
+/* */
+/* - The TCG grants to the user of the other parts of the specification */
+/* (other than the Source Code) the rights to reproduce, distribute, */
+/* display, and perform the specification solely for the purpose of */
+/* developing products based on such documents. */
+/* */
+/* 2. Source Code Distribution Conditions: */
+/* */
+/* - Redistributions of Source Code must retain the above copyright licenses, */
+/* this list of conditions and the following disclaimers. */
+/* */
+/* - Redistributions in binary form must reproduce the above copyright */
+/* licenses, this list of conditions and the following disclaimers in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* 3. Disclaimers: */
+/* */
+/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
+/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
+/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
+/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
+/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
+/* information on specification licensing rights available through TCG */
+/* membership agreements. */
+/* */
+/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
+/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
+/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
+/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
+/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
+/* */
+/* - Without limitation, TCG and its members and licensors disclaim all */
+/* liability, including liability for infringement of any proprietary */
+/* rights, relating to use of information in this specification and to the */
+/* implementation of this specification, and TCG disclaims all liability for */
+/* cost of procurement of substitute goods or services, lost profits, loss */
+/* of use, loss of data or any incidental, consequential, direct, indirect, */
+/* or special damages, whether under contract, tort, warranty or otherwise, */
+/* arising in any way out of use or reliance upon this specification or any */
+/* information herein. */
+/* */
+/* (c) Copyright IBM Corp. and others, 2016 - 2019 */
+/* */
+/********************************************************************************/
+
+#ifndef CRYPTRAND_FP_H
+#define CRYPTRAND_FP_H
+
+BOOL
+DRBG_GetEntropy(
+ UINT32 requiredEntropy, // IN: requested number of bytes of full
+ // entropy
+ BYTE *entropy // OUT: buffer to return collected entropy
+ );
+void
+IncrementIv(
+ DRBG_IV *iv
+ );
+BOOL
+DRBG_Reseed(
+ DRBG_STATE *drbgState, // IN: the state to update
+ DRBG_SEED *providedEntropy, // IN: entropy
+ DRBG_SEED *additionalData // IN:
+ );
+BOOL
+DRBG_SelfTest(
+ void
+ );
+LIB_EXPORT TPM_RC
+CryptRandomStir(
+ UINT16 additionalDataSize,
+ BYTE *additionalData
+ );
+LIB_EXPORT UINT16
+CryptRandomGenerate(
+ UINT16 randomSize,
+ BYTE *buffer
+ );
+LIB_EXPORT BOOL
+DRBG_InstantiateSeededKdf(
+ KDF_STATE *state, // IN: buffer to hold the state
+ TPM_ALG_ID hashAlg, // IN: hash algorithm
+ TPM_ALG_ID kdf, // IN: the KDF to use
+ TPM2B *seed, // IN: the seed to use
+ const TPM2B *label, // IN: a label for the generation process.
+ TPM2B *context, // IN: the context value
+ UINT32 limit // IN: Maximum number of bits from the KDF
+ );
+LIB_EXPORT void
+DRBG_AdditionalData(
+ DRBG_STATE *drbgState, // IN:OUT state to update
+ TPM2B *additionalData // IN: value to incorporate
+ );
+LIB_EXPORT TPM_RC
+DRBG_InstantiateSeeded(
+ DRBG_STATE *drbgState, // IN: buffer to hold the state
+ const TPM2B *seed, // IN: the seed to use
+ const TPM2B *purpose, // IN: a label for the generation process.
+ const TPM2B *name, // IN: name of the object
+ const TPM2B *additional, // IN: additional data
+ SEED_COMPAT_LEVEL seedCompatLevel// IN: compatibility level (associated with seed); libtpms added
+ );
+LIB_EXPORT BOOL
+CryptRandStartup(
+ void
+ );
+LIB_EXPORT BOOL
+CryptRandInit(
+ void
+ );
+LIB_EXPORT UINT16
+DRBG_Generate(
+ RAND_STATE *state,
+ BYTE *random, // OUT: buffer to receive the random values
+ UINT16 randomSize // IN: the number of bytes to generate
+ );
+// libtpms added begin
+LIB_EXPORT SEED_COMPAT_LEVEL
+DRBG_GetSeedCompatLevel(
+ RAND_STATE *state // IN
+ );
+// libtpms added end
+LIB_EXPORT BOOL
+DRBG_Instantiate(
+ DRBG_STATE *drbgState, // OUT: the instantiated value
+ UINT16 pSize, // IN: Size of personalization string
+ BYTE *personalization // IN: The personalization string
+ );
+LIB_EXPORT TPM_RC
+DRBG_Uninstantiate(
+ DRBG_STATE *drbgState // IN/OUT: working state to erase
+ );
+LIB_EXPORT NUMBYTES
+CryptRandMinMax(
+ BYTE *out,
+ UINT32 max,
+ UINT32 min,
+ RAND_STATE *rand
+ );
+
+
+#endif
diff --git a/src/tpm2/crypto/CryptRsa.h b/src/tpm2/crypto/CryptRsa.h
new file mode 100644
index 0000000..f3c1fa1
--- /dev/null
+++ b/src/tpm2/crypto/CryptRsa.h
@@ -0,0 +1,99 @@
+/********************************************************************************/
+/* */
+/* RSA-related structures and defines */
+/* Written by Ken Goldman */
+/* IBM Thomas J. Watson Research Center */
+/* $Id: CryptRsa.h 1476 2019-06-10 19:32:03Z kgoldman $ */
+/* */
+/* Licenses and Notices */
+/* */
+/* 1. Copyright Licenses: */
+/* */
+/* - Trusted Computing Group (TCG) grants to the user of the source code in */
+/* this specification (the "Source Code") a worldwide, irrevocable, */
+/* nonexclusive, royalty free, copyright license to reproduce, create */
+/* derivative works, distribute, display and perform the Source Code and */
+/* derivative works thereof, and to grant others the rights granted herein. */
+/* */
+/* - The TCG grants to the user of the other parts of the specification */
+/* (other than the Source Code) the rights to reproduce, distribute, */
+/* display, and perform the specification solely for the purpose of */
+/* developing products based on such documents. */
+/* */
+/* 2. Source Code Distribution Conditions: */
+/* */
+/* - Redistributions of Source Code must retain the above copyright licenses, */
+/* this list of conditions and the following disclaimers. */
+/* */
+/* - Redistributions in binary form must reproduce the above copyright */
+/* licenses, this list of conditions and the following disclaimers in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* 3. Disclaimers: */
+/* */
+/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
+/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
+/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
+/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
+/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
+/* information on specification licensing rights available through TCG */
+/* membership agreements. */
+/* */
+/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
+/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
+/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
+/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
+/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
+/* */
+/* - Without limitation, TCG and its members and licensors disclaim all */
+/* liability, including liability for infringement of any proprietary */
+/* rights, relating to use of information in this specification and to the */
+/* implementation of this specification, and TCG disclaims all liability for */
+/* cost of procurement of substitute goods or services, lost profits, loss */
+/* of use, loss of data or any incidental, consequential, direct, indirect, */
+/* or special damages, whether under contract, tort, warranty or otherwise, */
+/* arising in any way out of use or reliance upon this specification or any */
+/* information herein. */
+/* */
+/* (c) Copyright IBM Corp. and others, 2016 - 2019 */
+/* */
+/********************************************************************************/
+
+// 10.1.5 CryptRsa.h
+// This file contains the RSA-related structures and defines.
+#ifndef _CRYPT_RSA_H
+#define _CRYPT_RSA_H
+
+/* This structure is a succinct representation of the cryptographic components of an RSA key. It is
+ used in testing */
+typedef struct
+{
+ UINT32 exponent; // The public exponent pointer
+ TPM2B *publicKey; // Pointer to the public modulus
+ TPM2B *privateKey; // The private prime
+} RSA_KEY;
+/* These values are used in the bigNum representation of various RSA values. */
+#define RSA_BITS (MAX_RSA_KEY_BYTES * 8)
+BN_TYPE(rsa, RSA_BITS);
+#define BN_RSA(name) BN_VAR(name, RSA_BITS)
+#define BN_RSA_INITIALIZED(name, initializer) \
+ BN_INITIALIZED(name, RSA_BITS, initializer)
+#define BN_PRIME(name) BN_VAR(name, (RSA_BITS / 2))
+BN_TYPE(prime, (RSA_BITS / 2));
+#define BN_PRIME_INITIALIZED(name, initializer) \
+ BN_INITIALIZED(name, RSA_BITS / 2, initializer)
+typedef struct privateExponent
+{
+#if CRT_FORMAT_RSA == NO
+ bn_rsa_t D;
+#else
+ bn_prime_t Q;
+ bn_prime_t dP;
+ bn_prime_t dQ;
+ bn_prime_t qInv;
+#endif // CRT_FORMAT_RSA
+} privateExponent_t;
+#endif // _CRYPT_RSA_H
+
+
+
diff --git a/src/tpm2/crypto/CryptRsa_fp.h b/src/tpm2/crypto/CryptRsa_fp.h
new file mode 100644
index 0000000..d473b51
--- /dev/null
+++ b/src/tpm2/crypto/CryptRsa_fp.h
@@ -0,0 +1,139 @@
+/********************************************************************************/
+/* */
+/* Implementation of cryptographic primitives for RSA */
+/* Written by Ken Goldman */
+/* IBM Thomas J. Watson Research Center */
+/* $Id: CryptRsa_fp.h 1476 2019-06-10 19:32:03Z kgoldman $ */
+/* */
+/* Licenses and Notices */
+/* */
+/* 1. Copyright Licenses: */
+/* */
+/* - Trusted Computing Group (TCG) grants to the user of the source code in */
+/* this specification (the "Source Code") a worldwide, irrevocable, */
+/* nonexclusive, royalty free, copyright license to reproduce, create */
+/* derivative works, distribute, display and perform the Source Code and */
+/* derivative works thereof, and to grant others the rights granted herein. */
+/* */
+/* - The TCG grants to the user of the other parts of the specification */
+/* (other than the Source Code) the rights to reproduce, distribute, */
+/* display, and perform the specification solely for the purpose of */
+/* developing products based on such documents. */
+/* */
+/* 2. Source Code Distribution Conditions: */
+/* */
+/* - Redistributions of Source Code must retain the above copyright licenses, */
+/* this list of conditions and the following disclaimers. */
+/* */
+/* - Redistributions in binary form must reproduce the above copyright */
+/* licenses, this list of conditions and the following disclaimers in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* 3. Disclaimers: */
+/* */
+/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
+/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
+/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
+/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
+/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
+/* information on specification licensing rights available through TCG */
+/* membership agreements. */
+/* */
+/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
+/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
+/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
+/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
+/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
+/* */
+/* - Without limitation, TCG and its members and licensors disclaim all */
+/* liability, including liability for infringement of any proprietary */
+/* rights, relating to use of information in this specification and to the */
+/* implementation of this specification, and TCG disclaims all liability for */
+/* cost of procurement of substitute goods or services, lost profits, loss */
+/* of use, loss of data or any incidental, consequential, direct, indirect, */
+/* or special damages, whether under contract, tort, warranty or otherwise, */
+/* arising in any way out of use or reliance upon this specification or any */
+/* information herein. */
+/* */
+/* (c) Copyright IBM Corp. and others, 2016 - 2019 */
+/* */
+/********************************************************************************/
+
+#ifndef CRYPTRSA_FP_H
+#define CRYPTRSA_FP_H
+
+BOOL
+CryptRsaInit(
+ void
+ );
+BOOL
+CryptRsaStartup(
+ void
+ );
+void
+RsaInitializeExponent(
+ privateExponent_t *pExp
+ );
+INT16
+CryptRsaPssSaltSize(
+ INT16 hashSize,
+ INT16 outSize
+ );
+TPMT_RSA_DECRYPT*
+CryptRsaSelectScheme(
+ TPMI_DH_OBJECT rsaHandle, // IN: handle of an RSA key
+ TPMT_RSA_DECRYPT *scheme // IN: a sign or decrypt scheme
+ );
+TPM_RC
+CryptRsaLoadPrivateExponent(
+ OBJECT *rsaKey // IN: the RSA key object
+ );
+LIB_EXPORT TPM_RC
+CryptRsaEncrypt(
+ TPM2B_PUBLIC_KEY_RSA *cOut, // OUT: the encrypted data
+ TPM2B *dIn, // IN: the data to encrypt
+ OBJECT *key, // IN: the key used for encryption
+ TPMT_RSA_DECRYPT *scheme, // IN: the type of padding and hash
+ // if needed
+ const TPM2B *label, // IN: in case it is needed
+ RAND_STATE *rand // IN: random number generator
+ // state (mostly for testing)
+ );
+LIB_EXPORT TPM_RC
+CryptRsaDecrypt(
+ TPM2B *dOut, // OUT: the decrypted data
+ TPM2B *cIn, // IN: the data to decrypt
+ OBJECT *key, // IN: the key to use for decryption
+ TPMT_RSA_DECRYPT *scheme, // IN: the padding scheme
+ const TPM2B *label // IN: in case it is needed for the scheme
+ );
+LIB_EXPORT TPM_RC
+CryptRsaSign(
+ TPMT_SIGNATURE *sigOut,
+ OBJECT *key, // IN: key to use
+ TPM2B_DIGEST *hIn, // IN: the digest to sign
+ RAND_STATE *rand // IN: the random number generator
+ // to use (mostly for testing)
+ );
+LIB_EXPORT TPM_RC
+CryptRsaValidateSignature(
+ TPMT_SIGNATURE *sig, // IN: signature
+ OBJECT *key, // IN: public modulus
+ TPM2B_DIGEST *digest // IN: The digest being validated
+ );
+LIB_EXPORT TPM_RC
+CryptRsaGenerateKey(
+ OBJECT *rsaKey, // IN/OUT: The object structure in which
+ // the key is created.
+ RAND_STATE *rand // IN: if not NULL, the deterministic
+ // RNG state
+ );
+INT16
+MakeDerTag(
+ TPM_ALG_ID hashAlg,
+ INT16 sizeOfBuffer,
+ BYTE *buffer
+ );
+
+
+#endif
diff --git a/src/tpm2/crypto/CryptSelfTest_fp.h b/src/tpm2/crypto/CryptSelfTest_fp.h
new file mode 100644
index 0000000..8dd3822
--- /dev/null
+++ b/src/tpm2/crypto/CryptSelfTest_fp.h
@@ -0,0 +1,87 @@
+/********************************************************************************/
+/* */
+/* */
+/* Written by Ken Goldman */
+/* IBM Thomas J. Watson Research Center */
+/* $Id: CryptSelfTest_fp.h 1490 2019-07-26 21:13:22Z kgoldman $ */
+/* */
+/* Licenses and Notices */
+/* */
+/* 1. Copyright Licenses: */
+/* */
+/* - Trusted Computing Group (TCG) grants to the user of the source code in */
+/* this specification (the "Source Code") a worldwide, irrevocable, */
+/* nonexclusive, royalty free, copyright license to reproduce, create */
+/* derivative works, distribute, display and perform the Source Code and */
+/* derivative works thereof, and to grant others the rights granted herein. */
+/* */
+/* - The TCG grants to the user of the other parts of the specification */
+/* (other than the Source Code) the rights to reproduce, distribute, */
+/* display, and perform the specification solely for the purpose of */
+/* developing products based on such documents. */
+/* */
+/* 2. Source Code Distribution Conditions: */
+/* */
+/* - Redistributions of Source Code must retain the above copyright licenses, */
+/* this list of conditions and the following disclaimers. */
+/* */
+/* - Redistributions in binary form must reproduce the above copyright */
+/* licenses, this list of conditions and the following disclaimers in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* 3. Disclaimers: */
+/* */
+/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
+/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
+/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
+/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
+/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
+/* information on specification licensing rights available through TCG */
+/* membership agreements. */
+/* */
+/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
+/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
+/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
+/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
+/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
+/* */
+/* - Without limitation, TCG and its members and licensors disclaim all */
+/* liability, including liability for infringement of any proprietary */
+/* rights, relating to use of information in this specification and to the */
+/* implementation of this specification, and TCG disclaims all liability for */
+/* cost of procurement of substitute goods or services, lost profits, loss */
+/* of use, loss of data or any incidental, consequential, direct, indirect, */
+/* or special damages, whether under contract, tort, warranty or otherwise, */
+/* arising in any way out of use or reliance upon this specification or any */
+/* information herein. */
+/* */
+/* (c) Copyright IBM Corp. and others, 2016 */
+/* */
+/********************************************************************************/
+
+#ifndef CRYPTSELFTEST_FP_H
+#define CRYPTSELFTEST_FP_H
+
+LIB_EXPORT
+TPM_RC
+CryptSelfTest(
+ TPMI_YES_NO fullTest // IN: if full test is required
+ );
+TPM_RC
+CryptIncrementalSelfTest(
+ TPML_ALG *toTest, // IN: list of algorithms to be tested
+ TPML_ALG *toDoList // OUT: list of algorithms needing test
+ );
+void
+CryptInitializeToTest(
+ void
+ );
+LIB_EXPORT
+TPM_RC
+CryptTestAlgorithm(
+ TPM_ALG_ID alg,
+ ALGORITHM_VECTOR *toTest
+ );
+
+
+#endif
diff --git a/src/tpm2/crypto/CryptSmac_fp.h b/src/tpm2/crypto/CryptSmac_fp.h
new file mode 100644
index 0000000..b93e8ac
--- /dev/null
+++ b/src/tpm2/crypto/CryptSmac_fp.h
@@ -0,0 +1,98 @@
+/********************************************************************************/
+/* Message Authentication Codes Based on a Symmetric Block Cipher */
+/* Implementation of cryptographic functions for hashing. */
+/* Written by Ken Goldman */
+/* IBM Thomas J. Watson Research Center */
+/* $Id: CryptSmac_fp.h 1490 2019-07-26 21:13:22Z kgoldman $ */
+/* */
+/* Licenses and Notices */
+/* */
+/* 1. Copyright Licenses: */
+/* */
+/* - Trusted Computing Group (TCG) grants to the user of the source code in */
+/* this specification (the "Source Code") a worldwide, irrevocable, */
+/* nonexclusive, royalty free, copyright license to reproduce, create */
+/* derivative works, distribute, display and perform the Source Code and */
+/* derivative works thereof, and to grant others the rights granted herein. */
+/* */
+/* - The TCG grants to the user of the other parts of the specification */
+/* (other than the Source Code) the rights to reproduce, distribute, */
+/* display, and perform the specification solely for the purpose of */
+/* developing products based on such documents. */
+/* */
+/* 2. Source Code Distribution Conditions: */
+/* */
+/* - Redistributions of Source Code must retain the above copyright licenses, */
+/* this list of conditions and the following disclaimers. */
+/* */
+/* - Redistributions in binary form must reproduce the above copyright */
+/* licenses, this list of conditions and the following disclaimers in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* 3. Disclaimers: */
+/* */
+/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
+/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
+/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
+/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
+/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
+/* information on specification licensing rights available through TCG */
+/* membership agreements. */
+/* */
+/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
+/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
+/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
+/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
+/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
+/* */
+/* - Without limitation, TCG and its members and licensors disclaim all */
+/* liability, including liability for infringement of any proprietary */
+/* rights, relating to use of information in this specification and to the */
+/* implementation of this specification, and TCG disclaims all liability for */
+/* cost of procurement of substitute goods or services, lost profits, loss */
+/* of use, loss of data or any incidental, consequential, direct, indirect, */
+/* or special damages, whether under contract, tort, warranty or otherwise, */
+/* arising in any way out of use or reliance upon this specification or any */
+/* information herein. */
+/* */
+/* (c) Copyright IBM Corp. and others, 2018 */
+/* */
+/********************************************************************************/
+
+#ifndef CRYPTSMAC_FP_H
+#define CRYPTSMAC_FP_H
+#include "Tpm.h"
+
+UINT16
+CryptSmacStart(
+ HASH_STATE *state,
+ TPMU_PUBLIC_PARMS *keyParameters,
+ TPM_ALG_ID macAlg,
+ TPM2B *key
+ );
+UINT16
+CryptMacStart(
+ HMAC_STATE *state,
+ TPMU_PUBLIC_PARMS *keyParameters,
+ TPM_ALG_ID macAlg,
+ TPM2B *key
+ );
+UINT16
+CryptMacEnd(
+ HMAC_STATE *state,
+ UINT32 size,
+ BYTE *buffer
+ );
+UINT16
+CryptMacEnd(
+ HMAC_STATE *state,
+ UINT32 size,
+ BYTE *buffer
+ );
+UINT16
+CryptMacEnd2B (
+ HMAC_STATE *state,
+ TPM2B *data
+ );
+
+#endif
diff --git a/src/tpm2/crypto/CryptSym.h b/src/tpm2/crypto/CryptSym.h
new file mode 100644
index 0000000..66cfb97
--- /dev/null
+++ b/src/tpm2/crypto/CryptSym.h
@@ -0,0 +1,142 @@
+/********************************************************************************/
+/* */
+/* Implementation of the symmetric block cipher modes */
+/* Written by Ken Goldman */
+/* IBM Thomas J. Watson Research Center */
+/* $Id: CryptSym.h 1658 2021-01-22 23:14:01Z kgoldman $ */
+/* */
+/* Licenses and Notices */
+/* */
+/* 1. Copyright Licenses: */
+/* */
+/* - Trusted Computing Group (TCG) grants to the user of the source code in */
+/* this specification (the "Source Code") a worldwide, irrevocable, */
+/* nonexclusive, royalty free, copyright license to reproduce, create */
+/* derivative works, distribute, display and perform the Source Code and */
+/* derivative works thereof, and to grant others the rights granted herein. */
+/* */
+/* - The TCG grants to the user of the other parts of the specification */
+/* (other than the Source Code) the rights to reproduce, distribute, */
+/* display, and perform the specification solely for the purpose of */
+/* developing products based on such documents. */
+/* */
+/* 2. Source Code Distribution Conditions: */
+/* */
+/* - Redistributions of Source Code must retain the above copyright licenses, */
+/* this list of conditions and the following disclaimers. */
+/* */
+/* - Redistributions in binary form must reproduce the above copyright */
+/* licenses, this list of conditions and the following disclaimers in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* 3. Disclaimers: */
+/* */
+/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
+/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
+/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
+/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
+/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
+/* information on specification licensing rights available through TCG */
+/* membership agreements. */
+/* */
+/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
+/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
+/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
+/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
+/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
+/* */
+/* - Without limitation, TCG and its members and licensors disclaim all */
+/* liability, including liability for infringement of any proprietary */
+/* rights, relating to use of information in this specification and to the */
+/* implementation of this specification, and TCG disclaims all liability for */
+/* cost of procurement of substitute goods or services, lost profits, loss */
+/* of use, loss of data or any incidental, consequential, direct, indirect, */
+/* or special damages, whether under contract, tort, warranty or otherwise, */
+/* arising in any way out of use or reliance upon this specification or any */
+/* information herein. */
+/* */
+/* (c) Copyright IBM Corp. and others, 2017 - 2021 */
+/* */
+/********************************************************************************/
+
+
+#ifndef CRYPTSYM_H
+#define CRYPTSYM_H
+
+#if ALG_AES
+# define IF_IMPLEMENTED_AES(op) op(AES, aes)
+#else
+# define IF_IMPLEMENTED_AES(op)
+#endif
+#if ALG_SM4
+# define IF_IMPLEMENTED_SM4(op) op(SM4, sm4)
+#else
+# define IF_IMPLEMENTED_SM4(op)
+#endif
+#if ALG_CAMELLIA
+# define IF_IMPLEMENTED_CAMELLIA(op) op(CAMELLIA, camellia)
+#else
+# define IF_IMPLEMENTED_CAMELLIA(op)
+#endif
+#if ALG_TDES
+# define IF_IMPLEMENTED_TDES(op) op(TDES, tdes)
+#else
+# define IF_IMPLEMENTED_TDES(op)
+#endif
+
+#define FOR_EACH_SYM(op) \
+ IF_IMPLEMENTED_AES(op) \
+ IF_IMPLEMENTED_SM4(op) \
+ IF_IMPLEMENTED_CAMELLIA(op) \
+ IF_IMPLEMENTED_TDES(op)
+
+ /* libtpms added begin */
+#define FOR_EACH_SYM_WITHOUT_TDES(op) \
+ IF_IMPLEMENTED_AES(op) \
+ IF_IMPLEMENTED_SM4(op) \
+ IF_IMPLEMENTED_CAMELLIA(op) /* libtpms added end */
+
+/* Macros for creating the key schedule union */
+
+#define KEY_SCHEDULE(SYM, sym) tpmKeySchedule##SYM sym;
+//#define TDES DES[3] /* libtpms commented */
+typedef union tpmCryptKeySchedule_t {
+ FOR_EACH_SYM_WITHOUT_TDES(KEY_SCHEDULE) /* libtpms changed from FOR_EACH_SYM */
+ tpmKeyScheduleTDES tdes[3]; /* libtpms added */
+
+#if SYMMETRIC_ALIGNMENT == 8
+ uint64_t alignment;
+#else
+ uint32_t alignment;
+#endif
+} tpmCryptKeySchedule_t;
+
+/* Each block cipher within a library is expected to conform to the same calling conventions with
+ three parameters (keySchedule, in, and out) in the same order. That means that all algorithms
+ would use the same order of the same parameters. The code is written assuming the (keySchedule,
+ in, and out) order. However, if the library uses a different order, the order can be changed with
+ a SWIZZLE macro that puts the parameters in the correct order. Note that all algorithms have to
+ use the same order and number of parameters because the code to build the calling list is common
+ for each call to encrypt or decrypt with the algorithm chosen by setting a function pointer to
+ select the algorithm that is used. */
+# define ENCRYPT(keySchedule, in, out) \
+ encrypt(SWIZZLE(keySchedule, in, out))
+# define DECRYPT(keySchedule, in, out) \
+ decrypt(SWIZZLE(keySchedule, in, out))
+
+/* Note that the macros rely on encrypt as local values in the functions that use these
+ macros. Those parameters are set by the macro that set the key schedule to be used for the
+ call. */
+
+#define ENCRYPT_CASE(ALG, alg) \
+ case TPM_ALG_##ALG: \
+ TpmCryptSetEncryptKey##ALG(key, keySizeInBits, &keySchedule.alg); \
+ encrypt = (TpmCryptSetSymKeyCall_t)TpmCryptEncrypt##ALG; \
+ break;
+#define DECRYPT_CASE(ALG, alg) \
+ case TPM_ALG_##ALG: \
+ TpmCryptSetDecryptKey##ALG(key, keySizeInBits, &keySchedule.alg); \
+ decrypt = (TpmCryptSetSymKeyCall_t)TpmCryptDecrypt##ALG; \
+ break;
+
+#endif
diff --git a/src/tpm2/crypto/CryptSym_fp.h b/src/tpm2/crypto/CryptSym_fp.h
new file mode 100644
index 0000000..e78215f
--- /dev/null
+++ b/src/tpm2/crypto/CryptSym_fp.h
@@ -0,0 +1,111 @@
+/********************************************************************************/
+/* */
+/* */
+/* Written by Ken Goldman */
+/* IBM Thomas J. Watson Research Center */
+/* $Id: CryptSym_fp.h 1047 2017-07-20 18:27:34Z kgoldman $ */
+/* */
+/* Licenses and Notices */
+/* */
+/* 1. Copyright Licenses: */
+/* */
+/* - Trusted Computing Group (TCG) grants to the user of the source code in */
+/* this specification (the "Source Code") a worldwide, irrevocable, */
+/* nonexclusive, royalty free, copyright license to reproduce, create */
+/* derivative works, distribute, display and perform the Source Code and */
+/* derivative works thereof, and to grant others the rights granted herein. */
+/* */
+/* - The TCG grants to the user of the other parts of the specification */
+/* (other than the Source Code) the rights to reproduce, distribute, */
+/* display, and perform the specification solely for the purpose of */
+/* developing products based on such documents. */
+/* */
+/* 2. Source Code Distribution Conditions: */
+/* */
+/* - Redistributions of Source Code must retain the above copyright licenses, */
+/* this list of conditions and the following disclaimers. */
+/* */
+/* - Redistributions in binary form must reproduce the above copyright */
+/* licenses, this list of conditions and the following disclaimers in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* 3. Disclaimers: */
+/* */
+/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
+/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
+/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
+/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
+/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
+/* information on specification licensing rights available through TCG */
+/* membership agreements. */
+/* */
+/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
+/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
+/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
+/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
+/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
+/* */
+/* - Without limitation, TCG and its members and licensors disclaim all */
+/* liability, including liability for infringement of any proprietary */
+/* rights, relating to use of information in this specification and to the */
+/* implementation of this specification, and TCG disclaims all liability for */
+/* cost of procurement of substitute goods or services, lost profits, loss */
+/* of use, loss of data or any incidental, consequential, direct, indirect, */
+/* or special damages, whether under contract, tort, warranty or otherwise, */
+/* arising in any way out of use or reliance upon this specification or any */
+/* information herein. */
+/* */
+/* (c) Copyright IBM Corp. and others, 2016 */
+/* */
+/********************************************************************************/
+
+#ifndef CRYPTSYM_FP_H
+#define CRYPTSYM_FP_H
+
+BOOL
+CryptSymInit(
+ void
+ );
+BOOL
+CryptSymStartup(
+ void
+ );
+LIB_EXPORT INT16
+CryptGetSymmetricBlockSize(
+ TPM_ALG_ID symmetricAlg, // IN: the symmetric algorithm
+ UINT16 keySizeInBits // IN: the key size
+ );
+LIB_EXPORT TPM_RC
+CryptSymmetricEncrypt(
+ BYTE *dOut, // OUT:
+ TPM_ALG_ID algorithm, // IN: the symmetric algorithm
+ UINT16 keySizeInBits, // IN: key size in bits
+ const BYTE *key, // IN: key buffer. The size of this buffer
+ // in bytes is (keySizeInBits + 7) / 8
+ TPM2B_IV *ivInOut, // IN/OUT: IV for decryption.
+ TPM_ALG_ID mode, // IN: Mode to use
+ INT32 dSize, // IN: data size (may need to be a
+ // multiple of the blockSize)
+ const BYTE *dIn // IN: data buffer
+ );
+LIB_EXPORT TPM_RC
+CryptSymmetricDecrypt(
+ BYTE *dOut, // OUT: decrypted data
+ TPM_ALG_ID algorithm, // IN: the symmetric algorithm
+ UINT16 keySizeInBits, // IN: key size in bits
+ const BYTE *key, // IN: key buffer. The size of this buffer
+ // in bytes is (keySizeInBits + 7) / 8
+ TPM2B_IV *ivInOut, // IN/OUT: IV for decryption.
+ TPM_ALG_ID mode, // IN: Mode to use
+ INT32 dSize, // IN: data size (may need to be a
+ // multiple of the blockSize)
+ const BYTE *dIn // IN: data buffer
+ );
+TPM_RC
+CryptSymKeyValidate(
+ TPMT_SYM_DEF_OBJECT *symDef,
+ TPM2B_SYM_KEY *key
+ );
+
+
+#endif
diff --git a/src/tpm2/crypto/CryptTest.h b/src/tpm2/crypto/CryptTest.h
new file mode 100644
index 0000000..ce2321b
--- /dev/null
+++ b/src/tpm2/crypto/CryptTest.h
@@ -0,0 +1,93 @@
+/********************************************************************************/
+/* */
+/* constant definitions used for self-test. */
+/* Written by Ken Goldman */
+/* IBM Thomas J. Watson Research Center */
+/* $Id: CryptTest.h 1594 2020-03-26 22:15:48Z kgoldman $ */
+/* */
+/* Licenses and Notices */
+/* */
+/* 1. Copyright Licenses: */
+/* */
+/* - Trusted Computing Group (TCG) grants to the user of the source code in */
+/* this specification (the "Source Code") a worldwide, irrevocable, */
+/* nonexclusive, royalty free, copyright license to reproduce, create */
+/* derivative works, distribute, display and perform the Source Code and */
+/* derivative works thereof, and to grant others the rights granted herein. */
+/* */
+/* - The TCG grants to the user of the other parts of the specification */
+/* (other than the Source Code) the rights to reproduce, distribute, */
+/* display, and perform the specification solely for the purpose of */
+/* developing products based on such documents. */
+/* */
+/* 2. Source Code Distribution Conditions: */
+/* */
+/* - Redistributions of Source Code must retain the above copyright licenses, */
+/* this list of conditions and the following disclaimers. */
+/* */
+/* - Redistributions in binary form must reproduce the above copyright */
+/* licenses, this list of conditions and the following disclaimers in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* 3. Disclaimers: */
+/* */
+/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
+/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
+/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
+/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
+/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
+/* information on specification licensing rights available through TCG */
+/* membership agreements. */
+/* */
+/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
+/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
+/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
+/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
+/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
+/* */
+/* - Without limitation, TCG and its members and licensors disclaim all */
+/* liability, including liability for infringement of any proprietary */
+/* rights, relating to use of information in this specification and to the */
+/* implementation of this specification, and TCG disclaims all liability for */
+/* cost of procurement of substitute goods or services, lost profits, loss */
+/* of use, loss of data or any incidental, consequential, direct, indirect, */
+/* or special damages, whether under contract, tort, warranty or otherwise, */
+/* arising in any way out of use or reliance upon this specification or any */
+/* information herein. */
+/* */
+/* (c) Copyright IBM Corp. and others, 2016 - 2020 */
+/* */
+/********************************************************************************/
+
+#ifndef CRYPTTEST_H
+#define CRYPTTEST_H
+
+/* 10.1.7 CryptTest.h */
+/* This file contains constant definitions used for self test */
+/* This is the definition of a bit array with one bit per algorithm */
+/* NOTE: Since bit numbering starts at zero, when TPM_ALG_LAST is a multiple of 8,
+ ALGORITHM_VECTOR will need to have byte for the single bit in the last byte. So, for example,
+ when TPM_ALG_LAST is 8, ALGORITHM_VECTOR will need 2 bytes. */
+#define ALGORITHM_VECTOR_BYTES ((TPM_ALG_LAST + 8) / 8)
+typedef BYTE ALGORITHM_VECTOR[ALGORITHM_VECTOR_BYTES];
+#ifdef TEST_SELF_TEST
+LIB_EXPORT extern ALGORITHM_VECTOR LibToTest;
+#endif
+/* This structure is used to contain self-test tracking information for the cryptographic
+ modules. Each of the major modules is given a 32-bit value in which it may maintain its own self
+ test information. The convention for this state is that when all of the bits in this structure
+ are 0, all functions need to be tested. */
+typedef struct
+{
+ UINT32 rng;
+ UINT32 hash;
+ UINT32 sym;
+#if ALG_RSA
+ UINT32 rsa;
+#endif
+#if ALG_ECC
+ UINT32 ecc;
+#endif
+} CRYPTO_SELF_TEST_STATE;
+#endif // _CRYPT_TEST_H
+
diff --git a/src/tpm2/crypto/CryptUtil_fp.h b/src/tpm2/crypto/CryptUtil_fp.h
new file mode 100644
index 0000000..2ca16e7
--- /dev/null
+++ b/src/tpm2/crypto/CryptUtil_fp.h
@@ -0,0 +1,232 @@
+/********************************************************************************/
+/* */
+/* Interfaces to the CryptoEngine */
+/* Written by Ken Goldman */
+/* IBM Thomas J. Watson Research Center */
+/* $Id: CryptUtil_fp.h 1519 2019-11-15 20:43:51Z kgoldman $ */
+/* */
+/* Licenses and Notices */
+/* */
+/* 1. Copyright Licenses: */
+/* */
+/* - Trusted Computing Group (TCG) grants to the user of the source code in */
+/* this specification (the "Source Code") a worldwide, irrevocable, */
+/* nonexclusive, royalty free, copyright license to reproduce, create */
+/* derivative works, distribute, display and perform the Source Code and */
+/* derivative works thereof, and to grant others the rights granted herein. */
+/* */
+/* - The TCG grants to the user of the other parts of the specification */
+/* (other than the Source Code) the rights to reproduce, distribute, */
+/* display, and perform the specification solely for the purpose of */
+/* developing products based on such documents. */
+/* */
+/* 2. Source Code Distribution Conditions: */
+/* */
+/* - Redistributions of Source Code must retain the above copyright licenses, */
+/* this list of conditions and the following disclaimers. */
+/* */
+/* - Redistributions in binary form must reproduce the above copyright */
+/* licenses, this list of conditions and the following disclaimers in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* 3. Disclaimers: */
+/* */
+/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
+/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
+/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
+/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
+/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
+/* information on specification licensing rights available through TCG */
+/* membership agreements. */
+/* */
+/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
+/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
+/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
+/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
+/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
+/* */
+/* - Without limitation, TCG and its members and licensors disclaim all */
+/* liability, including liability for infringement of any proprietary */
+/* rights, relating to use of information in this specification and to the */
+/* implementation of this specification, and TCG disclaims all liability for */
+/* cost of procurement of substitute goods or services, lost profits, loss */
+/* of use, loss of data or any incidental, consequential, direct, indirect, */
+/* or special damages, whether under contract, tort, warranty or otherwise, */
+/* arising in any way out of use or reliance upon this specification or any */
+/* information herein. */
+/* */
+/* (c) Copyright IBM Corp. and others, 2016 - 2019 */
+/* */
+/********************************************************************************/
+
+#ifndef CRYPTUTIL_FP_H
+#define CRYPTUTIL_FP_H
+
+BOOL
+CryptIsSchemeAnonymous(
+ TPM_ALG_ID scheme // IN: the scheme algorithm to test
+ );
+void
+ParmDecryptSym(
+ TPM_ALG_ID symAlg, // IN: the symmetric algorithm
+ TPM_ALG_ID hash, // IN: hash algorithm for KDFa
+ UINT16 keySizeInBits, // IN: the key size in bits
+ TPM2B *key, // IN: KDF HMAC key
+ TPM2B *nonceCaller, // IN: nonce caller
+ TPM2B *nonceTpm, // IN: nonce TPM
+ UINT32 dataSize, // IN: size of parameter buffer
+ BYTE *data // OUT: buffer to be decrypted
+ );
+void
+ParmEncryptSym(
+ TPM_ALG_ID symAlg, // IN: symmetric algorithm
+ TPM_ALG_ID hash, // IN: hash algorithm for KDFa
+ UINT16 keySizeInBits, // IN: AES key size in bits
+ TPM2B *key, // IN: KDF HMAC key
+ TPM2B *nonceCaller, // IN: nonce caller
+ TPM2B *nonceTpm, // IN: nonce TPM
+ UINT32 dataSize, // IN: size of parameter buffer
+ BYTE *data // OUT: buffer to be encrypted
+ );
+void
+CryptXORObfuscation(
+ TPM_ALG_ID hash, // IN: hash algorithm for KDF
+ TPM2B *key, // IN: KDF key
+ TPM2B *contextU, // IN: contextU
+ TPM2B *contextV, // IN: contextV
+ UINT32 dataSize, // IN: size of data buffer
+ BYTE *data // IN/OUT: data to be XORed in place
+ );
+BOOL
+CryptInit(
+ void
+ );
+BOOL
+CryptStartup(
+ STARTUP_TYPE type // IN: the startup type
+ );
+BOOL
+CryptIsAsymAlgorithm(
+ TPM_ALG_ID algID // IN: algorithm ID
+ );
+TPM_RC
+CryptSecretEncrypt(
+ OBJECT *encryptKey, // IN: encryption key object
+ const TPM2B *label, // IN: a null-terminated string as L
+ TPM2B_DATA *data, // OUT: secret value
+ TPM2B_ENCRYPTED_SECRET *secret // OUT: secret structure
+ );
+TPM_RC
+CryptSecretDecrypt(
+ OBJECT *decryptKey, // IN: decrypt key
+ TPM2B_NONCE *nonceCaller, // IN: nonceCaller. It is needed for
+ // symmetric decryption. For
+ // asymmetric decryption, this
+ // parameter is NULL
+ const TPM2B *label, // IN: a value for L
+ TPM2B_ENCRYPTED_SECRET *secret, // IN: input secret
+ TPM2B_DATA *data // OUT: decrypted secret value
+ );
+void
+CryptParameterEncryption(
+ TPM_HANDLE handle, // IN: encrypt session handle
+ TPM2B *nonceCaller, // IN: nonce caller
+ UINT16 leadingSizeInByte, // IN: the size of the leading size field in
+ // bytes
+ TPM2B_AUTH *extraKey, // IN: additional key material other than
+ // sessionAuth
+ BYTE *buffer // IN/OUT: parameter buffer to be encrypted
+ );
+TPM_RC
+CryptParameterDecryption(
+ TPM_HANDLE handle, // IN: encrypted session handle
+ TPM2B *nonceCaller, // IN: nonce caller
+ UINT32 bufferSize, // IN: size of parameter buffer
+ UINT16 leadingSizeInByte, // IN: the size of the leading size field in
+ // byte
+ TPM2B_AUTH *extraKey, // IN: the authValue
+ BYTE *buffer // IN/OUT: parameter buffer to be decrypted
+ );
+void
+CryptComputeSymmetricUnique(
+ TPMT_PUBLIC *publicArea, // IN: the object's public area
+ TPMT_SENSITIVE *sensitive, // IN: the associated sensitive area
+ TPM2B_DIGEST *unique // OUT: unique buffer
+ );
+TPM_RC
+CryptCreateObject(
+ OBJECT *object, // IN: new object structure pointer
+ TPMS_SENSITIVE_CREATE *sensitiveCreate, // IN: sensitive creation
+ RAND_STATE *rand // IN: the random number generator
+ // to use
+ );
+TPMI_ALG_HASH
+CryptGetSignHashAlg(
+ TPMT_SIGNATURE *auth // IN: signature
+ );
+BOOL
+CryptIsSplitSign(
+ TPM_ALG_ID scheme // IN: the algorithm selector
+ );
+BOOL
+CryptIsAsymSignScheme(
+ TPMI_ALG_PUBLIC publicType, // IN: Type of the object
+ TPMI_ALG_ASYM_SCHEME scheme // IN: the scheme
+ );
+BOOL
+CryptIsAsymDecryptScheme(
+ TPMI_ALG_PUBLIC publicType, // IN: Type of the object
+ TPMI_ALG_ASYM_SCHEME scheme // IN: the scheme
+ );
+BOOL
+CryptSelectSignScheme(
+ OBJECT *signObject, // IN: signing key
+ TPMT_SIG_SCHEME *scheme // IN/OUT: signing scheme
+ );
+TPM_RC
+CryptSign(
+ OBJECT *signKey, // IN: signing key
+ TPMT_SIG_SCHEME *signScheme, // IN: sign scheme.
+ TPM2B_DIGEST *digest, // IN: The digest being signed
+ TPMT_SIGNATURE *signature // OUT: signature
+ );
+TPM_RC
+CryptValidateSignature(
+ TPMI_DH_OBJECT keyHandle, // IN: The handle of sign key
+ TPM2B_DIGEST *digest, // IN: The digest being validated
+ TPMT_SIGNATURE *signature // IN: signature
+ );
+TPM_RC
+CryptGetTestResult(
+ TPM2B_MAX_BUFFER *outData // OUT: test result data
+ );
+TPM_RC
+CryptValidateKeys(
+ TPMT_PUBLIC *publicArea,
+ TPMT_SENSITIVE *sensitive,
+ TPM_RC blamePublic,
+ TPM_RC blameSensitive
+ );
+TPM_RC
+CryptSelectMac(
+ TPMT_PUBLIC *publicArea,
+ TPMI_ALG_MAC_SCHEME *inMac
+ );
+BOOL
+CryptMacIsValidForKey(
+ TPM_ALG_ID keyType,
+ TPM_ALG_ID macAlg,
+ BOOL flag
+ );
+BOOL
+CryptSmacIsValidAlg(
+ TPM_ALG_ID alg,
+ BOOL FLAG // IN: Indicates if TPM_ALG_NULL is valid
+ );
+BOOL
+CryptSymModeIsValid(
+ TPM_ALG_ID mode,
+ BOOL flag
+ );
+
+#endif
diff --git a/src/tpm2/crypto/openssl/BnConvert_fp.h b/src/tpm2/crypto/openssl/BnConvert_fp.h
new file mode 100644
index 0000000..dd60da0
--- /dev/null
+++ b/src/tpm2/crypto/openssl/BnConvert_fp.h
@@ -0,0 +1,108 @@
+/********************************************************************************/
+/* */
+/* */
+/* Written by Ken Goldman */
+/* IBM Thomas J. Watson Research Center */
+/* $Id: BnConvert_fp.h 809 2016-11-16 18:31:54Z kgoldman $ */
+/* */
+/* Licenses and Notices */
+/* */
+/* 1. Copyright Licenses: */
+/* */
+/* - Trusted Computing Group (TCG) grants to the user of the source code in */
+/* this specification (the "Source Code") a worldwide, irrevocable, */
+/* nonexclusive, royalty free, copyright license to reproduce, create */
+/* derivative works, distribute, display and perform the Source Code and */
+/* derivative works thereof, and to grant others the rights granted herein. */
+/* */
+/* - The TCG grants to the user of the other parts of the specification */
+/* (other than the Source Code) the rights to reproduce, distribute, */
+/* display, and perform the specification solely for the purpose of */
+/* developing products based on such documents. */
+/* */
+/* 2. Source Code Distribution Conditions: */
+/* */
+/* - Redistributions of Source Code must retain the above copyright licenses, */
+/* this list of conditions and the following disclaimers. */
+/* */
+/* - Redistributions in binary form must reproduce the above copyright */
+/* licenses, this list of conditions and the following disclaimers in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* 3. Disclaimers: */
+/* */
+/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
+/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
+/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
+/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
+/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
+/* information on specification licensing rights available through TCG */
+/* membership agreements. */
+/* */
+/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
+/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
+/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
+/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
+/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
+/* */
+/* - Without limitation, TCG and its members and licensors disclaim all */
+/* liability, including liability for infringement of any proprietary */
+/* rights, relating to use of information in this specification and to the */
+/* implementation of this specification, and TCG disclaims all liability for */
+/* cost of procurement of substitute goods or services, lost profits, loss */
+/* of use, loss of data or any incidental, consequential, direct, indirect, */
+/* or special damages, whether under contract, tort, warranty or otherwise, */
+/* arising in any way out of use or reliance upon this specification or any */
+/* information herein. */
+/* */
+/* (c) Copyright IBM Corp. and others, 2016 */
+/* */
+/********************************************************************************/
+
+#ifndef BNCONVERT_FP_H
+#define BNCONVERT_FP_H
+
+LIB_EXPORT bigNum
+BnFromBytes(
+ bigNum bn,
+ const BYTE *bytes,
+ NUMBYTES nBytes
+ );
+LIB_EXPORT bigNum
+BnFrom2B(
+ bigNum bn, // OUT:
+ const TPM2B *a2B // IN: number to convert
+ );
+LIB_EXPORT bigNum
+BnFromHex(
+ bigNum bn, // OUT:
+ const char *hex // IN:
+ );
+LIB_EXPORT BOOL
+BnToBytes(
+ bigConst bn,
+ BYTE *buffer,
+ NUMBYTES *size // This the number of bytes that are
+ // available in the buffer. The result
+ // should be this big.
+ );
+LIB_EXPORT BOOL
+BnTo2B(
+ bigConst bn, // IN:
+ TPM2B *a2B, // OUT:
+ NUMBYTES size // IN: the desired size
+ );
+LIB_EXPORT bn_point_t *
+BnPointFrom2B(
+ bigPoint ecP, // OUT: the preallocated point structure
+ TPMS_ECC_POINT *p // IN: the number to convert
+ );
+LIB_EXPORT BOOL
+BnPointTo2B(
+ TPMS_ECC_POINT *p, // OUT: the converted 2B structure
+ bigPoint ecP, // IN: the values to be converted
+ bigCurve E // IN: curve descriptor for the point
+ );
+
+
+#endif
diff --git a/src/tpm2/crypto/openssl/BnMath_fp.h b/src/tpm2/crypto/openssl/BnMath_fp.h
new file mode 100644
index 0000000..62ba7b2
--- /dev/null
+++ b/src/tpm2/crypto/openssl/BnMath_fp.h
@@ -0,0 +1,163 @@
+/********************************************************************************/
+/* */
+/* */
+/* Written by Ken Goldman */
+/* IBM Thomas J. Watson Research Center */
+/* $Id: BnMath_fp.h 809 2016-11-16 18:31:54Z kgoldman $ */
+/* */
+/* Licenses and Notices */
+/* */
+/* 1. Copyright Licenses: */
+/* */
+/* - Trusted Computing Group (TCG) grants to the user of the source code in */
+/* this specification (the "Source Code") a worldwide, irrevocable, */
+/* nonexclusive, royalty free, copyright license to reproduce, create */
+/* derivative works, distribute, display and perform the Source Code and */
+/* derivative works thereof, and to grant others the rights granted herein. */
+/* */
+/* - The TCG grants to the user of the other parts of the specification */
+/* (other than the Source Code) the rights to reproduce, distribute, */
+/* display, and perform the specification solely for the purpose of */
+/* developing products based on such documents. */
+/* */
+/* 2. Source Code Distribution Conditions: */
+/* */
+/* - Redistributions of Source Code must retain the above copyright licenses, */
+/* this list of conditions and the following disclaimers. */
+/* */
+/* - Redistributions in binary form must reproduce the above copyright */
+/* licenses, this list of conditions and the following disclaimers in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* 3. Disclaimers: */
+/* */
+/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
+/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
+/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
+/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
+/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
+/* information on specification licensing rights available through TCG */
+/* membership agreements. */
+/* */
+/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
+/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
+/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
+/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
+/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
+/* */
+/* - Without limitation, TCG and its members and licensors disclaim all */
+/* liability, including liability for infringement of any proprietary */
+/* rights, relating to use of information in this specification and to the */
+/* implementation of this specification, and TCG disclaims all liability for */
+/* cost of procurement of substitute goods or services, lost profits, loss */
+/* of use, loss of data or any incidental, consequential, direct, indirect, */
+/* or special damages, whether under contract, tort, warranty or otherwise, */
+/* arising in any way out of use or reliance upon this specification or any */
+/* information herein. */
+/* */
+/* (c) Copyright IBM Corp. and others, 2016 */
+/* */
+/********************************************************************************/
+
+#ifndef BNMATH_FP_H
+#define BNMATH_FP_H
+
+LIB_EXPORT BOOL
+BnAdd(
+ bigNum result,
+ bigConst op1,
+ bigConst op2
+ );
+LIB_EXPORT BOOL
+BnAddWord(
+ bigNum result,
+ bigConst op,
+ crypt_uword_t word
+ );
+LIB_EXPORT BOOL
+BnSub(
+ bigNum result,
+ bigConst op1,
+ bigConst op2
+ );
+LIB_EXPORT BOOL
+BnSubWord(
+ bigNum result,
+ bigConst op,
+ crypt_uword_t word
+ );
+LIB_EXPORT int
+BnUnsignedCmp(
+ bigConst op1,
+ bigConst op2
+ );
+LIB_EXPORT int
+BnUnsignedCmpWord(
+ bigConst op1,
+ crypt_uword_t word
+ );
+LIB_EXPORT crypt_word_t
+BnModWord(
+ bigConst numerator,
+ crypt_word_t modulus
+ );
+LIB_EXPORT int
+Msb(
+ crypt_uword_t word
+ );
+LIB_EXPORT int
+BnMsb(
+ bigConst bn
+ );
+LIB_EXPORT unsigned
+BnSizeInBits(
+ bigConst n
+ );
+LIB_EXPORT bigNum
+BnSetWord(
+ bigNum n,
+ crypt_uword_t w
+ );
+LIB_EXPORT BOOL
+BnSetBit(
+ bigNum bn, // IN/OUT: big number to modify
+ unsigned int bitNum // IN: Bit number to SET
+ );
+LIB_EXPORT BOOL
+BnTestBit(
+ bigNum bn, // IN: number to check
+ unsigned int bitNum // IN: bit to test
+ );
+LIB_EXPORT BOOL
+BnMaskBits(
+ bigNum bn, // IN/OUT: number to mask
+ crypt_uword_t maskBit // IN: the bit number for the mask.
+ );
+LIB_EXPORT BOOL
+BnShiftRight(
+ bigNum result,
+ bigConst toShift,
+ uint32_t shiftAmount
+ );
+LIB_EXPORT BOOL
+BnGetRandomBits(
+ bigNum n,
+ size_t bits,
+ RAND_STATE *rand
+ );
+LIB_EXPORT BOOL
+BnGenerateRandomInRange(
+ bigNum dest,
+ bigConst limit,
+ RAND_STATE *rand
+ );
+// libtpms added begin
+LIB_EXPORT BOOL
+BnGenerateRandomInRangeAllBytes(
+ bigNum dest,
+ bigConst limit,
+ RAND_STATE *rand
+ );
+// libtpms added end
+
+#endif
diff --git a/src/tpm2/crypto/openssl/BnMemory_fp.h b/src/tpm2/crypto/openssl/BnMemory_fp.h
new file mode 100644
index 0000000..819a0a6
--- /dev/null
+++ b/src/tpm2/crypto/openssl/BnMemory_fp.h
@@ -0,0 +1,108 @@
+/********************************************************************************/
+/* */
+/* */
+/* Written by Ken Goldman */
+/* IBM Thomas J. Watson Research Center */
+/* $Id: BnMemory_fp.h 809 2016-11-16 18:31:54Z kgoldman $ */
+/* */
+/* Licenses and Notices */
+/* */
+/* 1. Copyright Licenses: */
+/* */
+/* - Trusted Computing Group (TCG) grants to the user of the source code in */
+/* this specification (the "Source Code") a worldwide, irrevocable, */
+/* nonexclusive, royalty free, copyright license to reproduce, create */
+/* derivative works, distribute, display and perform the Source Code and */
+/* derivative works thereof, and to grant others the rights granted herein. */
+/* */
+/* - The TCG grants to the user of the other parts of the specification */
+/* (other than the Source Code) the rights to reproduce, distribute, */
+/* display, and perform the specification solely for the purpose of */
+/* developing products based on such documents. */
+/* */
+/* 2. Source Code Distribution Conditions: */
+/* */
+/* - Redistributions of Source Code must retain the above copyright licenses, */
+/* this list of conditions and the following disclaimers. */
+/* */
+/* - Redistributions in binary form must reproduce the above copyright */
+/* licenses, this list of conditions and the following disclaimers in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* 3. Disclaimers: */
+/* */
+/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
+/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
+/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
+/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
+/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
+/* information on specification licensing rights available through TCG */
+/* membership agreements. */
+/* */
+/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
+/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
+/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
+/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
+/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
+/* */
+/* - Without limitation, TCG and its members and licensors disclaim all */
+/* liability, including liability for infringement of any proprietary */
+/* rights, relating to use of information in this specification and to the */
+/* implementation of this specification, and TCG disclaims all liability for */
+/* cost of procurement of substitute goods or services, lost profits, loss */
+/* of use, loss of data or any incidental, consequential, direct, indirect, */
+/* or special damages, whether under contract, tort, warranty or otherwise, */
+/* arising in any way out of use or reliance upon this specification or any */
+/* information herein. */
+/* */
+/* (c) Copyright IBM Corp. and others, 2016 */
+/* */
+/********************************************************************************/
+
+#ifndef BNMEMORY_FP_H
+#define BNMEMORY_FP_H
+
+LIB_EXPORT bigNum
+BnSetTop(
+ bigNum bn, // IN/OUT: number to clean
+ crypt_uword_t top // IN: the new top
+ );
+#if 0 /* libtpms added */
+LIB_EXPORT bigNum
+BnClearTop(
+ bigNum bn
+ );
+#endif /* libtpms added */
+LIB_EXPORT bigNum
+BnInitializeWord(
+ bigNum bn, // IN:
+ crypt_uword_t allocated, // IN:
+ crypt_uword_t word // IN:
+ );
+LIB_EXPORT bigNum
+BnInit(
+ bigNum bn,
+ crypt_uword_t allocated
+ );
+LIB_EXPORT BOOL
+BnCopy(
+ bigNum out,
+ bigConst in
+ );
+#if 0 /* libtpms added */
+LIB_EXPORT BOOL
+BnPointCopy(
+ bigPoint pOut,
+ pointConst pIn
+ );
+#endif /* libtpms added */
+LIB_EXPORT bn_point_t *
+BnInitializePoint(
+ bigPoint p, // OUT: structure to receive pointers
+ bigNum x, // IN: x coordinate
+ bigNum y, // IN: y coordinate
+ bigNum z // IN: x coordinate
+ );
+
+
+#endif
diff --git a/src/tpm2/crypto/openssl/BnValues.h b/src/tpm2/crypto/openssl/BnValues.h
new file mode 100644
index 0000000..1e0164d
--- /dev/null
+++ b/src/tpm2/crypto/openssl/BnValues.h
@@ -0,0 +1,329 @@
+/********************************************************************************/
+/* */
+/* For defining the internal BIGNUM structure */
+/* Written by Ken Goldman */
+/* IBM Thomas J. Watson Research Center */
+/* $Id: BnValues.h 1658 2021-01-22 23:14:01Z kgoldman $ */
+/* */
+/* Licenses and Notices */
+/* */
+/* 1. Copyright Licenses: */
+/* */
+/* - Trusted Computing Group (TCG) grants to the user of the source code in */
+/* this specification (the "Source Code") a worldwide, irrevocable, */
+/* nonexclusive, royalty free, copyright license to reproduce, create */
+/* derivative works, distribute, display and perform the Source Code and */
+/* derivative works thereof, and to grant others the rights granted herein. */
+/* */
+/* - The TCG grants to the user of the other parts of the specification */
+/* (other than the Source Code) the rights to reproduce, distribute, */
+/* display, and perform the specification solely for the purpose of */
+/* developing products based on such documents. */
+/* */
+/* 2. Source Code Distribution Conditions: */
+/* */
+/* - Redistributions of Source Code must retain the above copyright licenses, */
+/* this list of conditions and the following disclaimers. */
+/* */
+/* - Redistributions in binary form must reproduce the above copyright */
+/* licenses, this list of conditions and the following disclaimers in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* 3. Disclaimers: */
+/* */
+/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
+/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
+/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
+/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
+/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
+/* information on specification licensing rights available through TCG */
+/* membership agreements. */
+/* */
+/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
+/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
+/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
+/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
+/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
+/* */
+/* - Without limitation, TCG and its members and licensors disclaim all */
+/* liability, including liability for infringement of any proprietary */
+/* rights, relating to use of information in this specification and to the */
+/* implementation of this specification, and TCG disclaims all liability for */
+/* cost of procurement of substitute goods or services, lost profits, loss */
+/* of use, loss of data or any incidental, consequential, direct, indirect, */
+/* or special damages, whether under contract, tort, warranty or otherwise, */
+/* arising in any way out of use or reliance upon this specification or any */
+/* information herein. */
+/* */
+/* (c) Copyright IBM Corp. and others, 2016 - 2021 */
+/* */
+/********************************************************************************/
+
+/* 10.1.1 BnValues.h */
+/* This file contains the definitions needed for defining the internal BIGNUM structure. A BIGNUM is
+ a pointer to a structure. The structure has three fields. The last field is and array (d) of
+ crypt_uword_t. Each word is in machine format (big- or little-endian) with the words in ascending
+ significance (i.e. words in little-endian order). This is the order that seems to be used in
+ every big number library in the worlds, so... */
+/* The first field in the structure (allocated) is the number of words in d. This is the upper limit
+ on the size of the number that can be held in the structure. This differs from libraries like
+ OpenSSL() as this is not intended to deal with numbers of arbitrary size; just numbers that are
+ needed to deal with the algorithms that are defined in the TPM implementation. */
+/* The second field in the structure (size) is the number of significant words in n. When this
+ number is zero, the number is zero. The word at used-1 should never be zero. All words between
+ d[size] and d[allocated-1] should be zero. */
+#ifndef _BN_NUMBERS_H
+#define _BN_NUMBERS_H
+#if RADIX_BITS == 64
+# define RADIX_LOG2 6
+#elif RADIX_BITS == 32
+#define RADIX_LOG2 5
+#else
+# error "Unsupported radix"
+#endif
+#define RADIX_MOD(x) ((x) & ((1 << RADIX_LOG2) - 1))
+#define RADIX_DIV(x) ((x) >> RADIX_LOG2)
+#define RADIX_MASK ((((crypt_uword_t)1) << RADIX_LOG2) - 1)
+#define BITS_TO_CRYPT_WORDS(bits) RADIX_DIV((bits) + (RADIX_BITS - 1))
+#define BYTES_TO_CRYPT_WORDS(bytes) BITS_TO_CRYPT_WORDS(bytes * 8)
+#define SIZE_IN_CRYPT_WORDS(thing) BYTES_TO_CRYPT_WORDS(sizeof(thing))
+#if RADIX_BITS == 64
+#define SWAP_CRYPT_WORD(x) REVERSE_ENDIAN_64(x)
+typedef uint64_t crypt_uword_t;
+typedef int64_t crypt_word_t;
+# define TO_CRYPT_WORD_64 BIG_ENDIAN_BYTES_TO_UINT64
+# define TO_CRYPT_WORD_32(a, b, c, d) TO_CRYPT_WORD_64(0, 0, 0, 0, a, b, c, d)
+#define BN_PAD 0 /* libtpms added */
+#elif RADIX_BITS == 32
+#define SWAP_CRYPT_WORD(x) REVERSE_ENDIAN_32((x))
+typedef uint32_t crypt_uword_t;
+typedef int32_t crypt_word_t;
+# define TO_CRYPT_WORD_64(a, b, c, d, e, f, g, h) \
+ BIG_ENDIAN_BYTES_TO_UINT32(e, f, g, h), \
+ BIG_ENDIAN_BYTES_TO_UINT32(a, b, c, d)
+# define TO_CRYPT_WORD_32 BIG_ENDIAN_BYTES_TO_UINT32
+#define BN_PAD 1 /* libtpms added */
+#endif
+#define MAX_CRYPT_UWORD (~((crypt_uword_t)0))
+#define MAX_CRYPT_WORD ((crypt_word_t)(MAX_CRYPT_UWORD >> 1))
+#define MIN_CRYPT_WORD (~MAX_CRYPT_WORD)
+#define LARGEST_NUMBER (MAX((ALG_RSA * MAX_RSA_KEY_BYTES), \
+ MAX((ALG_ECC * MAX_ECC_KEY_BYTES), MAX_DIGEST_SIZE)))
+#define LARGEST_NUMBER_BITS (LARGEST_NUMBER * 8)
+#define MAX_ECC_PARAMETER_BYTES (MAX_ECC_KEY_BYTES * ALG_ECC)
+/* These are the basic big number formats. This is convertible to the library- specific format
+ without too much difficulty. For the math performed using these numbers, the value is always
+ positive. */
+#define BN_STRUCT_DEF(count) struct { \
+ crypt_uword_t allocated; \
+ crypt_uword_t size; \
+ crypt_uword_t d[count + BN_PAD + BN_PAD + BN_PAD]; /* libtpms changed */ \
+ }
+typedef BN_STRUCT_DEF(1) bignum_t;
+#ifndef bigNum
+typedef bignum_t *bigNum;
+typedef const bignum_t *bigConst;
+#endif
+extern const bignum_t BnConstZero;
+/* The Functions to access the properties of a big number. Get number of allocated words */
+#define BnGetAllocated(x) (unsigned)((x)->allocated)
+/* Get number of words used */
+#define BnGetSize(x) ((x)->size)
+/* Get a pointer to the data array */
+#define BnGetArray(x) ((crypt_uword_t *)&((x)->d[0]))
+/* Get the nth word of a BIGNUM (zero-based) */
+#define BnGetWord(x, i) (crypt_uword_t)((x)->d[i])
+/* Some things that are done often. Test to see if a bignum_t is equal to zero */
+#define BnEqualZero(bn) (BnGetSize(bn) == 0)
+/* Test to see if a bignum_t is equal to a word type */
+#define BnEqualWord(bn, word) \
+ ((BnGetSize(bn) == 1) && (BnGetWord(bn, 0) == (crypt_uword_t)word))
+/* Determine if a BIGNUM is even. A zero is even. Although the indication that a number is zero is
+ that its size is zero, all words of the number are 0 so this test works on zero. */
+#define BnIsEven(n) ((BnGetWord(n, 0) & 1) == 0)
+/* The macros below are used to define BIGNUM values of the required size. The values are allocated
+ on the stack so they can be treated like simple local values. This will call the initialization
+ function for a defined bignum_t. This sets the allocated and used fields and clears the words of
+ n. */
+#define BN_INIT(name) \
+ (bigNum)BnInit((bigNum)&(name), \
+ BYTES_TO_CRYPT_WORDS(sizeof(name.d)))
+/* In some cases, a function will need the address of the structure associated with a variable. The
+ structure for a BIGNUM variable of name is name_. Generally, when the structure is created, it is
+ initialized and a parameter is created with a pointer to the structure. The pointer has the name
+ and the structure it points to is name_ */
+#define BN_ADDRESS(name) (bigNum)&name##_
+
+#define BN_CONST(name, words, initializer) \
+ typedef const struct name##_type { \
+ crypt_uword_t allocated; \
+ crypt_uword_t size; \
+ crypt_uword_t d[words < 1 ? 1 : words]; \
+ } name##_type; \
+ name##_type name = {(words < 1 ? 1 : words), words, {initializer}};
+
+#define BN_STRUCT_ALLOCATION(bits) (BITS_TO_CRYPT_WORDS(bits) + 1)
+/* Create a structure of the correct size. */
+#define BN_STRUCT(bits) \
+ BN_STRUCT_DEF(BN_STRUCT_ALLOCATION(bits))
+/* Define a BIGNUM type with a specific allocation */
+#define BN_TYPE(name, bits) \
+ typedef BN_STRUCT(bits) bn_##name##_t
+/* This creates a local BIGNUM variable of a specific size and initializes it from a TPM2B input
+ parameter. */
+#define BN_INITIALIZED(name, bits, initializer) \
+ BN_STRUCT(bits) name##_; \
+ bigNum name = BnFrom2B(BN_INIT(name##_), \
+ (const TPM2B *)initializer)
+/* Create a local variable that can hold a number with bits */
+#define BN_VAR(name, bits) \
+ BN_STRUCT(bits) _##name; \
+ bigNum name = BN_INIT(_##name)
+/* Create a type that can hold the largest number defined by the implementation. */
+#define BN_MAX(name) BN_VAR(name, LARGEST_NUMBER_BITS)
+#define BN_MAX_INITIALIZED(name, initializer) \
+ BN_INITIALIZED(name, LARGEST_NUMBER_BITS, initializer)
+/* A word size value is useful */
+#define BN_WORD(name) BN_VAR(name, RADIX_BITS)
+/* This is used to create a word-size BIGNUM and initialize it with an input parameter to a
+ function. */
+#define BN_WORD_INITIALIZED(name, initial) \
+ BN_STRUCT(RADIX_BITS) name##_; \
+ bigNum name = BnInitializeWord((bigNum)&name##_, \
+ BN_STRUCT_ALLOCATION(RADIX_BITS), initial)
+/* ECC-Specific Values This is the format for a point. It is always in affine format. The Z value is
+ carried as part of the point, primarily to simplify the interface to the support library. Rather
+ than have the interface layer have to create space for the point each time it is used... The x,
+ y, and z values are pointers to bigNum values and not in-line versions of the numbers. This is a
+ relic of the days when there was no standard TPM format for the numbers */
+typedef struct _bn_point_t
+{
+ bigNum x;
+ bigNum y;
+ bigNum z;
+} bn_point_t;
+typedef bn_point_t *bigPoint;
+typedef const bn_point_t *pointConst;
+typedef struct constant_point_t
+{
+ bigConst x;
+ bigConst y;
+ bigConst z;
+} constant_point_t;
+#define ECC_BITS (MAX_ECC_KEY_BYTES * 8)
+BN_TYPE(ecc, ECC_BITS);
+#define ECC_NUM(name) BN_VAR(name, ECC_BITS)
+#define ECC_INITIALIZED(name, initializer) \
+ BN_INITIALIZED(name, ECC_BITS, initializer)
+#define POINT_INSTANCE(name, bits) \
+ BN_STRUCT (bits) name##_x = \
+ {BITS_TO_CRYPT_WORDS ( bits ), 0,{0}}; \
+ BN_STRUCT ( bits ) name##_y = \
+ {BITS_TO_CRYPT_WORDS ( bits ), 0,{0}}; \
+ BN_STRUCT ( bits ) name##_z = \
+ {BITS_TO_CRYPT_WORDS ( bits ), 0,{0}}; \
+ bn_point_t name##_
+#define POINT_INITIALIZER(name) \
+ BnInitializePoint(&name##_, (bigNum)&name##_x, \
+ (bigNum)&name##_y, (bigNum)&name##_z)
+#define POINT_INITIALIZED(name, initValue) \
+ POINT_INSTANCE(name, MAX_ECC_KEY_BITS); \
+ bigPoint name = BnPointFrom2B( \
+ POINT_INITIALIZER(name), \
+ initValue)
+#define POINT_VAR(name, bits) \
+ POINT_INSTANCE (name, bits); \
+ bigPoint name = POINT_INITIALIZER(name)
+#define POINT(name) POINT_VAR(name, MAX_ECC_KEY_BITS)
+/* Structure for the curve parameters. This is an analog to the TPMS_ALGORITHM_DETAIL_ECC */
+typedef struct
+{
+ bigConst prime; // a prime number
+ bigConst order; // the order of the curve
+ bigConst h; // cofactor
+ bigConst a; // linear coefficient
+ bigConst b; // constant term
+ constant_point_t base; // base point
+} ECC_CURVE_DATA;
+/* Access macros for the ECC_CURVE structure. The parameter C is a pointer to an ECC_CURVE_DATA
+ structure. In some libraries, the curve structure contains a pointer to an ECC_CURVE_DATA
+ structure as well as some other bits. For those cases, the AccessCurveData() macro is used in the
+ code to first get the pointer to the ECC_CURVE_DATA for access. In some cases, the macro does
+ nothing. */
+#define CurveGetPrime(C) ((C)->prime)
+#define CurveGetOrder(C) ((C)->order)
+#define CurveGetCofactor(C) ((C)->h)
+#define CurveGet_a(C) ((C)->a)
+#define CurveGet_b(C) ((C)->b)
+#define CurveGetG(C) ((pointConst)&((C)->base))
+#define CurveGetGx(C) ((C)->base.x)
+#define CurveGetGy(C) ((C)->base.y)
+/* Convert bytes in initializers according to the endianness of the system. This is used for
+ CryptEccData.c. */
+#define BIG_ENDIAN_BYTES_TO_UINT32(a, b, c, d) \
+ ( ((UINT32)(a) << 24) \
+ + ((UINT32)(b) << 16) \
+ + ((UINT32)(c) << 8) \
+ + ((UINT32)(d)) \
+ )
+#define BIG_ENDIAN_BYTES_TO_UINT64(a, b, c, d, e, f, g, h) \
+ ( ((UINT64)(a) << 56) \
+ + ((UINT64)(b) << 48) \
+ + ((UINT64)(c) << 40) \
+ + ((UINT64)(d) << 32) \
+ + ((UINT64)(e) << 24) \
+ + ((UINT64)(f) << 16) \
+ + ((UINT64)(g) << 8) \
+ + ((UINT64)(h)) \
+ )
+
+#ifndef RADIX_BYTES
+# if RADIX_BITS == 32
+# define RADIX_BYTES 4
+# elif RADIX_BITS == 64
+# define RADIX_BYTES 8
+# else
+# error "RADIX_BITS must either be 32 or 64"
+# endif
+#endif
+
+/* These macros are used for data initialization of big number ECC constants These two macros
+ combine a macro for data definition with a macro for structure initialization. The a parameter is
+ a macro that gives numbers to each of the bytes of the initializer and defines where each of the
+ numberd bytes will show up in the final structure. The b value is a structure that contains the
+ requisite number of bytes in big endian order. S, the MJOIN and JOIND macros will combine a macro
+ defining a data layout with a macro defining the data to be places. Generally, these macros will
+ only need expansion when CryptEccData().c gets compiled. */
+#define JOINED(a,b) a b
+#define MJOIN(a,b) a b
+
+#define B4_TO_BN(a, b, c, d) (((((a << 8) + b) << 8) + c) + d)
+#if RADIX_BYTES == 64
+#define B8_TO_BN(a, b, c, d, e, f, g, h) \
+ (UINT64)(((((((((((((((a) << 8) | b) << 8) | c) << 8) | d) << 8) \
+ e) << 8) | f) << 8) | g) << 8) | h)
+#define B1_TO_BN(a) B8_TO_BN(0, 0, 0, 0, 0, 0, 0, a)
+#define B2_TO_BN(a, b) B8_TO_BN(0, 0, 0, 0, 0, 0, a, b)
+#define B3_TO_BN(a, b, c) B8_TO_BN(0, 0, 0, 0, 0, a, b, c)
+#define B4_TO_BN(a, b, c, d) B8_TO_BN(0, 0, 0, 0, a, b, c, d)
+#define B5_TO_BN(a, b, c, d, e) B8_TO_BN(0, 0, 0, a, b, c, d, e)
+#define B6_TO_BN(a, b, c, d, e, f) B8_TO_BN(0, 0, a, b, c, d, e, f)
+#define B7_TO_BN(a, b, c, d, e, f, g) B8_TO_BN(0, a, b, c, d, e, f, g)
+#else
+#define B1_TO_BN(a) B4_TO_BN(0, 0, 0, a)
+#define B2_TO_BN(a, b) B4_TO_BN(0, 0, a, b)
+#define B3_TO_BN(a, b, c) B4_TO_BN(0, a, b, c)
+#define B4_TO_BN(a, b, c, d) (((((a << 8) + b) << 8) + c) + d)
+#define B5_TO_BN(a, b, c, d, e) B4_TO_BN(b, c, d, e), B1_TO_BN(a)
+#define B6_TO_BN(a, b, c, d, e, f) B4_TO_BN(c, d, e, f), B2_TO_BN(a, b)
+#define B7_TO_BN(a, b, c, d, e, f, g) B4_TO_BN(d, e, f, g), B3_TO_BN(a, b, c)
+#define B8_TO_BN(a, b, c, d, e, f, g, h) B4_TO_BN(e, f, g, h), B4_TO_BN(a, b, c, d)
+
+#endif
+
+/* Add implementation dependent definitions for other ECC Values and for linkages */
+
+#include LIB_INCLUDE(MATH_LIB, Math)
+
+#endif // _BN_NUMBERS_H
+
diff --git a/src/tpm2/crypto/openssl/ConsttimeUtils.h b/src/tpm2/crypto/openssl/ConsttimeUtils.h
new file mode 100644
index 0000000..3364bee
--- /dev/null
+++ b/src/tpm2/crypto/openssl/ConsttimeUtils.h
@@ -0,0 +1,117 @@
+/********************************************************************************/
+/* */
+/* Constant time debugging helper functions */
+/* Written by Stefan Berger */
+/* IBM Thomas J. Watson Research Center */
+/* */
+/* Licenses and Notices */
+/* */
+/* 1. Copyright Licenses: */
+/* */
+/* - Trusted Computing Group (TCG) grants to the user of the source code in */
+/* this specification (the "Source Code") a worldwide, irrevocable, */
+/* nonexclusive, royalty free, copyright license to reproduce, create */
+/* derivative works, distribute, display and perform the Source Code and */
+/* derivative works thereof, and to grant others the rights granted herein. */
+/* */
+/* - The TCG grants to the user of the other parts of the specification */
+/* (other than the Source Code) the rights to reproduce, distribute, */
+/* display, and perform the specification solely for the purpose of */
+/* developing products based on such documents. */
+/* */
+/* 2. Source Code Distribution Conditions: */
+/* */
+/* - Redistributions of Source Code must retain the above copyright licenses, */
+/* this list of conditions and the following disclaimers. */
+/* */
+/* - Redistributions in binary form must reproduce the above copyright */
+/* licenses, this list of conditions and the following disclaimers in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* 3. Disclaimers: */
+/* */
+/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
+/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
+/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
+/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
+/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
+/* information on specification licensing rights available through TCG */
+/* membership agreements. */
+/* */
+/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
+/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
+/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
+/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
+/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
+/* */
+/* - Without limitation, TCG and its members and licensors disclaim all */
+/* liability, including liability for infringement of any proprietary */
+/* rights, relating to use of information in this specification and to the */
+/* implementation of this specification, and TCG disclaims all liability for */
+/* cost of procurement of substitute goods or services, lost profits, loss */
+/* of use, loss of data or any incidental, consequential, direct, indirect, */
+/* or special damages, whether under contract, tort, warranty or otherwise, */
+/* arising in any way out of use or reliance upon this specification or any */
+/* information herein. */
+/* */
+/* (c) Copyright IBM Corp. and others, 2020 */
+/* */
+/********************************************************************************/
+
+#ifndef CONSTTIME_UTILS_H
+#define CONSTTIME_UTILS_H
+
+#include <assert.h>
+#include <stdio.h>
+
+#include "BnValues.h"
+
+#include <openssl/bn.h>
+
+static __inline__ unsigned long long rdtsc() {
+ unsigned long h, l;
+
+ __asm__ __volatile__ ("rdtsc" : "=a"(l), "=d"(h));
+
+ return (unsigned long long)l |
+ ((unsigned long long)h << 32 );
+}
+
+// Make sure that the given BIGNUM has the given number of expected bytes.
+// Skip over any leading zeros the BIGNUM may have.
+static inline void assert_ossl_num_bytes(const BIGNUM *a,
+ unsigned int num_bytes,
+ int verbose,
+ const char *caller) {
+ unsigned char buffer[LARGEST_NUMBER] = { 0, };
+ int len, i;
+
+ len = BN_bn2bin(a, buffer);
+ for (i = 0; i < len; i++) {
+ if (buffer[i])
+ break;
+ }
+ len -= i;
+ if (num_bytes != (unsigned int)len) {
+ printf("%s: Expected %u bytes but found %d (caller: %s)\n", __func__, num_bytes, len, caller);
+ } else {
+ if (verbose)
+ printf("%s: check passed; num_bytes = %d (caller: %s)\n",__func__, num_bytes, caller);
+ }
+ assert(num_bytes == (unsigned int)len);
+}
+
+// Make sure that the bigNum has the expected number of bytes after it was
+// converted to an OpenSSL BIGNUM.
+static inline void assert_bn_ossl_num_bytes(bigNum tpmb,
+ unsigned int num_bytes,
+ int verbose,
+ const char *caller) {
+ BIG_INITIALIZED(osslb, tpmb);
+
+ assert_ossl_num_bytes(osslb, num_bytes, verbose, caller);
+
+ BN_free(osslb);
+}
+
+#endif /* CONSTTIME_UTILS_H */
diff --git a/src/tpm2/crypto/openssl/CryptCmac.c b/src/tpm2/crypto/openssl/CryptCmac.c
new file mode 100644
index 0000000..0461e78
--- /dev/null
+++ b/src/tpm2/crypto/openssl/CryptCmac.c
@@ -0,0 +1,210 @@
+/********************************************************************************/
+/* */
+/* Message Authentication Codes Based on a Symmetric Block Cipher */
+/* Written by Ken Goldman */
+/* IBM Thomas J. Watson Research Center */
+/* $Id: CryptCmac.c 1658 2021-01-22 23:14:01Z kgoldman $ */
+/* */
+/* Licenses and Notices */
+/* */
+/* 1. Copyright Licenses: */
+/* */
+/* - Trusted Computing Group (TCG) grants to the user of the source code in */
+/* this specification (the "Source Code") a worldwide, irrevocable, */
+/* nonexclusive, royalty free, copyright license to reproduce, create */
+/* derivative works, distribute, display and perform the Source Code and */
+/* derivative works thereof, and to grant others the rights granted herein. */
+/* */
+/* - The TCG grants to the user of the other parts of the specification */
+/* (other than the Source Code) the rights to reproduce, distribute, */
+/* display, and perform the specification solely for the purpose of */
+/* developing products based on such documents. */
+/* */
+/* 2. Source Code Distribution Conditions: */
+/* */
+/* - Redistributions of Source Code must retain the above copyright licenses, */
+/* this list of conditions and the following disclaimers. */
+/* */
+/* - Redistributions in binary form must reproduce the above copyright */
+/* licenses, this list of conditions and the following disclaimers in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* 3. Disclaimers: */
+/* */
+/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
+/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
+/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
+/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
+/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
+/* information on specification licensing rights available through TCG */
+/* membership agreements. */
+/* */
+/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
+/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
+/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
+/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
+/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
+/* */
+/* - Without limitation, TCG and its members and licensors disclaim all */
+/* liability, including liability for infringement of any proprietary */
+/* rights, relating to use of information in this specification and to the */
+/* implementation of this specification, and TCG disclaims all liability for */
+/* cost of procurement of substitute goods or services, lost profits, loss */
+/* of use, loss of data or any incidental, consequential, direct, indirect, */
+/* or special damages, whether under contract, tort, warranty or otherwise, */
+/* arising in any way out of use or reliance upon this specification or any */
+/* information herein. */
+/* */
+/* (c) Copyright IBM Corp. and others, 2018 - 2021 */
+/* */
+/********************************************************************************/
+
+/* 10.2.6 CryptCmac.c */
+/* 10.2.6.1 Introduction */
+/* This file contains the implementation of the message authentication codes based on a symmetric
+ block cipher. These functions only use the single block encryption functions of the selected
+ symmetric cryptographic library. */
+/* 10.2.6.2 Includes, Defines, and Typedefs */
+#define _CRYPT_HASH_C_
+#include "Tpm.h"
+#include "CryptSym.h"
+#if ALG_CMAC
+ /* 10.2.6.3 Functions */
+ /* 10.2.6.3.1 CryptCmacStart() */
+ /* This is the function to start the CMAC sequence operation. It initializes the dispatch
+ functions for the data and end operations for CMAC and initializes the parameters that are
+ used for the processing of data, including the key, key size and block cipher algorithm. */
+UINT16
+CryptCmacStart(
+ SMAC_STATE *state,
+ TPMU_PUBLIC_PARMS *keyParms,
+ TPM_ALG_ID macAlg,
+ TPM2B *key
+ )
+{
+ tpmCmacState_t *cState = &state->state.cmac;
+ TPMT_SYM_DEF_OBJECT *def = &keyParms->symDetail.sym;
+ //
+ if(macAlg != TPM_ALG_CMAC)
+ return 0;
+ MemorySet(cState, 0, sizeof(*cState)); // libtpms bugfix
+ // set up the encryption algorithm and parameters
+ cState->symAlg = def->algorithm;
+ cState->keySizeBits = def->keyBits.sym;
+ cState->iv.t.size = CryptGetSymmetricBlockSize(def->algorithm,
+ def->keyBits.sym);
+ MemoryCopy2B(&cState->symKey.b, key, sizeof(cState->symKey.t.buffer));
+ // Set up the dispatch methods for the CMAC
+ state->smacMethods.data = CryptCmacData;
+ state->smacMethods.end = CryptCmacEnd;
+ return cState->iv.t.size;
+}
+
+/* 10.2.5.3.2 CryptCmacData() */
+/* This function is used to add data to the CMAC sequence computation. The function will XOR new
+ data into the IV. If the buffer is full, and there is additional input data, the data is
+ encrypted into the IV buffer, the new data is then XOR into the IV. When the data runs out, the
+ function returns without encrypting even if the buffer is full. The last data block of a sequence
+ will not be encrypted until the call to CryptCmacEnd(). This is to allow the proper subkey to be
+ computed and applied before the last block is encrypted. */
+void
+CryptCmacData(
+ SMAC_STATES *state,
+ UINT32 size,
+ const BYTE *buffer
+ )
+{
+ tpmCmacState_t *cmacState = &state->cmac;
+ TPM_ALG_ID algorithm = cmacState->symAlg;
+ BYTE *key = cmacState->symKey.t.buffer;
+ UINT16 keySizeInBits = cmacState->keySizeBits;
+ tpmCryptKeySchedule_t keySchedule;
+ TpmCryptSetSymKeyCall_t encrypt;
+ //
+ memset(&keySchedule, 0, sizeof(keySchedule)); /* libtpms added: coverity */
+ // Set up the encryption values based on the algorithm
+ switch (algorithm)
+ {
+ FOR_EACH_SYM(ENCRYPT_CASE)
+ default:
+ FAIL(FATAL_ERROR_INTERNAL);
+ }
+ while(size > 0)
+ {
+ if(cmacState->bcount == cmacState->iv.t.size)
+ {
+ ENCRYPT(&keySchedule, cmacState->iv.t.buffer, cmacState->iv.t.buffer);
+ cmacState->bcount = 0;
+ }
+ for(;(size > 0) && (cmacState->bcount < cmacState->iv.t.size);
+ size--, cmacState->bcount++)
+ {
+ cmacState->iv.t.buffer[cmacState->bcount] ^= *buffer++;
+ }
+ }
+}
+
+/* 10.2.6.3.3 CryptCmacEnd() */
+/* This is the completion function for the CMAC. It does padding, if needed, and selects the subkey
+ to be applied before the last block is encrypted. */
+UINT16
+CryptCmacEnd(
+ SMAC_STATES *state,
+ UINT32 outSize,
+ BYTE *outBuffer
+ )
+{
+ tpmCmacState_t *cState = &state->cmac;
+ // Need to set algorithm, key, and keySizeInBits in the local context so that
+ // the SELECT and ENCRYPT macros will work here
+ TPM_ALG_ID algorithm = cState->symAlg;
+ BYTE *key = cState->symKey.t.buffer;
+ UINT16 keySizeInBits = cState->keySizeBits;
+ tpmCryptKeySchedule_t keySchedule;
+ TpmCryptSetSymKeyCall_t encrypt;
+ TPM2B_IV subkey = {{0, {0}}};
+ BOOL xorVal;
+ UINT16 i;
+ memset(&keySchedule, 0, sizeof(keySchedule)); /* libtpms added: coverity */
+
+ subkey.t.size = cState->iv.t.size;
+ // Encrypt a block of zero
+ // Set up the encryption values based on the algorithm
+ switch (algorithm)
+ {
+ FOR_EACH_SYM(ENCRYPT_CASE)
+ default:
+ return 0;
+ }
+ ENCRYPT(&keySchedule, subkey.t.buffer, subkey.t.buffer);
+
+ // shift left by 1 and XOR with 0x0...87 if the MSb was 0
+ xorVal = ((subkey.t.buffer[0] & 0x80) == 0) ? 0 : 0x87;
+ ShiftLeft(&subkey.b);
+ subkey.t.buffer[subkey.t.size - 1] ^= xorVal;
+ // this is a sanity check to make sure that the algorithm is working properly.
+ // remove this check when debug is done
+ pAssert(cState->bcount <= cState->iv.t.size);
+ // If the buffer is full then no need to compute subkey 2.
+ if(cState->bcount < cState->iv.t.size)
+ {
+ //Pad the data
+ cState->iv.t.buffer[cState->bcount++] ^= 0x80;
+ // The rest of the data is a pad of zero which would simply be XORed
+ // with the iv value so nothing to do...
+ // Now compute K2
+ xorVal = ((subkey.t.buffer[0] & 0x80) == 0) ? 0 : 0x87;
+ ShiftLeft(&subkey.b);
+ subkey.t.buffer[subkey.t.size - 1] ^= xorVal;
+ }
+ // XOR the subkey into the IV
+ for(i = 0; i < subkey.t.size; i++)
+ cState->iv.t.buffer[i] ^= subkey.t.buffer[i];
+ ENCRYPT(&keySchedule, cState->iv.t.buffer, cState->iv.t.buffer);
+ i = (UINT16)MIN(cState->iv.t.size, outSize);
+ MemoryCopy(outBuffer, cState->iv.t.buffer, i);
+
+ return i;
+}
+
+#endif
diff --git a/src/tpm2/crypto/openssl/CryptDes.c b/src/tpm2/crypto/openssl/CryptDes.c
new file mode 100644
index 0000000..9efa3ce
--- /dev/null
+++ b/src/tpm2/crypto/openssl/CryptDes.c
@@ -0,0 +1,189 @@
+/********************************************************************************/
+/* */
+/* Functions Required for TDES */
+/* Written by Ken Goldman */
+/* IBM Thomas J. Watson Research Center */
+/* $Id: CryptDes.c 1398 2018-12-17 22:37:57Z kgoldman $ */
+/* */
+/* Licenses and Notices */
+/* */
+/* 1. Copyright Licenses: */
+/* */
+/* - Trusted Computing Group (TCG) grants to the user of the source code in */
+/* this specification (the "Source Code") a worldwide, irrevocable, */
+/* nonexclusive, royalty free, copyright license to reproduce, create */
+/* derivative works, distribute, display and perform the Source Code and */
+/* derivative works thereof, and to grant others the rights granted herein. */
+/* */
+/* - The TCG grants to the user of the other parts of the specification */
+/* (other than the Source Code) the rights to reproduce, distribute, */
+/* display, and perform the specification solely for the purpose of */
+/* developing products based on such documents. */
+/* */
+/* 2. Source Code Distribution Conditions: */
+/* */
+/* - Redistributions of Source Code must retain the above copyright licenses, */
+/* this list of conditions and the following disclaimers. */
+/* */
+/* - Redistributions in binary form must reproduce the above copyright */
+/* licenses, this list of conditions and the following disclaimers in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* 3. Disclaimers: */
+/* */
+/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
+/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
+/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
+/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
+/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
+/* information on specification licensing rights available through TCG */
+/* membership agreements. */
+/* */
+/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
+/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
+/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
+/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
+/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
+/* */
+/* - Without limitation, TCG and its members and licensors disclaim all */
+/* liability, including liability for infringement of any proprietary */
+/* rights, relating to use of information in this specification and to the */
+/* implementation of this specification, and TCG disclaims all liability for */
+/* cost of procurement of substitute goods or services, lost profits, loss */
+/* of use, loss of data or any incidental, consequential, direct, indirect, */
+/* or special damages, whether under contract, tort, warranty or otherwise, */
+/* arising in any way out of use or reliance upon this specification or any */
+/* information herein. */
+/* */
+/* (c) Copyright IBM Corp. and others, 2016 - 2018 */
+/* */
+/********************************************************************************/
+
+/* 10.2.9 CryptDes.c */
+/* 10.2.9.1 Introduction */
+/* This file contains the extra functions required for TDES. */
+/* 10.2.9.2 Includes, Defines, and Typedefs */
+#include "Tpm.h"
+#include "Helpers_fp.h" // libtpms added
+#if ALG_TDES
+#define DES_NUM_WEAK 64
+const UINT64 DesWeakKeys[DES_NUM_WEAK] = {
+ 0x0101010101010101ULL, 0xFEFEFEFEFEFEFEFEULL, 0xE0E0E0E0F1F1F1F1ULL, 0x1F1F1F1F0E0E0E0EULL,
+ 0x011F011F010E010EULL, 0x1F011F010E010E01ULL, 0x01E001E001F101F1ULL, 0xE001E001F101F101ULL,
+ 0x01FE01FE01FE01FEULL, 0xFE01FE01FE01FE01ULL, 0x1FE01FE00EF10EF1ULL, 0xE01FE01FF10EF10EULL,
+ 0x1FFE1FFE0EFE0EFEULL, 0xFE1FFE1FFE0EFE0EULL, 0xE0FEE0FEF1FEF1FEULL, 0xFEE0FEE0FEF1FEF1ULL,
+ 0x01011F1F01010E0EULL, 0x1F1F01010E0E0101ULL, 0xE0E01F1FF1F10E0EULL, 0x0101E0E00101F1F1ULL,
+ 0x1F1FE0E00E0EF1F1ULL, 0xE0E0FEFEF1F1FEFEULL, 0x0101FEFE0101FEFEULL, 0x1F1FFEFE0E0EFEFEULL,
+ 0xE0FE011FF1FE010EULL, 0x011F1F01010E0E01ULL, 0x1FE001FE0EF101FEULL, 0xE0FE1F01F1FE0E01ULL,
+ 0x011FE0FE010EF1FEULL, 0x1FE0E01F0EF1F10EULL, 0xE0FEFEE0F1FEFEF1ULL, 0x011FFEE0010EFEF1ULL,
+ 0x1FE0FE010EF1FE01ULL, 0xFE0101FEFE0101FEULL, 0x01E01FFE01F10EFEULL, 0x1FFE01E00EFE01F1ULL,
+ 0xFE011FE0FE010EF1ULL, 0xFE01E01FFE01F10EULL, 0x1FFEE0010EFEF101ULL, 0xFE1F01E0FE0E01F1ULL,
+ 0x01E0E00101F1F101ULL, 0x1FFEFE1F0EFEFE0EULL, 0xFE1FE001FE0EF101ULL, 0x01E0FE1F01F1FE0EULL,
+ 0xE00101E0F10101F1ULL, 0xFE1F1FFEFE0E0EFEULL, 0x01FE1FE001FE0EF1ULL, 0xE0011FFEF1010EFEULL,
+ 0xFEE0011FFEF1010EULL, 0x01FEE01F01FEF10EULL, 0xE001FE1FF101FE0EULL, 0xFEE01F01FEF10E01ULL,
+ 0x01FEFE0101FEFE01ULL, 0xE01F01FEF10E01FEULL, 0xFEE0E0FEFEF1F1FEULL, 0x1F01011F0E01010EULL,
+ 0xE01F1FE0F10E0EF1ULL, 0xFEFE0101FEFE0101ULL, 0x1F01E0FE0E01F1FEULL, 0xE01FFE01F10EFE01ULL,
+ 0xFEFE1F1FFEFE0E0EULL, 0x1F01FEE00E01FEF1ULL, 0xE0E00101F1F10101ULL, 0xFEFEE0E0FEFEF1F1ULL};
+/* 10.2.9.2.1 CryptSetOddByteParity() */
+/* This function sets the per byte parity of a 64-bit value. The least-significant bit is of each
+ byte is replaced with the odd parity of the other 7 bits in the byte. With odd parity, no byte
+ will ever be 0x00. */
+UINT64
+CryptSetOddByteParity(
+ UINT64 k
+ )
+{
+#define PMASK 0x0101010101010101ULL
+ UINT64 out;
+ k |= PMASK; // set the parity bit
+ out = k;
+ k ^= k >> 4;
+ k ^= k >> 2;
+ k ^= k >> 1;
+ k &= PMASK; // odd parity extracted
+ out ^= k; // out is now even parity because parity bit was already set
+ out ^= PMASK; // out is now even parity
+ return out;
+}
+/* 10.2.9.2.2 CryptDesIsWeakKey() */
+/* Check to see if a DES key is on the list of weak, semi-weak, or possibly weak keys. */
+/* Return Value Meaning */
+/* TRUE(1) DES key is weak */
+/* FALSE(0) DES key is not weak */
+static BOOL
+CryptDesIsWeakKey(
+ UINT64 k
+ )
+{
+ int i;
+ //
+ for(i = 0; i < DES_NUM_WEAK; i++)
+ {
+ if(k == DesWeakKeys[i])
+ return TRUE;
+ }
+ return FALSE;
+}
+/* 10.2.9.2.3 CryptDesValidateKey() */
+/* Function to check to see if the input key is a valid DES key where the definition of valid is
+ that none of the elements are on the list of weak, semi-weak, or possibly weak keys; and that for
+ two keys, K1!=K2, and for three keys that K1!=K2 and K2!=K3. */
+BOOL
+CryptDesValidateKey(
+ TPM2B_SYM_KEY *desKey // IN: key to validate
+ )
+{
+ UINT64 k[3];
+ int i;
+ int keys = (desKey->t.size + 7) / 8;
+ BYTE *pk = desKey->t.buffer;
+ BOOL ok;
+ //
+ // Note: 'keys' is the number of keys, not the maximum index for 'k'
+ ok = ((keys == 2) || (keys == 3)) && ((desKey->t.size % 8) == 0);
+ for(i = 0; ok && i < keys; pk += 8, i++)
+ {
+ k[i] = CryptSetOddByteParity(BYTE_ARRAY_TO_UINT64(pk));
+ ok = !CryptDesIsWeakKey(k[i]);
+ }
+ ok = ok && k[0] != k[1];
+ if(keys == 3)
+ ok = ok && k[1] != k[2];
+ return ok;
+}
+/* 10.2.9.2.4 CryptGenerateKeyDes() */
+/* This function is used to create a DES key of the appropriate size. The key will have odd parity
+ in the bytes. */
+TPM_RC
+CryptGenerateKeyDes(
+ TPMT_PUBLIC *publicArea, // IN/OUT: The public area template
+ // for the new key.
+ TPMT_SENSITIVE *sensitive, // OUT: sensitive area
+ RAND_STATE *rand // IN: the "entropy" source for
+ )
+{
+ // Assume that the publicArea key size has been validated and is a supported
+ // number of bits.
+ sensitive->sensitive.sym.t.size =
+ BITS_TO_BYTES(publicArea->parameters.symDetail.sym.keyBits.sym);
+#if USE_OPENSSL_FUNCTIONS_SYMMETRIC // libtpms added begin
+ if (rand == NULL)
+ return OpenSSLCryptGenerateKeyDes(sensitive);
+#endif // libtpms added end
+ do
+ {
+ BYTE *pK = sensitive->sensitive.sym.t.buffer;
+ int i = (sensitive->sensitive.sym.t.size + 7) / 8;
+ // Use the random number generator to generate the required number of bits
+ if(DRBG_Generate(rand, pK, sensitive->sensitive.sym.t.size) == 0)
+ return TPM_RC_NO_RESULT;
+ for(; i > 0; pK += 8, i--)
+ {
+ UINT64 k = BYTE_ARRAY_TO_UINT64(pK);
+ k = CryptSetOddByteParity(k);
+ UINT64_TO_BYTE_ARRAY(k, pK);
+ }
+ } while(!CryptDesValidateKey(&sensitive->sensitive.sym));
+ return TPM_RC_SUCCESS;
+}
+#endif
diff --git a/src/tpm2/crypto/openssl/CryptEccKeyExchange.c b/src/tpm2/crypto/openssl/CryptEccKeyExchange.c
new file mode 100644
index 0000000..4d1fccb
--- /dev/null
+++ b/src/tpm2/crypto/openssl/CryptEccKeyExchange.c
@@ -0,0 +1,373 @@
+/********************************************************************************/
+/* */
+/* Functions that are used for the two-phase, ECC, key-exchange protocols */
+/* Written by Ken Goldman */
+/* IBM Thomas J. Watson Research Center */
+/* $Id: CryptEccKeyExchange.c 1658 2021-01-22 23:14:01Z kgoldman $ */
+/* */
+/* Licenses and Notices */
+/* */
+/* 1. Copyright Licenses: */
+/* */
+/* - Trusted Computing Group (TCG) grants to the user of the source code in */
+/* this specification (the "Source Code") a worldwide, irrevocable, */
+/* nonexclusive, royalty free, copyright license to reproduce, create */
+/* derivative works, distribute, display and perform the Source Code and */
+/* derivative works thereof, and to grant others the rights granted herein. */
+/* */
+/* - The TCG grants to the user of the other parts of the specification */
+/* (other than the Source Code) the rights to reproduce, distribute, */
+/* display, and perform the specification solely for the purpose of */
+/* developing products based on such documents. */
+/* */
+/* 2. Source Code Distribution Conditions: */
+/* */
+/* - Redistributions of Source Code must retain the above copyright licenses, */
+/* this list of conditions and the following disclaimers. */
+/* */
+/* - Redistributions in binary form must reproduce the above copyright */
+/* licenses, this list of conditions and the following disclaimers in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* 3. Disclaimers: */
+/* */
+/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
+/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
+/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
+/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
+/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
+/* information on specification licensing rights available through TCG */
+/* membership agreements. */
+/* */
+/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
+/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
+/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
+/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
+/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
+/* */
+/* - Without limitation, TCG and its members and licensors disclaim all */
+/* liability, including liability for infringement of any proprietary */
+/* rights, relating to use of information in this specification and to the */
+/* implementation of this specification, and TCG disclaims all liability for */
+/* cost of procurement of substitute goods or services, lost profits, loss */
+/* of use, loss of data or any incidental, consequential, direct, indirect, */
+/* or special damages, whether under contract, tort, warranty or otherwise, */
+/* arising in any way out of use or reliance upon this specification or any */
+/* information herein. */
+/* */
+/* (c) Copyright IBM Corp. and others, 2016 - 2021 */
+/* */
+/********************************************************************************/
+
+/* 10.2.11 CryptEccKeyExchange.c */
+#include "Tpm.h"
+
+LIB_EXPORT TPM_RC
+SM2KeyExchange(
+ TPMS_ECC_POINT *outZ, // OUT: the computed point
+ TPM_ECC_CURVE curveId, // IN: the curve for the computations
+ TPM2B_ECC_PARAMETER *dsAIn, // IN: static private TPM key
+ TPM2B_ECC_PARAMETER *deAIn, // IN: ephemeral private TPM key
+ TPMS_ECC_POINT *QsBIn, // IN: static public party B key
+ TPMS_ECC_POINT *QeBIn // IN: ephemeral public party B key
+ );
+
+#if CC_ZGen_2Phase == YES
+#if ALG_ECMQV
+/* 10.2.11.1.1 avf1() */
+/* This function does the associated value computation required by MQV key exchange. Process: */
+/* a) Convert xQ to an integer xqi using the convention specified in Appendix C.3. */
+/* b) Calculate xqm = xqi mod 2^ceil(f/2) (where f = ceil(log2(n)). */
+/* c) Calculate the associate value function avf(Q) = xqm + 2ceil(f / 2) */
+/* Always returns TRUE(1). */
+static BOOL
+avf1(
+ bigNum bnX, // IN/OUT: the reduced value
+ bigNum bnN // IN: the order of the curve
+ )
+{
+ // compute f = 2^(ceil(ceil(log2(n)) / 2))
+ int f = (BnSizeInBits(bnN) + 1) / 2;
+ // x' = 2^f + (x mod 2^f)
+ BnMaskBits(bnX, f); // This is mod 2*2^f but it doesn't matter because
+ // the next operation will SET the extra bit anyway
+ BnSetBit(bnX, f);
+ return TRUE;
+}
+/* 10.2.11.1.2 C_2_2_MQV() */
+/* This function performs the key exchange defined in SP800-56A 6.1.1.4 Full MQV, C(2, 2, ECC
+ MQV). */
+/* CAUTION: Implementation of this function may require use of essential claims in patents not owned
+ by TCG members. */
+/* Points QsB() and QeB() are required to be on the curve of inQsA. The function will fail, possibly
+ catastrophically, if this is not the case. */
+/* Error Returns Meaning */
+/* TPM_RC_NO_RESULT the value for dsA does not give a valid point on the curve */
+static TPM_RC
+C_2_2_MQV(
+ TPMS_ECC_POINT *outZ, // OUT: the computed point
+ TPM_ECC_CURVE curveId, // IN: the curve for the computations
+ TPM2B_ECC_PARAMETER *dsA, // IN: static private TPM key
+ TPM2B_ECC_PARAMETER *deA, // IN: ephemeral private TPM key
+ TPMS_ECC_POINT *QsB, // IN: static public party B key
+ TPMS_ECC_POINT *QeB // IN: ephemeral public party B key
+ )
+{
+ CURVE_INITIALIZED(E, curveId);
+ const ECC_CURVE_DATA *C;
+ POINT(pQeA);
+ POINT_INITIALIZED(pQeB, QeB);
+ POINT_INITIALIZED(pQsB, QsB);
+ ECC_NUM(bnTa);
+ ECC_INITIALIZED(bnDeA, deA);
+ ECC_INITIALIZED(bnDsA, dsA);
+ ECC_NUM(bnN);
+ ECC_NUM(bnXeB);
+ TPM_RC retVal;
+ //
+ // Parameter checks
+ if(E == NULL)
+ ERROR_RETURN(TPM_RC_VALUE);
+ pAssert(outZ != NULL && pQeB != NULL && pQsB != NULL && deA != NULL
+ && dsA != NULL);
+ C = AccessCurveData(E);
+ // Process:
+ // 1. implicitsigA = (de,A + avf(Qe,A)ds,A ) mod n.
+ // 2. P = h(implicitsigA)(Qe,B + avf(Qe,B)Qs,B).
+ // 3. If P = O, output an error indicator.
+ // 4. Z=xP, where xP is the x-coordinate of P.
+ // Compute the public ephemeral key pQeA = [de,A]G
+ if((retVal = BnPointMult(pQeA, CurveGetG(C), bnDeA, NULL, NULL, E))
+ != TPM_RC_SUCCESS)
+ goto Exit;
+ // 1. implicitsigA = (de,A + avf(Qe,A)ds,A ) mod n.
+ // tA := (ds,A + de,A avf(Xe,A)) mod n (3)
+ // Compute 'tA' = ('deA' + 'dsA' avf('XeA')) mod n
+ // Ta = avf(XeA);
+ BnCopy(bnTa, pQeA->x);
+ avf1(bnTa, bnN);
+ // do Ta = ds,A * Ta mod n = dsA * avf(XeA) mod n
+ BnModMult(bnTa, bnDsA, bnTa, bnN);
+ // now Ta = deA + Ta mod n = deA + dsA * avf(XeA) mod n
+ BnAdd(bnTa, bnTa, bnDeA);
+ BnMod(bnTa, bnN);
+ // 2. P = h(implicitsigA)(Qe,B + avf(Qe,B)Qs,B).
+ // Put this in because almost every case of h is == 1 so skip the call when
+ // not necessary.
+ if(!BnEqualWord(CurveGetCofactor(C), 1))
+ // Cofactor is not 1 so compute Ta := Ta * h mod n
+ BnModMult(bnTa, bnTa, CurveGetCofactor(C), CurveGetOrder(C));
+ // Now that 'tA' is (h * 'tA' mod n)
+ // 'outZ' = (tA)(Qe,B + avf(Qe,B)Qs,B).
+ // first, compute XeB = avf(XeB)
+ avf1(bnXeB, bnN);
+ // QsB := [XeB]QsB
+ BnPointMult(pQsB, pQsB, bnXeB, NULL, NULL, E);
+ BnEccAdd(pQeB, pQeB, pQsB, E);
+ // QeB := [tA]QeB = [tA](QsB + [Xe,B]QeB) and check for at infinity
+ // If the result is not the point at infinity, return QeB
+ BnPointMult(pQeB, pQeB, bnTa, NULL, NULL, E);
+ if(BnEqualZero(pQeB->z))
+ ERROR_RETURN(TPM_RC_NO_RESULT);
+ // Convert BIGNUM E to TPM2B E
+ BnPointTo2B(outZ, pQeB, E);
+ Exit:
+ CURVE_FREE(E);
+ return retVal;
+}
+#endif // ALG_ECMQV
+/* 10.2.11.1.3 C_2_2_ECDH() */
+/* This function performs the two phase key exchange defined in SP800-56A, 6.1.1.2 Full Unified
+ Model, C(2, 2, ECC CDH). */
+static TPM_RC
+C_2_2_ECDH(
+ TPMS_ECC_POINT *outZs, // OUT: Zs
+ TPMS_ECC_POINT *outZe, // OUT: Ze
+ TPM_ECC_CURVE curveId, // IN: the curve for the computations
+ TPM2B_ECC_PARAMETER *dsA, // IN: static private TPM key
+ TPM2B_ECC_PARAMETER *deA, // IN: ephemeral private TPM key
+ TPMS_ECC_POINT *QsB, // IN: static public party B key
+ TPMS_ECC_POINT *QeB // IN: ephemeral public party B key
+ )
+{
+ CURVE_INITIALIZED(E, curveId);
+ ECC_INITIALIZED(bnAs, dsA);
+ ECC_INITIALIZED(bnAe, deA);
+ POINT_INITIALIZED(ecBs, QsB);
+ POINT_INITIALIZED(ecBe, QeB);
+ POINT(ecZ);
+ TPM_RC retVal;
+ //
+ // Parameter checks
+ if(E == NULL)
+ ERROR_RETURN(TPM_RC_CURVE);
+ pAssert(outZs != NULL && dsA != NULL && deA != NULL && QsB != NULL
+ && QeB != NULL);
+ // Do the point multiply for the Zs value ([dsA]QsB)
+ retVal = BnPointMult(ecZ, ecBs, bnAs, NULL, NULL, E);
+ if(retVal == TPM_RC_SUCCESS)
+ {
+ // Convert the Zs value.
+ BnPointTo2B(outZs, ecZ, E);
+ // Do the point multiply for the Ze value ([deA]QeB)
+ retVal = BnPointMult(ecZ, ecBe, bnAe, NULL, NULL, E);
+ if(retVal == TPM_RC_SUCCESS)
+ BnPointTo2B(outZe, ecZ, E);
+ }
+ Exit:
+ CURVE_FREE(E);
+ return retVal;
+}
+/* 10.2.11.1.4 CryptEcc2PhaseKeyExchange() */
+/* This function is the dispatch routine for the EC key exchange functions that use two ephemeral
+ and two static keys. */
+/* Error Returns Meaning */
+/* TPM_RC_SCHEME scheme is not defined */
+LIB_EXPORT TPM_RC
+CryptEcc2PhaseKeyExchange(
+ TPMS_ECC_POINT *outZ1, // OUT: a computed point
+ TPMS_ECC_POINT *outZ2, // OUT: and optional second point
+ TPM_ECC_CURVE curveId, // IN: the curve for the computations
+ TPM_ALG_ID scheme, // IN: the key exchange scheme
+ TPM2B_ECC_PARAMETER *dsA, // IN: static private TPM key
+ TPM2B_ECC_PARAMETER *deA, // IN: ephemeral private TPM key
+ TPMS_ECC_POINT *QsB, // IN: static public party B key
+ TPMS_ECC_POINT *QeB // IN: ephemeral public party B key
+ )
+{
+ pAssert(outZ1 != NULL
+ && dsA != NULL && deA != NULL
+ && QsB != NULL && QeB != NULL);
+ // Initialize the output points so that they are empty until one of the
+ // functions decides otherwise
+ outZ1->x.b.size = 0;
+ outZ1->y.b.size = 0;
+ if(outZ2 != NULL)
+ {
+ outZ2->x.b.size = 0;
+ outZ2->y.b.size = 0;
+ }
+ switch(scheme)
+ {
+ case TPM_ALG_ECDH:
+ return C_2_2_ECDH(outZ1, outZ2, curveId, dsA, deA, QsB, QeB);
+ break;
+#if ALG_ECMQV
+ case TPM_ALG_ECMQV:
+ return C_2_2_MQV(outZ1, curveId, dsA, deA, QsB, QeB);
+ break;
+#endif
+#if ALG_SM2
+ case TPM_ALG_SM2:
+ return SM2KeyExchange(outZ1, curveId, dsA, deA, QsB, QeB);
+ break;
+#endif
+ default:
+ return TPM_RC_SCHEME;
+ }
+}
+#if ALG_SM2
+/* 10.2.11.1.5 ComputeWForSM2() */
+/* Compute the value for w used by SM2 */
+static UINT32
+ComputeWForSM2(
+ bigCurve E
+ )
+{
+ // w := ceil(ceil(log2(n)) / 2) - 1
+ return (BnMsb(CurveGetOrder(AccessCurveData(E))) / 2 - 1);
+}
+/* 10.2.11.1.6 avfSm2() */
+/* This function does the associated value computation required by SM2 key exchange. This is
+ different form the avf() in the international standards because it returns a value that is half
+ the size of the value 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 means that an input value of 14 (1110b) would return a
+ value of 110b with the standard but 10b with the scheme in SM2. */
+static bigNum
+avfSm2(
+ bigNum bn, // IN/OUT: the reduced value
+ UINT32 w // IN: the value of w
+ )
+{
+ // a) set w := ceil(ceil(log2(n)) / 2) - 1
+ // b) set x' := 2^w + ( x & (2^w - 1))
+ // This is just like the avf for MQV where x' = 2^w + (x mod 2^w)
+ BnMaskBits(bn, w); // as with avf1, this is too big by a factor of 2 but
+ // it doesn't matter because we SET the extra bit
+ // anyway
+ BnSetBit(bn, w);
+ return bn;
+}
+/* SM2KeyExchange() This function performs the key exchange defined in SM2. The first step is to
+ compute tA = (dsA + deA avf(Xe,A)) mod n Then, compute the Z value from outZ = (h tA mod n) (QsA
+ + [avf(QeB().x)](QeB())). The function will compute the ephemeral public key from the ephemeral
+ private key. All points are required to be on the curve of inQsA. The function will fail
+ catastrophically if this is not the case */
+/* Error Returns Meaning */
+/* TPM_RC_NO_RESULT the value for dsA does not give a valid point on the curve */
+LIB_EXPORT TPM_RC
+SM2KeyExchange(
+ TPMS_ECC_POINT *outZ, // OUT: the computed point
+ TPM_ECC_CURVE curveId, // IN: the curve for the computations
+ TPM2B_ECC_PARAMETER *dsAIn, // IN: static private TPM key
+ TPM2B_ECC_PARAMETER *deAIn, // IN: ephemeral private TPM key
+ TPMS_ECC_POINT *QsBIn, // IN: static public party B key
+ TPMS_ECC_POINT *QeBIn // IN: ephemeral public party B key
+ )
+{
+ CURVE_INITIALIZED(E, curveId);
+ const ECC_CURVE_DATA *C;
+ ECC_INITIALIZED(dsA, dsAIn);
+ ECC_INITIALIZED(deA, deAIn);
+ POINT_INITIALIZED(QsB, QsBIn);
+ POINT_INITIALIZED(QeB, QeBIn);
+ BN_WORD_INITIALIZED(One, 1);
+ POINT(QeA);
+ ECC_NUM(XeB);
+ POINT(Z);
+ ECC_NUM(Ta);
+ UINT32 w;
+ TPM_RC retVal = TPM_RC_NO_RESULT;
+ //
+ // Parameter checks
+ if(E == NULL)
+ ERROR_RETURN(TPM_RC_CURVE);
+ C = AccessCurveData(E);
+ pAssert(outZ != NULL && dsA != NULL && deA != NULL && QsB != NULL
+ && QeB != NULL);
+ // Compute the value for w
+ w = ComputeWForSM2(E);
+ // Compute the public ephemeral key pQeA = [de,A]G
+ if(!BnEccModMult(QeA, CurveGetG(C), deA, E))
+ goto Exit;
+ // tA := (ds,A + de,A avf(Xe,A)) mod n (3)
+ // Compute 'tA' = ('dsA' + 'deA' avf('XeA')) mod n
+ // Ta = avf(XeA);
+ // do Ta = de,A * Ta = deA * avf(XeA)
+ BnMult(Ta, deA, avfSm2(QeA->x, w));
+ // now Ta = dsA + Ta = dsA + deA * avf(XeA)
+ BnAdd(Ta, dsA, Ta);
+ BnMod(Ta, CurveGetOrder(C));
+ // outZ = [h tA mod n] (Qs,B + [avf(Xe,B)](Qe,B)) (4)
+ // Put this in because almost every case of h is == 1 so skip the call when
+ // not necessary.
+ if(!BnEqualWord(CurveGetCofactor(C), 1))
+ // Cofactor is not 1 so compute Ta := Ta * h mod n
+ BnModMult(Ta, Ta, CurveGetCofactor(C), CurveGetOrder(C));
+ // Now that 'tA' is (h * 'tA' mod n)
+ // 'outZ' = ['tA'](QsB + [avf(QeB.x)](QeB)).
+ BnCopy(XeB, QeB->x);
+ if(!BnEccModMult2(Z, QsB, One, QeB, avfSm2(XeB, w), E))
+ goto Exit;
+ // QeB := [tA]QeB = [tA](QsB + [Xe,B]QeB) and check for at infinity
+ if(!BnEccModMult(Z, Z, Ta, E))
+ goto Exit;
+ // Convert BIGNUM E to TPM2B E
+ BnPointTo2B(outZ, Z, E);
+ retVal = TPM_RC_SUCCESS;
+ Exit:
+ CURVE_FREE(E);
+ return retVal;
+}
+#endif
+#endif // CC_ZGen_2Phase
diff --git a/src/tpm2/crypto/openssl/CryptEccMain.c b/src/tpm2/crypto/openssl/CryptEccMain.c
new file mode 100644
index 0000000..be92831
--- /dev/null
+++ b/src/tpm2/crypto/openssl/CryptEccMain.c
@@ -0,0 +1,866 @@
+/********************************************************************************/
+/* */
+/* ECC Main */
+/* Written by Ken Goldman */
+/* IBM Thomas J. Watson Research Center */
+/* $Id: CryptEccMain.c 1519 2019-11-15 20:43:51Z kgoldman $ */
+/* */
+/* Licenses and Notices */
+/* */
+/* 1. Copyright Licenses: */
+/* */
+/* - Trusted Computing Group (TCG) grants to the user of the source code in */
+/* this specification (the "Source Code") a worldwide, irrevocable, */
+/* nonexclusive, royalty free, copyright license to reproduce, create */
+/* derivative works, distribute, display and perform the Source Code and */
+/* derivative works thereof, and to grant others the rights granted herein. */
+/* */
+/* - The TCG grants to the user of the other parts of the specification */
+/* (other than the Source Code) the rights to reproduce, distribute, */
+/* display, and perform the specification solely for the purpose of */
+/* developing products based on such documents. */
+/* */
+/* 2. Source Code Distribution Conditions: */
+/* */
+/* - Redistributions of Source Code must retain the above copyright licenses, */
+/* this list of conditions and the following disclaimers. */
+/* */
+/* - Redistributions in binary form must reproduce the above copyright */
+/* licenses, this list of conditions and the following disclaimers in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* 3. Disclaimers: */
+/* */
+/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
+/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
+/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
+/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
+/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
+/* information on specification licensing rights available through TCG */
+/* membership agreements. */
+/* */
+/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
+/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
+/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
+/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
+/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
+/* */
+/* - Without limitation, TCG and its members and licensors disclaim all */
+/* liability, including liability for infringement of any proprietary */
+/* rights, relating to use of information in this specification and to the */
+/* implementation of this specification, and TCG disclaims all liability for */
+/* cost of procurement of substitute goods or services, lost profits, loss */
+/* of use, loss of data or any incidental, consequential, direct, indirect, */
+/* or special damages, whether under contract, tort, warranty or otherwise, */
+/* arising in any way out of use or reliance upon this specification or any */
+/* information herein. */
+/* */
+/* (c) Copyright IBM Corp. and others, 2016 - 2019 */
+/* */
+/********************************************************************************/
+
+/* 10.2.11 CryptEccMain.c */
+/* 10.2.11.1 Includes and Defines */
+#include "Tpm.h"
+#include "Helpers_fp.h" // libtpms added
+#include "TpmToOsslMath_fp.h" // libtpms added
+#if ALG_ECC
+/* This version requires that the new format for ECC data be used */
+#if !USE_BN_ECC_DATA
+#error "Need to SET USE_BN_ECC_DATA to YES in TpmBuildSwitches.h"
+#endif
+/* 10.2.11.2 Functions */
+#if SIMULATION
+void
+EccSimulationEnd(
+ void
+ )
+{
+#if SIMULATION
+ // put things to be printed at the end of the simulation here
+#endif
+}
+#endif // SIMULATION
+/* 10.2.11.2.1 CryptEccInit() */
+/* This function is called at _TPM_Init() */
+BOOL
+CryptEccInit(
+ void
+ )
+{
+ return TRUE;
+}
+/* 10.2.11.2.2 CryptEccStartup() */
+/* This function is called at TPM2_Startup(). */
+BOOL
+CryptEccStartup(
+ void
+ )
+{
+ return TRUE;
+}
+/* 10.2.11.2.3 ClearPoint2B(generic */
+/* Initialize the size values of a TPMS_ECC_POINT structure. */
+void
+ClearPoint2B(
+ TPMS_ECC_POINT *p // IN: the point
+ )
+{
+ if(p != NULL)
+ {
+ p->x.t.size = 0;
+ p->y.t.size = 0;
+ }
+}
+/* 10.2.11.2.4 CryptEccGetParametersByCurveId() */
+/* This function returns a pointer to the curve data that is associated with the indicated
+ curveId. If there is no curve with the indicated ID, the function returns NULL. This function is
+ in this module so that it can be called by GetCurve() data. */
+/* Return Values Meaning */
+/* NULL curve with the indicated TPM_ECC_CURVE is not implemented */
+/* non-NULL pointer to the curve data */
+LIB_EXPORT const ECC_CURVE *
+CryptEccGetParametersByCurveId(
+ TPM_ECC_CURVE curveId // IN: the curveID
+ )
+{
+ int i;
+ for(i = 0; i < ECC_CURVE_COUNT; i++)
+ {
+ if(eccCurves[i].curveId == curveId)
+ return &eccCurves[i];
+ }
+ return NULL;
+}
+/* 10.2.11.2.5 CryptEccGetKeySizeForCurve() */
+/* This function returns the key size in bits of the indicated curve */
+LIB_EXPORT UINT16
+CryptEccGetKeySizeForCurve(
+ TPM_ECC_CURVE curveId // IN: the curve
+ )
+{
+ const ECC_CURVE *curve = CryptEccGetParametersByCurveId(curveId);
+ UINT16 keySizeInBits;
+ //
+ keySizeInBits = (curve != NULL) ? curve->keySizeBits : 0;
+ return keySizeInBits;
+}
+/* 10.2.11.2.6 GetCurveData() */
+/* This function returns the a pointer for the parameter data associated with a curve. */
+const ECC_CURVE_DATA *
+GetCurveData(
+ TPM_ECC_CURVE curveId // IN: the curveID
+ )
+{
+ const ECC_CURVE *curve = CryptEccGetParametersByCurveId(curveId);
+ return (curve != NULL) ? curve->curveData : NULL;
+}
+/* 10.2.11.2.7 CryptEccGetOID() */
+const BYTE *
+CryptEccGetOID(
+ TPM_ECC_CURVE curveId
+ )
+{
+ const ECC_CURVE *curve = CryptEccGetParametersByCurveId(curveId);
+ return (curve != NULL) ? curve->OID : NULL;
+}
+/* 10.2.11.2.7 CryptEccGetCurveByIndex() */
+/* This function returns the number of the i-th implemented curve. The normal use would be to call
+ this function with i starting at 0. When the i is greater than or equal to the number of
+ implemented curves, TPM_ECC_NONE is returned. */
+LIB_EXPORT TPM_ECC_CURVE
+CryptEccGetCurveByIndex(
+ UINT16 i
+ )
+{
+ if(i >= ECC_CURVE_COUNT)
+ return TPM_ECC_NONE;
+ return eccCurves[i].curveId;
+}
+/* 10.2.11.2.8 CryptEccGetParameter() */
+/* This function returns an ECC curve parameter. The parameter is selected by a single character
+ designator from the set of {PNABXYH}. */
+/* Return Values Meaning */
+/* TRUE curve exists and parameter returned */
+/* FALSE curve does not exist or parameter selector */
+LIB_EXPORT BOOL
+CryptEccGetParameter(
+ TPM2B_ECC_PARAMETER *out, // OUT: place to put parameter
+ char p, // IN: the parameter selector
+ TPM_ECC_CURVE curveId // IN: the curve id
+ )
+{
+ const ECC_CURVE_DATA *curve = GetCurveData(curveId);
+ bigConst parameter = NULL;
+ if(curve != NULL)
+ {
+ switch(p)
+ {
+ case 'p':
+ parameter = CurveGetPrime(curve);
+ break;
+ case 'n':
+ parameter = CurveGetOrder(curve);
+ break;
+ case 'a':
+ parameter = CurveGet_a(curve);
+ break;
+ case 'b':
+ parameter = CurveGet_b(curve);
+ break;
+ case 'x':
+ parameter = CurveGetGx(curve);
+ break;
+ case 'y':
+ parameter = CurveGetGy(curve);
+ break;
+ case 'h':
+ parameter = CurveGetCofactor(curve);
+ break;
+ default:
+ FAIL(FATAL_ERROR_INTERNAL);
+ break;
+ }
+ }
+ // If not debugging and we get here with parameter still NULL, had better
+ // not try to convert so just return FALSE instead.
+ return (parameter != NULL) ? BnTo2B(parameter, &out->b, 0) : 0;
+}
+/* 10.2.11.2.9 CryptCapGetECCCurve() */
+/* This function returns the list of implemented ECC curves. */
+/* Return Values Meaning */
+/* YES if no more ECC curve is available */
+/* NO if there are more ECC curves not reported */
+TPMI_YES_NO
+CryptCapGetECCCurve(
+ TPM_ECC_CURVE curveID, // IN: the starting ECC curve
+ UINT32 maxCount, // IN: count of returned curves
+ TPML_ECC_CURVE *curveList // OUT: ECC curve list
+ )
+{
+ TPMI_YES_NO more = NO;
+ UINT16 i;
+ UINT32 count = ECC_CURVE_COUNT;
+ TPM_ECC_CURVE curve;
+ // Initialize output property list
+ curveList->count = 0;
+ // The maximum count of curves we may return is MAX_ECC_CURVES
+ if(maxCount > MAX_ECC_CURVES) maxCount = MAX_ECC_CURVES;
+ // Scan the eccCurveValues array
+ for(i = 0; i < count; i++)
+ {
+ curve = CryptEccGetCurveByIndex(i);
+ // If curveID is less than the starting curveID, skip it
+ if(curve < curveID)
+ continue;
+ if (!CryptEccIsCurveRuntimeUsable(curve)) // libtpms added: runtime filter supported curves
+ continue;
+ if(curveList->count < maxCount)
+ {
+ // If we have not filled up the return list, add more curves to
+ // it
+ curveList->eccCurves[curveList->count] = curve;
+ curveList->count++;
+ }
+ else
+ {
+ // If the return list is full but we still have curves
+ // available, report this and stop iterating
+ more = YES;
+ break;
+ }
+ }
+ return more;
+}
+/* 10.2.11.2.10 CryptGetCurveSignScheme() */
+/* This function will return a pointer to the scheme of the curve. */
+const TPMT_ECC_SCHEME *
+CryptGetCurveSignScheme(
+ TPM_ECC_CURVE curveId // IN: The curve selector
+ )
+{
+ const ECC_CURVE *curve = CryptEccGetParametersByCurveId(curveId);
+ if(curve != NULL)
+ return &(curve->sign);
+ else
+ return NULL;
+}
+/* 10.2.11.2.11 CryptGenerateR() */
+/* This function computes the commit random value for a split signing scheme. */
+/* If c is NULL, it indicates that r is being generated for TPM2_Commit(). If c is not NULL, the TPM
+ will validate that the gr.commitArray bit associated with the input value of c is SET. If not,
+ the TPM returns FALSE and no r value is generated. */
+/* Return Values Meaning */
+/* TRUE r value computed */
+/* FALSE no r value computed */
+BOOL
+CryptGenerateR(
+ TPM2B_ECC_PARAMETER *r, // OUT: the generated random value
+ UINT16 *c, // IN/OUT: count value.
+ TPMI_ECC_CURVE curveID, // IN: the curve for the value
+ TPM2B_NAME *name // IN: optional name of a key to
+ // associate with 'r'
+ )
+{
+ // This holds the marshaled g_commitCounter.
+ TPM2B_TYPE(8B, 8);
+ TPM2B_8B cntr = {{8,{0}}};
+ UINT32 iterations;
+ TPM2B_ECC_PARAMETER n;
+ UINT64 currentCount = gr.commitCounter;
+ UINT16 t1;
+ //
+ if(!CryptEccGetParameter(&n, 'n', curveID))
+ return FALSE;
+ // If this is the commit phase, use the current value of the commit counter
+ if(c != NULL)
+ {
+ // if the array bit is not set, can't use the value.
+ if(!TEST_BIT((*c & COMMIT_INDEX_MASK), gr.commitArray))
+ return FALSE;
+ // If it is the sign phase, figure out what the counter value was
+ // when the commitment was made.
+ //
+ // When gr.commitArray has less than 64K bits, the extra
+ // bits of 'c' are used as a check to make sure that the
+ // signing operation is not using an out of range count value
+ t1 = (UINT16)currentCount;
+ // If the lower bits of c are greater or equal to the lower bits of t1
+ // then the upper bits of t1 must be one more than the upper bits
+ // of c
+ if((*c & COMMIT_INDEX_MASK) >= (t1 & COMMIT_INDEX_MASK))
+ // Since the counter is behind, reduce the current count
+ currentCount = currentCount - (COMMIT_INDEX_MASK + 1);
+ t1 = (UINT16)currentCount;
+ if((t1 & ~COMMIT_INDEX_MASK) != (*c & ~COMMIT_INDEX_MASK))
+ return FALSE;
+ // set the counter to the value that was
+ // present when the commitment was made
+ currentCount = (currentCount & 0xffffffffffff0000ULL) | *c; /* libtpms changed */
+ }
+ // Marshal the count value to a TPM2B buffer for the KDF
+ cntr.t.size = sizeof(currentCount);
+ UINT64_TO_BYTE_ARRAY(currentCount, cntr.t.buffer);
+ // Now can do the KDF to create the random value for the signing operation
+ // During the creation process, we may generate an r that does not meet the
+ // requirements of the random value.
+ // want to generate a new r.
+ r->t.size = n.t.size;
+ for(iterations = 1; iterations < 1000000;)
+ {
+ int i;
+
+ CryptKDFa(CONTEXT_INTEGRITY_HASH_ALG, &gr.commitNonce.b, COMMIT_STRING,
+ (TPM2B *)name, &cntr.b, n.t.size * 8, // libtpms ubsan
+ r->t.buffer, &iterations, FALSE); // libtpms changed
+
+ // "random" value must be less than the prime
+ if(UnsignedCompareB(r->b.size, r->b.buffer, n.t.size, n.t.buffer) >= 0)
+ continue;
+
+ // in this implementation it is required that at least bit
+ // in the upper half of the number be set
+ for(i = n.t.size / 2; i >= 0; i--)
+ if(r->b.buffer[i] != 0)
+ return TRUE;
+ }
+ return FALSE;
+}
+/* 10.2.11.2.12 CryptCommit() */
+/* This function is called when the count value is committed. The gr.commitArray value associated
+ with the current count value is SET and g_commitCounter is incremented. The low-order 16 bits of
+ old value of the counter is returned. */
+UINT16
+CryptCommit(
+ void
+ )
+{
+ UINT16 oldCount = (UINT16)gr.commitCounter;
+ gr.commitCounter++;
+ SET_BIT(oldCount & COMMIT_INDEX_MASK, gr.commitArray);
+ return oldCount;
+}
+/* 10.2.11.2.13 CryptEndCommit() */
+/* This function is called when the signing operation using the committed value is completed. It
+ clears the gr.commitArray bit associated with the count value so that it can't be used again. */
+void
+CryptEndCommit(
+ UINT16 c // IN: the counter value of the commitment
+ )
+{
+ ClearBit((c & COMMIT_INDEX_MASK), gr.commitArray, sizeof(gr.commitArray));
+}
+/* 10.2.11.2.14 CryptEccGetParameters() */
+/* This function returns the ECC parameter details of the given curve */
+/* Return Values Meaning */
+/* TRUE success */
+/* FALSE unsupported ECC curve ID */
+BOOL
+CryptEccGetParameters(
+ TPM_ECC_CURVE curveId, // IN: ECC curve ID
+ TPMS_ALGORITHM_DETAIL_ECC *parameters // OUT: ECC parameters
+ )
+{
+ const ECC_CURVE *curve = CryptEccGetParametersByCurveId(curveId);
+ const ECC_CURVE_DATA *data;
+ BOOL found = curve != NULL;
+ if(found)
+ {
+ data = curve->curveData;
+ parameters->curveID = curve->curveId;
+ parameters->keySize = curve->keySizeBits;
+ parameters->kdf = curve->kdf;
+ parameters->sign = curve->sign;
+ /* BnTo2B(data->prime, &parameters->p.b, 0); */
+ BnTo2B(data->prime, &parameters->p.b, parameters->p.t.size);
+ BnTo2B(data->a, &parameters->a.b, parameters->p.t.size /* libtpms changed for HLK */);
+ BnTo2B(data->b, &parameters->b.b, parameters->p.t.size /* libtpms changed for HLK */);
+ BnTo2B(data->base.x, &parameters->gX.b, parameters->p.t.size);
+ BnTo2B(data->base.y, &parameters->gY.b, parameters->p.t.size);
+ BnTo2B(data->order, &parameters->n.b, 0);
+ BnTo2B(data->h, &parameters->h.b, 0);
+ }
+ return found;
+}
+/* 10.2.11.2.15 BnGetCurvePrime() */
+/* This function is used to get just the prime modulus associated with a curve */
+const bignum_t *
+BnGetCurvePrime(
+ TPM_ECC_CURVE curveId
+ )
+{
+ const ECC_CURVE_DATA *C = GetCurveData(curveId);
+ return (C != NULL) ? CurveGetPrime(C) : NULL;
+}
+/* 10.2.11.2.16 BnGetCurveOrder() */
+/* This function is used to get just the curve order */
+const bignum_t *
+BnGetCurveOrder(
+ TPM_ECC_CURVE curveId
+ )
+{
+ const ECC_CURVE_DATA *C = GetCurveData(curveId);
+ return (C != NULL) ? CurveGetOrder(C) : NULL;
+}
+/* 10.2.11.2.17 BnIsOnCurve() */
+/* This function checks if a point is on the curve. */
+BOOL
+BnIsOnCurve(
+ pointConst Q,
+ const ECC_CURVE_DATA *C
+ )
+{
+ BN_VAR(right, (MAX_ECC_KEY_BITS * 3));
+ BN_VAR(left, (MAX_ECC_KEY_BITS * 2));
+ bigConst prime = CurveGetPrime(C);
+ //
+ // Show that point is on the curve y^2 = x^3 + ax + b;
+ // Or y^2 = x(x^2 + a) + b
+ // y^2
+ BnMult(left, Q->y, Q->y);
+ BnMod(left, prime);
+ // x^2
+ BnMult(right, Q->x, Q->x);
+ // x^2 + a
+ BnAdd(right, right, CurveGet_a(C));
+ // BnMod(right, CurveGetPrime(C));
+ // x(x^2 + a)
+ BnMult(right, right, Q->x);
+ // x(x^2 + a) + b
+ BnAdd(right, right, CurveGet_b(C));
+ BnMod(right, prime);
+ if(BnUnsignedCmp(left, right) == 0)
+ return TRUE;
+ else
+ return FALSE;
+}
+/* 10.2.11.2.18 BnIsValidPrivateEcc() */
+/* Checks that 0 < x < q */
+BOOL
+BnIsValidPrivateEcc(
+ bigConst x, // IN: private key to check
+ bigCurve E // IN: the curve to check
+ )
+{
+ BOOL retVal;
+ retVal = (!BnEqualZero(x)
+ && (BnUnsignedCmp(x, CurveGetOrder(AccessCurveData(E))) < 0));
+ return retVal;
+}
+LIB_EXPORT BOOL
+CryptEccIsValidPrivateKey(
+ TPM2B_ECC_PARAMETER *d,
+ TPM_ECC_CURVE curveId
+ )
+{
+ BN_INITIALIZED(bnD, MAX_ECC_PARAMETER_BYTES * 8, d);
+ return !BnEqualZero(bnD) && (BnUnsignedCmp(bnD, BnGetCurveOrder(curveId)) < 0);
+}
+/* 10.2.11.2.19 BnPointMul() */
+/* This function does a point multiply of the form R = [d]S + [u]Q where the parameters are bigNum
+ values. If S is NULL and d is not NULL, then it computes R = [d]G + [u]Q or just R = [d]G if u
+ and Q are NULL. If skipChecks is TRUE, then the function will not verify that the inputs are
+ correct for the domain. This would be the case when the values were created by the CryptoEngine()
+ code. It will return TPM_RC_NO_RESULT if the resulting point is the point at infinity. */
+/* Error Returns Meaning */
+/* TPM_RC_NO_RESULT result of multiplication is a point at infinity */
+/* TPM_RC_ECC_POINT S or Q is not on the curve */
+/* TPM_RC_VALUE d or u is not < n */
+TPM_RC
+BnPointMult(
+ bigPoint R, // OUT: computed point
+ pointConst S, // IN: optional point to multiply by 'd'
+ bigConst d, // IN: scalar for [d]S or [d]G
+ pointConst Q, // IN: optional second point
+ bigConst u, // IN: optional second scalar
+ bigCurve E // IN: curve parameters
+ )
+{
+ BOOL OK;
+ //
+ TEST(TPM_ALG_ECDH);
+ // Need one scalar
+ OK = (d != NULL || u != NULL);
+ // If S is present, then d has to be present. If S is not
+ // present, then d may or may not be present
+ OK = OK && (((S == NULL) == (d == NULL)) || (d != NULL));
+ // either both u and Q have to be provided or neither can be provided (don't
+ // know what to do if only one is provided.
+ OK = OK && ((u == NULL) == (Q == NULL));
+ OK = OK && (E != NULL);
+ if(!OK)
+ return TPM_RC_VALUE;
+ OK = (S == NULL) || BnIsOnCurve(S, AccessCurveData(E));
+ OK = OK && ((Q == NULL) || BnIsOnCurve(Q, AccessCurveData(E)));
+ if(!OK)
+ return TPM_RC_ECC_POINT;
+ if((d != NULL) && (S == NULL))
+ S = CurveGetG(AccessCurveData(E));
+ // If only one scalar, don't need Shamir's trick
+ if((d == NULL) || (u == NULL))
+ {
+ if(d == NULL)
+ OK = BnEccModMult(R, Q, u, E);
+ else
+ OK = BnEccModMult(R, S, d, E);
+ }
+ else
+ {
+ OK = BnEccModMult2(R, S, d, Q, u, E);
+ }
+ return (OK ? TPM_RC_SUCCESS : TPM_RC_NO_RESULT);
+}
+/* 10.2.11.2.20 BnEccGetPrivate() */
+/* This function gets random values that are the size of the key plus 64 bits. The value is reduced
+ (mod (q - 1)) and incremented by 1 (q is the order of the curve. This produces a value (d) such
+ that 1 <= d < q. This is the method of FIPS 186-4 Section B.4.1 'Key Pair Generation Using Extra
+ Random Value Meaning */
+/* TRUE success */
+/* FALSE failure generating private key */
+#if !USE_OPENSSL_FUNCTIONS_EC // libtpms added
+BOOL
+BnEccGetPrivate(
+ bigNum dOut, // OUT: the qualified random value
+ const ECC_CURVE_DATA *C, // IN: curve for which the private key
+ // needs to be appropriate
+ RAND_STATE *rand // IN: state for DRBG
+ )
+{
+ bigConst order = CurveGetOrder(C);
+ BOOL OK;
+ UINT32 orderBits = BnSizeInBits(order);
+ UINT32 orderBytes = BITS_TO_BYTES(orderBits);
+ BN_VAR(bnExtraBits, MAX_ECC_KEY_BITS + 64);
+ BN_VAR(nMinus1, MAX_ECC_KEY_BITS);
+ //
+ OK = BnGetRandomBits(bnExtraBits, (orderBytes * 8) + 64, rand);
+ OK = OK && BnSubWord(nMinus1, order, 1);
+ OK = OK && BnMod(bnExtraBits, nMinus1);
+ OK = OK && BnAddWord(dOut, bnExtraBits, 1);
+ return OK && !g_inFailureMode;
+}
+#else // libtpms added begin
+BOOL
+BnEccGetPrivate(
+ bigNum dOut, // OUT: the qualified random value
+ const ECC_CURVE_DATA *C, // IN: curve for which the private key
+ const EC_GROUP *G, // IN: the EC_GROUP to use; must be != NULL for rand == NULL
+ BOOL noLeadingZeros, // IN: require that all bytes in the private key be set
+ // result may not have leading zero bytes
+ // needs to be appropriate
+ RAND_STATE *rand // IN: state for DRBG
+ )
+{
+ bigConst order = CurveGetOrder(C);
+ BOOL OK;
+ UINT32 orderBits = BnSizeInBits(order);
+ UINT32 orderBytes = BITS_TO_BYTES(orderBits);
+ UINT32 requestedBits = 0;
+ BN_VAR(bnExtraBits, MAX_ECC_KEY_BITS + 64);
+ BN_VAR(nMinus1, MAX_ECC_KEY_BITS);
+
+ if (rand == NULL) {
+ if (noLeadingZeros)
+ requestedBits = orderBits;
+
+ return OpenSSLEccGetPrivate(dOut, G, requestedBits);
+ }
+
+ //
+ OK = BnGetRandomBits(bnExtraBits, (orderBytes * 8) + 64, rand);
+ OK = OK && BnSubWord(nMinus1, order, 1);
+ OK = OK && BnMod(bnExtraBits, nMinus1);
+ OK = OK && BnAddWord(dOut, bnExtraBits, 1);
+ return OK && !g_inFailureMode;
+}
+#endif // USE_OPENSSL_FUNCTIONS_EC libtpms added end
+/* 10.2.11.2.21 BnEccGenerateKeyPair() */
+/* This function gets a private scalar from the source of random bits and does the point multiply to
+ get the public key. */
+#if !USE_OPENSSL_FUNCTIONS_EC // libtpms added
+
+BOOL
+BnEccGenerateKeyPair(
+ bigNum bnD, // OUT: private scalar
+ bn_point_t *ecQ, // OUT: public point
+ bigCurve E, // IN: curve for the point
+ RAND_STATE *rand // IN: DRBG state to use
+ )
+{
+ BOOL OK = FALSE;
+ // Get a private scalar
+ OK = BnEccGetPrivate(bnD, AccessCurveData(E), rand);
+ // Do a point multiply
+ OK = OK && BnEccModMult(ecQ, NULL, bnD, E);
+ if(!OK)
+ BnSetWord(ecQ->z, 0);
+ else
+ BnSetWord(ecQ->z, 1);
+ return OK;
+}
+
+#else // libtpms added begin
+
+/* In this version of BnEccGenerateKeyPair we take a dual approach to constant
+ time requirements: For curves whose order is at the byte boundary, e.g.
+ NIST P224/P256/P384, we make sure that bnD has all bytes set (no leading zeros)
+ so that OpenSSL BIGNUM code will not reduce the number of bytes and the
+ subsequent BnEccModMult() would run faster for a shoter value. For all other
+ curves whose order is not at the byte boundary, e.g. NIST P521, we simply
+ always add the order of the curve to bnD and call BnEccModMult() with the
+ result bnD1, which leads to the same result. */
+BOOL
+BnEccGenerateKeyPair(
+ bigNum bnD, // OUT: private scalar
+ bn_point_t *ecQ, // OUT: public point
+ bigCurve E, // IN: curve for the point
+ RAND_STATE *rand // IN: DRBG state to use
+ )
+{
+ BOOL OK = FALSE;
+ bigConst order = CurveGetOrder(AccessCurveData(E));
+ UINT32 orderBits = BnSizeInBits(order);
+ BOOL atByteBoundary = (orderBits & 7) == 0;
+ BOOL noLeadingZeros = atByteBoundary;
+ ECC_NUM(bnD1);
+
+ // We request that bnD not have leading zeros if it is at byte-boundary,
+ // like for example it is the case for NIST P256.
+ OK = BnEccGetPrivate(bnD, AccessCurveData(E), E->G, noLeadingZeros, rand);
+ if (!atByteBoundary) {
+ // for NIST P521 we can add the order to bnD to ensure we have
+ // a constant amount of bytes; the result is the same as if we
+ // were doing the BnEccModMult() calculation with bnD.
+ OK = OK && BnAdd(bnD1, bnD, order);
+ OK = OK && BnEccModMult(ecQ, NULL, bnD1, E);
+ } else {
+ OK = OK && BnEccModMult(ecQ, NULL, bnD, E);
+ }
+
+ if(!OK)
+ BnSetWord(ecQ->z, 0);
+ else
+ BnSetWord(ecQ->z, 1);
+ return OK;
+}
+
+#endif // libtpms added end
+
+/* 10.2.11.2.21 CryptEccNewKeyPair */
+/* This function creates an ephemeral ECC. It is ephemeral in that is expected that the private part
+ of the key will be discarded */
+LIB_EXPORT TPM_RC
+CryptEccNewKeyPair(
+ TPMS_ECC_POINT *Qout, // OUT: the public point
+ TPM2B_ECC_PARAMETER *dOut, // OUT: the private scalar
+ TPM_ECC_CURVE curveId // IN: the curve for the key
+ )
+{
+ CURVE_INITIALIZED(E, curveId);
+ POINT(ecQ);
+ ECC_NUM(bnD);
+ BOOL OK;
+ if(E == NULL)
+ return TPM_RC_CURVE;
+ TEST(TPM_ALG_ECDH);
+ OK = BnEccGenerateKeyPair(bnD, ecQ, E, NULL);
+ if(OK)
+ {
+ BnPointTo2B(Qout, ecQ, E);
+ BnTo2B(bnD, &dOut->b, Qout->x.t.size);
+ }
+ else
+ {
+ Qout->x.t.size = Qout->y.t.size = dOut->t.size = 0;
+ }
+ CURVE_FREE(E);
+ return OK ? TPM_RC_SUCCESS : TPM_RC_NO_RESULT;
+}
+/* 10.2.11.2.22 CryptEccPointMultiply() */
+/* This function computes 'R := [dIn]G + [uIn]QIn. Where dIn and uIn are scalars, G and QIn are
+ points on the specified curve and G is the default generator of the curve. */
+/* The xOut and yOut parameters are optional and may be set to NULL if not used. */
+/* It is not necessary to provide uIn if QIn is specified but one of uIn and dIn must be
+ provided. If dIn and QIn are specified but uIn is not provided, then R = [dIn]QIn. */
+/* If the multiply produces the point at infinity, the TPM_RC_NO_RESULT is returned. */
+/* The sizes of xOut and yOut' will be set to be the size of the degree of the curve */
+/* It is a fatal error if dIn and uIn are both unspecified (NULL) or if Qin or Rout is
+ unspecified. */
+/* Error Returns Meaning */
+/* TPM_RC_ECC_POINT the point Pin or Qin is not on the curve */
+/* TPM_RC_NO_RESULT the product point is at infinity */
+/* TPM_RC_CURVE bad curve */
+/* TPM_RC_VALUE dIn or uIn out of range */
+LIB_EXPORT TPM_RC
+CryptEccPointMultiply(
+ TPMS_ECC_POINT *Rout, // OUT: the product point R
+ TPM_ECC_CURVE curveId, // IN: the curve to use
+ TPMS_ECC_POINT *Pin, // IN: first point (can be null)
+ TPM2B_ECC_PARAMETER *dIn, // IN: scalar value for [dIn]Qin
+ // the Pin
+ TPMS_ECC_POINT *Qin, // IN: point Q
+ TPM2B_ECC_PARAMETER *uIn // IN: scalar value for the multiplier
+ // of Q
+ )
+{
+ CURVE_INITIALIZED(E, curveId);
+ POINT_INITIALIZED(ecP, Pin);
+ ECC_INITIALIZED(bnD, dIn); // If dIn is null, then bnD is null
+ ECC_INITIALIZED(bnU, uIn);
+ POINT_INITIALIZED(ecQ, Qin);
+ POINT(ecR);
+ TPM_RC retVal;
+ //
+ retVal = BnPointMult(ecR, ecP, bnD, ecQ, bnU, E);
+ if(retVal == TPM_RC_SUCCESS)
+ BnPointTo2B(Rout, ecR, E);
+ else
+ ClearPoint2B(Rout);
+ CURVE_FREE(E);
+ return retVal;
+}
+/* 10.2.11.2.23 CryptEccIsPointOnCurve() */
+/* 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 + a*x + b mod p */
+/* It is a fatal error if Q is not specified (is NULL). */
+/* Return Values Meaning */
+/* TRUE point is on curve */
+/* FALSE point is not on curve or curve is not supported */
+LIB_EXPORT BOOL
+CryptEccIsPointOnCurve(
+ TPM_ECC_CURVE curveId, // IN: the curve selector
+ TPMS_ECC_POINT *Qin // IN: the point.
+ )
+{
+ const ECC_CURVE_DATA *C = GetCurveData(curveId);
+ POINT_INITIALIZED(ecQ, Qin);
+ BOOL OK;
+ //
+ pAssert(Qin != NULL);
+ OK = (C != NULL && (BnIsOnCurve(ecQ, C)));
+ return OK;
+}
+/* 10.2.11.2.24 CryptEccGenerateKey() */
+/* This function generates an ECC key pair based on the input parameters. This routine uses KDFa()
+ to produce candidate numbers. The method is according to FIPS 186-3, section B.1.2 "Key Pair
+ Generation by Testing Candidates." According to the method in FIPS 186-3, the resulting private
+ value d should be 1 <= d < n where n is the order of the base point. */
+/* It is a fatal error if Qout, dOut, is not provided (is NULL). */
+/* If the curve is not supported If seed is not provided, then a random number will be used for the
+ key */
+/* Error Returns Meaning */
+/* TPM_RC_CURVE curve is not supported */
+/* TPM_RC_NO_RESULT could not verify key with signature (FIPS only) */
+LIB_EXPORT TPM_RC
+CryptEccGenerateKey(
+ TPMT_PUBLIC *publicArea, // IN/OUT: The public area template for
+ // the new key. The public key
+ // area will be replaced computed
+ // ECC public key
+ TPMT_SENSITIVE *sensitive, // OUT: the sensitive area will be
+ // updated to contain the private
+ // ECC key and the symmetric
+ // encryption key
+ RAND_STATE *rand // IN: if not NULL, the deterministic
+ // RNG state
+ )
+{
+ CURVE_INITIALIZED(E, publicArea->parameters.eccDetail.curveID);
+ ECC_NUM(bnD);
+ POINT(ecQ);
+ BOOL OK;
+ TPM_RC retVal;
+ TEST(TPM_ALG_ECDSA); // ECDSA is used to verify each key
+ // Validate parameters
+ if(E == NULL)
+ ERROR_RETURN(TPM_RC_CURVE);
+ publicArea->unique.ecc.x.t.size = 0;
+ publicArea->unique.ecc.y.t.size = 0;
+ sensitive->sensitive.ecc.t.size = 0;
+ OK = BnEccGenerateKeyPair(bnD, ecQ, E, rand);
+ if(OK)
+ {
+ BnPointTo2B(&publicArea->unique.ecc, ecQ, E);
+ BnTo2B(bnD, &sensitive->sensitive.ecc.b, publicArea->unique.ecc.x.t.size);
+ }
+#if FIPS_COMPLIANT
+ // See if PWCT is required
+ if(OK && (IS_ATTRIBUTE(publicArea->objectAttributes, TPMA_OBJECT, sign)))
+ {
+ ECC_NUM(bnT);
+ ECC_NUM(bnS);
+ TPM2B_DIGEST digest;
+ TEST(TPM_ALG_ECDSA);
+ digest.t.size = MIN(sensitive->sensitive.ecc.t.size, sizeof(digest.t.buffer));
+ // Get a random value to sign using the built in DRBG state
+ DRBG_Generate(NULL, digest.t.buffer, digest.t.size);
+ if(g_inFailureMode)
+ return TPM_RC_FAILURE;
+ BnSignEcdsa(bnT, bnS, E, bnD, &digest, NULL);
+ // and make sure that we can validate the signature
+ OK = BnValidateSignatureEcdsa(bnT, bnS, E, ecQ, &digest) == TPM_RC_SUCCESS;
+ }
+#endif
+ retVal = (OK) ? TPM_RC_SUCCESS : TPM_RC_NO_RESULT;
+ Exit:
+ CURVE_FREE(E);
+ return retVal;
+}
+
+// libtpms added begin
+// Support for some curves may be compiled in but they may not be
+// supported by openssl's crypto library.
+LIB_EXPORT BOOL
+CryptEccIsCurveRuntimeUsable(
+ TPMI_ECC_CURVE curveId
+ )
+{
+ CURVE_INITIALIZED(E, curveId);
+ if (E == NULL)
+ return FALSE;
+ CURVE_FREE(E);
+ return TRUE;
+}
+// libtpms added end
+
+#endif // TPM_ALG_ECC
diff --git a/src/tpm2/crypto/openssl/CryptEccSignature.c b/src/tpm2/crypto/openssl/CryptEccSignature.c
new file mode 100644
index 0000000..a325a46
--- /dev/null
+++ b/src/tpm2/crypto/openssl/CryptEccSignature.c
@@ -0,0 +1,1043 @@
+/********************************************************************************/
+/* */
+/* ECC Signatures */
+/* Written by Ken Goldman */
+/* IBM Thomas J. Watson Research Center */
+/* $Id: CryptEccSignature.c 1658 2021-01-22 23:14:01Z kgoldman $ */
+/* */
+/* Licenses and Notices */
+/* */
+/* 1. Copyright Licenses: */
+/* */
+/* - Trusted Computing Group (TCG) grants to the user of the source code in */
+/* this specification (the "Source Code") a worldwide, irrevocable, */
+/* nonexclusive, royalty free, copyright license to reproduce, create */
+/* derivative works, distribute, display and perform the Source Code and */
+/* derivative works thereof, and to grant others the rights granted herein. */
+/* */
+/* - The TCG grants to the user of the other parts of the specification */
+/* (other than the Source Code) the rights to reproduce, distribute, */
+/* display, and perform the specification solely for the purpose of */
+/* developing products based on such documents. */
+/* */
+/* 2. Source Code Distribution Conditions: */
+/* */
+/* - Redistributions of Source Code must retain the above copyright licenses, */
+/* this list of conditions and the following disclaimers. */
+/* */
+/* - Redistributions in binary form must reproduce the above copyright */
+/* licenses, this list of conditions and the following disclaimers in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* 3. Disclaimers: */
+/* */
+/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
+/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
+/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
+/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
+/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
+/* information on specification licensing rights available through TCG */
+/* membership agreements. */
+/* */
+/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
+/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
+/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
+/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
+/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
+/* */
+/* - Without limitation, TCG and its members and licensors disclaim all */
+/* liability, including liability for infringement of any proprietary */
+/* rights, relating to use of information in this specification and to the */
+/* implementation of this specification, and TCG disclaims all liability for */
+/* cost of procurement of substitute goods or services, lost profits, loss */
+/* of use, loss of data or any incidental, consequential, direct, indirect, */
+/* or special damages, whether under contract, tort, warranty or otherwise, */
+/* arising in any way out of use or reliance upon this specification or any */
+/* information herein. */
+/* */
+/* (c) Copyright IBM Corp. and others, 2016 - 2021 */
+/* */
+/********************************************************************************/
+
+/* 10.2.12 CryptEccSignature.c */
+/* 10.2.12.1 Includes and Defines */
+#include "Tpm.h"
+#include "CryptEccSignature_fp.h"
+#include "TpmToOsslMath_fp.h" // libtpms added
+#if ALG_ECC
+/* 10.2.12.2 Utility Functions */
+/* 10.2.12.2.1 EcdsaDigest() */
+/* Function to adjust the digest so that it is no larger than the order of the curve. This is used
+ for ECDSA sign and verification. */
+#if !USE_OPENSSL_FUNCTIONS_ECDSA // libtpms added
+static bigNum
+EcdsaDigest(
+ bigNum bnD, // OUT: the adjusted digest
+ const TPM2B_DIGEST *digest, // IN: digest to adjust
+ bigConst max // IN: value that indicates the maximum
+ // number of bits in the results
+ )
+{
+ int bitsInMax = BnSizeInBits(max);
+ int shift;
+ //
+ if(digest == NULL)
+ BnSetWord(bnD, 0);
+ else
+ {
+ BnFromBytes(bnD, digest->t.buffer,
+ (NUMBYTES)MIN(digest->t.size, BITS_TO_BYTES(bitsInMax)));
+ shift = BnSizeInBits(bnD) - bitsInMax;
+ if(shift > 0)
+ BnShiftRight(bnD, bnD, shift);
+ }
+ return bnD;
+}
+#endif // libtpms added
+/* 10.2.12.2.2 BnSchnorrSign() */
+/* This contains the Schnorr signature computation. It is used by both ECDSA and Schnorr
+ signing. The result is computed as: [s = k + r * d (mod n)] where */
+/* a) s is the signature */
+/* b) k is a random value */
+/* c) r is the value to sign */
+/* d) d is the private EC key */
+/* e) n is the order of the curve */
+/* Error Returns Meaning */
+/* TPM_RC_NO_RESULT the result of the operation was zero or r (mod n) is zero */
+static TPM_RC
+BnSchnorrSign(
+ bigNum bnS, // OUT: s component of the signature
+ bigConst bnK, // IN: a random value
+ bigNum bnR, // IN: the signature 'r' value
+ bigConst bnD, // IN: the private key
+ bigConst bnN // IN: the order of the curve
+ )
+{
+ // Need a local temp value to store the intermediate computation because product
+ // size can be larger than will fit in bnS.
+ BN_VAR(bnT1, MAX_ECC_PARAMETER_BYTES * 2 * 8);
+ //
+ // Reduce bnR without changing the input value
+ BnDiv(NULL, bnT1, bnR, bnN);
+ if(BnEqualZero(bnT1))
+ return TPM_RC_NO_RESULT;
+ // compute s = (k + r * d)(mod n)
+ // r * d
+ BnMult(bnT1, bnT1, bnD);
+ // k * r * d
+ BnAdd(bnT1, bnT1, bnK);
+ // k + r * d (mod n)
+ BnDiv(NULL, bnS, bnT1, bnN);
+ return (BnEqualZero(bnS)) ? TPM_RC_NO_RESULT : TPM_RC_SUCCESS;
+}
+/* 10.2.12.3 Signing Functions */
+/* 10.2.12.3.1 BnSignEcdsa() */
+/* This function implements the ECDSA signing algorithm. The method is described in the comments
+ below. This version works with internal numbers. */
+#if !USE_OPENSSL_FUNCTIONS_ECDSA // libtpms added
+TPM_RC
+BnSignEcdsa(
+ bigNum bnR, // OUT: r component of the signature
+ bigNum bnS, // OUT: s component of the signature
+ bigCurve E, // IN: the curve used in the signature
+ // process
+ bigNum bnD, // IN: private signing key
+ const TPM2B_DIGEST *digest, // IN: the digest to sign
+ RAND_STATE *rand // IN: used in debug of signing
+ )
+{
+ ECC_NUM(bnK);
+ ECC_NUM(bnIk);
+ BN_VAR(bnE, MAX(MAX_ECC_KEY_BYTES, MAX_DIGEST_SIZE) * 8);
+ POINT(ecR);
+ bigConst order = CurveGetOrder(AccessCurveData(E));
+ TPM_RC retVal = TPM_RC_SUCCESS;
+ INT32 tries = 10;
+ BOOL OK = FALSE;
+ //
+ pAssert(digest != NULL);
+ // The algorithm as described in "Suite B Implementer's Guide to FIPS
+ // 186-3(ECDSA)"
+ // 1. Use one of the routines in Appendix A.2 to generate (k, k^-1), a
+ // per-message secret number and its inverse modulo n. Since n is prime,
+ // the output will be invalid only if there is a failure in the RBG.
+ // 2. Compute the elliptic curve point R = [k]G = (xR, yR) using EC scalar
+ // multiplication (see [Routines]), where G is the base point included in
+ // the set of domain parameters.
+ // 3. Compute r = xR mod n. If r = 0, then return to Step 1. 1.
+ // 4. Use the selected hash function to compute H = Hash(M).
+ // 5. Convert the bit string H to an integer e as described in Appendix B.2.
+ // 6. Compute s = (k^-1 * (e + d * r)) mod q. If s = 0, return to Step 1.2.
+ // 7. Return (r, s).
+ // In the code below, q is n (that it, the order of the curve is p)
+ do // This implements the loop at step 6. If s is zero, start over.
+ {
+ for(; tries > 0; tries--)
+ {
+ // Step 1 and 2 -- generate an ephemeral key and the modular inverse
+ // of the private key.
+ if(!BnEccGenerateKeyPair(bnK, ecR, E, rand))
+ continue;
+ // x coordinate is mod p. Make it mod q
+ BnMod(ecR->x, order);
+ // Make sure that it is not zero;
+ if(BnEqualZero(ecR->x))
+ continue;
+ // write the modular reduced version of r as part of the signature
+ BnCopy(bnR, ecR->x);
+ // Make sure that a modular inverse exists and try again if not
+ OK = (BnModInverse(bnIk, bnK, order));
+ if(OK)
+ break;
+ }
+ if(!OK)
+ goto Exit;
+ EcdsaDigest(bnE, digest, order);
+ // now have inverse of K (bnIk), e (bnE), r (bnR), d (bnD) and
+ // CurveGetOrder(E)
+ // Compute s = k^-1 (e + r*d)(mod q)
+ // first do s = r*d mod q
+ BnModMult(bnS, bnR, bnD, order);
+ // s = e + s = e + r * d
+ BnAdd(bnS, bnE, bnS);
+ // s = k^(-1)s (mod n) = k^(-1)(e + r * d)(mod n)
+ BnModMult(bnS, bnIk, bnS, order);
+ // If S is zero, try again
+ } while(BnEqualZero(bnS));
+ Exit:
+ return retVal;
+}
+#else // !USE_OPENSSL_FUNCTIONS_ECDSA libtpms added begin
+TPM_RC
+BnSignEcdsa(
+ bigNum bnR, // OUT: r component of the signature
+ bigNum bnS, // OUT: s component of the signature
+ bigCurve E, // IN: the curve used in the signature
+ // process
+ bigNum bnD, // IN: private signing key
+ const TPM2B_DIGEST *digest, // IN: the digest to sign
+ RAND_STATE *rand // IN: used in debug of signing
+ )
+{
+ ECDSA_SIG *sig = NULL;
+ EC_KEY *eckey;
+ int retVal;
+ const BIGNUM *r;
+ const BIGNUM *s;
+ BIGNUM *d = BN_new();
+
+ d = BigInitialized(d, bnD);
+
+ eckey = EC_KEY_new();
+
+ if (d == NULL || eckey == NULL)
+ ERROR_RETURN(TPM_RC_FAILURE);
+
+ if (EC_KEY_set_group(eckey, E->G) != 1)
+ ERROR_RETURN(TPM_RC_FAILURE);
+
+ if (EC_KEY_set_private_key(eckey, d) != 1)
+ ERROR_RETURN(TPM_RC_FAILURE);
+
+ sig = ECDSA_do_sign(digest->b.buffer, digest->b.size, eckey);
+ if (sig == NULL)
+ ERROR_RETURN(TPM_RC_FAILURE);
+
+ ECDSA_SIG_get0(sig, &r, &s);
+ OsslToTpmBn(bnR, r);
+ OsslToTpmBn(bnS, s);
+
+ retVal = TPM_RC_SUCCESS;
+
+ Exit:
+ BN_clear_free(d);
+ EC_KEY_free(eckey);
+ ECDSA_SIG_free(sig);
+
+ return retVal;
+}
+#endif // USE_OPENSSL_FUNCTIONS_ECDSA libtpms added end
+#if ALG_ECDAA
+/* 10.2.12.3.2 BnSignEcdaa() */
+/* This function performs s = r + T * d mod q where */
+/* a) 'r is a random, or pseudo-random value created in the commit phase */
+/* b) nonceK is a TPM-generated, random value 0 < nonceK < n */
+/* c) T is mod q of Hash(nonceK || digest), and */
+/* d) d is a private key. */
+/* The signature is the tuple (nonceK, s) */
+/* Regrettably, the parameters in this function kind of collide with the parameter names used in
+ ECSCHNORR making for a lot of confusion. In particular, the k value in this function is value in
+ this function u */
+/* Error Returns Meaning */
+/* TPM_RC_SCHEME unsupported hash algorithm */
+/* TPM_RC_NO_RESULT cannot get values from random number generator */
+static TPM_RC
+BnSignEcdaa(
+ TPM2B_ECC_PARAMETER *nonceK, // OUT: nonce component of the signature
+ bigNum bnS, // OUT: s component of the signature
+ bigCurve E, // IN: the curve used in signing
+ bigNum bnD, // IN: the private key
+ const TPM2B_DIGEST *digest, // IN: the value to sign (mod q)
+ TPMT_ECC_SCHEME *scheme, // IN: signing scheme (contains the
+ // commit count value).
+ OBJECT *eccKey, // IN: The signing key
+ RAND_STATE *rand // IN: a random number state
+ )
+{
+ TPM_RC retVal;
+ TPM2B_ECC_PARAMETER r;
+ HASH_STATE state;
+ TPM2B_DIGEST T;
+ BN_MAX(bnT);
+ //
+ NOT_REFERENCED(rand);
+ if(!CryptGenerateR(&r, &scheme->details.ecdaa.count,
+ eccKey->publicArea.parameters.eccDetail.curveID,
+ &eccKey->name))
+ retVal = TPM_RC_VALUE;
+ else
+ {
+ // This allocation is here because 'r' doesn't have a value until
+ // CrypGenerateR() is done.
+ ECC_INITIALIZED(bnR, &r);
+ do
+ {
+ // generate nonceK such that 0 < nonceK < n
+ // use bnT as a temp.
+#if USE_OPENSSL_FUNCTIONS_EC // libtpms added begin
+ if(!BnEccGetPrivate(bnT, AccessCurveData(E), E->G, false, rand))
+#else // libtpms added end
+ if(!BnEccGetPrivate(bnT, AccessCurveData(E), rand))
+#endif // libtpms added
+ {
+ retVal = TPM_RC_NO_RESULT;
+ break;
+ }
+ BnTo2B(bnT, &nonceK->b, 0);
+ T.t.size = CryptHashStart(&state, scheme->details.ecdaa.hashAlg);
+ if(T.t.size == 0)
+ {
+ retVal = TPM_RC_SCHEME;
+ }
+ else
+ {
+ CryptDigestUpdate2B(&state, &nonceK->b);
+ CryptDigestUpdate2B(&state, &digest->b);
+ CryptHashEnd2B(&state, &T.b);
+ BnFrom2B(bnT, &T.b);
+ // libtpms: Note: T is NOT a concern for constant-timeness
+ // Watch out for the name collisions in this call!!
+ retVal = BnSchnorrSign(bnS, bnR, bnT, bnD,
+ AccessCurveData(E)->order);
+ }
+ } while(retVal == TPM_RC_NO_RESULT);
+ // Because the rule is that internal state is not modified if the command
+ // fails, only end the commit if the command succeeds.
+ // NOTE that if the result of the Schnorr computation was zero
+ // it will probably not be worthwhile to run the same command again because
+ // the result will still be zero. This means that the Commit command will
+ // need to be run again to get a new commit value for the signature.
+ if(retVal == TPM_RC_SUCCESS)
+ CryptEndCommit(scheme->details.ecdaa.count);
+ }
+ return retVal;
+}
+#endif // ALG_ECDAA
+#if ALG_ECSCHNORR
+/* 10.2.12.3.3 SchnorrReduce() */
+/* Function to reduce a hash result if it's magnitude is to large. The size of number is set so that
+ it has no more bytes of significance than the reference value. If the resulting number can have
+ more bits of significance than the reference. */
+static void
+SchnorrReduce(
+ TPM2B *number, // IN/OUT: Value to reduce
+ bigConst reference // IN: the reference value
+ )
+{
+ UINT16 maxBytes = (UINT16)BITS_TO_BYTES(BnSizeInBits(reference));
+ if(number->size > maxBytes)
+ number->size = maxBytes;
+}
+/* 10.2.12.3.4 SchnorrEcc() */
+/* This function is used to perform a modified Schnorr signature. */
+/* This function will generate a random value k and compute */
+/* a) (xR, yR) = [k]G */
+/* b) r = hash(xR || P)(mod q) */
+/* c) rT = truncated r */
+/* d) s= k + rT * ds (mod q) */
+/* e) return the tuple rT, s */
+/* Error Returns Meaning */
+/* TPM_RC_NO_RESULT failure in the Schnorr sign process */
+/* TPM_RC_SCHEME hashAlg can't produce zero-length digest */
+static TPM_RC
+BnSignEcSchnorr(
+ bigNum bnR, // OUT: r component of the signature
+ bigNum bnS, // OUT: s component of the signature
+ bigCurve E, // IN: the curve used in signing
+ bigNum bnD, // IN: the signing key
+ const TPM2B_DIGEST *digest, // IN: the digest to sign
+ TPM_ALG_ID hashAlg, // IN: signing scheme (contains a hash)
+ RAND_STATE *rand // IN: non-NULL when testing
+ )
+{
+ HASH_STATE hashState;
+ UINT16 digestSize
+ = CryptHashGetDigestSize(hashAlg);
+ TPM2B_TYPE(T, MAX(MAX_DIGEST_SIZE, MAX_ECC_KEY_BYTES));
+ TPM2B_T T2b;
+ TPM2B *e = &T2b.b;
+ TPM_RC retVal = TPM_RC_NO_RESULT;
+ const ECC_CURVE_DATA *C;
+ bigConst order;
+ bigConst prime;
+ ECC_NUM(bnK);
+ POINT(ecR);
+ //
+ // Parameter checks
+ if(E == NULL)
+ ERROR_RETURN(TPM_RC_VALUE);
+ C = AccessCurveData(E);
+ order = CurveGetOrder(C);
+ prime = CurveGetOrder(C);
+ // If the digest does not produce a hash, then null the signature and return
+ // a failure.
+ if(digestSize == 0)
+ {
+ BnSetWord(bnR, 0);
+ BnSetWord(bnS, 0);
+ ERROR_RETURN(TPM_RC_SCHEME);
+ }
+ do
+ {
+ // Generate a random key pair
+ if(!BnEccGenerateKeyPair(bnK, ecR, E, rand))
+ break;
+ // Convert R.x to a string
+ BnTo2B(ecR->x, e, (NUMBYTES)BITS_TO_BYTES(BnSizeInBits(prime)));
+ // f) compute r = Hash(e || P) (mod n)
+ CryptHashStart(&hashState, hashAlg);
+ CryptDigestUpdate2B(&hashState, e);
+ CryptDigestUpdate2B(&hashState, &digest->b);
+ e->size = CryptHashEnd(&hashState, digestSize, e->buffer);
+ // Reduce the hash size if it is larger than the curve order
+ SchnorrReduce(e, order);
+ // Convert hash to number
+ BnFrom2B(bnR, e);
+ // libtpms: Note: e is NOT a concern for constant-timeness
+ // Do the Schnorr computation
+ retVal = BnSchnorrSign(bnS, bnK, bnR, bnD, CurveGetOrder(C));
+ } while(retVal == TPM_RC_NO_RESULT);
+ Exit:
+ return retVal;
+}
+#endif // ALG_ECSCHNORR
+#if ALG_SM2
+#ifdef _SM2_SIGN_DEBUG
+/* 10.2.12.3.5 BnHexEqual() */
+/* This function compares a bignum value to a hex string. */
+/* Return Value Meaning */
+/* TRUE(1) values equal */
+/* FALSE(0) values not equal */
+static BOOL
+BnHexEqual(
+ bigNum bn, //IN: big number value
+ const char *c //IN: character string number
+ )
+{
+ ECC_NUM(bnC);
+ BnFromHex(bnC, c);
+ return (BnUnsignedCmp(bn, bnC) == 0);
+}
+#endif // _SM2_SIGN_DEBUG
+/* 10.2.12.3.5 BnSignEcSm2() */
+/* This function signs a digest using the method defined in SM2 Part 2. The method in the standard
+ will add a header to the message to be signed that is a hash of the values that define the
+ key. This then hashed with the message to produce a digest (e) that is signed. This function
+ signs e. */
+/* Error Returns Meaning */
+/* TPM_RC_VALUE bad curve */
+static TPM_RC
+BnSignEcSm2(
+ bigNum bnR, // OUT: r component of the signature
+ bigNum bnS, // OUT: s component of the signature
+ bigCurve E, // IN: the curve used in signing
+ bigNum bnD, // IN: the private key
+ const TPM2B_DIGEST *digest, // IN: the digest to sign
+ RAND_STATE *rand // IN: random number generator (mostly for
+ // debug)
+ )
+{
+ BN_MAX_INITIALIZED(bnE, digest); // Don't know how big digest might be
+ ECC_NUM(bnN);
+ ECC_NUM(bnK);
+ ECC_NUM(bnT); // temp
+ POINT(Q1);
+ bigConst order = (E != NULL)
+ ? CurveGetOrder(AccessCurveData(E)) : NULL;
+// libtpms added begin
+ UINT32 orderBits = BnSizeInBits(order);
+ BOOL atByteBoundary = (orderBits & 7) == 0;
+ ECC_NUM(bnK1);
+// libtpms added end
+
+ //
+#ifdef _SM2_SIGN_DEBUG
+ BnFromHex(bnE, "B524F552CD82B8B028476E005C377FB1"
+ "9A87E6FC682D48BB5D42E3D9B9EFFE76");
+ BnFromHex(bnD, "128B2FA8BD433C6C068C8D803DFF7979"
+ "2A519A55171B1B650C23661D15897263");
+#endif
+ // A3: Use random number generator to generate random number 1 <= k <= n-1;
+ // NOTE: Ax: numbers are from the SM2 standard
+ loop:
+ {
+ // Get a random number 0 < k < n
+ // libtpms modified begin
+ //
+ // We take a dual approach here. One for curves whose order is not at
+ // the byte boundary, e.g. NIST P521, we get a random number bnK and add
+ // the order to that number to have bnK1. This will not spill over into
+ // a new byte and we can then use bnK1 to do the do the BnEccModMult
+ // with a constant number of bytes. For curves whose order is at the
+ // byte boundary we require that the random number bnK comes back with
+ // a requested number of bytes.
+ if (!atByteBoundary) {
+ BnGenerateRandomInRange(bnK, order, rand);
+ BnAdd(bnK1, bnK, order);
+#ifdef _SM2_SIGN_DEBUG
+ BnFromHex(bnK1, "6CB28D99385C175C94F94E934817663F"
+ "C176D925DD72B727260DBAAE1FB2F96F");
+#endif
+ // A4: Figure out the point of elliptic curve (x1, y1)=[k]G, and according
+ // to details specified in 4.2.7 in Part 1 of this document, transform the
+ // data type of x1 into an integer;
+ if(!BnEccModMult(Q1, NULL, bnK1, E))
+ goto loop;
+ } else {
+ BnGenerateRandomInRangeAllBytes(bnK, order, rand);
+#ifdef _SM2_SIGN_DEBUG
+ BnFromHex(bnK, "6CB28D99385C175C94F94E934817663F"
+ "C176D925DD72B727260DBAAE1FB2F96F");
+#endif
+ if(!BnEccModMult(Q1, NULL, bnK, E))
+ goto loop;
+ } // libtpms modified end
+ // A5: Figure out r = (e + x1) mod n,
+ BnAdd(bnR, bnE, Q1->x);
+ BnMod(bnR, order);
+#ifdef _SM2_SIGN_DEBUG
+ pAssert(BnHexEqual(bnR, "40F1EC59F793D9F49E09DCEF49130D41"
+ "94F79FB1EED2CAA55BACDB49C4E755D1"));
+#endif
+ // if r=0 or r+k=n, return to A3;
+ if(BnEqualZero(bnR))
+ goto loop;
+ BnAdd(bnT, bnK, bnR);
+ if(BnUnsignedCmp(bnT, bnN) == 0)
+ goto loop;
+ // A6: Figure out s = ((1 + dA)^-1 (k - r dA)) mod n,
+ // if s=0, return to A3;
+ // compute t = (1+dA)^-1
+ BnAddWord(bnT, bnD, 1);
+ BnModInverse(bnT, bnT, order);
+#ifdef _SM2_SIGN_DEBUG
+ pAssert(BnHexEqual(bnT, "79BFCF3052C80DA7B939E0C6914A18CB"
+ "B2D96D8555256E83122743A7D4F5F956"));
+#endif
+ // compute s = t * (k - r * dA) mod n
+ BnModMult(bnS, bnR, bnD, order);
+ // k - r * dA mod n = k + n - ((r * dA) mod n)
+ BnSub(bnS, order, bnS);
+ BnAdd(bnS, bnK, bnS);
+ BnModMult(bnS, bnS, bnT, order);
+#ifdef _SM2_SIGN_DEBUG
+ pAssert(BnHexEqual(bnS, "6FC6DAC32C5D5CF10C77DFB20F7C2EB6"
+ "67A457872FB09EC56327A67EC7DEEBE7"));
+#endif
+ if(BnEqualZero(bnS))
+ goto loop;
+ }
+ // A7: According to details specified in 4.2.1 in Part 1 of this document,
+ // transform the data type of r, s into bit strings, signature of message M
+ // is (r, s).
+ // This is handled by the common return code
+#ifdef _SM2_SIGN_DEBUG
+ pAssert(BnHexEqual(bnR, "40F1EC59F793D9F49E09DCEF49130D41"
+ "94F79FB1EED2CAA55BACDB49C4E755D1"));
+ pAssert(BnHexEqual(bnS, "6FC6DAC32C5D5CF10C77DFB20F7C2EB6"
+ "67A457872FB09EC56327A67EC7DEEBE7"));
+#endif
+ return TPM_RC_SUCCESS;
+}
+#endif // ALG_SM2
+/* 10.2.12.3.6 CryptEccSign() */
+/* This function is the dispatch function for the various ECC-based signing schemes. There is a bit
+ of ugliness to the parameter passing. In order to test this, we sometime would like to use a
+ deterministic RNG so that we can get the same signatures during testing. The easiest way to do
+ this for most schemes is to pass in a deterministic RNG and let it return canned values during
+ testing. There is a competing need for a canned parameter to use in ECDAA. To accommodate both
+ needs with minimal fuss, a special type of RAND_STATE is defined to carry the address of the
+ commit value. The setup and handling of this is not very different for the caller than what was
+ in previous versions of the code. */
+/* Error Returns Meaning */
+/* TPM_RC_SCHEME scheme is not supported */
+LIB_EXPORT TPM_RC
+CryptEccSign(
+ TPMT_SIGNATURE *signature, // OUT: signature
+ OBJECT *signKey, // IN: ECC key to sign the hash
+ const TPM2B_DIGEST *digest, // IN: digest to sign
+ TPMT_ECC_SCHEME *scheme, // IN: signing scheme
+ RAND_STATE *rand
+ )
+{
+ CURVE_INITIALIZED(E, signKey->publicArea.parameters.eccDetail.curveID);
+ ECC_INITIALIZED(bnD, &signKey->sensitive.sensitive.ecc.b);
+ ECC_NUM(bnR);
+ ECC_NUM(bnS);
+ const ECC_CURVE_DATA *C;
+ TPM_RC retVal = TPM_RC_SCHEME;
+ //
+ NOT_REFERENCED(scheme);
+ if(E == NULL)
+ ERROR_RETURN(TPM_RC_VALUE);
+ C = AccessCurveData(E);
+ signature->signature.ecdaa.signatureR.t.size
+ = sizeof(signature->signature.ecdaa.signatureR.t.buffer);
+ signature->signature.ecdaa.signatureS.t.size
+ = sizeof(signature->signature.ecdaa.signatureS.t.buffer);
+ TEST(signature->sigAlg);
+ switch(signature->sigAlg)
+ {
+ case TPM_ALG_ECDSA:
+ retVal = BnSignEcdsa(bnR, bnS, E, bnD, digest, rand);
+ break;
+#if ALG_ECDAA
+ case TPM_ALG_ECDAA:
+ retVal = BnSignEcdaa(&signature->signature.ecdaa.signatureR, bnS, E,
+ bnD, digest, scheme, signKey, rand);
+ bnR = NULL;
+ break;
+#endif
+#if ALG_ECSCHNORR
+ case TPM_ALG_ECSCHNORR:
+ retVal = BnSignEcSchnorr(bnR, bnS, E, bnD, digest,
+ signature->signature.ecschnorr.hash,
+ rand);
+ break;
+#endif
+#if ALG_SM2
+ case TPM_ALG_SM2:
+ retVal = BnSignEcSm2(bnR, bnS, E, bnD, digest, rand);
+ break;
+#endif
+ default:
+ break;
+ }
+ // If signature generation worked, convert the results.
+ if(retVal == TPM_RC_SUCCESS)
+ {
+ NUMBYTES orderBytes =
+ (NUMBYTES)BITS_TO_BYTES(BnSizeInBits(CurveGetOrder(C)));
+ if(bnR != NULL)
+ BnTo2B(bnR, &signature->signature.ecdaa.signatureR.b, orderBytes);
+ if(bnS != NULL)
+ BnTo2B(bnS, &signature->signature.ecdaa.signatureS.b, orderBytes);
+ }
+ Exit:
+ CURVE_FREE(E);
+ return retVal;
+}
+#if ALG_ECDSA
+/* 10.2.12.3.7 BnValidateSignatureEcdsa() */
+/* This function validates an ECDSA signature. rIn and sIn should have been checked to make sure
+ that they are in the range 0 < v < n */
+/* Error Returns Meaning */
+/* TPM_RC_SIGNATURE signature not valid */
+#if !USE_OPENSSL_FUNCTIONS_ECDSA // libtpms added
+TPM_RC
+BnValidateSignatureEcdsa(
+ bigNum bnR, // IN: r component of the signature
+ bigNum bnS, // IN: s component of the signature
+ bigCurve E, // IN: the curve used in the signature
+ // process
+ bn_point_t *ecQ, // IN: the public point of the key
+ const TPM2B_DIGEST *digest // IN: the digest that was signed
+ )
+{
+ // Make sure that the allocation for the digest is big enough for a maximum
+ // digest
+ BN_VAR(bnE, MAX(MAX_ECC_KEY_BYTES, MAX_DIGEST_SIZE) * 8);
+ POINT(ecR);
+ ECC_NUM(bnU1);
+ ECC_NUM(bnU2);
+ ECC_NUM(bnW);
+ bigConst order = CurveGetOrder(AccessCurveData(E));
+ TPM_RC retVal = TPM_RC_SIGNATURE;
+ // Get adjusted digest
+ EcdsaDigest(bnE, digest, order);
+ // 1. If r and s are not both integers in the interval [1, n - 1], output
+ // INVALID.
+ // bnR and bnS were validated by the caller
+ // 2. Use the selected hash function to compute H0 = Hash(M0).
+ // This is an input parameter
+ // 3. Convert the bit string H0 to an integer e as described in Appendix B.2.
+ // Done at entry
+ // 4. Compute w = (s')^-1 mod n, using the routine in Appendix B.1.
+ if(!BnModInverse(bnW, bnS, order))
+ goto Exit;
+ // 5. Compute u1 = (e' * w) mod n, and compute u2 = (r' * w) mod n.
+ BnModMult(bnU1, bnE, bnW, order);
+ BnModMult(bnU2, bnR, bnW, order);
+ // 6. Compute the elliptic curve point R = (xR, yR) = u1G+u2Q, using EC
+ // scalar multiplication and EC addition (see [Routines]). If R is equal to
+ // the point at infinity O, output INVALID.
+ if(BnPointMult(ecR, CurveGetG(AccessCurveData(E)), bnU1, ecQ, bnU2, E)
+ != TPM_RC_SUCCESS)
+ goto Exit;
+ // 7. Compute v = Rx mod n.
+ BnMod(ecR->x, order);
+ // 8. Compare v and r0. If v = r0, output VALID; otherwise, output INVALID
+ if(BnUnsignedCmp(ecR->x, bnR) != 0)
+ goto Exit;
+ retVal = TPM_RC_SUCCESS;
+ Exit:
+ return retVal;
+}
+#else // USE_OPENSSL_FUNCTIONS_ECDSA libtpms added begin
+TPM_RC
+BnValidateSignatureEcdsa(
+ bigNum bnR, // IN: r component of the signature
+ bigNum bnS, // IN: s component of the signature
+ bigCurve E, // IN: the curve used in the signature
+ // process
+ bn_point_t *ecQ, // IN: the public point of the key
+ const TPM2B_DIGEST *digest // IN: the digest that was signed
+ )
+{
+ int retVal;
+ int rc;
+ ECDSA_SIG *sig = NULL;
+ EC_KEY *eckey = NULL;
+ BIGNUM *r = BN_new();
+ BIGNUM *s = BN_new();
+ EC_POINT *q = EcPointInitialized(ecQ, E);
+
+ r = BigInitialized(r, bnR);
+ s = BigInitialized(s, bnS);
+
+ sig = ECDSA_SIG_new();
+ eckey = EC_KEY_new();
+
+ if (r == NULL || s == NULL || q == NULL || sig == NULL || eckey == NULL)
+ ERROR_RETURN(TPM_RC_FAILURE);
+
+ if (EC_KEY_set_group(eckey, E->G) != 1)
+ ERROR_RETURN(TPM_RC_FAILURE);
+
+ if (EC_KEY_set_public_key(eckey, q) != 1)
+ ERROR_RETURN(TPM_RC_FAILURE);
+
+ if (ECDSA_SIG_set0(sig, r, s) != 1)
+ ERROR_RETURN(TPM_RC_FAILURE);
+
+ /* sig now owns r and s */
+ r = NULL;
+ s = NULL;
+
+ rc = ECDSA_do_verify(digest->b.buffer, digest->b.size, sig, eckey);
+ switch (rc) {
+ case 1:
+ retVal = TPM_RC_SUCCESS;
+ break;
+ case 0:
+ retVal = TPM_RC_SIGNATURE;
+ break;
+ default:
+ retVal = TPM_RC_FAILURE;
+ break;
+ }
+
+ Exit:
+ EC_KEY_free(eckey);
+ ECDSA_SIG_free(sig);
+ EC_POINT_clear_free(q);
+ BN_clear_free(r);
+ BN_clear_free(s);
+
+ return retVal;
+}
+#endif // USE_OPENSSL_FUNCTIONS_ECDSA libtpms added end
+#endif // ALG_ECDSA
+#if ALG_SM2
+/* 10.2.12.3.8 BnValidateSignatureEcSm2() */
+/* This function is used to validate an SM2 signature. */
+/* Error Returns Meaning */
+/* TPM_RC_SIGNATURE signature not valid */
+static TPM_RC
+BnValidateSignatureEcSm2(
+ bigNum bnR, // IN: r component of the signature
+ bigNum bnS, // IN: s component of the signature
+ bigCurve E, // IN: the curve used in the signature
+ // process
+ bigPoint ecQ, // IN: the public point of the key
+ const TPM2B_DIGEST *digest // IN: the digest that was signed
+ )
+{
+ POINT(P);
+ ECC_NUM(bnRp);
+ ECC_NUM(bnT);
+ BN_MAX_INITIALIZED(bnE, digest);
+ BOOL OK;
+ bigConst order = CurveGetOrder(AccessCurveData(E));
+#ifdef _SM2_SIGN_DEBUG
+ // Make sure that the input signature is the test signature
+ pAssert(BnHexEqual(bnR,
+ "40F1EC59F793D9F49E09DCEF49130D41"
+ "94F79FB1EED2CAA55BACDB49C4E755D1"));
+ pAssert(BnHexEqual(bnS,
+ "6FC6DAC32C5D5CF10C77DFB20F7C2EB6"
+ "67A457872FB09EC56327A67EC7DEEBE7"));
+#endif
+ // b) compute t := (r + s) mod n
+ BnAdd(bnT, bnR, bnS);
+ BnMod(bnT, order);
+#ifdef _SM2_SIGN_DEBUG
+ pAssert(BnHexEqual(bnT,
+ "2B75F07ED7ECE7CCC1C8986B991F441A"
+ "D324D6D619FE06DD63ED32E0C997C801"));
+#endif
+ // c) verify that t > 0
+ OK = !BnEqualZero(bnT);
+ if(!OK)
+ // set T to a value that should allow rest of the computations to run
+ // without trouble
+ BnCopy(bnT, bnS);
+ // d) compute (x, y) := [s]G + [t]Q
+ OK = BnEccModMult2(P, NULL, bnS, ecQ, bnT, E);
+#ifdef _SM2_SIGN_DEBUG
+ pAssert(OK && BnHexEqual(P->x,
+ "110FCDA57615705D5E7B9324AC4B856D"
+ "23E6D9188B2AE47759514657CE25D112"));
+#endif
+ // e) compute r' := (e + x) mod n (the x coordinate is in bnT)
+ OK = OK && BnAdd(bnRp, bnE, P->x);
+ OK = OK && BnMod(bnRp, order);
+ // f) verify that r' = r
+ OK = OK && (BnUnsignedCmp(bnR, bnRp) == 0);
+
+ if(!OK)
+ return TPM_RC_SIGNATURE;
+ else
+ return TPM_RC_SUCCESS;
+}
+#endif // ALG_SM2
+#if ALG_ECSCHNORR
+/* 10.2.12.3.9 BnValidateSignatureEcSchnorr() */
+/* This function is used to validate an EC Schnorr signature. */
+/* Error Returns Meaning */
+/* TPM_RC_SIGNATURE signature not valid */
+static TPM_RC
+BnValidateSignatureEcSchnorr(
+ bigNum bnR, // IN: r component of the signature
+ bigNum bnS, // IN: s component of the signature
+ TPM_ALG_ID hashAlg, // IN: hash algorithm of the signature
+ bigCurve E, // IN: the curve used in the signature
+ // process
+ bigPoint ecQ, // IN: the public point of the key
+ const TPM2B_DIGEST *digest // IN: the digest that was signed
+ )
+{
+ BN_MAX(bnRn);
+ POINT(ecE);
+ BN_MAX(bnEx);
+ const ECC_CURVE_DATA *C = AccessCurveData(E);
+ bigConst order = CurveGetOrder(C);
+ UINT16 digestSize = CryptHashGetDigestSize(hashAlg);
+ HASH_STATE hashState;
+ TPM2B_TYPE(BUFFER, MAX(MAX_ECC_PARAMETER_BYTES, MAX_DIGEST_SIZE));
+ TPM2B_BUFFER Ex2 = {{sizeof(Ex2.t.buffer),{ 0 }}};
+ BOOL OK;
+ //
+ // E = [s]G - [r]Q
+ BnMod(bnR, order);
+ // Make -r = n - r
+ BnSub(bnRn, order, bnR);
+ // E = [s]G + [-r]Q
+ OK = BnPointMult(ecE, CurveGetG(C), bnS, ecQ, bnRn, E) == TPM_RC_SUCCESS;
+ // // reduce the x portion of E mod q
+ // OK = OK && BnMod(ecE->x, order);
+ // Convert to byte string
+ OK = OK && BnTo2B(ecE->x, &Ex2.b,
+ (NUMBYTES)(BITS_TO_BYTES(BnSizeInBits(order))));
+ if(OK)
+ {
+ // Ex = h(pE.x || digest)
+ CryptHashStart(&hashState, hashAlg);
+ CryptDigestUpdate(&hashState, Ex2.t.size, Ex2.t.buffer);
+ CryptDigestUpdate(&hashState, digest->t.size, digest->t.buffer);
+ Ex2.t.size = CryptHashEnd(&hashState, digestSize, Ex2.t.buffer);
+ SchnorrReduce(&Ex2.b, order);
+ BnFrom2B(bnEx, &Ex2.b);
+ // see if Ex matches R
+ OK = BnUnsignedCmp(bnEx, bnR) == 0;
+ }
+ return (OK) ? TPM_RC_SUCCESS : TPM_RC_SIGNATURE;
+}
+#endif // ALG_ECSCHNORR
+/* 10.2.12.3.10 CryptEccValidateSignature() */
+/* This function validates an EcDsa() or EcSchnorr() signature. The point Qin needs to have been
+ validated to be on the curve of curveId. */
+/* Error Returns Meaning */
+/* TPM_RC_SIGNATURE not a valid signature */
+LIB_EXPORT TPM_RC
+CryptEccValidateSignature(
+ TPMT_SIGNATURE *signature, // IN: signature to be verified
+ OBJECT *signKey, // IN: ECC key signed the hash
+ const TPM2B_DIGEST *digest // IN: digest that was signed
+ )
+{
+ CURVE_INITIALIZED(E, signKey->publicArea.parameters.eccDetail.curveID);
+ ECC_NUM(bnR);
+ ECC_NUM(bnS);
+ POINT_INITIALIZED(ecQ, &signKey->publicArea.unique.ecc);
+ bigConst order;
+ TPM_RC retVal;
+ if(E == NULL)
+ ERROR_RETURN(TPM_RC_VALUE);
+ order = CurveGetOrder(AccessCurveData(E));
+ // // Make sure that the scheme is valid
+ switch(signature->sigAlg)
+ {
+ case TPM_ALG_ECDSA:
+#if ALG_ECSCHNORR
+ case TPM_ALG_ECSCHNORR:
+#endif
+#if ALG_SM2
+ case TPM_ALG_SM2:
+#endif
+ break;
+ default:
+ ERROR_RETURN(TPM_RC_SCHEME);
+ break;
+ }
+ // Can convert r and s after determining that the scheme is an ECC scheme. If
+ // this conversion doesn't work, it means that the unmarshaling code for
+ // an ECC signature is broken.
+ BnFrom2B(bnR, &signature->signature.ecdsa.signatureR.b);
+ BnFrom2B(bnS, &signature->signature.ecdsa.signatureS.b);
+ // r and s have to be greater than 0 but less than the curve order
+ if(BnEqualZero(bnR) || BnEqualZero(bnS))
+ ERROR_RETURN(TPM_RC_SIGNATURE);
+ if((BnUnsignedCmp(bnS, order) >= 0)
+ || (BnUnsignedCmp(bnR, order) >= 0))
+ ERROR_RETURN(TPM_RC_SIGNATURE);
+ switch(signature->sigAlg)
+ {
+ case TPM_ALG_ECDSA:
+ retVal = BnValidateSignatureEcdsa(bnR, bnS, E, ecQ, digest);
+ break;
+#if ALG_ECSCHNORR
+ case TPM_ALG_ECSCHNORR:
+ retVal = BnValidateSignatureEcSchnorr(bnR, bnS,
+ signature->signature.any.hashAlg,
+ E, ecQ, digest);
+ break;
+#endif
+#if ALG_SM2
+ case TPM_ALG_SM2:
+ retVal = BnValidateSignatureEcSm2(bnR, bnS, E, ecQ, digest);
+ break;
+#endif
+ default:
+ FAIL(FATAL_ERROR_INTERNAL);
+ }
+ Exit:
+ CURVE_FREE(E);
+ return retVal;
+}
+/* 10.2.12.3.11 CryptEccCommitCompute() */
+/* This function performs the point multiply operations required by TPM2_Commit(). */
+/* If B or M is provided, they must be on the curve defined by curveId. This routine does not check
+ that they are on the curve and results are unpredictable if they are not. */
+/* It is a fatal error if r is NULL. If B is not NULL, then it is a fatal error if d is NULL or if K
+ and L are both NULL. If M is not NULL, then it is a fatal error if E is NULL. */
+/* Error Returns Meaning */
+/* TPM_RC_NO_RESULT if K, L or E was computed to be the point at infinity */
+/* TPM_RC_CANCELED a cancel indication was asserted during this function */
+LIB_EXPORT TPM_RC
+CryptEccCommitCompute(
+ TPMS_ECC_POINT *K, // OUT: [d]B or [r]Q
+ TPMS_ECC_POINT *L, // OUT: [r]B
+ TPMS_ECC_POINT *E, // OUT: [r]M
+ TPM_ECC_CURVE curveId, // IN: the curve for the computations
+ TPMS_ECC_POINT *M, // IN: M (optional)
+ TPMS_ECC_POINT *B, // IN: B (optional)
+ TPM2B_ECC_PARAMETER *d, // IN: d (optional)
+ TPM2B_ECC_PARAMETER *r // IN: the computed r value (required)
+ )
+{
+ CURVE_INITIALIZED(curve, curveId); // Normally initialize E as the curve, but E means
+ // something else in this function
+ ECC_INITIALIZED(bnR, r);
+ TPM_RC retVal = TPM_RC_SUCCESS;
+ //
+ // Validate that the required parameters are provided.
+ // Note: E has to be provided if computing E := [r]Q or E := [r]M. Will do
+ // E := [r]Q if both M and B are NULL.
+ pAssert(r != NULL && E != NULL);
+ // Initialize the output points in case they are not computed
+ ClearPoint2B(K);
+ ClearPoint2B(L);
+ ClearPoint2B(E);
+ // Sizes of the r parameter may not be zero
+ pAssert(r->t.size > 0);
+ // If B is provided, compute K=[d]B and L=[r]B
+ if(B != NULL)
+ {
+ ECC_INITIALIZED(bnD, d);
+ POINT_INITIALIZED(pB, B);
+ POINT(pK);
+ POINT(pL);
+ //
+ pAssert(d != NULL && K != NULL && L != NULL);
+ if(!BnIsOnCurve(pB, AccessCurveData(curve)))
+ ERROR_RETURN(TPM_RC_VALUE);
+ // do the math for K = [d]B
+ if((retVal = BnPointMult(pK, pB, bnD, NULL, NULL, curve)) != TPM_RC_SUCCESS)
+ goto Exit;
+ // Convert BN K to TPM2B K
+ BnPointTo2B(K, pK, curve);
+ // compute L= [r]B after checking for cancel
+ if(_plat__IsCanceled())
+ ERROR_RETURN(TPM_RC_CANCELED);
+ // compute L = [r]B
+ if(!BnIsValidPrivateEcc(bnR, curve))
+ ERROR_RETURN(TPM_RC_VALUE);
+ if((retVal = BnPointMult(pL, pB, bnR, NULL, NULL, curve)) != TPM_RC_SUCCESS)
+ goto Exit;
+ // Convert BN L to TPM2B L
+ BnPointTo2B(L, pL, curve);
+ }
+ if((M != NULL) || (B == NULL))
+ {
+ POINT_INITIALIZED(pM, M);
+ POINT(pE);
+ //
+ // Make sure that a place was provided for the result
+ pAssert(E != NULL);
+ // if this is the third point multiply, check for cancel first
+ if((B != NULL) && _plat__IsCanceled())
+ ERROR_RETURN(TPM_RC_CANCELED);
+ // If M provided, then pM will not be NULL and will compute E = [r]M.
+ // However, if M was not provided, then pM will be NULL and E = [r]G
+ // will be computed
+ if((retVal = BnPointMult(pE, pM, bnR, NULL, NULL, curve)) != TPM_RC_SUCCESS)
+ goto Exit;
+ // Convert E to 2B format
+ BnPointTo2B(E, pE, curve);
+ }
+ Exit:
+ CURVE_FREE(curve);
+ return retVal;
+}
+#endif // TPM_ALG_ECC
diff --git a/src/tpm2/crypto/openssl/CryptHash.c b/src/tpm2/crypto/openssl/CryptHash.c
new file mode 100644
index 0000000..cb5bd0f
--- /dev/null
+++ b/src/tpm2/crypto/openssl/CryptHash.c
@@ -0,0 +1,871 @@
+/********************************************************************************/
+/* */
+/* Implementation of cryptographic functions for hashing. */
+/* Written by Ken Goldman */
+/* IBM Thomas J. Watson Research Center */
+/* $Id: CryptHash.c 1658 2021-01-22 23:14:01Z kgoldman $ */
+/* */
+/* Licenses and Notices */
+/* */
+/* 1. Copyright Licenses: */
+/* */
+/* - Trusted Computing Group (TCG) grants to the user of the source code in */
+/* this specification (the "Source Code") a worldwide, irrevocable, */
+/* nonexclusive, royalty free, copyright license to reproduce, create */
+/* derivative works, distribute, display and perform the Source Code and */
+/* derivative works thereof, and to grant others the rights granted herein. */
+/* */
+/* - The TCG grants to the user of the other parts of the specification */
+/* (other than the Source Code) the rights to reproduce, distribute, */
+/* display, and perform the specification solely for the purpose of */
+/* developing products based on such documents. */
+/* */
+/* 2. Source Code Distribution Conditions: */
+/* */
+/* - Redistributions of Source Code must retain the above copyright licenses, */
+/* this list of conditions and the following disclaimers. */
+/* */
+/* - Redistributions in binary form must reproduce the above copyright */
+/* licenses, this list of conditions and the following disclaimers in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* 3. Disclaimers: */
+/* */
+/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
+/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
+/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
+/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
+/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
+/* information on specification licensing rights available through TCG */
+/* membership agreements. */
+/* */
+/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
+/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
+/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
+/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
+/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
+/* */
+/* - Without limitation, TCG and its members and licensors disclaim all */
+/* liability, including liability for infringement of any proprietary */
+/* rights, relating to use of information in this specification and to the */
+/* implementation of this specification, and TCG disclaims all liability for */
+/* cost of procurement of substitute goods or services, lost profits, loss */
+/* of use, loss of data or any incidental, consequential, direct, indirect, */
+/* or special damages, whether under contract, tort, warranty or otherwise, */
+/* arising in any way out of use or reliance upon this specification or any */
+/* information herein. */
+/* */
+/* (c) Copyright IBM Corp. and others, 2016 - 2021 */
+/* */
+/********************************************************************************/
+
+/* 10.2.13 CryptHash.c */
+/* 10.2.13.1 Description */
+/* This file contains implementation of cryptographic functions for hashing. */
+/* 10.2.13.2 Includes, Defines, and Types */
+#define _CRYPT_HASH_C_
+#include "Tpm.h"
+#include "CryptHash_fp.h"
+#include "CryptHash.h"
+#include "OIDs.h"
+
+/* Instance each of the hash descriptors based on the implemented algorithms */
+
+FOR_EACH_HASH(HASH_DEF_TEMPLATE)
+
+/* Instance a null def. */
+
+ HASH_DEF NULL_Def = {{0}};
+
+/* Create a table of pointers to the defined hash definitions */
+
+#define HASH_DEF_ENTRY(HASH, Hash) &Hash##_Def,
+PHASH_DEF HashDefArray[] = {
+ // for each implemented HASH, expands to: &HASH_Def,
+ FOR_EACH_HASH(HASH_DEF_ENTRY)
+ &NULL_Def
+};
+
+/* 10.2.13.3 Obligatory Initialization Functions */
+/* 10.2.13.3.1 CryptHashInit() */
+/* This function is called by _TPM_Init() do perform the initialization operations for the
+ library. */
+BOOL
+CryptHashInit(
+ void
+ )
+{
+ LibHashInit();
+ return TRUE;
+}
+/* 10.2.13.3.2 CryptHashStartup() */
+/* This function is called by TPM2_Startup(). It checks that the size of the HashDefArray() is
+ consistent with the HASH_COUNT. */
+BOOL
+CryptHashStartup(
+ void
+ )
+{
+ int i = sizeof(HashDefArray) / sizeof(PHASH_DEF) - 1;
+ return (i == HASH_COUNT);
+}
+/* 10.2.13.4 Hash Information Access Functions */
+/* 10.2.13.4.1 Introduction */
+/* These functions provide access to the hash algorithm description information. */
+/* 10.2.13.4.2 CryptGetHashDef() */
+/* This function accesses the hash descriptor associated with a hash a algorithm. The function
+ returns a pointer to a null descriptor if hashAlg is TPM_ALG_NULL or not a defined algorithm. */
+
+PHASH_DEF
+CryptGetHashDef(
+ TPM_ALG_ID hashAlg
+ )
+{
+#define GET_DEF(HASH, Hash) case ALG_##HASH##_VALUE: return &Hash##_Def;
+ switch(hashAlg)
+ {
+ FOR_EACH_HASH(GET_DEF)
+ default:
+ return &NULL_Def;
+ }
+#undef GET_DEF
+}
+/* 10.2.13.4.3 CryptHashIsValidAlg() */
+/* This function tests to see if an algorithm ID is a valid hash algorithm. If flag is true, then
+ TPM_ALG_NULL is a valid hash. */
+/* Return Value Meaning */
+/* TRUE(1) hashAlg is a valid, implemented hash on this TPM */
+/* FALSE(0) hashAlg is not valid for this TPM */
+BOOL
+CryptHashIsValidAlg(
+ TPM_ALG_ID hashAlg, // IN: the algorithm to check
+ BOOL flag // IN: TRUE if TPM_ALG_NULL is to be treated
+ // as a valid hash
+ )
+{
+ if(hashAlg == TPM_ALG_NULL)
+ return flag;
+ return CryptGetHashDef(hashAlg) != &NULL_Def;
+}
+/* 10.2.13.4.4 CryptHashGetAlgByIndex() */
+/* This function is used to iterate through the hashes. TPM_ALG_NULL is returned for all indexes
+ that are not valid hashes. If the TPM implements 3 hashes, then an index value of 0 will return
+ the first implemented hash and an index of 2 will return the last. All other index values will
+ return TPM_ALG_NULL. */
+/* Return Value Meaning */
+/* TPM_ALG_xxx a hash algorithm */
+/* TPM_ALG_NULL this can be used as a stop value */
+LIB_EXPORT TPM_ALG_ID
+CryptHashGetAlgByIndex(
+ UINT32 index // IN: the index
+ )
+{
+ TPM_ALG_ID hashAlg;
+ if(index >= HASH_COUNT)
+ hashAlg = TPM_ALG_NULL;
+ else
+ hashAlg = HashDefArray[index]->hashAlg;
+ return hashAlg;
+}
+/* 10.2.13.4.5 CryptHashGetDigestSize() */
+/* Returns the size of the digest produced by the hash. If hashAlg is not a hash algorithm, the TPM
+ will FAIL. */
+/* Return Value Meaning */
+/* 0 TPM_ALG_NULL */
+/* > 0 the digest size */
+LIB_EXPORT UINT16
+CryptHashGetDigestSize(
+ TPM_ALG_ID hashAlg // IN: hash algorithm to look up
+ )
+{
+ return CryptGetHashDef(hashAlg)->digestSize;
+}
+/* 10.2.13.4.6 CryptHashGetBlockSize() */
+/* Returns the size of the block used by the hash. If hashAlg is not a hash algorithm, the TPM will
+ FAIL. */
+/* Return Value Meaning */
+/* 0 TPM_ALG_NULL */
+/* > 0 the digest size */
+LIB_EXPORT UINT16
+CryptHashGetBlockSize(
+ TPM_ALG_ID hashAlg // IN: hash algorithm to look up
+ )
+{
+ return CryptGetHashDef(hashAlg)->blockSize;
+}
+/* 10.2.13.4.7 CryptHashGetOid() */
+/* This function returns a pointer to DER=encoded OID for a hash algorithm. All OIDs are full OID
+ values including the Tag (0x06) and length byte. */
+#if 0 // libtpms added
+LIB_EXPORT const BYTE *
+CryptHashGetOid(
+ TPM_ALG_ID hashAlg
+ )
+{
+ return CryptGetHashDef(hashAlg)->OID;
+}
+#endif // libtpms added
+/* 10.2.13.4.8 CryptHashGetContextAlg() */
+/* This function returns the hash algorithm associated with a hash context. */
+#if 0 // libtpms added
+TPM_ALG_ID
+CryptHashGetContextAlg(
+ PHASH_STATE state // IN: the context to check
+ )
+{
+ return state->hashAlg;
+}
+#endif // libtpms added
+/* 10.2.13.5 State Import and Export */
+/* 10.2.13.5.1 CryptHashCopyState */
+/* This function is used to clone a HASH_STATE. */
+#if 0 // libtpms added
+LIB_EXPORT void
+CryptHashCopyState(
+ HASH_STATE *out, // OUT: destination of the state
+ const HASH_STATE *in // IN: source of the state
+ )
+{
+ pAssert(out->type == in->type);
+ out->hashAlg = in->hashAlg;
+ out->def = in->def;
+ if(in->hashAlg != TPM_ALG_NULL)
+ {
+ HASH_STATE_COPY(out, in);
+ }
+ if(in->type == HASH_STATE_HMAC)
+ {
+ const HMAC_STATE *hIn = (HMAC_STATE *)in;
+ HMAC_STATE *hOut = (HMAC_STATE *)out;
+ hOut->hmacKey = hIn->hmacKey;
+ }
+ return;
+}
+#endif // libtpms added
+#if 0 // libtpms added
+/* 10.2.13.5.2 CryptHashExportState() */
+/* This function is used to export a hash or HMAC hash state. This function would be called when
+ preparing to context save a sequence object. */
+void
+CryptHashExportState(
+ PCHASH_STATE internalFmt, // IN: the hash state formatted for use by
+ // library
+ PEXPORT_HASH_STATE externalFmt // OUT: the exported hash state
+ )
+{
+ BYTE *outBuf = (BYTE *)externalFmt;
+ //
+ cAssert(sizeof(HASH_STATE) <= sizeof(EXPORT_HASH_STATE));
+ // the following #define is used to move data from an aligned internal data
+ // structure to a byte buffer (external format data.
+#define CopyToOffset(value) \
+ memcpy(&outBuf[offsetof(HASH_STATE,value)], &internalFmt->value, \
+ sizeof(internalFmt->value))
+ // Copy the hashAlg
+ CopyToOffset(hashAlg);
+ CopyToOffset(type);
+#ifdef HASH_STATE_SMAC
+ if(internalFmt->type == HASH_STATE_SMAC)
+ {
+ memcpy(outBuf, internalFmt, sizeof(HASH_STATE));
+ return;
+
+ }
+#endif
+ if(internalFmt->type == HASH_STATE_HMAC)
+ {
+ HMAC_STATE *from = (HMAC_STATE *)internalFmt;
+ memcpy(&outBuf[offsetof(HMAC_STATE, hmacKey)], &from->hmacKey,
+ sizeof(from->hmacKey));
+ }
+ if(internalFmt->hashAlg != TPM_ALG_NULL)
+ HASH_STATE_EXPORT(externalFmt, internalFmt);
+}
+/* 10.2.13.5.3 CryptHashImportState() */
+/* This function is used to import the hash state. This function would be called to import a hash
+ state when the context of a sequence object was being loaded. */
+void
+CryptHashImportState(
+ PHASH_STATE internalFmt, // OUT: the hash state formatted for use by
+ // the library
+ PCEXPORT_HASH_STATE externalFmt // IN: the exported hash state
+ )
+{
+ BYTE *inBuf = (BYTE *)externalFmt;
+ //
+#define CopyFromOffset(value) \
+ memcpy(&internalFmt->value, &inBuf[offsetof(HASH_STATE,value)], \
+ sizeof(internalFmt->value))
+
+ // Copy the hashAlg of the byte-aligned input structure to the structure-aligned
+ // internal structure.
+ CopyFromOffset(hashAlg);
+ CopyFromOffset(type);
+ if(internalFmt->hashAlg != TPM_ALG_NULL)
+ {
+#ifdef HASH_STATE_SMAC
+ if(internalFmt->type == HASH_STATE_SMAC)
+ {
+ memcpy(internalFmt, inBuf, sizeof(HASH_STATE));
+ return;
+ }
+#endif
+ internalFmt->def = CryptGetHashDef(internalFmt->hashAlg);
+ HASH_STATE_IMPORT(internalFmt, inBuf);
+ if(internalFmt->type == HASH_STATE_HMAC)
+ {
+ HMAC_STATE *to = (HMAC_STATE *)internalFmt;
+ memcpy(&to->hmacKey, &inBuf[offsetof(HMAC_STATE, hmacKey)],
+ sizeof(to->hmacKey));
+ }
+ }
+}
+#endif // libtpms added
+/* 10.2.13.6 State Modification Functions */
+/* 10.2.13.6.1 HashEnd() */
+/* Local function to complete a hash that uses the hashDef instead of an algorithm ID. This function
+ is used to complete the hash and only return a partial digest. The return value is the size of
+ the data copied. */
+static UINT16
+HashEnd(
+ PHASH_STATE hashState, // IN: the hash state
+ UINT32 dOutSize, // IN: the size of receive buffer
+ PBYTE dOut // OUT: the receive buffer
+ )
+{
+ BYTE temp[MAX_DIGEST_SIZE];
+ if((hashState->hashAlg == TPM_ALG_NULL)
+ || (hashState->type != HASH_STATE_HASH))
+ dOutSize = 0;
+ if(dOutSize > 0)
+ {
+ hashState->def = CryptGetHashDef(hashState->hashAlg);
+ // Set the final size
+ dOutSize = MIN(dOutSize, hashState->def->digestSize);
+ // Complete into the temp buffer and then copy
+ HASH_END(hashState, temp);
+ // Don't want any other functions calling the HASH_END method
+ // directly.
+#undef HASH_END
+ memcpy(dOut, &temp, dOutSize);
+ }
+ hashState->type = HASH_STATE_EMPTY;
+ return (UINT16)dOutSize;
+}
+/* 10.2.13.6.2 CryptHashStart() */
+/* Functions starts a hash stack Start a hash stack and returns the digest size. As a side effect,
+ the value of stateSize in hashState is updated to indicate the number of bytes of state that were
+ saved. This function calls GetHashServer() and that function will put the TPM into failure mode
+ if the hash algorithm is not supported. */
+/* This function does not use the sequence parameter. If it is necessary to import or export
+ context, this will start the sequence in a local state and export the state to the input
+ buffer. Will need to add a flag to the state structure to indicate that it needs to be imported
+ before it can be used. (BLEH). */
+/* Return Value Meaning */
+/* 0 hash is TPM_ALG_NULL */
+/* >0 digest size */
+LIB_EXPORT UINT16
+CryptHashStart(
+ PHASH_STATE hashState, // OUT: the running hash state
+ TPM_ALG_ID hashAlg // IN: hash algorithm
+ )
+{
+ UINT16 retVal;
+
+ TEST(hashAlg);
+
+ hashState->hashAlg = hashAlg;
+ if(hashAlg == TPM_ALG_NULL)
+ {
+ retVal = 0;
+ }
+ else
+ {
+ hashState->def = CryptGetHashDef(hashAlg);
+ HASH_START(hashState);
+ retVal = hashState->def->digestSize;
+ }
+#undef HASH_START
+ hashState->type = HASH_STATE_HASH;
+ return retVal;
+}
+/* 10.2.13.6.3 CryptDigestUpdate() */
+/* Add data to a hash or HMAC, SMAC stack. */
+void
+CryptDigestUpdate(
+ PHASH_STATE hashState, // IN: the hash context information
+ UINT32 dataSize, // IN: the size of data to be added
+ const BYTE *data // IN: data to be hashed
+ )
+{
+ if(hashState->hashAlg != TPM_ALG_NULL)
+ {
+ if((hashState->type == HASH_STATE_HASH)
+ || (hashState->type == HASH_STATE_HMAC))
+ HASH_DATA(hashState, dataSize, (BYTE *)data);
+#if SMAC_IMPLEMENTED
+ else if(hashState->type == HASH_STATE_SMAC)
+ (hashState->state.smac.smacMethods.data)(&hashState->state.smac.state,
+ dataSize, data);
+#endif // SMAC_IMPLEMENTED
+ else
+ FAIL(FATAL_ERROR_INTERNAL);
+ }
+ return;
+}
+/* 10.2.13.6.4 CryptHashEnd() */
+/* Complete a hash or HMAC computation. This function will place the smaller of digestSize or the
+ size of the digest in dOut. The number of bytes in the placed in the buffer is returned. If there
+ is a failure, the returned value is <= 0. */
+/* Return Value Meaning */
+/* 0 no data returned */
+/* > 0 the number of bytes in the digest or dOutSize, whichever is smaller */
+LIB_EXPORT UINT16
+CryptHashEnd(
+ PHASH_STATE hashState, // IN: the state of hash stack
+ UINT32 dOutSize, // IN: size of digest buffer
+ BYTE *dOut // OUT: hash digest
+ )
+{
+ pAssert(hashState->type == HASH_STATE_HASH);
+ return HashEnd(hashState, dOutSize, dOut);
+}
+/* 10.2.13.6.5 CryptHashBlock() */
+/* Start a hash, hash a single block, update digest and return the size of the results. */
+/* The digestSize parameter can be smaller than the digest. If so, only the more significant
+ bytes are returned. */
+/* Return Value Meaning */
+/* >= 0 number of bytes placed in dOut */
+LIB_EXPORT UINT16
+CryptHashBlock(
+ TPM_ALG_ID hashAlg, // IN: The hash algorithm
+ UINT32 dataSize, // IN: size of buffer to hash
+ const BYTE *data, // IN: the buffer to hash
+ UINT32 dOutSize, // IN: size of the digest buffer
+ BYTE *dOut // OUT: digest buffer
+ )
+{
+ HASH_STATE state;
+ CryptHashStart(&state, hashAlg);
+ CryptDigestUpdate(&state, dataSize, data);
+ return HashEnd(&state, dOutSize, dOut);
+}
+/* 10.2.13.6.6 CryptDigestUpdate2B() */
+/* This function updates a digest (hash or HMAC) with a TPM2B. */
+/* This function can be used for both HMAC and hash functions so the digestState is void so that
+ either state type can be passed. */
+LIB_EXPORT void
+CryptDigestUpdate2B(
+ PHASH_STATE state, // IN: the digest state
+ const TPM2B *bIn // IN: 2B containing the data
+ )
+{
+ // Only compute the digest if a pointer to the 2B is provided.
+ // In CryptDigestUpdate(), if size is zero or buffer is NULL, then no change
+ // to the digest occurs. This function should not provide a buffer if bIn is
+ // not provided.
+ pAssert(bIn != NULL);
+ CryptDigestUpdate(state, bIn->size, bIn->buffer);
+ return;
+}
+/* 10.2.13.6.7 CryptHashEnd2B() */
+/* This function is the same as CryptCompleteHash() but the digest is placed in a TPM2B. This is the
+ most common use and this is provided for specification clarity. digest.size should be set to
+ indicate the number of bytes to place in the buffer */
+/* Return Value Meaning */
+/* >=0 the number of bytes placed in digest.buffer */
+LIB_EXPORT UINT16
+CryptHashEnd2B(
+ PHASH_STATE state, // IN: the hash state
+ P2B digest // IN: the size of the buffer Out: requested
+ // number of bytes
+ )
+{
+ return CryptHashEnd(state, digest->size, digest->buffer);
+}
+/* 10.2.13.6.8 CryptDigestUpdateInt() */
+/* This function is used to include an integer value to a hash stack. The function marshals the
+ integer into its canonical form before calling CryptDigestUpdate(). */
+LIB_EXPORT void
+CryptDigestUpdateInt(
+ void *state, // IN: the state of hash stack
+ UINT32 intSize, // IN: the size of 'intValue' in bytes
+ UINT64 intValue // IN: integer value to be hashed
+ )
+{
+#if LITTLE_ENDIAN_TPM
+ intValue = REVERSE_ENDIAN_64(intValue);
+#endif
+ CryptDigestUpdate(state, intSize, &((BYTE *)&intValue)[8 - intSize]);
+}
+/* 10.2.13.7 HMAC Functions */
+/* 10.2.13.7.1 CryptHmacStart() */
+/* This function is used to start an HMAC using a temp hash context. The function does the
+ initialization of the hash with the HMAC key XOR iPad and updates the HMAC key XOR oPad. */
+/* The function returns the number of bytes in a digest produced by hashAlg. */
+/* Return Value Meaning */
+/* >= 0 number of bytes in digest produced by hashAlg (may be zero) */
+LIB_EXPORT UINT16
+CryptHmacStart(
+ PHMAC_STATE state, // IN/OUT: the state buffer
+ TPM_ALG_ID hashAlg, // IN: the algorithm to use
+ UINT16 keySize, // IN: the size of the HMAC key
+ const BYTE *key // IN: the HMAC key
+ )
+{
+ PHASH_DEF hashDef;
+ BYTE * pb;
+ UINT32 i;
+ //
+ hashDef = CryptGetHashDef(hashAlg);
+ if(hashDef->digestSize != 0)
+ {
+ // If the HMAC key is larger than the hash block size, it has to be reduced
+ // to fit. The reduction is a digest of the hashKey.
+ if(keySize > hashDef->blockSize)
+ {
+ // if the key is too big, reduce it to a digest of itself
+ state->hmacKey.t.size = CryptHashBlock(hashAlg, keySize, key,
+ hashDef->digestSize,
+ state->hmacKey.t.buffer);
+ }
+ else
+ {
+ memcpy(state->hmacKey.t.buffer, key, keySize);
+ state->hmacKey.t.size = keySize;
+ }
+ // XOR the key with iPad (0x36)
+ pb = state->hmacKey.t.buffer;
+ for(i = state->hmacKey.t.size; i > 0; i--)
+ *pb++ ^= 0x36;
+
+ // if the keySize is smaller than a block, fill the rest with 0x36
+ for(i = hashDef->blockSize - state->hmacKey.t.size; i > 0; i--)
+ *pb++ = 0x36;
+
+ // Increase the oPadSize to a full block
+ state->hmacKey.t.size = hashDef->blockSize;
+
+ // Start a new hash with the HMAC key
+ // This will go in the caller's state structure and may be a sequence or not
+ CryptHashStart((PHASH_STATE)state, hashAlg);
+ CryptDigestUpdate((PHASH_STATE)state, state->hmacKey.t.size,
+ state->hmacKey.t.buffer);
+ // XOR the key block with 0x5c ^ 0x36
+ for(pb = state->hmacKey.t.buffer, i = hashDef->blockSize; i > 0; i--)
+ *pb++ ^= (0x5c ^ 0x36);
+ }
+ // Set the hash algorithm
+ state->hashState.hashAlg = hashAlg;
+ // Set the hash state type
+ state->hashState.type = HASH_STATE_HMAC;
+
+ return hashDef->digestSize;
+}
+/* 10.2.13.7.2 CryptHmacEnd() */
+/* This function is called to complete an HMAC. It will finish the current digest, and start a new digest. It will then add the oPadKey and the completed digest and return the results in dOut. It will not return more than dOutSize bytes. */
+/* Return Value Meaning */
+/* >= 0 number of bytes in dOut (may be zero) */
+LIB_EXPORT UINT16
+CryptHmacEnd(
+ PHMAC_STATE state, // IN: the hash state buffer
+ UINT32 dOutSize, // IN: size of digest buffer
+ BYTE *dOut // OUT: hash digest
+ )
+{
+ BYTE temp[MAX_DIGEST_SIZE];
+ PHASH_STATE hState = (PHASH_STATE)&state->hashState;
+
+#if SMAC_IMPLEMENTED
+ if(hState->type == HASH_STATE_SMAC)
+ return (state->hashState.state.smac.smacMethods.end)
+ (&state->hashState.state.smac.state,
+ dOutSize,
+ dOut);
+#endif
+ pAssert(hState->type == HASH_STATE_HMAC);
+ hState->def = CryptGetHashDef(hState->hashAlg);
+ // Change the state type for completion processing
+ hState->type = HASH_STATE_HASH;
+ if(hState->hashAlg == TPM_ALG_NULL)
+ dOutSize = 0;
+ else
+ {
+
+ // Complete the current hash
+ HashEnd(hState, hState->def->digestSize, temp);
+ // Do another hash starting with the oPad
+ CryptHashStart(hState, hState->hashAlg);
+ CryptDigestUpdate(hState, state->hmacKey.t.size, state->hmacKey.t.buffer);
+ CryptDigestUpdate(hState, hState->def->digestSize, temp);
+ }
+ return HashEnd(hState, dOutSize, dOut);
+}
+/* 10.2.13.7.3 CryptHmacStart2B() */
+/* This function starts an HMAC and returns the size of the digest that will be produced. */
+/* This function is provided to support the most common use of starting an HMAC with a TPM2B key. */
+/* The caller must provide a block of memory in which the hash sequence state is kept. The caller
+ should not alter the contents of this buffer until the hash sequence is completed or
+ abandoned. */
+/* Return Value Meaning */
+/* > 0 the digest size of the algorithm */
+/* = 0 the hashAlg was TPM_ALG_NULL */
+LIB_EXPORT UINT16
+CryptHmacStart2B(
+ PHMAC_STATE hmacState, // OUT: the state of HMAC stack. It will be used
+ // in HMAC update and completion
+ TPMI_ALG_HASH hashAlg, // IN: hash algorithm
+ P2B key // IN: HMAC key
+ )
+{
+ return CryptHmacStart(hmacState, hashAlg, key->size, key->buffer);
+}
+ /* 10.2.13.7.4 CryptHmacEnd2B() */
+ /* This function is the same as CryptHmacEnd() but the HMAC result is returned in a TPM2B which is the most common use. */
+ /* Return Value Meaning */
+ /* >=0 the number of bytes placed in digest */
+LIB_EXPORT UINT16
+CryptHmacEnd2B(
+ PHMAC_STATE hmacState, // IN: the state of HMAC stack
+ P2B digest // OUT: HMAC
+ )
+{
+ return CryptHmacEnd(hmacState, digest->size, digest->buffer);
+}
+/* 10.2.13.8 Mask and Key Generation Functions */
+/* 10.2.13.8.1 CryptMGF_KDF() */
+/* This function performs MGF1/KDF1 or KDF2 using the selected hash. KDF1 and KDF2 are T(n) = T(n-1)
+ || H(seed || counter) with the difference being that, with KDF1, counter starts at 0 but with
+ KDF2, counter starts at 1. The caller determines which version by setting the initial value of
+ counter to either 0 or 1. */
+/* Return Value Meaning */
+/* 0 hash algorithm was TPM_ALG_NULL */
+/* > 0 should be the same as mSize */
+LIB_EXPORT UINT16
+CryptMGF_KDF(
+ UINT32 mSize, // IN: length of the mask to be produced
+ BYTE *mask, // OUT: buffer to receive the mask
+ TPM_ALG_ID hashAlg, // IN: hash to use
+ UINT32 seedSize, // IN: size of the seed
+ BYTE *seed, // IN: seed size
+ UINT32 counter // IN: counter initial value
+ )
+{
+ HASH_STATE hashState;
+ PHASH_DEF hDef = CryptGetHashDef(hashAlg);
+ UINT32 hLen;
+ UINT32 bytes;
+ //
+ // If there is no digest to compute return
+ if((hDef->digestSize == 0) || (mSize == 0))
+ return 0;
+ if(counter != 0)
+ counter = 1;
+ hLen = hDef->digestSize;
+ for(bytes = 0; bytes < mSize; bytes += hLen)
+ {
+ // Start the hash and include the seed and counter
+ CryptHashStart(&hashState, hashAlg);
+ CryptDigestUpdate(&hashState, seedSize, seed);
+ CryptDigestUpdateInt(&hashState, 4, counter);
+ // Get as much as will fit.
+ CryptHashEnd(&hashState, MIN((mSize - bytes), hLen),
+ &mask[bytes]);
+ counter++;
+ }
+ return (UINT16)mSize;
+}
+/* 10.2.13.8.2 CryptKDFa() */
+/* This function performs the key generation according to Part 1 of the TPM specification. */
+/* This function returns the number of bytes generated which may be zero. */
+/* The key and keyStream pointers are not allowed to be NULL. The other pointer values may be
+ NULL. The value of sizeInBits must be no larger than (2^18)-1 = 256K bits (32385 bytes). */
+/* The once parameter is set to allow incremental generation of a large value. If this flag is
+ TRUE, sizeInBits will be used in the HMAC computation but only one iteration of the KDF is
+ performed. This would be used for XOR obfuscation so that the mask value can be generated in
+ digest-sized chunks rather than having to be generated all at once in an arbitrarily large
+ buffer and then XORed into the result. If once is TRUE, then sizeInBits must be a multiple of
+ 8. */
+/* Any error in the processing of this command is considered fatal. */
+/* Return Value Meaning */
+/* 0 hash algorithm is not supported or is TPM_ALG_NULL */
+/* > 0 the number of bytes in the keyStream buffer */
+LIB_EXPORT UINT16
+CryptKDFa(
+ TPM_ALG_ID hashAlg, // IN: hash algorithm used in HMAC
+ const TPM2B *key, // IN: HMAC key
+ const TPM2B *label, // IN: a label for the KDF
+ const TPM2B *contextU, // IN: context U
+ const TPM2B *contextV, // IN: context V
+ UINT32 sizeInBits, // IN: size of generated key in bits
+ BYTE *keyStream, // OUT: key buffer
+ UINT32 *counterInOut, // IN/OUT: caller may provide the iteration
+ // counter for incremental operations to
+ // avoid large intermediate buffers.
+ UINT16 blocks // IN: If non-zero, this is the maximum number
+ // of blocks to be returned, regardless
+ // of sizeInBits
+ )
+{
+ UINT32 counter = 0; // counter value
+ INT16 bytes; // number of bytes to produce
+ UINT16 generated; // number of bytes generated
+ BYTE *stream = keyStream;
+ HMAC_STATE hState;
+ UINT16 digestSize = CryptHashGetDigestSize(hashAlg);
+
+ pAssert(key != NULL && keyStream != NULL);
+
+ TEST(TPM_ALG_KDF1_SP800_108);
+
+ if(digestSize == 0)
+ return 0;
+
+ if(counterInOut != NULL)
+ counter = *counterInOut;
+
+ // If the size of the request is larger than the numbers will handle,
+ // it is a fatal error.
+ pAssert(((sizeInBits + 7) / 8) <= INT16_MAX);
+
+ // The number of bytes to be generated is the smaller of the sizeInBits bytes or
+ // the number of requested blocks. The number of blocks is the smaller of the
+ // number requested or the number allowed by sizeInBits. A partial block is
+ // a full block.
+ bytes = (blocks > 0) ? blocks * digestSize : (UINT16)BITS_TO_BYTES(sizeInBits);
+ generated = bytes;
+
+ // Generate required bytes
+ for(; bytes > 0; bytes -= digestSize)
+ {
+ counter++;
+ // Start HMAC
+ if(CryptHmacStart(&hState, hashAlg, key->size, key->buffer) == 0)
+ return 0;
+ // Adding counter
+ CryptDigestUpdateInt(&hState.hashState, 4, counter);
+
+ // Adding label
+ if(label != NULL)
+ HASH_DATA(&hState.hashState, label->size, (BYTE *)label->buffer);
+ // Add a null. SP108 is not very clear about when the 0 is needed but to
+ // make this like the previous version that did not add an 0x00 after
+ // a null-terminated string, this version will only add a null byte
+ // if the label parameter did not end in a null byte, or if no label
+ // is present.
+ if((label == NULL)
+ || (label->size == 0)
+ || (label->buffer[label->size - 1] != 0))
+ CryptDigestUpdateInt(&hState.hashState, 1, 0);
+ // Adding contextU
+ if(contextU != NULL)
+ HASH_DATA(&hState.hashState, contextU->size, contextU->buffer);
+ // Adding contextV
+ if(contextV != NULL)
+ HASH_DATA(&hState.hashState, contextV->size, contextV->buffer);
+ // Adding size in bits
+ CryptDigestUpdateInt(&hState.hashState, 4, sizeInBits);
+
+ // Complete and put the data in the buffer
+ CryptHmacEnd(&hState, bytes, stream);
+ stream = &stream[digestSize];
+ }
+ // Masking in the KDF is disabled. If the calling function wants something
+ // less than even number of bytes, then the caller should do the masking
+ // because there is no universal way to do it here
+ if(counterInOut != NULL)
+ *counterInOut = counter;
+ return generated;
+}
+/* 10.2.13.8.3 CryptKDFe() */
+/* This function implements KDFe() as defined in TPM specification part 1. */
+/* This function returns the number of bytes generated which may be zero. */
+/* The Z and keyStream pointers are not allowed to be NULL. The other pointer values may be
+ NULL. The value of sizeInBits must be no larger than (2^18)-1 = 256K bits (32385 bytes). Any
+ error in the processing of this command is considered fatal. */
+/* Return Value Meaning */
+/* 0 hash algorithm is not supported or is TPM_ALG_NULL */
+/* > 0 the number of bytes in the keyStream buffer */
+LIB_EXPORT UINT16
+CryptKDFe(
+ TPM_ALG_ID hashAlg, // IN: hash algorithm used in HMAC
+ TPM2B *Z, // IN: Z
+ const TPM2B *label, // IN: a label value for the KDF
+ TPM2B *partyUInfo, // IN: PartyUInfo
+ TPM2B *partyVInfo, // IN: PartyVInfo
+ UINT32 sizeInBits, // IN: size of generated key in bits
+ BYTE *keyStream // OUT: key buffer
+ )
+{
+ HASH_STATE hashState;
+ PHASH_DEF hashDef = CryptGetHashDef(hashAlg);
+
+ UINT32 counter = 0; // counter value
+ UINT16 hLen;
+ BYTE *stream = keyStream;
+ INT16 bytes; // number of bytes to generate
+
+ pAssert(keyStream != NULL && Z != NULL && ((sizeInBits + 7) / 8) < INT16_MAX);
+ //
+ hLen = hashDef->digestSize;
+ bytes = (INT16)((sizeInBits + 7) / 8);
+ if(hashAlg == TPM_ALG_NULL || bytes == 0)
+ return 0;
+
+ // Generate required bytes
+ //The inner loop of that KDF uses:
+ // Hash[i] := H(counter | Z | OtherInfo) (5)
+ // Where:
+ // Hash[i] the hash generated on the i-th iteration of the loop.
+ // H() an approved hash function
+ // counter a 32-bit counter that is initialized to 1 and incremented
+ // on each iteration
+ // Z the X coordinate of the product of a public ECC key and a
+ // different private ECC key.
+ // OtherInfo a collection of qualifying data for the KDF defined below.
+ // In this specification, OtherInfo will be constructed by:
+ // OtherInfo := Use | PartyUInfo | PartyVInfo
+ for(; bytes > 0; stream = &stream[hLen], bytes = bytes - hLen)
+ {
+ if(bytes < hLen)
+ hLen = bytes;
+ counter++;
+ // Do the hash
+ CryptHashStart(&hashState, hashAlg);
+ // Add counter
+ CryptDigestUpdateInt(&hashState, 4, counter);
+
+ // Add Z
+ if(Z != NULL)
+ CryptDigestUpdate2B(&hashState, Z);
+ // Add label
+ if(label != NULL)
+ CryptDigestUpdate2B(&hashState, label);
+ // Add a null. SP108 is not very clear about when the 0 is needed but to
+ // make this like the previous version that did not add an 0x00 after
+ // a null-terminated string, this version will only add a null byte
+ // if the label parameter did not end in a null byte, or if no label
+ // is present.
+ if((label == NULL)
+ || (label->size == 0)
+ || (label->buffer[label->size - 1] != 0))
+ CryptDigestUpdateInt(&hashState, 1, 0);
+ // Add PartyUInfo
+ if(partyUInfo != NULL)
+ CryptDigestUpdate2B(&hashState, partyUInfo);
+
+ // Add PartyVInfo
+ if(partyVInfo != NULL)
+ CryptDigestUpdate2B(&hashState, partyVInfo);
+
+ // Compute Hash. hLen was changed to be the smaller of bytes or hLen
+ // at the start of each iteration.
+ CryptHashEnd(&hashState, hLen, stream);
+ }
+
+ // Mask off bits if the required bits is not a multiple of byte size
+ if((sizeInBits % 8) != 0)
+ keyStream[0] &= ((1 << (sizeInBits % 8)) - 1);
+
+ return (UINT16)((sizeInBits + 7) / 8);
+}
diff --git a/src/tpm2/crypto/openssl/CryptPrime.c b/src/tpm2/crypto/openssl/CryptPrime.c
new file mode 100644
index 0000000..0de9ef2
--- /dev/null
+++ b/src/tpm2/crypto/openssl/CryptPrime.c
@@ -0,0 +1,440 @@
+/********************************************************************************/
+/* */
+/* Code for prime validation. */
+/* Written by Ken Goldman */
+/* IBM Thomas J. Watson Research Center */
+/* $Id: CryptPrime.c 1529 2019-11-21 23:29:01Z kgoldman $ */
+/* */
+/* Licenses and Notices */
+/* */
+/* 1. Copyright Licenses: */
+/* */
+/* - Trusted Computing Group (TCG) grants to the user of the source code in */
+/* this specification (the "Source Code") a worldwide, irrevocable, */
+/* nonexclusive, royalty free, copyright license to reproduce, create */
+/* derivative works, distribute, display and perform the Source Code and */
+/* derivative works thereof, and to grant others the rights granted herein. */
+/* */
+/* - The TCG grants to the user of the other parts of the specification */
+/* (other than the Source Code) the rights to reproduce, distribute, */
+/* display, and perform the specification solely for the purpose of */
+/* developing products based on such documents. */
+/* */
+/* 2. Source Code Distribution Conditions: */
+/* */
+/* - Redistributions of Source Code must retain the above copyright licenses, */
+/* this list of conditions and the following disclaimers. */
+/* */
+/* - Redistributions in binary form must reproduce the above copyright */
+/* licenses, this list of conditions and the following disclaimers in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* 3. Disclaimers: */
+/* */
+/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
+/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
+/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
+/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
+/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
+/* information on specification licensing rights available through TCG */
+/* membership agreements. */
+/* */
+/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
+/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
+/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
+/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
+/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
+/* */
+/* - Without limitation, TCG and its members and licensors disclaim all */
+/* liability, including liability for infringement of any proprietary */
+/* rights, relating to use of information in this specification and to the */
+/* implementation of this specification, and TCG disclaims all liability for */
+/* cost of procurement of substitute goods or services, lost profits, loss */
+/* of use, loss of data or any incidental, consequential, direct, indirect, */
+/* or special damages, whether under contract, tort, warranty or otherwise, */
+/* arising in any way out of use or reliance upon this specification or any */
+/* information herein. */
+/* */
+/* (c) Copyright IBM Corp. and others, 2016 - 2019 */
+/* */
+/********************************************************************************/
+
+/* 10.2.14 CryptPrime.c */
+/* 10.2.14.1 Introduction */
+/* This file contains the code for prime validation. */
+
+#include "Tpm.h"
+#include "CryptPrime_fp.h"
+//#define CPRI_PRIME
+//#include "PrimeTable.h"
+#include "CryptPrimeSieve_fp.h"
+extern const uint32_t s_LastPrimeInTable;
+extern const uint32_t s_PrimeTableSize;
+extern const uint32_t s_PrimesInTable;
+extern const unsigned char s_PrimeTable[];
+extern bigConst s_CompositeOfSmallPrimes;
+
+/* 10.2.14.1.1 Root2() */
+/* This finds ceil(sqrt(n)) to use as a stopping point for searching the prime table. */
+static uint32_t
+Root2(
+ uint32_t n
+ )
+{
+ int32_t last = (int32_t)(n >> 2);
+ int32_t next = (int32_t)(n >> 1);
+ int32_t diff;
+ int32_t stop = 10;
+ //
+ // get a starting point
+ for(; next != 0; last >>= 1, next >>= 2);
+ last++;
+ do
+ {
+ next = (last + (n / last)) >> 1;
+ diff = next - last;
+ last = next;
+ if(stop-- == 0)
+ FAIL(FATAL_ERROR_INTERNAL);
+ } while(diff < -1 || diff > 1);
+ if((n / next) > (unsigned)next)
+ next++;
+ pAssert(next != 0);
+ pAssert(((n / next) <= (unsigned)next) && (n / (next + 1) < (unsigned)next));
+ return next;
+}
+/* 10.2.14.1.2 IsPrimeInt() */
+/* This will do a test of a word of up to 32-bits in size. */
+BOOL
+IsPrimeInt(
+ uint32_t n
+ )
+{
+ uint32_t i;
+ uint32_t stop;
+ if(n < 3 || ((n & 1) == 0))
+ return (n == 2);
+ if(n <= s_LastPrimeInTable)
+ {
+ n >>= 1;
+ return ((s_PrimeTable[n >> 3] >> (n & 7)) & 1);
+ }
+ // Need to search
+ stop = Root2(n) >> 1;
+ // starting at 1 is equivalent to staring at (1 << 1) + 1 = 3
+ for(i = 1; i < stop; i++)
+ {
+ if((s_PrimeTable[i >> 3] >> (i & 7)) & 1)
+ // see if this prime evenly divides the number
+ if((n % ((i << 1) + 1)) == 0)
+ return FALSE;
+ }
+ return TRUE;
+}
+#if !RSA_KEY_SIEVE // libtpms added
+/* 10.2.14.1.3 BnIsProbablyPrime() */
+/* This function is used when the key sieve is not implemented. This function Will try to eliminate
+ some of the obvious things before going on to perform MillerRabin() as a final verification of
+ primeness. */
+BOOL
+BnIsProbablyPrime(
+ bigNum prime, // IN:
+ RAND_STATE *rand // IN: the random state just
+ // in case Miller-Rabin is required
+ )
+{
+#if RADIX_BITS > 32
+ if(BnUnsignedCmpWord(prime, UINT32_MAX) <= 0)
+#else
+ if(BnGetSize(prime) == 1)
+#endif
+ return IsPrimeInt((uint32_t)prime->d[0]);
+ if(BnIsEven(prime))
+ return FALSE;
+ if(BnUnsignedCmpWord(prime, s_LastPrimeInTable) <= 0)
+ {
+ crypt_uword_t temp = prime->d[0] >> 1;
+ return ((s_PrimeTable[temp >> 3] >> (temp & 7)) & 1);
+ }
+ {
+ BN_VAR(n, LARGEST_NUMBER_BITS);
+ BnGcd(n, prime, s_CompositeOfSmallPrimes);
+ if(!BnEqualWord(n, 1))
+ return FALSE;
+ }
+ return MillerRabin(prime, rand);
+}
+#endif // libtpms added
+/* 10.2.14.1.4 MillerRabinRounds() */
+/* Function returns the number of Miller-Rabin rounds necessary to give an error probability equal
+ to the security strength of the prime. These values are from FIPS 186-3. */
+UINT32
+MillerRabinRounds(
+ UINT32 bits // IN: Number of bits in the RSA prime
+ )
+{
+ if(bits < 511) return 8; // don't really expect this
+ if(bits < 1536) return 5; // for 512 and 1K primes
+ return 4; // for 3K public modulus and greater
+}
+/* 10.2.14.1.5 MillerRabin() */
+/* This function performs a Miller-Rabin test from FIPS 186-3. It does iterations trials on the
+ number. In all likelihood, if the number is not prime, the first test fails. */
+/* Return Values Meaning */
+/* TRUE probably prime */
+/* FALSE composite */
+BOOL
+MillerRabin(
+ bigNum bnW,
+ RAND_STATE *rand
+ )
+{
+ BN_MAX(bnWm1);
+ BN_PRIME(bnM);
+ BN_PRIME(bnB);
+ BN_PRIME(bnZ);
+ BOOL ret = FALSE; // Assumed composite for easy exit
+ unsigned int a;
+ unsigned int j;
+ int wLen;
+ int i;
+ int iterations = MillerRabinRounds(BnSizeInBits(bnW));
+ //
+ INSTRUMENT_INC(MillerRabinTrials[PrimeIndex]);
+
+ pAssert(bnW->size > 1);
+ // Let a be the largest integer such that 2^a divides w1.
+ BnSubWord(bnWm1, bnW, 1);
+ pAssert(bnWm1->size != 0);
+
+ // Since w is odd (w-1) is even so start at bit number 1 rather than 0
+ // Get the number of bits in bnWm1 so that it doesn't have to be recomputed
+ // on each iteration.
+ i = (int)(bnWm1->size * RADIX_BITS);
+ // Now find the largest power of 2 that divides w1
+ for(a = 1;
+ (a < (bnWm1->size * RADIX_BITS)) &&
+ (BnTestBit(bnWm1, a) == 0);
+ a++);
+ // 2. m = (w1) / 2^a
+ BnShiftRight(bnM, bnWm1, a);
+ // 3. wlen = len (w).
+ wLen = BnSizeInBits(bnW);
+ // 4. For i = 1 to iterations do
+ for(i = 0; i < iterations; i++)
+ {
+ // 4.1 Obtain a string b of wlen bits from an RBG.
+ // Ensure that 1 < b < w1.
+ // 4.2 If ((b <= 1) or (b >= w1)), then go to step 4.1.
+ while(BnGetRandomBits(bnB, wLen, rand) && ((BnUnsignedCmpWord(bnB, 1) <= 0)
+ || (BnUnsignedCmp(bnB, bnWm1) >= 0)));
+ if(g_inFailureMode)
+ return FALSE;
+
+ // 4.3 z = b^m mod w.
+ // if ModExp fails, then say this is not
+ // prime and bail out.
+ BnModExp(bnZ, bnB, bnM, bnW);
+
+ // 4.4 If ((z == 1) or (z = w == 1)), then go to step 4.7.
+ if((BnUnsignedCmpWord(bnZ, 1) == 0)
+ || (BnUnsignedCmp(bnZ, bnWm1) == 0))
+ goto step4point7;
+ // 4.5 For j = 1 to a 1 do.
+ for(j = 1; j < a; j++)
+ {
+ // 4.5.1 z = z^2 mod w.
+ BnModMult(bnZ, bnZ, bnZ, bnW);
+ // 4.5.2 If (z = w1), then go to step 4.7.
+ if(BnUnsignedCmp(bnZ, bnWm1) == 0)
+ goto step4point7;
+ // 4.5.3 If (z = 1), then go to step 4.6.
+ if(BnEqualWord(bnZ, 1))
+ goto step4point6;
+ }
+ // 4.6 Return COMPOSITE.
+ step4point6:
+ INSTRUMENT_INC(failedAtIteration[i]);
+ goto end;
+ // 4.7 Continue. Comment: Increment i for the do-loop in step 4.
+ step4point7:
+ continue;
+ }
+ // 5. Return PROBABLY PRIME
+ ret = TRUE;
+ end:
+ return ret;
+}
+#if ALG_RSA
+/* 10.2.14.1.6 RsaCheckPrime() */
+/* This will check to see if a number is prime and appropriate for an RSA prime. */
+/* This has different functionality based on whether we are using key sieving or not. If not, the
+ number checked to see if it is divisible by the public exponent, then the number is adjusted
+ either up or down in order to make it a better candidate. It is then checked for being probably
+ prime. */
+/* If sieving is used, the number is used to root a sieving process. */
+TPM_RC
+RsaCheckPrime(
+ bigNum prime,
+ UINT32 exponent,
+ RAND_STATE *rand
+ )
+{
+#if !RSA_KEY_SIEVE
+ TPM_RC retVal = TPM_RC_SUCCESS;
+ UINT32 modE = BnModWord(prime, exponent);
+ NOT_REFERENCED(rand);
+ if(modE == 0)
+ // evenly divisible so add two keeping the number odd
+ BnAddWord(prime, prime, 2);
+ // want 0 != (p - 1) mod e
+ // which is 1 != p mod e
+ else if(modE == 1)
+ // subtract 2 keeping number odd and insuring that
+ // 0 != (p - 1) mod e
+ BnSubWord(prime, prime, 2);
+ if(BnIsProbablyPrime(prime, rand) == 0)
+ ERROR_RETURN(g_inFailureMode ? TPM_RC_FAILURE : TPM_RC_VALUE);
+ Exit:
+ return retVal;
+#else
+ return PrimeSelectWithSieve(prime, exponent, rand);
+#endif
+}
+/*
+ * RsaAdjustPrimeCandidate_PreRev155 is the pre-rev.155 algorithm used; we
+ * still have to use it for old seeds to maintain backwards compatibility.
+ */
+static void
+RsaAdjustPrimeCandidate_PreRev155(
+ bigNum prime
+ )
+{
+ UINT16 highBytes;
+ crypt_uword_t *msw = &prime->d[prime->size - 1];
+#define MASK (MAX_CRYPT_UWORD >> (RADIX_BITS - 16))
+ highBytes = *msw >> (RADIX_BITS - 16);
+ // This is fixed point arithmetic on 16-bit values
+ highBytes = ((UINT32)highBytes * (UINT32)0x4AFB) >> 16;
+ highBytes += 0xB505;
+ *msw = ((crypt_uword_t)(highBytes) << (RADIX_BITS - 16)) + (*msw & MASK);
+ prime->d[0] |= 1;
+}
+
+/* 10.2.14.1.7 RsaAdjustPrimeCandidate() */
+
+/* For this math, we assume that the RSA numbers are fixed-point numbers with the decimal point to
+ the left of the most significant bit. This approach helps make it clear what is happening with
+ the MSb of the values. The two RSA primes have to be large enough so that their product will be a
+ number with the necessary number of significant bits. For example, we want to be able to multiply
+ two 1024-bit numbers to produce a number with 2048 significant bits. If we accept any 1024-bit
+ prime that has its MSb set, then it is possible to produce a product that does not have the MSb
+ SET. For example, if we use tiny keys of 16 bits and have two 8-bit primes of 0x80, then the
+ public key would be 0x4000 which is only 15-bits. So, what we need to do is made sure that each
+ of the primes is large enough so that the product of the primes is twice as large as each
+ prime. A little arithmetic will show that the only way to do this is to make sure that each of
+ the primes is no less than root(2)/2. That's what this functions does. This function adjusts the
+ candidate prime so that it is odd and >= root(2)/2. This allows the product of these two numbers
+ to be .5, which, in fixed point notation means that the most significant bit is 1. For this
+ routine, the root(2)/2 (0.7071067811865475) approximated with 0xB505 which is, in fixed point,
+ 0.7071075439453125 or an error of 0.000108%. Just setting the upper two bits would give a value >
+ 0.75 which is an error of > 6%. Given the amount of time all the other computations take,
+ reducing the error is not much of a cost, but it isn't totally required either. */
+/* This function can be replaced with a function that just sets the two most significant bits of
+ each prime candidate without introducing any computational issues. */
+
+static void
+RsaAdjustPrimeCandidate_New(
+ bigNum prime
+ )
+{
+ UINT32 msw;
+ UINT32 adjusted;
+
+ // If the radix is 32, the compiler should turn this into a simple assignment
+ msw = prime->d[prime->size - 1] >> ((RADIX_BITS == 64) ? 32 : 0);
+ // Multiplying 0xff...f by 0x4AFB gives 0xff..f - 0xB5050...0
+ adjusted = (msw >> 16) * 0x4AFB;
+ adjusted += ((msw & 0xFFFF) * 0x4AFB) >> 16;
+ adjusted += 0xB5050000UL;
+#if RADIX_BITS == 64
+ // Save the low-order 32 bits
+ prime->d[prime->size - 1] &= 0xFFFFFFFFUL;
+ // replace the upper 32-bits
+ prime->d[prime->size -1] |= ((crypt_uword_t)adjusted << 32);
+#else
+ prime->d[prime->size - 1] = (crypt_uword_t)adjusted;
+#endif
+ // make sure the number is odd
+ prime->d[0] |= 1;
+}
+
+
+LIB_EXPORT void
+RsaAdjustPrimeCandidate(
+ bigNum prime,
+ SEED_COMPAT_LEVEL seedCompatLevel // IN: compatibility level; libtpms added
+ )
+{
+ switch (seedCompatLevel) {
+ case SEED_COMPAT_LEVEL_ORIGINAL:
+ RsaAdjustPrimeCandidate_PreRev155(prime);
+ break;
+ case SEED_COMPAT_LEVEL_LAST:
+ /* case SEED_COMPAT_LEVEL_RSA_PRIME_ADJUST_FIX: */
+ RsaAdjustPrimeCandidate_New(prime);
+ break;
+ default:
+ FAIL(FATAL_ERROR_INTERNAL);
+ }
+}
+/* 10.2.14.1.8 BnGeneratePrimeForRSA() */
+/* Function to generate a prime of the desired size with the proper attributes for an RSA prime. */
+
+TPM_RC
+BnGeneratePrimeForRSA(
+ bigNum prime, // IN/OUT: points to the BN that will get the
+ // random value
+ UINT32 bits, // IN: number of bits to get
+ UINT32 exponent, // IN: the exponent
+ RAND_STATE *rand // IN: the random state
+ )
+{
+ BOOL found = FALSE;
+ //
+ // Make sure that the prime is large enough
+ pAssert(prime->allocated >= BITS_TO_CRYPT_WORDS(bits));
+ // Only try to handle specific sizes of keys in order to save overhead
+ pAssert((bits % 32) == 0);
+
+ prime->size = BITS_TO_CRYPT_WORDS(bits);
+
+ while(!found)
+ {
+ // The change below is to make sure that all keys that are generated from the same
+ // seed value will be the same regardless of the endianness or word size of the CPU.
+ // DRBG_Generate(rand, (BYTE *)prime->d, (UINT16)BITS_TO_BYTES(bits));// old
+ // if(g_inFailureMode) // old
+ // libtpms changed begin
+ switch (DRBG_GetSeedCompatLevel(rand)) {
+ case SEED_COMPAT_LEVEL_ORIGINAL:
+ DRBG_Generate(rand, (BYTE *)prime->d, (UINT16)BITS_TO_BYTES(bits));
+ if (g_inFailureMode)
+ return TPM_RC_FAILURE;
+ break;
+ case SEED_COMPAT_LEVEL_LAST:
+ /* case SEED_COMPAT_LEVEL_RSA_PRIME_ADJUST_FIX: */
+ if(!BnGetRandomBits(prime, bits, rand)) // new
+ return TPM_RC_FAILURE;
+ break;
+ default:
+ FAIL(FATAL_ERROR_INTERNAL);
+ }
+ RsaAdjustPrimeCandidate(prime, DRBG_GetSeedCompatLevel(rand));
+ // libtpms changed end
+ found = RsaCheckPrime(prime, exponent, rand) == TPM_RC_SUCCESS;
+ }
+ return TPM_RC_SUCCESS;
+}
+
+#endif // TPM_ALG_RSA
diff --git a/src/tpm2/crypto/openssl/CryptPrimeSieve.c b/src/tpm2/crypto/openssl/CryptPrimeSieve.c
new file mode 100644
index 0000000..8c4e52b
--- /dev/null
+++ b/src/tpm2/crypto/openssl/CryptPrimeSieve.c
@@ -0,0 +1,554 @@
+/********************************************************************************/
+/* */
+/* CryptPrimeSieve */
+/* Written by Ken Goldman */
+/* IBM Thomas J. Watson Research Center */
+/* $Id: CryptPrimeSieve.c 1519 2019-11-15 20:43:51Z kgoldman $ */
+/* */
+/* Licenses and Notices */
+/* */
+/* 1. Copyright Licenses: */
+/* */
+/* - Trusted Computing Group (TCG) grants to the user of the source code in */
+/* this specification (the "Source Code") a worldwide, irrevocable, */
+/* nonexclusive, royalty free, copyright license to reproduce, create */
+/* derivative works, distribute, display and perform the Source Code and */
+/* derivative works thereof, and to grant others the rights granted herein. */
+/* */
+/* - The TCG grants to the user of the other parts of the specification */
+/* (other than the Source Code) the rights to reproduce, distribute, */
+/* display, and perform the specification solely for the purpose of */
+/* developing products based on such documents. */
+/* */
+/* 2. Source Code Distribution Conditions: */
+/* */
+/* - Redistributions of Source Code must retain the above copyright licenses, */
+/* this list of conditions and the following disclaimers. */
+/* */
+/* - Redistributions in binary form must reproduce the above copyright */
+/* licenses, this list of conditions and the following disclaimers in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* 3. Disclaimers: */
+/* */
+/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
+/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
+/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
+/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
+/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
+/* information on specification licensing rights available through TCG */
+/* membership agreements. */
+/* */
+/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
+/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
+/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
+/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
+/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
+/* */
+/* - Without limitation, TCG and its members and licensors disclaim all */
+/* liability, including liability for infringement of any proprietary */
+/* rights, relating to use of information in this specification and to the */
+/* implementation of this specification, and TCG disclaims all liability for */
+/* cost of procurement of substitute goods or services, lost profits, loss */
+/* of use, loss of data or any incidental, consequential, direct, indirect, */
+/* or special damages, whether under contract, tort, warranty or otherwise, */
+/* arising in any way out of use or reliance upon this specification or any */
+/* information herein. */
+/* */
+/* (c) Copyright IBM Corp. and others, 2016 - 2019 */
+/* */
+/********************************************************************************/
+
+/* 10.2.17 CryptPrimeSieve.c */
+/* 10.2.17.1 Includes and defines */
+#include "Tpm.h"
+#if RSA_KEY_SIEVE
+#include "CryptPrimeSieve_fp.h"
+/* This determines the number of bits in the largest sieve field. */
+#define MAX_FIELD_SIZE 2048
+extern const uint32_t s_LastPrimeInTable;
+extern const uint32_t s_PrimeTableSize;
+extern const uint32_t s_PrimesInTable;
+extern const unsigned char s_PrimeTable[];
+/* This table is set of prime markers. Each entry is the prime value for the ((n + 1) * 1024)
+ prime. That is, the entry in s_PrimeMarkers[1] is the value for the 2,048th prime. This is used
+ in the PrimeSieve() to adjust the limit for the prime search. When processing smaller prime
+ candidates, fewer primes are checked directly before going to Miller-Rabin. As the prime grows,
+ it is worth spending more time eliminating primes as, a) the density is lower, and b) the cost of
+ Miller-Rabin is higher. */
+const uint32_t s_PrimeMarkersCount = 6;
+const uint32_t s_PrimeMarkers[] = {
+ 8167, 17881, 28183, 38891, 49871, 60961 };
+uint32_t primeLimit;
+
+/* 10.2.17.1.1 RsaAdjustPrimeLimit() */
+/* This used during the sieve process. The iterator for getting the next prime (RsaNextPrime()) will
+ return primes until it hits the limit (primeLimit) set up by this function. This causes the sieve
+ process to stop when an appropriate number of primes have been sieved. */
+
+void
+RsaAdjustPrimeLimit(
+ uint32_t requestedPrimes
+ )
+{
+ if(requestedPrimes == 0 || requestedPrimes > s_PrimesInTable)
+ requestedPrimes = s_PrimesInTable;
+ requestedPrimes = (requestedPrimes - 1) / 1024;
+ if(requestedPrimes < s_PrimeMarkersCount)
+ primeLimit = s_PrimeMarkers[requestedPrimes];
+ else
+ primeLimit = s_LastPrimeInTable - 2; // libtpms: Fix for 3072 bit keys to avoid mark=5
+ primeLimit >>= 1;
+}
+
+/* 10.2.17.1.2 RsaNextPrime() */
+/* This the iterator used during the sieve process. The input is the last prime returned (or any
+ starting point) and the output is the next higher prime. The function returns 0 when the
+ primeLimit is reached. */
+uint32_t
+RsaNextPrime(
+ uint32_t lastPrime
+ )
+{
+ if(lastPrime == 0)
+ return 0;
+ lastPrime >>= 1;
+ for(lastPrime += 1; lastPrime <= primeLimit; lastPrime++)
+ {
+ if(((s_PrimeTable[lastPrime >> 3] >> (lastPrime & 0x7)) & 1) == 1)
+ return ((lastPrime << 1) + 1);
+ }
+ return 0;
+}
+/* This table contains a previously sieved table. It has the bits for 3, 5, and 7 removed. Because
+ of the factors, it needs to be aligned to 105 and has a repeat of 105. */
+const BYTE seedValues[] = {
+ 0x16, 0x29, 0xcb, 0xa4, 0x65, 0xda, 0x30, 0x6c,
+ 0x99, 0x96, 0x4c, 0x53, 0xa2, 0x2d, 0x52, 0x96,
+ 0x49, 0xcb, 0xb4, 0x61, 0xd8, 0x32, 0x2d, 0x99,
+ 0xa6, 0x44, 0x5b, 0xa4, 0x2c, 0x93, 0x96, 0x69,
+ 0xc3, 0xb0, 0x65, 0x5a, 0x32, 0x4d, 0x89, 0xb6,
+ 0x48, 0x59, 0x26, 0x2d, 0xd3, 0x86, 0x61, 0xcb,
+ 0xb4, 0x64, 0x9a, 0x12, 0x6d, 0x91, 0xb2, 0x4c,
+ 0x5a, 0xa6, 0x0d, 0xc3, 0x96, 0x69, 0xc9, 0x34,
+ 0x25, 0xda, 0x22, 0x65, 0x99, 0xb4, 0x4c, 0x1b,
+ 0x86, 0x2d, 0xd3, 0x92, 0x69, 0x4a, 0xb4, 0x45,
+ 0xca, 0x32, 0x69, 0x99, 0x36, 0x0c, 0x5b, 0xa6,
+ 0x25, 0xd3, 0x94, 0x68, 0x8b, 0x94, 0x65, 0xd2,
+ 0x32, 0x6d, 0x18, 0xb6, 0x4c, 0x4b, 0xa6, 0x29,
+ 0xd1};
+#define USE_NIBBLE
+#ifndef USE_NIBBLE
+static const BYTE bitsInByte[256] = {
+ 0x00, 0x01, 0x01, 0x02, 0x01, 0x02, 0x02, 0x03,
+ 0x01, 0x02, 0x02, 0x03, 0x02, 0x03, 0x03, 0x04,
+ 0x01, 0x02, 0x02, 0x03, 0x02, 0x03, 0x03, 0x04,
+ 0x02, 0x03, 0x03, 0x04, 0x03, 0x04, 0x04, 0x05,
+ 0x01, 0x02, 0x02, 0x03, 0x02, 0x03, 0x03, 0x04,
+ 0x02, 0x03, 0x03, 0x04, 0x03, 0x04, 0x04, 0x05,
+ 0x02, 0x03, 0x03, 0x04, 0x03, 0x04, 0x04, 0x05,
+ 0x03, 0x04, 0x04, 0x05, 0x04, 0x05, 0x05, 0x06,
+ 0x01, 0x02, 0x02, 0x03, 0x02, 0x03, 0x03, 0x04,
+ 0x02, 0x03, 0x03, 0x04, 0x03, 0x04, 0x04, 0x05,
+ 0x02, 0x03, 0x03, 0x04, 0x03, 0x04, 0x04, 0x05,
+ 0x03, 0x04, 0x04, 0x05, 0x04, 0x05, 0x05, 0x06,
+ 0x02, 0x03, 0x03, 0x04, 0x03, 0x04, 0x04, 0x05,
+ 0x03, 0x04, 0x04, 0x05, 0x04, 0x05, 0x05, 0x06,
+ 0x03, 0x04, 0x04, 0x05, 0x04, 0x05, 0x05, 0x06,
+ 0x04, 0x05, 0x05, 0x06, 0x05, 0x06, 0x06, 0x07,
+ 0x01, 0x02, 0x02, 0x03, 0x02, 0x03, 0x03, 0x04,
+ 0x02, 0x03, 0x03, 0x04, 0x03, 0x04, 0x04, 0x05,
+ 0x02, 0x03, 0x03, 0x04, 0x03, 0x04, 0x04, 0x05,
+ 0x03, 0x04, 0x04, 0x05, 0x04, 0x05, 0x05, 0x06,
+ 0x02, 0x03, 0x03, 0x04, 0x03, 0x04, 0x04, 0x05,
+ 0x03, 0x04, 0x04, 0x05, 0x04, 0x05, 0x05, 0x06,
+ 0x03, 0x04, 0x04, 0x05, 0x04, 0x05, 0x05, 0x06,
+ 0x04, 0x05, 0x05, 0x06, 0x05, 0x06, 0x06, 0x07,
+ 0x02, 0x03, 0x03, 0x04, 0x03, 0x04, 0x04, 0x05,
+ 0x03, 0x04, 0x04, 0x05, 0x04, 0x05, 0x05, 0x06,
+ 0x03, 0x04, 0x04, 0x05, 0x04, 0x05, 0x05, 0x06,
+ 0x04, 0x05, 0x05, 0x06, 0x05, 0x06, 0x06, 0x07,
+ 0x03, 0x04, 0x04, 0x05, 0x04, 0x05, 0x05, 0x06,
+ 0x04, 0x05, 0x05, 0x06, 0x05, 0x06, 0x06, 0x07,
+ 0x04, 0x05, 0x05, 0x06, 0x05, 0x06, 0x06, 0x07,
+ 0x05, 0x06, 0x06, 0x07, 0x06, 0x07, 0x07, 0x08
+};
+#define BitsInByte(x) bitsInByte[(unsigned char)x]
+#else
+const BYTE bitsInNibble[16] = {
+ 0x00, 0x01, 0x01, 0x02, 0x01, 0x02, 0x02, 0x03,
+ 0x01, 0x02, 0x02, 0x03, 0x02, 0x03, 0x03, 0x04};
+#define BitsInByte(x) \
+ (bitsInNibble[(unsigned char)(x) & 0xf] \
+ + bitsInNibble[((unsigned char)(x) >> 4) & 0xf])
+#endif
+
+/* 10.2.17.1.3 BitsInArry() */
+/* This function counts the number of bits set in an array of bytes. */
+static int
+BitsInArray(
+ const unsigned char *a, // IN: A pointer to an array of bytes
+ unsigned int aSize // IN: the number of bytes to sum
+ )
+{
+ int j = 0;
+ for(; aSize; a++, aSize--)
+ j += BitsInByte(*a);
+ return j;
+}
+
+/* 10.2.17.1.4 FindNthSetBit() */
+/* This function finds the nth SET bit in a bit array. The n parameter is between 1 and the number
+ of bits in the array (always a multiple of 8). If called when the array does not have n bits set,
+ it will return -1 */
+/* Return Values Meaning */
+/* <0 no bit is set or no bit with the requested number is set */
+/* >=0 the number of the bit in the array that is the nth set */
+int
+FindNthSetBit(
+ const UINT16 aSize, // IN: the size of the array to check
+ const BYTE *a, // IN: the array to check
+ const UINT32 n // IN, the number of the SET bit
+ )
+{
+ UINT16 i;
+ int retValue;
+ UINT32 sum = 0;
+ BYTE sel;
+ //find the bit
+ for(i = 0; (i < (int)aSize) && (sum < n); i++)
+ sum += BitsInByte(a[i]);
+ i--;
+ // The chosen bit is in the byte that was just accessed
+ // Compute the offset to the start of that byte
+ retValue = i * 8 - 1;
+ sel = a[i];
+ // Subtract the bits in the last byte added.
+ sum -= BitsInByte(sel);
+ // Now process the byte, one bit at a time.
+ for(; (sel != 0) && (sum != n); retValue++, sel = sel >> 1)
+ sum += (sel & 1) != 0;
+ return (sum == n) ? retValue : -1;
+}
+typedef struct
+{
+ UINT16 prime;
+ UINT16 count;
+} SIEVE_MARKS;
+const SIEVE_MARKS sieveMarks[5] = {
+ {31, 7}, {73, 5}, {241, 4}, {1621, 3}, {UINT16_MAX, 2}};
+
+/* 10.2.17.1.5 PrimeSieve() */
+/* This function does a prime sieve over the input field which has as its starting address the value
+ in bnN. Since this initializes the Sieve using a precomputed field with the bits associated with
+ 3, 5 and 7 already turned off, the value of pnN may need to be adjusted by a few counts to allow
+ the precomputed field to be used without modification. */
+/* To get better performance, one could address the issue of developing the composite numbers. When
+ the size of the prime gets large, the time for doing the divisions goes up, noticeably. It could
+ be better to develop larger composite numbers even if they need to be bigNum's themselves. The
+ object would be to reduce the number of times that the large prime is divided into a few large
+ divides and then use smaller divides to get to the final 16 bit (or smaller) remainders. */
+UINT32
+PrimeSieve(
+ bigNum bnN, // IN/OUT: number to sieve
+ UINT32 fieldSize, // IN: size of the field area in bytes
+ BYTE *field // IN: field
+ )
+{
+ UINT32 i;
+ UINT32 j;
+ UINT32 fieldBits = fieldSize * 8;
+ UINT32 r;
+ BYTE *pField;
+ INT32 iter;
+ UINT32 adjust;
+ UINT32 mark = 0;
+ UINT32 count = sieveMarks[0].count;
+ UINT32 stop = sieveMarks[0].prime;
+ UINT32 composite;
+ UINT32 pList[8];
+ UINT32 next;
+ pAssert(field != NULL && bnN != NULL);
+ // If the remainder is odd, then subtracting the value will give an even number,
+ // but we want an odd number, so subtract the 105+rem. Otherwise, just subtract
+ // the even remainder.
+ adjust = (UINT32)BnModWord(bnN, 105);
+ if(adjust & 1)
+ adjust += 105;
+ // Adjust the input number so that it points to the first number in a
+ // aligned field.
+ BnSubWord(bnN, bnN, adjust);
+ // pAssert(BnModWord(bnN, 105) == 0);
+ pField = field;
+ for(i = fieldSize; i >= sizeof(seedValues);
+ pField += sizeof(seedValues), i -= sizeof(seedValues))
+ {
+ memcpy(pField, seedValues, sizeof(seedValues));
+ }
+ if(i != 0)
+ memcpy(pField, seedValues, i);
+ // Cycle through the primes, clearing bits
+ // Have already done 3, 5, and 7
+ iter = 7;
+#define NEXT_PRIME(iter) (iter = RsaNextPrime(iter))
+ // Get the next N primes where N is determined by the mark in the sieveMarks
+ while((composite = NEXT_PRIME(iter)) != 0)
+ {
+ next = 0;
+ i = count;
+ pList[i--] = composite;
+ for(; i > 0; i--)
+ {
+ next = NEXT_PRIME(iter);
+ pList[i] = next;
+ if(next != 0)
+ composite *= next;
+ }
+ // Get the remainder when dividing the base field address
+ // by the composite
+ composite = (UINT32)BnModWord(bnN, composite);
+ // 'composite' is divisible by the composite components. for each of the
+ // composite components, divide 'composite'. That remainder (r) is used to
+ // pick a starting point for clearing the array. The stride is equal to the
+ // composite component. Note, the field only contains odd numbers. If the
+ // field were expanded to contain all numbers, then half of the bits would
+ // have already been cleared. We can save the trouble of clearing them a
+ // second time by having a stride of 2*next. Or we can take all of the even
+ // numbers out of the field and use a stride of 'next'
+ for(i = count; i > 0; i--)
+ {
+ next = pList[i];
+ if(next == 0)
+ goto done;
+ r = composite % next;
+ // these computations deal with the fact that we have picked a field-sized
+ // range that is aligned to a 105 count boundary. The problem is, this field
+ // only contains odd numbers. If we take our prime guess and walk through all
+ // the numbers using that prime as the 'stride', then every other 'stride' is
+ // going to be an even number. So, we are actually counting by 2 * the stride
+ // We want the count to start on an odd number at the start of our field. That
+ // is, we want to assume that we have counted up to the edge of the field by
+ // the 'stride' and now we are going to start flipping bits in the field as we
+ // continue to count up by 'stride'. If we take the base of our field and
+ // divide by the stride, we find out how much we find out how short the last
+ // count was from reaching the edge of the bit field. Say we get a quotient of
+ // 3 and remainder of 1. This means that after 3 strides, we are 1 short of
+ // the start of the field and the next stride will either land within the
+ // field or step completely over it. The confounding factor is that our field
+ // only contains odd numbers and our stride is actually 2 * stride. If the
+ // quoitent is even, then that means that when we add 2 * stride, we are going
+ // to hit another even number. So, we have to know if we need to back off
+ // by 1 stride before we start counting by 2 * stride.
+ // We can tell from the remainder whether we are on an even or odd
+ // stride when we hit the beginning of the table. If we are on an odd stride
+ // (r & 1), we would start half a stride in (next - r)/2. If we are on an
+ // even stride, we need 0.5 strides (next - r/2) because the table only has
+ // odd numbers. If the remainder happens to be zero, then the start of the
+ // table is on stride so no adjustment is necessary.
+
+ if(r & 1) j = (next - r) / 2;
+ else if(r == 0) j = 0;
+ else j = next - (r / 2);
+ for(; j < fieldBits; j += next)
+ ClearBit(j, field, fieldSize);
+ }
+ if(next >= stop)
+ {
+ mark++;
+ count = sieveMarks[mark].count;
+ stop = sieveMarks[mark].prime;
+ }
+ }
+ done:
+ INSTRUMENT_INC(totalFieldsSieved[PrimeIndex]);
+ i = BitsInArray(field, fieldSize);
+ INSTRUMENT_ADD(bitsInFieldAfterSieve[PrimeIndex], i);
+ INSTRUMENT_ADD(emptyFieldsSieved[PrimeIndex], (i == 0));
+ return i;
+}
+#ifdef SIEVE_DEBUG
+static uint32_t fieldSize = 210;
+
+/* 10.2.17.1.6 SetFieldSize() */
+/* Function to set the field size used for prime generation. Used for tuning. */
+uint32_t
+SetFieldSize(
+ uint32_t newFieldSize
+ )
+{
+ if(newFieldSize == 0 || newFieldSize > MAX_FIELD_SIZE)
+ fieldSize = MAX_FIELD_SIZE;
+ else
+ fieldSize = newFieldSize;
+ return fieldSize;
+}
+#endif // SIEVE_DEBUG
+
+/* 10.2.17.1.7 PrimeSelectWithSieve() */
+/* This function will sieve the field around the input prime candidate. If the sieve field is not
+ empty, one of the one bits in the field is chosen for testing with Miller-Rabin. If the value is
+ prime, pnP is updated with this value and the function returns success. If this value is not
+ prime, another pseudo-random candidate is chosen and tested. This process repeats until all
+ values in the field have been checked. If all bits in the field have been checked and none is
+ prime, the function returns FALSE and a new random value needs to be chosen. */
+/* Error Returns Meaning */
+/* TPM_RC_FAILURE TPM in failure mode, probably due to entropy source */
+/* TPM_RC_SUCCESS candidate is probably prime */
+/* TPM_RC_NO_RESULT candidate is not prime and couldn't find and alternative in the field */
+LIB_EXPORT TPM_RC
+PrimeSelectWithSieve(
+ bigNum candidate, // IN/OUT: The candidate to filter
+ UINT32 e, // IN: the exponent
+ RAND_STATE *rand // IN: the random number generator state
+ )
+{
+ BYTE field[MAX_FIELD_SIZE];
+ UINT32 first;
+ UINT32 ones;
+ INT32 chosen;
+ BN_PRIME(test);
+ UINT32 modE;
+#ifndef SIEVE_DEBUG
+ UINT32 fieldSize = MAX_FIELD_SIZE;
+#endif
+ UINT32 primeSize;
+ //
+ // Adjust the field size and prime table list to fit the size of the prime
+ // being tested. This is done to try to optimize the trade-off between the
+ // dividing done for sieving and the time for Miller-Rabin. When the size
+ // of the prime is large, the cost of Miller-Rabin is fairly high, as is the
+ // cost of the sieving. However, the time for Miller-Rabin goes up considerably
+ // faster than the cost of dividing by a number of primes.
+ primeSize = BnSizeInBits(candidate);
+
+ if(primeSize <= 512)
+ {
+ RsaAdjustPrimeLimit(1024); // Use just the first 1024 primes
+ }
+ else if(primeSize <= 1024)
+ {
+ RsaAdjustPrimeLimit(4096); // Use just the first 4K primes
+ }
+ else
+ {
+ RsaAdjustPrimeLimit(0); // Use all available
+ }
+
+ // Save the low-order word to use as a search generator and make sure that
+ // it has some interesting range to it
+ first = (UINT32)(candidate->d[0] | 0x80000000);
+
+ // Sieve the field
+ ones = PrimeSieve(candidate, fieldSize, field);
+ pAssert(ones > 0 && ones < (fieldSize * 8));
+ for(; ones > 0; ones--)
+ {
+ // Decide which bit to look at and find its offset
+ chosen = FindNthSetBit((UINT16)fieldSize, field, ((first % ones) + 1));
+
+ if((chosen < 0) || (chosen >= (INT32)(fieldSize * 8)))
+ FAIL(FATAL_ERROR_INTERNAL);
+
+ // Set this as the trial prime
+ BnAddWord(test, candidate, (crypt_uword_t)(chosen * 2));
+
+ // The exponent might not have been one of the tested primes so
+ // make sure that it isn't divisible and make sure that 0 != (p-1) mod e
+ // Note: This is the same as 1 != p mod e
+ modE = (UINT32)BnModWord(test, e);
+ if((modE != 0) && (modE != 1) && MillerRabin(test, rand))
+ {
+ BnCopy(candidate, test);
+ return TPM_RC_SUCCESS;
+ }
+ // Clear the bit just tested
+ ClearBit(chosen, field, fieldSize);
+ }
+ // Ran out of bits and couldn't find a prime in this field
+ INSTRUMENT_INC(noPrimeFields[PrimeIndex]);
+ return (g_inFailureMode ? TPM_RC_FAILURE : TPM_RC_NO_RESULT);
+}
+
+#if RSA_INSTRUMENT
+static char a[256];
+char *
+PrintTuple(
+ UINT32 *i
+ )
+{
+ sprintf(a, "{%d, %d, %d}", i[0], i[1], i[2]);
+ return a;
+}
+#define CLEAR_VALUE(x) memset(x, 0, sizeof(x))
+
+void
+RsaSimulationEnd(
+ void
+ )
+{
+ int i;
+ UINT32 averages[3];
+ UINT32 nonFirst = 0;
+ if((PrimeCounts[0] + PrimeCounts[1] + PrimeCounts[2]) != 0)
+ {
+ printf("Primes generated = %s\n", PrintTuple(PrimeCounts));
+ printf("Fields sieved = %s\n", PrintTuple(totalFieldsSieved));
+ printf("Fields with no primes = %s\n", PrintTuple(noPrimeFields));
+ printf("Primes checked with Miller-Rabin = %s\n",
+ PrintTuple(MillerRabinTrials));
+ for(i = 0; i < 3; i++)
+ averages[i] = (totalFieldsSieved[i]
+ != 0 ? bitsInFieldAfterSieve[i] / totalFieldsSieved[i]
+ : 0);
+ printf("Average candidates in field %s\n", PrintTuple(averages));
+ for(i = 1; i < (sizeof(failedAtIteration) / sizeof(failedAtIteration[0]));
+ i++)
+ nonFirst += failedAtIteration[i];
+ printf("Miller-Rabin failures not in first round = %d\n", nonFirst);
+ }
+ CLEAR_VALUE(PrimeCounts);
+ CLEAR_VALUE(totalFieldsSieved);
+ CLEAR_VALUE(noPrimeFields);
+ CLEAR_VALUE(MillerRabinTrials);
+ CLEAR_VALUE(bitsInFieldAfterSieve);
+}
+void
+GetSieveStats(
+ uint32_t *trials,
+ uint32_t *emptyFields,
+ uint32_t *averageBits
+ )
+{
+ uint32_t totalBits;
+ uint32_t fields;
+ *trials = MillerRabinTrials[0] + MillerRabinTrials[1] + MillerRabinTrials[2];
+ *emptyFields = noPrimeFields[0] + noPrimeFields[1] + noPrimeFields[2];
+ fields = totalFieldsSieved[0] + totalFieldsSieved[1]
+ + totalFieldsSieved[2];
+ totalBits = bitsInFieldAfterSieve[0] + bitsInFieldAfterSieve[1]
+ + bitsInFieldAfterSieve[2];
+ if(fields != 0)
+ *averageBits = totalBits / fields;
+ else
+ *averageBits = 0;
+ CLEAR_VALUE(PrimeCounts);
+ CLEAR_VALUE(totalFieldsSieved);
+ CLEAR_VALUE(noPrimeFields);
+ CLEAR_VALUE(MillerRabinTrials);
+ CLEAR_VALUE(bitsInFieldAfterSieve);
+}
+#endif
+#endif // RSA_KEY_SIEVE
+#if !RSA_INSTRUMENT
+//*** RsaSimulationEnd()
+// Stub for call when not doing instrumentation.
+#if 0 // libtpms added
+void
+RsaSimulationEnd(
+ void
+ )
+{
+ return;
+}
+#endif // libtpms added
+#endif
diff --git a/src/tpm2/crypto/openssl/CryptRand.c b/src/tpm2/crypto/openssl/CryptRand.c
new file mode 100644
index 0000000..5bf0643
--- /dev/null
+++ b/src/tpm2/crypto/openssl/CryptRand.c
@@ -0,0 +1,881 @@
+/********************************************************************************/
+/* */
+/* DRBG with a behavior according to SP800-90A */
+/* Written by Ken Goldman */
+/* IBM Thomas J. Watson Research Center */
+/* $Id: CryptRand.c 1658 2021-01-22 23:14:01Z kgoldman $ */
+/* */
+/* Licenses and Notices */
+/* */
+/* 1. Copyright Licenses: */
+/* */
+/* - Trusted Computing Group (TCG) grants to the user of the source code in */
+/* this specification (the "Source Code") a worldwide, irrevocable, */
+/* nonexclusive, royalty free, copyright license to reproduce, create */
+/* derivative works, distribute, display and perform the Source Code and */
+/* derivative works thereof, and to grant others the rights granted herein. */
+/* */
+/* - The TCG grants to the user of the other parts of the specification */
+/* (other than the Source Code) the rights to reproduce, distribute, */
+/* display, and perform the specification solely for the purpose of */
+/* developing products based on such documents. */
+/* */
+/* 2. Source Code Distribution Conditions: */
+/* */
+/* - Redistributions of Source Code must retain the above copyright licenses, */
+/* this list of conditions and the following disclaimers. */
+/* */
+/* - Redistributions in binary form must reproduce the above copyright */
+/* licenses, this list of conditions and the following disclaimers in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* 3. Disclaimers: */
+/* */
+/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
+/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
+/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
+/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
+/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
+/* information on specification licensing rights available through TCG */
+/* membership agreements. */
+/* */
+/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
+/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
+/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
+/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
+/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
+/* */
+/* - Without limitation, TCG and its members and licensors disclaim all */
+/* liability, including liability for infringement of any proprietary */
+/* rights, relating to use of information in this specification and to the */
+/* implementation of this specification, and TCG disclaims all liability for */
+/* cost of procurement of substitute goods or services, lost profits, loss */
+/* of use, loss of data or any incidental, consequential, direct, indirect, */
+/* or special damages, whether under contract, tort, warranty or otherwise, */
+/* arising in any way out of use or reliance upon this specification or any */
+/* information herein. */
+/* */
+/* (c) Copyright IBM Corp. and others, 2016 - 2021 */
+/* */
+/********************************************************************************/
+
+#include "Tpm.h"
+#include "PRNG_TestVectors.h"
+const BYTE DRBG_NistTestVector_Entropy[] = {DRBG_TEST_INITIATE_ENTROPY};
+const BYTE DRBG_NistTestVector_GeneratedInterm[] =
+ {DRBG_TEST_GENERATED_INTERM};
+const BYTE DRBG_NistTestVector_EntropyReseed[] =
+ {DRBG_TEST_RESEED_ENTROPY};
+const BYTE DRBG_NistTestVector_Generated[] = {DRBG_TEST_GENERATED};
+
+/* 10.2.16.2.2 Derivation Function Defines and Structures */
+#define DF_COUNT (DRBG_KEY_SIZE_WORDS / DRBG_IV_SIZE_WORDS + 1)
+#if DRBG_KEY_SIZE_BITS != 128 && DRBG_KEY_SIZE_BITS != 256
+# error "CryptRand.c only written for AES with 128- or 256-bit keys."
+#endif
+
+typedef struct
+{
+ DRBG_KEY_SCHEDULE keySchedule;
+ DRBG_IV iv[DF_COUNT];
+ DRBG_IV out1;
+ DRBG_IV buf;
+ int contents;
+} DF_STATE, *PDF_STATE;
+/* 10.2.16.2.3 DfCompute() */
+/* This function does the incremental update of the derivation function state. It encrypts the iv
+ value and XOR's the results into each of the blocks of the output. This is equivalent to
+ processing all of input data for each output block. */
+static void
+DfCompute(
+ PDF_STATE dfState
+ )
+{
+ int i;
+ int iv;
+ crypt_uword_t *pIv;
+ crypt_uword_t temp[DRBG_IV_SIZE_WORDS] = {0};
+ //
+ for(iv = 0; iv < DF_COUNT; iv++)
+ {
+ pIv = (crypt_uword_t *)&dfState->iv[iv].words[0];
+ for(i = 0; i < DRBG_IV_SIZE_WORDS; i++)
+ {
+ temp[i] ^= pIv[i] ^ dfState->buf.words[i];
+ }
+ DRBG_ENCRYPT(&dfState->keySchedule, &temp, pIv);
+ }
+ for(i = 0; i < DRBG_IV_SIZE_WORDS; i++)
+ dfState->buf.words[i] = 0;
+ dfState->contents = 0;
+}
+/* 10.2.16.2.4 DfStart() */
+/* This initializes the output blocks with an encrypted counter value and initializes the key
+ schedule. */
+static void
+DfStart(
+ PDF_STATE dfState,
+ uint32_t inputLength
+ )
+{
+ BYTE init[8];
+ int i;
+ UINT32 drbgSeedSize = sizeof(DRBG_SEED);
+ const BYTE dfKey[DRBG_KEY_SIZE_BYTES] = {
+ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+ 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f
+#if DRBG_KEY_SIZE_BYTES > 16
+ ,0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
+ 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f
+#endif
+ };
+ memset(dfState, 0, sizeof(DF_STATE));
+ DRBG_ENCRYPT_SETUP(&dfKey[0], DRBG_KEY_SIZE_BITS, &dfState->keySchedule);
+ // Create the first chaining values
+ for(i = 0; i < DF_COUNT; i++)
+ ((BYTE *)&dfState->iv[i])[3] = (BYTE)i;
+ DfCompute(dfState);
+ // initialize the first 64 bits of the IV in a way that doesn't depend
+ // on the size of the words used.
+ UINT32_TO_BYTE_ARRAY(inputLength, init);
+ UINT32_TO_BYTE_ARRAY(drbgSeedSize, &init[4]);
+ memcpy(&dfState->iv[0], init, 8);
+ dfState->contents = 4;
+}
+/* 10.2.16.2.5 DfUpdate() */
+/* This updates the state with the input data. A byte at a time is moved into the state buffer until
+ it is full and then that block is encrypted by DfCompute(). */
+static void
+DfUpdate(
+ PDF_STATE dfState,
+ int size,
+ const BYTE *data
+ )
+{
+ while(size > 0)
+ {
+ int toFill = DRBG_IV_SIZE_BYTES - dfState->contents;
+ if(size < toFill)
+ toFill = size;
+ // Copy as many bytes as there are or until the state buffer is full
+ memcpy(&dfState->buf.bytes[dfState->contents], data, toFill);
+ // Reduce the size left by the amount copied
+ size -= toFill;
+ // Advance the data pointer by the amount copied
+ data += toFill;
+ // increase the buffer contents count by the amount copied
+ dfState->contents += toFill;
+ pAssert(dfState->contents <= DRBG_IV_SIZE_BYTES);
+ // If we have a full buffer, do a computation pass.
+ if(dfState->contents == DRBG_IV_SIZE_BYTES)
+ DfCompute(dfState);
+ }
+}
+/* 10.2.16.2.6 DfEnd() */
+/* This function is called to get the result of the derivation function computation. If the buffer
+ is not full, it is padded with zeros. The output buffer is structured to be the same as a
+ DRBG_SEED value so that the function can return a pointer to the DRBG_SEED value in the DF_STATE
+ structure. */
+static DRBG_SEED *
+DfEnd(
+ PDF_STATE dfState
+ )
+{
+ // Since DfCompute is always called when a buffer is full, there is always
+ // space in the buffer for the terminator
+ dfState->buf.bytes[dfState->contents++] = 0x80;
+ // If the buffer is not full, pad with zeros
+ while(dfState->contents < DRBG_IV_SIZE_BYTES)
+ dfState->buf.bytes[dfState->contents++] = 0;
+ // Do a final state update
+ DfCompute(dfState);
+ return (DRBG_SEED *)&dfState->iv;
+}
+/* 10.2.16.2.7 DfBuffer() */
+/* Function to take an input buffer and do the derivation function to produce a DRBG_SEED value that
+ can be used in DRBG_Reseed(); */
+static DRBG_SEED *
+DfBuffer(
+ DRBG_SEED *output, // OUT: receives the result
+ int size, // IN: size of the buffer to add
+ BYTE *buf // IN: address of the buffer
+ )
+{
+ DF_STATE dfState;
+ if(size == 0 || buf == NULL)
+ return NULL;
+ // Initialize the derivation function
+ DfStart(&dfState, size);
+ DfUpdate(&dfState, size, buf);
+ DfEnd(&dfState);
+ memcpy(output, &dfState.iv[0], sizeof(DRBG_SEED));
+ return output;
+}
+/* 10.2.16.2.8 DRBG_GetEntropy() */
+/* Even though this implementation never fails, it may get blocked indefinitely long in the call to
+ get entropy from the platform (DRBG_GetEntropy32()). This function is only used during
+ instantiation of the DRBG for manufacturing and on each start-up after an non-orderly
+ shutdown. */
+/* Return Values Meaning */
+/* TRUE Requested entropy returned */
+/* FALSE Entropy Failure */
+BOOL
+DRBG_GetEntropy(
+ UINT32 requiredEntropy, // IN: requested number of bytes of full
+ // entropy
+ BYTE *entropy // OUT: buffer to return collected entropy
+ )
+{
+#if !USE_DEBUG_RNG
+ UINT32 obtainedEntropy;
+ INT32 returnedEntropy;
+ // If in debug mode, always use the self-test values for initialization
+ if(IsSelfTest())
+ {
+#endif
+ // If doing simulated DRBG, then check to see if the
+ // entropyFailure condition is being tested
+ if(!IsEntropyBad())/* This function increments the IV value by 1. It is used by EncryptDRBG(). */
+ {
+ // In self-test, the caller should be asking for exactly the seed
+ // size of entropy.
+ pAssert(requiredEntropy == sizeof(DRBG_NistTestVector_Entropy));
+ memcpy(entropy, DRBG_NistTestVector_Entropy,
+ sizeof(DRBG_NistTestVector_Entropy));
+ }
+#if !USE_DEBUG_RNG
+ }
+ else if(!IsEntropyBad())
+ {
+ // Collect entropy
+ // Note: In debug mode, the only "entropy" value ever returned
+ // is the value of the self-test vector.
+ for(returnedEntropy = 1, obtainedEntropy = 0;
+ obtainedEntropy < requiredEntropy && !IsEntropyBad();
+ obtainedEntropy += returnedEntropy)
+ {
+ returnedEntropy = _plat__GetEntropy(&entropy[obtainedEntropy],
+ requiredEntropy - obtainedEntropy);
+ if(returnedEntropy <= 0)
+ SetEntropyBad();
+ }
+ }
+#endif
+ return !IsEntropyBad();
+}
+
+void
+IncrementIv(
+ DRBG_IV *iv
+ )
+{
+ BYTE *ivP = ((BYTE *)iv) + DRBG_IV_SIZE_BYTES;
+ while((--ivP >= (BYTE *)iv) && ((*ivP = ((*ivP + 1) & 0xFF)) == 0));
+}
+/* 10.2.16.2.10 EncryptDRBG() */
+/* This does the encryption operation for the DRBG. It will encrypt the input state counter (IV)
+ using the state key. Into the output buffer for as many times as it takes to generate the
+ required number of bytes. */
+static BOOL
+EncryptDRBG(
+ BYTE *dOut,
+ UINT32 dOutBytes,
+ DRBG_KEY_SCHEDULE *keySchedule,
+ DRBG_IV *iv,
+ UINT32 *lastValue // Points to the last output value
+ )
+{
+#if FIPS_COMPLIANT
+ // For FIPS compliance, the DRBG has to do a continuous self-test to make sure that
+ // no two consecutive values are the same. This overhead is not incurred if the TPM
+ // is not required to be FIPS compliant
+ //
+ UINT32 temp[DRBG_IV_SIZE_BYTES / sizeof(UINT32)];
+ int i;
+ BYTE *p;
+ for(; dOutBytes > 0;)
+ {
+ // Increment the IV before each encryption (this is what makes this
+ // different from normal counter-mode encryption
+ IncrementIv(iv);
+ DRBG_ENCRYPT(keySchedule, iv, temp);
+ // Expect a 16 byte block
+#if DRBG_IV_SIZE_BITS != 128
+#error "Unsuppored IV size in DRBG"
+#endif
+ if((lastValue[0] == temp[0])
+ && (lastValue[1] == temp[1])
+ && (lastValue[2] == temp[2])
+ && (lastValue[3] == temp[3])
+ )
+ {
+ LOG_FAILURE(FATAL_ERROR_ENTROPY);
+ return FALSE;
+ }
+ lastValue[0] = temp[0];
+ lastValue[1] = temp[1];
+ lastValue[2] = temp[2];
+ lastValue[3] = temp[3];
+ i = MIN(dOutBytes, DRBG_IV_SIZE_BYTES);
+ dOutBytes -= i;
+ for(p = (BYTE *)temp; i > 0; i--)
+ *dOut++ = *p++;
+ }
+#else // version without continuous self-test
+ NOT_REFERENCED(lastValue);
+ for(; dOutBytes >= DRBG_IV_SIZE_BYTES;
+ dOut = &dOut[DRBG_IV_SIZE_BYTES], dOutBytes -= DRBG_IV_SIZE_BYTES)
+ {
+ // Increment the IV
+ IncrementIv(iv);
+ DRBG_ENCRYPT(keySchedule, iv, dOut);
+ }
+ // If there is a partial, generate into a block-sized
+ // temp buffer and copy to the output.
+ if(dOutBytes != 0)
+ {
+ BYTE temp[DRBG_IV_SIZE_BYTES];
+ // Increment the IV
+ IncrementIv(iv);
+ DRBG_ENCRYPT(keySchedule, iv, temp);
+ memcpy(dOut, temp, dOutBytes);
+ }
+#endif
+ return TRUE;
+}
+/* 10.2.16.2.11 DRBG_Update() */
+/* This function performs the state update function. According to SP800-90A, a temp value is created
+ by doing CTR mode encryption of providedData and replacing the key and IV with these values. The
+ one difference is that, with counter mode, the IV is incremented after each block is encrypted
+ and in this operation, the counter is incremented before each block is encrypted. This function
+ implements an optimized version of the algorithm in that it does the update of the
+ drbgState->seed in place and then providedData is XORed into drbgState->seed to complete the
+ encryption of providedData. This works because the IV is the last thing that gets encrypted. */
+static BOOL
+DRBG_Update(
+ DRBG_STATE *drbgState, // IN:OUT state to update
+ DRBG_KEY_SCHEDULE *keySchedule, // IN: the key schedule (optional)
+ DRBG_SEED *providedData // IN: additional data
+ )
+{
+ UINT32 i;
+ BYTE *temp = (BYTE *)&drbgState->seed;
+ DRBG_KEY *key = pDRBG_KEY(&drbgState->seed);
+ DRBG_IV *iv = pDRBG_IV(&drbgState->seed);
+ DRBG_KEY_SCHEDULE localKeySchedule;
+ memset(&localKeySchedule, 0, sizeof(localKeySchedule)); /* libtpms added: coverity */
+ //
+ pAssert(drbgState->magic == DRBG_MAGIC);
+ // If an key schedule was not provided, make one
+ if(keySchedule == NULL)
+ {
+ if(DRBG_ENCRYPT_SETUP((BYTE *)key,
+ DRBG_KEY_SIZE_BITS, &localKeySchedule) != 0)
+ {
+ LOG_FAILURE(FATAL_ERROR_INTERNAL);
+ return FALSE;
+ }
+ keySchedule = &localKeySchedule;
+ }
+ // Encrypt the temp value
+ EncryptDRBG(temp, sizeof(DRBG_SEED), keySchedule, iv,
+ drbgState->lastValue);
+ if(providedData != NULL)
+ {
+ BYTE *pP = (BYTE *)providedData;
+ for(i = DRBG_SEED_SIZE_BYTES; i != 0; i--)
+ *temp++ ^= *pP++;
+ }
+ // Since temp points to the input key and IV, we are done and
+ // don't need to copy the resulting 'temp' to drbgState->seed
+ return TRUE;
+}
+/* 10.2.16.2.12 DRBG_Reseed() */
+/* This function is used when reseeding of the DRBG is required. If entropy is provided, it is used
+ in lieu of using hardware entropy. */
+/* NOTE: the provided entropy must be the required size. */
+/* Return Values Meaning */
+/* TRUE reseed succeeded */
+/* FALSE reseed failed, probably due to the entropy generation */
+BOOL
+DRBG_Reseed(
+ DRBG_STATE *drbgState, // IN: the state to update
+ DRBG_SEED *providedEntropy, // IN: entropy
+ DRBG_SEED *additionalData // IN:
+ )
+{
+ DRBG_SEED seed;
+ pAssert((drbgState != NULL) && (drbgState->magic == DRBG_MAGIC));
+ if(providedEntropy == NULL)
+ {
+ providedEntropy = &seed;
+ if(!DRBG_GetEntropy(sizeof(DRBG_SEED), (BYTE *)providedEntropy))
+ return FALSE;
+ }
+ if(additionalData != NULL)
+ {
+ unsigned int i;
+ // XOR the provided data into the provided entropy
+ for(i = 0; i < sizeof(DRBG_SEED); i++)
+ ((BYTE *)providedEntropy)[i] ^= ((BYTE *)additionalData)[i];
+ }
+ DRBG_Update(drbgState, NULL, providedEntropy);
+ drbgState->reseedCounter = 1;
+ return TRUE;
+}
+/* 10.2.16.2.13 DRBG_SelfTest() */
+/* This is run when the DRBG is instantiated and at startup */
+/* Return Values Meaning */
+/* FALSE test failed */
+/* TRUE test OK */
+BOOL
+DRBG_SelfTest(
+ void
+ )
+{
+ BYTE buf[sizeof(DRBG_NistTestVector_Generated)];
+ DRBG_SEED seed;
+ UINT32 i;
+ BYTE *p;
+ DRBG_STATE testState;
+ //
+ pAssert(!IsSelfTest());
+ SetSelfTest();
+ SetDrbgTested();
+ // Do an instantiate
+ if(!DRBG_Instantiate(&testState, 0, NULL))
+ return FALSE;
+#if DRBG_DEBUG_PRINT
+ dbgDumpMemBlock(pDRBG_KEY(&testState), DRBG_KEY_SIZE_BYTES,
+ "Key after Instantiate");
+ dbgDumpMemBlock(pDRBG_IV(&testState), DRBG_IV_SIZE_BYTES,
+ "Value after Instantiate");
+#endif
+ if(DRBG_Generate((RAND_STATE *)&testState, buf, sizeof(buf)) == 0)
+ return FALSE;
+#if DRBG_DEBUG_PRINT
+ dbgDumpMemBlock(pDRBG_KEY(&testState.seed), DRBG_KEY_SIZE_BYTES,
+ "Key after 1st Generate");
+ dbgDumpMemBlock(pDRBG_IV(&testState.seed), DRBG_IV_SIZE_BYTES,
+ "Value after 1st Generate");
+#endif
+ if(memcmp(buf, DRBG_NistTestVector_GeneratedInterm, sizeof(buf)) != 0)
+ return FALSE;
+ memcpy(seed.bytes, DRBG_NistTestVector_EntropyReseed, sizeof(seed));
+ DRBG_Reseed(&testState, &seed, NULL);
+#if DRBG_DEBUG_PRINT
+ dbgDumpMemBlock((BYTE *)pDRBG_KEY(&testState.seed), DRBG_KEY_SIZE_BYTES,
+ "Key after 2nd Generate");
+ dbgDumpMemBlock((BYTE *)pDRBG_IV(&testState.seed), DRBG_IV_SIZE_BYTES,
+ "Value after 2nd Generate");
+ dbgDumpMemBlock(buf, sizeof(buf), "2nd Generated");
+#endif
+ if(DRBG_Generate((RAND_STATE *)&testState, buf, sizeof(buf)) == 0)
+ return FALSE;
+ if(memcmp(buf, DRBG_NistTestVector_Generated, sizeof(buf)) != 0)
+ return FALSE;
+ ClearSelfTest();
+ DRBG_Uninstantiate(&testState);
+ for(p = (BYTE *)&testState, i = 0; i < sizeof(DRBG_STATE); i++)
+ {
+ if(*p++)
+ return FALSE;
+ }
+ // Simulate hardware failure to make sure that we get an error when
+ // trying to instantiate
+ SetEntropyBad();
+ if(DRBG_Instantiate(&testState, 0, NULL))
+ return FALSE;
+ ClearEntropyBad();
+ return TRUE;
+}
+/* 10.2.16.3 Public Interface */
+
+/* 10.2.16.3.1 Description */
+/* The functions in this section are the interface to the RNG. These are the functions that are used
+ by TPM.lib. */
+
+/* 10.2.16.3.2 CryptRandomStir() */
+/* This function is used to cause a reseed. A DRBG_SEED amount of entropy is collected from the
+ hardware and then additional data is added. */
+/* Error Returns Meaning */
+/* TPM_RC_NO_RESULT failure of the entropy generator */
+LIB_EXPORT TPM_RC
+CryptRandomStir(
+ UINT16 additionalDataSize,
+ BYTE *additionalData
+ )
+{
+#if !USE_DEBUG_RNG
+ DRBG_SEED tmpBuf;
+ DRBG_SEED dfResult;
+ //
+ // All reseed with outside data starts with a buffer full of entropy
+ if(!DRBG_GetEntropy(sizeof(tmpBuf), (BYTE *)&tmpBuf))
+ return TPM_RC_NO_RESULT;
+ DRBG_Reseed(&drbgDefault, &tmpBuf,
+ DfBuffer(&dfResult, additionalDataSize, additionalData));
+ drbgDefault.reseedCounter = 1;
+ return TPM_RC_SUCCESS;
+#else
+ // If doing debug, use the input data as the initial setting for the RNG state
+ // so that the test can be reset at any time.
+ // Note: If this is called with a data size of 0 or less, nothing happens. The
+ // presumption is that, in a debug environment, the caller will have specific
+ // values for initialization, so this check is just a simple way to prevent
+ // inadvertent programming errors from screwing things up. This doesn't use an
+ // pAssert() because the non-debug version of this function will accept these
+ // parameters as meaning that there is no additionalData and only hardware
+ // entropy is used.
+ if((additionalDataSize > 0) && (additionalData != NULL))
+ {
+ memset(drbgDefault.seed.bytes, 0, sizeof(drbgDefault.seed.bytes));
+ memcpy(drbgDefault.seed.bytes, additionalData,
+ MIN(additionalDataSize, sizeof(drbgDefault.seed.bytes)));
+ }
+ drbgDefault.reseedCounter = 1;
+ return TPM_RC_SUCCESS;
+#endif
+}
+/* 10.2.16.3.3 CryptRandomGenerate() */
+/* Generate a randomSize number or random bytes. */
+LIB_EXPORT UINT16
+CryptRandomGenerate(
+ UINT16 randomSize,
+ BYTE *buffer
+ )
+{
+ return DRBG_Generate((RAND_STATE *)&drbgDefault, buffer, randomSize);
+}
+/* 10.2.16.3.4 DRBG_InstantiateSeededKdf() */
+/* Function used to instantiate a KDF-based RNG. This is used for derivations. This function always
+ returns TRUE. */
+LIB_EXPORT BOOL
+DRBG_InstantiateSeededKdf(
+ KDF_STATE *state, // OUT: buffer to hold the state
+ TPM_ALG_ID hashAlg, // IN: hash algorithm
+ TPM_ALG_ID kdf, // IN: the KDF to use
+ TPM2B *seed, // IN: the seed to use
+ const TPM2B *label, // IN: a label for the generation process.
+ TPM2B *context, // IN: the context value
+ UINT32 limit // IN: Maximum number of bits from the KDF
+ )
+{
+ state->magic = KDF_MAGIC;
+ state->limit = limit;
+ state->seed = seed;
+ state->hash = hashAlg;
+ state->kdf = kdf;
+ state->label = label;
+ state->context = context;
+ state->digestSize = CryptHashGetDigestSize(hashAlg);
+ state->counter = 0;
+ state->residual.t.size = 0;
+ return TRUE;
+}
+/* 10.2.16.3.5 DRBG_AdditionalData() */
+/* Function to reseed the DRBG with additional entropy. This is normally called before computing the
+ protection value of a primary key in the Endorsement hierarchy. */
+LIB_EXPORT void
+DRBG_AdditionalData(
+ DRBG_STATE *drbgState, // IN:OUT state to update
+ TPM2B *additionalData // IN: value to incorporate
+ )
+{
+ DRBG_SEED dfResult;
+ if(drbgState->magic == DRBG_MAGIC)
+ {
+ DfBuffer(&dfResult, additionalData->size, additionalData->buffer);
+ DRBG_Reseed(drbgState, &dfResult, NULL);
+ }
+}
+/* 10.2.16.3.6 DRBG_InstantiateSeeded() */
+/* This function is used to instantiate a random number generator from seed values. The nominal use
+ of this generator is to create sequences of pseudo-random numbers from a seed value. */
+/* Returns
+ TPM_RC_FAILURE DRBG self-test failure
+*/
+LIB_EXPORT TPM_RC
+DRBG_InstantiateSeeded(
+ DRBG_STATE *drbgState, // IN/OUT: buffer to hold the state
+ const TPM2B *seed, // IN: the seed to use
+ const TPM2B *purpose, // IN: a label for the generation process.
+ const TPM2B *name, // IN: name of the object
+ const TPM2B *additional, // IN: additional data
+ SEED_COMPAT_LEVEL seedCompatLevel // IN: compatibility level; libtpms added
+ )
+{
+ DF_STATE dfState;
+ int totalInputSize;
+ // DRBG should have been tested, but...
+ if(!IsDrbgTested() && !DRBG_SelfTest())
+ {
+ LOG_FAILURE(FATAL_ERROR_SELF_TEST);
+ return TPM_RC_FAILURE;
+ }
+ // Initialize the DRBG state
+ memset(drbgState, 0, sizeof(DRBG_STATE));
+ drbgState->magic = DRBG_MAGIC;
+ drbgState->seedCompatLevel = seedCompatLevel; // libtpms added
+ // Size all of the values
+ totalInputSize = (seed != NULL) ? seed->size : 0;
+ totalInputSize += (purpose != NULL) ? purpose->size : 0;
+ totalInputSize += (name != NULL) ? name->size : 0;
+ totalInputSize += (additional != NULL) ? additional->size : 0;
+ // Initialize the derivation
+ DfStart(&dfState, totalInputSize);
+ // Run all the input strings through the derivation function
+ if(seed != NULL)
+ DfUpdate(&dfState, seed->size, seed->buffer);
+ if(purpose != NULL)
+ DfUpdate(&dfState, purpose->size, purpose->buffer);
+ if(name != NULL)
+ DfUpdate(&dfState, name->size, name->buffer);
+ if(additional != NULL)
+ DfUpdate(&dfState, additional->size, additional->buffer);
+ // Used the derivation function output as the "entropy" input. This is not
+ // how it is described in SP800-90A but this is the equivalent function
+ DRBG_Reseed(((DRBG_STATE *)drbgState), DfEnd(&dfState), NULL);
+ return TPM_RC_SUCCESS;
+}
+/* 10.2.16.3.7 CryptRandStartup() */
+/* This function is called when TPM_Startup() is executed. */
+/* TRUE instantiation succeeded */ /* kgold */
+/* FALSE instantiation failed */
+LIB_EXPORT BOOL
+CryptRandStartup(
+ void
+ )
+{
+#if ! _DRBG_STATE_SAVE
+ // If not saved in NV, re-instantiate on each startup
+ return DRBG_Instantiate(&drbgDefault, 0, NULL);
+#else
+ // If the running state is saved in NV, NV has to be loaded before it can
+ // be updated
+ if(go.drbgState.magic == DRBG_MAGIC)
+ return DRBG_Reseed(&go.drbgState, NULL, NULL);
+ else
+ return DRBG_Instantiate(&go.drbgState, 0, NULL);
+#endif
+}
+/* 10.2.16.3.8 CryptRandInit() */
+/* This function is called when _TPM_Init() is being processed */
+LIB_EXPORT BOOL
+CryptRandInit(
+ void
+ )
+{
+#if !USE_DEBUG_RNG
+ _plat__GetEntropy(NULL, 0);
+#endif
+ return DRBG_SelfTest();
+}
+// libtpms added begin
+LIB_EXPORT SEED_COMPAT_LEVEL
+DRBG_GetSeedCompatLevel(
+ RAND_STATE *state
+ )
+{
+ if(state == NULL)
+ {
+ return SEED_COMPAT_LEVEL_LAST;
+ }
+ else if(state->drbg.magic == DRBG_MAGIC)
+ {
+ DRBG_STATE *drbgState = (DRBG_STATE *)state;
+
+ return drbgState->seedCompatLevel;
+ }
+ else
+ {
+ return SEED_COMPAT_LEVEL_LAST;
+ }
+}
+// libtpms added end
+/* 10.2.16.5 DRBG_Generate() */
+/* This function generates a random sequence according SP800-90A. If random is not NULL, then
+ randomSize bytes of random values are generated. If random is NULL or randomSize is zero, then
+ the function returns TRUE without generating any bits or updating the reseed counter. This
+ function returns 0 if a reseed is required. Otherwise, it returns the number of bytes produced
+ which could be less than the number requested if the request is too large.("too large" is
+ implementation dependent.) */
+LIB_EXPORT UINT16
+DRBG_Generate(
+ RAND_STATE *state,
+ BYTE *random, // OUT: buffer to receive the random values
+ UINT16 randomSize // IN: the number of bytes to generate
+ )
+{
+ if(state == NULL)
+ state = (RAND_STATE *)&drbgDefault;
+ if(random == NULL)
+ return 0;
+
+ // If the caller used a KDF state, generate a sequence from the KDF not to
+ // exceed the limit.
+ if(state->kdf.magic == KDF_MAGIC)
+ {
+ KDF_STATE *kdf = (KDF_STATE *)state;
+ UINT32 counter = (UINT32)kdf->counter;
+ INT32 bytesLeft = randomSize;
+
+ // If the number of bytes to be returned would put the generator
+ // over the limit, then return 0
+ if((((kdf->counter * kdf->digestSize) + randomSize) * 8) > kdf->limit)
+ return 0;
+ // Process partial and full blocks until all requested bytes provided
+ while(bytesLeft > 0)
+ {
+ // If there is any residual data in the buffer, copy it to the output
+ // buffer
+ if(kdf->residual.t.size > 0)
+ {
+ INT32 size;
+ //
+ // Don't use more of the residual than will fit or more than are
+ // available
+ size = MIN(kdf->residual.t.size, bytesLeft);
+ // Copy some or all of the residual to the output. The residual is
+ // at the end of the buffer. The residual might be a full buffer.
+ MemoryCopy(random,
+ &kdf->residual.t.buffer
+ [kdf->digestSize - kdf->residual.t.size], size);
+ // Advance the buffer pointer
+ random += size;
+ // Reduce the number of bytes left to get
+ bytesLeft -= size;
+ // And reduce the residual size appropriately
+ kdf->residual.t.size -= (UINT16)size;
+ }
+ else
+ {
+ UINT16 blocks = (UINT16)(bytesLeft / kdf->digestSize);
+ //
+ // Get the number of required full blocks
+ if(blocks > 0)
+ {
+ UINT16 size = blocks * kdf->digestSize;
+ // Get some number of full blocks and put them in the return buffer
+ CryptKDFa(kdf->hash, kdf->seed, kdf->label, kdf->context, NULL,
+ kdf->limit, random, &counter, blocks);
+ // reduce the size remaining to be moved and advance the pointer
+ bytesLeft -= size;
+ random += size;
+ }
+ else
+ {
+ // Fill the residual buffer with a full block and then loop to
+ // top to get part of it copied to the output.
+ kdf->residual.t.size = CryptKDFa(kdf->hash, kdf->seed,
+ kdf->label, kdf->context, NULL,
+ kdf->limit,
+ kdf->residual.t.buffer,
+ &counter, 1);
+ }
+ }
+ }
+ kdf->counter = counter;
+ return randomSize;
+ }
+ else if(state->drbg.magic == DRBG_MAGIC)
+ {
+ DRBG_STATE *drbgState = (DRBG_STATE *)state;
+ DRBG_KEY_SCHEDULE keySchedule;
+ DRBG_SEED *seed = &drbgState->seed;
+ memset(&keySchedule, 0, sizeof(keySchedule)); /* libtpms added: coverity */
+ if(drbgState->reseedCounter >= CTR_DRBG_MAX_REQUESTS_PER_RESEED)
+ {
+ if(drbgState == &drbgDefault)
+ {
+ DRBG_Reseed(drbgState, NULL, NULL);
+ if(IsEntropyBad() && !IsSelfTest())
+ return 0;
+ }
+ else
+ {
+ // If this is a PRNG then the only way to get
+ // here is if the SW has run away.
+ LOG_FAILURE(FATAL_ERROR_INTERNAL);
+ return 0;
+ }
+ }
+ // if the allowed number of bytes in a request is larger than the
+ // less than the number of bytes that can be requested, then check
+#if UINT16_MAX >= CTR_DRBG_MAX_BYTES_PER_REQUEST
+ if(randomSize > CTR_DRBG_MAX_BYTES_PER_REQUEST)
+ randomSize = CTR_DRBG_MAX_BYTES_PER_REQUEST;
+#endif
+ // Create encryption schedule
+ if(DRBG_ENCRYPT_SETUP((BYTE *)pDRBG_KEY(seed),
+ DRBG_KEY_SIZE_BITS, &keySchedule) != 0)
+ {
+ LOG_FAILURE(FATAL_ERROR_INTERNAL);
+ return 0;
+ }
+ // Generate the random data
+ EncryptDRBG(random, randomSize, &keySchedule, pDRBG_IV(seed),
+ drbgState->lastValue);
+ // Do a key update
+ DRBG_Update(drbgState, &keySchedule, NULL);
+ // Increment the reseed counter
+ drbgState->reseedCounter += 1;
+ }
+ else
+ {
+ LOG_FAILURE(FATAL_ERROR_INTERNAL);
+ return 0; // libtpms changed from FALSE
+ }
+ return randomSize;
+}
+/* 10.2.16.6 DRBG_Instantiate() */
+/* This is CTR_DRBG_Instantiate_algorithm() from [SP 800-90A 10.2.1.3.1]. This is called when a the
+ TPM DRBG is to be instantiated. This is called to instantiate a DRBG used by the TPM for normal
+ operations. */
+/* Return Values Meaning */
+/* TRUE instantiation succeeded */
+/* FALSE instantiation failed */
+LIB_EXPORT BOOL
+DRBG_Instantiate(
+ DRBG_STATE *drbgState, // OUT: the instantiated value
+ UINT16 pSize, // IN: Size of personalization string
+ BYTE *personalization // IN: The personalization string
+ )
+{
+ DRBG_SEED seed;
+ DRBG_SEED dfResult;
+ //
+ pAssert((pSize == 0) || (pSize <= sizeof(seed)) || (personalization != NULL));
+ // If the DRBG has not been tested, test when doing an instantiation. Since
+ // Instantiation is called during self test, make sure we don't get stuck in a
+ // loop.
+ if(!IsDrbgTested() && !IsSelfTest() && !DRBG_SelfTest())
+ return FALSE;
+ // If doing a self test, DRBG_GetEntropy will return the NIST
+ // test vector value.
+ if(!DRBG_GetEntropy(sizeof(seed), (BYTE *)&seed))
+ return FALSE;
+ // set everything to zero
+ memset(drbgState, 0, sizeof(DRBG_STATE));
+ drbgState->magic = DRBG_MAGIC;
+ // Steps 1, 2, 3, 6, 7 of SP 800-90A 10.2.1.3.1 are exactly what
+ // reseeding does. So, do a reduction on the personalization value (if any)
+ // and do a reseed.
+ DRBG_Reseed(drbgState, &seed, DfBuffer(&dfResult, pSize, personalization));
+ return TRUE;
+}
+/* 10.2.16.7 DRBG_Uninstantiate() */
+/* This is Uninstantiate_function() from [SP 800-90A 9.4]. */
+/* Error Returns Meaning */
+/* TPM_RC_VALUE not a valid state */
+LIB_EXPORT TPM_RC
+DRBG_Uninstantiate(
+ DRBG_STATE *drbgState // IN/OUT: working state to erase
+ )
+{
+ if((drbgState == NULL) || (drbgState->magic != DRBG_MAGIC))
+ return TPM_RC_VALUE;
+ memset(drbgState, 0, sizeof(DRBG_STATE));
+ return TPM_RC_SUCCESS;
+}
+
diff --git a/src/tpm2/crypto/openssl/CryptRsa.c b/src/tpm2/crypto/openssl/CryptRsa.c
new file mode 100644
index 0000000..4ed0438
--- /dev/null
+++ b/src/tpm2/crypto/openssl/CryptRsa.c
@@ -0,0 +1,1634 @@
+/********************************************************************************/
+/* */
+/* Implementation of cryptographic primitives for RSA */
+/* Written by Ken Goldman */
+/* IBM Thomas J. Watson Research Center */
+/* $Id: CryptRsa.c 1658 2021-01-22 23:14:01Z kgoldman $ */
+/* */
+/* Licenses and Notices */
+/* */
+/* 1. Copyright Licenses: */
+/* */
+/* - Trusted Computing Group (TCG) grants to the user of the source code in */
+/* this specification (the "Source Code") a worldwide, irrevocable, */
+/* nonexclusive, royalty free, copyright license to reproduce, create */
+/* derivative works, distribute, display and perform the Source Code and */
+/* derivative works thereof, and to grant others the rights granted herein. */
+/* */
+/* - The TCG grants to the user of the other parts of the specification */
+/* (other than the Source Code) the rights to reproduce, distribute, */
+/* display, and perform the specification solely for the purpose of */
+/* developing products based on such documents. */
+/* */
+/* 2. Source Code Distribution Conditions: */
+/* */
+/* - Redistributions of Source Code must retain the above copyright licenses, */
+/* this list of conditions and the following disclaimers. */
+/* */
+/* - Redistributions in binary form must reproduce the above copyright */
+/* licenses, this list of conditions and the following disclaimers in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* 3. Disclaimers: */
+/* */
+/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
+/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
+/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
+/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
+/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
+/* information on specification licensing rights available through TCG */
+/* membership agreements. */
+/* */
+/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
+/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
+/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
+/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
+/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
+/* */
+/* - Without limitation, TCG and its members and licensors disclaim all */
+/* liability, including liability for infringement of any proprietary */
+/* rights, relating to use of information in this specification and to the */
+/* implementation of this specification, and TCG disclaims all liability for */
+/* cost of procurement of substitute goods or services, lost profits, loss */
+/* of use, loss of data or any incidental, consequential, direct, indirect, */
+/* or special damages, whether under contract, tort, warranty or otherwise, */
+/* arising in any way out of use or reliance upon this specification or any */
+/* information herein. */
+/* */
+/* (c) Copyright IBM Corp. and others, 2016 - 2021 */
+/* */
+/********************************************************************************/
+
+/* 10.2.17 CryptRsa.c */
+/* 10.2.17.1 Introduction */
+/* This file contains implementation of cryptographic primitives for RSA. Vendors may replace the
+ implementation in this file with their own library functions. */
+/* 10.2.17.2 Includes */
+/* Need this define to get the private defines for this function */
+#define CRYPT_RSA_C
+#include "Tpm.h"
+#include "Helpers_fp.h" // libtpms added
+
+#include <openssl/rsa.h> // libtpms added
+
+#if ALG_RSA
+/* 10.2.17.3 Obligatory Initialization Functions */
+/* 10.2.17.3.1 CryptRsaInit() */
+/* Function called at _TPM_Init(). */
+BOOL
+CryptRsaInit(
+ void
+ )
+{
+ return TRUE;
+}
+/* 10.2.17.3.2 CryptRsaStartup() */
+/* Function called at TPM2_Startup() */
+BOOL
+CryptRsaStartup(
+ void
+ )
+{
+ return TRUE;
+}
+/* 10.2.17.4 Internal Functions */
+void
+RsaInitializeExponent(
+ privateExponent_t *pExp
+ )
+{
+#if CRT_FORMAT_RSA == NO
+ BN_INIT(pExp->D);
+#else
+ BN_INIT(pExp->Q);
+ BN_INIT(pExp->dP);
+ BN_INIT(pExp->dQ);
+ BN_INIT(pExp->qInv);
+#endif
+}
+/* 10.2.17.4.1 ComputePrivateExponent() */
+/* This function computes the private exponent from the primes. */
+/* Return Value Meaning */
+/* TRUE(1) success */
+/* FALSE(0) failure */
+static BOOL
+ComputePrivateExponent(
+ bigNum P, // IN: first prime (size is 1/2 of bnN)
+ bigNum Q, // IN: second prime (size is 1/2 of bnN)
+ bigNum E, // IN: the public exponent
+ bigNum N, // IN: the public modulus
+ privateExponent_t *pExp // OUT:
+ )
+{
+ BOOL pOK;
+ BOOL qOK;
+#if CRT_FORMAT_RSA == NO
+ BN_RSA(bnPhi);
+ //
+ RsaInitializeExponent(pExp);
+ // Get compute Phi = (p - 1)(q - 1) = pq - p - q + 1 = n - p - q + 1
+ pOK = BnCopy(bnPhi, N);
+ pOK = pOK && BnSub(bnPhi, bnPhi, P);
+ pOK = pOK && BnSub(bnPhi, bnPhi, Q);
+ pOK = pOK && BnAddWord(bnPhi, bnPhi, 1);
+ // Compute the multiplicative inverse d = 1/e mod Phi
+ pOK = pOK && BnModInverse((bigNum)&pExp->D, E, bnPhi);
+ qOK = pOK;
+#else
+ BN_PRIME(temp);
+ bigNum pT;
+ //
+ NOT_REFERENCED(N);
+ RsaInitializeExponent(pExp);
+ BnCopy((bigNum)&pExp->Q, Q);
+ // make p the larger value so that m2 is always less than p
+ if(BnUnsignedCmp(P, Q) < 0)
+ {
+ pT = P;
+ P = Q;
+ Q = pT;
+ }
+ //dP = (1/e) mod (p-1) = d mod (p-1)
+ pOK = BnSubWord(temp, P, 1);
+ pOK = pOK && BnModInverse((bigNum)&pExp->dP, E, temp);
+ //dQ = (1/e) mod (q-1) = d mod (q-1)
+ qOK = BnSubWord(temp, Q, 1);
+ qOK = qOK && BnModInverse((bigNum)&pExp->dQ, E, temp);
+ // qInv = (1/q) mod p
+ if(pOK && qOK)
+ pOK = qOK = BnModInverse((bigNum)&pExp->qInv, Q, P);
+#endif
+ if(!pOK)
+ BnSetWord(P, 0);
+ if(!qOK)
+ BnSetWord(Q, 0);
+ return pOK && qOK;
+}
+/* 10.2.17.4.2 RsaPrivateKeyOp() */
+/* This function is called to do the exponentiation with the private key. Compile options allow use
+ of the simple (but slow) private exponent, or the more complex but faster CRT method. */
+/* Return Value Meaning */
+/* TRUE(1) success */
+/* FALSE(0) failure */
+static BOOL
+RsaPrivateKeyOp(
+ bigNum inOut, // IN/OUT: number to be exponentiated
+ bigNum N, // IN: public modulus (can be NULL if CRT)
+ bigNum P, // IN: one of the primes (can be NULL if not CRT)
+ privateExponent_t *pExp
+ )
+{
+ BOOL OK;
+#if CRT_FORMAT_RSA == NO
+ (P);
+ OK = BnModExp(inOut, inOut, (bigNum)&pExp->D, N);
+#else
+ BN_RSA(M1);
+ BN_RSA(M2);
+ BN_RSA(M);
+ BN_RSA(H);
+ bigNum Q = (bigNum)&pExp->Q;
+ NOT_REFERENCED(N);
+ // Make P the larger prime.
+ // NOTE that when the CRT form of the private key is created, dP will always
+ // be computed using the larger of p and q so the only thing needed here is that
+ // the primes be selected so that they agree with dP.
+ if(BnUnsignedCmp(P, Q) < 0)
+ {
+ bigNum T = P;
+ P = Q;
+ Q = T;
+ }
+ // m1 = cdP mod p
+ OK = BnModExp(M1, inOut, (bigNum)&pExp->dP, P);
+ // m2 = cdQ mod q
+ OK = OK && BnModExp(M2, inOut, (bigNum)&pExp->dQ, Q);
+ // h = qInv * (m1 - m2) mod p = qInv * (m1 + P - m2) mod P because Q < P
+ // so m2 < P
+ OK = OK && BnSub(H, P, M2);
+ OK = OK && BnAdd(H, H, M1);
+ OK = OK && BnModMult(H, H, (bigNum)&pExp->qInv, P);
+ // m = m2 + h * q
+ OK = OK && BnMult(M, H, Q);
+ OK = OK && BnAdd(inOut, M2, M);
+#endif
+ return OK;
+}
+/* 10.2.17.4.3 RSAEP() */
+/* This function performs the RSAEP operation defined in PKCS#1v2.1. It is an exponentiation of a
+ value (m) with the public exponent (e), modulo the public (n). */
+/* Error Returns Meaning */
+/* TPM_RC_VALUE number to exponentiate is larger than the modulus */
+#if !USE_OPENSSL_FUNCTIONS_RSA // libtpms added
+static TPM_RC
+RSAEP(
+ TPM2B *dInOut, // IN: size of the encrypted block and the size of
+ // the encrypted value. It must be the size of
+ // the modulus.
+ // OUT: the encrypted data. Will receive the
+ // decrypted value
+ OBJECT *key // IN: the key to use
+ )
+{
+ TPM2B_TYPE(4BYTES, 4);
+ TPM2B_4BYTES(e) = {{4, {(BYTE)((RSA_DEFAULT_PUBLIC_EXPONENT >> 24) & 0xff),
+ (BYTE)((RSA_DEFAULT_PUBLIC_EXPONENT >> 16) & 0xff),
+ (BYTE)((RSA_DEFAULT_PUBLIC_EXPONENT >> 8) & 0xff),
+ (BYTE)((RSA_DEFAULT_PUBLIC_EXPONENT)& 0xff)}}};
+ //
+ if(key->publicArea.parameters.rsaDetail.exponent != 0)
+ UINT32_TO_BYTE_ARRAY(key->publicArea.parameters.rsaDetail.exponent,
+ e.t.buffer);
+ return ModExpB(dInOut->size, dInOut->buffer, dInOut->size, dInOut->buffer,
+ e.t.size, e.t.buffer, key->publicArea.unique.rsa.t.size,
+ key->publicArea.unique.rsa.t.buffer);
+}
+/* 10.2.17.4.4 RSADP() */
+/* This function performs the RSADP operation defined in PKCS#1v2.1. It is an exponentiation of a
+ value (c) with the private exponent (d), modulo the public modulus (n). The decryption is in
+ place. */
+/* This function also checks the size of the private key. If the size indicates that only a prime
+ value is present, the key is converted to being a private exponent. */
+/* Error Returns Meaning */
+/* TPM_RC_SIZE the value to decrypt is larger than the modulus */
+static TPM_RC
+RSADP(
+ TPM2B *inOut, // IN/OUT: the value to encrypt
+ OBJECT *key // IN: the key
+ )
+{
+ BN_RSA_INITIALIZED(bnM, inOut);
+ BN_RSA_INITIALIZED(bnN, &key->publicArea.unique.rsa);
+ BN_RSA_INITIALIZED(bnP, &key->sensitive.sensitive.rsa);
+ if(BnUnsignedCmp(bnM, bnN) >= 0)
+ return TPM_RC_SIZE;
+ // private key operation requires that private exponent be loaded
+ // During self-test, this might not be the case so load it up if it hasn't
+ // already done
+ // been done
+ if(!key->attributes.privateExp)
+ CryptRsaLoadPrivateExponent(key);
+ if(!RsaPrivateKeyOp(bnM, bnN, bnP, &key->privateExponent))
+ FAIL(FATAL_ERROR_INTERNAL);
+ BnTo2B(bnM, inOut, inOut->size);
+ return TPM_RC_SUCCESS;
+}
+/* 10.2.17.4.5 OaepEncode() */
+/* This function performs OAEP padding. The size of the buffer to receive the OAEP padded data must
+ equal the size of the modulus */
+/* Error Returns Meaning */
+/* TPM_RC_VALUE hashAlg is not valid or message size is too large */
+static TPM_RC
+OaepEncode(
+ TPM2B *padded, // OUT: the pad data
+ TPM_ALG_ID hashAlg, // IN: algorithm to use for padding
+ const TPM2B *label, // IN: null-terminated string (may be NULL)
+ TPM2B *message, // IN: the message being padded
+ RAND_STATE *rand // IN: the random number generator to use
+ )
+{
+ INT32 padLen;
+ INT32 dbSize;
+ INT32 i;
+ BYTE mySeed[MAX_DIGEST_SIZE];
+ BYTE *seed = mySeed;
+ UINT16 hLen = CryptHashGetDigestSize(hashAlg);
+ BYTE mask[MAX_RSA_KEY_BYTES];
+ BYTE *pp;
+ BYTE *pm;
+ TPM_RC retVal = TPM_RC_SUCCESS;
+ pAssert(padded != NULL && message != NULL);
+ // A value of zero is not allowed because the KDF can't produce a result
+ // if the digest size is zero.
+ if(hLen == 0)
+ return TPM_RC_VALUE;
+ // Basic size checks
+ // make sure digest isn't too big for key size
+ if(padded->size < (2 * hLen) + 2)
+ ERROR_RETURN(TPM_RC_HASH);
+ // and that message will fit messageSize <= k - 2hLen - 2
+ if(message->size > (padded->size - (2 * hLen) - 2))
+ ERROR_RETURN(TPM_RC_VALUE);
+ // Hash L even if it is null
+ // Offset into padded leaving room for masked seed and byte of zero
+ pp = &padded->buffer[hLen + 1];
+ if(CryptHashBlock(hashAlg, label->size, (BYTE *)label->buffer,
+ hLen, pp) != hLen)
+ ERROR_RETURN(TPM_RC_FAILURE);
+ // concatenate PS of k mLen 2hLen 2
+ padLen = padded->size - message->size - (2 * hLen) - 2;
+ MemorySet(&pp[hLen], 0, padLen);
+ pp[hLen + padLen] = 0x01;
+ padLen += 1;
+ memcpy(&pp[hLen + padLen], message->buffer, message->size);
+ // The total size of db = hLen + pad + mSize;
+ dbSize = hLen + padLen + message->size;
+ // If testing, then use the provided seed. Otherwise, use values
+ // from the RNG
+ CryptRandomGenerate(hLen, mySeed);
+ DRBG_Generate(rand, mySeed, (UINT16)hLen);
+ // mask = MGF1 (seed, nSize hLen 1)
+ CryptMGF_KDF(dbSize, mask, hashAlg, hLen, seed, 0);
+ // Create the masked db
+ pm = mask;
+ for(i = dbSize; i > 0; i--)
+ *pp++ ^= *pm++;
+ pp = &padded->buffer[hLen + 1];
+ // Run the masked data through MGF1
+ if(CryptMGF_KDF(hLen, &padded->buffer[1], hashAlg, dbSize, pp, 0) != (unsigned)hLen)
+ ERROR_RETURN(TPM_RC_VALUE);
+ // Now XOR the seed to create masked seed
+ pp = &padded->buffer[1];
+ pm = seed;
+ for(i = hLen; i > 0; i--)
+ *pp++ ^= *pm++;
+ // Set the first byte to zero
+ padded->buffer[0] = 0x00;
+ Exit:
+ return retVal;
+}
+/* 10.2.17.4.6 OaepDecode() */
+/* This function performs OAEP padding checking. The size of the buffer to receive the recovered
+ data. If the padding is not valid, the dSize size is set to zero and the function returns
+ TPM_RC_VALUE. */
+/* The dSize parameter is used as an input to indicate the size available in the buffer. If
+ insufficient space is available, the size is not changed and the return code is TPM_RC_VALUE. */
+/* Error Returns Meaning */
+/* TPM_RC_VALUE the value to decode was larger than the modulus, or the padding is wrong or the
+ buffer to receive the results is too small */
+static TPM_RC
+OaepDecode(
+ TPM2B *dataOut, // OUT: the recovered data
+ TPM_ALG_ID hashAlg, // IN: algorithm to use for padding
+ const TPM2B *label, // IN: null-terminated string (may be NULL)
+ TPM2B *padded // IN: the padded data
+ )
+{
+ UINT32 i;
+ BYTE seedMask[MAX_DIGEST_SIZE];
+ UINT32 hLen = CryptHashGetDigestSize(hashAlg);
+ BYTE mask[MAX_RSA_KEY_BYTES];
+ BYTE *pp;
+ BYTE *pm;
+ TPM_RC retVal = TPM_RC_SUCCESS;
+ // Strange size (anything smaller can't be an OAEP padded block)
+ // Also check for no leading 0
+ if((padded->size < (unsigned)((2 * hLen) + 2)) || (padded->buffer[0] != 0))
+ ERROR_RETURN(TPM_RC_VALUE);
+ // Use the hash size to determine what to put through MGF1 in order
+ // to recover the seedMask
+ CryptMGF_KDF(hLen, seedMask, hashAlg, padded->size - hLen - 1,
+ &padded->buffer[hLen + 1], 0);
+ // Recover the seed into seedMask
+ pAssert(hLen <= sizeof(seedMask));
+ pp = &padded->buffer[1];
+ pm = seedMask;
+ for(i = hLen; i > 0; i--)
+ *pm++ ^= *pp++;
+ // Use the seed to generate the data mask
+ CryptMGF_KDF(padded->size - hLen - 1, mask, hashAlg, hLen, seedMask, 0);
+ // Use the mask generated from seed to recover the padded data
+ pp = &padded->buffer[hLen + 1];
+ pm = mask;
+ for(i = (padded->size - hLen - 1); i > 0; i--)
+ *pm++ ^= *pp++;
+ // Make sure that the recovered data has the hash of the label
+ // Put trial value in the seed mask
+ if((CryptHashBlock(hashAlg, label->size, (BYTE *)label->buffer,
+ hLen, seedMask)) != hLen)
+ FAIL(FATAL_ERROR_INTERNAL);
+ if(memcmp(seedMask, mask, hLen) != 0)
+ ERROR_RETURN(TPM_RC_VALUE);
+ // find the start of the data
+ pm = &mask[hLen];
+ for(i = (UINT32)padded->size - (2 * hLen) - 1; i > 0; i--)
+ {
+ if(*pm++ != 0)
+ break;
+ }
+ // If we ran out of data or didn't end with 0x01, then return an error
+ if(i == 0 || pm[-1] != 0x01)
+ ERROR_RETURN(TPM_RC_VALUE);
+ // pm should be pointing at the first part of the data
+ // and i is one greater than the number of bytes to move
+ i--;
+ if(i > dataOut->size)
+ // Special exit to preserve the size of the output buffer
+ return TPM_RC_VALUE;
+ memcpy(dataOut->buffer, pm, i);
+ dataOut->size = (UINT16)i;
+ Exit:
+ if(retVal != TPM_RC_SUCCESS)
+ dataOut->size = 0;
+ return retVal;
+}
+/* 10.2.17.4.7 PKCS1v1_5Encode() */
+/* This function performs the encoding for RSAES-PKCS1-V1_5-ENCRYPT as defined in PKCS#1V2.1 */
+/* Error Returns Meaning */
+/* TPM_RC_VALUE message size is too large */
+static TPM_RC
+RSAES_PKCS1v1_5Encode(
+ TPM2B *padded, // OUT: the pad data
+ TPM2B *message, // IN: the message being padded
+ RAND_STATE *rand
+ )
+{
+ UINT32 ps = padded->size - message->size - 3;
+ //
+ if(message->size > padded->size - 11)
+ return TPM_RC_VALUE;
+ // move the message to the end of the buffer
+ memcpy(&padded->buffer[padded->size - message->size], message->buffer,
+ message->size);
+ // Set the first byte to 0x00 and the second to 0x02
+ padded->buffer[0] = 0;
+ padded->buffer[1] = 2;
+ // Fill with random bytes
+ DRBG_Generate(rand, &padded->buffer[2], (UINT16)ps);
+ // Set the delimiter for the random field to 0
+ padded->buffer[2 + ps] = 0;
+ // Now, the only messy part. Make sure that all the 'ps' bytes are non-zero
+ // In this implementation, use the value of the current index
+ for(ps++; ps > 1; ps--)
+ {
+ if(padded->buffer[ps] == 0)
+ padded->buffer[ps] = 0x55; // In the < 0.5% of the cases that the
+ // random value is 0, just pick a value to
+ // put into the spot.
+ }
+ return TPM_RC_SUCCESS;
+}
+/* 10.2.17.4.8 RSAES_Decode() */
+/* This function performs the decoding for RSAES-PKCS1-V1_5-ENCRYPT as defined in PKCS#1V2.1 */
+/* Error Returns Meaning */
+/* TPM_RC_FAIL decoding error or results would no fit into provided buffer */
+static TPM_RC
+RSAES_Decode(
+ TPM2B *message, // OUT: the recovered message
+ TPM2B *coded // IN: the encoded message
+ )
+{
+ BOOL fail = FALSE;
+ UINT16 pSize;
+ fail = (coded->size < 11);
+ fail = (coded->buffer[0] != 0x00) | fail;
+ fail = (coded->buffer[1] != 0x02) | fail;
+ for(pSize = 2; pSize < coded->size; pSize++)
+ {
+ if(coded->buffer[pSize] == 0)
+ break;
+ }
+ pSize++;
+ // Make sure that pSize has not gone over the end and that there are at least 8
+ // bytes of pad data.
+ fail = (pSize > coded->size) | fail;
+ fail = ((pSize - 2) <= 8) | fail;
+ if((message->size < (UINT16)(coded->size - pSize)) || fail)
+ return TPM_RC_VALUE;
+ message->size = coded->size - pSize;
+ memcpy(message->buffer, &coded->buffer[pSize], coded->size - pSize);
+ return TPM_RC_SUCCESS;
+}
+#endif // libtpms added
+/* 10.2.17.4.13 CryptRsaPssSaltSize() */
+/* This function computes the salt size used in PSS. It is broken out so that the X509 code can get
+ the same value that is used by the encoding function in this module. */
+INT16
+CryptRsaPssSaltSize(
+ INT16 hashSize,
+ INT16 outSize
+)
+{
+ INT16 saltSize;
+ //
+ // (Mask Length) = (outSize - hashSize - 1);
+ // Max saltSize is (Mask Length) - 1
+ saltSize = (outSize - hashSize - 1) - 1;
+ // Use the maximum salt size allowed by FIPS 186-4
+ if (saltSize > hashSize)
+ saltSize = hashSize;
+ else if (saltSize < 0)
+ saltSize = 0;
+ return saltSize;
+}
+
+#if !USE_OPENSSL_FUNCTIONS_RSA // libtpms added
+/* 10.2.17.4.9 PssEncode() */
+/* This function creates an encoded block of data that is the size of modulus. The function uses the
+ maximum salt size that will fit in the encoded block. */
+/* Returns TPM_RC_SUCCESS or goes into failure mode. */
+static TPM_RC
+PssEncode(
+ TPM2B *out, // OUT: the encoded buffer
+ TPM_ALG_ID hashAlg, // IN: hash algorithm for the encoding
+ TPM2B *digest, // IN: the digest
+ RAND_STATE *rand // IN: random number source
+ )
+{
+ UINT32 hLen = CryptHashGetDigestSize(hashAlg);
+ BYTE salt[MAX_RSA_KEY_BYTES - 1];
+ UINT16 saltSize;
+ BYTE *ps = salt;
+ BYTE *pOut;
+ UINT16 mLen;
+ HASH_STATE hashState;
+ // These are fatal errors indicating bad TPM firmware
+ pAssert(out != NULL && hLen > 0 && digest != NULL);
+ // Get the size of the mask
+ mLen = (UINT16)(out->size - hLen - 1);
+ // Maximum possible salt size is mask length - 1
+ saltSize = mLen - 1;
+ // Use the maximum salt size allowed by FIPS 186-4
+ if(saltSize > hLen)
+ saltSize = (UINT16)hLen;
+ //using eOut for scratch space
+ // Set the first 8 bytes to zero
+ pOut = out->buffer;
+ memset(pOut, 0, 8);
+ // Get set the salt
+ DRBG_Generate(rand, salt, saltSize);
+ // Create the hash of the pad || input hash || salt
+ CryptHashStart(&hashState, hashAlg);
+ CryptDigestUpdate(&hashState, 8, pOut);
+ CryptDigestUpdate2B(&hashState, digest);
+ CryptDigestUpdate(&hashState, saltSize, salt);
+ CryptHashEnd(&hashState, hLen, &pOut[out->size - hLen - 1]);
+ // Create a mask
+ if(CryptMGF_KDF(mLen, pOut, hashAlg, hLen, &pOut[mLen], 0) != mLen)
+ FAIL(FATAL_ERROR_INTERNAL);
+ // Since this implementation uses key sizes that are all even multiples of
+ // 8, just need to make sure that the most significant bit is CLEAR
+ *pOut &= 0x7f;
+ // Before we mess up the pOut value, set the last byte to 0xbc
+ pOut[out->size - 1] = 0xbc;
+ // XOR a byte of 0x01 at the position just before where the salt will be XOR'ed
+ pOut = &pOut[mLen - saltSize - 1];
+ *pOut++ ^= 0x01;
+ // XOR the salt data into the buffer
+ for(; saltSize > 0; saltSize--)
+ *pOut++ ^= *ps++;
+ // and we are done
+ return TPM_RC_SUCCESS;
+}
+/* 10.2.17.4.10 PssDecode() */
+/* This function checks that the PSS encoded block was built from the provided digest. If the check
+ is successful, TPM_RC_SUCCESS is returned. Any other value indicates an error. */
+/* This implementation of PSS decoding is intended for the reference TPM implementation and is not
+ at all generalized. It is used to check signatures over hashes and assumptions are made about
+ the sizes of values. Those assumptions are enforce by this implementation. This implementation
+ does allow for a variable size salt value to have been used by the creator of the signature. */
+/* Error Returns Meaning */
+/* TPM_RC_SCHEME hashAlg is not a supported hash algorithm */
+/* TPM_RC_VALUE decode operation failed */
+static TPM_RC
+PssDecode(
+ TPM_ALG_ID hashAlg, // IN: hash algorithm to use for the encoding
+ TPM2B *dIn, // In: the digest to compare
+ TPM2B *eIn // IN: the encoded data
+ )
+{
+ UINT32 hLen = CryptHashGetDigestSize(hashAlg);
+ BYTE mask[MAX_RSA_KEY_BYTES];
+ BYTE *pm = mask;
+ BYTE *pe;
+ BYTE pad[8] = {0};
+ UINT32 i;
+ UINT32 mLen;
+ BYTE fail;
+ TPM_RC retVal = TPM_RC_SUCCESS;
+ HASH_STATE hashState;
+ // These errors are indicative of failures due to programmer error
+ pAssert(dIn != NULL && eIn != NULL);
+ pe = eIn->buffer;
+ // check the hash scheme
+ if(hLen == 0)
+ ERROR_RETURN(TPM_RC_SCHEME);
+ // most significant bit must be zero
+ fail = pe[0] & 0x80;
+ // last byte must be 0xbc
+ fail |= pe[eIn->size - 1] ^ 0xbc;
+ // Use the hLen bytes at the end of the buffer to generate a mask
+ // Doesn't start at the end which is a flag byte
+ mLen = eIn->size - hLen - 1;
+ CryptMGF_KDF(mLen, mask, hashAlg, hLen, &pe[mLen], 0);
+ // Clear the MSO of the mask to make it consistent with the encoding.
+ mask[0] &= 0x7F;
+ pAssert(mLen <= sizeof(mask));
+ // XOR the data into the mask to recover the salt. This sequence
+ // advances eIn so that it will end up pointing to the seed data
+ // which is the hash of the signature data
+ for(i = mLen; i > 0; i--)
+ *pm++ ^= *pe++;
+ // Find the first byte of 0x01 after a string of all 0x00
+ for(pm = mask, i = mLen; i > 0; i--)
+ {
+ if(*pm == 0x01)
+ break;
+ else
+ fail |= *pm++;
+ }
+ // i should not be zero
+ fail |= (i == 0);
+ // if we have failed, will continue using the entire mask as the salt value so
+ // that the timing attacks will not disclose anything (I don't think that this
+ // is a problem for TPM applications but, usually, we don't fail so this
+ // doesn't cost anything).
+ if(fail)
+ {
+ i = mLen;
+ pm = mask;
+ }
+ else
+ {
+ pm++;
+ i--;
+ }
+ // i contains the salt size and pm points to the salt. Going to use the input
+ // hash and the seed to recreate the hash in the lower portion of eIn.
+ CryptHashStart(&hashState, hashAlg);
+ // add the pad of 8 zeros
+ CryptDigestUpdate(&hashState, 8, pad);
+ // add the provided digest value
+ CryptDigestUpdate(&hashState, dIn->size, dIn->buffer);
+ // and the salt
+ CryptDigestUpdate(&hashState, i, pm);
+ // get the result
+ fail |= (CryptHashEnd(&hashState, hLen, mask) != hLen);
+ // Compare all bytes
+ for(pm = mask; hLen > 0; hLen--)
+ // don't use fail = because that could skip the increment and compare
+ // operations after the first failure and that gives away timing
+ // information.
+ fail |= *pm++ ^ *pe++;
+ retVal = (fail != 0) ? TPM_RC_VALUE : TPM_RC_SUCCESS;
+ Exit:
+ return retVal;
+}
+/* 10.2.17.4.16 MakeDerTag() */
+/* Construct the DER value that is used in RSASSA */
+/* Return Value Meaning */
+/* > 0 size of value */
+/* <= 0 no hash exists */
+INT16
+MakeDerTag(
+ TPM_ALG_ID hashAlg,
+ INT16 sizeOfBuffer,
+ BYTE *buffer
+ )
+{
+ // 0x30, 0x31, // SEQUENCE (2 elements) 1st
+ // 0x30, 0x0D, // SEQUENCE (2 elements)
+ // 0x06, 0x09, // HASH OID
+ // 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01,
+ // 0x05, 0x00, // NULL
+ // 0x04, 0x20 // OCTET STRING
+ HASH_DEF *info = CryptGetHashDef(hashAlg);
+ INT16 oidSize;
+ // If no OID, can't do encode
+ VERIFY(info != NULL);
+ oidSize = 2 + (info->OID)[1];
+ // make sure this fits in the buffer
+ VERIFY(sizeOfBuffer >= (oidSize + 8));
+ *buffer++ = 0x30; // 1st SEQUENCE
+ // Size of the 1st SEQUENCE is 6 bytes + size of the hash OID + size of the
+ // digest size
+ *buffer++ = (BYTE)(6 + oidSize + info->digestSize); //
+ *buffer++ = 0x30; // 2nd SEQUENCE
+ // size is 4 bytes of overhead plus the side of the OID
+ *buffer++ = (BYTE)(2 + oidSize);
+ MemoryCopy(buffer, info->OID, oidSize);
+ buffer += oidSize;
+ *buffer++ = 0x05; // Add a NULL
+ *buffer++ = 0x00;
+
+ *buffer++ = 0x04;
+ *buffer++ = (BYTE)(info->digestSize);
+ return oidSize + 8;
+ Error:
+ return 0;
+
+}
+
+/* 10.2.17.4.17 RSASSA_Encode() */
+/* Encode a message using PKCS1v1.5 method. */
+/* Error Returns Meaning */
+/* TPM_RC_SCHEME hashAlg is not a supported hash algorithm */
+/* TPM_RC_SIZE eOutSize is not large enough */
+/* TPM_RC_VALUE hInSize does not match the digest size of hashAlg */
+static TPM_RC
+RSASSA_Encode(
+ TPM2B *pOut, // IN:OUT on in, the size of the public key
+ // on out, the encoded area
+ TPM_ALG_ID hashAlg, // IN: hash algorithm for PKCS1v1_5
+ TPM2B *hIn // IN: digest value to encode
+ )
+{
+ BYTE DER[20];
+ BYTE *der = DER;
+ INT32 derSize = MakeDerTag(hashAlg, sizeof(DER), DER);
+ BYTE *eOut;
+ INT32 fillSize;
+ TPM_RC retVal = TPM_RC_SUCCESS;
+
+ // Can't use this scheme if the algorithm doesn't have a DER string defined.
+ if(derSize == 0)
+ ERROR_RETURN(TPM_RC_SCHEME);
+
+ // If the digest size of 'hashAl' doesn't match the input digest size, then
+ // the DER will misidentify the digest so return an error
+ if(CryptHashGetDigestSize(hashAlg) != hIn->size)
+ ERROR_RETURN(TPM_RC_VALUE);
+ fillSize = pOut->size - derSize - hIn->size - 3;
+ eOut = pOut->buffer;
+
+ // Make sure that this combination will fit in the provided space
+ if(fillSize < 8)
+ ERROR_RETURN(TPM_RC_SIZE);
+
+ // Start filling
+ *eOut++ = 0; // initial byte of zero
+ *eOut++ = 1; // byte of 0x01
+ for(; fillSize > 0; fillSize--)
+ *eOut++ = 0xff; // bunch of 0xff
+ *eOut++ = 0; // another 0
+ for(; derSize > 0; derSize--)
+ *eOut++ = *der++; // copy the DER
+ der = hIn->buffer;
+ for(fillSize = hIn->size; fillSize > 0; fillSize--)
+ *eOut++ = *der++; // copy the hash
+ Exit:
+ return retVal;
+}
+
+/* 10.2.17.4.18 RSASSA_Decode() */
+/* This function performs the RSASSA decoding of a signature. */
+/* Error Returns Meaning */
+/* TPM_RC_VALUE decode unsuccessful */
+/* TPM_RC_SCHEME haslAlg is not supported */
+static TPM_RC
+RSASSA_Decode(
+ TPM_ALG_ID hashAlg, // IN: hash algorithm to use for the encoding
+ TPM2B *hIn, // In: the digest to compare
+ TPM2B *eIn // IN: the encoded data
+ )
+{
+ BYTE fail;
+ BYTE DER[20];
+ BYTE *der = DER;
+ INT32 derSize = MakeDerTag(hashAlg, sizeof(DER), DER);
+ BYTE *pe;
+ INT32 hashSize = CryptHashGetDigestSize(hashAlg);
+ INT32 fillSize;
+ TPM_RC retVal;
+ BYTE *digest;
+ UINT16 digestSize;
+
+ pAssert(hIn != NULL && eIn != NULL);
+ pe = eIn->buffer;
+
+ // Can't use this scheme if the algorithm doesn't have a DER string
+ // defined or if the provided hash isn't the right size
+ if(derSize == 0 || (unsigned)hashSize != hIn->size)
+ ERROR_RETURN(TPM_RC_SCHEME);
+
+ // Make sure that this combination will fit in the provided space
+ // Since no data movement takes place, can just walk though this
+ // and accept nearly random values. This can only be called from
+ // CryptValidateSignature() so eInSize is known to be in range.
+ fillSize = eIn->size - derSize - hashSize - 3;
+
+ // Start checking (fail will become non-zero if any of the bytes do not have
+ // the expected value.
+ fail = *pe++; // initial byte of zero
+ fail |= *pe++ ^ 1; // byte of 0x01
+ for(; fillSize > 0; fillSize--)
+ fail |= *pe++ ^ 0xff; // bunch of 0xff
+ fail |= *pe++; // another 0
+ for(; derSize > 0; derSize--)
+ fail |= *pe++ ^ *der++; // match the DER
+ digestSize = hIn->size;
+ digest = hIn->buffer;
+ for(; digestSize > 0; digestSize--)
+ fail |= *pe++ ^ *digest++; // match the hash
+ retVal = (fail != 0) ? TPM_RC_VALUE : TPM_RC_SUCCESS;
+ Exit:
+ return retVal;
+}
+#endif // libtpms added
+
+/* 10.2.17.4.13 CryptRsaSelectScheme() */
+/* This function is used by TPM2_RSA_Decrypt() and TPM2_RSA_Encrypt(). It sets up the rules to
+ select a scheme between input and object default. This function assume the RSA object is
+ loaded. If a default scheme is defined in object, the default scheme should be chosen, otherwise,
+ the input scheme should be chosen. In the case that both the object and scheme are not
+ TPM_ALG_NULL, then if the schemes are the same, the input scheme will be chosen. if the scheme
+ are not compatible, a NULL pointer will be returned. */
+/* The return pointer may point to a TPM_ALG_NULL scheme. */
+TPMT_RSA_DECRYPT*
+CryptRsaSelectScheme(
+ TPMI_DH_OBJECT rsaHandle, // IN: handle of an RSA key
+ TPMT_RSA_DECRYPT *scheme // IN: a sign or decrypt scheme
+ )
+{
+ OBJECT *rsaObject;
+ TPMT_ASYM_SCHEME *keyScheme;
+ TPMT_RSA_DECRYPT *retVal = NULL;
+ // Get sign object pointer
+ rsaObject = HandleToObject(rsaHandle);
+ keyScheme = &rsaObject->publicArea.parameters.asymDetail.scheme;
+ // if the default scheme of the object is TPM_ALG_NULL, then select the
+ // input scheme
+ if(keyScheme->scheme == TPM_ALG_NULL)
+ {
+ retVal = scheme;
+ }
+ // if the object scheme is not TPM_ALG_NULL and the input scheme is
+ // TPM_ALG_NULL, then select the default scheme of the object.
+ else if(scheme->scheme == TPM_ALG_NULL)
+ {
+ // if input scheme is NULL
+ retVal = (TPMT_RSA_DECRYPT *)keyScheme;
+ }
+ // get here if both the object scheme and the input scheme are
+ // not TPM_ALG_NULL. Need to insure that they are the same.
+ // IMPLEMENTATION NOTE: This could cause problems if future versions have
+ // schemes that have more values than just a hash algorithm. A new function
+ // (IsSchemeSame()) might be needed then.
+ else if(keyScheme->scheme == scheme->scheme
+ && keyScheme->details.anySig.hashAlg == scheme->details.anySig.hashAlg)
+ {
+ retVal = scheme;
+ }
+ // two different, incompatible schemes specified will return NULL
+ return retVal;
+}
+/* 10.2.17.4.14 CryptRsaLoadPrivateExponent() */
+/* Error Returns Meaning */
+/* TPM_RC_BINDING public and private parts of rsaKey are not matched */
+TPM_RC
+CryptRsaLoadPrivateExponent(
+ OBJECT *rsaKey // IN: the RSA key object
+ )
+{
+ BN_RSA_INITIALIZED(bnN, &rsaKey->publicArea.unique.rsa);
+ BN_PRIME_INITIALIZED(bnP, &rsaKey->sensitive.sensitive.rsa);
+ BN_RSA(bnQ);
+ BN_PRIME(bnQr);
+ BN_WORD_INITIALIZED(bnE, (rsaKey->publicArea.parameters.rsaDetail.exponent == 0)
+ ? RSA_DEFAULT_PUBLIC_EXPONENT
+ : rsaKey->publicArea.parameters.rsaDetail.exponent);
+ TPM_RC retVal = TPM_RC_SUCCESS;
+ if(!rsaKey->attributes.privateExp)
+ {
+ TEST(TPM_ALG_NULL);
+ // Make sure that the bigNum used for the exponent is properly initialized
+ RsaInitializeExponent(&rsaKey->privateExponent);
+ // Find the second prime by division
+ BnDiv(bnQ, bnQr, bnN, bnP);
+ if(!BnEqualZero(bnQr))
+ ERROR_RETURN(TPM_RC_BINDING);
+ // Compute the private exponent and return it if found
+ if(!ComputePrivateExponent(bnP, bnQ, bnE, bnN,
+ &rsaKey->privateExponent))
+ ERROR_RETURN(TPM_RC_BINDING);
+ }
+ Exit:
+ rsaKey->attributes.privateExp = (retVal == TPM_RC_SUCCESS);
+ return retVal;
+}
+#if !USE_OPENSSL_FUNCTIONS_RSA // libtpms added
+/* 10.2.17.4.15 CryptRsaEncrypt() */
+/* This is the entry point for encryption using RSA. Encryption is use of the public exponent. The
+ padding parameter determines what padding will be used. */
+/* The cOutSize parameter must be at least as large as the size of the key. */
+/* If the padding is RSA_PAD_NONE, dIn is treated as a number. It must be lower in value than the
+ key modulus. */
+/* 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 the call to RSAEP. This is because the high order bytes of dIn might have
+ a numeric value that is greater than the value of the key modulus. If this had low-order zeros
+ added, it would have a numeric value larger than the modulus even though it started out with a
+ lower numeric value. */
+/* Error Returns Meaning */
+/* TPM_RC_VALUE cOutSize is too small (must be the size of the modulus) */
+/* TPM_RC_SCHEME padType is not a supported scheme */
+LIB_EXPORT TPM_RC
+CryptRsaEncrypt(
+ TPM2B_PUBLIC_KEY_RSA *cOut, // OUT: the encrypted data
+ TPM2B *dIn, // IN: the data to encrypt
+ OBJECT *key, // IN: the key used for encryption
+ TPMT_RSA_DECRYPT *scheme, // IN: the type of padding and hash
+ // if needed
+ const TPM2B *label, // IN: in case it is needed
+ RAND_STATE *rand // IN: random number generator
+ // state (mostly for testing)
+ )
+{
+ TPM_RC retVal = TPM_RC_SUCCESS;
+ TPM2B_PUBLIC_KEY_RSA dataIn;
+ //
+ // if the input and output buffers are the same, copy the input to a scratch
+ // buffer so that things don't get messed up.
+ if(dIn == &cOut->b)
+ {
+ MemoryCopy2B(&dataIn.b, dIn, sizeof(dataIn.t.buffer));
+ dIn = &dataIn.b;
+ }
+ // All encryption schemes return the same size of data
+ cOut->t.size = key->publicArea.unique.rsa.t.size;
+ TEST(scheme->scheme);
+ switch(scheme->scheme)
+ {
+ case TPM_ALG_NULL: // 'raw' encryption
+ {
+ INT32 i;
+ INT32 dSize = dIn->size;
+ // dIn can have more bytes than cOut as long as the extra bytes
+ // are zero. Note: the more significant bytes of a number in a byte
+ // buffer are the bytes at the start of the array.
+ for(i = 0; (i < dSize) && (dIn->buffer[i] == 0); i++);
+ dSize -= i;
+ if(dSize > cOut->t.size)
+ ERROR_RETURN(TPM_RC_VALUE);
+ // Pad cOut with zeros if dIn is smaller
+ memset(cOut->t.buffer, 0, cOut->t.size - dSize);
+ // And copy the rest of the value
+ memcpy(&cOut->t.buffer[cOut->t.size - dSize], &dIn->buffer[i], dSize);
+ // If the size of dIn is the same as cOut dIn could be larger than
+ // the modulus. If it is, then RSAEP() will catch it.
+ }
+ break;
+ case TPM_ALG_RSAES:
+ retVal = RSAES_PKCS1v1_5Encode(&cOut->b, dIn, rand);
+ break;
+ case TPM_ALG_OAEP:
+ retVal = OaepEncode(&cOut->b, scheme->details.oaep.hashAlg, label, dIn,
+ rand);
+ break;
+ default:
+ ERROR_RETURN(TPM_RC_SCHEME);
+ break;
+ }
+ // All the schemes that do padding will come here for the encryption step
+ // Check that the Encoding worked
+ if(retVal == TPM_RC_SUCCESS)
+ // Padding OK so do the encryption
+ retVal = RSAEP(&cOut->b, key);
+ Exit:
+ return retVal;
+}
+/* 10.2.17.4.16 CryptRsaDecrypt() */
+/* This is the entry point for decryption using RSA. Decryption is use of the private exponent. The
+ padType parameter determines what padding was used. */
+/* Error Returns Meaning */
+/* TPM_RC_SIZE cInSize is not the same as the size of the public modulus of key; or numeric value of
+ the encrypted data is greater than the modulus */
+/* TPM_RC_VALUE dOutSize is not large enough for the result */
+/* TPM_RC_SCHEME padType is not supported */
+LIB_EXPORT TPM_RC
+CryptRsaDecrypt(
+ TPM2B *dOut, // OUT: the decrypted data
+ TPM2B *cIn, // IN: the data to decrypt
+ OBJECT *key, // IN: the key to use for decryption
+ TPMT_RSA_DECRYPT *scheme, // IN: the padding scheme
+ const TPM2B *label // IN: in case it is needed for the scheme
+ )
+{
+ TPM_RC retVal;
+ // Make sure that the necessary parameters are provided
+ pAssert(cIn != NULL && dOut != NULL && key != NULL);
+ // Size is checked to make sure that the encrypted value is the right size
+ if(cIn->size != key->publicArea.unique.rsa.t.size)
+ ERROR_RETURN(TPM_RC_SIZE);
+ TEST(scheme->scheme);
+ // For others that do padding, do the decryption in place and then
+ // go handle the decoding.
+ retVal = RSADP(cIn, key);
+ if(retVal == TPM_RC_SUCCESS)
+ {
+ // Remove padding
+ switch(scheme->scheme)
+ {
+ case TPM_ALG_NULL:
+ if(dOut->size < cIn->size)
+ return TPM_RC_VALUE;
+ MemoryCopy2B(dOut, cIn, dOut->size);
+ break;
+ case TPM_ALG_RSAES:
+ retVal = RSAES_Decode(dOut, cIn);
+ break;
+ case TPM_ALG_OAEP:
+ retVal = OaepDecode(dOut, scheme->details.oaep.hashAlg, label, cIn);
+ break;
+ default:
+ retVal = TPM_RC_SCHEME;
+ break;
+ }
+ }
+ Exit:
+ return retVal;
+}
+/* 10.2.17.4.17 CryptRsaSign() */
+/* This function is used to generate an RSA signature of the type indicated in scheme. */
+/* Error Returns Meaning */
+/* TPM_RC_SCHEME scheme or hashAlg are not supported */
+/* TPM_RC_VALUE hInSize does not match hashAlg (for RSASSA) */
+LIB_EXPORT TPM_RC
+CryptRsaSign(
+ TPMT_SIGNATURE *sigOut,
+ OBJECT *key, // IN: key to use
+ TPM2B_DIGEST *hIn, // IN: the digest to sign
+ RAND_STATE *rand // IN: the random number generator
+ // to use (mostly for testing)
+ )
+{
+ TPM_RC retVal = TPM_RC_SUCCESS;
+ UINT16 modSize;
+ // parameter checks
+ pAssert(sigOut != NULL && key != NULL && hIn != NULL);
+ modSize = key->publicArea.unique.rsa.t.size;
+ // for all non-null signatures, the size is the size of the key modulus
+ sigOut->signature.rsapss.sig.t.size = modSize;
+ TEST(sigOut->sigAlg);
+ switch(sigOut->sigAlg)
+ {
+ case TPM_ALG_NULL:
+ sigOut->signature.rsapss.sig.t.size = 0;
+ return TPM_RC_SUCCESS;
+ case TPM_ALG_RSAPSS:
+ retVal = PssEncode(&sigOut->signature.rsapss.sig.b,
+ sigOut->signature.rsapss.hash, &hIn->b, rand);
+ break;
+ case TPM_ALG_RSASSA:
+ retVal = RSASSA_Encode(&sigOut->signature.rsassa.sig.b,
+ sigOut->signature.rsassa.hash, &hIn->b);
+ break;
+ default:
+ retVal = TPM_RC_SCHEME;
+ }
+ if(retVal == TPM_RC_SUCCESS)
+ {
+ // Do the encryption using the private key
+ retVal = RSADP(&sigOut->signature.rsapss.sig.b, key);
+ }
+ return retVal;
+}
+/* 10.2.17.4.18 CryptRsaValidateSignature() */
+/* This function is used to validate an RSA signature. If the signature is valid TPM_RC_SUCCESS is
+ returned. If the signature is not valid, TPM_RC_SIGNATURE is returned. Other return codes
+ indicate either parameter problems or fatal errors. */
+/* Error Returns Meaning */
+/* TPM_RC_SIGNATURE the signature does not check */
+/* TPM_RC_SCHEME unsupported scheme or hash algorithm */
+LIB_EXPORT TPM_RC
+CryptRsaValidateSignature(
+ TPMT_SIGNATURE *sig, // IN: signature
+ OBJECT *key, // IN: public modulus
+ TPM2B_DIGEST *digest // IN: The digest being validated
+ )
+{
+ TPM_RC retVal;
+ //
+ // Fatal programming errors
+ pAssert(key != NULL && sig != NULL && digest != NULL);
+ switch(sig->sigAlg)
+ {
+ case TPM_ALG_RSAPSS:
+ case TPM_ALG_RSASSA:
+ break;
+ default:
+ return TPM_RC_SCHEME;
+ }
+ // Errors that might be caused by calling parameters
+ if(sig->signature.rsassa.sig.t.size != key->publicArea.unique.rsa.t.size)
+ ERROR_RETURN(TPM_RC_SIGNATURE);
+ TEST(sig->sigAlg);
+ // Decrypt the block
+ retVal = RSAEP(&sig->signature.rsassa.sig.b, key);
+ if(retVal == TPM_RC_SUCCESS)
+ {
+ switch(sig->sigAlg)
+ {
+ case TPM_ALG_RSAPSS:
+ retVal = PssDecode(sig->signature.any.hashAlg, &digest->b,
+ &sig->signature.rsassa.sig.b);
+ break;
+ case TPM_ALG_RSASSA:
+ retVal = RSASSA_Decode(sig->signature.any.hashAlg, &digest->b,
+ &sig->signature.rsassa.sig.b);
+ break;
+ default:
+ return TPM_RC_SCHEME;
+ }
+ }
+ Exit:
+ return (retVal != TPM_RC_SUCCESS) ? TPM_RC_SIGNATURE : TPM_RC_SUCCESS;
+}
+#endif // libtpms added
+#if SIMULATION && USE_RSA_KEY_CACHE
+extern int s_rsaKeyCacheEnabled;
+int GetCachedRsaKey(OBJECT *key, RAND_STATE *rand);
+#define GET_CACHED_KEY(key, rand) \
+ (s_rsaKeyCacheEnabled && GetCachedRsaKey(key, rand))
+#else
+#define GET_CACHED_KEY(key, rand)
+#endif
+/* 10.2.17.4.19 CryptRsaGenerateKey() */
+/* Generate an RSA key from a provided seed */
+/* Error Returns Meaning */
+/* TPM_RC_CANCELED operation was canceled */
+/* TPM_RC_RANGE public exponent is not supported */
+/* TPM_RC_VALUE could not find a prime using the provided parameters */
+LIB_EXPORT TPM_RC
+CryptRsaGenerateKey(
+ OBJECT *rsaKey, // IN/OUT: The object structure in which
+ // the key is created.
+ RAND_STATE *rand // IN: if not NULL, the deterministic
+ // RNG state
+ )
+{
+ UINT32 i;
+ BN_PRIME(bnP); // These four declarations initialize the number to 0
+ BN_PRIME(bnQ);
+ BN_RSA(bnD);
+ BN_RSA(bnN);
+ BN_WORD(bnE);
+ UINT32 e;
+ int keySizeInBits;
+ TPMT_PUBLIC *publicArea = &rsaKey->publicArea;
+ TPMT_SENSITIVE *sensitive = &rsaKey->sensitive;
+ TPM_RC retVal = TPM_RC_NO_RESULT;
+ //
+ // Need to make sure that the caller did not specify an exponent that is
+ // not supported
+ e = publicArea->parameters.rsaDetail.exponent;
+ if(e == 0)
+ e = RSA_DEFAULT_PUBLIC_EXPONENT;
+ if(e < 65537)
+ ERROR_RETURN(TPM_RC_RANGE);
+ if(e != RSA_DEFAULT_PUBLIC_EXPONENT && !IsPrimeInt(e))
+ ERROR_RETURN(TPM_RC_RANGE);
+ BnSetWord(bnE, e);
+ // Check that e is prime
+ // check for supported key size.
+ keySizeInBits = publicArea->parameters.rsaDetail.keyBits;
+ if(((keySizeInBits % 1024) != 0)
+ || (keySizeInBits > MAX_RSA_KEY_BITS) // this might be redundant, but...
+ || (keySizeInBits == 0))
+ ERROR_RETURN(TPM_RC_VALUE);
+ // Set the prime size for instrumentation purposes
+ INSTRUMENT_SET(PrimeIndex, PRIME_INDEX(keySizeInBits / 2));
+#if SIMULATION && USE_RSA_KEY_CACHE
+ if(GET_CACHED_KEY(rsaKey, rand))
+ return TPM_RC_SUCCESS;
+#endif
+ // Make sure that key generation has been tested
+ TEST(TPM_ALG_NULL);
+#if USE_OPENSSL_FUNCTIONS_RSA // libtpms added begin
+ if (rand == NULL)
+ return OpenSSLCryptRsaGenerateKey(rsaKey, e, keySizeInBits);
+#endif // libtpms added end
+ // Need to initialize the privateExponent structure
+ RsaInitializeExponent(&rsaKey->privateExponent);
+ // The prime is computed in P. When a new prime is found, Q is checked to
+ // see if it is zero. If so, P is copied to Q and a new P is found.
+ // When both P and Q are non-zero, the modulus and
+ // private exponent are computed and a trial encryption/decryption is
+ // performed. If the encrypt/decrypt fails, assume that at least one of the
+ // primes is composite. Since we don't know which one, set Q to zero and start
+ // over and find a new pair of primes.
+ for(i = 1; (retVal != TPM_RC_SUCCESS) && (i != 100); i++)
+ {
+ if(_plat__IsCanceled())
+ ERROR_RETURN(TPM_RC_CANCELED);
+ BnGeneratePrimeForRSA(bnP, keySizeInBits / 2, e, rand);
+ INSTRUMENT_INC(PrimeCounts[PrimeIndex]);
+ // If this is the second prime, make sure that it differs from the
+ // first prime by at least 2^100
+ if(BnEqualZero(bnQ))
+ {
+ // copy p to q and compute another prime in p
+ BnCopy(bnQ, bnP);
+ continue;
+ }
+ // Make sure that the difference is at least 100 bits. Need to do it this
+ // way because the big numbers are only positive values
+ if(BnUnsignedCmp(bnP, bnQ) < 0)
+ BnSub(bnD, bnQ, bnP);
+ else
+ BnSub(bnD, bnP, bnQ);
+ if(BnMsb(bnD) < 100)
+ continue;
+ //Form the public modulus and set the unique value
+ BnMult(bnN, bnP, bnQ);
+ BnTo2B(bnN, &publicArea->unique.rsa.b,
+ (NUMBYTES)BITS_TO_BYTES(keySizeInBits));
+ // And the prime to the sensitive area
+ BnTo2B(bnP, &sensitive->sensitive.rsa.b,
+ (NUMBYTES)BITS_TO_BYTES(keySizeInBits) / 2);
+ // Make sure everything came out right. The MSb of the values must be
+ // one
+ if(((publicArea->unique.rsa.t.buffer[0] & 0x80) == 0)
+ || ((sensitive->sensitive.rsa.t.buffer[0] & 0x80) == 0))
+ FAIL(FATAL_ERROR_INTERNAL);
+ // Make sure that we can form the private exponent values
+ if(ComputePrivateExponent(bnP, bnQ, bnE, bnN, &rsaKey->privateExponent)
+ != TRUE)
+ {
+ // If ComputePrivateExponent could not find an inverse for
+ // Q, then copy P and recompute P. This might
+ // cause both to be recomputed if P is also zero
+ if(BnEqualZero(bnQ))
+ BnCopy(bnQ, bnP);
+ continue;
+ }
+ retVal = TPM_RC_SUCCESS;
+ // Do a trial encryption decryption if this is a signing key
+ if(IS_ATTRIBUTE(publicArea->objectAttributes, TPMA_OBJECT, sign))
+ {
+ BN_RSA(temp1);
+ BN_RSA(temp2);
+ BnGenerateRandomInRange(temp1, bnN, rand);
+ // Encrypt with public exponent...
+ BnModExp(temp2, temp1, bnE, bnN);
+ // ... then decrypt with private exponent
+ RsaPrivateKeyOp(temp2, bnN, bnP, &rsaKey->privateExponent);
+ // If the starting and ending values are not the same,
+ // start over )-;
+ if(BnUnsignedCmp(temp2, temp1) != 0)
+ {
+ BnSetWord(bnQ, 0);
+ retVal = TPM_RC_NO_RESULT;
+ }
+ }
+ }
+ Exit:
+ if(retVal == TPM_RC_SUCCESS)
+ rsaKey->attributes.privateExp = SET;
+ return retVal;
+}
+
+#if USE_OPENSSL_FUNCTIONS_RSA // libtpms added begin
+LIB_EXPORT TPM_RC
+CryptRsaEncrypt(
+ TPM2B_PUBLIC_KEY_RSA *cOut, // OUT: the encrypted data
+ TPM2B *dIn, // IN: the data to encrypt
+ OBJECT *key, // IN: the key used for encryption
+ TPMT_RSA_DECRYPT *scheme, // IN: the type of padding and hash
+ // if needed
+ const TPM2B *label, // IN: in case it is needed
+ RAND_STATE *rand // IN: random number generator
+ // state (mostly for testing)
+ )
+{
+ TPM_RC retVal;
+ TPM2B_PUBLIC_KEY_RSA dataIn;
+ TPM2B_PUBLIC_KEY_RSA scratch;
+ size_t outlen;
+ EVP_PKEY *pkey = NULL;
+ EVP_PKEY_CTX *ctx = NULL;
+ const EVP_MD *md;
+ const char *digestname;
+ unsigned char *tmp = NULL;
+ //
+ // if the input and output buffers are the same, copy the input to a scratch
+ // buffer so that things don't get messed up.
+ if(dIn == &cOut->b)
+ {
+ MemoryCopy2B(&dataIn.b, dIn, sizeof(dataIn.t.buffer));
+ dIn = &dataIn.b;
+ }
+ // All encryption schemes return the same size of data
+ pAssert(sizeof(cOut->t.buffer) >= key->publicArea.unique.rsa.t.size);
+ cOut->t.size = key->publicArea.unique.rsa.t.size;
+ TEST(scheme->scheme);
+
+ retVal = InitOpenSSLRSAPublicKey(key, &pkey);
+ if (retVal != TPM_RC_SUCCESS)
+ return retVal;
+
+ ctx = EVP_PKEY_CTX_new(pkey, NULL);
+ if (ctx == NULL ||
+ EVP_PKEY_encrypt_init(ctx) <= 0)
+ ERROR_RETURN(TPM_RC_FAILURE);
+
+ switch(scheme->scheme)
+ {
+ case TPM_ALG_NULL: // 'raw' encryption
+ {
+ INT32 i;
+ INT32 dSize = dIn->size;
+ // dIn can have more bytes than cOut as long as the extra bytes
+ // are zero. Note: the more significant bytes of a number in a byte
+ // buffer are the bytes at the start of the array.
+ for(i = 0; (i < dSize) && (dIn->buffer[i] == 0); i++);
+ dSize -= i;
+ scratch.t.size = cOut->t.size;
+ pAssert(scratch.t.size <= sizeof(scratch.t.buffer));
+ if(dSize > scratch.t.size)
+ ERROR_RETURN(TPM_RC_VALUE);
+ // Pad cOut with zeros if dIn is smaller
+ memset(scratch.t.buffer, 0, scratch.t.size - dSize);
+ // And copy the rest of the value; value is then right-aligned
+ memcpy(&scratch.t.buffer[scratch.t.size - dSize], &dIn->buffer[i], dSize);
+
+ dIn = &scratch.b;
+ }
+ if (EVP_PKEY_CTX_set_rsa_padding(ctx, RSA_NO_PADDING) <= 0)
+ ERROR_RETURN(TPM_RC_FAILURE);
+ break;
+ case TPM_ALG_RSAES:
+ if (EVP_PKEY_CTX_set_rsa_padding(ctx, RSA_PKCS1_PADDING) <= 0)
+ ERROR_RETURN(TPM_RC_FAILURE);
+ break;
+ case TPM_ALG_OAEP:
+ digestname = GetDigestNameByHashAlg(scheme->details.oaep.hashAlg);
+ if (digestname == NULL)
+ ERROR_RETURN(TPM_RC_VALUE);
+
+ md = EVP_get_digestbyname(digestname);
+ if (md == NULL ||
+ EVP_PKEY_CTX_set_rsa_padding(ctx, RSA_PKCS1_OAEP_PADDING) <= 0 ||
+ EVP_PKEY_CTX_set_rsa_oaep_md(ctx, md) <= 0)
+ ERROR_RETURN(TPM_RC_FAILURE);
+
+ if (label->size > 0) {
+ tmp = malloc(label->size);
+ if (tmp == NULL)
+ ERROR_RETURN(TPM_RC_FAILURE);
+ memcpy(tmp, label->buffer, label->size);
+ }
+ // label->size == 0 is supported
+ if (EVP_PKEY_CTX_set0_rsa_oaep_label(ctx, tmp, label->size) <= 0)
+ ERROR_RETURN(TPM_RC_FAILURE);
+ tmp = NULL;
+ break;
+ default:
+ ERROR_RETURN(TPM_RC_SCHEME);
+ break;
+ }
+
+ outlen = cOut->t.size;
+
+ if (EVP_PKEY_encrypt(ctx, cOut->t.buffer, &outlen,
+ dIn->buffer, dIn->size) <= 0)
+ ERROR_RETURN(TPM_RC_FAILURE);
+
+ cOut->t.size = outlen;
+
+ Exit:
+ EVP_PKEY_free(pkey);
+ EVP_PKEY_CTX_free(ctx);
+ free(tmp);
+
+ return retVal;
+}
+
+LIB_EXPORT TPM_RC
+CryptRsaDecrypt(
+ TPM2B *dOut, // OUT: the decrypted data
+ TPM2B *cIn, // IN: the data to decrypt
+ OBJECT *key, // IN: the key to use for decryption
+ TPMT_RSA_DECRYPT *scheme, // IN: the padding scheme
+ const TPM2B *label // IN: in case it is needed for the scheme
+ )
+{
+ TPM_RC retVal;
+ EVP_PKEY *pkey = NULL;
+ EVP_PKEY_CTX *ctx = NULL;
+ const EVP_MD *md = NULL;
+ const char *digestname;
+ size_t outlen;
+ unsigned char *tmp = NULL;
+ unsigned char buffer[MAX_RSA_KEY_BYTES];
+
+ // Make sure that the necessary parameters are provided
+ pAssert(cIn != NULL && dOut != NULL && key != NULL);
+ // Size is checked to make sure that the encrypted value is the right size
+ if(cIn->size != key->publicArea.unique.rsa.t.size)
+ ERROR_RETURN(TPM_RC_SIZE);
+ TEST(scheme->scheme);
+
+ retVal = InitOpenSSLRSAPrivateKey(key, &pkey);
+ if (retVal != TPM_RC_SUCCESS)
+ return retVal;
+
+ ctx = EVP_PKEY_CTX_new(pkey, NULL);
+ if (ctx == NULL ||
+ EVP_PKEY_decrypt_init(ctx) <= 0)
+ ERROR_RETURN(TPM_RC_FAILURE);
+
+ switch(scheme->scheme)
+ {
+ case TPM_ALG_NULL: // 'raw' encryption
+ if (EVP_PKEY_CTX_set_rsa_padding(ctx, RSA_NO_PADDING) <= 0)
+ ERROR_RETURN(TPM_RC_FAILURE);
+ break;
+ case TPM_ALG_RSAES:
+ if (EVP_PKEY_CTX_set_rsa_padding(ctx, RSA_PKCS1_PADDING) <= 0)
+ ERROR_RETURN(TPM_RC_FAILURE);
+ break;
+ case TPM_ALG_OAEP:
+ digestname = GetDigestNameByHashAlg(scheme->details.oaep.hashAlg);
+ if (digestname == NULL)
+ ERROR_RETURN(TPM_RC_VALUE);
+
+ md = EVP_get_digestbyname(digestname);
+ if (md == NULL ||
+ EVP_PKEY_CTX_set_rsa_padding(ctx, RSA_PKCS1_OAEP_PADDING) <= 0 ||
+ EVP_PKEY_CTX_set_rsa_oaep_md(ctx, md) <= 0)
+ ERROR_RETURN(TPM_RC_FAILURE);
+
+ if (label->size > 0) {
+ tmp = malloc(label->size);
+ if (tmp == NULL)
+ ERROR_RETURN(TPM_RC_FAILURE);
+ memcpy(tmp, label->buffer, label->size);
+
+ if (EVP_PKEY_CTX_set0_rsa_oaep_label(ctx, tmp, label->size) <= 0)
+ ERROR_RETURN(TPM_RC_FAILURE);
+ tmp = NULL;
+ }
+ break;
+ default:
+ ERROR_RETURN(TPM_RC_SCHEME);
+ break;
+ }
+
+ /* cannot use cOut->buffer */
+ outlen = sizeof(buffer);
+ if (EVP_PKEY_decrypt(ctx, buffer, &outlen,
+ cIn->buffer, cIn->size) <= 0)
+ ERROR_RETURN(TPM_RC_FAILURE);
+
+ if (outlen > dOut->size)
+ ERROR_RETURN(TPM_RC_FAILURE);
+
+ memcpy(dOut->buffer, buffer, outlen);
+ dOut->size = outlen;
+
+ retVal = TPM_RC_SUCCESS;
+
+ Exit:
+ EVP_PKEY_free(pkey);
+ EVP_PKEY_CTX_free(ctx);
+ free(tmp);
+
+ return retVal;
+}
+
+LIB_EXPORT TPM_RC
+CryptRsaSign(
+ TPMT_SIGNATURE *sigOut,
+ OBJECT *key, // IN: key to use
+ TPM2B_DIGEST *hIn, // IN: the digest to sign
+ RAND_STATE *rand // IN: the random number generator
+ // to use (mostly for testing)
+ )
+{
+ TPM_RC retVal = TPM_RC_SUCCESS;
+ UINT16 modSize;
+ size_t outlen;
+ int padding;
+ EVP_PKEY *pkey = NULL;
+ EVP_PKEY_CTX *ctx = NULL;
+ const EVP_MD *md;
+ const char *digestname;
+ TPMI_ALG_HASH hashAlg;
+
+ // parameter checks
+ pAssert(sigOut != NULL && key != NULL && hIn != NULL);
+ modSize = key->publicArea.unique.rsa.t.size;
+ // for all non-null signatures, the size is the size of the key modulus
+ sigOut->signature.rsapss.sig.t.size = modSize;
+ TEST(sigOut->sigAlg);
+
+ switch(sigOut->sigAlg)
+ {
+ case TPM_ALG_NULL:
+ sigOut->signature.rsapss.sig.t.size = 0;
+ return TPM_RC_SUCCESS;
+ case TPM_ALG_RSAPSS:
+ padding = RSA_PKCS1_PSS_PADDING;
+ hashAlg = sigOut->signature.rsapss.hash;
+ break;
+ case TPM_ALG_RSASSA:
+ padding = RSA_PKCS1_PADDING;
+ hashAlg = sigOut->signature.rsassa.hash;
+ break;
+ default:
+ ERROR_RETURN(TPM_RC_SCHEME);
+ }
+
+ digestname = GetDigestNameByHashAlg(hashAlg);
+ if (digestname == NULL)
+ ERROR_RETURN(TPM_RC_VALUE);
+
+ md = EVP_get_digestbyname(digestname);
+ if (md == NULL)
+ ERROR_RETURN(TPM_RC_FAILURE);
+
+ retVal = InitOpenSSLRSAPrivateKey(key, &pkey);
+ if (retVal != TPM_RC_SUCCESS)
+ return retVal;
+
+ ctx = EVP_PKEY_CTX_new(pkey, NULL);
+ if (ctx == NULL ||
+ EVP_PKEY_sign_init(ctx) <= 0)
+ ERROR_RETURN(TPM_RC_FAILURE);
+
+ if (EVP_PKEY_CTX_set_rsa_padding(ctx, padding) <= 0 ||
+ EVP_PKEY_CTX_set_signature_md(ctx, md) <= 0)
+ ERROR_RETURN(TPM_RC_FAILURE);
+
+ /* careful with PSS padding: Use salt length = hash length (-1) if
+ * length(digest) + length(hash-to-sign) + 2 <= modSize
+ * otherwise use the max. possible salt length, which is the default (-2)
+ * test case: 1024 bit key PSS signing sha512 hash
+ */
+ if (padding == RSA_PKCS1_PSS_PADDING &&
+ EVP_MD_size(md) + hIn->b.size + 2 <= modSize && /* OSSL: RSA_padding_add_PKCS1_PSS_mgf1 */
+ EVP_PKEY_CTX_set_rsa_pss_saltlen(ctx, -1) <= 0)
+ ERROR_RETURN(TPM_RC_FAILURE);
+
+ outlen = sigOut->signature.rsapss.sig.t.size;
+ if (EVP_PKEY_sign(ctx,
+ sigOut->signature.rsapss.sig.t.buffer, &outlen,
+ hIn->b.buffer, hIn->b.size) <= 0)
+ ERROR_RETURN(TPM_RC_FAILURE);
+
+ sigOut->signature.rsapss.sig.t.size = outlen;
+
+ Exit:
+ EVP_PKEY_free(pkey);
+ EVP_PKEY_CTX_free(ctx);
+
+ return retVal;
+}
+
+LIB_EXPORT TPM_RC
+CryptRsaValidateSignature(
+ TPMT_SIGNATURE *sig, // IN: signature
+ OBJECT *key, // IN: public modulus
+ TPM2B_DIGEST *digest // IN: The digest being validated
+ )
+{
+ TPM_RC retVal;
+ int padding;
+ EVP_PKEY *pkey = NULL;
+ EVP_PKEY_CTX *ctx = NULL;
+ const EVP_MD *md;
+ const char *digestname;
+
+ //
+ // Fatal programming errors
+ pAssert(key != NULL && sig != NULL && digest != NULL);
+ switch(sig->sigAlg)
+ {
+ case TPM_ALG_RSAPSS:
+ padding = RSA_PKCS1_PSS_PADDING;
+ break;
+ case TPM_ALG_RSASSA:
+ padding = RSA_PKCS1_PADDING;
+ break;
+ default:
+ return TPM_RC_SCHEME;
+ }
+ // Errors that might be caused by calling parameters
+ if(sig->signature.rsassa.sig.t.size != key->publicArea.unique.rsa.t.size)
+ ERROR_RETURN(TPM_RC_SIGNATURE);
+ TEST(sig->sigAlg);
+
+ retVal = InitOpenSSLRSAPublicKey(key, &pkey);
+ if (retVal != TPM_RC_SUCCESS)
+ return retVal;
+
+ digestname = GetDigestNameByHashAlg(sig->signature.any.hashAlg);
+ if (digestname == NULL)
+ ERROR_RETURN(TPM_RC_VALUE);
+
+ md = EVP_get_digestbyname(digestname);
+ ctx = EVP_PKEY_CTX_new(pkey, NULL);
+ if (md == NULL || ctx == NULL ||
+ EVP_PKEY_verify_init(ctx) <= 0)
+ ERROR_RETURN(TPM_RC_FAILURE);
+
+ if (EVP_PKEY_CTX_set_rsa_padding(ctx, padding) <= 0 ||
+ EVP_PKEY_CTX_set_signature_md(ctx, md) <= 0)
+ ERROR_RETURN(TPM_RC_FAILURE);
+
+ if (EVP_PKEY_verify(ctx,
+ sig->signature.rsassa.sig.t.buffer, sig->signature.rsassa.sig.t.size,
+ digest->t.buffer, digest->t.size) <= 0)
+ ERROR_RETURN(TPM_RC_SIGNATURE);
+
+ retVal = TPM_RC_SUCCESS;
+
+ Exit:
+ EVP_PKEY_free(pkey);
+ EVP_PKEY_CTX_free(ctx);
+
+ return (retVal != TPM_RC_SUCCESS) ? TPM_RC_SIGNATURE : TPM_RC_SUCCESS;
+}
+#endif // USE_OPENSSL_FUNCTIONS_RSA libtpms added end
+
+#endif // TPM_ALG_RSA
diff --git a/src/tpm2/crypto/openssl/CryptSmac.c b/src/tpm2/crypto/openssl/CryptSmac.c
new file mode 100644
index 0000000..c4b3515
--- /dev/null
+++ b/src/tpm2/crypto/openssl/CryptSmac.c
@@ -0,0 +1,156 @@
+/********************************************************************************/
+/* */
+/* Message Authentication Codes Based on a Symmetric Block Cipher */
+/* Written by Ken Goldman */
+/* IBM Thomas J. Watson Research Center */
+/* $Id: CryptSmac.c 1658 2021-01-22 23:14:01Z kgoldman $ */
+/* */
+/* Licenses and Notices */
+/* */
+/* 1. Copyright Licenses: */
+/* */
+/* - Trusted Computing Group (TCG) grants to the user of the source code in */
+/* this specification (the "Source Code") a worldwide, irrevocable, */
+/* nonexclusive, royalty free, copyright license to reproduce, create */
+/* derivative works, distribute, display and perform the Source Code and */
+/* derivative works thereof, and to grant others the rights granted herein. */
+/* */
+/* - The TCG grants to the user of the other parts of the specification */
+/* (other than the Source Code) the rights to reproduce, distribute, */
+/* display, and perform the specification solely for the purpose of */
+/* developing products based on such documents. */
+/* */
+/* 2. Source Code Distribution Conditions: */
+/* */
+/* - Redistributions of Source Code must retain the above copyright licenses, */
+/* this list of conditions and the following disclaimers. */
+/* */
+/* - Redistributions in binary form must reproduce the above copyright */
+/* licenses, this list of conditions and the following disclaimers in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* 3. Disclaimers: */
+/* */
+/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
+/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
+/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
+/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
+/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
+/* information on specification licensing rights available through TCG */
+/* membership agreements. */
+/* */
+/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
+/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
+/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
+/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
+/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
+/* */
+/* - Without limitation, TCG and its members and licensors disclaim all */
+/* liability, including liability for infringement of any proprietary */
+/* rights, relating to use of information in this specification and to the */
+/* implementation of this specification, and TCG disclaims all liability for */
+/* cost of procurement of substitute goods or services, lost profits, loss */
+/* of use, loss of data or any incidental, consequential, direct, indirect, */
+/* or special damages, whether under contract, tort, warranty or otherwise, */
+/* arising in any way out of use or reliance upon this specification or any */
+/* information herein. */
+/* */
+/* (c) Copyright IBM Corp. and others, 2018 - 2021 */
+/* */
+/********************************************************************************/
+
+/* 10.2.20 CryptSmac.c */
+/* 10.2.20.1 Introduction */
+/* This file contains the implementation of the message authentication codes based on a symmetric
+ block cipher. These functions only use the single block encryption functions of the selected
+ symmetric cryptographic library. */
+/* 10.2.20.2 Includes, Defines, and Typedefs */
+#define _CRYPT_HASH_C_
+#include "Tpm.h"
+#if SMAC_IMPLEMENTED
+ /* 10.2.20.2.1 CryptSmacStart() */
+ /* Function to start an SMAC. */
+UINT16
+CryptSmacStart(
+ HASH_STATE *state,
+ TPMU_PUBLIC_PARMS *keyParameters,
+ TPM_ALG_ID macAlg, // IN: the type of MAC
+ TPM2B *key
+ )
+{
+ UINT16 retVal = 0;
+ //
+ // Make sure that the key size is correct. This should have been checked
+ // at key load, but...
+ if(BITS_TO_BYTES(keyParameters->symDetail.sym.keyBits.sym) == key->size)
+ {
+ switch(macAlg)
+ {
+#if ALG_CMAC
+ case TPM_ALG_CMAC:
+ retVal = CryptCmacStart(&state->state.smac, keyParameters,
+ macAlg, key);
+ break;
+#endif
+ default:
+ break;
+ }
+ }
+ state->type = (retVal != 0) ? HASH_STATE_SMAC : HASH_STATE_EMPTY;
+ return retVal;
+}
+/* 10.2.20.2.2 CryptMacStart() */
+/* Function to start either an HMAC or an SMAC. Cannot reuse the CryptHmacStart() function because
+ of the difference in number of parameters. */
+UINT16
+CryptMacStart(
+ HMAC_STATE *state,
+ TPMU_PUBLIC_PARMS *keyParameters,
+ TPM_ALG_ID macAlg, // IN: the type of MAC
+ TPM2B *key
+ )
+{
+ MemorySet(state, 0, sizeof(HMAC_STATE));
+ if(CryptHashIsValidAlg(macAlg, FALSE))
+ {
+ return CryptHmacStart(state, macAlg, key->size, key->buffer);
+ }
+ else if(CryptSmacIsValidAlg(macAlg, FALSE))
+ {
+ return CryptSmacStart(&state->hashState, keyParameters, macAlg, key);
+ }
+ else
+ return 0;
+}
+/* 10.2.20.2.3 CryptMacEnd() */
+/* Dispatch to the MAC end function using a size and buffer pointer. */
+UINT16
+CryptMacEnd(
+ HMAC_STATE *state,
+ UINT32 size,
+ BYTE *buffer
+ )
+{
+ UINT16 retVal = 0;
+ if(state->hashState.type == HASH_STATE_SMAC)
+ retVal = (state->hashState.state.smac.smacMethods.end)(
+ &state->hashState.state.smac.state, size, buffer);
+ else if(state->hashState.type == HASH_STATE_HMAC)
+ retVal = CryptHmacEnd(state, size, buffer);
+ state->hashState.type = HASH_STATE_EMPTY;
+ return retVal;
+}
+#if 0 /* libtpms added */
+/* 10.2.20.2.4 CryptMacEnd2B() */
+/* Dispatch to the MAC end function using a 2B. */
+UINT16
+CryptMacEnd2B (
+ HMAC_STATE *state,
+ TPM2B *data
+ )
+{
+ return CryptMacEnd(state, data->size, data->buffer);
+}
+#endif /* libtpms added */
+#endif // SMAC_IMPLEMENTED
+
diff --git a/src/tpm2/crypto/openssl/CryptSym.c b/src/tpm2/crypto/openssl/CryptSym.c
new file mode 100644
index 0000000..c8a0497
--- /dev/null
+++ b/src/tpm2/crypto/openssl/CryptSym.c
@@ -0,0 +1,771 @@
+/********************************************************************************/
+/* */
+/* Symmetric block cipher modes */
+/* Written by Ken Goldman */
+/* IBM Thomas J. Watson Research Center */
+/* $Id: CryptSym.c 1658 2021-01-22 23:14:01Z kgoldman $ */
+/* */
+/* Licenses and Notices */
+/* */
+/* 1. Copyright Licenses: */
+/* */
+/* - Trusted Computing Group (TCG) grants to the user of the source code in */
+/* this specification (the "Source Code") a worldwide, irrevocable, */
+/* nonexclusive, royalty free, copyright license to reproduce, create */
+/* derivative works, distribute, display and perform the Source Code and */
+/* derivative works thereof, and to grant others the rights granted herein. */
+/* */
+/* - The TCG grants to the user of the other parts of the specification */
+/* (other than the Source Code) the rights to reproduce, distribute, */
+/* display, and perform the specification solely for the purpose of */
+/* developing products based on such documents. */
+/* */
+/* 2. Source Code Distribution Conditions: */
+/* */
+/* - Redistributions of Source Code must retain the above copyright licenses, */
+/* this list of conditions and the following disclaimers. */
+/* */
+/* - Redistributions in binary form must reproduce the above copyright */
+/* licenses, this list of conditions and the following disclaimers in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* 3. Disclaimers: */
+/* */
+/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
+/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
+/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
+/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
+/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
+/* information on specification licensing rights available through TCG */
+/* membership agreements. */
+/* */
+/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
+/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
+/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
+/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
+/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
+/* */
+/* - Without limitation, TCG and its members and licensors disclaim all */
+/* liability, including liability for infringement of any proprietary */
+/* rights, relating to use of information in this specification and to the */
+/* implementation of this specification, and TCG disclaims all liability for */
+/* cost of procurement of substitute goods or services, lost profits, loss */
+/* of use, loss of data or any incidental, consequential, direct, indirect, */
+/* or special damages, whether under contract, tort, warranty or otherwise, */
+/* arising in any way out of use or reliance upon this specification or any */
+/* information herein. */
+/* */
+/* (c) Copyright IBM Corp. and others, 2016 - 2021 */
+/* */
+/********************************************************************************/
+
+/* 10.2.19 CryptSym.c */
+/* 10.2.19.1 Introduction */
+/* This file contains the implementation of the symmetric block cipher modes allowed for a
+ TPM. These functions only use the single block encryption functions of the selected symmetric
+ crypto library. */
+
+/* 10.2.19.2 Includes, Defines, and Typedefs */
+#include "Tpm.h"
+#include "CryptSym.h"
+#include "Helpers_fp.h" // libtpms changed
+
+
+#define KEY_BLOCK_SIZES(ALG, alg) \
+ static const INT16 alg##KeyBlockSizes[] = { \
+ ALG##_KEY_SIZES_BITS, -1, ALG##_BLOCK_SIZES };
+
+FOR_EACH_SYM(KEY_BLOCK_SIZES)
+
+/* 10.2.19.3 Initialization and Data Access Functions */
+/* 10.2.19.3.1 CryptSymInit() */
+/* This function is called to do _TPM_Init() processing */
+BOOL
+CryptSymInit(
+ void
+ )
+{
+ return TRUE;
+}
+/* 10.2.19.3.2 CryptSymStartup() */
+/* This function is called to do TPM2_Startup() processing */
+BOOL
+CryptSymStartup(
+ void
+ )
+{
+ return TRUE;
+}
+/* 10.2.20.4 Data Access Functions */
+/* 10.2.20.4.1 CryptGetSymmetricBlockSize() */
+/* This function returns the block size of the algorithm. The table of bit sizes has an entry for
+ each allowed key size. The entry for a key size is 0 if the TPM does not implement that key
+ size. The key size table is delimited with a negative number (-1). After the delimiter is a list
+ of block sizes with each entry corresponding to the key bit size. For most symmetric algorithms,
+ the block size is the same regardless of the key size but this arrangement allows them to be
+ different. */
+/* Return Values Meaning */
+/* <= 0 cipher not supported */
+/* > 0 the cipher block size in bytes */
+
+LIB_EXPORT INT16
+CryptGetSymmetricBlockSize(
+ TPM_ALG_ID symmetricAlg, // IN: the symmetric algorithm
+ UINT16 keySizeInBits // IN: the key size
+ )
+{
+ const INT16 *sizes;
+ INT16 i;
+#if 0 // libtpms added
+#define ALG_CASE(SYM, sym) case TPM_ALG_##SYM: sizes = sym##KeyBlockSizes; break
+#endif // libtpms added
+ switch(symmetricAlg)
+ {
+#define GET_KEY_BLOCK_POINTER(SYM, sym) \
+ case TPM_ALG_##SYM: \
+ sizes = sym##KeyBlockSizes; \
+ break;
+ // Get the pointer to the block size array
+ FOR_EACH_SYM(GET_KEY_BLOCK_POINTER);
+
+ default:
+ return 0;
+ }
+ // Find the index of the indicated keySizeInBits
+ for(i = 0; *sizes >= 0; i++, sizes++)
+ {
+ if(*sizes == keySizeInBits)
+ break;
+ }
+ // If sizes is pointing at the end of the list of key sizes, then the desired
+ // key size was not found so set the block size to zero.
+ if(*sizes++ < 0)
+ return 0;
+ // Advance until the end of the list is found
+ while(*sizes++ >= 0);
+ // sizes is pointing to the first entry in the list of block sizes. Use the
+ // ith index to find the block size for the corresponding key size.
+ return sizes[i];
+}
+
+#if !USE_OPENSSL_FUNCTIONS_SYMMETRIC // libtpms added
+/* 10.2.20.5 Symmetric Encryption */
+/* This function performs symmetric encryption based on the mode. */
+/* Error Returns Meaning */
+/* TPM_RC_SIZE dSize is not a multiple of the block size for an algorithm that requires it */
+/* TPM_RC_FAILURE Fatal error */
+LIB_EXPORT TPM_RC
+CryptSymmetricEncrypt(
+ BYTE *dOut, // OUT:
+ TPM_ALG_ID algorithm, // IN: the symmetric algorithm
+ UINT16 keySizeInBits, // IN: key size in bits
+ const BYTE *key, // IN: key buffer. The size of this buffer
+ // in bytes is (keySizeInBits + 7) / 8
+ TPM2B_IV *ivInOut, // IN/OUT: IV for decryption.
+ TPM_ALG_ID mode, // IN: Mode to use
+ INT32 dSize, // IN: data size (may need to be a
+ // multiple of the blockSize)
+ const BYTE *dIn // IN: data buffer
+ )
+{
+ BYTE *pIv;
+ int i;
+ BYTE tmp[MAX_SYM_BLOCK_SIZE];
+ BYTE *pT;
+ tpmCryptKeySchedule_t keySchedule;
+ INT16 blockSize;
+ TpmCryptSetSymKeyCall_t encrypt;
+ BYTE *iv;
+ BYTE defaultIv[MAX_SYM_BLOCK_SIZE] = {0};
+ //
+ memset(&keySchedule, 0, sizeof(keySchedule)); // libtpms added; coverity
+ pAssert(dOut != NULL && key != NULL && dIn != NULL);
+ if(dSize == 0)
+ return TPM_RC_SUCCESS;
+ TEST(algorithm);
+ blockSize = CryptGetSymmetricBlockSize(algorithm, keySizeInBits);
+ if(blockSize == 0)
+ return TPM_RC_FAILURE;
+ // If the iv is provided, then it is expected to be block sized. In some cases,
+ // the caller is providing an array of 0's that is equal to [MAX_SYM_BLOCK_SIZE]
+ // with no knowledge of the actual block size. This function will set it.
+ if((ivInOut != NULL) && (mode != TPM_ALG_ECB))
+ {
+ ivInOut->t.size = blockSize;
+ iv = ivInOut->t.buffer;
+ }
+ else
+ iv = defaultIv;
+ pIv = iv;
+ // Create encrypt key schedule and set the encryption function pointer.
+ switch (algorithm)
+ {
+ FOR_EACH_SYM(ENCRYPT_CASE)
+
+ default:
+ return TPM_RC_SYMMETRIC;
+ }
+ switch(mode)
+ {
+#if ALG_CTR
+ case TPM_ALG_CTR:
+ for(; dSize > 0; dSize -= blockSize)
+ {
+ // Encrypt the current value of the IV(counter)
+ ENCRYPT(&keySchedule, iv, tmp);
+ //increment the counter (counter is big-endian so start at end)
+ for(i = blockSize - 1; i >= 0; i--)
+ if((iv[i] += 1) != 0)
+ break;
+ // XOR the encrypted counter value with input and put into output
+ pT = tmp;
+ for(i = (dSize < blockSize) ? dSize : blockSize; i > 0; i--)
+ *dOut++ = *dIn++ ^ *pT++;
+ }
+ break;
+#endif
+#if ALG_OFB
+ case TPM_ALG_OFB:
+ // This is written so that dIn and dOut may be the same
+ for(; dSize > 0; dSize -= blockSize)
+ {
+ // Encrypt the current value of the "IV"
+ ENCRYPT(&keySchedule, iv, iv);
+ // XOR the encrypted IV into dIn to create the cipher text (dOut)
+ pIv = iv;
+ for(i = (dSize < blockSize) ? dSize : blockSize; i > 0; i--)
+ *dOut++ = (*pIv++ ^ *dIn++);
+ }
+ break;
+#endif
+#if ALG_CBC
+ case TPM_ALG_CBC:
+ // For CBC the data size must be an even multiple of the
+ // cipher block size
+ if((dSize % blockSize) != 0)
+ return TPM_RC_SIZE;
+ // XOR the data block into the IV, encrypt the IV into the IV
+ // and then copy the IV to the output
+ for(; dSize > 0; dSize -= blockSize)
+ {
+ pIv = iv;
+ for(i = blockSize; i > 0; i--)
+ *pIv++ ^= *dIn++;
+ ENCRYPT(&keySchedule, iv, iv);
+ pIv = iv;
+ for(i = blockSize; i > 0; i--)
+ *dOut++ = *pIv++;
+ }
+ break;
+#endif
+ // CFB is not optional
+ case TPM_ALG_CFB:
+ // Encrypt the IV into the IV, XOR in the data, and copy to output
+ for(; dSize > 0; dSize -= blockSize)
+ {
+ // Encrypt the current value of the IV
+ ENCRYPT(&keySchedule, iv, iv);
+ pIv = iv;
+ for(i = (int)(dSize < blockSize) ? dSize : blockSize; i > 0; i--)
+ // XOR the data into the IV to create the cipher text
+ // and put into the output
+ *dOut++ = *pIv++ ^= *dIn++;
+ }
+ // If the inner loop (i loop) was smaller than blockSize, then dSize
+ // would have been smaller than blockSize and it is now negative. If
+ // it is negative, then it indicates how many bytes are needed to pad
+ // out the IV for the next round.
+ for(; dSize < 0; dSize++)
+ *pIv++ = 0;
+ break;
+#if ALG_ECB
+ case TPM_ALG_ECB:
+ // For ECB the data size must be an even multiple of the
+ // cipher block size
+ if((dSize % blockSize) != 0)
+ return TPM_RC_SIZE;
+ // Encrypt the input block to the output block
+ for(; dSize > 0; dSize -= blockSize)
+ {
+ ENCRYPT(&keySchedule, dIn, dOut);
+ dIn = &dIn[blockSize];
+ dOut = &dOut[blockSize];
+ }
+ break;
+#endif
+ default:
+ return TPM_RC_FAILURE;
+ }
+ return TPM_RC_SUCCESS;
+}
+/* 10.2.20.5.1 CryptSymmetricDecrypt() */
+/* This function performs symmetric decryption based on the mode. */
+/* Error Returns Meaning */
+/* TPM_RC_FAILURE A fatal error */
+/* TPM_RCS_SIZE dSize is not a multiple of the block size for an algorithm that requires it */
+LIB_EXPORT TPM_RC
+CryptSymmetricDecrypt(
+ BYTE *dOut, // OUT: decrypted data
+ TPM_ALG_ID algorithm, // IN: the symmetric algorithm
+ UINT16 keySizeInBits, // IN: key size in bits
+ const BYTE *key, // IN: key buffer. The size of this buffer
+ // in bytes is (keySizeInBits + 7) / 8
+ TPM2B_IV *ivInOut, // IN/OUT: IV for decryption.
+ TPM_ALG_ID mode, // IN: Mode to use
+ INT32 dSize, // IN: data size (may need to be a
+ // multiple of the blockSize)
+ const BYTE *dIn // IN: data buffer
+ )
+{
+ BYTE *pIv;
+ int i;
+ BYTE tmp[MAX_SYM_BLOCK_SIZE];
+ BYTE *pT;
+ tpmCryptKeySchedule_t keySchedule;
+ INT16 blockSize;
+ BYTE *iv;
+ TpmCryptSetSymKeyCall_t encrypt;
+ TpmCryptSetSymKeyCall_t decrypt;
+ BYTE defaultIv[MAX_SYM_BLOCK_SIZE] = {0};
+
+ memset(&keySchedule, 0, sizeof(keySchedule)); // libtpms added; coverity
+ // These are used but the compiler can't tell because they are initialized
+ // in case statements and it can't tell if they are always initialized
+ // when needed, so... Comment these out if the compiler can tell or doesn't
+ // care that these are initialized before use.
+ encrypt = NULL;
+ decrypt = NULL;
+ pAssert(dOut != NULL && key != NULL && dIn != NULL);
+ if(dSize == 0)
+ return TPM_RC_SUCCESS;
+ TEST(algorithm);
+ blockSize = CryptGetSymmetricBlockSize(algorithm, keySizeInBits);
+ if(blockSize == 0)
+ return TPM_RC_FAILURE;
+ // If the iv is provided, then it is expected to be block sized. In some cases,
+ // the caller is providing an array of 0's that is equal to [MAX_SYM_BLOCK_SIZE]
+ // with no knowledge of the actual block size. This function will set it.
+ if((ivInOut != NULL) && (mode != TPM_ALG_ECB))
+ {
+ ivInOut->t.size = blockSize;
+ iv = ivInOut->t.buffer;
+ }
+ else
+ iv = defaultIv;
+ pIv = iv;
+ // Use the mode to select the key schedule to create. Encrypt always uses the
+ // encryption schedule. Depending on the mode, decryption might use either
+ // the decryption or encryption schedule.
+ switch(mode)
+ {
+#if ALG_CBC || ALG_ECB
+ case TPM_ALG_CBC: // decrypt = decrypt
+ case TPM_ALG_ECB:
+ // For ECB and CBC, the data size must be an even multiple of the
+ // cipher block size
+ if((dSize % blockSize) != 0)
+ return TPM_RC_SIZE;
+ switch (algorithm)
+ {
+ FOR_EACH_SYM(DECRYPT_CASE)
+ default:
+ return TPM_RC_SYMMETRIC;
+ }
+ break;
+#endif
+ default:
+ // For the remaining stream ciphers, use encryption to decrypt
+ switch (algorithm)
+ {
+ FOR_EACH_SYM(ENCRYPT_CASE)
+ default:
+ return TPM_RC_SYMMETRIC;
+ }
+ }
+ // Now do the mode-dependent decryption
+ switch(mode)
+ {
+#if ALG_CBC
+ case TPM_ALG_CBC:
+ // Copy the input data to a temp buffer, decrypt the buffer into the
+ // output, XOR in the IV, and copy the temp buffer to the IV and repeat.
+ for(; dSize > 0; dSize -= blockSize)
+ {
+ pT = tmp;
+ for(i = blockSize; i > 0; i--)
+ *pT++ = *dIn++;
+ DECRYPT(&keySchedule, tmp, dOut);
+ pIv = iv;
+ pT = tmp;
+ for(i = blockSize; i > 0; i--)
+ {
+ *dOut++ ^= *pIv;
+ *pIv++ = *pT++;
+ }
+ }
+ break;
+#endif
+ case TPM_ALG_CFB:
+ for(; dSize > 0; dSize -= blockSize)
+ {
+ // Encrypt the IV into the temp buffer
+ ENCRYPT(&keySchedule, iv, tmp);
+ pT = tmp;
+ pIv = iv;
+ for(i = (dSize < blockSize) ? dSize : blockSize; i > 0; i--)
+ // Copy the current cipher text to IV, XOR
+ // with the temp buffer and put into the output
+ *dOut++ = *pT++ ^ (*pIv++ = *dIn++);
+ }
+ // If the inner loop (i loop) was smaller than blockSize, then dSize
+ // would have been smaller than blockSize and it is now negative
+ // If it is negative, then it indicates how may fill bytes
+ // are needed to pad out the IV for the next round.
+ for(; dSize < 0; dSize++)
+ *pIv++ = 0;
+ break;
+#if ALG_CTR
+ case TPM_ALG_CTR:
+ for(; dSize > 0; dSize -= blockSize)
+ {
+ // Encrypt the current value of the IV(counter)
+ ENCRYPT(&keySchedule, iv, tmp);
+ //increment the counter (counter is big-endian so start at end)
+ for(i = blockSize - 1; i >= 0; i--)
+ if((iv[i] += 1) != 0)
+ break;
+ // XOR the encrypted counter value with input and put into output
+ pT = tmp;
+ for(i = (dSize < blockSize) ? dSize : blockSize; i > 0; i--)
+ *dOut++ = *dIn++ ^ *pT++;
+ }
+ break;
+#endif
+#if ALG_ECB
+ case TPM_ALG_ECB:
+ for(; dSize > 0; dSize -= blockSize)
+ {
+ DECRYPT(&keySchedule, dIn, dOut);
+ dIn = &dIn[blockSize];
+ dOut = &dOut[blockSize];
+ }
+ break;
+#endif
+#if ALG_OFB
+ case TPM_ALG_OFB:
+ // This is written so that dIn and dOut may be the same
+ for(; dSize > 0; dSize -= blockSize)
+ {
+ // Encrypt the current value of the "IV"
+ ENCRYPT(&keySchedule, iv, iv);
+ // XOR the encrypted IV into dIn to create the cipher text (dOut)
+ pIv = iv;
+ for(i = (dSize < blockSize) ? dSize : blockSize; i > 0; i--)
+ *dOut++ = (*pIv++ ^ *dIn++);
+ }
+ break;
+#endif
+ default:
+ return TPM_RC_FAILURE;
+ }
+ return TPM_RC_SUCCESS;
+}
+
+#else // libtpms added begin
+
+#if ALG_TDES && ALG_CTR
+// Emulated TDES Counter mode since OpenSSL does not implement it
+static void TDES_CTR(const BYTE *key, // IN
+ INT32 keySizeInBits, // IN
+ INT32 dSize, // IN
+ const BYTE *dIn, // IN
+ BYTE *iv, // IN
+ BYTE *dOut, // OUT
+ INT16 blockSize // IN
+ )
+{
+ tpmCryptKeySchedule_t keySchedule;
+ int i;
+ BYTE tmp[MAX_SYM_BLOCK_SIZE];
+ BYTE *pT;
+
+ TDES_set_encrypt_key(key, keySizeInBits,
+ (tpmKeyScheduleTDES *)&keySchedule.tdes);
+
+ for(; dSize > 0; dSize -= blockSize)
+ {
+ // Encrypt the current value of the IV(counter)
+ TDES_encrypt(iv, tmp, (tpmKeyScheduleTDES *)&keySchedule.tdes);
+ //increment the counter (counter is big-endian so start at end)
+ for(i = blockSize - 1; i >= 0; i--)
+ if((iv[i] += 1) != 0)
+ break;
+ // XOR the encrypted counter value with input and put into output
+ pT = tmp;
+ for(i = (dSize < blockSize) ? dSize : blockSize; i > 0; i--)
+ *dOut++ = *dIn++ ^ *pT++;
+ }
+}
+#endif
+
+/* 10.2.20.5 Symmetric Encryption */
+/* This function performs symmetric encryption based on the mode. */
+/* Error Returns Meaning */
+/* TPM_RC_SIZE dSize is not a multiple of the block size for an algorithm that requires it */
+/* TPM_RC_FAILURE Fatal error */
+LIB_EXPORT TPM_RC
+CryptSymmetricEncrypt(
+ BYTE *dOut, // OUT:
+ TPM_ALG_ID algorithm, // IN: the symmetric algorithm
+ UINT16 keySizeInBits, // IN: key size in bits
+ const BYTE *key, // IN: key buffer. The size of this buffer
+ // in bytes is (keySizeInBits + 7) / 8
+ TPM2B_IV *ivInOut, // IN/OUT: IV for decryption.
+ TPM_ALG_ID mode, // IN: Mode to use
+ INT32 dSize, // IN: data size (may need to be a
+ // multiple of the blockSize)
+ const BYTE *dIn // IN: data buffer
+ )
+{
+ INT16 blockSize;
+ BYTE *iv;
+ BYTE defaultIv[MAX_SYM_BLOCK_SIZE] = {0};
+ evpfunc evpfn;
+ EVP_CIPHER_CTX *ctx = NULL;
+ int outlen1 = 0;
+ int outlen2 = 0;
+ BYTE *pOut = dOut;
+ BYTE *buffer = NULL; // for in-place encryption
+ UINT32 buffersize = 0;
+ BYTE keyToUse[MAX_SYM_KEY_BYTES];
+ UINT16 keyToUseLen = (UINT16)sizeof(keyToUse);
+ TPM_RC retVal = TPM_RC_SUCCESS;
+ int ivLen;
+
+ pAssert(dOut != NULL && key != NULL && dIn != NULL);
+ if(dSize == 0)
+ return TPM_RC_SUCCESS;
+ TEST(algorithm);
+ blockSize = CryptGetSymmetricBlockSize(algorithm, keySizeInBits);
+ if(blockSize == 0)
+ return TPM_RC_FAILURE;
+ // If the iv is provided, then it is expected to be block sized. In some cases,
+ // the caller is providing an array of 0's that is equal to [MAX_SYM_BLOCK_SIZE]
+ // with no knowledge of the actual block size. This function will set it.
+ if((ivInOut != NULL) && (mode != TPM_ALG_ECB))
+ {
+ ivInOut->t.size = blockSize;
+ iv = ivInOut->t.buffer;
+ }
+ else
+ iv = defaultIv;
+
+ switch (mode)
+ {
+ case TPM_ALG_ECB:
+ case TPM_ALG_CBC:
+ // For ECB & CBC the data size must be an even multiple of the
+ // cipher block size
+ if((dSize % blockSize) != 0)
+ return TPM_RC_SIZE;
+ }
+
+ evpfn = GetEVPCipher(algorithm, keySizeInBits, mode, key,
+ keyToUse, &keyToUseLen);
+ if (evpfn == NULL)
+ return TPM_RC_FAILURE;
+
+ if (dIn == dOut) {
+ // in-place encryption; we use a temp buffer
+ buffersize = TPM2_ROUNDUP(dSize, blockSize);
+ buffer = malloc(buffersize);
+ if (buffer == NULL)
+ ERROR_RETURN(TPM_RC_FAILURE);
+
+ pOut = buffer;
+ }
+
+#if ALG_TDES && ALG_CTR
+ if (algorithm == TPM_ALG_TDES && mode == TPM_ALG_CTR) {
+ TDES_CTR(keyToUse, keyToUseLen * 8, dSize, dIn, iv, pOut, blockSize);
+ outlen1 = dSize;
+ ERROR_RETURN(TPM_RC_SUCCESS);
+ }
+#endif
+
+ ctx = EVP_CIPHER_CTX_new();
+ if (!ctx ||
+ EVP_EncryptInit_ex(ctx, evpfn(), NULL, keyToUse, iv) != 1 ||
+ EVP_CIPHER_CTX_set_padding(ctx, 0) != 1 ||
+ EVP_EncryptUpdate(ctx, pOut, &outlen1, dIn, dSize) != 1)
+ ERROR_RETURN(TPM_RC_FAILURE);
+
+ pAssert(outlen1 <= dSize || dSize >= outlen1 + blockSize);
+
+ if (EVP_EncryptFinal_ex(ctx, pOut + outlen1, &outlen2) != 1)
+ ERROR_RETURN(TPM_RC_FAILURE);
+
+ if (ivInOut) {
+ ivLen = EVP_CIPHER_CTX_iv_length(ctx);
+ if (ivLen < 0 || (size_t)ivLen > sizeof(ivInOut->t.buffer))
+ ERROR_RETURN(TPM_RC_FAILURE);
+
+ ivInOut->t.size = ivLen;
+ memcpy(ivInOut->t.buffer, EVP_CIPHER_CTX_iv(ctx), ivInOut->t.size);
+ }
+ Exit:
+ if (retVal == TPM_RC_SUCCESS && pOut != dOut)
+ memcpy(dOut, pOut, outlen1 + outlen2);
+
+ clear_and_free(buffer, buffersize);
+ EVP_CIPHER_CTX_free(ctx);
+
+ return retVal;
+}
+
+/* 10.2.20.5.1 CryptSymmetricDecrypt() */
+/* This function performs symmetric decryption based on the mode. */
+/* Error Returns Meaning */
+/* TPM_RC_FAILURE A fatal error */
+/* TPM_RCS_SIZE dSize is not a multiple of the block size for an algorithm that requires it */
+LIB_EXPORT TPM_RC
+CryptSymmetricDecrypt(
+ BYTE *dOut, // OUT: decrypted data
+ TPM_ALG_ID algorithm, // IN: the symmetric algorithm
+ UINT16 keySizeInBits, // IN: key size in bits
+ const BYTE *key, // IN: key buffer. The size of this buffer
+ // in bytes is (keySizeInBits + 7) / 8
+ TPM2B_IV *ivInOut, // IN/OUT: IV for decryption.
+ TPM_ALG_ID mode, // IN: Mode to use
+ INT32 dSize, // IN: data size (may need to be a
+ // multiple of the blockSize)
+ const BYTE *dIn // IN: data buffer
+ )
+{
+ INT16 blockSize;
+ BYTE *iv;
+ BYTE defaultIv[MAX_SYM_BLOCK_SIZE] = {0};
+ evpfunc evpfn;
+ EVP_CIPHER_CTX *ctx = NULL;
+ int outlen1 = 0;
+ int outlen2 = 0;
+ BYTE *buffer;
+ UINT32 buffersize = 0;
+ BYTE keyToUse[MAX_SYM_KEY_BYTES];
+ UINT16 keyToUseLen = (UINT16)sizeof(keyToUse);
+ TPM_RC retVal = TPM_RC_SUCCESS;
+ int ivLen;
+
+ // These are used but the compiler can't tell because they are initialized
+ // in case statements and it can't tell if they are always initialized
+ // when needed, so... Comment these out if the compiler can tell or doesn't
+ // care that these are initialized before use.
+ pAssert(dOut != NULL && key != NULL && dIn != NULL);
+ if(dSize == 0)
+ return TPM_RC_SUCCESS;
+ TEST(algorithm);
+ blockSize = CryptGetSymmetricBlockSize(algorithm, keySizeInBits);
+ if(blockSize == 0)
+ return TPM_RC_FAILURE;
+ // If the iv is provided, then it is expected to be block sized. In some cases,
+ // the caller is providing an array of 0's that is equal to [MAX_SYM_BLOCK_SIZE]
+ // with no knowledge of the actual block size. This function will set it.
+ if((ivInOut != NULL) && (mode != TPM_ALG_ECB))
+ {
+ ivInOut->t.size = blockSize;
+ iv = ivInOut->t.buffer;
+ }
+ else
+ iv = defaultIv;
+
+ switch(mode)
+ {
+#if ALG_CBC || ALG_ECB
+ case TPM_ALG_CBC:
+ case TPM_ALG_ECB:
+ // For ECB and CBC, the data size must be an even multiple of the
+ // cipher block size
+ if((dSize % blockSize) != 0)
+ return TPM_RC_SIZE;
+ break;
+#endif
+ default:
+ break;
+ }
+
+ evpfn = GetEVPCipher(algorithm, keySizeInBits, mode, key,
+ keyToUse, &keyToUseLen);
+ if (evpfn == NULL)
+ return TPM_RC_FAILURE;
+
+ /* a buffer with a 'safety margin' for EVP_DecryptUpdate */
+ buffersize = TPM2_ROUNDUP(dSize + blockSize, blockSize);
+ buffer = malloc(buffersize);
+ if (buffer == NULL)
+ ERROR_RETURN(TPM_RC_FAILURE);
+
+#if ALG_TDES && ALG_CTR
+ if (algorithm == TPM_ALG_TDES && mode == TPM_ALG_CTR) {
+ TDES_CTR(keyToUse, keyToUseLen * 8, dSize, dIn, iv, buffer, blockSize);
+ outlen1 = dSize;
+ ERROR_RETURN(TPM_RC_SUCCESS);
+ }
+#endif
+
+ ctx = EVP_CIPHER_CTX_new();
+ if (!ctx ||
+ EVP_DecryptInit_ex(ctx, evpfn(), NULL, keyToUse, iv) != 1 ||
+ EVP_CIPHER_CTX_set_padding(ctx, 0) != 1 ||
+ EVP_DecryptUpdate(ctx, buffer, &outlen1, dIn, dSize) != 1)
+ ERROR_RETURN(TPM_RC_FAILURE);
+
+ pAssert((int)buffersize >= outlen1);
+
+ if ((int)buffersize <= outlen1 /* coverity */ ||
+ EVP_DecryptFinal(ctx, &buffer[outlen1], &outlen2) != 1)
+ ERROR_RETURN(TPM_RC_FAILURE);
+
+ pAssert((int)buffersize >= outlen1 + outlen2);
+
+ if (ivInOut) {
+ ivLen = EVP_CIPHER_CTX_iv_length(ctx);
+ if (ivLen < 0 || (size_t)ivLen > sizeof(ivInOut->t.buffer))
+ ERROR_RETURN(TPM_RC_FAILURE);
+
+ ivInOut->t.size = ivLen;
+ memcpy(ivInOut->t.buffer, EVP_CIPHER_CTX_iv(ctx), ivInOut->t.size);
+ }
+
+ Exit:
+ if (retVal == TPM_RC_SUCCESS) {
+ pAssert(dSize >= outlen1 + outlen2);
+ memcpy(dOut, buffer, outlen1 + outlen2);
+ }
+
+ clear_and_free(buffer, buffersize);
+ EVP_CIPHER_CTX_free(ctx);
+
+ return retVal;
+}
+
+#endif // libtpms added end
+
+/* 10.2.20.5.2 CryptSymKeyValidate() */
+/* Validate that a provided symmetric key meets the requirements of the TPM */
+/* Error Returns Meaning */
+/* TPM_RC_KEY_SIZE Key size specifiers do not match */
+/* TPM_RC_KEY Key is not allowed */
+TPM_RC
+CryptSymKeyValidate(
+ TPMT_SYM_DEF_OBJECT *symDef,
+ TPM2B_SYM_KEY *key
+ )
+{
+ if(key->t.size != BITS_TO_BYTES(symDef->keyBits.sym))
+ return TPM_RCS_KEY_SIZE;
+#if ALG_TDES
+ if(symDef->algorithm == TPM_ALG_TDES && !CryptDesValidateKey(key))
+ return TPM_RCS_KEY;
+#endif // TPM_ALG_TDES
+ return TPM_RC_SUCCESS;
+}
diff --git a/src/tpm2/crypto/openssl/ExpDCache.c b/src/tpm2/crypto/openssl/ExpDCache.c
new file mode 100644
index 0000000..5aeaf14
--- /dev/null
+++ b/src/tpm2/crypto/openssl/ExpDCache.c
@@ -0,0 +1,200 @@
+/********************************************************************************/
+/* */
+/* Private Exponent D cache functions */
+/* Written by Stefan Berger */
+/* IBM Thomas J. Watson Research Center */
+/* */
+/* Licenses and Notices */
+/* */
+/* 1. Copyright Licenses: */
+/* */
+/* - Trusted Computing Group (TCG) grants to the user of the source code in */
+/* this specification (the "Source Code") a worldwide, irrevocable, */
+/* nonexclusive, royalty free, copyright license to reproduce, create */
+/* derivative works, distribute, display and perform the Source Code and */
+/* derivative works thereof, and to grant others the rights granted herein. */
+/* */
+/* - The TCG grants to the user of the other parts of the specification */
+/* (other than the Source Code) the rights to reproduce, distribute, */
+/* display, and perform the specification solely for the purpose of */
+/* developing products based on such documents. */
+/* */
+/* 2. Source Code Distribution Conditions: */
+/* */
+/* - Redistributions of Source Code must retain the above copyright licenses, */
+/* this list of conditions and the following disclaimers. */
+/* */
+/* - Redistributions in binary form must reproduce the above copyright */
+/* licenses, this list of conditions and the following disclaimers in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* 3. Disclaimers: */
+/* */
+/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
+/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
+/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
+/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
+/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
+/* information on specification licensing rights available through TCG */
+/* membership agreements. */
+/* */
+/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
+/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
+/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
+/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
+/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
+/* */
+/* - Without limitation, TCG and its members and licensors disclaim all */
+/* liability, including liability for infringement of any proprietary */
+/* rights, relating to use of information in this specification and to the */
+/* implementation of this specification, and TCG disclaims all liability for */
+/* cost of procurement of substitute goods or services, lost profits, loss */
+/* of use, loss of data or any incidental, consequential, direct, indirect, */
+/* or special damages, whether under contract, tort, warranty or otherwise, */
+/* arising in any way out of use or reliance upon this specification or any */
+/* information herein. */
+/* */
+/* (c) Copyright IBM Corp., 2021 */
+/* */
+/********************************************************************************/
+
+#include "Tpm.h"
+#include "ExpDCache_fp.h"
+
+/* Implement a cache for the private exponent D so it doesn't need to be
+ * recalculated every time from P, Q, E and N (modulus). The cache has a
+ * number of entries that cache D and use P, Q, and E for lookup.
+ * A least-recently-used cache eviction strategy is implemented that evicts
+ * the oldest cache entry in case space is needed. An entry is young once
+ * it is added or made young when it was found via lookup. All other entries
+ * age by '1' when an entry is added or accessed.
+ */
+
+struct ExpDCacheEntry {
+ /* The age of the entry; the higher the number the more likely it
+ * will be evicted soon
+ */
+ unsigned int age;
+ BIGNUM *P; /* input */
+ BIGNUM *N; /* input */
+ BIGNUM *E; /* input */
+ BIGNUM *Q; /* cached */
+ BIGNUM *D; /* cached */
+};
+
+#define DCACHE_NUM_ENTRIES 64
+
+static struct ExpDCacheEntry ExpDCache[DCACHE_NUM_ENTRIES];
+
+/* Increment the age of all cache entries that have a current age <= maxage */
+static void ExpDCacheIncrementAge(unsigned maxage)
+{
+ size_t i;
+
+ for (i = 0; i < ARRAY_SIZE(ExpDCache); i++) {
+ if (ExpDCache[i].age <= maxage && ExpDCache[i].D != NULL)
+ ExpDCache[i].age++;
+ }
+}
+
+/* Free the data associated with a ExpDCacheEntry and initialize it */
+static void ExpDCacheEntryFree(struct ExpDCacheEntry *dce)
+{
+ BN_clear_free(dce->P);
+ BN_free(dce->N);
+ BN_free(dce->E);
+ BN_clear_free(dce->Q);
+ BN_clear_free(dce->D);
+ memset(dce, 0, sizeof(*dce));
+}
+
+void ExpDCacheFree(void)
+{
+ size_t i;
+
+ for (i = 0; i < ARRAY_SIZE(ExpDCache); i++)
+ ExpDCacheEntryFree(&ExpDCache[i]);
+}
+
+/* Get a ExpDCacheEntry by finding either an unused entry or evicting the oldest
+ * entry. The returned entry will have all NULL pointers and age 0.
+ */
+static struct ExpDCacheEntry *ExpDCacheEntryGet(void)
+{
+ size_t i, use_i = 0;
+ unsigned oldest_age = 0;
+ struct ExpDCacheEntry *dce;
+
+ for (i = 0; i < ARRAY_SIZE(ExpDCache); i++) {
+ if (ExpDCache[i].D == NULL) {
+ /* use this free entry */
+ use_i = i;
+ break;
+ }
+ if (ExpDCache[i].age > oldest_age) {
+ /* this one is currently the oldest */
+ use_i = i;
+ oldest_age = ExpDCache[i].age;
+ }
+ }
+ dce = &ExpDCache[use_i];
+
+ ExpDCacheEntryFree(dce);
+
+ return dce;
+}
+
+/* Add 'D' to the ExpDCache. This function does not check for duplicates */
+void ExpDCacheAdd(const BIGNUM *P, const BIGNUM *N, const BIGNUM *E,
+ const BIGNUM *Q, const BIGNUM *D)
+{
+ struct ExpDCacheEntry *dce = ExpDCacheEntryGet();
+
+ /* age of 'dce' is '0' */
+ dce->P = BN_dup(P);
+ dce->N = BN_dup(N);
+ dce->E = BN_dup(E);
+ dce->Q = BN_dup(Q);
+ dce->D = BN_dup(D);
+
+ if (!dce->P || !dce->N || !dce->E || !dce->Q || !dce->D)
+ ExpDCacheEntryFree(dce);
+ else
+ ExpDCacheIncrementAge(~0);
+}
+
+BIGNUM *ExpDCacheFind(const BIGNUM *P, const BIGNUM *N, const BIGNUM *E, BIGNUM **Q)
+{
+ size_t i;
+ unsigned myage;
+ BIGNUM *D;
+
+ for (i = 0; i < ARRAY_SIZE(ExpDCache); i++) {
+ if (BN_cmp(ExpDCache[i].P, P) == 0 && BN_cmp(ExpDCache[i].N, N) == 0 &&
+ BN_cmp(ExpDCache[i].E, E) == 0) {
+ /* entry found */
+ myage = ExpDCache[i].age;
+ /* mark this entry as most recently used */
+ ExpDCache[i].age = 0;
+ /* Increment everyone who is <= 'myage'.
+ * The age of this entry will be '1' after that.
+ */
+ ExpDCacheIncrementAge(myage);
+
+ *Q = BN_dup(ExpDCache[i].Q);
+ if (*Q == NULL)
+ return NULL;
+ D = BN_dup(ExpDCache[i].D);
+ if (D == NULL) {
+ BN_clear_free(*Q);
+ *Q = NULL;
+ return NULL;
+ }
+ BN_set_flags(*Q, BN_FLG_CONSTTIME);
+ BN_set_flags(D, BN_FLG_CONSTTIME);
+ return D;
+ }
+ }
+
+ return NULL;
+}
diff --git a/src/tpm2/crypto/openssl/ExpDCache_fp.h b/src/tpm2/crypto/openssl/ExpDCache_fp.h
new file mode 100644
index 0000000..b8ee9d7
--- /dev/null
+++ b/src/tpm2/crypto/openssl/ExpDCache_fp.h
@@ -0,0 +1,75 @@
+/********************************************************************************/
+/* */
+/* Private Exponent D cache functions */
+/* Written by Stefan Berger */
+/* IBM Thomas J. Watson Research Center */
+/* */
+/* Licenses and Notices */
+/* */
+/* 1. Copyright Licenses: */
+/* */
+/* - Trusted Computing Group (TCG) grants to the user of the source code in */
+/* this specification (the "Source Code") a worldwide, irrevocable, */
+/* nonexclusive, royalty free, copyright license to reproduce, create */
+/* derivative works, distribute, display and perform the Source Code and */
+/* derivative works thereof, and to grant others the rights granted herein. */
+/* */
+/* - The TCG grants to the user of the other parts of the specification */
+/* (other than the Source Code) the rights to reproduce, distribute, */
+/* display, and perform the specification solely for the purpose of */
+/* developing products based on such documents. */
+/* */
+/* 2. Source Code Distribution Conditions: */
+/* */
+/* - Redistributions of Source Code must retain the above copyright licenses, */
+/* this list of conditions and the following disclaimers. */
+/* */
+/* - Redistributions in binary form must reproduce the above copyright */
+/* licenses, this list of conditions and the following disclaimers in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* 3. Disclaimers: */
+/* */
+/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
+/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
+/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
+/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
+/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
+/* information on specification licensing rights available through TCG */
+/* membership agreements. */
+/* */
+/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
+/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
+/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
+/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
+/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
+/* */
+/* - Without limitation, TCG and its members and licensors disclaim all */
+/* liability, including liability for infringement of any proprietary */
+/* rights, relating to use of information in this specification and to the */
+/* implementation of this specification, and TCG disclaims all liability for */
+/* cost of procurement of substitute goods or services, lost profits, loss */
+/* of use, loss of data or any incidental, consequential, direct, indirect, */
+/* or special damages, whether under contract, tort, warranty or otherwise, */
+/* arising in any way out of use or reliance upon this specification or any */
+/* information herein. */
+/* */
+/* (c) Copyright IBM Corp., 2021 */
+/* */
+/********************************************************************************/
+
+#ifndef DCACHE_FP_H
+#define DCACHE_FP_H
+
+#include <openssl/bn.h>
+
+BIGNUM *ExpDCacheFind(const BIGNUM *P, const BIGNUM *N, const BIGNUM *E,
+ BIGNUM **Q);
+
+void ExpDCacheAdd(const BIGNUM *P, const BIGNUM *N, const BIGNUM *E,
+ const BIGNUM *Q, const BIGNUM *D);
+
+void ExpDCacheFree(void);
+
+#endif /* DCACHE_FP_H */
+
diff --git a/src/tpm2/crypto/openssl/Helpers.c b/src/tpm2/crypto/openssl/Helpers.c
new file mode 100644
index 0000000..f47cdbf
--- /dev/null
+++ b/src/tpm2/crypto/openssl/Helpers.c
@@ -0,0 +1,625 @@
+/********************************************************************************/
+/* */
+/* OpenSSL helper functions */
+/* Written by Stefan Berger */
+/* IBM Thomas J. Watson Research Center */
+/* */
+/* Licenses and Notices */
+/* */
+/* 1. Copyright Licenses: */
+/* */
+/* - Trusted Computing Group (TCG) grants to the user of the source code in */
+/* this specification (the "Source Code") a worldwide, irrevocable, */
+/* nonexclusive, royalty free, copyright license to reproduce, create */
+/* derivative works, distribute, display and perform the Source Code and */
+/* derivative works thereof, and to grant others the rights granted herein. */
+/* */
+/* - The TCG grants to the user of the other parts of the specification */
+/* (other than the Source Code) the rights to reproduce, distribute, */
+/* display, and perform the specification solely for the purpose of */
+/* developing products based on such documents. */
+/* */
+/* 2. Source Code Distribution Conditions: */
+/* */
+/* - Redistributions of Source Code must retain the above copyright licenses, */
+/* this list of conditions and the following disclaimers. */
+/* */
+/* - Redistributions in binary form must reproduce the above copyright */
+/* licenses, this list of conditions and the following disclaimers in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* 3. Disclaimers: */
+/* */
+/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
+/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
+/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
+/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
+/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
+/* information on specification licensing rights available through TCG */
+/* membership agreements. */
+/* */
+/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
+/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
+/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
+/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
+/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
+/* */
+/* - Without limitation, TCG and its members and licensors disclaim all */
+/* liability, including liability for infringement of any proprietary */
+/* rights, relating to use of information in this specification and to the */
+/* implementation of this specification, and TCG disclaims all liability for */
+/* cost of procurement of substitute goods or services, lost profits, loss */
+/* of use, loss of data or any incidental, consequential, direct, indirect, */
+/* or special damages, whether under contract, tort, warranty or otherwise, */
+/* arising in any way out of use or reliance upon this specification or any */
+/* information herein. */
+/* */
+/* (c) Copyright IBM Corp. and others, 2019 */
+/* */
+/********************************************************************************/
+
+#include "Tpm.h"
+#include "ExpDCache_fp.h"
+#include "Helpers_fp.h"
+#include "TpmToOsslMath_fp.h"
+
+#include "config.h"
+
+#include <openssl/evp.h>
+#include <openssl/rsa.h>
+
+/* to enable RSA_check_key() on private keys set to != 0 */
+#ifndef DO_RSA_CHECK_KEY
+#define DO_RSA_CHECK_KEY 0
+#endif
+
+#if USE_OPENSSL_FUNCTIONS_SYMMETRIC
+
+TPM_RC
+OpenSSLCryptGenerateKeyDes(
+ TPMT_SENSITIVE *sensitive // OUT: sensitive area
+ )
+{
+ DES_cblock *key;
+ size_t offset;
+ size_t limit;
+
+ limit = MIN(sizeof(sensitive->sensitive.sym.t.buffer),
+ sensitive->sensitive.sym.t.size);
+ limit = TPM2_ROUNDUP(limit, sizeof(*key));
+ pAssert(limit < sizeof(sensitive->sensitive.sym.t.buffer));
+
+ for (offset = 0; offset < limit; offset += sizeof(*key)) {
+ key = (DES_cblock *)&sensitive->sensitive.sym.t.buffer[offset];
+ if (DES_random_key(key) != 1)
+ return TPM_RC_NO_RESULT;
+ }
+ return TPM_RC_SUCCESS;
+}
+
+evpfunc GetEVPCipher(TPM_ALG_ID algorithm, // IN
+ UINT16 keySizeInBits, // IN
+ TPM_ALG_ID mode, // IN
+ const BYTE *key, // IN
+ BYTE *keyToUse, // OUT same as key or stretched key
+ UINT16 *keyToUseLen // IN/OUT
+ )
+{
+ int i;
+ UINT16 keySizeInBytes = keySizeInBits / 8;
+ evpfunc evpfn = NULL;
+
+ // key size to array index: 128 -> 0, 192 -> 1, 256 -> 2
+ i = (keySizeInBits >> 6) - 2;
+ if (i < 0 || i > 2)
+ return NULL;
+
+ pAssert(*keyToUseLen >= keySizeInBytes)
+ memcpy(keyToUse, key, keySizeInBytes);
+
+ switch (algorithm) {
+#if ALG_AES
+ case TPM_ALG_AES:
+ *keyToUseLen = keySizeInBytes;
+ switch (mode) {
+#if ALG_CTR
+ case TPM_ALG_CTR:
+ evpfn = (evpfunc []){EVP_aes_128_ctr, EVP_aes_192_ctr,
+ EVP_aes_256_ctr}[i];
+ break;
+#endif
+#if ALG_OFB
+ case TPM_ALG_OFB:
+ evpfn = (evpfunc[]){EVP_aes_128_ofb, EVP_aes_192_ofb,
+ EVP_aes_256_ofb}[i];
+ break;
+#endif
+#if ALG_CBC
+ case TPM_ALG_CBC:
+ evpfn = (evpfunc[]){EVP_aes_128_cbc, EVP_aes_192_cbc,
+ EVP_aes_256_cbc}[i];
+ break;
+#endif
+#if ALG_CFB
+ case TPM_ALG_CFB:
+ evpfn = (evpfunc[]){EVP_aes_128_cfb, EVP_aes_192_cfb,
+ EVP_aes_256_cfb}[i];
+ break;
+#endif
+#if ALG_ECB
+ case TPM_ALG_ECB:
+ evpfn = (evpfunc[]){EVP_aes_128_ecb, EVP_aes_192_ecb,
+ EVP_aes_256_ecb}[i];
+ break;
+#endif
+ }
+ break;
+#endif
+#if ALG_TDES
+ case TPM_ALG_TDES:
+ if (keySizeInBits == 128) {
+ pAssert(*keyToUseLen >= BITS_TO_BYTES(192))
+ // stretch the key
+ memcpy(&keyToUse[16], &keyToUse[0], 8);
+ *keyToUseLen = BITS_TO_BYTES(192);
+ }
+
+ switch (mode) {
+#if ALG_CTR
+ case TPM_ALG_CTR:
+ evpfn = (evpfunc[]){EVP_des_ede3, EVP_des_ede3, NULL}[i];
+ break;
+#endif
+#if ALG_OFB
+ case TPM_ALG_OFB:
+ evpfn = (evpfunc[]){EVP_des_ede3_ofb, EVP_des_ede3_ofb, NULL}[i];
+ break;
+#endif
+#if ALG_CBC
+ case TPM_ALG_CBC:
+ evpfn = (evpfunc[]){EVP_des_ede3_cbc, EVP_des_ede3_cbc, NULL}[i];
+ break;
+#endif
+#if ALG_CFB
+ case TPM_ALG_CFB:
+ evpfn = (evpfunc[]){EVP_des_ede3_cfb64, EVP_des_ede3_cfb64, NULL}[i];
+ break;
+#endif
+#if ALG_ECB
+ case TPM_ALG_ECB:
+ evpfn = (evpfunc[]){EVP_des_ede3_ecb, EVP_des_ede3_ecb, NULL}[i];
+ break;
+#endif
+ }
+ break;
+#endif
+
+#if ALG_SM4
+ case TPM_ALG_SM4:
+ *keyToUseLen = keySizeInBytes;
+ switch (mode) {
+#if ALG_CTR
+ case TPM_ALG_CTR:
+ evpfn = (evpfunc[]){EVP_sm4_ctr, NULL, NULL}[i];
+ break;
+#endif
+#if ALG_OFB
+ case TPM_ALG_OFB:
+ evpfn = (evpfunc[]){EVP_sm4_ofb, NULL, NULL}[i];
+ break;
+#endif
+#if ALG_CBC
+ case TPM_ALG_CBC:
+ evpfn = (evpfunc[]){EVP_sm4_cbc, NULL, NULL}[i];
+ break;
+#endif
+#if ALG_CFB
+ case TPM_ALG_CFB:
+ evpfn = (evpfunc[]){EVP_sm4_cfb, NULL, NULL}[i];
+ break;
+#endif
+#if ALG_ECB
+ case TPM_ALG_ECB:
+ evpfn = (evpfunc[]){EVP_sm4_ecb, NULL, NULL}[i];
+ break;
+#endif
+ }
+ break;
+#endif
+
+#if ALG_CAMELLIA
+ case TPM_ALG_CAMELLIA:
+ *keyToUseLen = keySizeInBytes;
+ switch (mode) {
+#if ALG_CTR
+ case TPM_ALG_CTR:
+ evpfn = (evpfunc []){EVP_camellia_128_ctr, EVP_camellia_192_ctr,
+ EVP_camellia_256_ctr}[i];
+ break;
+#endif
+#if ALG_OFB
+ case TPM_ALG_OFB:
+ evpfn = (evpfunc[]){EVP_camellia_128_ofb, EVP_camellia_192_ofb,
+ EVP_camellia_256_ofb}[i];
+ break;
+#endif
+#if ALG_CBC
+ case TPM_ALG_CBC:
+ evpfn = (evpfunc[]){EVP_camellia_128_cbc, EVP_camellia_192_cbc,
+ EVP_camellia_256_cbc}[i];
+ break;
+#endif
+#if ALG_CFB
+ case TPM_ALG_CFB:
+ evpfn = (evpfunc[]){EVP_camellia_128_cfb, EVP_camellia_192_cfb,
+ EVP_camellia_256_cfb}[i];
+ break;
+#endif
+#if ALG_ECB
+ case TPM_ALG_ECB:
+ evpfn = (evpfunc[]){EVP_camellia_128_ecb, EVP_camellia_192_ecb,
+ EVP_camellia_256_ecb}[i];
+ break;
+#endif
+ }
+ break;
+#endif
+ }
+
+ if (evpfn == NULL)
+ MemorySet(keyToUse, 0, *keyToUseLen);
+
+ return evpfn;
+}
+
+#endif // USE_OPENSSL_FUNCTIONS_SYMMETRIC
+
+#if USE_OPENSSL_FUNCTIONS_EC
+BOOL
+OpenSSLEccGetPrivate(
+ bigNum dOut, // OUT: the qualified random value
+ const EC_GROUP *G, // IN: the EC_GROUP to use
+ const UINT32 requestedBits // IN: if not 0, then dOut must have that many bits
+ )
+{
+ BOOL OK = FALSE;
+ const BIGNUM *D;
+ EC_KEY *eckey = EC_KEY_new();
+ UINT32 requestedBytes = BITS_TO_BYTES(requestedBits);
+ int repeats = 0;
+ int maxRepeats;
+ int numBytes;
+
+ pAssert(G != NULL);
+
+ if (!eckey)
+ return FALSE;
+
+ if (EC_KEY_set_group(eckey, G) != 1)
+ goto Exit;
+
+ maxRepeats = 8;
+ // non-byte boundary order'ed curves, like NIST P521, need more loops to
+ // have a result with topmost byte != 0
+ if (requestedBits & 7)
+ maxRepeats += (9 - (requestedBits & 7));
+
+ while (true) {
+ if (EC_KEY_generate_key(eckey) == 1) {
+ D = EC_KEY_get0_private_key(eckey);
+ // if we need a certain amount of bytes and we are below a threshold
+ // of loops, check the number of bytes we have, otherwise take the
+ // result
+ if ((requestedBytes != 0) && (repeats < maxRepeats)) {
+ numBytes = BN_num_bytes(D);
+ if ((int)requestedBytes != numBytes) {
+ // result does not have enough bytes
+ repeats++;
+ continue;
+ }
+ // result is sufficient
+ }
+ OK = TRUE;
+ OsslToTpmBn(dOut, D);
+ }
+ break;
+ }
+
+ Exit:
+ EC_KEY_free(eckey);
+
+ return OK;
+}
+#endif // USE_OPENSSL_FUNCTIONS_EC
+
+#if USE_OPENSSL_FUNCTIONS_RSA
+
+static const struct hnames {
+ const char *name;
+ TPM_ALG_ID hashAlg;
+} hnames[HASH_COUNT + 1] = {
+ {
+#if ALG_SHA1
+ .name = "sha1",
+ .hashAlg = ALG_SHA1_VALUE,
+ }, {
+#endif
+#if ALG_SHA256
+ .name = "sha256",
+ .hashAlg = ALG_SHA256_VALUE,
+ }, {
+#endif
+#if ALG_SHA384
+ .name = "sha384",
+ .hashAlg = ALG_SHA384_VALUE,
+ }, {
+#endif
+#if ALG_SHA512
+ .name = "sha512",
+ .hashAlg = ALG_SHA512_VALUE,
+ }, {
+#endif
+ .name = NULL,
+ }
+};
+#if HASH_COUNT != ALG_SHA1 + ALG_SHA256 + ALG_SHA384 + ALG_SHA512
+# error Missing entry in hnames array!
+#endif
+
+LIB_EXPORT const char *
+GetDigestNameByHashAlg(const TPM_ALG_ID hashAlg)
+{
+ unsigned i;
+
+ for (i = 0; i < HASH_COUNT; i++) {
+ if (hashAlg == hnames[i].hashAlg)
+ return hnames[i].name;
+ }
+ return NULL;
+}
+
+static BOOL
+ComputePrivateExponentD(
+ const BIGNUM *P, // IN: first prime (size is 1/2 of bnN)
+ const BIGNUM *Q, // IN: second prime (size is 1/2 of bnN)
+ const BIGNUM *E, // IN: the public exponent
+ const BIGNUM *N, // IN: the public modulus
+ BIGNUM **D // OUT:
+ )
+{
+ BOOL pOK = FALSE;
+ BIGNUM *phi;
+ BN_CTX *ctx;
+ //
+ // compute Phi = (p - 1)(q - 1) = pq - p - q + 1 = n - p - q + 1
+ phi = BN_dup(N);
+ ctx = BN_CTX_new();
+ if (phi && ctx) {
+ pOK = BN_sub(phi, phi, P);
+ pOK = pOK && BN_sub(phi, phi, Q);
+ pOK = pOK && BN_add_word(phi, 1);
+ // Compute the multiplicative inverse d = 1/e mod Phi
+ BN_set_flags(phi, BN_FLG_CONSTTIME); // phi is secret
+ pOK = pOK && (*D = BN_mod_inverse(NULL, E, phi, ctx)) != NULL;
+ }
+ BN_CTX_free(ctx);
+ BN_clear_free(phi);
+
+ return pOK;
+}
+
+LIB_EXPORT TPM_RC
+InitOpenSSLRSAPublicKey(OBJECT *key, // IN
+ EVP_PKEY **pkey // OUT
+ )
+{
+ TPM_RC retVal;
+ RSA *rsakey = RSA_new();
+ BIGNUM *N = NULL;
+ BIGNUM *E = BN_new();
+ BN_ULONG eval;
+
+ *pkey = EVP_PKEY_new();
+
+ if (rsakey == NULL || *pkey == NULL || E == NULL)
+ ERROR_RETURN(TPM_RC_FAILURE);
+
+ if(key->publicArea.parameters.rsaDetail.exponent != 0)
+ eval = key->publicArea.parameters.rsaDetail.exponent;
+ else
+ eval = RSA_DEFAULT_PUBLIC_EXPONENT;
+
+ if (BN_set_word(E, eval) != 1)
+ ERROR_RETURN(TPM_RC_FAILURE);
+
+ N = BN_bin2bn(key->publicArea.unique.rsa.b.buffer,
+ key->publicArea.unique.rsa.b.size, NULL);
+ if (N == NULL ||
+ RSA_set0_key(rsakey, N, E, NULL) != 1 ||
+ EVP_PKEY_assign_RSA(*pkey, rsakey) == 0)
+ ERROR_RETURN(TPM_RC_FAILURE)
+
+ RSA_set_flags(rsakey, RSA_FLAG_NO_BLINDING);
+
+ retVal = TPM_RC_SUCCESS;
+
+ Exit:
+ if (retVal != TPM_RC_SUCCESS) {
+ RSA_free(rsakey);
+ EVP_PKEY_free(*pkey);
+ *pkey = NULL;
+ }
+
+ return retVal;
+}
+
+static void DoRSACheckKey(const BIGNUM *P, const BIGNUM *Q, const BIGNUM *N,
+ const BIGNUM *E, const BIGNUM *D)
+{
+ RSA *mykey;
+ static int disp;
+
+ if (!DO_RSA_CHECK_KEY)
+ return;
+ if (!disp) {
+ fprintf(stderr, "RSA key checking is enabled\n");
+ disp = 1;
+ }
+
+ mykey = RSA_new();
+ RSA_set0_factors(mykey, BN_dup(P), BN_dup(Q));
+ RSA_set0_key(mykey, BN_dup(N), BN_dup(E), BN_dup(D));
+ if (RSA_check_key(mykey) != 1) {
+ fprintf(stderr, "Detected bad RSA key. STOP.\n");
+ while (1);
+ }
+ RSA_free(mykey);
+}
+
+LIB_EXPORT TPM_RC
+InitOpenSSLRSAPrivateKey(OBJECT *rsaKey, // IN
+ EVP_PKEY **pkey // OUT
+ )
+{
+ const BIGNUM *N = NULL;
+ const BIGNUM *E = NULL;
+ BIGNUM *P = NULL;
+ BIGNUM *Q = NULL;
+ BIGNUM *Qr = NULL;
+ BIGNUM *D = NULL;
+#if CRT_FORMAT_RSA == YES
+ BIGNUM *dP = BN_new();
+ BIGNUM *dQ = BN_new();
+ BIGNUM *qInv = BN_new();
+#endif
+ RSA *key = NULL;
+ BN_CTX *ctx = NULL;
+ TPM_RC retVal = InitOpenSSLRSAPublicKey(rsaKey, pkey);
+
+ if (retVal != TPM_RC_SUCCESS)
+ return retVal;
+
+ if(!rsaKey->attributes.privateExp)
+ CryptRsaLoadPrivateExponent(rsaKey);
+
+ P = BN_bin2bn(rsaKey->sensitive.sensitive.rsa.t.buffer,
+ rsaKey->sensitive.sensitive.rsa.t.size, NULL);
+ if (P == NULL)
+ ERROR_RETURN(TPM_RC_FAILURE)
+
+ key = EVP_PKEY_get1_RSA(*pkey);
+ if (key == NULL)
+ ERROR_RETURN(TPM_RC_FAILURE);
+ RSA_get0_key(key, &N, &E, NULL);
+
+ D = ExpDCacheFind(P, N, E, &Q);
+ if (D == NULL) {
+ ctx = BN_CTX_new();
+ Q = BN_new();
+ Qr = BN_new();
+ if (ctx == NULL || Q == NULL || Qr == NULL)
+ ERROR_RETURN(TPM_RC_FAILURE);
+ /* Q = N/P; no remainder */
+ BN_set_flags(P, BN_FLG_CONSTTIME); // P is secret
+ BN_div(Q, Qr, N, P, ctx);
+ if(!BN_is_zero(Qr))
+ ERROR_RETURN(TPM_RC_BINDING);
+ BN_set_flags(Q, BN_FLG_CONSTTIME); // Q is secret
+
+ if (ComputePrivateExponentD(P, Q, E, N, &D) == FALSE)
+ ERROR_RETURN(TPM_RC_FAILURE);
+ ExpDCacheAdd(P, N, E, Q, D);
+ }
+ if (RSA_set0_key(key, NULL, NULL, D) != 1)
+ ERROR_RETURN(TPM_RC_FAILURE);
+
+ DoRSACheckKey(P, Q, N, E, D);
+
+ D = NULL;
+
+#if CRT_FORMAT_RSA == YES
+ /* CRT parameters are not absolutely needed but may speed up ops */
+ dP = BigInitialized(dP, (bigConst)&rsaKey->privateExponent.dP);
+ dQ = BigInitialized(dQ, (bigConst)&rsaKey->privateExponent.dQ);
+ qInv = BigInitialized(qInv, (bigConst)&rsaKey->privateExponent.qInv);
+ if (dP == NULL || dQ == NULL || qInv == NULL ||
+ RSA_set0_crt_params(key, dP, dQ, qInv) != 1)
+ ERROR_RETURN(TPM_RC_FAILURE);
+#endif
+
+ retVal = TPM_RC_SUCCESS;
+
+ Exit:
+ BN_CTX_free(ctx);
+ BN_clear_free(P);
+ BN_clear_free(Q);
+ BN_free(Qr);
+ RSA_free(key); // undo reference from EVP_PKEY_get1_RSA()
+
+ if (retVal != TPM_RC_SUCCESS) {
+ BN_clear_free(D);
+#if CRT_FORMAT_RSA == YES
+ BN_clear_free(dP);
+ BN_clear_free(dQ);
+ BN_clear_free(qInv);
+#endif
+ EVP_PKEY_free(*pkey);
+ *pkey = NULL;
+ }
+
+ return retVal;
+}
+
+LIB_EXPORT TPM_RC
+OpenSSLCryptRsaGenerateKey(
+ OBJECT *rsaKey, // IN/OUT: The object structure in which
+ // the key is created.
+ UINT32 e,
+ int keySizeInBits
+ )
+{
+ TPMT_PUBLIC *publicArea = &rsaKey->publicArea;
+ TPMT_SENSITIVE *sensitive = &rsaKey->sensitive;
+ TPM_RC retVal = TPM_RC_SUCCESS;
+ int rc;
+ RSA *rsa = NULL;
+ const BIGNUM *bnP = NULL;
+ const BIGNUM *bnN = NULL;
+ BIGNUM *bnE = BN_new();
+ BN_RSA(tmp);
+
+ if (bnE == NULL || BN_set_word(bnE, e) != 1)
+ ERROR_RETURN(TPM_RC_FAILURE);
+
+ // Need to initialize the privateExponent structure
+ RsaInitializeExponent(&rsaKey->privateExponent);
+
+ rsa = RSA_new();
+ if (rsa == NULL)
+ ERROR_RETURN(TPM_RC_FAILURE);
+
+ rc = RSA_generate_key_ex(rsa, keySizeInBits, bnE, NULL);
+ if (rc == 0)
+ ERROR_RETURN(TPM_RC_NO_RESULT);
+
+ RSA_get0_key(rsa, &bnN, NULL, NULL);
+ RSA_get0_factors(rsa, &bnP, NULL);
+
+ OsslToTpmBn(tmp, bnN);
+ BnTo2B((bigNum)tmp, &publicArea->unique.rsa.b, 0);
+
+ OsslToTpmBn(tmp, bnP);
+ BnTo2B((bigNum)tmp, &sensitive->sensitive.rsa.b, 0);
+
+ // CryptRsaGenerateKey calls ComputePrivateExponent; we have to call
+ // it via CryptRsaLoadPrivateExponent
+ retVal = CryptRsaLoadPrivateExponent(rsaKey);
+
+ Exit:
+ BN_free(bnE);
+ RSA_free(rsa);
+
+ return retVal;
+}
+
+#endif // USE_OPENSSL_FUNCTIONS_RSA
diff --git a/src/tpm2/crypto/openssl/Helpers_fp.h b/src/tpm2/crypto/openssl/Helpers_fp.h
new file mode 100644
index 0000000..5b9ca14
--- /dev/null
+++ b/src/tpm2/crypto/openssl/Helpers_fp.h
@@ -0,0 +1,117 @@
+/********************************************************************************/
+/* */
+/* OpenSSL helper functions */
+/* Written by Stefan Berger */
+/* IBM Thomas J. Watson Research Center */
+/* */
+/* Licenses and Notices */
+/* */
+/* 1. Copyright Licenses: */
+/* */
+/* - Trusted Computing Group (TCG) grants to the user of the source code in */
+/* this specification (the "Source Code") a worldwide, irrevocable, */
+/* nonexclusive, royalty free, copyright license to reproduce, create */
+/* derivative works, distribute, display and perform the Source Code and */
+/* derivative works thereof, and to grant others the rights granted herein. */
+/* */
+/* - The TCG grants to the user of the other parts of the specification */
+/* (other than the Source Code) the rights to reproduce, distribute, */
+/* display, and perform the specification solely for the purpose of */
+/* developing products based on such documents. */
+/* */
+/* 2. Source Code Distribution Conditions: */
+/* */
+/* - Redistributions of Source Code must retain the above copyright licenses, */
+/* this list of conditions and the following disclaimers. */
+/* */
+/* - Redistributions in binary form must reproduce the above copyright */
+/* licenses, this list of conditions and the following disclaimers in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* 3. Disclaimers: */
+/* */
+/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
+/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
+/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
+/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
+/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
+/* information on specification licensing rights available through TCG */
+/* membership agreements. */
+/* */
+/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
+/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
+/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
+/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
+/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
+/* */
+/* - Without limitation, TCG and its members and licensors disclaim all */
+/* liability, including liability for infringement of any proprietary */
+/* rights, relating to use of information in this specification and to the */
+/* implementation of this specification, and TCG disclaims all liability for */
+/* cost of procurement of substitute goods or services, lost profits, loss */
+/* of use, loss of data or any incidental, consequential, direct, indirect, */
+/* or special damages, whether under contract, tort, warranty or otherwise, */
+/* arising in any way out of use or reliance upon this specification or any */
+/* information herein. */
+/* */
+/* (c) Copyright IBM Corp. and others, 2019 */
+/* */
+/********************************************************************************/
+
+#ifndef HELPERS_FP_H
+#define HELPERS_FP_H
+
+#include "TpmTypes.h"
+
+#include <openssl/evp.h>
+
+#if USE_OPENSSL_FUNCTIONS_SYMMETRIC
+TPM_RC
+OpenSSLCryptGenerateKeyDes(
+ TPMT_SENSITIVE *sensitive // OUT: sensitive area
+ );
+
+typedef const EVP_CIPHER *(*evpfunc)(void);
+
+evpfunc GetEVPCipher(TPM_ALG_ID algorithm, // IN
+ UINT16 keySizeInBits, // IN
+ TPM_ALG_ID mode, // IN
+ const BYTE *key, // IN
+ BYTE *keyToUse, // OUT same as key or stretched key
+ UINT16 *keyToUseLen // IN/OUT
+ );
+#endif
+
+#if USE_OPENSSL_FUNCTIONS_EC
+BOOL OpenSSLEccGetPrivate(
+ bigNum dOut, // OUT: the qualified random value
+ const EC_GROUP *G, // IN: the EC_GROUP to use
+ const UINT32 requestedBits // IN: if not 0, then dOut must have that many bits
+ );
+#endif
+
+#if USE_OPENSSL_FUNCTIONS_RSA
+
+const char *GetDigestNameByHashAlg(const TPM_ALG_ID hashAlg);
+
+LIB_EXPORT TPM_RC
+OpenSSLCryptRsaGenerateKey(
+ OBJECT *rsaKey, // IN/OUT: The object structure in which
+ // the key is created.
+ UINT32 e,
+ int keySizeInBits
+ );
+
+LIB_EXPORT TPM_RC
+InitOpenSSLRSAPublicKey(OBJECT *key, // IN
+ EVP_PKEY **pkey //OUT
+ );
+
+LIB_EXPORT TPM_RC
+InitOpenSSLRSAPrivateKey(OBJECT *rsaKey, // IN
+ EVP_PKEY **pkey // OUT
+ );
+
+#endif // USE_OPENSSL_FUNCTIONS_RSA
+
+#endif /* HELPERS_FP_H */
diff --git a/src/tpm2/crypto/openssl/LibSupport.h b/src/tpm2/crypto/openssl/LibSupport.h
new file mode 100644
index 0000000..d571b84
--- /dev/null
+++ b/src/tpm2/crypto/openssl/LibSupport.h
@@ -0,0 +1,98 @@
+/********************************************************************************/
+/* */
+/* select the library code that gets included in the TPM build */
+/* Written by Ken Goldman */
+/* IBM Thomas J. Watson Research Center */
+/* $Id: LibSupport.h 1656 2021-01-15 21:45:18Z kgoldman $ */
+/* */
+/* Licenses and Notices */
+/* */
+/* 1. Copyright Licenses: */
+/* */
+/* - Trusted Computing Group (TCG) grants to the user of the source code in */
+/* this specification (the "Source Code") a worldwide, irrevocable, */
+/* nonexclusive, royalty free, copyright license to reproduce, create */
+/* derivative works, distribute, display and perform the Source Code and */
+/* derivative works thereof, and to grant others the rights granted herein. */
+/* */
+/* - The TCG grants to the user of the other parts of the specification */
+/* (other than the Source Code) the rights to reproduce, distribute, */
+/* display, and perform the specification solely for the purpose of */
+/* developing products based on such documents. */
+/* */
+/* 2. Source Code Distribution Conditions: */
+/* */
+/* - Redistributions of Source Code must retain the above copyright licenses, */
+/* this list of conditions and the following disclaimers. */
+/* */
+/* - Redistributions in binary form must reproduce the above copyright */
+/* licenses, this list of conditions and the following disclaimers in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* 3. Disclaimers: */
+/* */
+/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
+/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
+/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
+/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
+/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
+/* information on specification licensing rights available through TCG */
+/* membership agreements. */
+/* */
+/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
+/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
+/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
+/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
+/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
+/* */
+/* - Without limitation, TCG and its members and licensors disclaim all */
+/* liability, including liability for infringement of any proprietary */
+/* rights, relating to use of information in this specification and to the */
+/* implementation of this specification, and TCG disclaims all liability for */
+/* cost of procurement of substitute goods or services, lost profits, loss */
+/* of use, loss of data or any incidental, consequential, direct, indirect, */
+/* or special damages, whether under contract, tort, warranty or otherwise, */
+/* arising in any way out of use or reliance upon this specification or any */
+/* information herein. */
+/* */
+/* (c) Copyright IBM Corp. and others, 2016 - 2020 */
+/* */
+/********************************************************************************/
+
+// 5.12 LibSupport.h
+// This header file is used to select the library code that gets included in the TPM build
+#ifndef _LIB_SUPPORT_H_
+#define _LIB_SUPPORT_H_
+
+#if 0 // libtpms added
+/* kgold added power and s390 */
+#ifndef RADIX_BITS
+# if defined(__x86_64__) || defined(__x86_64) \
+ || defined(__amd64__) || defined(__amd64) \
+ || defined(_WIN64) || defined(_M_X64) \
+ || defined(_M_ARM64) || defined(__aarch64__) \
+ || defined(__powerpc64__) || defined(__PPC64__) || defined(__ppc64__) \
+ || defined(__s390x__)
+# define RADIX_BITS 64
+# elif defined(__i386__) || defined(__i386) || defined(i386) \
+ || defined(_WIN32) || defined(_M_IX86) \
+ || defined(_M_ARM) || defined(__arm__) || defined(__thumb__) \
+ || defined(__powerpc__) || defined(__PPC__)
+# define RADIX_BITS 32
+# else
+# error Unable to determine RADIX_BITS from compiler environment
+# endif
+#endif // RADIX_BITS
+#endif // libtpms added
+
+// These macros use the selected libraries to the proper include files.
+#define LIB_QUOTE(_STRING_) #_STRING_
+#define LIB_INCLUDE2(_LIB_, _TYPE_) LIB_QUOTE(TpmTo##_LIB_##_TYPE_.h)
+#define LIB_INCLUDE(_LIB_, _TYPE_) LIB_INCLUDE2(_LIB_, _TYPE_)
+// Include the options for hashing and symmetric. Defer the load of the math package until the
+// bignum parameters are defined.
+#include LIB_INCLUDE(SYM_LIB, Sym)
+#include LIB_INCLUDE(HASH_LIB, Hash)
+#undef MIN
+#undef MAX
+#endif // _LIB_SUPPORT_H_
diff --git a/src/tpm2/crypto/openssl/TpmToOsslDesSupport.c b/src/tpm2/crypto/openssl/TpmToOsslDesSupport.c
new file mode 100644
index 0000000..d27aad2
--- /dev/null
+++ b/src/tpm2/crypto/openssl/TpmToOsslDesSupport.c
@@ -0,0 +1,119 @@
+/********************************************************************************/
+/* */
+/* TPM DES Support */
+/* Written by Ken Goldman */
+/* IBM Thomas J. Watson Research Center */
+/* $Id: TpmToOsslDesSupport.c 1476 2019-06-10 19:32:03Z kgoldman $ */
+/* */
+/* Licenses and Notices */
+/* */
+/* 1. Copyright Licenses: */
+/* */
+/* - Trusted Computing Group (TCG) grants to the user of the source code in */
+/* this specification (the "Source Code") a worldwide, irrevocable, */
+/* nonexclusive, royalty free, copyright license to reproduce, create */
+/* derivative works, distribute, display and perform the Source Code and */
+/* derivative works thereof, and to grant others the rights granted herein. */
+/* */
+/* - The TCG grants to the user of the other parts of the specification */
+/* (other than the Source Code) the rights to reproduce, distribute, */
+/* display, and perform the specification solely for the purpose of */
+/* developing products based on such documents. */
+/* */
+/* 2. Source Code Distribution Conditions: */
+/* */
+/* - Redistributions of Source Code must retain the above copyright licenses, */
+/* this list of conditions and the following disclaimers. */
+/* */
+/* - Redistributions in binary form must reproduce the above copyright */
+/* licenses, this list of conditions and the following disclaimers in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* 3. Disclaimers: */
+/* */
+/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
+/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
+/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
+/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
+/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
+/* information on specification licensing rights available through TCG */
+/* membership agreements. */
+/* */
+/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
+/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
+/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
+/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
+/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
+/* */
+/* - Without limitation, TCG and its members and licensors disclaim all */
+/* liability, including liability for infringement of any proprietary */
+/* rights, relating to use of information in this specification and to the */
+/* implementation of this specification, and TCG disclaims all liability for */
+/* cost of procurement of substitute goods or services, lost profits, loss */
+/* of use, loss of data or any incidental, consequential, direct, indirect, */
+/* or special damages, whether under contract, tort, warranty or otherwise, */
+/* arising in any way out of use or reliance upon this specification or any */
+/* information herein. */
+/* */
+/* (c) Copyright IBM Corp. and others, 2016 - 2019 */
+/* */
+/********************************************************************************/
+
+/* B.2.3.1. TpmToOsslDesSupport.c */
+/* B.2.3.1.1. Introduction */
+/* The functions in this file are used for initialization of the interface to the OpenSSL
+ library. */
+/* B.2.3.1.2. Defines and Includes */
+#include "Tpm.h"
+#if (defined SYM_LIB_OSSL) && ALG_TDES
+/* B.2.3.1.3. Functions */
+/* B.2.3.1.3.1. TDES_set_encyrpt_key() */
+/* This function makes creation of a TDES key look like the creation of a key for any of the other
+ OpenSSL block ciphers. It will create three key schedules, one for each of the DES keys. If
+ there are only two keys, then the third schedule is a copy of the first. */
+void
+TDES_set_encrypt_key(
+ const BYTE *key,
+ UINT16 keySizeInBits,
+ tpmKeyScheduleTDES *keySchedule
+ )
+{
+ DES_set_key_unchecked((const_DES_cblock *)key, &keySchedule[0]);
+ DES_set_key_unchecked((const_DES_cblock *)&key[8], &keySchedule[1]);
+ // If is two-key, copy the schedule for K1 into K3, otherwise, compute the
+ // the schedule for K3
+ if(keySizeInBits == 128)
+ keySchedule[2] = keySchedule[0];
+ else
+ DES_set_key_unchecked((const_DES_cblock *)&key[16],
+ &keySchedule[2]);
+}
+/* B.2.3.1.3.2. TDES_encyrpt() */
+/* The TPM code uses one key schedule. For TDES, the schedule contains three schedules. OpenSSL
+ wants the schedules referenced separately. This function does that. */
+void TDES_encrypt(
+ const BYTE *in,
+ BYTE *out,
+ tpmKeyScheduleTDES *ks
+ )
+{
+ DES_ecb3_encrypt((const_DES_cblock *)in, (DES_cblock *)out,
+ &ks[0], &ks[1], &ks[2],
+ DES_ENCRYPT);
+}
+#if !USE_OPENSSL_FUNCTIONS_SYMMETRIC
+/* B.2.3.1.3.3. TDES_decrypt() */
+/* As with TDES_encypt() this function bridges between the TPM single schedule model and the
+ OpenSSL three schedule model. */
+void TDES_decrypt(
+ const BYTE *in,
+ BYTE *out,
+ tpmKeyScheduleTDES *ks
+ )
+{
+ DES_ecb3_encrypt((const_DES_cblock *)in, (DES_cblock *)out,
+ &ks[0], &ks[1], &ks[2],
+ DES_DECRYPT);
+}
+#endif // !USE_OPENSSL_FUNCTIONS_SYMMETRIC
+#endif // SYM_LIB_OSSL
diff --git a/src/tpm2/crypto/openssl/TpmToOsslDesSupport_fp.h b/src/tpm2/crypto/openssl/TpmToOsslDesSupport_fp.h
new file mode 100644
index 0000000..4338fe6
--- /dev/null
+++ b/src/tpm2/crypto/openssl/TpmToOsslDesSupport_fp.h
@@ -0,0 +1,83 @@
+/********************************************************************************/
+/* */
+/* */
+/* Written by Ken Goldman */
+/* IBM Thomas J. Watson Research Center */
+/* $Id: TpmToOsslDesSupport_fp.h 809 2016-11-16 18:31:54Z kgoldman $ */
+/* */
+/* Licenses and Notices */
+/* */
+/* 1. Copyright Licenses: */
+/* */
+/* - Trusted Computing Group (TCG) grants to the user of the source code in */
+/* this specification (the "Source Code") a worldwide, irrevocable, */
+/* nonexclusive, royalty free, copyright license to reproduce, create */
+/* derivative works, distribute, display and perform the Source Code and */
+/* derivative works thereof, and to grant others the rights granted herein. */
+/* */
+/* - The TCG grants to the user of the other parts of the specification */
+/* (other than the Source Code) the rights to reproduce, distribute, */
+/* display, and perform the specification solely for the purpose of */
+/* developing products based on such documents. */
+/* */
+/* 2. Source Code Distribution Conditions: */
+/* */
+/* - Redistributions of Source Code must retain the above copyright licenses, */
+/* this list of conditions and the following disclaimers. */
+/* */
+/* - Redistributions in binary form must reproduce the above copyright */
+/* licenses, this list of conditions and the following disclaimers in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* 3. Disclaimers: */
+/* */
+/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
+/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
+/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
+/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
+/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
+/* information on specification licensing rights available through TCG */
+/* membership agreements. */
+/* */
+/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
+/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
+/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
+/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
+/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
+/* */
+/* - Without limitation, TCG and its members and licensors disclaim all */
+/* liability, including liability for infringement of any proprietary */
+/* rights, relating to use of information in this specification and to the */
+/* implementation of this specification, and TCG disclaims all liability for */
+/* cost of procurement of substitute goods or services, lost profits, loss */
+/* of use, loss of data or any incidental, consequential, direct, indirect, */
+/* or special damages, whether under contract, tort, warranty or otherwise, */
+/* arising in any way out of use or reliance upon this specification or any */
+/* information herein. */
+/* */
+/* (c) Copyright IBM Corp. and others, 2016 */
+/* */
+/********************************************************************************/
+
+#ifndef TPMTOOSSLDESSUPPORT_FP_H
+#define TPMTOOSSLDESSUPPORT_FP_H
+
+void
+TDES_set_encrypt_key(
+ const BYTE *key,
+ UINT16 keySizeInBits,
+ tpmKeyScheduleTDES *keySchedule
+ );
+void TDES_encrypt(
+ const BYTE *in,
+ BYTE *out,
+ tpmKeyScheduleTDES *ks
+ );
+void TDES_decrypt(
+ const BYTE *in,
+ BYTE *out,
+ tpmKeyScheduleTDES *ks
+ );
+
+
+#endif
diff --git a/src/tpm2/crypto/openssl/TpmToOsslHash.h b/src/tpm2/crypto/openssl/TpmToOsslHash.h
new file mode 100644
index 0000000..9fa6479
--- /dev/null
+++ b/src/tpm2/crypto/openssl/TpmToOsslHash.h
@@ -0,0 +1,219 @@
+/********************************************************************************/
+/* */
+/* Used to splice the OpenSSL() hash code into the TPM code */
+/* Written by Ken Goldman */
+/* IBM Thomas J. Watson Research Center */
+/* $Id: TpmToOsslHash.h 1658 2021-01-22 23:14:01Z kgoldman $ */
+/* */
+/* Licenses and Notices */
+/* */
+/* 1. Copyright Licenses: */
+/* */
+/* - Trusted Computing Group (TCG) grants to the user of the source code in */
+/* this specification (the "Source Code") a worldwide, irrevocable, */
+/* nonexclusive, royalty free, copyright license to reproduce, create */
+/* derivative works, distribute, display and perform the Source Code and */
+/* derivative works thereof, and to grant others the rights granted herein. */
+/* */
+/* - The TCG grants to the user of the other parts of the specification */
+/* (other than the Source Code) the rights to reproduce, distribute, */
+/* display, and perform the specification solely for the purpose of */
+/* developing products based on such documents. */
+/* */
+/* 2. Source Code Distribution Conditions: */
+/* */
+/* - Redistributions of Source Code must retain the above copyright licenses, */
+/* this list of conditions and the following disclaimers. */
+/* */
+/* - Redistributions in binary form must reproduce the above copyright */
+/* licenses, this list of conditions and the following disclaimers in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* 3. Disclaimers: */
+/* */
+/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
+/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
+/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
+/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
+/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
+/* information on specification licensing rights available through TCG */
+/* membership agreements. */
+/* */
+/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
+/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
+/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
+/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
+/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
+/* */
+/* - Without limitation, TCG and its members and licensors disclaim all */
+/* liability, including liability for infringement of any proprietary */
+/* rights, relating to use of information in this specification and to the */
+/* implementation of this specification, and TCG disclaims all liability for */
+/* cost of procurement of substitute goods or services, lost profits, loss */
+/* of use, loss of data or any incidental, consequential, direct, indirect, */
+/* or special damages, whether under contract, tort, warranty or otherwise, */
+/* arising in any way out of use or reliance upon this specification or any */
+/* information herein. */
+/* */
+/* (c) Copyright IBM Corp. and others, 2016 - 2021 */
+/* */
+/********************************************************************************/
+
+/* B.2.2.1. TpmToOsslHash.h */
+/* B.2.2.1.1. Introduction */
+/* This header file is used to splice the OpenSSL hash code into the TPM code. */
+#ifndef HASH_LIB_DEFINED
+#define HASH_LIB_DEFINED
+#define HASH_LIB_OSSL
+#include <openssl/evp.h>
+#include <openssl/sha.h>
+
+#if ALG_SM3_256
+# if defined(OPENSSL_NO_SM3) || OPENSSL_VERSION_NUMBER < 0x10101010L
+# if ALG_SM3_256 // libtpms added begin
+# error This version of OpenSSL does not support SM3
+# endif // libtpms added end
+# undef ALG_SM3_256
+# define ALG_SM3_256 ALG_NO
+# elif OPENSSL_VERSION_NUMBER >= 0x10200000L
+# include <openssl/sm3.h>
+# else
+// OpenSSL 1.1.1 keeps smX.h headers in the include/crypto directory,
+// and they do not get installed as part of the libssl package
+# define SM3_LBLOCK (64/4)
+
+# error Check support for this version of SM3 in OpenSSL (libtpms)
+typedef struct SM3state_st {
+ unsigned int A, B, C, D, E, F, G, H;
+ unsigned int Nl, Nh;
+ unsigned int data[SM3_LBLOCK];
+ unsigned int num;
+} SM3_CTX;
+
+int sm3_init(SM3_CTX *c);
+int sm3_update(SM3_CTX *c, const void *data, size_t len);
+int sm3_final(unsigned char *md, SM3_CTX *c);
+# endif // OpenSSL < 1.2
+#endif // ALG_SM3_256
+
+#include <openssl/ossl_typ.h>
+
+#define HASH_ALIGNMENT RADIX_BYTES /* libtpms: keep; not sure whether needed */
+
+/* B.2.2.1.2. Links to the OpenSSL HASH code */
+/* Redefine the internal name used for each of the hash state structures to the name used by the
+ library. These defines need to be known in all parts of the TPM so that the structure sizes can
+ be properly computed when needed. */
+#define tpmHashStateSHA1_t SHA_CTX
+#define tpmHashStateSHA256_t SHA256_CTX
+#define tpmHashStateSHA384_t SHA512_CTX
+#define tpmHashStateSHA512_t SHA512_CTX
+#define tpmHashStateSM3_256_t SM3_CTX
+#if ALG_SM3_256
+# error "The version of OpenSSL used by this code does not support SM3"
+#endif
+/* The defines below are only needed when compiling CryptHash.c or CryptSmac.c. This isolation
+ is primarily to avoid name space collision. However, if there is a real collision, it will
+ likely show up when the linker tries to put things together. */
+#ifdef _CRYPT_HASH_C_
+typedef BYTE *PBYTE;
+typedef const BYTE *PCBYTE;
+/* Define the interface between CryptHash.c to the functions provided by the library. For each
+ method, define the calling parameters of the method and then define how the method is invoked in
+ CryptHash.c. */
+/* All hashes are required to have the same calling sequence. If they don't, create a simple
+ adaptation function that converts from the standard form of the call to the form used by the
+ specific hash (and then send a nasty letter to the person who wrote the hash function for the
+ library). */
+/* The macro that calls the method also defines how the parameters get swizzled between the default
+ form (in CryptHash.c)and the library form. */
+
+#define HASH_ALIGNMENT RADIX_BYTES
+
+/* Initialize the hash context */
+#define HASH_START_METHOD_DEF void (HASH_START_METHOD)(PANY_HASH_STATE state)
+#define HASH_START(hashState) \
+ ((hashState)->def->method.start)(&(hashState)->state);
+/* Add data to the hash */
+#define HASH_DATA_METHOD_DEF \
+ void (HASH_DATA_METHOD)(PANY_HASH_STATE state, \
+ PCBYTE buffer, \
+ size_t size)
+#define HASH_DATA(hashState, dInSize, dIn) \
+ ((hashState)->def->method.data)(&(hashState)->state, dIn, dInSize)
+/* Finalize the hash and get the digest */
+#define HASH_END_METHOD_DEF \
+ void (HASH_END_METHOD)(BYTE *buffer, PANY_HASH_STATE state)
+#define HASH_END(hashState, buffer) \
+ ((hashState)->def->method.end)(buffer, &(hashState)->state)
+/* Copy the hash context */
+/* NOTE: For import, export, and copy, memcpy() is used since there is no reformatting necessary
+ between the internal and external forms. */
+#define HASH_STATE_COPY_METHOD_DEF \
+ void (HASH_STATE_COPY_METHOD)(PANY_HASH_STATE to, \
+ PCANY_HASH_STATE from, \
+ size_t size)
+#define HASH_STATE_COPY(hashStateOut, hashStateIn) \
+ ((hashStateIn)->def->method.copy)(&(hashStateOut)->state, \
+ &(hashStateIn)->state, \
+ (hashStateIn)->def->contextSize)
+/* Copy (with reformatting when necessary) an internal hash structure to an external blob */
+#define HASH_STATE_EXPORT_METHOD_DEF \
+ void (HASH_STATE_EXPORT_METHOD)(BYTE *to, \
+ PCANY_HASH_STATE from, \
+ size_t size)
+#define HASH_STATE_EXPORT(to, hashStateFrom) \
+ ((hashStateFrom)->def->method.copyOut) \
+ (&(((BYTE *)(to))[offsetof(HASH_STATE, state)]), \
+ &(hashStateFrom)->state, \
+ (hashStateFrom)->def->contextSize)
+/* Copy from an external blob to an internal format (with reformatting when necessary) */
+#define HASH_STATE_IMPORT_METHOD_DEF \
+ void (HASH_STATE_IMPORT_METHOD)(PANY_HASH_STATE to, \
+ const BYTE *from, \
+ size_t size)
+#define HASH_STATE_IMPORT(hashStateTo, from) \
+ ((hashStateTo)->def->method.copyIn) \
+ (&(hashStateTo)->state, \
+ &(((const BYTE *)(from))[offsetof(HASH_STATE, state)]), \
+ (hashStateTo)->def->contextSize)
+/* Function aliases. The code in CryptHash.c uses the internal designation for the functions. These
+ need to be translated to the function names of the library. */
+#define tpmHashStart_SHA1 SHA1_Init // external name of the initialization method
+#define tpmHashData_SHA1 SHA1_Update
+#define tpmHashEnd_SHA1 SHA1_Final
+#define tpmHashStateCopy_SHA1 memcpy
+#define tpmHashStateExport_SHA1 memcpy
+#define tpmHashStateImport_SHA1 memcpy
+#define tpmHashStart_SHA256 SHA256_Init
+#define tpmHashData_SHA256 SHA256_Update
+#define tpmHashEnd_SHA256 SHA256_Final
+#define tpmHashStateCopy_SHA256 memcpy
+#define tpmHashStateExport_SHA256 memcpy
+#define tpmHashStateImport_SHA256 memcpy
+#define tpmHashStart_SHA384 SHA384_Init
+#define tpmHashData_SHA384 SHA384_Update
+#define tpmHashEnd_SHA384 SHA384_Final
+#define tpmHashStateCopy_SHA384 memcpy
+#define tpmHashStateExport_SHA384 memcpy
+#define tpmHashStateImport_SHA384 memcpy
+#define tpmHashStart_SHA512 SHA512_Init
+#define tpmHashData_SHA512 SHA512_Update
+#define tpmHashEnd_SHA512 SHA512_Final
+#define tpmHashStateCopy_SHA512 memcpy
+#define tpmHashStateExport_SHA512 memcpy
+#define tpmHashStateImport_SHA512 memcpy
+#define tpmHashStart_SM3_256 sm3_init
+#define tpmHashData_SM3_256 sm3_update
+#define tpmHashEnd_SM3_256 sm3_final
+#define tpmHashStateCopy_SM3_256 memcpy
+#define tpmHashStateExport_SM3_256 memcpy
+#define tpmHashStateImport_SM3_256 memcpy
+
+#endif // _CRYPT_HASH_C_
+#define LibHashInit()
+/* This definition would change if there were something to report */
+#define HashLibSimulationEnd()
+#endif // // HASH_LIB_DEFINED
+
+
diff --git a/src/tpm2/crypto/openssl/TpmToOsslMath.c b/src/tpm2/crypto/openssl/TpmToOsslMath.c
new file mode 100644
index 0000000..18e6c23
--- /dev/null
+++ b/src/tpm2/crypto/openssl/TpmToOsslMath.c
@@ -0,0 +1,736 @@
+/********************************************************************************/
+/* */
+/* TPM to OpenSSL BigNum Shim Layer */
+/* Written by Ken Goldman */
+/* IBM Thomas J. Watson Research Center */
+/* $Id: TpmToOsslMath.c 1598 2020-03-27 21:59:49Z kgoldman $ */
+/* */
+/* Licenses and Notices */
+/* */
+/* 1. Copyright Licenses: */
+/* */
+/* - Trusted Computing Group (TCG) grants to the user of the source code in */
+/* this specification (the "Source Code") a worldwide, irrevocable, */
+/* nonexclusive, royalty free, copyright license to reproduce, create */
+/* derivative works, distribute, display and perform the Source Code and */
+/* derivative works thereof, and to grant others the rights granted herein. */
+/* */
+/* - The TCG grants to the user of the other parts of the specification */
+/* (other than the Source Code) the rights to reproduce, distribute, */
+/* display, and perform the specification solely for the purpose of */
+/* developing products based on such documents. */
+/* */
+/* 2. Source Code Distribution Conditions: */
+/* */
+/* - Redistributions of Source Code must retain the above copyright licenses, */
+/* this list of conditions and the following disclaimers. */
+/* */
+/* - Redistributions in binary form must reproduce the above copyright */
+/* licenses, this list of conditions and the following disclaimers in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* 3. Disclaimers: */
+/* */
+/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
+/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
+/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
+/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
+/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
+/* information on specification licensing rights available through TCG */
+/* membership agreements. */
+/* */
+/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
+/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
+/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
+/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
+/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
+/* */
+/* - Without limitation, TCG and its members and licensors disclaim all */
+/* liability, including liability for infringement of any proprietary */
+/* rights, relating to use of information in this specification and to the */
+/* implementation of this specification, and TCG disclaims all liability for */
+/* cost of procurement of substitute goods or services, lost profits, loss */
+/* of use, loss of data or any incidental, consequential, direct, indirect, */
+/* or special damages, whether under contract, tort, warranty or otherwise, */
+/* arising in any way out of use or reliance upon this specification or any */
+/* information herein. */
+/* */
+/* (c) Copyright IBM Corp. and others, 2016 - 2020 */
+/* */
+/********************************************************************************/
+
+/* B.2.3.2. TpmToOsslMath.c */
+/* B.2.3.2.1. Introduction */
+
+/* The functions in this file provide the low-level interface between the TPM code and the big
+ number and elliptic curve math routines in OpenSSL. */
+/* Most math on big numbers require a context. The context contains the memory in which OpenSSL
+ creates and manages the big number values. When a OpenSSL math function will be called that
+ modifies a BIGNUM value, that value must be created in an OpenSSL context. The first line of code
+ in such a function must be: OSSL_ENTER(); and the last operation before returning must be
+ OSSL_LEAVE(). OpenSSL variables can then be created with BnNewVariable(). Constant values to be
+ used by OpenSSL are created from the bigNum values passed to the functions in this file. Space
+ for the BIGNUM control block is allocated in the stack of the function and then it is initialized
+ by calling BigInitialized(). That function sets up the values in the BIGNUM structure and sets
+ the data pointer to point to the data in the bignum_t. This is only used when the value is known
+ to be a constant in the called function. */
+/* Because the allocations of constants is on the local stack and the OSSL_ENTER()/OSSL_LEAVE() pair
+ flushes everything created in OpenSSL memory, there should be no chance of a memory leak. */
+
+
+#include "Tpm.h"
+#ifdef MATH_LIB_OSSL
+#include "TpmToOsslMath_fp.h"
+
+/* B.2.3.2.3.1. OsslToTpmBn() */
+/* This function converts an OpenSSL BIGNUM to a TPM bignum. In this implementation it is assumed
+ that OpenSSL uses a different control structure but the same data layout -- an array of
+ native-endian words in little-endian order. */
+/* Return Value Meaning */
+/* TRUE(1) success */
+/* FALSE(0) failure because value will not fit or OpenSSL variable doesn't exist */
+BOOL
+OsslToTpmBn(
+ bigNum bn,
+ const BIGNUM *osslBn // libtpms: added 'const'
+ )
+{
+ VERIFY(osslBn != NULL);
+ // If the bn is NULL, it means that an output value pointer was NULL meaning that
+ // the results is simply to be discarded.
+ unsigned char buffer[LARGEST_NUMBER + 1]; // libtpms added
+ int buffer_len; // libtpms added
+
+ if(bn != NULL)
+ {
+#if 1 //libtpms added begin
+ int num_bytes;
+
+ num_bytes = BN_num_bytes(osslBn);
+ VERIFY(num_bytes >= 0 && sizeof(buffer) >= (size_t)num_bytes);
+ buffer_len = BN_bn2bin(osslBn, buffer); /* ossl to bin */
+ BnFromBytes(bn, buffer, buffer_len); /* bin to TPM */
+#else // libtpms added end
+ int i;
+ //
+ VERIFY((unsigned)osslBn->top <= BnGetAllocated(bn));
+ for(i = 0; i < osslBn->top; i++)
+ bn->d[i] = osslBn->d[i];
+ BnSetTop(bn, osslBn->top);
+#endif // libtpms added
+ }
+ return TRUE;
+ Error:
+ return FALSE;
+}
+
+/* B.2.3.2.3.2. BigInitialized() */
+/* This function initializes an OSSL BIGNUM from a TPM bigConst. Do not use this for values that are
+ passed to OpenSLL when they are not declared as const in the function prototype. Instead, use
+ BnNewVariable(). */
+BIGNUM *
+BigInitialized(
+ BIGNUM *toInit,
+ bigConst initializer
+ )
+{
+#if 1 // libtpms added begin
+ BIGNUM *_toInit;
+ unsigned char buffer[LARGEST_NUMBER + 1];
+ NUMBYTES buffer_len = (NUMBYTES )sizeof(buffer);
+#endif // libtpms added end
+
+ if(initializer == NULL)
+ FAIL(FATAL_ERROR_PARAMETER);
+ if(toInit == NULL || initializer == NULL)
+ return NULL;
+
+#if 1 // libtpms added begin
+ BnToBytes(initializer, buffer, &buffer_len); /* TPM to bin */
+ _toInit = BN_bin2bn(buffer, buffer_len, NULL); /* bin to ossl */
+ BN_set_flags(_toInit, BN_FLG_CONSTTIME);
+ BN_copy(toInit, _toInit);
+ BN_clear_free(_toInit);
+#else // libtpms added end
+ toInit->d = (BN_ULONG *)&initializer->d[0];
+ toInit->dmax = (int)initializer->allocated;
+ toInit->top = (int)initializer->size;
+ toInit->neg = 0;
+ toInit->flags = 0;
+#endif
+ return toInit;
+}
+
+#ifndef OSSL_DEBUG
+# define BIGNUM_PRINT(label, bn, eol)
+# define DEBUG_PRINT(x)
+#else
+# define DEBUG_PRINT(x) printf("%s", x)
+# define BIGNUM_PRINT(label, bn, eol) BIGNUM_print((label), (bn), (eol))
+
+static
+void BIGNUM_print(
+ const char *label,
+ const BIGNUM *a,
+ BOOL eol
+ )
+{
+ BN_ULONG *d;
+ int i;
+ int notZero = FALSE;
+ if(label != NULL)
+ printf("%s", label);
+ if(a == NULL)
+ {
+ printf("NULL");
+ goto done;
+ }
+ if (a->neg)
+ printf("-");
+ for(i = a->top, d = &a->d[i - 1]; i > 0; i--)
+ {
+ int j;
+ BN_ULONG l = *d--;
+ for(j = BN_BITS2 - 8; j >= 0; j -= 8)
+ {
+ BYTE b = (BYTE)((l >> j) & 0xFF);
+ notZero = notZero || (b != 0);
+ if(notZero)
+ printf("%02x", b);
+ }
+ if(!notZero)
+ printf("0");
+ }
+ done:
+ if(eol)
+ printf("\n");
+ return;
+}
+#endif
+
+/* B.2.3.2.3.4. BnNewVariable() */
+/* This function allocates a new variable in the provided context. If the context does not exist or
+ the allocation fails, it is a catastrophic failure. */
+static BIGNUM *
+BnNewVariable(
+ BN_CTX *CTX
+ )
+{
+ BIGNUM *new;
+ //
+ // This check is intended to protect against calling this function without
+ // having initialized the CTX.
+ if((CTX == NULL) || ((new = BN_CTX_get(CTX)) == NULL))
+ FAIL(FATAL_ERROR_ALLOCATION);
+ return new;
+}
+
+#if LIBRARY_COMPATIBILITY_CHECK
+
+BOOL
+MathLibraryCompatibilityCheck(
+ void
+ )
+{
+ OSSL_ENTER();
+ BIGNUM *osslTemp = BnNewVariable(CTX);
+#if 0
+ crypt_uword_t i;
+#endif
+ BYTE test[] = {0x1F, 0x1E, 0x1D, 0x1C, 0x1B, 0x1A, 0x19, 0x18,
+ 0x17, 0x16, 0x15, 0x14, 0x13, 0x12, 0x11, 0x10,
+ 0x0F, 0x0E, 0x0D, 0x0C, 0x0B, 0x0A, 0x09, 0x08,
+ 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00};
+ BN_VAR(tpmTemp, sizeof(test) * 8); // allocate some space for a test value
+ //
+ // Convert the test data to a bigNum
+ BnFromBytes(tpmTemp, test, sizeof(test));
+ // Convert the test data to an OpenSSL BIGNUM
+ BN_bin2bn(test, sizeof(test), osslTemp);
+ // Make sure the values are consistent
+#if 0
+ VERIFY(osslTemp->top == (int)tpmTemp->size);
+ for(i = 0; i < tpmTemp->size; i++)
+ VERIFY(osslTemp->d[i] == tpmTemp->d[i]);
+#endif
+ OSSL_LEAVE();
+ return 1;
+#if 0
+ Error:
+ return 0;
+#endif
+}
+
+#endif
+
+/* B.2.3.2.3.3. BnModMult() */
+/* Does multiply and divide returning the remainder of the divide. */
+/* Return Value Meaning */
+/* TRUE(1) success */
+/* FALSE(0) failure in operation */
+
+LIB_EXPORT BOOL
+BnModMult(
+ bigNum result,
+ bigConst op1,
+ bigConst op2,
+ bigConst modulus
+ )
+{
+ OSSL_ENTER();
+ BOOL OK = TRUE;
+ BIGNUM *bnResult = BN_NEW();
+ BIGNUM *bnTemp = BN_NEW();
+ BIG_INITIALIZED(bnOp1, op1);
+ BIG_INITIALIZED(bnOp2, op2);
+ BIG_INITIALIZED(bnMod, modulus);
+ //
+ VERIFY(BN_mul(bnTemp, bnOp1, bnOp2, CTX));
+ VERIFY(BN_div(NULL, bnResult, bnTemp, bnMod, CTX));
+ VERIFY(OsslToTpmBn(result, bnResult));
+ goto Exit;
+ Error:
+ OK = FALSE;
+ Exit:
+ BN_clear_free(bnMod); // libtpms added
+ BN_clear_free(bnOp2); // libtpms added
+ BN_clear_free(bnOp1); // libtpms added
+ OSSL_LEAVE();
+ return OK;
+}
+
+/* B.2.3.2.3.4. BnMult() */
+/* Multiplies two numbers */
+/* Return Value Meaning */
+/* TRUE(1) success */
+/* FALSE(0) failure in operation */
+
+LIB_EXPORT BOOL
+BnMult(
+ bigNum result,
+ bigConst multiplicand,
+ bigConst multiplier
+ )
+{
+ OSSL_ENTER();
+ BIGNUM *bnTemp = BN_NEW();
+ BOOL OK = TRUE;
+ BIG_INITIALIZED(bnA, multiplicand);
+ BIG_INITIALIZED(bnB, multiplier);
+ //
+ VERIFY(BN_mul(bnTemp, bnA, bnB, CTX));
+ VERIFY(OsslToTpmBn(result, bnTemp));
+ goto Exit;
+ Error:
+ OK = FALSE;
+ Exit:
+ BN_clear_free(bnB); // libtpms added
+ BN_clear_free(bnA); // libtpms added
+ OSSL_LEAVE();
+ return OK;
+}
+
+/* B.2.3.2.3.5. BnDiv() */
+/* This function divides two bigNum values. The function returns FALSE if there is an error in the
+ operation. */
+/* Return Value Meaning */
+/* TRUE(1) success */
+/* FALSE(0) failure in operation */
+
+LIB_EXPORT BOOL
+BnDiv(
+ bigNum quotient,
+ bigNum remainder,
+ bigConst dividend,
+ bigConst divisor
+ )
+{
+ OSSL_ENTER();
+ BIGNUM *bnQ = BN_NEW();
+ BIGNUM *bnR = BN_NEW();
+ BOOL OK = TRUE;
+ BIG_INITIALIZED(bnDend, dividend);
+ BIG_INITIALIZED(bnSor, divisor);
+ //
+ if(BnEqualZero(divisor))
+ FAIL(FATAL_ERROR_DIVIDE_ZERO);
+ VERIFY(BN_div(bnQ, bnR, bnDend, bnSor, CTX));
+ VERIFY(OsslToTpmBn(quotient, bnQ));
+ VERIFY(OsslToTpmBn(remainder, bnR));
+ DEBUG_PRINT("In BnDiv:\n");
+ BIGNUM_PRINT(" bnDividend: ", bnDend, TRUE);
+ BIGNUM_PRINT(" bnDivisor: ", bnSor, TRUE);
+ BIGNUM_PRINT(" bnQuotient: ", bnQ, TRUE);
+ BIGNUM_PRINT(" bnRemainder: ", bnR, TRUE);
+ goto Exit;
+ Error:
+ OK = FALSE;
+ Exit:
+ BN_clear_free(bnSor); // libtpms added
+ BN_clear_free(bnDend); // libtpms added
+ OSSL_LEAVE();
+ return OK;
+}
+
+#if ALG_RSA
+#if !RSA_KEY_SIEVE // libtpms added
+/* B.2.3.2.3.6. BnGcd() */
+/* Get the greatest common divisor of two numbers */
+/* Return Value Meaning */
+/* TRUE(1) success */
+/* FALSE(0) failure in operation */
+
+LIB_EXPORT BOOL
+BnGcd(
+ bigNum gcd, // OUT: the common divisor
+ bigConst number1, // IN:
+ bigConst number2 // IN:
+ )
+{
+ OSSL_ENTER();
+ BIGNUM *bnGcd = BN_NEW();
+ BOOL OK = TRUE;
+ BIG_INITIALIZED(bn1, number1);
+ BIG_INITIALIZED(bn2, number2);
+ //
+ BN_set_flags(bn1, BN_FLG_CONSTTIME); // number1 is secret prime number
+ VERIFY(BN_gcd(bnGcd, bn1, bn2, CTX));
+ VERIFY(OsslToTpmBn(gcd, bnGcd));
+ goto Exit;
+ Error:
+ OK = FALSE;
+ Exit:
+ BN_clear_free(bn2); // libtpms added
+ BN_clear_free(bn1); // libtpms added
+ OSSL_LEAVE();
+ return OK;
+}
+#endif // libtpms added
+
+/* B.2.3.2.3.7. BnModExp() */
+/* Do modular exponentiation using bigNum values. The conversion from a bignum_t to a bigNum is
+ trivial as they are based on the same structure */
+/* Return Value Meaning */
+/* TRUE(1) success */
+/* FALSE(0) failure in operation */
+
+LIB_EXPORT BOOL
+BnModExp(
+ bigNum result, // OUT: the result
+ bigConst number, // IN: number to exponentiate
+ bigConst exponent, // IN:
+ bigConst modulus // IN:
+ )
+{
+ OSSL_ENTER();
+ BIGNUM *bnResult = BN_NEW();
+ BOOL OK = TRUE;
+ BIG_INITIALIZED(bnN, number);
+ BIG_INITIALIZED(bnE, exponent);
+ BIG_INITIALIZED(bnM, modulus);
+ //
+ BN_set_flags(bnE, BN_FLG_CONSTTIME); // exponent may be private
+ VERIFY(BN_mod_exp(bnResult, bnN, bnE, bnM, CTX));
+ VERIFY(OsslToTpmBn(result, bnResult));
+ goto Exit;
+ Error:
+ OK = FALSE;
+ Exit:
+ BN_clear_free(bnM); // libtpms added
+ BN_clear_free(bnE); // libtpms added
+ BN_clear_free(bnN); // libtpms added
+ OSSL_LEAVE();
+ return OK;
+}
+
+/* B.2.3.2.3.8. BnModInverse() */
+/* Modular multiplicative inverse */
+/* Return Value Meaning */
+/* TRUE(1) success */
+/* FALSE(0) failure in operation */
+
+LIB_EXPORT BOOL
+BnModInverse(
+ bigNum result,
+ bigConst number,
+ bigConst modulus
+ )
+{
+ OSSL_ENTER();
+ BIGNUM *bnResult = BN_NEW();
+ BOOL OK = TRUE;
+ BIG_INITIALIZED(bnN, number);
+ BIG_INITIALIZED(bnM, modulus);
+ //
+ BN_set_flags(bnN, BN_FLG_CONSTTIME); // number may be private
+ VERIFY(BN_mod_inverse(bnResult, bnN, bnM, CTX) != NULL);
+ VERIFY(OsslToTpmBn(result, bnResult));
+ goto Exit;
+ Error:
+ OK = FALSE;
+ Exit:
+ BN_clear_free(bnM); // libtpms added
+ BN_clear_free(bnN); // libtpms added
+ OSSL_LEAVE();
+ return OK;
+}
+
+#endif // TPM_ALG_RSA
+
+#if ALG_ECC
+
+/* B.2.3.2.3.9. PointFromOssl() */
+/* Function to copy the point result from an OSSL function to a bigNum */
+/* Return Value Meaning */
+/* TRUE(1) success */
+/* FALSE(0) failure in operation */
+static BOOL
+PointFromOssl(
+ bigPoint pOut, // OUT: resulting point
+ EC_POINT *pIn, // IN: the point to return
+ bigCurve E // IN: the curve
+ )
+{
+ BIGNUM *x = NULL;
+ BIGNUM *y = NULL;
+ BOOL OK;
+ BN_CTX_start(E->CTX);
+ //
+ x = BN_CTX_get(E->CTX);
+ y = BN_CTX_get(E->CTX);
+ if(y == NULL)
+ FAIL(FATAL_ERROR_ALLOCATION);
+ // If this returns false, then the point is at infinity
+#if OPENSSL_VERSION_NUMBER >= 0x10100000L && \
+ !defined(LIBRESSL_VERSION_NUMBER) // libtpms added begin
+ OK = EC_POINT_get_affine_coordinates(E->G, pIn, x, y, E->CTX);
+#else // libtpms added begin
+ OK = EC_POINT_get_affine_coordinates_GFp(E->G, pIn, x, y, E->CTX);
+#endif // libtpms added end
+ if(OK)
+ {
+ OsslToTpmBn(pOut->x, x);
+ OsslToTpmBn(pOut->y, y);
+ BnSetWord(pOut->z, 1);
+ }
+ else
+ BnSetWord(pOut->z, 0);
+ BN_CTX_end(E->CTX);
+ return OK;
+}
+/* B.2.3.2.3.10. EcPointInitialized() */
+/* Allocate and initialize a point. */
+
+LIB_EXPORT EC_POINT * // libtpms: exported function
+EcPointInitialized(
+ pointConst initializer,
+ bigCurve E
+ )
+{
+ EC_POINT *P = NULL;
+
+ if(initializer != NULL)
+ {
+ BIG_INITIALIZED(bnX, initializer->x);
+ BIG_INITIALIZED(bnY, initializer->y);
+ if(E == NULL)
+ FAIL(FATAL_ERROR_ALLOCATION);
+ P = EC_POINT_new(E->G);
+#if OPENSSL_VERSION_NUMBER >= 0x10100000L && \
+ !defined(LIBRESSL_VERSION_NUMBER) // libtpms added begin
+ if(!EC_POINT_set_affine_coordinates(E->G, P, bnX, bnY, E->CTX))
+#else // libtpms added end
+ if(!EC_POINT_set_affine_coordinates_GFp(E->G, P, bnX, bnY, E->CTX))
+#endif // libtpms added
+ P = NULL;
+ BN_clear_free(bnX); // libtpms added
+ BN_clear_free(bnY); // libtpms added
+ }
+ return P;
+}
+
+/* B.2.3.2.3.11. BnCurveInitialize() */
+/* This function initializes the OpenSSL group definition */
+/* It is a fatal error if groupContext is not provided. */
+/* Return Values Meaning */
+/* NULL the TPM_ECC_CURVE is not valid */
+/* non-NULL points to a structure in groupContext */
+
+LIB_EXPORT bigCurve
+BnCurveInitialize(
+ bigCurve E, // IN: curve structure to initialize
+ TPM_ECC_CURVE curveId // IN: curve identifier
+ )
+{
+ const ECC_CURVE_DATA *C = GetCurveData(curveId);
+ if(C == NULL)
+ E = NULL;
+ if(E != NULL)
+ {
+ // This creates the OpenSSL memory context that stays in effect as long as the
+ // curve (E) is defined.
+ OSSL_ENTER(); // if the allocation fails, the TPM fails
+ EC_POINT *P = NULL;
+ BIG_INITIALIZED(bnP, C->prime);
+ BIG_INITIALIZED(bnA, C->a);
+ BIG_INITIALIZED(bnB, C->b);
+ BIG_INITIALIZED(bnX, C->base.x);
+ BIG_INITIALIZED(bnY, C->base.y);
+ BIG_INITIALIZED(bnN, C->order);
+ BIG_INITIALIZED(bnH, C->h);
+ //
+ E->C = C;
+ E->CTX = CTX;
+
+ // initialize EC group, associate a generator point and initialize the point
+ // from the parameter data
+ // Create a group structure
+ E->G = EC_GROUP_new_curve_GFp(bnP, bnA, bnB, CTX);
+ VERIFY(E->G != NULL);
+
+ // Allocate a point in the group that will be used in setting the
+ // generator. This is not needed after the generator is set.
+ P = EC_POINT_new(E->G);
+ VERIFY(P != NULL);
+
+ // Need to use this in case Montgomery method is being used
+#if OPENSSL_VERSION_NUMBER >= 0x10100000L && \
+ !defined(LIBRESSL_VERSION_NUMBER) // libtpms added begin
+ VERIFY(EC_POINT_set_affine_coordinates(E->G, P, bnX, bnY, CTX));
+#else // libtpms added end
+ VERIFY(EC_POINT_set_affine_coordinates_GFp(E->G, P, bnX, bnY, CTX));
+#endif // libtpms added
+ // Now set the generator
+ VERIFY(EC_GROUP_set_generator(E->G, P, bnN, bnH));
+
+ EC_POINT_free(P);
+ goto Exit_free; // libtpms changed
+ Error:
+ EC_POINT_free(P);
+ BnCurveFree(E);
+ E = NULL;
+
+ Exit_free: // libtpms added begin
+ BN_clear_free(bnH);
+ BN_clear_free(bnN);
+ BN_clear_free(bnY);
+ BN_clear_free(bnX);
+ BN_clear_free(bnB);
+ BN_clear_free(bnA);
+ BN_clear_free(bnP); // libtpms added end
+ }
+// Exit:
+ return E;
+}
+
+/* B.2.3.2.3.15. BnCurveFree() */
+/* This function will free the allocated components of the curve and end the frame in which the
+ curve data exists */
+LIB_EXPORT void
+BnCurveFree(
+ bigCurve E
+ )
+{
+ if(E)
+ {
+ EC_GROUP_free(E->G);
+ OsslContextLeave(E->CTX);
+ }
+}
+
+/* B.2.3.2.3.11. BnEccModMult() */
+/* This functi2n does a point multiply of the form R = [d]S */
+/* Return Values Meaning */
+/* FALSE failure in operation; treat as result being point at infinity */
+
+LIB_EXPORT BOOL
+BnEccModMult(
+ bigPoint R, // OUT: computed point
+ pointConst S, // IN: point to multiply by 'd' (optional)
+ bigConst d, // IN: scalar for [d]S
+ bigCurve E
+ )
+{
+ EC_POINT *pR = EC_POINT_new(E->G);
+ EC_POINT *pS = EcPointInitialized(S, E);
+ BIG_INITIALIZED(bnD, d);
+
+ if(S == NULL)
+ EC_POINT_mul(E->G, pR, bnD, NULL, NULL, E->CTX);
+ else
+ EC_POINT_mul(E->G, pR, NULL, pS, bnD, E->CTX);
+ PointFromOssl(R, pR, E);
+ EC_POINT_clear_free(pR); // libtpms changed
+ EC_POINT_clear_free(pS); // libtpms changed
+ BN_clear_free(bnD); // libtpms added
+ return !BnEqualZero(R->z);
+}
+
+/* B.2.3.2.3.13. BnEccModMult2() */
+/* This function does a point multiply of the form R = [d]G + [u]Q */
+/* FALSE failure in operation; treat as result being point at infinity */
+
+LIB_EXPORT BOOL
+BnEccModMult2(
+ bigPoint R, // OUT: computed point
+ pointConst S, // IN: optional point
+ bigConst d, // IN: scalar for [d]S or [d]G
+ pointConst Q, // IN: second point
+ bigConst u, // IN: second scalar
+ bigCurve E // IN: curve
+ )
+{
+ EC_POINT *pR = EC_POINT_new(E->G);
+ EC_POINT *pS = EcPointInitialized(S, E);
+ BIG_INITIALIZED(bnD, d);
+ EC_POINT *pQ = EcPointInitialized(Q, E);
+ BIG_INITIALIZED(bnU, u);
+
+ if(S == NULL || S == (pointConst)&(AccessCurveData(E)->base))
+ EC_POINT_mul(E->G, pR, bnD, pQ, bnU, E->CTX);
+ else
+ {
+ const EC_POINT *points[2];
+ const BIGNUM *scalars[2];
+ points[0] = pS;
+ points[1] = pQ;
+ scalars[0] = bnD;
+ scalars[1] = bnU;
+ EC_POINTs_mul(E->G, pR, NULL, 2, points, scalars, E->CTX);
+ }
+ PointFromOssl(R, pR, E);
+ EC_POINT_clear_free(pR); // libtpms changed
+ EC_POINT_clear_free(pS); // libtpms changed
+ EC_POINT_clear_free(pQ); // libtpms changed
+ BN_clear_free(bnD); // libtpms added
+ BN_clear_free(bnU); // libtpms added
+
+ return !BnEqualZero(R->z);
+}
+
+/* B.2.3.2.4. BnEccAdd() */
+/* This function does addition of two points. */
+/* Return Values Meaning */
+/* FALSE failure in operation; treat as result being point at infinity */
+LIB_EXPORT BOOL
+BnEccAdd(
+ bigPoint R, // OUT: computed point
+ pointConst S, // IN: point to multiply by 'd'
+ pointConst Q, // IN: second point
+ bigCurve E // IN: curve
+ )
+{
+ EC_POINT *pR = EC_POINT_new(E->G);
+ EC_POINT *pS = EcPointInitialized(S, E);
+ EC_POINT *pQ = EcPointInitialized(Q, E);
+ //
+ EC_POINT_add(E->G, pR, pS, pQ, E->CTX);
+ PointFromOssl(R, pR, E);
+ EC_POINT_clear_free(pR); // libtpms changed
+ EC_POINT_clear_free(pS); // libtpms changed
+ EC_POINT_clear_free(pQ); // libtpms changed
+ return !BnEqualZero(R->z);
+}
+
+#endif // ALG_ECC
+#endif // MATH_LIB_OSSL
diff --git a/src/tpm2/crypto/openssl/TpmToOsslMath.h b/src/tpm2/crypto/openssl/TpmToOsslMath.h
new file mode 100644
index 0000000..47333c7
--- /dev/null
+++ b/src/tpm2/crypto/openssl/TpmToOsslMath.h
@@ -0,0 +1,164 @@
+/********************************************************************************/
+/* */
+/* TPM to OpenSSL BigNum Shim Layer */
+/* Written by Ken Goldman */
+/* IBM Thomas J. Watson Research Center */
+/* $Id: TpmToOsslMath.h 1658 2021-01-22 23:14:01Z kgoldman $ */
+/* */
+/* Licenses and Notices */
+/* */
+/* 1. Copyright Licenses: */
+/* */
+/* - Trusted Computing Group (TCG) grants to the user of the source code in */
+/* this specification (the "Source Code") a worldwide, irrevocable, */
+/* nonexclusive, royalty free, copyright license to reproduce, create */
+/* derivative works, distribute, display and perform the Source Code and */
+/* derivative works thereof, and to grant others the rights granted herein. */
+/* */
+/* - The TCG grants to the user of the other parts of the specification */
+/* (other than the Source Code) the rights to reproduce, distribute, */
+/* display, and perform the specification solely for the purpose of */
+/* developing products based on such documents. */
+/* */
+/* 2. Source Code Distribution Conditions: */
+/* */
+/* - Redistributions of Source Code must retain the above copyright licenses, */
+/* this list of conditions and the following disclaimers. */
+/* */
+/* - Redistributions in binary form must reproduce the above copyright */
+/* licenses, this list of conditions and the following disclaimers in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* 3. Disclaimers: */
+/* */
+/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
+/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
+/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
+/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
+/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
+/* information on specification licensing rights available through TCG */
+/* membership agreements. */
+/* */
+/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
+/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
+/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
+/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
+/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
+/* */
+/* - Without limitation, TCG and its members and licensors disclaim all */
+/* liability, including liability for infringement of any proprietary */
+/* rights, relating to use of information in this specification and to the */
+/* implementation of this specification, and TCG disclaims all liability for */
+/* cost of procurement of substitute goods or services, lost profits, loss */
+/* of use, loss of data or any incidental, consequential, direct, indirect, */
+/* or special damages, whether under contract, tort, warranty or otherwise, */
+/* arising in any way out of use or reliance upon this specification or any */
+/* information herein. */
+/* */
+/* (c) Copyright IBM Corp. and others, 2016 - 2021 */
+/* */
+/********************************************************************************/
+
+/* B.2.2.1. TpmToOsslMath.h */
+/* B.2.2.1.1. Introduction */
+/* This file contains the structure definitions used for ECC in the OpenSSL version of the
+ code. These definitions would change, based on the library. The ECC-related structures that cross
+ the TPM interface are defined in TpmTypes.h */
+
+#ifndef MATH_LIB_DEFINED
+#define MATH_LIB_DEFINED
+#define MATH_LIB_OSSL
+#include <openssl/evp.h>
+#include <openssl/ec.h>
+
+#define SYMMETRIC_ALIGNMENT RADIX_BYTES
+
+#if 0 // libtpms added
+#if OPENSSL_VERSION_NUMBER >= 0x10200000L
+// Check the bignum_st definition in crypto/bn/bn_lcl.h and either update the
+// version check or provide the new definition for this version.
+# error Untested OpenSSL version
+#elif OPENSSL_VERSION_NUMBER >= 0x10100000L
+// from crypto/bn/bn_lcl.h
+struct bignum_st {
+ BN_ULONG *d;
+ int top;
+
+ int dmax;
+ int neg;
+ int flags;
+};
+#if 0 // libtpms added
+# define EC_POINT_get_affine_coordinates EC_POINT_get_affine_coordinates_GFp
+# define EC_POINT_set_affine_coordinates EC_POINT_set_affine_coordinates_GFp
+#endif // libtpms added
+#endif // OPENSSL_VERSION_NUMBER
+#endif // libtpms added
+
+#include <openssl/bn.h>
+#if USE_OPENSSL_FUNCTIONS_ECDSA // libtpms added begin
+#include <openssl/ecdsa.h>
+#endif // libtpms added end
+
+/* B.2.2.2.2. Macros and Defines */
+/* Make sure that the library is using the correct size for a crypt word */
+
+#if defined THIRTY_TWO_BIT && (RADIX_BITS != 32) \
+ || ((defined SIXTY_FOUR_BIT_LONG || defined SIXTY_FOUR_BIT) \
+ && (RADIX_BITS != 64))
+# error Ossl library is using different radix
+#endif
+
+/* Allocate a local BIGNUM value. For the allocation, a bigNum structure is created as is a local
+ BIGNUM. The bigNum is initialized and then the BIGNUM is set to reference the local value. */
+
+#define BIG_VAR(name, bits) \
+ BN_VAR(name##Bn, (bits)); \
+ BIGNUM *_##name = BN_new(); /* libtpms */ \
+ BIGNUM *name = BigInitialized(_##name, /* libtpms */ \
+ BnInit(name##Bn, \
+ BYTES_TO_CRYPT_WORDS(sizeof(_##name##Bn.d))))
+
+/* Allocate a BIGNUM and initialize with the values in a bigNum initializer */
+
+#define BIG_INITIALIZED(name, initializer) \
+ BIGNUM *_##name = BN_new(); /* libtpms */ \
+ BIGNUM *name = BigInitialized(_##name, initializer) /* libtpms */
+
+typedef struct
+{
+ const ECC_CURVE_DATA *C; // the TPM curve values
+ EC_GROUP *G; // group parameters
+ BN_CTX *CTX; // the context for the math (this might not be
+ // the context in which the curve was created>;
+} OSSL_CURVE_DATA;
+typedef OSSL_CURVE_DATA *bigCurve;
+#define AccessCurveData(E) ((E)->C)
+
+#include "TpmToOsslSupport_fp.h"
+
+#define OSSL_ENTER() BN_CTX *CTX = OsslContextEnter()
+#define OSSL_LEAVE() OsslContextLeave(CTX)
+
+/* Start and end a context that spans multiple ECC functions. This is used so that the group for the
+ curve can persist across multiple frames. */
+
+#define CURVE_INITIALIZED(name, initializer) \
+ OSSL_CURVE_DATA _##name; \
+ bigCurve name = BnCurveInitialize(&_##name, initializer)
+
+#define CURVE_FREE(name) BnCurveFree(name)
+
+/* Start and end a local stack frame within the context of the curve frame */
+#if 0 /* kgold not used */
+#define ECC_ENTER() BN_CTX *CTX = OsslPushContext(E->CTX)
+#define ECC_LEAVE() OsslPopContext(CTX)
+#endif
+#define BN_NEW() BnNewVariable(CTX)
+
+
+/* This definition would change if there were something to report */
+#define MathLibSimulationEnd()
+#endif // MATH_LIB_DEFINED
+
+
diff --git a/src/tpm2/crypto/openssl/TpmToOsslMath_fp.h b/src/tpm2/crypto/openssl/TpmToOsslMath_fp.h
new file mode 100644
index 0000000..7c42e71
--- /dev/null
+++ b/src/tpm2/crypto/openssl/TpmToOsslMath_fp.h
@@ -0,0 +1,152 @@
+/********************************************************************************/
+/* */
+/* TPM to OpenSSL BigNum Shim Layer */
+/* Written by Ken Goldman */
+/* IBM Thomas J. Watson Research Center */
+/* $Id: TpmToOsslMath_fp.h 1519 2019-11-15 20:43:51Z kgoldman $ */
+/* */
+/* Licenses and Notices */
+/* */
+/* 1. Copyright Licenses: */
+/* */
+/* - Trusted Computing Group (TCG) grants to the user of the source code in */
+/* this specification (the "Source Code") a worldwide, irrevocable, */
+/* nonexclusive, royalty free, copyright license to reproduce, create */
+/* derivative works, distribute, display and perform the Source Code and */
+/* derivative works thereof, and to grant others the rights granted herein. */
+/* */
+/* - The TCG grants to the user of the other parts of the specification */
+/* (other than the Source Code) the rights to reproduce, distribute, */
+/* display, and perform the specification solely for the purpose of */
+/* developing products based on such documents. */
+/* */
+/* 2. Source Code Distribution Conditions: */
+/* */
+/* - Redistributions of Source Code must retain the above copyright licenses, */
+/* this list of conditions and the following disclaimers. */
+/* */
+/* - Redistributions in binary form must reproduce the above copyright */
+/* licenses, this list of conditions and the following disclaimers in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* 3. Disclaimers: */
+/* */
+/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
+/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
+/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
+/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
+/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
+/* information on specification licensing rights available through TCG */
+/* membership agreements. */
+/* */
+/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
+/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
+/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
+/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
+/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
+/* */
+/* - Without limitation, TCG and its members and licensors disclaim all */
+/* liability, including liability for infringement of any proprietary */
+/* rights, relating to use of information in this specification and to the */
+/* implementation of this specification, and TCG disclaims all liability for */
+/* cost of procurement of substitute goods or services, lost profits, loss */
+/* of use, loss of data or any incidental, consequential, direct, indirect, */
+/* or special damages, whether under contract, tort, warranty or otherwise, */
+/* arising in any way out of use or reliance upon this specification or any */
+/* information herein. */
+/* */
+/* (c) Copyright IBM Corp. and others, 2016 - 2019 */
+/* */
+/********************************************************************************/
+
+#ifndef TPMTOOSSLMATH_FP_H
+#define TPMTOOSSLMATH_FP_H
+
+#include <openssl/bn.h>
+
+BOOL
+OsslToTpmBn(
+ bigNum bn,
+ const BIGNUM *osslBn // libtpms added 'const'
+ );
+BIGNUM *
+BigInitialized(
+ BIGNUM *toInit,
+ bigConst initializer
+ );
+// libtpms added begin
+EC_POINT *
+EcPointInitialized(
+ pointConst initializer,
+ bigCurve E
+ );
+// libtpms added end
+LIB_EXPORT BOOL
+BnModMult(
+ bigNum result,
+ bigConst op1,
+ bigConst op2,
+ bigConst modulus
+ );
+LIB_EXPORT BOOL
+BnMult(
+ bigNum result,
+ bigConst multiplicand,
+ bigConst multiplier
+ );
+LIB_EXPORT BOOL
+BnDiv(
+ bigNum quotient,
+ bigNum remainder,
+ bigConst dividend,
+ bigConst divisor
+ );
+LIB_EXPORT BOOL
+BnGcd(
+ bigNum gcd, // OUT: the common divisor
+ bigConst number1, // IN:
+ bigConst number2 // IN:
+ );
+LIB_EXPORT BOOL
+BnModExp(
+ bigNum result, // OUT: the result
+ bigConst number, // IN: number to exponentiate
+ bigConst exponent, // IN:
+ bigConst modulus // IN:
+ );
+LIB_EXPORT BOOL
+BnModInverse(
+ bigNum result,
+ bigConst number,
+ bigConst modulus
+ );
+bigCurve
+BnCurveInitialize(
+ bigCurve E, // IN: curve structure to initialize
+ TPM_ECC_CURVE curveId // IN: curve identifier
+ );
+LIB_EXPORT BOOL
+BnEccModMult(
+ bigPoint R, // OUT: computed point
+ pointConst S, // IN: point to multiply by 'd' (optional)
+ bigConst d, // IN: scalar for [d]S
+ bigCurve E
+ );
+LIB_EXPORT BOOL
+BnEccModMult2(
+ bigPoint R, // OUT: computed point
+ pointConst S, // IN: optional point
+ bigConst d, // IN: scalar for [d]S or [d]G
+ pointConst Q, // IN: second point
+ bigConst u, // IN: second scalar
+ bigCurve E // IN: curve
+ );
+LIB_EXPORT BOOL
+BnEccAdd(
+ bigPoint R, // OUT: computed point
+ pointConst S, // IN: point to multiply by 'd'
+ pointConst Q, // IN: second point
+ bigCurve E // IN: curve
+ );
+
+#endif
diff --git a/src/tpm2/crypto/openssl/TpmToOsslSupport.c b/src/tpm2/crypto/openssl/TpmToOsslSupport.c
new file mode 100644
index 0000000..921b02f
--- /dev/null
+++ b/src/tpm2/crypto/openssl/TpmToOsslSupport.c
@@ -0,0 +1,129 @@
+/********************************************************************************/
+/* */
+/* Initialization of the Interface to the OpenSSL Library. */
+/* Written by Ken Goldman */
+/* IBM Thomas J. Watson Research Center */
+/* $Id: TpmToOsslSupport.c 1519 2019-11-15 20:43:51Z kgoldman $ */
+/* */
+/* Licenses and Notices */
+/* */
+/* 1. Copyright Licenses: */
+/* */
+/* - Trusted Computing Group (TCG) grants to the user of the source code in */
+/* this specification (the "Source Code") a worldwide, irrevocable, */
+/* nonexclusive, royalty free, copyright license to reproduce, create */
+/* derivative works, distribute, display and perform the Source Code and */
+/* derivative works thereof, and to grant others the rights granted herein. */
+/* */
+/* - The TCG grants to the user of the other parts of the specification */
+/* (other than the Source Code) the rights to reproduce, distribute, */
+/* display, and perform the specification solely for the purpose of */
+/* developing products based on such documents. */
+/* */
+/* 2. Source Code Distribution Conditions: */
+/* */
+/* - Redistributions of Source Code must retain the above copyright licenses, */
+/* this list of conditions and the following disclaimers. */
+/* */
+/* - Redistributions in binary form must reproduce the above copyright */
+/* licenses, this list of conditions and the following disclaimers in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* 3. Disclaimers: */
+/* */
+/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
+/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
+/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
+/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
+/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
+/* information on specification licensing rights available through TCG */
+/* membership agreements. */
+/* */
+/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
+/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
+/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
+/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
+/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
+/* */
+/* - Without limitation, TCG and its members and licensors disclaim all */
+/* liability, including liability for infringement of any proprietary */
+/* rights, relating to use of information in this specification and to the */
+/* implementation of this specification, and TCG disclaims all liability for */
+/* cost of procurement of substitute goods or services, lost profits, loss */
+/* of use, loss of data or any incidental, consequential, direct, indirect, */
+/* or special damages, whether under contract, tort, warranty or otherwise, */
+/* arising in any way out of use or reliance upon this specification or any */
+/* information herein. */
+/* */
+/* (c) Copyright IBM Corp. and others, 2016 - 2019 */
+/* */
+/********************************************************************************/
+
+/* B.2.3.3. TpmToOsslSupport.c */
+/* B.2.3.3.1. Introduction */
+/* The functions in this file are used for initialization of the interface to the OpenSSL
+ library. */
+/* B.2.3.3.2. Defines and Includes */
+#include "Tpm.h"
+
+#if defined(HASH_LIB_OSSL) || defined(MATH_LIB_OSSL) || defined(SYM_LIB_OSSL)
+
+/* Used to pass the pointers to the correct sub-keys */
+typedef const BYTE *desKeyPointers[3];
+/* B.2.3.3.2.1. SupportLibInit() */
+/* This does any initialization required by the support library. */
+LIB_EXPORT int
+SupportLibInit(
+ void
+ )
+{
+ return TRUE;
+}
+/* B.2.3.3.2.2. OsslContextEnter() */
+/* This function is used to initialize an OpenSSL context at the start of a function that will
+ call to an OpenSSL math function. */
+BN_CTX *
+OsslContextEnter(
+ void
+ )
+{
+ BN_CTX *CTX = BN_CTX_new();
+ return OsslPushContext(CTX);
+}
+/* B.2.3.3.2.3. OsslContextLeave() */
+/* This is the companion function to OsslContextEnter(). */
+void
+OsslContextLeave(
+ BN_CTX *CTX
+ )
+{
+ OsslPopContext(CTX);
+ BN_CTX_free(CTX);
+}
+
+/* B.2.3.3.2.4. OsslPushContext() */
+/* This function is used to create a frame in a context. All values allocated within this context after the frame is started will be automatically freed when the context (OsslPopContext() */
+BN_CTX *
+OsslPushContext(
+ BN_CTX *CTX
+ )
+{
+ if(CTX == NULL)
+ FAIL(FATAL_ERROR_ALLOCATION);
+ BN_CTX_start(CTX);
+ return CTX;
+}
+
+/* B.2.3.3.2.5. OsslPopContext() */
+/* This is the companion function to OsslPushContext(). */
+void
+OsslPopContext(
+ BN_CTX *CTX
+ )
+{
+ // BN_CTX_end can't be called with NULL. It will blow up.
+ if(CTX != NULL)
+ BN_CTX_end(CTX);
+}
+
+#endif // HASH_LIB_OSSL || MATH_LIB_OSSL || SYM_LIB_OSSL
diff --git a/src/tpm2/crypto/openssl/TpmToOsslSupport_fp.h b/src/tpm2/crypto/openssl/TpmToOsslSupport_fp.h
new file mode 100644
index 0000000..c8d7b5a
--- /dev/null
+++ b/src/tpm2/crypto/openssl/TpmToOsslSupport_fp.h
@@ -0,0 +1,83 @@
+/********************************************************************************/
+/* */
+/* Initialization of the Interface to the OpenSSL Library */
+/* Written by Ken Goldman */
+/* IBM Thomas J. Watson Research Center */
+/* $Id: TpmToOsslSupport_fp.h 1476 2019-06-10 19:32:03Z kgoldman $ */
+/* */
+/* Licenses and Notices */
+/* */
+/* 1. Copyright Licenses: */
+/* */
+/* - Trusted Computing Group (TCG) grants to the user of the source code in */
+/* this specification (the "Source Code") a worldwide, irrevocable, */
+/* nonexclusive, royalty free, copyright license to reproduce, create */
+/* derivative works, distribute, display and perform the Source Code and */
+/* derivative works thereof, and to grant others the rights granted herein. */
+/* */
+/* - The TCG grants to the user of the other parts of the specification */
+/* (other than the Source Code) the rights to reproduce, distribute, */
+/* display, and perform the specification solely for the purpose of */
+/* developing products based on such documents. */
+/* */
+/* 2. Source Code Distribution Conditions: */
+/* */
+/* - Redistributions of Source Code must retain the above copyright licenses, */
+/* this list of conditions and the following disclaimers. */
+/* */
+/* - Redistributions in binary form must reproduce the above copyright */
+/* licenses, this list of conditions and the following disclaimers in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* 3. Disclaimers: */
+/* */
+/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
+/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
+/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
+/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
+/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
+/* information on specification licensing rights available through TCG */
+/* membership agreements. */
+/* */
+/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
+/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
+/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
+/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
+/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
+/* */
+/* - Without limitation, TCG and its members and licensors disclaim all */
+/* liability, including liability for infringement of any proprietary */
+/* rights, relating to use of information in this specification and to the */
+/* implementation of this specification, and TCG disclaims all liability for */
+/* cost of procurement of substitute goods or services, lost profits, loss */
+/* of use, loss of data or any incidental, consequential, direct, indirect, */
+/* or special damages, whether under contract, tort, warranty or otherwise, */
+/* arising in any way out of use or reliance upon this specification or any */
+/* information herein. */
+/* */
+/* (c) Copyright IBM Corp. and others, 2016 - 2019 */
+/* */
+/********************************************************************************/
+
+#ifndef TPMTOOSSLSUPPORT_FP_H
+#define TPMTOOSSLSUPPORT_FP_H
+
+BN_CTX *
+OsslContextEnter(
+ void
+ );
+void
+OsslContextLeave(
+ BN_CTX *context
+ );
+BN_CTX *
+OsslPushContext(
+ BN_CTX *CTX
+ );
+void
+OsslPopContext(
+ BN_CTX *CTX
+ );
+
+
+#endif
diff --git a/src/tpm2/crypto/openssl/TpmToOsslSym.h b/src/tpm2/crypto/openssl/TpmToOsslSym.h
new file mode 100644
index 0000000..521204f
--- /dev/null
+++ b/src/tpm2/crypto/openssl/TpmToOsslSym.h
@@ -0,0 +1,197 @@
+/********************************************************************************/
+/* */
+/* Splice the OpenSSL() library into the TPM code. */
+/* Written by Ken Goldman */
+/* IBM Thomas J. Watson Research Center */
+/* $Id: TpmToOsslSym.h 1619 2020-05-19 16:51:47Z kgoldman $ */
+/* */
+/* Licenses and Notices */
+/* */
+/* 1. Copyright Licenses: */
+/* */
+/* - Trusted Computing Group (TCG) grants to the user of the source code in */
+/* this specification (the "Source Code") a worldwide, irrevocable, */
+/* nonexclusive, royalty free, copyright license to reproduce, create */
+/* derivative works, distribute, display and perform the Source Code and */
+/* derivative works thereof, and to grant others the rights granted herein. */
+/* */
+/* - The TCG grants to the user of the other parts of the specification */
+/* (other than the Source Code) the rights to reproduce, distribute, */
+/* display, and perform the specification solely for the purpose of */
+/* developing products based on such documents. */
+/* */
+/* 2. Source Code Distribution Conditions: */
+/* */
+/* - Redistributions of Source Code must retain the above copyright licenses, */
+/* this list of conditions and the following disclaimers. */
+/* */
+/* - Redistributions in binary form must reproduce the above copyright */
+/* licenses, this list of conditions and the following disclaimers in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* 3. Disclaimers: */
+/* */
+/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
+/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
+/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
+/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
+/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
+/* information on specification licensing rights available through TCG */
+/* membership agreements. */
+/* */
+/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
+/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
+/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
+/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
+/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
+/* */
+/* - Without limitation, TCG and its members and licensors disclaim all */
+/* liability, including liability for infringement of any proprietary */
+/* rights, relating to use of information in this specification and to the */
+/* implementation of this specification, and TCG disclaims all liability for */
+/* cost of procurement of substitute goods or services, lost profits, loss */
+/* of use, loss of data or any incidental, consequential, direct, indirect, */
+/* or special damages, whether under contract, tort, warranty or otherwise, */
+/* arising in any way out of use or reliance upon this specification or any */
+/* information herein. */
+/* */
+/* (c) Copyright IBM Corp. and others, 2016 - 2020 */
+/* */
+/********************************************************************************/
+
+/* B.2.3.2. TpmToOsslSym.h */
+/* B.2.3.2.1. Introduction */
+/* This header file is used to splice the OpenSSL() library into the TPM code. */
+/* The support required of a library are a hash module, a block cipher module and portions of a big
+ number library. All of the library-dependent headers should have the same guard to that only the
+ first one gets defined. */
+
+#ifndef SYM_LIB_DEFINED
+#define SYM_LIB_DEFINED
+#define SYM_LIB_OSSL
+#include <openssl/aes.h>
+#if ALG_TDES
+#include <openssl/des.h>
+#endif
+
+#if ALG_SM4
+# if defined(OPENSSL_NO_SM4) || OPENSSL_VERSION_NUMBER < 0x10101010L
+# undef ALG_SM4
+# define ALG_SM4 ALG_NO
+# elif OPENSSL_VERSION_NUMBER >= 0x10200000L
+# include <openssl/sm4.h>
+# else
+// OpenSSL 1.1.1 keeps smX.h headers in the include/crypto directory,
+// and they do not get installed as part of the libssl package
+
+# define SM4_KEY_SCHEDULE 32
+
+typedef struct SM4_KEY_st {
+ uint32_t rk[SM4_KEY_SCHEDULE];
+} SM4_KEY;
+
+int SM4_set_key(const uint8_t *key, SM4_KEY *ks);
+void SM4_encrypt(const uint8_t *in, uint8_t *out, const SM4_KEY *ks);
+void SM4_decrypt(const uint8_t *in, uint8_t *out, const SM4_KEY *ks);
+# endif // OpenSSL < 1.2
+#endif // ALG_SM4
+
+#if ALG_CAMELLIA
+#include <openssl/camellia.h>
+#endif
+#include <openssl/bn.h>
+#include <openssl/ossl_typ.h>
+
+/* B.2.2.3.2. Links to the OpenSSL symmetric algorithms */
+// The Crypt functions that call the block encryption function use the parameters in the order:
+// a) keySchedule
+// b) in buffer
+// c) out buffer Since open SSL uses the order in encryptoCall_t above, need to swizzle the values
+// to the order required by the library.
+
+#define SWIZZLE(keySchedule, in, out) \
+ (const BYTE *)(in), (BYTE *)(out), (void *)(keySchedule)
+
+// Define the order of parameters to the library functions that do block encryption and decryption.
+
+typedef void(*TpmCryptSetSymKeyCall_t)(
+ const BYTE *in,
+ BYTE *out,
+ void *keySchedule
+ );
+
+#define SYM_ALIGNMENT 4 /* libtpms: keep old value */
+
+/* B.2.2.3.3. Links to the OpenSSL AES code */
+/* Macros to set up the encryption/decryption key schedules */
+
+#define TpmCryptSetEncryptKeyAES(key, keySizeInBits, schedule) \
+ AES_set_encrypt_key((key), (keySizeInBits), (tpmKeyScheduleAES *)(schedule))
+#define TpmCryptSetDecryptKeyAES(key, keySizeInBits, schedule) \
+ AES_set_decrypt_key((key), (keySizeInBits), (tpmKeyScheduleAES *)(schedule))
+
+/* Macros to alias encryption calls to specific algorithms. This should be used
+ sparingly. Currently, only used by CryptSym.c and CryptRand.c */
+/* When using these calls, to call the AES block encryption code, the caller should use:
+ TpmCryptEncryptAES(SWIZZLE(keySchedule, in, out)); */
+
+#define TpmCryptEncryptAES AES_encrypt
+#define TpmCryptDecryptAES AES_decrypt
+#define tpmKeyScheduleAES AES_KEY
+
+/* B.2.2.3.4. Links to the OpenSSL DES code */
+
+#if ALG_TDES && 0 // libtpms changed
+#include "TpmToOsslDesSupport_fp.h"
+#endif
+
+#define TpmCryptSetEncryptKeyTDES(key, keySizeInBits, schedule) \
+ TDES_set_encrypt_key((key), (keySizeInBits), (tpmKeyScheduleTDES *)(schedule))
+#define TpmCryptSetDecryptKeyTDES(key, keySizeInBits, schedule) \
+ TDES_set_encrypt_key((key), (keySizeInBits), (tpmKeyScheduleTDES *)(schedule))
+
+/* Macros to alias encryption calls to specific algorithms. This should be used
+ sparingly. Currently, only used by CryptRand.c */
+
+#define TpmCryptEncryptTDES TDES_encrypt
+#define TpmCryptDecryptTDES TDES_decrypt
+#define tpmKeyScheduleTDES DES_key_schedule
+
+#if ALG_TDES // libtpms added begin
+#include "TpmToOsslDesSupport_fp.h"
+#endif // libtpms added end
+
+/* B.2.2.3.5. Links to the OpenSSL SM4 code */
+/* Macros to set up the encryption/decryption key schedules */
+
+#define TpmCryptSetEncryptKeySM4(key, keySizeInBits, schedule) \
+ SM4_set_key((key), (tpmKeyScheduleSM4 *)(schedule))
+#define TpmCryptSetDecryptKeySM4(key, keySizeInBits, schedule) \
+ SM4_set_key((key), (tpmKeyScheduleSM4 *)(schedule))
+/* Macros to alias encryption calls to specific algorithms. This should be used sparingly. */
+
+#define TpmCryptEncryptSM4 SM4_encrypt
+#define TpmCryptDecryptSM4 SM4_decrypt
+#define tpmKeyScheduleSM4 SM4_KEY
+
+/* B.2.2.3.6. Links to the OpenSSL CAMELLIA code */
+/* Macros to set up the encryption/decryption key schedules */
+
+#define TpmCryptSetEncryptKeyCAMELLIA(key, keySizeInBits, schedule) \
+ Camellia_set_key((key), (keySizeInBits), (tpmKeyScheduleCAMELLIA *)(schedule))
+#define TpmCryptSetDecryptKeyCAMELLIA(key, keySizeInBits, schedule) \
+ Camellia_set_key((key), (keySizeInBits), (tpmKeyScheduleCAMELLIA *)(schedule))
+
+/* Macros to alias encryption calls to specific algorithms. This should be used sparingly. */
+
+#define TpmCryptEncryptCAMELLIA Camellia_encrypt
+#define TpmCryptDecryptCAMELLIA Camellia_decrypt
+#define tpmKeyScheduleCAMELLIA CAMELLIA_KEY
+
+/* Forward reference */
+
+// kgold typedef union tpmCryptKeySchedule_t tpmCryptKeySchedule_t;
+
+/* This definition would change if there were something to report */
+#define SymLibSimulationEnd()
+#endif // SYM_LIB_DEFINED
diff --git a/src/tpm2/crypto/openssl/consttime.txt b/src/tpm2/crypto/openssl/consttime.txt
new file mode 100644
index 0000000..6dd8328
--- /dev/null
+++ b/src/tpm2/crypto/openssl/consttime.txt
@@ -0,0 +1,76 @@
+The following (top level) OpenSSL public BIGNUM functions check for
+the BN_FLG_CONSTTIME:
+
+bn_blind.c:
+ BN_BLINDING_new()
+
+bn_exp.c:
+ BN_exp : must not be set for input bignums
+! BN_mod_exp : SHOULD be set for any one of input bignums (only) if m is odd
+ BN_mod_exp_recp: must NOT be set for input bignums
+ BN_mod_exp_mont: SHOULD be set for any one of input bignums
+ BN_mod_exp_mont_word: must NOT be set for input bignums
+ BN_mod_exp_simple: must NOT bet set for input bignums
+
+bn_gcd.c:
+! BN_mod_inverse: SHOULD be set for any one of input bignums
+
+bn_lib:
+ BN_num_bits
+! BN_copy
+
+bn_mont.c:
+ BN_MONT_CTX_set
+
+bn.h:
+! BN_num_bytes: Calls BN_num_bits
+
+
+Relevant files and functions in the files:
+Helpers.c
+ ComputePrivateExponentD:
+ - BN_dup: -> BN_copy: YES, BN_FLG_CONSTTIME set by caller on P and Q
+ - BN_sub: no
+ - BN_add_word: no
+ - BN_mod_inverse: YES, DONE
+ InitOpenSSLRSAPublicKey:
+ - BN_set_word: no
+ - BN_bin2bn: no
+ InitOpenSSLRSAPrivateKey:
+ - BN_bin2bn: no
+ - BN_div: -> BN_copy: YES, DONE
+ - BN_is_zero: no
+
+TpmToOsslMath:
+ OsslToTpmBn:
+ - BN_num_bytes: need not
+ - BN_bn2bin: -> BN_num_bytes: need not
+ BigInitialized:
+ - BN_bin2bn: no
+ - BN_copy: YES, DONE
+ BnModMult:
+ - BN_mul: no
+ - BN_div: -> BN_copy: ?
+ BnMult:
+ - BN_mul: no
+ BnDiv:
+ - BN_div: -> BN_copy: ?
+ BnGcd: /* FUNCTION IS NOT USED */
+ - BN_gcd: -> BN_copy, BN_num_bits: YES, DONE
+ BnModExp:
+ - BN_mod_exp: YES, DONE
+ BnModInverse:
+ - BN_mod_inverse: YES, DONE
+
+
+Elliptic curve signing :
+
+CryptEccMain.c:
+ BnEccGenerateKeyPair:
+ - BnEccModMult: YES, DONE (we have control over random number bnD)
+ called by BnSignEcSchnorr
+ called by BnSignEcdsa (if OpenSSL function not used)
+
+CryptEccSignature.c:
+ BnEccSignSM2:
+ - BnEccModMult: YES, DONE (we have control over random number bnK)
diff --git a/src/tpm2/crypto/openssl/consttime.txt' b/src/tpm2/crypto/openssl/consttime.txt'
new file mode 100644
index 0000000..b667086
--- /dev/null
+++ b/src/tpm2/crypto/openssl/consttime.txt'
@@ -0,0 +1,58 @@
+The following OpenSSL public BIGNUM functions check for the BN_FLG_CONSTTIME:
+
+bn_blind.c:
+ BN_BLINDING_new()
+
+bn_exp.c:
+ BN_exp : must not be set for input bignums
+! BN_mod_exp : SHOULD be set for any one of input bignums (only) if m is odd
+ BN_mod_exp_recp: must NOT be set for input bignums
+ BN_mod_exp_mont: SHOULD be set for any one of input bignums
+ BN_mod_exp_mont_word: must NOT be set for input bignums
+ BN_mod_exp_simple: must NOT bet set for input bignums
+
+bn_gcd.c:
+! BN_mod_inverse: SHOULD be set for any one of input bignums
+
+bn_lib:
+ BN_num_bits
+! BN_copy
+
+bn_mont.c:
+ BN_MONT_CTX_set
+
+bn.h:
+! BN_num_bytes: Calls BN_num_bits
+
+
+Relevant files and functions in the files:
+Helpers.c
+ - BN_dup:
+ - BN_sub:
+ - BN_add_word:
+ - BN_mod_inverse: yes
+ - BN_set_word:
+ - BN_bin2bn:
+ - BN_div:
+ - BN_is_zero:
+
+TpmToOsslMath:
+ OsslToTpmBn:
+ - BN_num_bytes:
+ - BN_bn2bin:
+ BigInitialized:
+ - BN_bin2bn:
+ - BN_copy:
+ BnModMult:
+ - BN_mul:
+ - BN_div:
+ BnMult:
+ - BN_mul:
+ BnDiv:
+ - BN_div:
+ BnGcd:
+ - BN_gcd:
+ BnModExp:
+ - BN_mod_exp: YES
+ BnModInverse:
+ - BN_mod_inverse: YES
diff --git a/src/tpm2/gensymtestsdata.sh b/src/tpm2/gensymtestsdata.sh
new file mode 100755
index 0000000..1c51c2f
--- /dev/null
+++ b/src/tpm2/gensymtestsdata.sh
@@ -0,0 +1,195 @@
+#!/bin/bash
+
+function do_aes() {
+ local data="$1"
+ local osslflag="$2"
+
+ for keysize in 128 192 256; do
+ tmp=AES_KEY_${keysize}
+ key=$(eval echo \$$tmp)
+ for mode in ecb cbc cfb ofb ctr; do
+ cipher="aes-${keysize}-${mode}"
+ bs=$((128 / 8))
+ iv=""
+ ivparm=""
+ case $mode in
+ ecb)
+ ;;
+ ctr)
+ v=255
+ for ((c=0; c < bs; c++)); do
+ iv="$(printf "%02x" $v)${iv}"
+ v=$((v - 1))
+ done
+ ivparm="-iv ${iv}"
+ ;;
+ *)
+ for ((c=0; c < bs; c++)); do
+ iv="${iv}$(printf "%02x" $c)"
+ done
+ ivparm="-iv ${iv}"
+ ;;
+ esac
+ echo -n "$cipher: "
+ openssl enc -e -K "${key}" ${ivparm} -${cipher} -in <(echo -en "$data") ${osslflag} | \
+ od -t x1 -w128 -An | \
+ sed -n 's/ \([a-f0-9]\{2\}\)/ 0x\1/pg'
+ done
+ done
+}
+
+function do_camellia() {
+ local data="$1"
+ local osslflag="$2"
+
+ for keysize in 128 192 256; do
+ tmp=CAMELLIA_KEY_${keysize}
+ key=$(eval echo \$$tmp)
+ for mode in ecb cbc cfb ofb ctr; do
+ cipher="camellia-${keysize}-${mode}"
+ bs=$((128 / 8))
+ iv=""
+ ivparm=""
+ case $mode in
+ ecb)
+ ;;
+ ctr)
+ v=255
+ for ((c=0; c < bs; c++)); do
+ iv="$(printf "%02x" $v)${iv}"
+ v=$((v - 1))
+ done
+ ivparm="-iv ${iv}"
+ ;;
+ *)
+ for ((c=0; c < bs; c++)); do
+ iv="${iv}$(printf "%02x" $c)"
+ done
+ ivparm="-iv ${iv}"
+ ;;
+ esac
+ echo -n "$cipher: "
+ openssl enc -e -K "${key}" ${ivparm} -${cipher} -in <(echo -en "$data") ${osslflag} | \
+ od -t x1 -w128 -An | \
+ sed -n 's/ \([a-f0-9]\{2\}\)/ 0x\1/pg'
+ done
+ done
+}
+
+function do_tdes() {
+ local data="$1"
+ local osslflag="$2"
+
+ for keysize in 128 192; do
+ tmp=TDES_KEY_${keysize}
+ key=$(eval echo \$$tmp)
+ for mode in ecb cbc cfb ofb; do
+ cipher="des-ede3-${mode}"
+ iv=""
+ ivparm=""
+ bs=8
+ case $mode in
+ ecb)
+ ;;
+ *)
+ for ((c=0; c < bs; c++)); do
+ iv="${iv}$(printf "%02x" $c)"
+ done
+ ivparm="-iv ${iv}"
+ ;;
+ esac
+ echo -n "$cipher [${keysize}]: "
+ case $mode in
+ ecb|cbc)
+ if [[ "${osslflag}" =~ "nopad" ]]; then
+ echo " Not supported without padding to blocksize"
+ continue
+ fi
+ ;;
+ esac
+ openssl enc -e -K "${key}" ${ivparm} -${cipher} -in <(echo -en "$data") ${osslflag} | \
+ od -t x1 -w128 -An | \
+ sed -n 's/ \([a-f0-9]\{2\}\)/ 0x\1/pg'
+ done
+ done
+}
+
+function do_sm4() {
+ local data="$1"
+ local osslflag="$2"
+
+ for keysize in 128; do
+ tmp=SM4_KEY_${keysize}
+ key=$(eval echo \$$tmp)
+ for mode in ecb cbc cfb ofb ctr; do
+ cipher="sm4-${mode}"
+ bs=$((128 / 8))
+ iv=""
+ ivparm=""
+ case $mode in
+ ecb)
+ ;;
+ ctr)
+ v=255
+ for ((c=0; c < bs; c++)); do
+ iv="$(printf "%02x" $v)${iv}"
+ v=$((v - 1))
+ done
+ ivparm="-iv ${iv}"
+ ;;
+ *)
+ for ((c=0; c < bs; c++)); do
+ iv="${iv}$(printf "%02x" $c)"
+ done
+ ivparm="-iv ${iv}"
+ ;;
+ esac
+ echo -n "$cipher: "
+ openssl enc -e -K "${key}" ${ivparm} -${cipher} -in <(echo -en "$data") ${osslflag} | \
+ od -t x1 -w128 -An | \
+ sed -n 's/ \([a-f0-9]\{2\}\)/ 0x\1/pg'
+ done
+ done
+}
+
+
+AES_KEY_128='2b7e151628aed2a6abf7158809cf4f3c'
+AES_KEY_192='8e73b0f7da0e6452c810f32b809079e562f8ead2522c6b7b'
+AES_KEY_256='603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4'
+AES_DATA_IN='\x6b\xc1\xbe\xe2\x2e\x40\x9f\x96\xe9\x3d\x7e\x11\x73\x93\x17\x2a\xae\x2d\x8a\x57\x1e\x03\xac\x9c\x9e\xb7\x6f\xac\x45\xaf\x8e\x51'
+
+echo "----- AES -----"
+do_aes "${AES_DATA_IN}" ""
+echo "---------------"
+
+# We need to extend the 128 bit key to be 192 bit key otherwise 3rd schedule is all zeroes
+TDES_KEY_128=${AES_KEY_128}${AES_KEY_128:0:16}
+TDES_KEY_192=${AES_KEY_192}
+TDES_DATA_IN=${AES_DATA_IN}
+
+echo "----- TDES -----"
+do_tdes "${TDES_DATA_IN}" ""
+echo "----------------"
+
+
+echo "---- TDES (short input) -----"
+do_tdes "\x31\x32\x33\x34\x35" "-nopad"
+echo "----------------"
+
+CAMELLIA_KEY_128=${AES_KEY_128}
+CAMELLIA_KEY_192=${AES_KEY_192}
+CAMELLIA_KEY_256=${AES_KEY_256}
+CAMELLIA_DATA_IN=${AES_DATA_IN}
+
+echo "----- CAMELLIA -----"
+do_camellia "${CAMELLIA_DATA_IN}" ""
+echo "--------------------"
+
+if [ -n "$(openssl enc -ciphers | grep sm4)" ]; then
+ SM4_KEY_128='0123456789abcdeffedcba9876543210'
+ SM4_DATA_IN='\xaa\xaa\xaa\xaa\xbb\xbb\xbb\xbb\xcc\xcc\xcc\xcc\xdd\xdd\xdd\xdd\xee\xee\xee\xee\xff\xff\xff\xff\xaa\xaa\xaa\xaa\xbb\xbb\xbb\xbb'
+
+ echo "-------- SM4 -------"
+ do_sm4 "${SM4_DATA_IN}" ""
+ echo "--------------------"
+fi
diff --git a/src/tpm2/swap.h b/src/tpm2/swap.h
new file mode 100644
index 0000000..42a2440
--- /dev/null
+++ b/src/tpm2/swap.h
@@ -0,0 +1,120 @@
+/********************************************************************************/
+/* */
+/* Swap */
+/* Written by Ken Goldman */
+/* IBM Thomas J. Watson Research Center */
+/* $Id: swap.h 1490 2019-07-26 21:13:22Z kgoldman $ */
+/* */
+/* Licenses and Notices */
+/* */
+/* 1. Copyright Licenses: */
+/* */
+/* - Trusted Computing Group (TCG) grants to the user of the source code in */
+/* this specification (the "Source Code") a worldwide, irrevocable, */
+/* nonexclusive, royalty free, copyright license to reproduce, create */
+/* derivative works, distribute, display and perform the Source Code and */
+/* derivative works thereof, and to grant others the rights granted herein. */
+/* */
+/* - The TCG grants to the user of the other parts of the specification */
+/* (other than the Source Code) the rights to reproduce, distribute, */
+/* display, and perform the specification solely for the purpose of */
+/* developing products based on such documents. */
+/* */
+/* 2. Source Code Distribution Conditions: */
+/* */
+/* - Redistributions of Source Code must retain the above copyright licenses, */
+/* this list of conditions and the following disclaimers. */
+/* */
+/* - Redistributions in binary form must reproduce the above copyright */
+/* licenses, this list of conditions and the following disclaimers in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* 3. Disclaimers: */
+/* */
+/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
+/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
+/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
+/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
+/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
+/* information on specification licensing rights available through TCG */
+/* membership agreements. */
+/* */
+/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
+/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
+/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
+/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
+/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
+/* */
+/* - Without limitation, TCG and its members and licensors disclaim all */
+/* liability, including liability for infringement of any proprietary */
+/* rights, relating to use of information in this specification and to the */
+/* implementation of this specification, and TCG disclaims all liability for */
+/* cost of procurement of substitute goods or services, lost profits, loss */
+/* of use, loss of data or any incidental, consequential, direct, indirect, */
+/* or special damages, whether under contract, tort, warranty or otherwise, */
+/* arising in any way out of use or reliance upon this specification or any */
+/* information herein. */
+/* */
+/* (c) Copyright IBM Corp. and others, 2016 - 2018 */
+/* */
+/********************************************************************************/
+
+#ifndef SWAP_H
+#define SWAP_H
+
+#if LITTLE_ENDIAN_TPM
+#define TO_BIG_ENDIAN_UINT16(i) REVERSE_ENDIAN_16(i)
+#define FROM_BIG_ENDIAN_UINT16(i) REVERSE_ENDIAN_16(i)
+#define TO_BIG_ENDIAN_UINT32(i) REVERSE_ENDIAN_32(i)
+#define FROM_BIG_ENDIAN_UINT32(i) REVERSE_ENDIAN_32(i)
+#define TO_BIG_ENDIAN_UINT64(i) REVERSE_ENDIAN_64(i)
+#define FROM_BIG_ENDIAN_UINT64(i) REVERSE_ENDIAN_64(i)
+#else
+#define TO_BIG_ENDIAN_UINT16(i) (i)
+#define FROM_BIG_ENDIAN_UINT16(i) (i)
+#define TO_BIG_ENDIAN_UINT32(i) (i)
+#define FROM_BIG_ENDIAN_UINT32(i) (i)
+#define TO_BIG_ENDIAN_UINT64(i) (i)
+#define FROM_BIG_ENDIAN_UINT64(i) (i)
+#endif
+#if AUTO_ALIGN == NO
+/* The aggregation macros for machines that do not allow unaligned access or for little-endian
+ machines. Aggregate bytes into an UINT */
+#define BYTE_ARRAY_TO_UINT8(b) (uint8_t)((b)[0])
+#define BYTE_ARRAY_TO_UINT16(b) ByteArrayToUint16((BYTE *)(b))
+#define BYTE_ARRAY_TO_UINT32(b) ByteArrayToUint32((BYTE *)(b))
+#define BYTE_ARRAY_TO_UINT64(b) ByteArrayToUint64((BYTE *)(b))
+#define UINT8_TO_BYTE_ARRAY(i, b) ((b)[0] = (uint8_t)(i))
+#define UINT16_TO_BYTE_ARRAY(i, b) Uint16ToByteArray((i), (BYTE *)(b))
+#define UINT32_TO_BYTE_ARRAY(i, b) Uint32ToByteArray((i), (BYTE *)(b))
+#define UINT64_TO_BYTE_ARRAY(i, b) Uint64ToByteArray((i), (BYTE *)(b))
+#else // AUTO_ALIGN
+#if BIG_ENDIAN_TPM
+/* The big-endian macros for machines that allow unaligned memory access Aggregate a byte
+ array into a UINT */
+#define BYTE_ARRAY_TO_UINT8(b) *((uint8_t *)(b))
+#define BYTE_ARRAY_TO_UINT16(b) *((uint16_t *)(b))
+#define BYTE_ARRAY_TO_UINT32(b) *((uint32_t *)(b))
+#define BYTE_ARRAY_TO_UINT64(b) *((uint64_t *)(b))
+/* Disaggregate a UINT into a byte array */
+#define UINT8_TO_BYTE_ARRAY(i, b) {*((uint8_t *)(b)) = (i);}
+#define UINT16_TO_BYTE_ARRAY(i, b) {*((uint16_t *)(b)) = (i);}
+#define UINT32_TO_BYTE_ARRAY(i, b) {*((uint32_t *)(b)) = (i);}
+#define UINT64_TO_BYTE_ARRAY(i, b) {*((uint64_t *)(b)) = (i);}
+#else
+/* the little endian macros for machines that allow unaligned memory access the big-endian macros
+ for machines that allow unaligned memory access Aggregate a byte array into a UINT */
+#define BYTE_ARRAY_TO_UINT8(b) *((uint8_t *)(b))
+#define BYTE_ARRAY_TO_UINT16(b) REVERSE_ENDIAN_16(*((uint16_t *)(b)))
+#define BYTE_ARRAY_TO_UINT32(b) REVERSE_ENDIAN_32(*((uint32_t *)(b)))
+#define BYTE_ARRAY_TO_UINT64(b) REVERSE_ENDIAN_64(*((uint64_t *)(b)))
+/* Disaggregate a UINT into a byte array */
+#define UINT8_TO_BYTE_ARRAY(i, b) {*((uint8_t *)(b)) = (i);}
+#define UINT16_TO_BYTE_ARRAY(i, b) {*((uint16_t *)(b)) = REVERSE_ENDIAN_16(i);}
+#define UINT32_TO_BYTE_ARRAY(i, b) {*((uint32_t *)(b)) = REVERSE_ENDIAN_32(i);}
+#define UINT64_TO_BYTE_ARRAY(i, b) {*((uint64_t *)(b)) = REVERSE_ENDIAN_64(i);}
+#endif // BIG_ENDIAN_TPM
+#endif // AUTO_ALIGN == NO
+
+
+#endif