diff --git a/configure.ac b/configure.ac index a79dbde7..a95434ff 100644 --- a/configure.ac +++ b/configure.ac @@ -162,8 +162,9 @@ if $LD --help 2>&1 | $GREP '\-z now ' > /dev/null; then fi AC_SUBST([HARDENING_CFLAGS]) +dnl FIXME: removed -Werror if test "$test_CFLAGS" != set; then - CFLAGS="$CFLAGS -Wall -Werror -Wreturn-type -Wsign-compare" + CFLAGS="$CFLAGS -Wall -Wreturn-type -Wsign-compare" fi AC_CONFIG_FILES(Makefile \ diff --git a/src/Makefile.am b/src/Makefile.am index 275e59a4..e69ed935 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -6,6 +6,10 @@ lib_LTLIBRARIES=libtpms.la +common_CFLAGS = -include tpm_library_conf.h \ + -I$(top_srcdir)/include/libtpms \ + $(HARDENING_CFLAGS) + # # TPM1.2 # @@ -16,9 +20,7 @@ libtpms_la_LIBADD = libtpms_tpm12.la libtpms_tpm12_la_LIBADD = -libtpms_tpm12_la_CFLAGS = -include tpm_library_conf.h \ - -I$(top_srcdir)/include/libtpms \ - $(HARDENING_CFLAGS) +libtpms_tpm12_la_CFLAGS = $(common_CFLAGS) #Build 1.2 TPM libtpms_tpm12_la_CFLAGS += -DTPM_V12 @@ -154,6 +156,353 @@ endif # LIBTPMS_USE_OPENSSL endif # LIBTPMS_USE_FREEBL +# TPM2 +# + +noinst_LTLIBRARIES += libtpms_tpm2.la + +libtpms_la_LIBADD += libtpms_tpm2.la + +libtpms_tpm2_la_LIBADD = + +libtpms_tpm2_la_LDFLAGS = -Wl,--version-script=./libtpms.syms \ + -version-info $(LIBTPMS_VERSION_INFO) \ + -no-undefined + +libtpms_tpm2_la_CFLAGS = $(common_CFLAGS) \ + -Wstrict-aliasing=3 + +libtpms_tpm2_la_CFLAGS += -D_POSIX_ +libtpms_tpm2_la_CFLAGS += -DTPM_POSIX + +libtpms_tpm2_la_SOURCES = \ + tpm2/AlgorithmCap.c \ + tpm2/AlgorithmTests.c \ + tpm2/AsymmetricCommands.c \ + tpm2/AttestationCommands.c \ + tpm2/Attest_spt.c \ + tpm2/AuditCommands.c \ + tpm2/Bits.c \ + tpm2/BnConvert.c \ + tpm2/BnEccData.c \ + tpm2/BnMath.c \ + tpm2/BnMemory.c \ + tpm2/Cancel.c \ + tpm2/CapabilityCommands.c \ + tpm2/Clock.c \ + tpm2/ClockCommands.c \ + tpm2/CommandAudit.c \ + tpm2/CommandCodeAttributes.c \ + tpm2/CommandDispatcher.c \ + tpm2/ContextCommands.c \ + tpm2/Context_spt.c \ + tpm2/CryptSelfTest.c \ + tpm2/CryptUtil.c \ + tpm2/DA.c \ + tpm2/DictionaryCommands.c \ + tpm2/DuplicationCommands.c \ + tpm2/EACommands.c \ + tpm2/EncryptDecrypt_spt.c \ + tpm2/Entity.c \ + tpm2/Entropy.c \ + tpm2/EphemeralCommands.c \ + tpm2/ExecCommand.c \ + tpm2/Global.c \ + tpm2/Handle.c \ + tpm2/HashCommands.c \ + tpm2/Hierarchy.c \ + tpm2/HierarchyCommands.c \ + tpm2/IntegrityCommands.c \ + tpm2/IoBuffers.c \ + tpm2/Locality.c \ + tpm2/LocalityPlat.c \ + tpm2/ManagementCommands.c \ + tpm2/Manufacture.c \ + tpm2/Marshal.c \ + tpm2/MathOnByteBuffers.c \ + tpm2/Memory.c \ + tpm2/NVCommands.c \ + tpm2/NVDynamic.c \ + tpm2/NVMem.c \ + tpm2/NVReserved.c \ + tpm2/NV_spt.c \ + tpm2/Object.c \ + tpm2/ObjectCommands.c \ + tpm2/Object_spt.c \ + tpm2/PCR.c \ + tpm2/PlatformData.c \ + tpm2/Policy_spt.c \ + tpm2/Power.c \ + tpm2/PowerPlat.c \ + tpm2/PP.c \ + tpm2/PPPlat.c \ + tpm2/PrimeData.c \ + tpm2/PropertyCap.c \ + tpm2/RandomCommands.c \ + tpm2/Response.c \ + tpm2/ResponseCodeProcessing.c \ + tpm2/RunCommand.c \ + tpm2/Session.c \ + tpm2/SessionCommands.c \ + tpm2/SessionProcess.c \ + tpm2/SigningCommands.c \ + tpm2/StartupCommands.c \ + tpm2/SymmetricCommands.c \ + tpm2/TestingCommands.c \ + tpm2/Ticket.c \ + tpm2/Time.c \ + tpm2/TpmSizeChecks.c \ + tpm2/TPMCmdp.c \ + tpm2/TpmFail.c \ + tpm2/Unique.c \ + tpm2/Unmarshal.c \ + tpm2/Vendor_TCG_Test.c + +noinst_HEADERS += \ + tpm2/crypto/CryptDes_fp.h \ + tpm2/crypto/CryptEcc.h \ + tpm2/crypto/CryptEccKeyExchange_fp.h \ + tpm2/crypto/CryptEccMain_fp.h \ + tpm2/crypto/CryptEccSignature_fp.h \ + tpm2/crypto/CryptHashData.h \ + tpm2/crypto/CryptHash_fp.h \ + tpm2/crypto/CryptHash.h \ + tpm2/crypto/CryptPrime_fp.h \ + tpm2/crypto/CryptPrimeSieve_fp.h \ + tpm2/crypto/CryptRand_fp.h \ + tpm2/crypto/CryptRand.h \ + tpm2/crypto/CryptRsa_fp.h \ + tpm2/crypto/CryptRsa.h \ + tpm2/crypto/CryptSelfTest_fp.h \ + tpm2/crypto/CryptSym_fp.h \ + tpm2/crypto/CryptTest.h \ + tpm2/crypto/CryptUtil_fp.h \ + tpm2/ActivateCredential_fp.h \ + tpm2/AlgorithmCap_fp.h \ + tpm2/AlgorithmTests_fp.h \ + tpm2/Attest_spt_fp.h \ + tpm2/BaseTypes.h \ + tpm2/Bits_fp.h \ + tpm2/Capabilities.h \ + tpm2/CertifyCreation_fp.h \ + tpm2/Certify_fp.h \ + tpm2/ChangeEPS_fp.h \ + tpm2/ChangePPS_fp.h \ + tpm2/ClearControl_fp.h \ + tpm2/Clear_fp.h \ + tpm2/ClockRateAdjust_fp.h \ + tpm2/ClockSet_fp.h \ + tpm2/CommandAttributeData.h \ + tpm2/CommandAttributes.h \ + tpm2/CommandAudit_fp.h \ + tpm2/CommandCodeAttributes_fp.h \ + tpm2/CommandDispatchData.h \ + tpm2/CommandDispatcher_fp.h \ + tpm2/Commit_fp.h \ + tpm2/CompilerDependencies.h \ + tpm2/ContextLoad_fp.h \ + tpm2/ContextSave_fp.h \ + tpm2/Context_spt_fp.h \ + tpm2/Create_fp.h \ + tpm2/CreateLoaded_fp.h \ + tpm2/CreatePrimary_fp.h \ + tpm2/CryptSelfTest_fp.h \ + tpm2/CryptUtil_fp.h \ + tpm2/DA_fp.h \ + tpm2/DictionaryAttackLockReset_fp.h \ + tpm2/DictionaryAttackParameters_fp.h \ + tpm2/Duplicate_fp.h \ + tpm2/EccTestData.h \ + tpm2/ECC_Parameters_fp.h \ + tpm2/ECDH_KeyGen_fp.h \ + tpm2/ECDH_ZGen_fp.h \ + tpm2/EC_Ephemeral_fp.h \ + tpm2/EncryptDecrypt2_fp.h \ + tpm2/EncryptDecrypt_fp.h \ + tpm2/EncryptDecrypt_spt.h \ + tpm2/EncryptDecrypt_spt_fp.h \ + tpm2/Entity_fp.h \ + tpm2/EventSequenceComplete_fp.h \ + tpm2/EvictControl_fp.h \ + tpm2/ExecCommand_fp.h \ + tpm2/FlushContext_fp.h \ + tpm2/GetCapability_fp.h \ + tpm2/GetCommandAuditDigest_fp.h \ + tpm2/GetRandom_fp.h \ + tpm2/GetSessionAuditDigest_fp.h \ + tpm2/GetTestResult_fp.h \ + tpm2/GetTime_fp.h \ + tpm2/Global.h \ + tpm2/GpMacros.h \ + tpm2/Handle_fp.h \ + tpm2/Hash_fp.h \ + tpm2/HashSequenceStart_fp.h \ + tpm2/HashTestData.h \ + tpm2/HierarchyChangeAuth_fp.h \ + tpm2/HierarchyControl_fp.h \ + tpm2/Hierarchy_fp.h \ + tpm2/HMAC_fp.h \ + tpm2/HMAC_Start_fp.h \ + tpm2/Implementation.h \ + tpm2/Import_fp.h \ + tpm2/IncrementalSelfTest_fp.h \ + tpm2/InternalRoutines.h \ + tpm2/IoBuffers_fp.h \ + tpm2/LoadExternal_fp.h \ + tpm2/Load_fp.h \ + tpm2/Locality_fp.h \ + tpm2/MakeCredential_fp.h \ + tpm2/Manufacture_fp.h \ + tpm2/Marshal_fp.h \ + tpm2/MathOnByteBuffers_fp.h \ + tpm2/Memory_fp.h \ + tpm2/NV_Certify_fp.h \ + tpm2/NV_ChangeAuth_fp.h \ + tpm2/NV_DefineSpace_fp.h \ + tpm2/NVDynamic_fp.h \ + tpm2/NV_Extend_fp.h \ + tpm2/NV_GlobalWriteLock_fp.h \ + tpm2/NV.h \ + tpm2/NV_Increment_fp.h \ + tpm2/NV_Read_fp.h \ + tpm2/NV_ReadLock_fp.h \ + tpm2/NV_ReadPublic_fp.h \ + tpm2/NVReserved_fp.h \ + tpm2/NV_SetBits_fp.h \ + tpm2/NV_spt_fp.h \ + tpm2/NV_UndefineSpace_fp.h \ + tpm2/NV_UndefineSpaceSpecial_fp.h \ + tpm2/NV_Write_fp.h \ + tpm2/NV_WriteLock_fp.h \ + tpm2/ObjectChangeAuth_fp.h \ + tpm2/Object_fp.h \ + tpm2/Object_spt_fp.h \ + tpm2/PCR_Allocate_fp.h \ + tpm2/PCR_Event_fp.h \ + tpm2/PCR_Extend_fp.h \ + tpm2/PCR_fp.h \ + tpm2/PCR_Read_fp.h \ + tpm2/PCR_Reset_fp.h \ + tpm2/PCR_SetAuthPolicy_fp.h \ + tpm2/PCR_SetAuthValue_fp.h \ + tpm2/PlatformData.h \ + tpm2/Platform_fp.h \ + tpm2/PolicyAuthorize_fp.h \ + tpm2/PolicyAuthorizeNV_fp.h \ + tpm2/PolicyAuthValue_fp.h \ + tpm2/PolicyCommandCode_fp.h \ + tpm2/PolicyCounterTimer_fp.h \ + tpm2/PolicyCpHash_fp.h \ + tpm2/PolicyDuplicationSelect_fp.h \ + tpm2/PolicyGetDigest_fp.h \ + tpm2/PolicyLocality_fp.h \ + tpm2/PolicyNameHash_fp.h \ + tpm2/PolicyNV_fp.h \ + tpm2/PolicyNvWritten_fp.h \ + tpm2/PolicyOR_fp.h \ + tpm2/PolicyPassword_fp.h \ + tpm2/PolicyPCR_fp.h \ + tpm2/PolicyPhysicalPresence_fp.h \ + tpm2/PolicyRestart_fp.h \ + tpm2/PolicySecret_fp.h \ + tpm2/PolicySigned_fp.h \ + tpm2/Policy_spt_fp.h \ + tpm2/PolicyTemplate_fp.h \ + tpm2/PolicyTicket_fp.h \ + tpm2/Power_fp.h \ + tpm2/PP_Commands_fp.h \ + tpm2/PP_fp.h \ + tpm2/PRNG_TestVectors.h \ + tpm2/PropertyCap_fp.h \ + tpm2/Quote_fp.h \ + tpm2/ReadClock_fp.h \ + tpm2/ReadPublic_fp.h \ + tpm2/ResponseCodeProcessing_fp.h \ + tpm2/Response_fp.h \ + tpm2/Rewrap_fp.h \ + tpm2/RsaTestData.h \ + tpm2/RSA_Decrypt_fp.h \ + tpm2/RSA_Encrypt_fp.h \ + tpm2/SelfTest.h \ + tpm2/SelfTest_fp.h \ + tpm2/SequenceComplete_fp.h \ + tpm2/SequenceUpdate_fp.h \ + tpm2/Session_fp.h \ + tpm2/SessionProcess_fp.h \ + tpm2/SetAlgorithmSet_fp.h \ + tpm2/SetCommandCodeAuditStatus_fp.h \ + tpm2/SetPrimaryPolicy_fp.h \ + tpm2/Shutdown_fp.h \ + tpm2/Sign_fp.h \ + tpm2/Simulator_fp.h \ + tpm2/StartAuthSession_fp.h \ + tpm2/Startup_fp.h \ + tpm2/StirRandom_fp.h \ + tpm2/SupportLibraryFunctionPrototypes_fp.h \ + tpm2/SymmetricTest.h \ + tpm2/SymmetricTestData.h \ + tpm2/swap.h \ + tpm2/TcpServerPosix_fp.h \ + tpm2/TestParms_fp.h \ + tpm2/Ticket_fp.h \ + tpm2/Time_fp.h \ + tpm2/TPMB.h \ + tpm2/TpmBuildSwitches.h \ + tpm2/TpmError.h \ + tpm2/TpmFail_fp.h \ + tpm2/Tpm.h \ + tpm2/_TPM_Hash_Data_fp.h \ + tpm2/_TPM_Hash_End_fp.h \ + tpm2/_TPM_Hash_Start_fp.h \ + tpm2/_TPM_Init_fp.h \ + tpm2/TpmSizeChecks_fp.h \ + tpm2/TpmTcpProtocol.h \ + tpm2/TpmTypes.h \ + tpm2/Unmarshal_fp.h \ + tpm2/Unseal_fp.h \ + tpm2/VendorString.h \ + tpm2/Vendor_TCG_Test_fp.h \ + tpm2/VerifySignature_fp.h \ + tpm2/ZGen_2Phase_fp.h + +if LIBTPMS_USE_OPENSSL + +libtpms_tpm2_la_SOURCES += \ + tpm2/crypto/openssl/CryptDes.c \ + tpm2/crypto/openssl/CryptEccKeyExchange.c \ + tpm2/crypto/openssl/CryptEccMain.c \ + tpm2/crypto/openssl/CryptEccSignature.c \ + tpm2/crypto/openssl/CryptHash.c \ + tpm2/crypto/openssl/CryptHashData.c \ + tpm2/crypto/openssl/CryptPrime.c \ + tpm2/crypto/openssl/CryptPrimeSieve.c \ + tpm2/crypto/openssl/CryptRand.c \ + tpm2/crypto/openssl/CryptRsa.c \ + tpm2/crypto/openssl/CryptSym.c \ + tpm2/crypto/openssl/TpmToOsslDesSupport.c \ + tpm2/crypto/openssl/TpmToOsslMath.c \ + tpm2/crypto/openssl/TpmToOsslSupport.c + +noinst_HEADERS += \ + tpm2/crypto/openssl/BnConvert_fp.h \ + tpm2/crypto/openssl/BnMath_fp.h \ + tpm2/crypto/openssl/BnMemory_fp.h \ + tpm2/crypto/openssl/BnValues.h \ + tpm2/crypto/openssl/LibSupport.h \ + tpm2/crypto/openssl/TpmToOsslDesSupport_fp.h \ + tpm2/crypto/openssl/TpmToOsslHash.h \ + tpm2/crypto/openssl/TpmToOsslMath_fp.h \ + tpm2/crypto/openssl/TpmToOsslMath.h \ + tpm2/crypto/openssl/TpmToOsslSupport_fp.h \ + tpm2/crypto/openssl/TpmToOsslSym.h + +libtpms_tpm2_la_CFLAGS += \ + -I tpm2 \ + -I tpm2/crypto \ + -I tpm2/crypto/openssl + +endif # LIBTPMS_USE_OPENSSL + # # Library API layer # @@ -161,8 +510,7 @@ endif # LIBTPMS_USE_FREEBL libtpms_la_SOURCES = \ tpm_library.c -libtpms_la_CFLAGS = \ - $(libtpms_tpm12_la_CFLAGS) +libtpms_la_CFLAGS = $(common_CFLAGS) libtpms_la_LDFLAGS = -Wl,--version-script=$(srcdir)/libtpms.syms \ -version-info $(LIBTPMS_VERSION_INFO) \ diff --git a/src/tpm2/ActivateCredential_fp.h b/src/tpm2/ActivateCredential_fp.h new file mode 100644 index 00000000..841d1178 --- /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 00000000..2fb7aee4 --- /dev/null +++ b/src/tpm2/AlgorithmCap.c @@ -0,0 +1,236 @@ +/********************************************************************************/ +/* */ +/* */ +/* Written by Ken Goldman */ +/* IBM Thomas J. Watson Research Center */ +/* $Id: AlgorithmCap.c 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 */ +/* */ +/********************************************************************************/ + +/* 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 +#ifdef TPM_ALG_RSA + {TPM_ALG_RSA, {1, 0, 0, 1, 0, 0, 0, 0, 0}}, +#endif +#ifdef TPM_ALG_TDES + {TPM_ALG_TDES, {0, 1, 0, 0, 0, 0, 0, 0, 0}}, +#endif +#ifdef TPM_ALG_SHA1 + {TPM_ALG_SHA1, {0, 0, 1, 0, 0, 0, 0, 0, 0}}, +#endif + {TPM_ALG_HMAC, {0, 0, 1, 0, 0, 1, 0, 0, 0}}, +#ifdef TPM_ALG_AES + {TPM_ALG_AES, {0, 1, 0, 0, 0, 0, 0, 0, 0}}, +#endif +#ifdef TPM_ALG_MGF1 + {TPM_ALG_MGF1, {0, 0, 1, 0, 0, 0, 0, 1, 0}}, +#endif + {TPM_ALG_KEYEDHASH, {0, 0, 1, 1, 0, 1, 1, 0, 0}}, +#ifdef TPM_ALG_XOR + {TPM_ALG_XOR, {0, 1, 1, 0, 0, 0, 0, 0, 0}}, +#endif +#ifdef TPM_ALG_SHA256 + {TPM_ALG_SHA256, {0, 0, 1, 0, 0, 0, 0, 0, 0}}, +#endif +#ifdef TPM_ALG_SHA384 + {TPM_ALG_SHA384, {0, 0, 1, 0, 0, 0, 0, 0, 0}}, +#endif +#ifdef TPM_ALG_SHA512 + {TPM_ALG_SHA512, {0, 0, 1, 0, 0, 0, 0, 0, 0}}, +#endif +#ifdef TPM_ALG_SM3_256 + {TPM_ALG_SM3_256, {0, 0, 1, 0, 0, 0, 0, 0, 0}}, +#endif +#ifdef TPM_ALG_SM4 + {TPM_ALG_SM4, {0, 1, 0, 0, 0, 0, 0, 0, 0}}, +#endif +#ifdef TPM_ALG_RSASSA + {TPM_ALG_RSASSA, {1, 0, 0, 0, 0, 1, 0, 0, 0}}, +#endif +#ifdef TPM_ALG_RSAES + {TPM_ALG_RSAES, {1, 0, 0, 0, 0, 0, 1, 0, 0}}, +#endif +#ifdef TPM_ALG_RSAPSS + {TPM_ALG_RSAPSS, {1, 0, 0, 0, 0, 1, 0, 0, 0}}, +#endif +#ifdef TPM_ALG_OAEP + {TPM_ALG_OAEP, {1, 0, 0, 0, 0, 0, 1, 0, 0}}, +#endif +#ifdef TPM_ALG_ECDSA + {TPM_ALG_ECDSA, {1, 0, 0, 0, 0, 1, 0, 1, 0}}, +#endif +#ifdef TPM_ALG_ECDH + {TPM_ALG_ECDH, {1, 0, 0, 0, 0, 0, 0, 1, 0}}, +#endif +#ifdef TPM_ALG_ECDAA + {TPM_ALG_ECDAA, {1, 0, 0, 0, 0, 1, 0, 0, 0}}, +#endif +#ifdef TPM_ALG_SM2 + {TPM_ALG_SM2, {1, 0, 0, 0, 0, 1, 0, 1, 0}}, +#endif +#ifdef TPM_ALG_ECSCHNORR + {TPM_ALG_ECSCHNORR, {1, 0, 0, 0, 0, 1, 0, 0, 0}}, +#endif +#ifdef TPM_ALG_ECMQV + {TPM_ALG_ECMQV, {1, 0, 0, 0, 0, 0, 0, 1, 0}}, +#endif +#ifdef TPM_ALG_KDF1_SP800_56A + {TPM_ALG_KDF1_SP800_56A,{0, 0, 1, 0, 0, 0, 0, 1, 0}}, +#endif +#ifdef TPM_ALG_KDF2 + {TPM_ALG_KDF2, {0, 0, 1, 0, 0, 0, 0, 1, 0}}, +#endif +#ifdef TPM_ALG_KDF1_SP800_108 + {TPM_ALG_KDF1_SP800_108,{0, 0, 1, 0, 0, 0, 0, 1, 0}}, +#endif +#ifdef TPM_ALG_ECC + {TPM_ALG_ECC, {1, 0, 0, 1, 0, 0, 0, 0, 0}}, +#endif + {TPM_ALG_SYMCIPHER, {0, 0, 0, 1, 0, 0, 0, 0, 0}}, +#ifdef TPM_ALG_CAMELLIA + {TPM_ALG_CAMELLIA, {0, 1, 0, 0, 0, 0, 0, 0, 0}}, +#endif +#ifdef TPM_ALG_CTR + {TPM_ALG_CTR, {0, 1, 0, 0, 0, 0, 1, 0, 0}}, +#endif +#ifdef TPM_ALG_OFB + {TPM_ALG_OFB, {0, 1, 0, 0, 0, 0, 1, 0, 0}}, +#endif +#ifdef TPM_ALG_CBC + {TPM_ALG_CBC, {0, 1, 0, 0, 0, 0, 1, 0, 0}}, +#endif +#ifdef TPM_ALG_CFB + {TPM_ALG_CFB, {0, 1, 0, 0, 0, 0, 1, 0, 0}}, +#endif +#ifdef TPM_ALG_ECB + {TPM_ALG_ECB, {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; +} +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)); + 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 00000000..802ff627 --- /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 827 2016-11-18 20:45: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 */ +/* */ +/********************************************************************************/ + +#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 00000000..72298d29 --- /dev/null +++ b/src/tpm2/AlgorithmTests.c @@ -0,0 +1,930 @@ +/********************************************************************************/ +/* */ +/* Code to perform the various self-test functions. */ +/* Written by Ken Goldman */ +/* IBM Thomas J. Watson Research Center */ +/* $Id: AlgorithmTests.c 953 2017-03-06 20:31: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, 2017 */ +/* */ +/********************************************************************************/ + +/* 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 +#ifdef 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" +#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 + UINT16 digestSize; + const TPM2B *testDigest = NULL; + HMAC_STATE state; + // TPM2B_TYPE(HMAC_BLOCK, DEFAULT_TEST_HASH_BLOCK_SIZE); + pAssert(hashAlg != TPM_ALG_NULL); + switch(hashAlg) + { +#if ALG_SHA1 + case ALG_SHA1_VALUE: + testDigest = &c_SHA1_digest.b; + break; +#endif +#if ALG_SHA256 + case ALG_SHA256_VALUE: + testDigest = &c_SHA256_digest.b; + break; +#endif +#if ALG_SHA384 + case ALG_SHA384_VALUE: + testDigest = &c_SHA384_digest.b; + break; +#endif +#if ALG_SHA512 + case ALG_SHA512_VALUE: + testDigest = &c_SHA512_digest.b; + break; +#endif +#if ALG_SM3_256 + case ALG_SM3_256_VALUE: + testDigest = &c_SM3_256_digest.b; + break; +#endif + default: + FAIL(FATAL_ERROR_INTERNAL); + } + // Clear the to-test bits + CLEAR_BOTH(hashAlg); + // 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)) { + FAIL(FATAL_ERROR_SELF_TEST); + // kgold SELF_TEST_FAILURE; + } + return TPM_RC_SUCCESS; +} +/* 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 == ALG_ECB_VALUE) + return 0; + if(mode == ALG_CTR_VALUE) + { + // 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; + // + // 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 - ALG_CTR_VALUE], + test->dataInOutSize)) { + FAIL(FATAL_ERROR_SELF_TEST); + // kgold 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 - ALG_CTR_VALUE]); + // Make sure that it matches what we started with + if(!MemoryEqual(decrypted, test->dataIn, test->dataInOutSize)) { + FAIL(FATAL_ERROR_SELF_TEST); + // kgold 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 */ +static BOOL +AllSymsAreDone( + ALGORITHM_VECTOR *toTest + ) +{ + return (!TEST_BOTH(ALG_AES_VALUE) && !TEST_BOTH(ALG_SM4_VALUE)); +} +/* 10.2.1.4.4 AllModesAreDone() */ +/* Checks if all the modes have been tested */ +static BOOL +AllModesAreDone( + ALGORITHM_VECTOR *toTest + ) +{ + TPM_ALG_ID alg; + for(alg = TPM_SYM_MODE_FIRST; alg <= TPM_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 == ALG_AES_VALUE || alg == ALG_SM4_VALUE || alg == ALG_CAMELLIA_VALUE) + { + // 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 = TPM_SYM_MODE_FIRST; + mode <= TPM_SYM_MODE_LAST; + mode++) + { + if(TEST_BIT(mode, *toTest)) + 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 = TPM_SYM_MODE_FIRST; alg <= TPM_SYM_MODE_LAST; alg++) + CLEAR_BOTH(alg); + } + } + else if(TPM_SYM_MODE_FIRST <= alg && alg <= TPM_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(ALG_AES_VALUE, *toTest) + && !TEST_BIT(ALG_SM4_VALUE, *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(ALG_AES_VALUE); + CLEAR_BOTH(ALG_SM4_VALUE); + } + } + else + pAssert(alg == 0 && alg != 0); + return TPM_RC_SUCCESS; +} +/* 10.2.1.5 RSA Tests */ +#ifdef TPM_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 + _cpri_ValidateSignatureRSA(). 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 test are for an 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; + const TPM2B_RSA_TEST_KEY *kvtValue = &c_RsaesKvt; + TPM_RC result = TPM_RC_SUCCESS; + const TPM2B *testLabel = NULL; + OBJECT testObject; + 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(ALG_NULL_VALUE); + 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)) { + FAIL(FATAL_ERROR_SELF_TEST); + // kgold SELF_TEST_FAILURE; + } + if(!MemoryEqual(testOutput.t.buffer, c_RsaepKvt.buffer, c_RsaepKvt.size)) { + FAIL(FATAL_ERROR_SELF_TEST); + // kgold SELF_TEST_FAILURE; + } + MemoryCopy2B(&testInput.b, &testOutput.b, sizeof(testInput.t.buffer)); + if(TPM_RC_SUCCESS != CryptRsaDecrypt(&testOutput.b, &testInput.b, + &testObject, &rsaScheme, NULL)) { + FAIL(FATAL_ERROR_SELF_TEST); + // kgold SELF_TEST_FAILURE; + } + if(!MemoryEqual(testOutput.t.buffer, c_RsaTestValue, + sizeof(c_RsaTestValue))) { + FAIL(FATAL_ERROR_SELF_TEST); + // kgold SELF_TEST_FAILURE; + } + } + else + { + // ALG_RSAES_VALUE: + // 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 + // ALG_OAEP_VALUE: + // 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 == ALG_OAEP_VALUE) + { + TEST_DEFAULT_TEST_HASH(toTest); + kvtValue = &c_OaepKvt; + testLabel = OAEP_TEST_STRING; + } + else if(scheme == ALG_RSAES_VALUE) + { + kvtValue = &c_RsaesKvt; + testLabel = NULL; + } + else { + FAIL(FATAL_ERROR_SELF_TEST); + // kgold 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)) { + FAIL(FATAL_ERROR_SELF_TEST); + // kgold 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)) { + FAIL(FATAL_ERROR_SELF_TEST); + // kgold 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)) { + FAIL(FATAL_ERROR_SELF_TEST); + // kgold 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)) { + FAIL(FATAL_ERROR_SELF_TEST); + // kgold SELF_TEST_FAILURE; + } + if(testOutput.t.size != DEFAULT_TEST_DIGEST_SIZE + || !MemoryEqual(testOutput.t.buffer, c_RsaTestValue, + DEFAULT_TEST_DIGEST_SIZE)) { + FAIL(FATAL_ERROR_SELF_TEST); + // kgold 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(ALG_NULL_VALUE); + CLEAR_BOTH(ALG_RSA_VALUE); + 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)) { + FAIL(FATAL_ERROR_SELF_TEST); + // kgold SELF_TEST_FAILURE; + } + // For RSASSA, make sure the results is what we are looking for + if(testSig.sigAlg == ALG_RSASSA_VALUE) + { + 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)) { + FAIL(FATAL_ERROR_SELF_TEST); + // kgold SELF_TEST_FAILURE; + } + } + // See if the TPM will validate its own signatures + if(TPM_RC_SUCCESS != CryptRsaValidateSignature(&testSig, &testObject, + &testDigest)) { + FAIL(FATAL_ERROR_SELF_TEST); + // SELF_TEST_FAILURE; + } + // If this is RSAPSS, check the verification with known signature + // Have to copy because CrytpRsaValidateSignature() eats the signature + if(ALG_RSAPSS_VALUE == 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)) { + FAIL(FATAL_ERROR_SELF_TEST); + // kgold 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 ALG_NULL_VALUE: + // 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(ALG_RSASSA_VALUE, *toTest) + && !TEST_BIT(ALG_RSAES_VALUE, *toTest) + && !TEST_BIT(ALG_RSAPSS_VALUE, *toTest) + && !TEST_BIT(ALG_OAEP_VALUE, *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 ALG_OAEP_VALUE: + case ALG_RSAES_VALUE: + result = TestRsaEncryptDecrypt(alg, toTest); + break; + case ALG_RSAPSS_VALUE: + case ALG_RSASSA_VALUE: + result = TestRsaSignAndVerify(alg, toTest); + break; + default: + FAIL(FATAL_ERROR_SELF_TEST); + // kgold SELF_TEST_FAILURE; + } + return result; +} +#endif // TPM_ALG_RSA +/* 10.2.1.6 ECC Tests */ +#ifdef TPM_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(ALG_ECDH_VALUE); + 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)) { + FAIL(FATAL_ERROR_SELF_TEST); + // kgold SELF_TEST_FAILURE; + } + if(!MemoryEqual2B(&c_ecTestEcdh_X.b, &Z.x.b) + || !MemoryEqual2B(&c_ecTestEcdh_Y.b, &Z.y.b)) { + FAIL(FATAL_ERROR_SELF_TEST); + // kgold SELF_TEST_FAILURE; + } + return result; +} +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(ALG_ECDH_VALUE); + // ECC signature verification testing uses a KVT. + switch(scheme) + { + case ALG_ECDSA_VALUE: + LoadEccParameter(&testSig.signature.ecdaa.signatureR, &c_TestEcDsa_r); + LoadEccParameter(&testSig.signature.ecdaa.signatureS, &c_TestEcDsa_s); + break; + case ALG_ECSCHNORR_VALUE: + LoadEccParameter(&testSig.signature.ecdaa.signatureR, + &c_TestEcSchnorr_r); + LoadEccParameter(&testSig.signature.ecdaa.signatureS, + &c_TestEcSchnorr_s); + break; + case ALG_SM2_VALUE: + // don't have a test for SM2 + return TPM_RC_SUCCESS; + default: + FAIL(FATAL_ERROR_SELF_TEST); + // kgold 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)) + { + //??? Don't have a valid test for ECSCORR right now because the algorithm has + //??? changed and the KVT has not been updated. + if(scheme != ALG_ECSCHNORR_VALUE) { + FAIL(FATAL_ERROR_SELF_TEST); + // kgold SELF_TEST_FAILURE; + } + } + CHECK_CANCELED; + // Now sign and verify some data + if(TPM_RC_SUCCESS != CryptEccSign(&testSig, &testObject, + (TPM2B_DIGEST *)&c_ecTestValue, + &eccScheme, NULL)) { + FAIL(FATAL_ERROR_SELF_TEST); + // kgold SELF_TEST_FAILURE; + } + CHECK_CANCELED; + if(TPM_RC_SUCCESS != CryptEccValidateSignature(&testSig, &testObject, + (TPM2B_DIGEST *)&c_ecTestValue)) { + FAIL(FATAL_ERROR_SELF_TEST); + // kgold SELF_TEST_FAILURE; + } + CHECK_CANCELED; + return TPM_RC_SUCCESS; +} +static TPM_RC +TestEcc( + TPM_ALG_ID alg, + ALGORITHM_VECTOR *toTest + ) +{ + TPM_RC result = TPM_RC_SUCCESS; + NOT_REFERENCED(toTest); + switch(alg) + { + case ALG_ECC_VALUE: + case ALG_ECDH_VALUE: + // 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(ALG_ECDSA_VALUE, *toTest) + || TEST_BIT(ALG_ECSCHNORR, *toTest) + || TEST_BIT(ALG_SM2_VALUE, *toTest))) + { + result = TestECDH(alg, toTest); + } + break; + case ALG_ECDSA_VALUE: + case ALG_ECSCHNORR_VALUE: + case ALG_SM2_VALUE: + result = TestEccSignAndVerify(alg, toTest); + break; + default: + FAIL(FATAL_ERROR_SELF_TEST); + // kgold 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. If algorithm is not 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 quietly cleared. If alg is zero + (TPM_ALG_ERROR), then the toTest vector is cleared of any bits for which there is a 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_SUCCESS test complete */ +/* 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 +#ifdef TPM_ALG_AES + case ALG_AES_VALUE: +#endif +#ifdef TPM_ALG_SM4 + // if SM4 is implemented, its test is like other block ciphers but there + // aren't any test vectors for it yet + // case ALG_SM4_VALUE: +#endif +#ifdef TPM_ALG_CAMELLIA + // no test vectors for camellia + // case ALG_CAMELLIA_VALUE: +#endif + // Symmetric modes +#ifndef TPM_ALG_CFB +# error CFB is required in all TPM implementations +#endif // !TPM_ALG_CFB + case ALG_CFB_VALUE: + if(doTest) + result = TestSymmetric(alg, toTest); + break; +#ifdef TPM_ALG_CTR + case ALG_CTR_VALUE: +#endif // TPM_ALG_CRT +#ifdef TPM_ALG_OFB + case ALG_OFB_VALUE: +#endif // TPM_ALG_OFB +#ifdef TPM_ALG_CBC + case ALG_CBC_VALUE: +#endif // TPM_ALG_CBC +#ifdef TPM_ALG_ECB + case ALG_ECB_VALUE: +#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; +#ifndef TPM_ALG_HMAC +# error HMAC is required in all TPM implementations +#endif + case ALG_HMAC_VALUE: + // 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; +#ifdef TPM_ALG_SHA1 + case ALG_SHA1_VALUE: +#endif // TPM_ALG_SHA1 +#ifdef TPM_ALG_SHA256 + case ALG_SHA256_VALUE: +#endif // TPM_ALG_SHA256 +#ifdef TPM_ALG_SHA384 + case ALG_SHA384_VALUE: +#endif // TPM_ALG_SHA384 +#ifdef TPM_ALG_SHA512 + case ALG_SHA512_VALUE: +#endif // TPM_ALG_SHA512 + // if SM3 is implemented its test is like any other hash, but there + // aren't any test vectors yet. +#ifdef TPM_ALG_SM3_256 + // case ALG_SM3_256_VALUE: +#endif // TPM_ALG_SM3_256 + if(doTest) + result = TestHash(alg, toTest); + break; + // RSA-dependent +#ifdef TPM_ALG_RSA + case ALG_RSA_VALUE: + CLEAR_BOTH(alg); + if(doTest) + result = TestRsa(TPM_ALG_NULL, toTest); + else + SET_BOTH(TPM_ALG_NULL); + break; + case ALG_RSASSA_VALUE: + case ALG_RSAES_VALUE: + case ALG_RSAPSS_VALUE: + case ALG_OAEP_VALUE: + case ALG_NULL_VALUE: // used or RSADP + if(doTest) + result = TestRsa(alg, toTest); + break; +#endif // TPM_ALG_RSA +#ifdef TPM_ALG_ECC + // ECC dependent but no tests + // case ALG_ECDAA_VALUE: + // case ALG_ECMQV_VALUE: + // case ALG_KDF1_SP800_56a_VALUE: + // case ALG_KDF2_VALUE: + // case ALG_KDF1_SP800_108_VALUE: + // case ALG_MGF1_VALUE: + case ALG_ECC_VALUE: + CLEAR_BOTH(alg); + if(doTest) + result = TestEcc(ALG_ECDH_VALUE, toTest); + else + SET_BOTH(ALG_ECDH_VALUE); + break; + case ALG_ECDSA_VALUE: + case ALG_ECDH_VALUE: + case ALG_ECSCHNORR_VALUE: + // case ALG_SM2_VALUE: + if(doTest) + result = TestEcc(alg, toTest); + break; +#endif // TPM_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 00000000..c180b7b1 --- /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 00000000..59c7d67b --- /dev/null +++ b/src/tpm2/AsymmetricCommands.c @@ -0,0 +1,310 @@ +/********************************************************************************/ +/* */ +/* */ +/* Written by Ken Goldman */ +/* IBM Thomas J. Watson Research Center */ +/* $Id: AsymmetricCommands.c 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 */ +/* */ +/********************************************************************************/ + +#include "Tpm.h" +#include "RSA_Encrypt_fp.h" +#ifdef TPM_CC_RSA_Encrypt // Conditional expansion of this file +#ifdef TPM_ALG_RSA +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(rsaKey->publicArea.objectAttributes.decrypt != SET) + 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 +#endif // CC_RSA_Encrypt +#include "Tpm.h" +#include "RSA_Decrypt_fp.h" +#ifdef TPM_CC_RSA_Decrypt // Conditional expansion of this file +#ifdef TPM_ALG_RSA +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(rsaKey->publicArea.objectAttributes.restricted == SET + || rsaKey->publicArea.objectAttributes.decrypt == CLEAR) + 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 +#endif // CC_RSA_Decrypt +#include "Tpm.h" +#include "ECDH_KeyGen_fp.h" +#ifdef TPM_CC_ECDH_KeyGen // Conditional expansion of this file +#ifdef TPM_ALG_ECC +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 // ALG_ECC +#endif // CC_ECDH_KeyGen +#include "Tpm.h" +#include "ECDH_ZGen_fp.h" +#ifdef TPM_CC_ECDH_ZGen // Conditional expansion of this file +#ifdef TPM_ALG_ECC +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(eccKey->publicArea.objectAttributes.restricted == SET + || eccKey->publicArea.objectAttributes.decrypt != SET) + 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 +#endif // CC_ECDH_ZGen +#include "Tpm.h" +#include "ECC_Parameters_fp.h" +#ifdef TPM_CC_ECC_Parameters // Conditional expansion of this file +#ifdef TPM_ALG_ECC +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 +#endif // CC_ECC_Parameters +#include "Tpm.h" +#include "ZGen_2Phase_fp.h" +#ifdef TPM_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(eccKey->publicArea.objectAttributes.restricted == SET + || eccKey->publicArea.objectAttributes.decrypt != SET + ) + 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 diff --git a/src/tpm2/Attest_spt.c b/src/tpm2/Attest_spt.c new file mode 100644 index 00000000..fb47a7eb --- /dev/null +++ b/src/tpm2/Attest_spt.c @@ -0,0 +1,207 @@ +/********************************************************************************/ +/* */ +/* */ +/* Written by Ken Goldman */ +/* IBM Thomas J. Watson Research Center */ +/* $Id: Attest_spt.c 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 */ +/* */ +/********************************************************************************/ + +#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) || ((object->publicArea.objectAttributes.sign == SET) + && 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 00000000..a3f260aa --- /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 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 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 00000000..5a465620 --- /dev/null +++ b/src/tpm2/AttestationCommands.c @@ -0,0 +1,301 @@ +/********************************************************************************/ +/* */ +/* */ +/* Written by Ken Goldman */ +/* IBM Thomas J. Watson Research Center */ +/* $Id: AttestationCommands.c 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 */ +/* */ +/********************************************************************************/ + +#include "Tpm.h" +#include "Attest_spt_fp.h" +#include "Certify_fp.h" +#ifdef TPM_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; + 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" +#ifdef TPM_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" +#ifdef TPM_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, "ed); + // 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, + "ed.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, "ed, &in->qualifyingData, + &out->quoted, &out->signature); +} +#endif // CC_Quote +#include "Tpm.h" +#include "Attest_spt_fp.h" +#include "GetSessionAuditDigest_fp.h" +#ifdef TPM_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" +#ifdef TPM_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" +#ifdef TPM_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 diff --git a/src/tpm2/AuditCommands.c b/src/tpm2/AuditCommands.c new file mode 100644 index 00000000..49c0244a --- /dev/null +++ b/src/tpm2/AuditCommands.c @@ -0,0 +1,112 @@ +/********************************************************************************/ +/* */ +/* */ +/* Written by Ken Goldman */ +/* IBM Thomas J. Watson Research Center */ +/* $Id: AuditCommands.c 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 */ +/* */ +/********************************************************************************/ + +#include "Tpm.h" +#include "SetCommandCodeAuditStatus_fp.h" +#ifdef TPM_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/BaseTypes.h b/src/tpm2/BaseTypes.h new file mode 100644 index 00000000..03524c0b --- /dev/null +++ b/src/tpm2/BaseTypes.h @@ -0,0 +1,85 @@ +/********************************************************************************/ +/* */ +/* */ +/* Written by Ken Goldman */ +/* IBM Thomas J. Watson Research Center */ +/* $Id: BaseTypes.h 827 2016-11-18 20:45: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 */ +/* */ +/********************************************************************************/ + +/* 5.2 BaseTypes.h */ + +#ifndef BASETYPES_H +#define BASETYPES_H + +#include + +/* 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 00000000..fa2f3f74 --- /dev/null +++ b/src/tpm2/Bits.c @@ -0,0 +1,115 @@ +/********************************************************************************/ +/* */ +/* */ +/* Written by Ken Goldman */ +/* IBM Thomas J. Watson Research Center */ +/* $Id: Bits.c 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 */ +/* */ +/********************************************************************************/ + +/* 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 */ +#ifndef INLINE_FUNCTIONS +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); +} +#endif // INLINE_FUNCTIONS +/* 9.2.3.2 SetBit() */ +/* This function will set the indicated bit in bArray. */ +#ifndef INLINE_FUNCTIONS +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)); +} +#endif // INLINE_FUNCTIONS +/* 9.2.3.3 ClearBit() */ +/* This function will clear the indicated bit in bArray. */ +#ifndef INLINE_FUNCTIONS +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)); +} +#endif // INLINE_FUNCTIONS diff --git a/src/tpm2/Bits_fp.h b/src/tpm2/Bits_fp.h new file mode 100644 index 00000000..5a9eaa8c --- /dev/null +++ b/src/tpm2/Bits_fp.h @@ -0,0 +1,133 @@ +/********************************************************************************/ +/* */ +/* */ +/* Written by Ken Goldman */ +/* IBM Thomas J. Watson Research Center */ +/* $Id: Bits_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 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 */ + +#ifndef INLINE_FUNCTIONS +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' + ); +#else +INLINE 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); +} +#endif // INLINE_FUNCTIONS +/* 5.3.2 SetBit() */ +/* This function will set the indicated bit in bArray. */ +#ifndef INLINE_FUNCTIONS +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' + ); +#else +INLINE 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)); +} +#endif // INLINE_FUNCTIONS +/* 5.3.3 ClearBit() */ +/* This function will clear the indicated bit in bArray. */ +#ifndef INLINE_FUNCTIONS +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' + ); +#else +INLINE 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)); +} +#endif // INLINE_FUNCTIONS + +#endif diff --git a/src/tpm2/BnConvert.c b/src/tpm2/BnConvert.c new file mode 100644 index 00000000..a7ce32d8 --- /dev/null +++ b/src/tpm2/BnConvert.c @@ -0,0 +1,282 @@ +/********************************************************************************/ +/* */ +/* conversion functions that will convert TPM2B to/from internal format */ +/* Written by Ken Goldman */ +/* IBM Thomas J. Watson Research Center */ +/* $Id: BnConvert.c 953 2017-03-06 20:31: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, 2017 */ +/* */ +/********************************************************************************/ + +/* 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; + // make sure things fit + pAssert(BnGetAllocated(bn) >= size); + // If nothing in, nothing out + if(bn == NULL) + return NULL; + 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); + return NULL; +} +/* 10.2.2.3.3 BnFromHex() */ +/* Convert a hex string into a bigNum. This is primarily used in debugging. */ +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]); + i = 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 == NO + for(i = 0; i < wordCount; i++) + bn->d[i] = SWAP_CRYPT_WORD(bn->d[i]); +#endif // BIG_ENDIAN_TPM + BnSetTop(bn, wordCount); + return bn; +} +/* 10.2.2.3.4 BnToBytes() */ +/* This function converts a BIG_NUM to a byte array. If size is not large enough to hold the bigNum + value, then the function return FALSE. Otherwise, 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). */ +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 != NULL && buffer != NULL && size != NULL); + 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(*size == 0) + *size = (NUMBYTES)requiredSize; + pAssert(requiredSize <= *size); +#if BIG_ENDIAN_TPM + // byte swap the words to make them little-endian + for(count = 0; count < bn->size; count++) + bn->d[count] = SWAP_CRYPT_WORD(bn->d[count]); +#endif + // Byte swap the number (not words but the whole value) + count = *size; + pFrom = (BYTE *)(&bn->d[0]) + requiredSize - 1; + pTo = buffer; + for(count = *size; count > requiredSize; count--) + *pTo++ = 0; + for(; requiredSize > 0; requiredSize--) + *pTo++ = *pFrom--; +#if BIG_ENDIAN_TPM + // Put the input back into big-endian format + for(count = 0; count < bn->size; count++) + bn->d[count] = SWAP_CRYPT_WORD(bn->d[count]); +#endif + } + 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 + a2B->size = size; + return BnToBytes(bn, a2B->buffer, &a2B->size); +} +#ifdef TPM_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 = (UINT16)BITS_TO_BYTES( + BnMsb(CurveGetOrder(AccessCurveData(E)))); + pAssert(p && ecP && E); + pAssert(BnEqualWord(ecP->z, 1)); + 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/BnEccData.c b/src/tpm2/BnEccData.c new file mode 100644 index 00000000..554a0db5 --- /dev/null +++ b/src/tpm2/BnEccData.c @@ -0,0 +1,670 @@ +/********************************************************************************/ +/* */ +/* */ +/* Written by Ken Goldman */ +/* IBM Thomas J. Watson Research Center */ +/* $Id: BnEccData.c 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 */ +/* */ +/********************************************************************************/ + +/* 10.2.3 BnEccData.c */ +#include "Tpm.h" +/* both the new, refactored code and the old code (this is necessary so that errata can be + handled). Another script (BnEccData().pl) does the conversion and generates BnEccData.c for use + in the refactored code. */ +#if defined TPM_ALG_ECC && !defined USE_2B_ECC_DATA +const struct { + crypt_uword_t allocated; + crypt_uword_t size; + crypt_uword_t d[BYTES_TO_CRYPT_WORDS(1)]; +} BN_ZERO = {BYTES_TO_CRYPT_WORDS(4), BYTES_TO_CRYPT_WORDS(0), {0}}; +const struct { + crypt_uword_t allocated; + crypt_uword_t size; + crypt_uword_t d[BYTES_TO_CRYPT_WORDS(1)]; +} BN_ONE = {BYTES_TO_CRYPT_WORDS(1), BYTES_TO_CRYPT_WORDS(1), {1}}; + +/* Defines for the sizes of ECC parameters */ + +#if defined ECC_NIST_P192 && ECC_NIST_P192 == YES +const struct { + crypt_uword_t allocated; + crypt_uword_t size; + crypt_uword_t d[BYTES_TO_CRYPT_WORDS(24)]; +} NIST_P192_p = {BYTES_TO_CRYPT_WORDS(24), BYTES_TO_CRYPT_WORDS(24), + {TO_CRYPT_WORD_64(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF), + TO_CRYPT_WORD_64(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE), + TO_CRYPT_WORD_64(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF)}}; +const struct { + crypt_uword_t allocated; + crypt_uword_t size; + crypt_uword_t d[BYTES_TO_CRYPT_WORDS(24)]; +} NIST_P192_a = {BYTES_TO_CRYPT_WORDS(24), BYTES_TO_CRYPT_WORDS(24), + {TO_CRYPT_WORD_64(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC), + TO_CRYPT_WORD_64(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE), + TO_CRYPT_WORD_64(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF)}}; +const struct { + crypt_uword_t allocated; + crypt_uword_t size; + crypt_uword_t d[BYTES_TO_CRYPT_WORDS(24)]; +} NIST_P192_b = {BYTES_TO_CRYPT_WORDS(24), BYTES_TO_CRYPT_WORDS(24), + {TO_CRYPT_WORD_64(0xFE, 0xB8, 0xDE, 0xEC, 0xC1, 0x46, 0xB9, 0xB1), + TO_CRYPT_WORD_64(0x0F, 0xA7, 0xE9, 0xAB, 0x72, 0x24, 0x30, 0x49), + TO_CRYPT_WORD_64(0x64, 0x21, 0x05, 0x19, 0xE5, 0x9C, 0x80, 0xE7)}}; +const struct { + crypt_uword_t allocated; + crypt_uword_t size; + crypt_uword_t d[BYTES_TO_CRYPT_WORDS(24)]; +} NIST_P192_gX = {BYTES_TO_CRYPT_WORDS(24), BYTES_TO_CRYPT_WORDS(24), + {TO_CRYPT_WORD_64(0xF4, 0xFF, 0x0A, 0xFD, 0x82, 0xFF, 0x10, 0x12), + TO_CRYPT_WORD_64(0x7C, 0xBF, 0x20, 0xEB, 0x43, 0xA1, 0x88, 0x00), + TO_CRYPT_WORD_64(0x18, 0x8D, 0xA8, 0x0E, 0xB0, 0x30, 0x90, 0xF6)}}; +const struct { + crypt_uword_t allocated; + crypt_uword_t size; + crypt_uword_t d[BYTES_TO_CRYPT_WORDS(24)]; +} NIST_P192_gY = {BYTES_TO_CRYPT_WORDS(24), BYTES_TO_CRYPT_WORDS(24), + {TO_CRYPT_WORD_64(0x73, 0xF9, 0x77, 0xA1, 0x1E, 0x79, 0x48, 0x11), + TO_CRYPT_WORD_64(0x63, 0x10, 0x11, 0xED, 0x6B, 0x24, 0xCD, 0xD5), + TO_CRYPT_WORD_64(0x07, 0x19, 0x2B, 0x95, 0xFF, 0xC8, 0xDA, 0x78)}}; +const struct { + crypt_uword_t allocated; + crypt_uword_t size; + crypt_uword_t d[BYTES_TO_CRYPT_WORDS(24)]; +} NIST_P192_n = {BYTES_TO_CRYPT_WORDS(24), BYTES_TO_CRYPT_WORDS(24), + {TO_CRYPT_WORD_64(0x14, 0x6B, 0xC9, 0xB1, 0xB4, 0xD2, 0x28, 0x31), + TO_CRYPT_WORD_64(0xFF, 0xFF, 0xFF, 0xFF, 0x99, 0xDE, 0xF8, 0x36), + TO_CRYPT_WORD_64(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF)}}; +#define NIST_P192_h BN_ONE +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)&BN_ONE}}; +#endif // ECC_NIST_P192 +#if defined ECC_NIST_P224 && ECC_NIST_P224 == YES +const struct { + crypt_uword_t allocated; + crypt_uword_t size; + crypt_uword_t d[BYTES_TO_CRYPT_WORDS(28)]; +} NIST_P224_p = {BYTES_TO_CRYPT_WORDS(28), BYTES_TO_CRYPT_WORDS(28), + {TO_CRYPT_WORD_64(0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01), + TO_CRYPT_WORD_64(0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00), + TO_CRYPT_WORD_64(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF), + TO_CRYPT_WORD_32(0xFF, 0xFF, 0xFF, 0xFF)}}; +const struct { + crypt_uword_t allocated; + crypt_uword_t size; + crypt_uword_t d[BYTES_TO_CRYPT_WORDS(28)]; +} NIST_P224_a = {BYTES_TO_CRYPT_WORDS(28), BYTES_TO_CRYPT_WORDS(28), + {TO_CRYPT_WORD_64(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE), + TO_CRYPT_WORD_64(0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF), + TO_CRYPT_WORD_64(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF), + TO_CRYPT_WORD_32(0xFF, 0xFF, 0xFF, 0xFF)}}; +const struct { + crypt_uword_t allocated; + crypt_uword_t size; + crypt_uword_t d[BYTES_TO_CRYPT_WORDS(28)]; +} NIST_P224_b = {BYTES_TO_CRYPT_WORDS(28), BYTES_TO_CRYPT_WORDS(28), + {TO_CRYPT_WORD_64(0x27, 0x0B, 0x39, 0x43, 0x23, 0x55, 0xFF, 0xB4), + TO_CRYPT_WORD_64(0x50, 0x44, 0xB0, 0xB7, 0xD7, 0xBF, 0xD8, 0xBA), + TO_CRYPT_WORD_64(0x0C, 0x04, 0xB3, 0xAB, 0xF5, 0x41, 0x32, 0x56), + TO_CRYPT_WORD_32(0xB4, 0x05, 0x0A, 0x85)}}; +const struct { + crypt_uword_t allocated; + crypt_uword_t size; + crypt_uword_t d[BYTES_TO_CRYPT_WORDS(28)]; +} NIST_P224_gX = {BYTES_TO_CRYPT_WORDS(28), BYTES_TO_CRYPT_WORDS(28), + {TO_CRYPT_WORD_64(0x34, 0x32, 0x80, 0xD6, 0x11, 0x5C, 0x1D, 0x21), + TO_CRYPT_WORD_64(0x4A, 0x03, 0xC1, 0xD3, 0x56, 0xC2, 0x11, 0x22), + TO_CRYPT_WORD_64(0x6B, 0xB4, 0xBF, 0x7F, 0x32, 0x13, 0x90, 0xB9), + TO_CRYPT_WORD_32(0xB7, 0x0E, 0x0C, 0xBD)}}; +const struct { + crypt_uword_t allocated; + crypt_uword_t size; + crypt_uword_t d[BYTES_TO_CRYPT_WORDS(28)]; +} NIST_P224_gY = {BYTES_TO_CRYPT_WORDS(28), BYTES_TO_CRYPT_WORDS(28), + {TO_CRYPT_WORD_64(0x44, 0xD5, 0x81, 0x99, 0x85, 0x00, 0x7E, 0x34), + TO_CRYPT_WORD_64(0xCD, 0x43, 0x75, 0xA0, 0x5A, 0x07, 0x47, 0x64), + TO_CRYPT_WORD_64(0xB5, 0xF7, 0x23, 0xFB, 0x4C, 0x22, 0xDF, 0xE6), + TO_CRYPT_WORD_32(0xBD, 0x37, 0x63, 0x88)}}; +const struct { + crypt_uword_t allocated; + crypt_uword_t size; + crypt_uword_t d[BYTES_TO_CRYPT_WORDS(28)]; +} NIST_P224_n = {BYTES_TO_CRYPT_WORDS(28), BYTES_TO_CRYPT_WORDS(28), + {TO_CRYPT_WORD_64(0x13, 0xDD, 0x29, 0x45, 0x5C, 0x5C, 0x2A, 0x3D), + TO_CRYPT_WORD_64(0xFF, 0xFF, 0x16, 0xA2, 0xE0, 0xB8, 0xF0, 0x3E), + TO_CRYPT_WORD_64(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF), + TO_CRYPT_WORD_32(0xFF, 0xFF, 0xFF, 0xFF)}}; +#define NIST_P224_h BN_ONE +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)&BN_ONE}}; +#endif // ECC_NIST_P224 +#if defined ECC_NIST_P256 && ECC_NIST_P256 == YES +const struct { + crypt_uword_t allocated; + crypt_uword_t size; + crypt_uword_t d[BYTES_TO_CRYPT_WORDS(32)]; +} NIST_P256_p = {BYTES_TO_CRYPT_WORDS(32), BYTES_TO_CRYPT_WORDS(32), + {TO_CRYPT_WORD_64(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF), + TO_CRYPT_WORD_64(0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF), + TO_CRYPT_WORD_64(0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00), + TO_CRYPT_WORD_64(0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x01)}}; +const struct { + crypt_uword_t allocated; + crypt_uword_t size; + crypt_uword_t d[BYTES_TO_CRYPT_WORDS(32)]; +} NIST_P256_a = {BYTES_TO_CRYPT_WORDS(32), BYTES_TO_CRYPT_WORDS(32), + {TO_CRYPT_WORD_64(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC), + TO_CRYPT_WORD_64(0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF), + TO_CRYPT_WORD_64(0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00), + TO_CRYPT_WORD_64(0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x01)}}; +const struct { + crypt_uword_t allocated; + crypt_uword_t size; + crypt_uword_t d[BYTES_TO_CRYPT_WORDS(32)]; +} NIST_P256_b = {BYTES_TO_CRYPT_WORDS(32), BYTES_TO_CRYPT_WORDS(32), + {TO_CRYPT_WORD_64(0x3B, 0xCE, 0x3C, 0x3E, 0x27, 0xD2, 0x60, 0x4B), + TO_CRYPT_WORD_64(0x65, 0x1D, 0x06, 0xB0, 0xCC, 0x53, 0xB0, 0xF6), + TO_CRYPT_WORD_64(0xB3, 0xEB, 0xBD, 0x55, 0x76, 0x98, 0x86, 0xBC), + TO_CRYPT_WORD_64(0x5A, 0xC6, 0x35, 0xD8, 0xAA, 0x3A, 0x93, 0xE7)}}; +const struct { + crypt_uword_t allocated; + crypt_uword_t size; + crypt_uword_t d[BYTES_TO_CRYPT_WORDS(32)]; +} NIST_P256_gX = {BYTES_TO_CRYPT_WORDS(32), BYTES_TO_CRYPT_WORDS(32), + {TO_CRYPT_WORD_64(0xF4, 0xA1, 0x39, 0x45, 0xD8, 0x98, 0xC2, 0x96), + TO_CRYPT_WORD_64(0x77, 0x03, 0x7D, 0x81, 0x2D, 0xEB, 0x33, 0xA0), + TO_CRYPT_WORD_64(0xF8, 0xBC, 0xE6, 0xE5, 0x63, 0xA4, 0x40, 0xF2), + TO_CRYPT_WORD_64(0x6B, 0x17, 0xD1, 0xF2, 0xE1, 0x2C, 0x42, 0x47)}}; +const struct { + crypt_uword_t allocated; + crypt_uword_t size; + crypt_uword_t d[BYTES_TO_CRYPT_WORDS(32)]; +} NIST_P256_gY = {BYTES_TO_CRYPT_WORDS(32), BYTES_TO_CRYPT_WORDS(32), + {TO_CRYPT_WORD_64(0xCB, 0xB6, 0x40, 0x68, 0x37, 0xBF, 0x51, 0xF5), + TO_CRYPT_WORD_64(0x2B, 0xCE, 0x33, 0x57, 0x6B, 0x31, 0x5E, 0xCE), + TO_CRYPT_WORD_64(0x8E, 0xE7, 0xEB, 0x4A, 0x7C, 0x0F, 0x9E, 0x16), + TO_CRYPT_WORD_64(0x4F, 0xE3, 0x42, 0xE2, 0xFE, 0x1A, 0x7F, 0x9B)}}; +const struct { + crypt_uword_t allocated; + crypt_uword_t size; + crypt_uword_t d[BYTES_TO_CRYPT_WORDS(32)]; +} NIST_P256_n = {BYTES_TO_CRYPT_WORDS(32), BYTES_TO_CRYPT_WORDS(32), + {TO_CRYPT_WORD_64(0xF3, 0xB9, 0xCA, 0xC2, 0xFC, 0x63, 0x25, 0x51), + TO_CRYPT_WORD_64(0xBC, 0xE6, 0xFA, 0xAD, 0xA7, 0x17, 0x9E, 0x84), + TO_CRYPT_WORD_64(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF), + TO_CRYPT_WORD_64(0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00)}}; +#define NIST_P256_h BN_ONE +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)&BN_ONE}}; +#endif // ECC_NIST_P256 +#if defined ECC_NIST_P384 && ECC_NIST_P384 == YES +const struct { + crypt_uword_t allocated; + crypt_uword_t size; + crypt_uword_t d[BYTES_TO_CRYPT_WORDS(48)]; +} NIST_P384_p = {BYTES_TO_CRYPT_WORDS(48), BYTES_TO_CRYPT_WORDS(48), + {TO_CRYPT_WORD_64(0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF), + TO_CRYPT_WORD_64(0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00), + TO_CRYPT_WORD_64(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE), + TO_CRYPT_WORD_64(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF), + TO_CRYPT_WORD_64(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF), + TO_CRYPT_WORD_64(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF)}}; +const struct { + crypt_uword_t allocated; + crypt_uword_t size; + crypt_uword_t d[BYTES_TO_CRYPT_WORDS(48)]; +} NIST_P384_a = {BYTES_TO_CRYPT_WORDS(48), BYTES_TO_CRYPT_WORDS(48), + {TO_CRYPT_WORD_64(0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFC), + TO_CRYPT_WORD_64(0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00), + TO_CRYPT_WORD_64(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE), + TO_CRYPT_WORD_64(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF), + TO_CRYPT_WORD_64(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF), + TO_CRYPT_WORD_64(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF)}}; +const struct { + crypt_uword_t allocated; + crypt_uword_t size; + crypt_uword_t d[BYTES_TO_CRYPT_WORDS(48)]; +} NIST_P384_b = {BYTES_TO_CRYPT_WORDS(48), BYTES_TO_CRYPT_WORDS(48), + {TO_CRYPT_WORD_64(0x2A, 0x85, 0xC8, 0xED, 0xD3, 0xEC, 0x2A, 0xEF), + TO_CRYPT_WORD_64(0xC6, 0x56, 0x39, 0x8D, 0x8A, 0x2E, 0xD1, 0x9D), + TO_CRYPT_WORD_64(0x03, 0x14, 0x08, 0x8F, 0x50, 0x13, 0x87, 0x5A), + TO_CRYPT_WORD_64(0x18, 0x1D, 0x9C, 0x6E, 0xFE, 0x81, 0x41, 0x12), + TO_CRYPT_WORD_64(0x98, 0x8E, 0x05, 0x6B, 0xE3, 0xF8, 0x2D, 0x19), + TO_CRYPT_WORD_64(0xB3, 0x31, 0x2F, 0xA7, 0xE2, 0x3E, 0xE7, 0xE4)}}; +const struct { + crypt_uword_t allocated; + crypt_uword_t size; + crypt_uword_t d[BYTES_TO_CRYPT_WORDS(48)]; +} NIST_P384_gX = {BYTES_TO_CRYPT_WORDS(48), BYTES_TO_CRYPT_WORDS(48), + {TO_CRYPT_WORD_64(0x3A, 0x54, 0x5E, 0x38, 0x72, 0x76, 0x0A, 0xB7), + TO_CRYPT_WORD_64(0x55, 0x02, 0xF2, 0x5D, 0xBF, 0x55, 0x29, 0x6C), + TO_CRYPT_WORD_64(0x59, 0xF7, 0x41, 0xE0, 0x82, 0x54, 0x2A, 0x38), + TO_CRYPT_WORD_64(0x6E, 0x1D, 0x3B, 0x62, 0x8B, 0xA7, 0x9B, 0x98), + TO_CRYPT_WORD_64(0x8E, 0xB1, 0xC7, 0x1E, 0xF3, 0x20, 0xAD, 0x74), + TO_CRYPT_WORD_64(0xAA, 0x87, 0xCA, 0x22, 0xBE, 0x8B, 0x05, 0x37)}}; +const struct { + crypt_uword_t allocated; + crypt_uword_t size; + crypt_uword_t d[BYTES_TO_CRYPT_WORDS(48)]; +} NIST_P384_gY = {BYTES_TO_CRYPT_WORDS(48), BYTES_TO_CRYPT_WORDS(48), + {TO_CRYPT_WORD_64(0x7A, 0x43, 0x1D, 0x7C, 0x90, 0xEA, 0x0E, 0x5F), + TO_CRYPT_WORD_64(0x0A, 0x60, 0xB1, 0xCE, 0x1D, 0x7E, 0x81, 0x9D), + TO_CRYPT_WORD_64(0xE9, 0xDA, 0x31, 0x13, 0xB5, 0xF0, 0xB8, 0xC0), + TO_CRYPT_WORD_64(0xF8, 0xF4, 0x1D, 0xBD, 0x28, 0x9A, 0x14, 0x7C), + TO_CRYPT_WORD_64(0x5D, 0x9E, 0x98, 0xBF, 0x92, 0x92, 0xDC, 0x29), + TO_CRYPT_WORD_64(0x36, 0x17, 0xDE, 0x4A, 0x96, 0x26, 0x2C, 0x6F)}}; +const struct { + crypt_uword_t allocated; + crypt_uword_t size; + crypt_uword_t d[BYTES_TO_CRYPT_WORDS(48)]; +} NIST_P384_n = {BYTES_TO_CRYPT_WORDS(48), BYTES_TO_CRYPT_WORDS(48), + {TO_CRYPT_WORD_64(0xEC, 0xEC, 0x19, 0x6A, 0xCC, 0xC5, 0x29, 0x73), + TO_CRYPT_WORD_64(0x58, 0x1A, 0x0D, 0xB2, 0x48, 0xB0, 0xA7, 0x7A), + TO_CRYPT_WORD_64(0xC7, 0x63, 0x4D, 0x81, 0xF4, 0x37, 0x2D, 0xDF), + TO_CRYPT_WORD_64(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF), + TO_CRYPT_WORD_64(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF), + TO_CRYPT_WORD_64(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF)}}; +#define NIST_P384_h BN_ONE +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)&BN_ONE}}; +#endif // ECC_NIST_P384 +#if defined ECC_NIST_P521 && ECC_NIST_P521 == YES +const struct { + crypt_uword_t allocated; + crypt_uword_t size; + crypt_uword_t d[BYTES_TO_CRYPT_WORDS(66)]; +} NIST_P521_p = {BYTES_TO_CRYPT_WORDS(66), BYTES_TO_CRYPT_WORDS(66), + {TO_CRYPT_WORD_64(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF), + TO_CRYPT_WORD_64(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF), + TO_CRYPT_WORD_64(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF), + TO_CRYPT_WORD_64(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF), + TO_CRYPT_WORD_64(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF), + TO_CRYPT_WORD_64(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF), + TO_CRYPT_WORD_64(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF), + TO_CRYPT_WORD_64(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF), + TO_CRYPT_WORD_32(0x00, 0x00, 0x01, 0xFF)}}; +const struct { + crypt_uword_t allocated; + crypt_uword_t size; + crypt_uword_t d[BYTES_TO_CRYPT_WORDS(66)]; +} NIST_P521_a = {BYTES_TO_CRYPT_WORDS(66), BYTES_TO_CRYPT_WORDS(66), + {TO_CRYPT_WORD_64(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC), + TO_CRYPT_WORD_64(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF), + TO_CRYPT_WORD_64(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF), + TO_CRYPT_WORD_64(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF), + TO_CRYPT_WORD_64(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF), + TO_CRYPT_WORD_64(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF), + TO_CRYPT_WORD_64(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF), + TO_CRYPT_WORD_64(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF), + TO_CRYPT_WORD_32(0x00, 0x00, 0x01, 0xFF)}}; +const struct { + crypt_uword_t allocated; + crypt_uword_t size; + crypt_uword_t d[BYTES_TO_CRYPT_WORDS(66)]; +} NIST_P521_b = {BYTES_TO_CRYPT_WORDS(66), BYTES_TO_CRYPT_WORDS(66), + {TO_CRYPT_WORD_64(0xEF, 0x45, 0x1F, 0xD4, 0x6B, 0x50, 0x3F, 0x00), + TO_CRYPT_WORD_64(0x35, 0x73, 0xDF, 0x88, 0x3D, 0x2C, 0x34, 0xF1), + TO_CRYPT_WORD_64(0x16, 0x52, 0xC0, 0xBD, 0x3B, 0xB1, 0xBF, 0x07), + TO_CRYPT_WORD_64(0x56, 0x19, 0x39, 0x51, 0xEC, 0x7E, 0x93, 0x7B), + TO_CRYPT_WORD_64(0xB8, 0xB4, 0x89, 0x91, 0x8E, 0xF1, 0x09, 0xE1), + TO_CRYPT_WORD_64(0xA2, 0xDA, 0x72, 0x5B, 0x99, 0xB3, 0x15, 0xF3), + TO_CRYPT_WORD_64(0x92, 0x9A, 0x21, 0xA0, 0xB6, 0x85, 0x40, 0xEE), + TO_CRYPT_WORD_64(0x95, 0x3E, 0xB9, 0x61, 0x8E, 0x1C, 0x9A, 0x1F), + TO_CRYPT_WORD_32(0x00, 0x00, 0x00, 0x51)}}; +const struct { + crypt_uword_t allocated; + crypt_uword_t size; + crypt_uword_t d[BYTES_TO_CRYPT_WORDS(66)]; +} NIST_P521_gX = {BYTES_TO_CRYPT_WORDS(66), BYTES_TO_CRYPT_WORDS(66), + {TO_CRYPT_WORD_64(0xF9, 0x7E, 0x7E, 0x31, 0xC2, 0xE5, 0xBD, 0x66), + TO_CRYPT_WORD_64(0x33, 0x48, 0xB3, 0xC1, 0x85, 0x6A, 0x42, 0x9B), + TO_CRYPT_WORD_64(0xFE, 0x1D, 0xC1, 0x27, 0xA2, 0xFF, 0xA8, 0xDE), + TO_CRYPT_WORD_64(0xA1, 0x4B, 0x5E, 0x77, 0xEF, 0xE7, 0x59, 0x28), + TO_CRYPT_WORD_64(0xF8, 0x28, 0xAF, 0x60, 0x6B, 0x4D, 0x3D, 0xBA), + TO_CRYPT_WORD_64(0x9C, 0x64, 0x81, 0x39, 0x05, 0x3F, 0xB5, 0x21), + TO_CRYPT_WORD_64(0x9E, 0x3E, 0xCB, 0x66, 0x23, 0x95, 0xB4, 0x42), + TO_CRYPT_WORD_64(0x85, 0x8E, 0x06, 0xB7, 0x04, 0x04, 0xE9, 0xCD), + TO_CRYPT_WORD_32(0x00, 0x00, 0x00, 0xC6)}}; +const struct { + crypt_uword_t allocated; + crypt_uword_t size; + crypt_uword_t d[BYTES_TO_CRYPT_WORDS(66)]; +} NIST_P521_gY = {BYTES_TO_CRYPT_WORDS(66), BYTES_TO_CRYPT_WORDS(66), + {TO_CRYPT_WORD_64(0x88, 0xBE, 0x94, 0x76, 0x9F, 0xD1, 0x66, 0x50), + TO_CRYPT_WORD_64(0x35, 0x3C, 0x70, 0x86, 0xA2, 0x72, 0xC2, 0x40), + TO_CRYPT_WORD_64(0xC5, 0x50, 0xB9, 0x01, 0x3F, 0xAD, 0x07, 0x61), + TO_CRYPT_WORD_64(0x97, 0xEE, 0x72, 0x99, 0x5E, 0xF4, 0x26, 0x40), + TO_CRYPT_WORD_64(0x17, 0xAF, 0xBD, 0x17, 0x27, 0x3E, 0x66, 0x2C), + TO_CRYPT_WORD_64(0x98, 0xF5, 0x44, 0x49, 0x57, 0x9B, 0x44, 0x68), + TO_CRYPT_WORD_64(0x5C, 0x8A, 0x5F, 0xB4, 0x2C, 0x7D, 0x1B, 0xD9), + TO_CRYPT_WORD_64(0x39, 0x29, 0x6A, 0x78, 0x9A, 0x3B, 0xC0, 0x04), + TO_CRYPT_WORD_32(0x00, 0x00, 0x01, 0x18)}}; +const struct { + crypt_uword_t allocated; + crypt_uword_t size; + crypt_uword_t d[BYTES_TO_CRYPT_WORDS(66)]; +} NIST_P521_n = {BYTES_TO_CRYPT_WORDS(66), BYTES_TO_CRYPT_WORDS(66), + {TO_CRYPT_WORD_64(0xBB, 0x6F, 0xB7, 0x1E, 0x91, 0x38, 0x64, 0x09), + TO_CRYPT_WORD_64(0x3B, 0xB5, 0xC9, 0xB8, 0x89, 0x9C, 0x47, 0xAE), + TO_CRYPT_WORD_64(0x7F, 0xCC, 0x01, 0x48, 0xF7, 0x09, 0xA5, 0xD0), + TO_CRYPT_WORD_64(0x51, 0x86, 0x87, 0x83, 0xBF, 0x2F, 0x96, 0x6B), + TO_CRYPT_WORD_64(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFA), + TO_CRYPT_WORD_64(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF), + TO_CRYPT_WORD_64(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF), + TO_CRYPT_WORD_64(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF), + TO_CRYPT_WORD_32(0x00, 0x00, 0x01, 0xFF)}}; +#define NIST_P521_h BN_ONE +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)&BN_ONE}}; +#endif // ECC_NIST_P521 +#if defined ECC_BN_P256 && ECC_BN_P256 == YES +const struct { + crypt_uword_t allocated; + crypt_uword_t size; + crypt_uword_t d[BYTES_TO_CRYPT_WORDS(32)]; +} BN_P256_p = {BYTES_TO_CRYPT_WORDS(32), BYTES_TO_CRYPT_WORDS(32), + {TO_CRYPT_WORD_64(0xD3, 0x29, 0x2D, 0xDB, 0xAE, 0xD3, 0x30, 0x13), + TO_CRYPT_WORD_64(0x0C, 0xDC, 0x65, 0xFB, 0x12, 0x98, 0x0A, 0x82), + TO_CRYPT_WORD_64(0x46, 0xE5, 0xF2, 0x5E, 0xEE, 0x71, 0xA4, 0x9F), + TO_CRYPT_WORD_64(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0xF0, 0xCD)}}; +#define BN_P256_a BN_ZERO +const struct { + crypt_uword_t allocated; + crypt_uword_t size; + crypt_uword_t d[BYTES_TO_CRYPT_WORDS(1)]; +} BN_P256_b = {BYTES_TO_CRYPT_WORDS(1), BYTES_TO_CRYPT_WORDS(1), + {TO_CRYPT_WORD_32(0x00, 0x00, 0x00, 0x03)}}; +#define BN_P256_gX BN_ONE +const struct { + crypt_uword_t allocated; + crypt_uword_t size; + crypt_uword_t d[BYTES_TO_CRYPT_WORDS(1)]; +} BN_P256_gY = {BYTES_TO_CRYPT_WORDS(1), BYTES_TO_CRYPT_WORDS(1), + {TO_CRYPT_WORD_32(0x00, 0x00, 0x00, 0x02)}}; +const struct { + crypt_uword_t allocated; + crypt_uword_t size; + crypt_uword_t d[BYTES_TO_CRYPT_WORDS(32)]; +} BN_P256_n = {BYTES_TO_CRYPT_WORDS(32), BYTES_TO_CRYPT_WORDS(32), + {TO_CRYPT_WORD_64(0xF6, 0x2D, 0x53, 0x6C, 0xD1, 0x0B, 0x50, 0x0D), + TO_CRYPT_WORD_64(0x0C, 0xDC, 0x65, 0xFB, 0x12, 0x99, 0x92, 0x1A), + TO_CRYPT_WORD_64(0x46, 0xE5, 0xF2, 0x5E, 0xEE, 0x71, 0xA4, 0x9E), + TO_CRYPT_WORD_64(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0xF0, 0xCD)}}; +#define BN_P256_h BN_ONE +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_ONE}}; +#endif // ECC_BN_P256 +#if defined ECC_BN_P638 && ECC_BN_P638 == YES +const struct { + crypt_uword_t allocated; + crypt_uword_t size; + crypt_uword_t d[BYTES_TO_CRYPT_WORDS(80)]; +} BN_P638_p = {BYTES_TO_CRYPT_WORDS(80), BYTES_TO_CRYPT_WORDS(80), + {TO_CRYPT_WORD_64(0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x67), + TO_CRYPT_WORD_64(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xEC, 0xE0), + TO_CRYPT_WORD_64(0x00, 0x00, 0x00, 0x4C, 0x80, 0x01, 0x5A, 0xCD), + TO_CRYPT_WORD_64(0xFF, 0xFF, 0xF5, 0x1F, 0xFF, 0xF4, 0xEB, 0x80), + TO_CRYPT_WORD_64(0xC0, 0x00, 0x86, 0x52, 0x00, 0x21, 0xE5, 0x5B), + TO_CRYPT_WORD_64(0xFF, 0xFD, 0xD0, 0xE0, 0x00, 0x08, 0xDE, 0x55), + TO_CRYPT_WORD_64(0x3F, 0xFF, 0x94, 0x87, 0x00, 0x00, 0xD5, 0x2F), + TO_CRYPT_WORD_64(0xFF, 0xFF, 0xF9, 0x42, 0xD0, 0x00, 0x16, 0x5E), + TO_CRYPT_WORD_64(0x7F, 0xFF, 0xFF, 0xB8, 0x00, 0x00, 0x01, 0xD3), + TO_CRYPT_WORD_64(0x23, 0xFF, 0xFF, 0xFD, 0xC0, 0x00, 0x00, 0x0D)}}; +#define BN_P638_a BN_ZERO +const struct { + crypt_uword_t allocated; + crypt_uword_t size; + crypt_uword_t d[BYTES_TO_CRYPT_WORDS(2)]; +} BN_P638_b = {BYTES_TO_CRYPT_WORDS(2), BYTES_TO_CRYPT_WORDS(2), + {TO_CRYPT_WORD_32(0x00, 0x00, 0x01, 0x01)}}; +const struct { + crypt_uword_t allocated; + crypt_uword_t size; + crypt_uword_t d[BYTES_TO_CRYPT_WORDS(80)]; +} BN_P638_gX = {BYTES_TO_CRYPT_WORDS(80), BYTES_TO_CRYPT_WORDS(80), + {TO_CRYPT_WORD_64(0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x66), + TO_CRYPT_WORD_64(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xEC, 0xE0), + TO_CRYPT_WORD_64(0x00, 0x00, 0x00, 0x4C, 0x80, 0x01, 0x5A, 0xCD), + TO_CRYPT_WORD_64(0xFF, 0xFF, 0xF5, 0x1F, 0xFF, 0xF4, 0xEB, 0x80), + TO_CRYPT_WORD_64(0xC0, 0x00, 0x86, 0x52, 0x00, 0x21, 0xE5, 0x5B), + TO_CRYPT_WORD_64(0xFF, 0xFD, 0xD0, 0xE0, 0x00, 0x08, 0xDE, 0x55), + TO_CRYPT_WORD_64(0x3F, 0xFF, 0x94, 0x87, 0x00, 0x00, 0xD5, 0x2F), + TO_CRYPT_WORD_64(0xFF, 0xFF, 0xF9, 0x42, 0xD0, 0x00, 0x16, 0x5E), + TO_CRYPT_WORD_64(0x7F, 0xFF, 0xFF, 0xB8, 0x00, 0x00, 0x01, 0xD3), + TO_CRYPT_WORD_64(0x23, 0xFF, 0xFF, 0xFD, 0xC0, 0x00, 0x00, 0x0D)}}; +const struct { + crypt_uword_t allocated; + crypt_uword_t size; + crypt_uword_t d[BYTES_TO_CRYPT_WORDS(1)]; +} BN_P638_gY = {BYTES_TO_CRYPT_WORDS(1), BYTES_TO_CRYPT_WORDS(1), + {TO_CRYPT_WORD_32(0x00, 0x00, 0x00, 0x10)}}; +const struct { + crypt_uword_t allocated; + crypt_uword_t size; + crypt_uword_t d[BYTES_TO_CRYPT_WORDS(80)]; +} BN_P638_n = {BYTES_TO_CRYPT_WORDS(80), BYTES_TO_CRYPT_WORDS(80), + {TO_CRYPT_WORD_64(0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x61), + TO_CRYPT_WORD_64(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xED, 0xA0), + TO_CRYPT_WORD_64(0x00, 0x00, 0x00, 0x49, 0x80, 0x01, 0x54, 0xD9), + TO_CRYPT_WORD_64(0xFF, 0xFF, 0xF5, 0x4F, 0xFF, 0xF4, 0xEA, 0xC0), + TO_CRYPT_WORD_64(0x60, 0x00, 0x86, 0x55, 0x00, 0x21, 0xE5, 0x55), + TO_CRYPT_WORD_64(0xFF, 0xFD, 0xD0, 0xE0, 0x00, 0x08, 0xDE, 0x55), + TO_CRYPT_WORD_64(0x3F, 0xFF, 0x94, 0x87, 0x00, 0x00, 0xD5, 0x2F), + TO_CRYPT_WORD_64(0xFF, 0xFF, 0xF9, 0x42, 0xD0, 0x00, 0x16, 0x5E), + TO_CRYPT_WORD_64(0x7F, 0xFF, 0xFF, 0xB8, 0x00, 0x00, 0x01, 0xD3), + TO_CRYPT_WORD_64(0x23, 0xFF, 0xFF, 0xFD, 0xC0, 0x00, 0x00, 0x0D)}}; +#define BN_P638_h BN_ONE +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_ONE}}; +#endif // ECC_BN_P638 +#if defined ECC_SM2_P256 && ECC_SM2_P256 == YES +const struct { + crypt_uword_t allocated; + crypt_uword_t size; + crypt_uword_t d[BYTES_TO_CRYPT_WORDS(32)]; +} SM2_P256_p = {BYTES_TO_CRYPT_WORDS(32), BYTES_TO_CRYPT_WORDS(32), + {TO_CRYPT_WORD_64(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF), + TO_CRYPT_WORD_64(0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00), + TO_CRYPT_WORD_64(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF), + TO_CRYPT_WORD_64(0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF)}}; +const struct { + crypt_uword_t allocated; + crypt_uword_t size; + crypt_uword_t d[BYTES_TO_CRYPT_WORDS(32)]; +} SM2_P256_a = {BYTES_TO_CRYPT_WORDS(32), BYTES_TO_CRYPT_WORDS(32), + {TO_CRYPT_WORD_64(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC), + TO_CRYPT_WORD_64(0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00), + TO_CRYPT_WORD_64(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF), + TO_CRYPT_WORD_64(0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF)}}; +const struct { + crypt_uword_t allocated; + crypt_uword_t size; + crypt_uword_t d[BYTES_TO_CRYPT_WORDS(32)]; +} SM2_P256_b = {BYTES_TO_CRYPT_WORDS(32), BYTES_TO_CRYPT_WORDS(32), + {TO_CRYPT_WORD_64(0xDD, 0xBC, 0xBD, 0x41, 0x4D, 0x94, 0x0E, 0x93), + TO_CRYPT_WORD_64(0xF3, 0x97, 0x89, 0xF5, 0x15, 0xAB, 0x8F, 0x92), + TO_CRYPT_WORD_64(0x4D, 0x5A, 0x9E, 0x4B, 0xCF, 0x65, 0x09, 0xA7), + TO_CRYPT_WORD_64(0x28, 0xE9, 0xFA, 0x9E, 0x9D, 0x9F, 0x5E, 0x34)}}; +const struct { + crypt_uword_t allocated; + crypt_uword_t size; + crypt_uword_t d[BYTES_TO_CRYPT_WORDS(32)]; +} SM2_P256_gX = {BYTES_TO_CRYPT_WORDS(32), BYTES_TO_CRYPT_WORDS(32), + {TO_CRYPT_WORD_64(0x71, 0x5A, 0x45, 0x89, 0x33, 0x4C, 0x74, 0xC7), + TO_CRYPT_WORD_64(0x8F, 0xE3, 0x0B, 0xBF, 0xF2, 0x66, 0x0B, 0xE1), + TO_CRYPT_WORD_64(0x5F, 0x99, 0x04, 0x46, 0x6A, 0x39, 0xC9, 0x94), + TO_CRYPT_WORD_64(0x32, 0xC4, 0xAE, 0x2C, 0x1F, 0x19, 0x81, 0x19)}}; +const struct { + crypt_uword_t allocated; + crypt_uword_t size; + crypt_uword_t d[BYTES_TO_CRYPT_WORDS(32)]; +} SM2_P256_gY = {BYTES_TO_CRYPT_WORDS(32), BYTES_TO_CRYPT_WORDS(32), + {TO_CRYPT_WORD_64(0x02, 0xDF, 0x32, 0xE5, 0x21, 0x39, 0xF0, 0xA0), + TO_CRYPT_WORD_64(0xD0, 0xA9, 0x87, 0x7C, 0xC6, 0x2A, 0x47, 0x40), + TO_CRYPT_WORD_64(0x59, 0xBD, 0xCE, 0xE3, 0x6B, 0x69, 0x21, 0x53), + TO_CRYPT_WORD_64(0xBC, 0x37, 0x36, 0xA2, 0xF4, 0xF6, 0x77, 0x9C)}}; +const struct { + crypt_uword_t allocated; + crypt_uword_t size; + crypt_uword_t d[BYTES_TO_CRYPT_WORDS(32)]; +} SM2_P256_n = {BYTES_TO_CRYPT_WORDS(32), BYTES_TO_CRYPT_WORDS(32), + {TO_CRYPT_WORD_64(0x53, 0xBB, 0xF4, 0x09, 0x39, 0xD5, 0x41, 0x23), + TO_CRYPT_WORD_64(0x72, 0x03, 0xDF, 0x6B, 0x21, 0xC6, 0x05, 0x2B), + TO_CRYPT_WORD_64(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF), + TO_CRYPT_WORD_64(0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF)}}; +#define SM2_P256_h BN_ONE +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)&BN_ONE}}; +#endif // ECC_SM2_P256 +#define comma +const ECC_CURVE eccCurves[] = { +#if defined ECC_NIST_P192 && ECC_NIST_P192 == YES + comma + {TPM_ECC_NIST_P192, + 192, + {ALG_KDF1_SP800_56A_VALUE, {{ALG_SHA256_VALUE}}}, + {ALG_NULL_VALUE, {{ALG_NULL_VALUE}}}, + &NIST_P192 CURVE_NAME("NIST_P192")} +# undef comma +# define comma , +#endif // ECC_NIST_P192 +#if defined ECC_NIST_P224 && ECC_NIST_P224 == YES + comma + {TPM_ECC_NIST_P224, + 224, + {ALG_KDF1_SP800_56A_VALUE, {{ALG_SHA256_VALUE}}}, + {ALG_NULL_VALUE, {{ALG_NULL_VALUE}}}, + &NIST_P224 CURVE_NAME("NIST_P224")} +# undef comma +# define comma , +#endif // ECC_NIST_P224 +#if defined ECC_NIST_P256 && ECC_NIST_P256 == YES + comma + {TPM_ECC_NIST_P256, + 256, + {ALG_KDF1_SP800_56A_VALUE, {{ALG_SHA256_VALUE}}}, + {ALG_NULL_VALUE, {{ALG_NULL_VALUE}}}, + &NIST_P256 CURVE_NAME("NIST_P256")} +# undef comma +# define comma , +#endif // ECC_NIST_P256 +#if defined ECC_NIST_P384 && ECC_NIST_P384 == YES + comma + {TPM_ECC_NIST_P384, + 384, + {ALG_KDF1_SP800_56A_VALUE, {{ALG_SHA384_VALUE}}}, + {ALG_NULL_VALUE, {{ALG_NULL_VALUE}}}, + &NIST_P384 CURVE_NAME("NIST_P384")} +# undef comma +# define comma , +#endif // ECC_NIST_P384 +#if defined ECC_NIST_P521 && ECC_NIST_P521 == YES + comma + {TPM_ECC_NIST_P521, + 521, + {ALG_KDF1_SP800_56A_VALUE, {{ALG_SHA512_VALUE}}}, + {ALG_NULL_VALUE, {{ALG_NULL_VALUE}}}, + &NIST_P521 CURVE_NAME("NIST_P521")} +# undef comma +# define comma , +#endif // ECC_NIST_P521 +#if defined ECC_BN_P256 && ECC_BN_P256 == YES + comma + {TPM_ECC_BN_P256, + 256, + {ALG_NULL_VALUE, {{ALG_NULL_VALUE}}}, + {ALG_NULL_VALUE, {{ALG_NULL_VALUE}}}, + &BN_P256 CURVE_NAME("BN_P256")} +# undef comma +# define comma , +#endif // ECC_BN_P256 +#if defined ECC_BN_P638 && ECC_BN_P638 == YES + comma + {TPM_ECC_BN_P638, + 638, + {ALG_NULL_VALUE, {{ALG_NULL_VALUE}}}, + {ALG_NULL_VALUE, {{ALG_NULL_VALUE}}}, + &BN_P638 CURVE_NAME("BN_P638")} +# undef comma +# define comma , +#endif // ECC_BN_P638 +#if defined ECC_SM2_P256 && ECC_SM2_P256 == YES + comma + {TPM_ECC_SM2_P256, + 256, + {ALG_KDF1_SP800_56A_VALUE, {{ALG_SM3_256_VALUE}}}, + {ALG_NULL_VALUE, {{ALG_NULL_VALUE}}}, + &SM2_P256 CURVE_NAME("SM2_P256")} +# undef comma +# define comma , +#endif // ECC_SM2_P256 +}; +#endif // TPM_ALG_ECC diff --git a/src/tpm2/BnMath.c b/src/tpm2/BnMath.c new file mode 100644 index 00000000..4a44c01a --- /dev/null +++ b/src/tpm2/BnMath.c @@ -0,0 +1,530 @@ +/********************************************************************************/ +/* */ +/* */ +/* Written by Ken Goldman */ +/* IBM Thomas J. Watson Research Center */ +/* $Id: BnMath.c 953 2017-03-06 20:31: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, 2017 */ +/* */ +/********************************************************************************/ + +/* 10.2.4 BnMath.c */ +/* 10.2.4.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.4.3 Functions */ +/* 10.2.4.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.4.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.4.3.3 BnAdd() */ +/* Function to add two bigNum values. Always returns TRUEF */ +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 = AddSame(result->d, n1->d, n2->d, stop); + if(n1->size > stop) + carry = CarryProp(&result->d[stop], &n1->d[stop], n1->size - stop, carry); + CarryResolve(result, n1->size, carry); + return TRUE; +} +/* 10.2.4.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], op->size - 1, carry); + CarryResolve(result, op->size, carry); + return TRUE; +} +/* 10.2.4.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.4.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.4.3.7 BnSub() */ +/* Function to do subtraction of result = op1 - op2 when op1 is greater than op2. If it isn't then a + fault is generated. */ +LIB_EXPORT BOOL +BnSub( + bigNum result, + bigConst op1, + bigConst op2 + ) +{ + int borrow; + crypt_uword_t stop = 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 > stop) + borrow = BorrowProp(&result->d[stop], &op1->d[stop], op1->size - stop, + borrow); + pAssert(!borrow); + BnSetTop(result, op1->size); + return TRUE; +} +/* 10.2.4.3.8 BnSubWord() */ +/* Subtract a word value from a bigNum. */ +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], op->size - 1, borrow); + pAssert(!borrow); + BnSetTop(result, op->size); + return TRUE; +} +/* 10.2.4.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 = 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.4.3.10 BnUnsignedCmpWord() */ +/* Compare a bigNum to a crypt_uword_t. -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.4.3.11 BnModWord() */ +/* Find the modulus 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.4.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.4.3.13 BnMsb() */ +/* Returns the number of the MSb(). Returns a negative number if the value is zero or bn is NULL. */ +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 += (bn->size - 1) * RADIX_BITS; + return retVal; + } + else + return -1; +} +/* 10.2.4.3.14 BnSizeInBits() */ +/* Returns the number of bits required to hold a number. */ +LIB_EXPORT unsigned +BnSizeInBits( + bigConst n + ) +{ + return BnMsb(n) + 1; +} +/* 10.2.4.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.4.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] |= (1 << RADIX_MOD(bitNum)); + return TRUE; +} +/* 10.2.4.3.17 BnTestBit() */ +/* Check to see if a bit is SET in a bignum_t. The 0th bit is the LSb() of d[0] If a bit is outside + the range of the number, it returns FALSE */ +/* 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.4.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.4.3.19 BnShiftRight() */ +/* Function will shift a bigNum to the right by the shiftAmount */ +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.4.3.20 BnGetRandomBits() */ +LIB_EXPORT BOOL +BnGetRandomBits( + bigNum n, + size_t bits, + RAND_STATE *rand + ) +{ + TPM2B_TYPE(LARGEST, LARGEST_NUMBER); + TPM2B_LARGEST large; + // + large.b.size = (UINT16)BITS_TO_BYTES(bits); + DRBG_Generate(rand, large.t.buffer, large.t.size); + BnFrom2B(n, &large.b); + BnMaskBits(n, bits); + return TRUE; +} +/* 10.2.4.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. */ +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 + { + do + { + BnGetRandomBits(dest, bits, rand); + } while(BnEqualZero(dest) || BnUnsignedCmp(dest, limit) >= 0); + } + return TRUE; +} diff --git a/src/tpm2/BnMemory.c b/src/tpm2/BnMemory.c new file mode 100644 index 00000000..e84fd16f --- /dev/null +++ b/src/tpm2/BnMemory.c @@ -0,0 +1,201 @@ +/********************************************************************************/ +/* */ +/* */ +/* Written by Ken Goldman */ +/* IBM Thomas J. Watson Research Center */ +/* $Id: BnMemory.c 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 */ +/* */ +/********************************************************************************/ + +/* 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; +} +/* 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; +} +/* 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; +} +#ifdef TPM_ALG_ECC +/* 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); +} +/* 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 00000000..e24c60e1 --- /dev/null +++ b/src/tpm2/Cancel.c @@ -0,0 +1,101 @@ +/********************************************************************************/ +/* */ +/* */ +/* Written by Ken Goldman */ +/* IBM Thomas J. Watson Research Center */ +/* $Id: Cancel.c 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 */ +/* */ +/********************************************************************************/ + +/* C.2 Cancel.c */ +/* C.2.1. Introduction */ +/* This module simulates the cancel pins on the TPM. */ +/* C.2.2. Includes, Typedefs, Structures, and Defines */ +#include "PlatformData.h" +#include "Platform_fp.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 00000000..a7872b3f --- /dev/null +++ b/src/tpm2/Capabilities.h @@ -0,0 +1,77 @@ +/********************************************************************************/ +/* */ +/* 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 953 2017-03-06 20:31: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, 2017 */ +/* */ +/********************************************************************************/ + +#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)) + +#ifdef TPM_CC_AC_GetCapability +/* This is #defined because TPMA_AC_CAPABILITIES might not be defined */ +# define MAX_AC_CAPABILITIES (MAX_CAP_DATA / sizeof(TPMS_AC_OUTPUT)) +#endif +#endif diff --git a/src/tpm2/CapabilityCommands.c b/src/tpm2/CapabilityCommands.c new file mode 100644 index 00000000..984c6063 --- /dev/null +++ b/src/tpm2/CapabilityCommands.c @@ -0,0 +1,207 @@ +/********************************************************************************/ +/* */ +/* */ +/* Written by Ken Goldman */ +/* IBM Thomas J. Watson Research Center */ +/* $Id: CapabilityCommands.c 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 */ +/* */ +/********************************************************************************/ + +#include "Tpm.h" +#include "GetCapability_fp.h" +#ifdef TPM_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; +#ifdef TPM_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_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" +#ifdef TPM_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 00000000..98be3b92 --- /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/Certify_fp.h b/src/tpm2/Certify_fp.h new file mode 100644 index 00000000..2e2ff6d7 --- /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 00000000..33001e92 --- /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 00000000..ec1ba459 --- /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 00000000..730e508b --- /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 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 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 00000000..44407778 --- /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 00000000..3c57ea44 --- /dev/null +++ b/src/tpm2/Clock.c @@ -0,0 +1,287 @@ +/********************************************************************************/ +/* */ +/* Used by the simulator to mimic a hardware clock */ +/* Written by Ken Goldman */ +/* IBM Thomas J. Watson Research Center */ +/* $Id: Clock.c 953 2017-03-06 20:31: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, 2017 */ +/* */ +/********************************************************************************/ + +/* added for portability because Linux clock is 32 bits */ + +#include +#include +#include + +static uint64_t tpmclock(void); + +#ifdef TPM_WINDOWS + +/* Windows returns result in units of CLOCKS_PER_SEC. seconds = clock() / CLOCKS_PER_SEC */ + +static uint64_t tpmclock(void) +{ + clock_t clocktime = clock(); + uint64_t tpmtime = ((uint64_t)clocktime * 1000) / (uint64_t)CLOCKS_PER_SEC; + return tpmtime; +} + +#endif + +#ifdef TPM_POSIX + + +#include + +/* return time in milliseconds */ + +static uint64_t tpmclock(void) +{ + struct timeval tval; + uint64_t tpmtime; + + gettimeofday(&tval, NULL); /* get the time */ + tpmtime = ((uint64_t)tval.tv_sec * 1000) + ((uint64_t)tval.tv_usec / 1000); + return tpmtime; +} + +#endif + +/* C.3 Clock.c */ +/* C.3.1. Introduction */ +/* 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 "PlatformData.h" +#include "Platform_fp.h" +#include "TpmFail_fp.h" +#include +/* 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. */ +LIB_EXPORT void +_plat__TimerReset( + void + ) +{ + s_realTimePrevious = (clock_t) tpmclock(); /* kgold, FIXME, something wrong here */ + s_tpmTime = 0; + s_adjustRate = CLOCK_NOMINAL; + s_timerReset = TRUE; + s_timerStopped = TRUE; + 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. */ +/* C.3.4.2. _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(). */ +/* The code in this function should be replaced by a read of a hardware tick timer. */ +LIB_EXPORT uint64_t +_plat__TimerRead( + void + ) +{ +#ifdef HARDWARE_CLOCK +#error "need a defintion for reading the hardware clock" + return HARDWARE_CLOCK +#else +#define BILLION 1000000000 +#define MILLION 1000000 +#define THOUSAND 1000 + clock_t timeDiff; + uint64_t adjusted; + // Save the value previously read from the system clock + timeDiff = s_realTimePrevious; + // update with the current value of the system clock + s_realTimePrevious = tpmclock(); + // In the place below when we "put back" the unused part of the timeDiff + // it is possible that we can put back more than we take out. That is, we could + // take out 1000 mSec, rate adjust it and put back 1001 mS. This means that + // on a subsequent call, time may not have caught up. Rather than trying + // to rate adjust this, just stop time. This only occurs in a simulation so + // time for more than one command being the same should not be an issue. + if(timeDiff >= s_realTimePrevious) + { + s_realTimePrevious = timeDiff; + return s_tpmTime; + } + // Compute the amount of time since the last call to the system clock + timeDiff = s_realTimePrevious - timeDiff; + // Do the time rate adjustment and conversion from CLOCKS_PER_SEC to mSec +#if 0 + adjusted = (((uint64_t)timeDiff * (THOUSAND * CLOCK_NOMINAL)) + / ((uint64_t)s_adjustRate * CLOCKS_PER_SEC)); +#endif + /* kgold */ + adjusted = (timeDiff * (uint64_t)(s_adjustRate)) / (uint64_t)CLOCK_NOMINAL; + s_tpmTime += (clock_t)adjusted; + // 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 +#if 0 + adjusted = (adjusted * ((uint64_t)s_adjustRate * CLOCKS_PER_SEC)) + / (THOUSAND * CLOCK_NOMINAL); +#endif + // If adjusted is not the same as timeDiff, then there is some rounding + // error that needs to be pushed back into the previous sample. + // NOTE: the following is so that the fact that everything is signed will not + // matter. + s_realTimePrevious = (clock_t)((int64_t)s_realTimePrevious - adjusted); + s_realTimePrevious += timeDiff; +#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 BOOL +_plat__TimerWasReset( + void + ) +{ + BOOL 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 BOOL +_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 00000000..e3cf27ea --- /dev/null +++ b/src/tpm2/ClockCommands.c @@ -0,0 +1,110 @@ +/********************************************************************************/ +/* */ +/* Clocks and Timers */ +/* Written by Ken Goldman */ +/* IBM Thomas J. Watson Research Center */ +/* $Id: ClockCommands.c 953 2017-03-06 20:31: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, 2017 */ +/* */ +/********************************************************************************/ + +#include "Tpm.h" +#include "ReadClock_fp.h" +#ifdef TPM_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" +#ifdef TPM_CC_ClockSet // Conditional expansion of this file +TPM_RC +TPM2_ClockSet( + ClockSet_In *in // IN: input parameter list + ) +{ +#define CLOCK_UPDATE_MASK ~((1ULL << NV_CLOCK_UPDATE_INTERVAL)- 1) + // 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" +#ifdef TPM_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 00000000..0c02067b --- /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 00000000..8f76b735 --- /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 00000000..b0186873 --- /dev/null +++ b/src/tpm2/CommandAttributeData.h @@ -0,0 +1,934 @@ +/********************************************************************************/ +/* */ +/* Command code attribute array for GetCapability */ +/* Written by Ken Goldman */ +/* IBM Thomas J. Watson Research Center */ +/* $Id: CommandAttributeData.h 953 2017-03-06 20:31: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, 2017 */ +/* */ +/********************************************************************************/ + +/* 5.6 CommandAttributeData.h */ +/* This file should only be included by CommandCodeAttibutes.c */ + +#ifdef _COMMAND_CODE_ATTRIBUTES_ +#include "CommandAttributes.h" +#if defined 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) + {0x011f, 0, 1, 0, 0, 2, 0, 0, 0}, // TPM_CC_NV_UndefineSpaceSpecial +#endif +#if (PAD_LIST || CC_EvictControl) + {0x0120, 0, 1, 0, 0, 2, 0, 0, 0}, // TPM_CC_EvictControl +#endif +#if (PAD_LIST || CC_HierarchyControl) + {0x0121, 0, 1, 1, 0, 1, 0, 0, 0}, // TPM_CC_HierarchyControl +#endif +#if (PAD_LIST || CC_NV_UndefineSpace) + {0x0122, 0, 1, 0, 0, 2, 0, 0, 0}, // TPM_CC_NV_UndefineSpace +#endif +#if (PAD_LIST) + {0x0123, 0, 0, 0, 0, 0, 0, 0, 0}, // No command +#endif +#if (PAD_LIST || CC_ChangeEPS) + {0x0124, 0, 1, 1, 0, 1, 0, 0, 0}, // TPM_CC_ChangeEPS +#endif +#if (PAD_LIST || CC_ChangePPS) + {0x0125, 0, 1, 1, 0, 1, 0, 0, 0}, // TPM_CC_ChangePPS +#endif +#if (PAD_LIST || CC_Clear) + {0x0126, 0, 1, 1, 0, 1, 0, 0, 0}, // TPM_CC_Clear +#endif +#if (PAD_LIST || CC_ClearControl) + {0x0127, 0, 1, 0, 0, 1, 0, 0, 0}, // TPM_CC_ClearControl +#endif +#if (PAD_LIST || CC_ClockSet) + {0x0128, 0, 1, 0, 0, 1, 0, 0, 0}, // TPM_CC_ClockSet +#endif +#if (PAD_LIST || CC_HierarchyChangeAuth) + {0x0129, 0, 1, 0, 0, 1, 0, 0, 0}, // TPM_CC_HierarchyChangeAuth +#endif +#if (PAD_LIST || CC_NV_DefineSpace) + {0x012a, 0, 1, 0, 0, 1, 0, 0, 0}, // TPM_CC_NV_DefineSpace +#endif +#if (PAD_LIST || CC_PCR_Allocate) + {0x012b, 0, 1, 0, 0, 1, 0, 0, 0}, // TPM_CC_PCR_Allocate +#endif +#if (PAD_LIST || CC_PCR_SetAuthPolicy) + {0x012c, 0, 1, 0, 0, 1, 0, 0, 0}, // TPM_CC_PCR_SetAuthPolicy +#endif +#if (PAD_LIST || CC_PP_Commands) + {0x012d, 0, 1, 0, 0, 1, 0, 0, 0}, // TPM_CC_PP_Commands +#endif +#if (PAD_LIST || CC_SetPrimaryPolicy) + {0x012e, 0, 1, 0, 0, 1, 0, 0, 0}, // TPM_CC_SetPrimaryPolicy +#endif +#if (PAD_LIST || CC_FieldUpgradeStart) + {0x012f, 0, 0, 0, 0, 2, 0, 0, 0}, // TPM_CC_FieldUpgradeStart +#endif +#if (PAD_LIST || CC_ClockRateAdjust) + {0x0130, 0, 0, 0, 0, 1, 0, 0, 0}, // TPM_CC_ClockRateAdjust +#endif +#if (PAD_LIST || CC_CreatePrimary) + {0x0131, 0, 0, 0, 0, 1, 1, 0, 0}, // TPM_CC_CreatePrimary +#endif +#if (PAD_LIST || CC_NV_GlobalWriteLock) + {0x0132, 0, 1, 0, 0, 1, 0, 0, 0}, // TPM_CC_NV_GlobalWriteLock +#endif +#if (PAD_LIST || CC_GetCommandAuditDigest) + {0x0133, 0, 1, 0, 0, 2, 0, 0, 0}, // TPM_CC_GetCommandAuditDigest +#endif +#if (PAD_LIST || CC_NV_Increment) + {0x0134, 0, 1, 0, 0, 2, 0, 0, 0}, // TPM_CC_NV_Increment +#endif +#if (PAD_LIST || CC_NV_SetBits) + {0x0135, 0, 1, 0, 0, 2, 0, 0, 0}, // TPM_CC_NV_SetBits +#endif +#if (PAD_LIST || CC_NV_Extend) + {0x0136, 0, 1, 0, 0, 2, 0, 0, 0}, // TPM_CC_NV_Extend +#endif +#if (PAD_LIST || CC_NV_Write) + {0x0137, 0, 1, 0, 0, 2, 0, 0, 0}, // TPM_CC_NV_Write +#endif +#if (PAD_LIST || CC_NV_WriteLock) + {0x0138, 0, 1, 0, 0, 2, 0, 0, 0}, // TPM_CC_NV_WriteLock +#endif +#if (PAD_LIST || CC_DictionaryAttackLockReset) + {0x0139, 0, 1, 0, 0, 1, 0, 0, 0}, // TPM_CC_DictionaryAttackLockReset +#endif +#if (PAD_LIST || CC_DictionaryAttackParameters) + {0x013a, 0, 1, 0, 0, 1, 0, 0, 0}, // TPM_CC_DictionaryAttackParameters +#endif +#if (PAD_LIST || CC_NV_ChangeAuth) + {0x013b, 0, 1, 0, 0, 1, 0, 0, 0}, // TPM_CC_NV_ChangeAuth +#endif +#if (PAD_LIST || CC_PCR_Event) + {0x013c, 0, 1, 0, 0, 1, 0, 0, 0}, // TPM_CC_PCR_Event +#endif +#if (PAD_LIST || CC_PCR_Reset) + {0x013d, 0, 1, 0, 0, 1, 0, 0, 0}, // TPM_CC_PCR_Reset +#endif +#if (PAD_LIST || CC_SequenceComplete) + {0x013e, 0, 0, 0, 1, 1, 0, 0, 0}, // TPM_CC_SequenceComplete +#endif +#if (PAD_LIST || CC_SetAlgorithmSet) + {0x013f, 0, 1, 0, 0, 1, 0, 0, 0}, // TPM_CC_SetAlgorithmSet +#endif +#if (PAD_LIST || CC_SetCommandCodeAuditStatus) + {0x0140, 0, 1, 0, 0, 1, 0, 0, 0}, // TPM_CC_SetCommandCodeAuditStatus +#endif +#if (PAD_LIST || CC_FieldUpgradeData) + {0x0141, 0, 1, 0, 0, 0, 0, 0, 0}, // TPM_CC_FieldUpgradeData +#endif +#if (PAD_LIST || CC_IncrementalSelfTest) + {0x0142, 0, 1, 0, 0, 0, 0, 0, 0}, // TPM_CC_IncrementalSelfTest +#endif +#if (PAD_LIST || CC_SelfTest) + {0x0143, 0, 1, 0, 0, 0, 0, 0, 0}, // TPM_CC_SelfTest +#endif +#if (PAD_LIST || CC_Startup) + {0x0144, 0, 1, 0, 0, 0, 0, 0, 0}, // TPM_CC_Startup +#endif +#if (PAD_LIST || CC_Shutdown) + {0x0145, 0, 1, 0, 0, 0, 0, 0, 0}, // TPM_CC_Shutdown +#endif +#if (PAD_LIST || CC_StirRandom) + {0x0146, 0, 1, 0, 0, 0, 0, 0, 0}, // TPM_CC_StirRandom +#endif +#if (PAD_LIST || CC_ActivateCredential) + {0x0147, 0, 0, 0, 0, 2, 0, 0, 0}, // TPM_CC_ActivateCredential +#endif +#if (PAD_LIST || CC_Certify) + {0x0148, 0, 0, 0, 0, 2, 0, 0, 0}, // TPM_CC_Certify +#endif +#if (PAD_LIST || CC_PolicyNV) + {0x0149, 0, 0, 0, 0, 3, 0, 0, 0}, // TPM_CC_PolicyNV +#endif +#if (PAD_LIST || CC_CertifyCreation) + {0x014a, 0, 0, 0, 0, 2, 0, 0, 0}, // TPM_CC_CertifyCreation +#endif +#if (PAD_LIST || CC_Duplicate) + {0x014b, 0, 0, 0, 0, 2, 0, 0, 0}, // TPM_CC_Duplicate +#endif +#if (PAD_LIST || CC_GetTime) + {0x014c, 0, 0, 0, 0, 2, 0, 0, 0}, // TPM_CC_GetTime +#endif +#if (PAD_LIST || CC_GetSessionAuditDigest) + {0x014d, 0, 0, 0, 0, 3, 0, 0, 0}, // TPM_CC_GetSessionAuditDigest +#endif +#if (PAD_LIST || CC_NV_Read) + {0x014e, 0, 0, 0, 0, 2, 0, 0, 0}, // TPM_CC_NV_Read +#endif +#if (PAD_LIST || CC_NV_ReadLock) + {0x014f, 0, 1, 0, 0, 2, 0, 0, 0}, // TPM_CC_NV_ReadLock +#endif +#if (PAD_LIST || CC_ObjectChangeAuth) + {0x0150, 0, 0, 0, 0, 2, 0, 0, 0}, // TPM_CC_ObjectChangeAuth +#endif +#if (PAD_LIST || CC_PolicySecret) + {0x0151, 0, 0, 0, 0, 2, 0, 0, 0}, // TPM_CC_PolicySecret +#endif +#if (PAD_LIST || CC_Rewrap) + {0x0152, 0, 0, 0, 0, 2, 0, 0, 0}, // TPM_CC_Rewrap +#endif +#if (PAD_LIST || CC_Create) + {0x0153, 0, 0, 0, 0, 1, 0, 0, 0}, // TPM_CC_Create +#endif +#if (PAD_LIST || CC_ECDH_ZGen) + {0x0154, 0, 0, 0, 0, 1, 0, 0, 0}, // TPM_CC_ECDH_ZGen +#endif +#if (PAD_LIST || CC_HMAC) + {0x0155, 0, 0, 0, 0, 1, 0, 0, 0}, // TPM_CC_HMAC +#endif +#if (PAD_LIST || CC_Import) + {0x0156, 0, 0, 0, 0, 1, 0, 0, 0}, // TPM_CC_Import +#endif +#if (PAD_LIST || CC_Load) + {0x0157, 0, 0, 0, 0, 1, 1, 0, 0}, // TPM_CC_Load +#endif +#if (PAD_LIST || CC_Quote) + {0x0158, 0, 0, 0, 0, 1, 0, 0, 0}, // TPM_CC_Quote +#endif +#if (PAD_LIST || CC_RSA_Decrypt) + {0x0159, 0, 0, 0, 0, 1, 0, 0, 0}, // TPM_CC_RSA_Decrypt +#endif +#if (PAD_LIST) + {0x015a, 0, 0, 0, 0, 0, 0, 0, 0}, // No command +#endif +#if (PAD_LIST || CC_HMAC_Start) + {0x015b, 0, 0, 0, 0, 1, 1, 0, 0}, // TPM_CC_HMAC_Start +#endif +#if (PAD_LIST || CC_SequenceUpdate) + {0x015c, 0, 0, 0, 0, 1, 0, 0, 0}, // TPM_CC_SequenceUpdate +#endif +#if (PAD_LIST || CC_Sign) + {0x015d, 0, 0, 0, 0, 1, 0, 0, 0}, // TPM_CC_Sign +#endif +#if (PAD_LIST || CC_Unseal) + {0x015e, 0, 0, 0, 0, 1, 0, 0, 0}, // TPM_CC_Unseal +#endif +#if (PAD_LIST) + {0x015f, 0, 0, 0, 0, 0, 0, 0, 0}, // No command +#endif +#if (PAD_LIST || CC_PolicySigned) + {0x0160, 0, 0, 0, 0, 2, 0, 0, 0}, // TPM_CC_PolicySigned +#endif +#if (PAD_LIST || CC_ContextLoad) + {0x0161, 0, 0, 0, 0, 0, 1, 0, 0}, // TPM_CC_ContextLoad +#endif +#if (PAD_LIST || CC_ContextSave) + {0x0162, 0, 0, 0, 0, 1, 0, 0, 0}, // TPM_CC_ContextSave +#endif +#if (PAD_LIST || CC_ECDH_KeyGen) + {0x0163, 0, 0, 0, 0, 1, 0, 0, 0}, // TPM_CC_ECDH_KeyGen +#endif +#if (PAD_LIST || CC_EncryptDecrypt) + {0x0164, 0, 0, 0, 0, 1, 0, 0, 0}, // TPM_CC_EncryptDecrypt +#endif +#if (PAD_LIST || CC_FlushContext) + {0x0165, 0, 0, 0, 0, 0, 0, 0, 0}, // TPM_CC_FlushContext +#endif +#if (PAD_LIST) + {0x0166, 0, 0, 0, 0, 0, 0, 0, 0}, // No command +#endif +#if (PAD_LIST || CC_LoadExternal) + {0x0167, 0, 0, 0, 0, 0, 1, 0, 0}, // TPM_CC_LoadExternal +#endif +#if (PAD_LIST || CC_MakeCredential) + {0x0168, 0, 0, 0, 0, 1, 0, 0, 0}, // TPM_CC_MakeCredential +#endif +#if (PAD_LIST || CC_NV_ReadPublic) + {0x0169, 0, 0, 0, 0, 1, 0, 0, 0}, // TPM_CC_NV_ReadPublic +#endif +#if (PAD_LIST || CC_PolicyAuthorize) + {0x016a, 0, 0, 0, 0, 1, 0, 0, 0}, // TPM_CC_PolicyAuthorize +#endif +#if (PAD_LIST || CC_PolicyAuthValue) + {0x016b, 0, 0, 0, 0, 1, 0, 0, 0}, // TPM_CC_PolicyAuthValue +#endif +#if (PAD_LIST || CC_PolicyCommandCode) + {0x016c, 0, 0, 0, 0, 1, 0, 0, 0}, // TPM_CC_PolicyCommandCode +#endif +#if (PAD_LIST || CC_PolicyCounterTimer) + {0x016d, 0, 0, 0, 0, 1, 0, 0, 0}, // TPM_CC_PolicyCounterTimer +#endif +#if (PAD_LIST || CC_PolicyCpHash) + {0x016e, 0, 0, 0, 0, 1, 0, 0, 0}, // TPM_CC_PolicyCpHash +#endif +#if (PAD_LIST || CC_PolicyLocality) + {0x016f, 0, 0, 0, 0, 1, 0, 0, 0}, // TPM_CC_PolicyLocality +#endif +#if (PAD_LIST || CC_PolicyNameHash) + {0x0170, 0, 0, 0, 0, 1, 0, 0, 0}, // TPM_CC_PolicyNameHash +#endif +#if (PAD_LIST || CC_PolicyOR) + {0x0171, 0, 0, 0, 0, 1, 0, 0, 0}, // TPM_CC_PolicyOR +#endif +#if (PAD_LIST || CC_PolicyTicket) + {0x0172, 0, 0, 0, 0, 1, 0, 0, 0}, // TPM_CC_PolicyTicket +#endif +#if (PAD_LIST || CC_ReadPublic) + {0x0173, 0, 0, 0, 0, 1, 0, 0, 0}, // TPM_CC_ReadPublic +#endif +#if (PAD_LIST || CC_RSA_Encrypt) + {0x0174, 0, 0, 0, 0, 1, 0, 0, 0}, // TPM_CC_RSA_Encrypt +#endif +#if (PAD_LIST) + {0x0175, 0, 0, 0, 0, 0, 0, 0, 0}, // No command +#endif +#if (PAD_LIST || CC_StartAuthSession) + {0x0176, 0, 0, 0, 0, 2, 1, 0, 0}, // TPM_CC_StartAuthSession +#endif +#if (PAD_LIST || CC_VerifySignature) + {0x0177, 0, 0, 0, 0, 1, 0, 0, 0}, // TPM_CC_VerifySignature +#endif +#if (PAD_LIST || CC_ECC_Parameters) + {0x0178, 0, 0, 0, 0, 0, 0, 0, 0}, // TPM_CC_ECC_Parameters +#endif +#if (PAD_LIST || CC_FirmwareRead) + {0x0179, 0, 0, 0, 0, 0, 0, 0, 0}, // TPM_CC_FirmwareRead +#endif +#if (PAD_LIST || CC_GetCapability) + {0x017a, 0, 0, 0, 0, 0, 0, 0, 0}, // TPM_CC_GetCapability +#endif +#if (PAD_LIST || CC_GetRandom) + {0x017b, 0, 0, 0, 0, 0, 0, 0, 0}, // TPM_CC_GetRandom +#endif +#if (PAD_LIST || CC_GetTestResult) + {0x017c, 0, 0, 0, 0, 0, 0, 0, 0}, // TPM_CC_GetTestResult +#endif +#if (PAD_LIST || CC_Hash) + {0x017d, 0, 0, 0, 0, 0, 0, 0, 0}, // TPM_CC_Hash +#endif +#if (PAD_LIST || CC_PCR_Read) + {0x017e, 0, 0, 0, 0, 0, 0, 0, 0}, // TPM_CC_PCR_Read +#endif +#if (PAD_LIST || CC_PolicyPCR) + {0x017f, 0, 0, 0, 0, 1, 0, 0, 0}, // TPM_CC_PolicyPCR +#endif +#if (PAD_LIST || CC_PolicyRestart) + {0x0180, 0, 0, 0, 0, 1, 0, 0, 0}, // TPM_CC_PolicyRestart +#endif +#if (PAD_LIST || CC_ReadClock) + {0x0181, 0, 0, 0, 0, 0, 0, 0, 0}, // TPM_CC_ReadClock +#endif +#if (PAD_LIST || CC_PCR_Extend) + {0x0182, 0, 1, 0, 0, 1, 0, 0, 0}, // TPM_CC_PCR_Extend +#endif +#if (PAD_LIST || CC_PCR_SetAuthValue) + {0x0183, 0, 0, 0, 0, 1, 0, 0, 0}, // TPM_CC_PCR_SetAuthValue +#endif +#if (PAD_LIST || CC_NV_Certify) + {0x0184, 0, 0, 0, 0, 3, 0, 0, 0}, // TPM_CC_NV_Certify +#endif +#if (PAD_LIST || CC_EventSequenceComplete) + {0x0185, 0, 1, 0, 1, 2, 0, 0, 0}, // TPM_CC_EventSequenceComplete +#endif +#if (PAD_LIST || CC_HashSequenceStart) + {0x0186, 0, 0, 0, 0, 0, 1, 0, 0}, // TPM_CC_HashSequenceStart +#endif +#if (PAD_LIST || CC_PolicyPhysicalPresence) + {0x0187, 0, 0, 0, 0, 1, 0, 0, 0}, // TPM_CC_PolicyPhysicalPresence +#endif +#if (PAD_LIST || CC_PolicyDuplicationSelect) + {0x0188, 0, 0, 0, 0, 1, 0, 0, 0}, // TPM_CC_PolicyDuplicationSelect +#endif +#if (PAD_LIST || CC_PolicyGetDigest) + {0x0189, 0, 0, 0, 0, 1, 0, 0, 0}, // TPM_CC_PolicyGetDigest +#endif +#if (PAD_LIST || CC_TestParms) + {0x018a, 0, 0, 0, 0, 0, 0, 0, 0}, // TPM_CC_TestParms +#endif +#if (PAD_LIST || CC_Commit) + {0x018b, 0, 0, 0, 0, 1, 0, 0, 0}, // TPM_CC_Commit +#endif +#if (PAD_LIST || CC_PolicyPassword) + {0x018c, 0, 0, 0, 0, 1, 0, 0, 0}, // TPM_CC_PolicyPassword +#endif +#if (PAD_LIST || CC_ZGen_2Phase) + {0x018d, 0, 0, 0, 0, 1, 0, 0, 0}, // TPM_CC_ZGen_2Phase +#endif +#if (PAD_LIST || CC_EC_Ephemeral) + {0x018e, 0, 0, 0, 0, 0, 0, 0, 0}, // TPM_CC_EC_Ephemeral +#endif +#if (PAD_LIST || CC_PolicyNvWritten) + {0x018f, 0, 0, 0, 0, 1, 0, 0, 0}, // TPM_CC_PolicyNvWritten +#endif +#if (PAD_LIST || CC_PolicyTemplate) + {0x0190, 0, 0, 0, 0, 1, 0, 0, 0}, // TPM_CC_PolicyTemplate +#endif +#if (PAD_LIST || CC_CreateLoaded) + {0x0191, 0, 0, 0, 0, 1, 1, 0, 0}, // TPM_CC_CreateLoaded +#endif +#if (PAD_LIST || CC_PolicyAuthorizeNV) + {0x0192, 0, 0, 0, 0, 3, 0, 0, 0}, // TPM_CC_PolicyAuthorizeNV +#endif +#if (PAD_LIST || CC_EncryptDecrypt2) + {0x0193, 0, 0, 0, 0, 1, 0, 0, 0}, // TPM_CC_EncryptDecrypt2 +#endif +#if (PAD_LIST || CC_AC_GetCapability) + {0x0194, 0, 0, 0, 0, 1, 0, 0, 0}, // TPM_CC_AC_GetCapability +#endif +#if (PAD_LIST || CC_AC_Send) + {0x0195, 0, 0, 0, 0, 3, 0, 0, 0}, // TPM_CC_AC_Send +#endif +#if (PAD_LIST || CC_Policy_AC_SendSelect) + {0x0196, 0, 0, 0, 0, 1, 0, 0, 0}, // TPM_CC_Policy_AC_SendSelect +#endif +#if (PAD_LIST) + {0x0197, 0, 0, 0, 0, 0, 0, 0, 0}, // No command +#endif +#if (PAD_LIST || CC_Vendor_TCG_Test) + {0x0000, 0, 0, 0, 0, 0, 0, 1, 0}, // TPM_CC_Vendor_TCG_Test +#endif + + {0x0000, 0, 0, 0, 0, 0, 0, 0, 0}, // kg - terminator? +}; + /* 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) + (COMMAND_ATTRIBUTES)(CC_HMAC * // 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) + (COMMAND_ATTRIBUTES)(CC_HMAC_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) + (COMMAND_ATTRIBUTES)(0), // 0x0197 +#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 00000000..315c6505 --- /dev/null +++ b/src/tpm2/CommandAttributes.h @@ -0,0 +1,89 @@ +/********************************************************************************/ +/* */ +/* */ +/* Written by Ken Goldman */ +/* IBM Thomas J. Watson Research Center */ +/* $Id: CommandAttributes.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 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 diff --git a/src/tpm2/CommandAudit.c b/src/tpm2/CommandAudit.c new file mode 100644 index 00000000..cc70c1d2 --- /dev/null +++ b/src/tpm2/CommandAudit.c @@ -0,0 +1,260 @@ +/********************************************************************************/ +/* */ +/* */ +/* Written by Ken Goldman */ +/* IBM Thomas J. Watson Research Center */ +/* $Id: CommandAudit.c 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 */ +/* */ +/********************************************************************************/ + +/* 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 is 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. */ +void +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; + } +} +/* 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 = s_ccAttr[commandIndex].commandIndex; + if(s_ccAttr[commandIndex].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 00000000..22c7d693 --- /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 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 COMMANDAUDIT_FP_H +#define COMMANDAUDIT_FP_H + +void +CommandAuditPreInstall_Init( + void + ); +void +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 00000000..cebb5138 --- /dev/null +++ b/src/tpm2/CommandCodeAttributes.c @@ -0,0 +1,542 @@ +/********************************************************************************/ +/* */ +/* Functions for testing various command properties */ +/* Written by Ken Goldman */ +/* IBM Thomas J. Watson Research Center */ +/* $Id: CommandCodeAttributes.c 953 2017-03-06 20:31: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, 2017 */ +/* */ +/********************************************************************************/ + +/* 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 their 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. */ +#ifndef 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 */ +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(s_ccAttr[LIBRARY_COMMAND_ARRAY_SIZE].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(s_ccAttr[COMMAND_COUNT - 1].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 = s_ccAttr[commandIndex].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(s_ccAttr[LIBRARY_COMMAND_ARRAY_SIZE - 1].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(s_ccAttr[0].commandIndex >= searchIndex) + { + return NextImplementedIndex(0); + } + else + { +#ifdef 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 = s_ccAttr[commandIndex].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 */ +/* UNIMPLEMNED_COMMAND_INDEX command is not implemented */ +/* other index of the command */ +COMMAND_INDEX +CommandCodeToCommandIndex( + TPM_CC commandCode // IN: the command code to look up + ) +{ + COMMAND_INDEX searchIndex = (COMMAND_INDEX)commandCode; + BOOL vendor = (commandCode & CC_VEND) != 0; + COMMAND_INDEX commandIndex; +#if !defined 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((s_ccAttr[commandIndex].commandIndex != searchIndex) + || ((s_ccAttr[commandIndex].V == SET) && !vendor) + || ((s_ccAttr[commandIndex].V == CLEAR) && 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 !defined 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 = s_ccAttr[commandIndex].commandIndex; + if(s_ccAttr[commandIndex].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 */ +#ifndef INLINE_FUNCTIONS +int +EncryptSize( + COMMAND_INDEX commandIndex // IN: command index + ) +{ + return ((s_commandAttributes[commandIndex] & ENCRYPT_2) ? 2 : + (s_commandAttributes[commandIndex] & ENCRYPT_4) ? 4 : 0); +} +#endif // INLINE_FUNCTIONS +/* 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 */ +#ifndef INLINE_FUNCTIONS +int +DecryptSize( + COMMAND_INDEX commandIndex // IN: command index + ) +{ + return ((s_commandAttributes[commandIndex] & DECRYPT_2) ? 2 : + (s_commandAttributes[commandIndex] & DECRYPT_4) ? 4 : 0); +} +#endif // INLINE_FUNCTIONS +/* 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 */ +#ifndef INLINE_FUNCTIONS +BOOL +IsSessionAllowed( + COMMAND_INDEX commandIndex // IN: the command to be checked + ) +{ + return ((s_commandAttributes[commandIndex] & NO_SESSIONS) == 0); +} +#endif // INLINE_FUNCTIONS +/* 9.3.3.10 IsHandleInResponse() */ +/* This function determines if a command has a handle in the response */ +#ifndef INLINE_FUNCTIONS +BOOL +IsHandleInResponse( + COMMAND_INDEX commandIndex + ) +{ + return ((s_commandAttributes[commandIndex] & R_HANDLE) != 0); +} +#endif // INLINE_FUNCTIONS +/* 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(!s_ccAttr[commandIndex].V) + { + switch(s_ccAttr[commandIndex].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(!s_ccAttr[commandIndex].V) + { + switch(s_ccAttr[commandIndex].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)) + { +#ifndef 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; +} +/* 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 */ +#ifndef INLINE_FUNCTIONS +BOOL +IsVendorCommand( + COMMAND_INDEX commandIndex // IN: command index to check + ) +{ + return (s_ccAttr[commandIndex].V == SET); +} +#endif // INLINE_FUNCTIONS diff --git a/src/tpm2/CommandCodeAttributes_fp.h b/src/tpm2/CommandCodeAttributes_fp.h new file mode 100644 index 00000000..b5b78284 --- /dev/null +++ b/src/tpm2/CommandCodeAttributes_fp.h @@ -0,0 +1,123 @@ +/********************************************************************************/ +/* */ +/* */ +/* Written by Ken Goldman */ +/* IBM Thomas J. Watson Research Center */ +/* $Id: CommandCodeAttributes_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 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 + ); +BOOL +IsVendorCommand( + COMMAND_INDEX commandIndex // IN: command index to check + ); + + +#endif diff --git a/src/tpm2/CommandDispatchData.h b/src/tpm2/CommandDispatchData.h new file mode 100644 index 00000000..50934a54 --- /dev/null +++ b/src/tpm2/CommandDispatchData.h @@ -0,0 +1,4191 @@ +/********************************************************************************/ +/* */ +/* */ +/* Written by Ken Goldman */ +/* IBM Thomas J. Watson Research Center */ +/* $Id: CommandDispatchData.h 828 2016-11-18 21:19: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 */ +/* */ +/********************************************************************************/ + +#ifndef COMMANDDISPATCHDATA_H +#define COMMANDDISPATCHDATA_H + +#define END_OF_LIST 0xff +#define ADD_FLAG 0x80 + +const UNMARSHAL_t UnmarshalArray[] = { +#define TPMI_DH_CONTEXT_H_UNMARSHAL 0 + (UNMARSHAL_t)TPMI_DH_CONTEXT_Unmarshal, +#define TPMI_RH_CLEAR_H_UNMARSHAL (TPMI_DH_CONTEXT_H_UNMARSHAL + 1) + (UNMARSHAL_t)TPMI_RH_CLEAR_Unmarshal, +#define TPMI_RH_HIERARCHY_AUTH_H_UNMARSHAL (TPMI_RH_CLEAR_H_UNMARSHAL + 1) + (UNMARSHAL_t)TPMI_RH_HIERARCHY_AUTH_Unmarshal, +#define TPMI_RH_LOCKOUT_H_UNMARSHAL (TPMI_RH_HIERARCHY_AUTH_H_UNMARSHAL + 1) + (UNMARSHAL_t)TPMI_RH_LOCKOUT_Unmarshal, +#define TPMI_RH_NV_AUTH_H_UNMARSHAL (TPMI_RH_LOCKOUT_H_UNMARSHAL + 1) + (UNMARSHAL_t)TPMI_RH_NV_AUTH_Unmarshal, +#define TPMI_RH_NV_INDEX_H_UNMARSHAL (TPMI_RH_NV_AUTH_H_UNMARSHAL + 1) + (UNMARSHAL_t)TPMI_RH_NV_INDEX_Unmarshal, +#define TPMI_RH_PLATFORM_H_UNMARSHAL (TPMI_RH_NV_INDEX_H_UNMARSHAL + 1) + (UNMARSHAL_t)TPMI_RH_PLATFORM_Unmarshal, +#define TPMI_RH_PROVISION_H_UNMARSHAL (TPMI_RH_PLATFORM_H_UNMARSHAL + 1) + (UNMARSHAL_t)TPMI_RH_PROVISION_Unmarshal, +#define TPMI_SH_HMAC_H_UNMARSHAL (TPMI_RH_PROVISION_H_UNMARSHAL + 1) + (UNMARSHAL_t)TPMI_SH_HMAC_Unmarshal, +#define TPMI_SH_POLICY_H_UNMARSHAL (TPMI_SH_HMAC_H_UNMARSHAL + 1) + (UNMARSHAL_t)TPMI_SH_POLICY_Unmarshal, + // 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_t)TPMI_DH_ENTITY_Unmarshal, +#define TPMI_DH_OBJECT_H_UNMARSHAL (TPMI_DH_ENTITY_H_UNMARSHAL + 1) + (UNMARSHAL_t)TPMI_DH_OBJECT_Unmarshal, +#define TPMI_DH_PARENT_H_UNMARSHAL (TPMI_DH_OBJECT_H_UNMARSHAL + 1) + (UNMARSHAL_t)TPMI_DH_PARENT_Unmarshal, +#define TPMI_DH_PCR_H_UNMARSHAL (TPMI_DH_PARENT_H_UNMARSHAL + 1) + (UNMARSHAL_t)TPMI_DH_PCR_Unmarshal, +#define TPMI_RH_ENDORSEMENT_H_UNMARSHAL (TPMI_DH_PCR_H_UNMARSHAL + 1) + (UNMARSHAL_t)TPMI_RH_ENDORSEMENT_Unmarshal, +#define TPMI_RH_HIERARCHY_H_UNMARSHAL (TPMI_RH_ENDORSEMENT_H_UNMARSHAL + 1) + (UNMARSHAL_t)TPMI_RH_HIERARCHY_Unmarshal, + // PARAMETER_FIRST_TYPE marks the end of the handle list. +#define PARAMETER_FIRST_TYPE (TPMI_RH_HIERARCHY_H_UNMARSHAL + 1) +#define UINT32_P_UNMARSHAL (TPMI_RH_HIERARCHY_H_UNMARSHAL + 1) + (UNMARSHAL_t)UINT32_Unmarshal, +#define TPM2B_DIGEST_P_UNMARSHAL (UINT32_P_UNMARSHAL + 1) + (UNMARSHAL_t)TPM2B_DIGEST_Unmarshal, +#define TPM2B_DATA_P_UNMARSHAL (TPM2B_DIGEST_P_UNMARSHAL + 1) + (UNMARSHAL_t)TPM2B_DATA_Unmarshal, +#define TPM2B_ECC_PARAMETER_P_UNMARSHAL (TPM2B_DATA_P_UNMARSHAL + 1) + (UNMARSHAL_t)TPM2B_ECC_PARAMETER_Unmarshal, +#define TPM2B_ECC_POINT_P_UNMARSHAL (TPM2B_ECC_PARAMETER_P_UNMARSHAL + 1) + (UNMARSHAL_t)TPM2B_ECC_POINT_Unmarshal, +#define TPM2B_ENCRYPTED_SECRET_P_UNMARSHAL (TPM2B_ECC_POINT_P_UNMARSHAL + 1) + (UNMARSHAL_t)TPM2B_ENCRYPTED_SECRET_Unmarshal, +#define TPM2B_EVENT_P_UNMARSHAL (TPM2B_ENCRYPTED_SECRET_P_UNMARSHAL + 1) + (UNMARSHAL_t)TPM2B_EVENT_Unmarshal, +#define TPM2B_ID_OBJECT_P_UNMARSHAL (TPM2B_EVENT_P_UNMARSHAL + 1) + (UNMARSHAL_t)TPM2B_ID_OBJECT_Unmarshal, +#define TPM2B_IV_P_UNMARSHAL (TPM2B_ID_OBJECT_P_UNMARSHAL + 1) + (UNMARSHAL_t)TPM2B_IV_Unmarshal, +#define TPM2B_MAX_BUFFER_P_UNMARSHAL (TPM2B_IV_P_UNMARSHAL + 1) + (UNMARSHAL_t)TPM2B_MAX_BUFFER_Unmarshal, +#define TPM2B_MAX_NV_BUFFER_P_UNMARSHAL (TPM2B_MAX_BUFFER_P_UNMARSHAL + 1) + (UNMARSHAL_t)TPM2B_MAX_NV_BUFFER_Unmarshal, +#define TPM2B_NAME_P_UNMARSHAL (TPM2B_MAX_NV_BUFFER_P_UNMARSHAL + 1) + (UNMARSHAL_t)TPM2B_NAME_Unmarshal, +#define TPM2B_NV_PUBLIC_P_UNMARSHAL (TPM2B_NAME_P_UNMARSHAL + 1) + (UNMARSHAL_t)TPM2B_NV_PUBLIC_Unmarshal, +#define TPM2B_PRIVATE_P_UNMARSHAL (TPM2B_NV_PUBLIC_P_UNMARSHAL + 1) + (UNMARSHAL_t)TPM2B_PRIVATE_Unmarshal, +#define TPM2B_PUBLIC_KEY_RSA_P_UNMARSHAL (TPM2B_PRIVATE_P_UNMARSHAL + 1) + (UNMARSHAL_t)TPM2B_PUBLIC_KEY_RSA_Unmarshal, +#define TPM2B_SENSITIVE_P_UNMARSHAL (TPM2B_PUBLIC_KEY_RSA_P_UNMARSHAL + 1) + (UNMARSHAL_t)TPM2B_SENSITIVE_Unmarshal, +#define TPM2B_SENSITIVE_CREATE_P_UNMARSHAL (TPM2B_SENSITIVE_P_UNMARSHAL + 1) + (UNMARSHAL_t)TPM2B_SENSITIVE_CREATE_Unmarshal, +#define TPM2B_SENSITIVE_DATA_P_UNMARSHAL (TPM2B_SENSITIVE_CREATE_P_UNMARSHAL + 1) + (UNMARSHAL_t)TPM2B_SENSITIVE_DATA_Unmarshal, +#define TPM2B_TEMPLATE_P_UNMARSHAL (TPM2B_SENSITIVE_DATA_P_UNMARSHAL + 1) + (UNMARSHAL_t)TPM2B_TEMPLATE_Unmarshal, +#define UINT8_P_UNMARSHAL (TPM2B_TEMPLATE_P_UNMARSHAL + 1) + (UNMARSHAL_t)UINT8_Unmarshal, +#define TPMI_DH_CONTEXT_P_UNMARSHAL (UINT8_P_UNMARSHAL + 1) + (UNMARSHAL_t)TPMI_DH_CONTEXT_Unmarshal, +#define TPMI_DH_PERSISTENT_P_UNMARSHAL (TPMI_DH_CONTEXT_P_UNMARSHAL + 1) + (UNMARSHAL_t)TPMI_DH_PERSISTENT_Unmarshal, +#define TPMI_ECC_CURVE_P_UNMARSHAL (TPMI_DH_PERSISTENT_P_UNMARSHAL + 1) + (UNMARSHAL_t)TPMI_ECC_CURVE_Unmarshal, +#define TPMI_YES_NO_P_UNMARSHAL (TPMI_ECC_CURVE_P_UNMARSHAL + 1) + (UNMARSHAL_t)TPMI_YES_NO_Unmarshal, +#define TPML_ALG_P_UNMARSHAL (TPMI_YES_NO_P_UNMARSHAL + 1) + (UNMARSHAL_t)TPML_ALG_Unmarshal, +#define TPML_CC_P_UNMARSHAL (TPML_ALG_P_UNMARSHAL + 1) + (UNMARSHAL_t)TPML_CC_Unmarshal, +#define TPML_DIGEST_P_UNMARSHAL (TPML_CC_P_UNMARSHAL + 1) + (UNMARSHAL_t)TPML_DIGEST_Unmarshal, +#define TPML_DIGEST_VALUES_P_UNMARSHAL (TPML_DIGEST_P_UNMARSHAL + 1) + (UNMARSHAL_t)TPML_DIGEST_VALUES_Unmarshal, +#define TPML_PCR_SELECTION_P_UNMARSHAL (TPML_DIGEST_VALUES_P_UNMARSHAL + 1) + (UNMARSHAL_t)TPML_PCR_SELECTION_Unmarshal, +#define TPMS_CONTEXT_P_UNMARSHAL (TPML_PCR_SELECTION_P_UNMARSHAL + 1) + (UNMARSHAL_t)TPMS_CONTEXT_Unmarshal, +#define TPMT_PUBLIC_PARMS_P_UNMARSHAL (TPMS_CONTEXT_P_UNMARSHAL + 1) + (UNMARSHAL_t)TPMT_PUBLIC_PARMS_Unmarshal, +#define TPMT_TK_AUTH_P_UNMARSHAL (TPMT_PUBLIC_PARMS_P_UNMARSHAL + 1) + (UNMARSHAL_t)TPMT_TK_AUTH_Unmarshal, +#define TPMT_TK_CREATION_P_UNMARSHAL (TPMT_TK_AUTH_P_UNMARSHAL + 1) + (UNMARSHAL_t)TPMT_TK_CREATION_Unmarshal, +#define TPMT_TK_HASHCHECK_P_UNMARSHAL (TPMT_TK_CREATION_P_UNMARSHAL + 1) + (UNMARSHAL_t)TPMT_TK_HASHCHECK_Unmarshal, +#define TPMT_TK_VERIFIED_P_UNMARSHAL (TPMT_TK_HASHCHECK_P_UNMARSHAL + 1) + (UNMARSHAL_t)TPMT_TK_VERIFIED_Unmarshal, +#define TPM_CAP_P_UNMARSHAL (TPMT_TK_VERIFIED_P_UNMARSHAL + 1) + (UNMARSHAL_t)TPM_CAP_Unmarshal, +#define TPM_CLOCK_ADJUST_P_UNMARSHAL (TPM_CAP_P_UNMARSHAL + 1) + (UNMARSHAL_t)TPM_CLOCK_ADJUST_Unmarshal, +#define TPM_EO_P_UNMARSHAL (TPM_CLOCK_ADJUST_P_UNMARSHAL + 1) + (UNMARSHAL_t)TPM_EO_Unmarshal, +#define TPM_SE_P_UNMARSHAL (TPM_EO_P_UNMARSHAL + 1) + (UNMARSHAL_t)TPM_SE_Unmarshal, +#define TPM_SU_P_UNMARSHAL (TPM_SE_P_UNMARSHAL + 1) + (UNMARSHAL_t)TPM_SU_Unmarshal, +#define UINT16_P_UNMARSHAL (TPM_SU_P_UNMARSHAL + 1) + (UNMARSHAL_t)UINT16_Unmarshal, +#define UINT64_P_UNMARSHAL (UINT16_P_UNMARSHAL + 1) + (UNMARSHAL_t)UINT64_Unmarshal, + //PARAMETER_FIRST_FLAG_TYPE is the first parameter to need a flag. +#define PARAMETER_FIRST_FLAG_TYPE (UINT64_P_UNMARSHAL + 1) +#define TPM2B_PUBLIC_P_UNMARSHAL (UINT64_P_UNMARSHAL + 1) + (UNMARSHAL_t)TPM2B_PUBLIC_Unmarshal, +#define TPMI_ALG_HASH_P_UNMARSHAL (TPM2B_PUBLIC_P_UNMARSHAL + 1) + (UNMARSHAL_t)TPMI_ALG_HASH_Unmarshal, +#define TPMI_ALG_SYM_MODE_P_UNMARSHAL (TPMI_ALG_HASH_P_UNMARSHAL + 1) + (UNMARSHAL_t)TPMI_ALG_SYM_MODE_Unmarshal, +#define TPMI_DH_PCR_P_UNMARSHAL (TPMI_ALG_SYM_MODE_P_UNMARSHAL + 1) + (UNMARSHAL_t)TPMI_DH_PCR_Unmarshal, +#define TPMI_ECC_KEY_EXCHANGE_P_UNMARSHAL (TPMI_DH_PCR_P_UNMARSHAL + 1) + (UNMARSHAL_t)TPMI_ECC_KEY_EXCHANGE_Unmarshal, +#define TPMI_RH_ENABLES_P_UNMARSHAL (TPMI_ECC_KEY_EXCHANGE_P_UNMARSHAL + 1) + (UNMARSHAL_t)TPMI_RH_ENABLES_Unmarshal, +#define TPMI_RH_HIERARCHY_P_UNMARSHAL (TPMI_RH_ENABLES_P_UNMARSHAL + 1) + (UNMARSHAL_t)TPMI_RH_HIERARCHY_Unmarshal, +#define TPMT_RSA_DECRYPT_P_UNMARSHAL (TPMI_RH_HIERARCHY_P_UNMARSHAL + 1) + (UNMARSHAL_t)TPMT_RSA_DECRYPT_Unmarshal, +#define TPMT_SIGNATURE_P_UNMARSHAL (TPMT_RSA_DECRYPT_P_UNMARSHAL + 1) + (UNMARSHAL_t)TPMT_SIGNATURE_Unmarshal, +#define TPMT_SIG_SCHEME_P_UNMARSHAL (TPMT_SIGNATURE_P_UNMARSHAL + 1) + (UNMARSHAL_t)TPMT_SIG_SCHEME_Unmarshal, +#define TPMT_SYM_DEF_P_UNMARSHAL (TPMT_SIG_SCHEME_P_UNMARSHAL + 1) + (UNMARSHAL_t)TPMT_SYM_DEF_Unmarshal, +#define TPMT_SYM_DEF_OBJECT_P_UNMARSHAL (TPMT_SYM_DEF_P_UNMARSHAL + 1) + (UNMARSHAL_t)TPMT_SYM_DEF_OBJECT_Unmarshal, + +#define PARAMETER_LAST_TYPE (TPMT_SYM_DEF_OBJECT_P_UNMARSHAL) + +}; + +const MARSHAL_t MarshalArray[] = { +#define UINT32_H_MARSHAL 0 + (MARSHAL_t)UINT32_Marshal, +#define RESPONSE_PARAMETER_FIRST_TYPE (UINT32_H_MARSHAL + 1) +#define TPM2B_ATTEST_P_MARSHAL (UINT32_H_MARSHAL + 1) + (MARSHAL_t)TPM2B_ATTEST_Marshal, +#define TPM2B_CREATION_DATA_P_MARSHAL (TPM2B_ATTEST_P_MARSHAL + 1) + (MARSHAL_t)TPM2B_CREATION_DATA_Marshal, +#define TPM2B_DATA_P_MARSHAL (TPM2B_CREATION_DATA_P_MARSHAL + 1) + (MARSHAL_t)TPM2B_DATA_Marshal, +#define TPM2B_DIGEST_P_MARSHAL (TPM2B_DATA_P_MARSHAL + 1) + (MARSHAL_t)TPM2B_DIGEST_Marshal, +#define TPM2B_ECC_POINT_P_MARSHAL (TPM2B_DIGEST_P_MARSHAL + 1) + (MARSHAL_t)TPM2B_ECC_POINT_Marshal, +#define TPM2B_ENCRYPTED_SECRET_P_MARSHAL (TPM2B_ECC_POINT_P_MARSHAL + 1) + (MARSHAL_t)TPM2B_ENCRYPTED_SECRET_Marshal, +#define TPM2B_ID_OBJECT_P_MARSHAL (TPM2B_ENCRYPTED_SECRET_P_MARSHAL + 1) + (MARSHAL_t)TPM2B_ID_OBJECT_Marshal, +#define TPM2B_IV_P_MARSHAL (TPM2B_ID_OBJECT_P_MARSHAL + 1) + (MARSHAL_t)TPM2B_IV_Marshal, +#define TPM2B_MAX_BUFFER_P_MARSHAL (TPM2B_IV_P_MARSHAL + 1) + (MARSHAL_t)TPM2B_MAX_BUFFER_Marshal, +#define TPM2B_MAX_NV_BUFFER_P_MARSHAL (TPM2B_MAX_BUFFER_P_MARSHAL + 1) + (MARSHAL_t)TPM2B_MAX_NV_BUFFER_Marshal, +#define TPM2B_NAME_P_MARSHAL (TPM2B_MAX_NV_BUFFER_P_MARSHAL + 1) + (MARSHAL_t)TPM2B_NAME_Marshal, +#define TPM2B_NV_PUBLIC_P_MARSHAL (TPM2B_NAME_P_MARSHAL + 1) + (MARSHAL_t)TPM2B_NV_PUBLIC_Marshal, +#define TPM2B_PRIVATE_P_MARSHAL (TPM2B_NV_PUBLIC_P_MARSHAL + 1) + (MARSHAL_t)TPM2B_PRIVATE_Marshal, +#define TPM2B_PUBLIC_P_MARSHAL (TPM2B_PRIVATE_P_MARSHAL + 1) + (MARSHAL_t)TPM2B_PUBLIC_Marshal, +#define TPM2B_PUBLIC_KEY_RSA_P_MARSHAL (TPM2B_PUBLIC_P_MARSHAL + 1) + (MARSHAL_t)TPM2B_PUBLIC_KEY_RSA_Marshal, +#define TPM2B_SENSITIVE_DATA_P_MARSHAL (TPM2B_PUBLIC_KEY_RSA_P_MARSHAL + 1) + (MARSHAL_t)TPM2B_SENSITIVE_DATA_Marshal, +#define UINT8_P_MARSHAL (TPM2B_SENSITIVE_DATA_P_MARSHAL + 1) + (MARSHAL_t)UINT8_Marshal, +#define TPML_ALG_P_MARSHAL (UINT8_P_MARSHAL + 1) + (MARSHAL_t)TPML_ALG_Marshal, +#define TPML_DIGEST_P_MARSHAL (TPML_ALG_P_MARSHAL + 1) + (MARSHAL_t)TPML_DIGEST_Marshal, +#define TPML_DIGEST_VALUES_P_MARSHAL (TPML_DIGEST_P_MARSHAL + 1) + (MARSHAL_t)TPML_DIGEST_VALUES_Marshal, +#define TPML_PCR_SELECTION_P_MARSHAL (TPML_DIGEST_VALUES_P_MARSHAL + 1) + (MARSHAL_t)TPML_PCR_SELECTION_Marshal, +#define TPMS_ALGORITHM_DETAIL_ECC_P_MARSHAL (TPML_PCR_SELECTION_P_MARSHAL + 1) + (MARSHAL_t)TPMS_ALGORITHM_DETAIL_ECC_Marshal, +#define TPMS_CAPABILITY_DATA_P_MARSHAL (TPMS_ALGORITHM_DETAIL_ECC_P_MARSHAL + 1) + (MARSHAL_t)TPMS_CAPABILITY_DATA_Marshal, +#define TPMS_CONTEXT_P_MARSHAL (TPMS_CAPABILITY_DATA_P_MARSHAL + 1) + (MARSHAL_t)TPMS_CONTEXT_Marshal, +#define TPMS_TIME_INFO_P_MARSHAL (TPMS_CONTEXT_P_MARSHAL + 1) + (MARSHAL_t)TPMS_TIME_INFO_Marshal, +#define TPMT_HA_P_MARSHAL (TPMS_TIME_INFO_P_MARSHAL + 1) + (MARSHAL_t)TPMT_HA_Marshal, +#define TPMT_SIGNATURE_P_MARSHAL (TPMT_HA_P_MARSHAL + 1) + (MARSHAL_t)TPMT_SIGNATURE_Marshal, +#define TPMT_TK_AUTH_P_MARSHAL (TPMT_SIGNATURE_P_MARSHAL + 1) + (MARSHAL_t)TPMT_TK_AUTH_Marshal, +#define TPMT_TK_CREATION_P_MARSHAL (TPMT_TK_AUTH_P_MARSHAL + 1) + (MARSHAL_t)TPMT_TK_CREATION_Marshal, +#define TPMT_TK_HASHCHECK_P_MARSHAL (TPMT_TK_CREATION_P_MARSHAL + 1) + (MARSHAL_t)TPMT_TK_HASHCHECK_Marshal, +#define TPMT_TK_VERIFIED_P_MARSHAL (TPMT_TK_HASHCHECK_P_MARSHAL + 1) + (MARSHAL_t)TPMT_TK_VERIFIED_Marshal, +#define UINT32_P_MARSHAL (TPMT_TK_VERIFIED_P_MARSHAL + 1) + (MARSHAL_t)UINT32_Marshal, +#define UINT16_P_MARSHAL (UINT32_P_MARSHAL + 1) + (MARSHAL_t)UINT16_Marshal, + + +#define RESPONSE_PARAMETER_LAST_TYPE (UINT16_P_MARSHAL) + +}; +#if CC_Startup == YES +#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 == YES +#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 == YES +#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 == YES +#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 == YES +#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, + UINT32_P_MARSHAL, + END_OF_LIST} +}; +#define _GetTestResultDataAddress (&_GetTestResultData) +#else +#define _GetTestResultDataAddress 0 +#endif +#if CC_StartAuthSession == YES +#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_DIGEST_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, + UINT32_H_MARSHAL, + TPM2B_DIGEST_P_MARSHAL, + END_OF_LIST} +}; +#define _StartAuthSessionDataAddress (&_StartAuthSessionData) +#else +#define _StartAuthSessionDataAddress 0 +#endif +#if CC_PolicyRestart == YES +#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 == YES +#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 == YES +#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, + UINT32_H_MARSHAL, + TPM2B_NAME_P_MARSHAL, + END_OF_LIST} +}; +#define _LoadDataAddress (&_LoadData) +#else +#define _LoadDataAddress 0 +#endif +#if CC_LoadExternal == YES +#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, + UINT32_H_MARSHAL, + TPM2B_NAME_P_MARSHAL, + END_OF_LIST} +}; +#define _LoadExternalDataAddress (&_LoadExternalData) +#else +#define _LoadExternalDataAddress 0 +#endif +#if CC_ReadPublic == YES +#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 == YES +#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 == YES +#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 == YES +#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 == YES +#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_DIGEST_P_UNMARSHAL, + END_OF_LIST, + TPM2B_PRIVATE_P_MARSHAL, + END_OF_LIST} +}; +#define _ObjectChangeAuthDataAddress (&_ObjectChangeAuthData) +#else +#define _ObjectChangeAuthDataAddress 0 +#endif +#if CC_CreateLoaded == YES +#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, + UINT32_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 == YES +#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 == YES +#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 == YES +#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 == YES +#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 == YES +#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 == YES +#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 == YES +#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_Parameters == YES +#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 == YES +#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 == YES +#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_SYM_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 == YES +#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_SYM_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 == YES +#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 == YES +#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_GetRandom == YES +#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 == YES +#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 == YES +#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_DIGEST_P_UNMARSHAL, + TPMI_ALG_HASH_P_UNMARSHAL + ADD_FLAG, + END_OF_LIST, + UINT32_H_MARSHAL, + END_OF_LIST} +}; +#define _HMAC_StartDataAddress (&_HMAC_StartData) +#else +#define _HMAC_StartDataAddress 0 +#endif +#if CC_HashSequenceStart == YES +#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_DIGEST_P_UNMARSHAL, + TPMI_ALG_HASH_P_UNMARSHAL + ADD_FLAG, + END_OF_LIST, + UINT32_H_MARSHAL, + END_OF_LIST} +}; +#define _HashSequenceStartDataAddress (&_HashSequenceStartData) +#else +#define _HashSequenceStartDataAddress 0 +#endif +#if CC_SequenceUpdate == YES +#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 == YES +#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 == YES +#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 == YES +#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 == YES +#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 == YES +#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 == YES +#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 == YES +#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 == YES +#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_Commit == YES +#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 == YES +#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 == YES +#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 == YES +#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 == YES +#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 == YES +#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 == YES +#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 == YES +#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 == YES +#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, + UINT8_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 == YES +#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 == YES +#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 == YES +#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 == YES +#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_DIGEST_P_UNMARSHAL, + TPM2B_DIGEST_P_UNMARSHAL, + TPM2B_DIGEST_P_UNMARSHAL, + UINT32_P_UNMARSHAL, + TPMT_SIGNATURE_P_UNMARSHAL, + END_OF_LIST, + TPM2B_DIGEST_P_MARSHAL, + TPMT_TK_AUTH_P_MARSHAL, + END_OF_LIST} +}; +#define _PolicySignedDataAddress (&_PolicySignedData) +#else +#define _PolicySignedDataAddress 0 +#endif +#if CC_PolicySecret == YES +#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_DIGEST_P_UNMARSHAL, + TPM2B_DIGEST_P_UNMARSHAL, + TPM2B_DIGEST_P_UNMARSHAL, + UINT32_P_UNMARSHAL, + END_OF_LIST, + TPM2B_DIGEST_P_MARSHAL, + TPMT_TK_AUTH_P_MARSHAL, + END_OF_LIST} +}; +#define _PolicySecretDataAddress (&_PolicySecretData) +#else +#define _PolicySecretDataAddress 0 +#endif +#if CC_PolicyTicket == YES +#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_DIGEST_P_UNMARSHAL, + TPM2B_DIGEST_P_UNMARSHAL, + TPM2B_DIGEST_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 == YES +#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 == YES +#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 == YES +#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, + UINT8_P_UNMARSHAL, + END_OF_LIST, + END_OF_LIST} +}; +#define _PolicyLocalityDataAddress (&_PolicyLocalityData) +#else +#define _PolicyLocalityDataAddress 0 +#endif +#if CC_PolicyNV == YES +#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_DIGEST_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 == YES +#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_DIGEST_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 == YES +#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, + UINT32_P_UNMARSHAL, + END_OF_LIST, + END_OF_LIST} +}; +#define _PolicyCommandCodeDataAddress (&_PolicyCommandCodeData) +#else +#define _PolicyCommandCodeDataAddress 0 +#endif +#if CC_PolicyPhysicalPresence == YES +#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 == YES +#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 == YES +#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 == YES +#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 == YES +#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_DIGEST_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 == YES +#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 == YES +#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 == YES +#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 == YES +#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 == YES +#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 == YES +#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 == YES +#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, + UINT32_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 == YES +#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 == YES +#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_AUTH_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 == YES +#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 == YES +#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 == YES +#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 == YES +#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 == YES +#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_DIGEST_P_UNMARSHAL, + END_OF_LIST, + END_OF_LIST} +}; +#define _HierarchyChangeAuthDataAddress (&_HierarchyChangeAuthData) +#else +#define _HierarchyChangeAuthDataAddress 0 +#endif +#if CC_DictionaryAttackLockReset == YES +#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 == YES +#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 == YES +#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 == YES +#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 == YES +#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 == YES +#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 == YES +#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 == YES +#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 == YES +#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, + UINT32_H_MARSHAL, + END_OF_LIST} +}; +#define _ContextLoadDataAddress (&_ContextLoadData) +#else +#define _ContextLoadDataAddress 0 +#endif +#if CC_FlushContext == YES +#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 == YES +#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 == YES +#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 == YES +#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 == YES +#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 == YES +#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, + UINT8_P_MARSHAL, + TPMS_CAPABILITY_DATA_P_MARSHAL, + END_OF_LIST} +}; +#define _GetCapabilityDataAddress (&_GetCapabilityData) +#else +#define _GetCapabilityDataAddress 0 +#endif +#if CC_TestParms == YES +#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 == YES +#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_DIGEST_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 == YES +#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 == YES +#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 == YES +#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 == YES +#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 == YES +#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 == YES +#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 == YES +#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 == YES +#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 == YES +#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 == YES +#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 == YES +#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 == YES +#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_DIGEST_P_UNMARSHAL, + END_OF_LIST, + END_OF_LIST} +}; +#define _NV_ChangeAuthDataAddress (&_NV_ChangeAuthData) +#else +#define _NV_ChangeAuthDataAddress 0 +#endif +#if CC_NV_Certify == YES +#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_Vendor_TCG_Test == YES +#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) + (COMMAND_DESCRIPTOR_t *)_HMACDataAddress, +#endif +#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) + (COMMAND_DESCRIPTOR_t *)_HMAC_StartDataAddress, +#endif +#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_Vendor_TCG_Test) + (COMMAND_DESCRIPTOR_t *)_Vendor_TCG_TestDataAddress, +#endif + 0 +}; +#endif diff --git a/src/tpm2/CommandDispatcher.c b/src/tpm2/CommandDispatcher.c new file mode 100644 index 00000000..b1a836b2 --- /dev/null +++ b/src/tpm2/CommandDispatcher.c @@ -0,0 +1,372 @@ +/********************************************************************************/ +/* */ +/* */ +/* Written by Ken Goldman */ +/* IBM Thomas J. Watson Research Center */ +/* $Id: CommandDispatcher.c 828 2016-11-18 21:19: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 */ +/* */ +/********************************************************************************/ + +/* 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 */ +#include "Tpm.h" +#ifdef 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; +#ifdef 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 defined 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++) + { + // 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); + } + // 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; + switch(command->code) + { +#include "HandleProcess.h" +#undef handles + default: + FAIL(FATAL_ERROR_INTERNAL); + break; + } +#endif + return TPM_RC_SUCCESS; +} +TPM_RC +CommandDispatcher( + COMMAND *command + ) +{ +#if !defined TABLE_DRIVEN_DISPATCH + TPM_RC result; + BYTE *parm_buffer = command->parameterBuffer; + INT32 *paramBufferSize = &command->parameterSize; + BYTE *responseBuffer = command->responseBuffer; + INT32 resHandleSize = 0; + INT32 *responseHandleSize = &resHandleSize; + INT32 *respParmSize = &command->parameterSize; + BYTE rHandle[4]; + BYTE *responseHandle = &rHandle[0]; + INT32 rSize = MAX_RESPONSE_SIZE; // used to make sure that the marshaling + // operation does not run away due to + // bad parameter in the function + // output. + TPM_HANDLE *handles = &command->handles[0]; + switch(GetCommandCode(command->index)) + { +#include "CommandDispatcher.h" + default: + FAIL(FATAL_ERROR_INTERNAL); + break; + } + command->responseBuffer = responseBuffer; + command->handleNum = 0; + // The response handle was marshaled into rHandle. 'Unmarshal' it into + // handles. + if(*responseHandleSize > 0) + { + command->handles[command->handleNum++] = BYTE_ARRAY_TO_UINT32(rHandle); + } + return TPM_RC_SUCCESS; +#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; + // Get a buffer for the input parameters + commandIn = MemoryGetActionInputBuffer(maxInSize); + // And the output parameters + commandOut = (BYTE *)MemoryGetActionOutputBuffer((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(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); + } + if(result != TPM_RC_SUCCESS) + return result + TPM_RC_P + (TPM_RC_1 * pNum); + // 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) + return TPM_RC_SIZE; + // 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) + return result; + // 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++) + { + const MARSHAL_t f = MarshalArray[dType]; + command->parameterSize += f(&commandOut[offset], &command->responseBuffer, + &maxOutSize); + offset = *offsets++; + } + return (maxOutSize < 0) ? TPM_RC_FAILURE : TPM_RC_SUCCESS; +#endif +} diff --git a/src/tpm2/CommandDispatcher_fp.h b/src/tpm2/CommandDispatcher_fp.h new file mode 100644 index 00000000..3087a140 --- /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 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 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 00000000..6233eaf7 --- /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 00000000..05e69513 --- /dev/null +++ b/src/tpm2/CompilerDependencies.h @@ -0,0 +1,152 @@ +/********************************************************************************/ +/* */ +/* */ +/* Written by Ken Goldman */ +/* IBM Thomas J. Watson Research Center */ +/* $Id: CompilerDependencies.h 953 2017-03-06 20:31: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, 2016 */ +/* */ +/********************************************************************************/ + +#ifndef COMPILERDEPEDENCIES_H +#define COMPILERDEPEDENCIES_H + +/* 5.10 CompilerDependencies.h */ +#ifdef GCC +# undef _MSC_VER +# undef WIN32 +#endif + +// If in-line functions are not being used, define INLINE as null. If INLINE_FUNCTIONS is defined, +// then need to define INLINE for each compiler. +#ifndef INLINE_FUNCTIONS +# define INLINE +#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) +// Handling of INLINE macro +# ifdef INLINE_FUNCTIONS +# define INLINE static __inline +# endif + +// 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 +# 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 +#endif // _MSC_VER + +#ifndef _MSC_VER +# define WINAPI +# define __pragma(x) +# define REVERSE_ENDIAN_16(_Number) __builtin_bswap16(_Number) +# define REVERSE_ENDIAN_32(_Number) __builtin_bswap32(_Number) +# define REVERSE_ENDIAN_64(_Number) __builtin_bswap64(_Number) +# ifdef INLINE_FUNCTIONS +# define INLINE static inline +# endif +# if defined(__GNUC__) +# define NORETURN __attribute__((noreturn)) +# include +# else +# define NORETURN +# endif +# define LIB_EXPORT +# define LIB_IMPORT +# define _REDUCE_WARNING_LEVEL_(n) +# define _NORMAL_WARNING_LEVEL_ +# define NOT_REFERENCED(x) (x = x) +#endif // _MSC_VER + +#ifdef TPM_POSIX +typedef int SOCKET; +#endif + +#endif // COMPILERDEPEDENCIES_H diff --git a/src/tpm2/ContextCommands.c b/src/tpm2/ContextCommands.c new file mode 100644 index 00000000..b76398d7 --- /dev/null +++ b/src/tpm2/ContextCommands.c @@ -0,0 +1,436 @@ +/********************************************************************************/ +/* */ +/* */ +/* Written by Ken Goldman */ +/* IBM Thomas J. Watson Research Center */ +/* $Id: ContextCommands.c 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 */ +/* */ +/********************************************************************************/ + +#include "Tpm.h" +#include "ContextSave_fp.h" +#ifdef TPM_CC_ContextSave // Conditional expansion of this file +#include "Context_spt_fp.h" +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 + // 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; + UINT16 objectSize = ObjectIsSequence(object) + ? sizeof(HASH_OBJECT) : sizeof(OBJECT); + 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, object, objectSize); + // 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; + SequenceDataExport((HASH_OBJECT *)object, + (HASH_OBJECT_BUFFER *)outObject); + } + 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" +#ifdef TPM_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 + ) +{ + // Local Variables + 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 + // 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 = ObjectContextLoad((ANY_OBJECT_BUFFER *)buffer, + &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(!SequenceNumbereForSavedContextIsValid(&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" +#ifdef TPM_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" +#ifdef TPM_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 00000000..79e8800d --- /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 00000000..631ee915 --- /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 00000000..6d2f534d --- /dev/null +++ b/src/tpm2/Context_spt.c @@ -0,0 +1,201 @@ +/********************************************************************************/ +/* */ +/* */ +/* Written by Ken Goldman */ +/* IBM Thomas J. Watson Research Center */ +/* $Id: Context_spt.c 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 */ +/* */ +/********************************************************************************/ + +/* 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_ConextSave() 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_AUTH *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(sizeof(contextBlob->sequence) <= sizeof(sequence2B.t.buffer)); + MemoryCopy(sequence2B.t.buffer, &contextBlob->sequence, + sizeof(contextBlob->sequence)); + // Get handle value in 2B format + handle2B.t.size = sizeof(contextBlob->savedHandle); + cAssert(sizeof(contextBlob->savedHandle) <= sizeof(handle2B.t.buffer)); + MemoryCopy(handle2B.t.buffer, &contextBlob->savedHandle, + sizeof(contextBlob->savedHandle)); + // 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_AUTH *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; +} +/* 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); + } +} diff --git a/src/tpm2/Context_spt_fp.h b/src/tpm2/Context_spt_fp.h new file mode 100644 index 00000000..e2be817f --- /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 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 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 00000000..b0fa44b5 --- /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 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 */ +/* */ +/********************************************************************************/ + +#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 00000000..724d1bc8 --- /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 00000000..a9e8fa7c --- /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 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 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/CryptSelfTest.c b/src/tpm2/CryptSelfTest.c new file mode 100644 index 00000000..e1ef42a6 --- /dev/null +++ b/src/tpm2/CryptSelfTest.c @@ -0,0 +1,226 @@ +/********************************************************************************/ +/* */ +/* */ +/* Written by Ken Goldman */ +/* IBM Thomas J. Watson Research Center */ +/* $Id: CryptSelfTest.c 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 */ +/* */ +/********************************************************************************/ + +/* 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 + ) +{ +#ifdef 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 algorithms 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_SUCCESS test complete */ +/* TPM_RC_CANCELED test was canceled */ +LIB_EXPORT +TPM_RC +CryptTestAlgorithm( + TPM_ALG_ID alg, + ALGORITHM_VECTOR *toTest + ) +{ + TPM_RC result; +#if defined 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 00000000..06a5523f --- /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 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 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 00000000..2b7a0a46 --- /dev/null +++ b/src/tpm2/CryptUtil.c @@ -0,0 +1,1684 @@ +/********************************************************************************/ +/* */ +/* */ +/* Written by Ken Goldman */ +/* IBM Thomas J. Watson Research Center */ +/* $Id: CryptUtil.c 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 */ +/* */ +/********************************************************************************/ + +/* 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_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 hashBlockSize; + 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(publicArea->objectAttributes.decrypt + || publicArea->objectAttributes.sign) + { + if(sensitiveCreate->data.t.size > hashBlockSize) + 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 + { + // If the TPM is going to generate the data, then set the size to be the + // size of the digest of the algorithm + int sizeInBits = digestSize * 8; + TPM2B_SENSITIVE_DATA *key = &sensitive->sensitive.bits; + key->t.size = CryptRandMinMax(key->t.buffer, sizeInBits, sizeInBits / 2, + rand); + } + 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 == ALG_ECDAA_VALUE; +} +/* 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 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_RCS_KEY_SIZE key size in the public area does not match the size in the sensitive creation + area */ +/* TPM_RCS_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)); + } +#ifdef TPM_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 = CryptRandMinMax( + sensitive->sensitive.sym.t.buffer, keyBits, keyBits / 2, rand); + 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(); +#ifdef TPM_ALG_RSA + ok = ok && CryptRsaInit(); +#endif // TPM_ALG_RSA +#ifdef TPM_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() && CryptRandStartup() && CryptHashStartup() +#ifdef TPM_ALG_RSA + && CryptRsaStartup() +#endif // TPM_ALG_RSA +#ifdef TPM_ALG_ECC + && CryptEccStartup() +#endif // TPM_ALG_ECC + ; +#ifdef TPM_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) + { +#ifdef TPM_ALG_RSA + case TPM_ALG_RSA: +#endif +#ifdef TPM_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(encryptKey->publicArea.objectAttributes.decrypt != SET) + return TPM_RC_ATTRIBUTES; + switch(encryptKey->publicArea.type) + { +#ifdef TPM_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 +#ifdef TPM_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) + { +#ifdef TPM_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 +#ifdef TPM_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 +#ifndef TPM_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 + // which 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.b.buffer, nonceCaller->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 sessionAuth 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(publicArea->objectAttributes.restricted + && publicArea->objectAttributes.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_Derive() 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_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; + TPM_RC result = TPM_RC_SUCCESS; + // + // Set the sensitive type for the object + object->sensitive.sensitiveType = publicArea->type; + // For all objects, copy the initial authorization data + object->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(object->publicArea.objectAttributes.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) + { +#ifdef TPM_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 +#ifdef TPM_ALG_ECC + // Create ECC key + case TPM_ALG_ECC: + result = CryptEccGenerateKey(&object->publicArea, &object->sensitive, + rand); + break; +#endif // TPM_ALG_ECC + case TPM_ALG_SYMCIPHER: + result = CryptGenerateKeySymmetric(&object->publicArea, + &object->sensitive, + sensitiveCreate, rand); + break; + case TPM_ALG_KEYEDHASH: + result = CryptGenerateKeyedHash(&object->publicArea, &object->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 the proof of the storage hierarchy but the + // proof of the endorsement hierarchy would also work + if(object->attributes.primary && object->attributes.epsHierarchy) + DRBG_AdditionalData((DRBG_STATE *)rand, &gp.shProof.b); + // Set the seed value to the size of the digest produced by the nameAlg + object->sensitive.seedValue.b.size + = CryptHashGetDigestSize(publicArea->nameAlg); + object->sensitive.seedValue.t.size = CryptRandMinMax( + object->sensitive.seedValue.t.buffer, + object->sensitive.seedValue.t.size * 8, + object->sensitive.seedValue.t.size * 8 / 2, rand); + // For symmetric values, need to compute the unique value + if(publicArea->type == TPM_ALG_SYMCIPHER + || publicArea->type == TPM_ALG_KEYEDHASH) + { + CryptComputeSymmetricUnique(&object->publicArea, &object->sensitive, + &object->publicArea.unique.sym); + } + else + { + // if this is an asymmetric key and it isn't a parent, then + // can get rid of the seed. + if(publicArea->objectAttributes.sign + || !publicArea->objectAttributes.restricted) + memset(&object->sensitive.seedValue, 0, + sizeof(object->sensitive.seedValue)); + } + // Compute the name + PublicMarshalAndComputeName(&object->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) + { +#ifdef TPM_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 +#ifdef TPM_ALG_ECC + // If ECC is defined, ECDSA is mandatory +# ifndef TPM_ALG_ECDSA +# error "ECDSA is requried for ECC" +# endif + case TPM_ALG_ECDSA: + // SM2 and ECSCHNORR are optional +# ifdef TPM_ALG_SM2 + case TPM_ALG_SM2: +# endif +# ifdef TPM_ALG_ECSCHNORR + case TPM_ALG_ECSCHNORR: +# endif + //all ECC signatures look the same + return auth->signature.ecdsa.hash; +# ifdef TPM_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) + { +# ifdef TPM_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) + { +#ifdef TPM_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 +#ifdef TPM_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: +#ifdef TPM_ALG_ECDAA // ECDAA is optional + case TPM_ALG_ECDAA: +#endif +#ifdef TPM_ALG_ECSCHNORR // Schnorr is also optional + case TPM_ALG_ECSCHNORR: +#endif +#ifdef TPM_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) + { +#ifdef TPM_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 +#ifdef TPM_ALG_ECC + // If ECC is implemented ECDH is required + case TPM_ALG_ECC: + switch(scheme) + { +#ifndef TPM_ALG_ECDH +# error "ECDH is required for ECC" +#endif + case TPM_ALG_ECDH: +#ifdef TPM_ALG_SM2 + case TPM_ALG_SM2: +#endif +#ifdef TPM_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 */ +/* 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 */ +/* TRUE scheme selected */ +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) + { +#ifdef TPM_ALG_RSA + case TPM_ALG_RSA: + result = CryptRsaSign(signature, signKey, digest, NULL); + break; +#endif //TPM_ALG_RSA +#ifdef TPM_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) + { +#ifdef TPM_ALG_RSA + case TPM_ALG_RSA: + { + // + // Call RSA code to verify signature + result = CryptRsaValidateSignature(signature, signObject, digest); + break; + } +#endif //TPM_ALG_RSA +#ifdef TPM_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 CryptIsUniqueSizeValid() */ +/* This function validates that the unique values are consistent. */ +/* NOTE: This is not a comprehensive test of the public key. */ +/* Return Values Meaning */ +/* TRUE sizes are consistent */ +/* FALSE sizes are not consistent */ +BOOL +CryptIsUniqueSizeValid( + TPMT_PUBLIC *publicArea // IN: the public area to check + ) +{ + BOOL consistent = FALSE; + UINT16 keySizeInBytes; + switch(publicArea->type) + { +#ifdef TPM_ALG_RSA + case TPM_ALG_RSA: + keySizeInBytes = BITS_TO_BYTES( + publicArea->parameters.rsaDetail.keyBits); + consistent = publicArea->unique.rsa.t.size == keySizeInBytes; + break; +#endif //TPM_ALG_RSA +#ifdef TPM_ALG_ECC + case TPM_ALG_ECC: + { + keySizeInBytes = BITS_TO_BYTES(CryptEccGetKeySizeForCurve( + publicArea->parameters.eccDetail.curveID)); + consistent = keySizeInBytes > 0 + && publicArea->unique.ecc.x.t.size <= keySizeInBytes + && publicArea->unique.ecc.y.t.size <= keySizeInBytes; + } + break; +#endif //TPM_ALG_ECC + default: + // For SYMCIPHER and KEYDEDHASH objects, the unique field is the size + // of the nameAlg digest. + consistent = publicArea->unique.sym.t.size + == CryptHashGetDigestSize(publicArea->nameAlg); + break; + } + return consistent; +} +/* 10.2.6.6.18 CryptIsSensitiveSizeValid() */ +/* This function is used by TPM2_LoadExternal() to validate that the sensitive area contains a + sensitive value that is consistent with the values in the public area. */ +BOOL +CryptIsSensitiveSizeValid( + TPMT_PUBLIC *publicArea, // IN: the object's public part + TPMT_SENSITIVE *sensitiveArea // IN: the object's sensitive part + ) +{ + BOOL consistent; + UINT16 keySizeInBytes; + switch(publicArea->type) + { +#ifdef TPM_ALG_RSA + case TPM_ALG_RSA: + // sensitive prime value has to be half the size of the public modulus + keySizeInBytes = BITS_TO_BYTES(publicArea->parameters.rsaDetail.keyBits); + consistent = ((sensitiveArea->sensitive.rsa.t.size * 2) + == keySizeInBytes); + break; +#endif +#ifdef TPM_ALG_ECC + case TPM_ALG_ECC: + keySizeInBytes = BITS_TO_BYTES(CryptEccGetKeySizeForCurve( + publicArea->parameters.eccDetail.curveID)); + consistent = keySizeInBytes > 0 + && sensitiveArea->sensitive.ecc.t.size == keySizeInBytes; + break; +#endif + case TPM_ALG_SYMCIPHER: + keySizeInBytes = BITS_TO_BYTES( + publicArea->parameters.symDetail.sym.keyBits.sym); + consistent = keySizeInBytes == sensitiveArea->sensitive.sym.t.size; + break; + case TPM_ALG_KEYEDHASH: + keySizeInBytes = CryptHashGetBlockSize(publicArea->nameAlg); + // if the block size is 0, then the algorithm is TPM_ALG_NULL and the + // size of the private part is limited to 128. If the algorithm block + // size is over 128 bytes, then the size is limited to 128 bytes for + // interoperability reasons. + if((keySizeInBytes == 0) || (keySizeInBytes > 128)) + keySizeInBytes = 128; + consistent = sensitiveArea->sensitive.bits.t.size <= keySizeInBytes; + break; + default: + consistent = TRUE; + break; + } + return consistent; +} +/* 10.2.6.6.19 CryptValidateKeys() */ +/* This function is used to verify that the key material of and 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) + { +#ifdef TPM_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 +#ifdef TPM_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(¶ms->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; + TPM_ALG_ID hashAlg; + scheme = ¶ms->keyedHashDetail.scheme; + if(scheme->scheme == TPM_ALG_XOR) + hashAlg = scheme->details.xorr.hashAlg; + else if(scheme->scheme == TPM_ALG_HMAC) + hashAlg = scheme->details.hmac.hashAlg; + else if(scheme->scheme == TPM_ALG_NULL) + hashAlg = publicArea->nameAlg; + else + return TPM_RCS_SCHEME + blamePublic; + if(sensitive->sensitive.bits.t.size + > CryptHashGetBlockSize(hashAlg)) + 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; + 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(publicArea->objectAttributes.restricted + && publicArea->objectAttributes.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.20 CryptAlgSetImplemented() */ +/* This function initializes the bit vector with one bit for each implemented algorithm. This + function is called from _TPM_Init(). The vector of implemented algorithms should be generated by + the part 2 parser so that the g_implementedAlgorithms vector can be a constant. That's not how it + is now */ +void +CryptAlgsSetImplemented( + void + ) +{ + AlgorithmGetImplementedVector(&g_implementedAlgorithms); +} diff --git a/src/tpm2/CryptUtil_fp.h b/src/tpm2/CryptUtil_fp.h new file mode 100644 index 00000000..93ed5efe --- /dev/null +++ b/src/tpm2/CryptUtil_fp.h @@ -0,0 +1,225 @@ +/********************************************************************************/ +/* */ +/* */ +/* Written by Ken Goldman */ +/* IBM Thomas J. Watson Research Center */ +/* $Id: CryptUtil_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 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 + ); +BOOL +CryptIsUniqueSizeValid( + TPMT_PUBLIC *publicArea // IN: the public area to check + ); +BOOL +CryptIsSensitiveSizeValid( + TPMT_PUBLIC *publicArea, // IN: the object's public part + TPMT_SENSITIVE *sensitiveArea // IN: the object's sensitive part + ); +TPM_RC +CryptValidateKeys( + TPMT_PUBLIC *publicArea, + TPMT_SENSITIVE *sensitive, + TPM_RC blamePublic, + TPM_RC blameSensitive + ); +void +CryptAlgsSetImplemented( + void + ); + + +#endif diff --git a/src/tpm2/DA.c b/src/tpm2/DA.c new file mode 100644 index 00000000..8c8baf40 --- /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 953 2017-03-06 20:31: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, 2017 */ +/* */ +/********************************************************************************/ + +/* 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.3 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. */ +void +DAStartup( + STARTUP_TYPE type // IN: startup type + ) +{ + NOT_REFERENCED(type); +#ifndef 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)) + { +#ifdef 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; +} +/* 8.2.3.4 DARegisterFailure() */ +/* This function is called when a 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.5 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 00000000..d5ec415f --- /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 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 DA_FP_H +#define DA_FP_H + +void +DAPreInstall_Init( + void + ); +void +DAInit( + void + ); +void +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/DictionaryAttackLockReset_fp.h b/src/tpm2/DictionaryAttackLockReset_fp.h new file mode 100644 index 00000000..7be9f3ad --- /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 00000000..598e9977 --- /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 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 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 00000000..b8397966 --- /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 953 2017-03-06 20:31: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, 2017 */ +/* */ +/********************************************************************************/ + +#include "Tpm.h" +#include "DictionaryAttackLockReset_fp.h" +#ifdef TPM_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" +#ifdef TPM_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 00000000..5deffa15 --- /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 00000000..0047e9c4 --- /dev/null +++ b/src/tpm2/DuplicationCommands.c @@ -0,0 +1,348 @@ +/********************************************************************************/ +/* */ +/* */ +/* Written by Ken Goldman */ +/* IBM Thomas J. Watson Research Center */ +/* $Id: DuplicationCommands.c 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 */ +/* */ +/********************************************************************************/ + +#include "Tpm.h" +#include "Duplicate_fp.h" +#ifdef TPM_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(object->publicArea.objectAttributes.fixedParent == SET) + 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(object->publicArea.objectAttributes.encryptedDuplication == SET) + { + 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" +#ifdef TPM_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" +#ifdef TPM_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; + UINT16 innerKeySize = 0; // encrypt key size for inner + // wrapper + // Input Validation + // FixedTPM and fixedParent must be CLEAR + if(in->objectPublic.publicArea.objectAttributes.fixedTPM == SET + || in->objectPublic.publicArea.objectAttributes.fixedParent == SET) + 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(in->objectPublic.publicArea.objectAttributes.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(in->objectPublic.publicArea.objectAttributes.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(parentObject->publicArea.objectAttributes.fixedTPM == SET) + { + 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.b, 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 00000000..f6ef862e --- /dev/null +++ b/src/tpm2/EACommands.c @@ -0,0 +1,1168 @@ +/********************************************************************************/ +/* */ +/* Enhanced Authorization Commands */ +/* Written by Ken Goldman */ +/* IBM Thomas J. Watson Research Center */ +/* $Id: EACommands.c 953 2017-03-06 20:31: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, 2017 */ +/* */ +/********************************************************************************/ + +#include "Tpm.h" +#include "Policy_spt_fp.h" +#include "PolicySigned_fp.h" +#ifdef TPM_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 + /*(See part 3 specification) + // The digest is computed as: + // aHash := hash ( nonceTPM | expiration | cpHashA | policyRef) + // where: + // hash() the hash associated with the signed authorization + // nonceTPM the nonceTPM value from the TPM2_StartAuthSession . + // response If the authorization is not limited to this + // session, the size of this value is zero. + // expiration time limit on authorization set by authorizing object. + // This 32-bit value is set to zero if the expiration + // time is not being set. + // cpHashA hash of the command parameters for the command being + // approved using the hash algorithm of the PSAP session. + // Set to NULLauth if the authorization is not limited + // to a specific command. + // policyRef hash of an opaque value determined by the authorizing + // object. Set to the NULLdigest if no hash is present. + */ + // 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); + // Generate timeout buffer. The format of output timeout buffer is + // TPM-specific. + // In this implementation, the timeout parameter is the timeout relative + // to g_time with a one byte flag to indicate if the ticket will expire on + // TPM Reset + out->timeout.t.size = sizeof(authTimeout) + 1; + UINT64_TO_BYTE_ARRAY(authTimeout, out->timeout.t.buffer); + out->timeout.t.buffer[sizeof(authTimeout)] = (BYTE)expiresOnReset; + // Compute policy ticket + TicketComputeAuth(TPM_ST_AUTH_SIGNED, EntityGetHierarchy(in->authObject), + authTimeout, expiresOnReset, &in->cpHashA, &in->policyRef, + &entityName, &out->policyTicket); + } + 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" +#ifdef TPM_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); + // Generate timeout buffer. The format of output timeout buffer is + // TPM-specific. + // In this implementation, the timeout parameter is the timeout relative + // to g_time with a one byte flag to indicate if the ticket will expire on + // TPM Reset + out->timeout.t.size = sizeof(authTimeout) + 1; + UINT64_TO_BYTE_ARRAY(authTimeout, out->timeout.t.buffer); + out->timeout.t.buffer[sizeof(authTimeout)] = (BYTE)expiresOnReset; + // Compute policy ticket + TicketComputeAuth(TPM_ST_AUTH_SECRET, EntityGetHierarchy(in->authHandle), + authTimeout, expiresOnReset, &in->cpHashA, &in->policyRef, + &entityName, &out->policyTicket); + } + 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" +#ifdef TPM_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, we simply copy the value of timeout to the + // buffer. + if(in->timeout.t.size != sizeof(UINT64) + 1) + return TPM_RCS_SIZE + RC_PolicyTicket_timeout; + authTimeout = BYTE_ARRAY_TO_UINT64(in->timeout.t.buffer); + expiresOnReset = in->timeout.t.buffer[sizeof(authTimeout)]; + // 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" +#ifdef TPM_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" +#ifdef TPM_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" +#ifdef TPM_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" +#ifdef TPM_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" +#ifdef TPM_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); + // 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" +#ifdef TPM_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" +#ifdef TPM_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" +#ifdef TPM_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" +#ifdef TPM_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" +#ifdef TPM_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" +#ifdef TPM_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(!CryptHashIsImplemented(hashAlg, 0)) + 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" +#ifdef TPM_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" +#ifdef TPM_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" +#ifdef TPM_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" +#ifdef TPM_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" +#ifdef TPM_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_RCS_VALUE + RC_PolicyTemplate_templateHash; + // 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" +//#include "PolicyAuthorizeNV_fp.h" +#ifdef TPM_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 00000000..75f9cdf4 --- /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 00000000..85f16f5b --- /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 00000000..5cc5b713 --- /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 00000000..fbe4e605 --- /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 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 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 00000000..b82b0772 --- /dev/null +++ b/src/tpm2/EccTestData.h @@ -0,0 +1,159 @@ +/********************************************************************************/ +/* */ +/* Parameter data for ECC testing */ +/* Written by Ken Goldman */ +/* IBM Thomas J. Watson Research Center */ +/* $Id: EccTestData.h 953 2017-03-06 20:31: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, 2017 */ +/* */ +/********************************************************************************/ + +#ifndef ECCTESTDATA_H +#define ECCTESTDATA_H + + +/* 10.1.12 EccTestData.h */ +#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}}}; +#if ALG_SHA1_VALUE == DEFAULT_TEST_HASH +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}}}; +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,0x42,0xc6,0x0d,0x2f, + 0x86,0xa0,0x1c,0x93,0x5e,0x4a,0xad,0x0b,0x67,0xde,0x5d,0x2a,0xb1,0x08,0x4d,0xae}}}; +const TPM2B_EC_TEST c_TestEcSchnorr_s = {{32, { + 0xb1,0x37,0x7b,0xff,0xf8,0xf7,0xcf,0x2f,0xa6,0xa9,0x5a,0xb1,0x03,0xc1,0x1e,0xa7, + 0xf8,0x05,0x33,0xc0,0x0a,0x7b,0xda,0x7b,0x1a,0x00,0x47,0xe1,0x9e,0xbe,0x50,0xe4}}}; +#endif // SHA1 +#if ALG_SHA384_VALUE == DEFAULT_TEST_HASH +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}}}; +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, { + 0xad,0xe8,0xd2,0xda,0x57,0x6d,0x4a,0xe5,0xcc,0xcd,0x7c,0x14,0x1a,0x71,0x93,0xab, + 0x6b,0x9d,0x0f,0x6a,0x97,0xb2,0x32,0x75,0x6c,0xb7,0x82,0x17,0x6b,0x17,0xca,0x1b}}}; +const TPM2B_EC_TEST c_TestEcSchnorr_s = {{32, { + 0xd6,0xf1,0xe3,0x05,0xe5,0xdb,0x7c,0x8f,0x67,0x46,0x24,0x0f,0x5a,0x67,0xf8,0x2d, + 0x5e,0xcb,0xa6,0x8b,0xd7,0x80,0x66,0x83,0x36,0x50,0xd7,0x73,0x7c,0xb8,0x63,0x41}}}; +#endif // SHA384 +#if ALG_SHA256_VALUE == DEFAULT_TEST_HASH +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}}}; +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, { + 0x80,0xd5,0x77,0x52,0xf4,0x51,0x4a,0xe8,0xd0,0x28,0x91,0x98,0xbd,0x36,0x5d,0x89, + 0x24,0x0b,0xcf,0x08,0x30,0x35,0xc2,0x19,0x9f,0xf9,0x49,0x4f,0x53,0xe5,0x1f,0xe8}}}; +const TPM2B_EC_TEST c_TestEcSchnorr_s = {{32, { + 0xf7,0x47,0xda,0x09,0xc6,0xc3,0x28,0x28,0xc2,0xbd,0xbf,0xe6,0xa2,0xec,0x3f,0x44, + 0xcf,0xee,0xa2,0x30,0x96,0xe7,0xa4,0xaf,0x1f,0x37,0xac,0x1f,0xc6,0xc1,0xb4,0x25}}}; +#endif // SHA256 +#endif // SELF_TEST_DATA + +#endif diff --git a/src/tpm2/EncryptDecrypt2_fp.h b/src/tpm2/EncryptDecrypt2_fp.h new file mode 100644 index 00000000..db42733b --- /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 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 134 */ + +#ifndef ENCRYPTDECRYPT2_FP_H +#define ENCRYPTDECRYPT2_FP_H + +typedef struct { + TPMI_DH_OBJECT keyHandle; + TPM2B_MAX_BUFFER inData; + TPMI_YES_NO decrypt; + TPMI_ALG_SYM_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 00000000..c7387b38 --- /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 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 ENCRYPTDECRYPT_FP_H +#define ENCRYPTDECRYPT_FP_H + +typedef struct { + TPMI_DH_OBJECT keyHandle; + TPMI_YES_NO decrypt; + TPMI_ALG_SYM_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 00000000..ad580484 --- /dev/null +++ b/src/tpm2/EncryptDecrypt_spt.c @@ -0,0 +1,165 @@ +/********************************************************************************/ +/* */ +/* Encrypt Decrypt Support */ +/* Written by Ken Goldman */ +/* IBM Thomas J. Watson Research Center */ +/* $Id: EncryptDecrypt_spt.c 953 2017-03-06 20:31: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, 2017 */ +/* */ +/********************************************************************************/ + +/* 7.7 Encrypt Decrypt Support (EncryptDecrypt_spt.c) */ +#include "Tpm.h" +#include "EncryptDecrypt_fp.h" +#include "EncryptDecrypt_spt.h" +#ifdef TPM_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 = symKey->publicArea.objectAttributes.restricted != SET; + if(YES == decryptIn) + OK = OK && symKey->publicArea.objectAttributes.decrypt == SET; + else + OK = OK && symKey->publicArea.objectAttributes.sign == SET; + 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((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); + // 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 ALG_xxx_VALUE for + // the algorithm is always defined. Both have the same numeric value. + // ALG_xxx_VALUE 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 == ALG_ECB_VALUE) && (ivIn->t.size != 0)) + || ((mode != ALG_ECB_VALUE) && (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 == ALG_CBC_VALUE) || (mode == ALG_ECB_VALUE)) + && ((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.h b/src/tpm2/EncryptDecrypt_spt.h new file mode 100644 index 00000000..2fbe2a66 --- /dev/null +++ b/src/tpm2/EncryptDecrypt_spt.h @@ -0,0 +1,78 @@ +/********************************************************************************/ +/* */ +/* */ +/* Written by Ken Goldman */ +/* IBM Thomas J. Watson Research Center */ +/* $Id: EncryptDecrypt_spt.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_H +#define ENCRYPTDECRYPT_SPT_H + +#include "EncryptDecrypt_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/EncryptDecrypt_spt_fp.h b/src/tpm2/EncryptDecrypt_spt_fp.h new file mode 100644 index 00000000..563a435e --- /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 00000000..1cb72565 --- /dev/null +++ b/src/tpm2/Entity.c @@ -0,0 +1,486 @@ +/********************************************************************************/ +/* */ +/* Accessing properties for handles of various types */ +/* Written by Ken Goldman */ +/* IBM Thomas J. Watson Research Center */ +/* $Id: Entity.c 953 2017-03-06 20:31: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, 2017 */ +/* */ +/********************************************************************************/ + +/* 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: + break; + default: + // handling of the manufacture_specific handles + if(((TPM_RH)handle >= TPM_RH_AUTH_00) + && ((TPM_RH)handle <= TPM_RH_AUTH_FF)) + // use the value that would have been returned from + // unmarshaling if it did the handle filtering + result = TPM_RC_VALUE; + else + FAIL(FATAL_ERROR_INTERNAL); + 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; +#ifdef TPM_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; + 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 + pAauth = &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(&auth->b, &pAuth->b, 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; + default: + return 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(IsNv_TPMA_NV_PLATFORMCREATE(nvIndex->publicArea.attributes)) + 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 complier happy + return hierarchy; +} diff --git a/src/tpm2/Entity_fp.h b/src/tpm2/Entity_fp.h new file mode 100644 index 00000000..17ea7214 --- /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 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 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 00000000..3dc54bef --- /dev/null +++ b/src/tpm2/Entropy.c @@ -0,0 +1,114 @@ +/********************************************************************************/ +/* */ +/* */ +/* Written by Ken Goldman */ +/* IBM Thomas J. Watson Research Center */ +/* $Id: Entropy.c 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 */ +/* */ +/********************************************************************************/ + +/* C.4 Entropy.c */ +/* C.4.1. Includes */ +#define _CRT_RAND_S +#include +#include +#include "PlatformData.h" +#include "Platform_fp.h" +/* C.4.2. Local values */ +/* 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; +extern int firstValue; +/* C.4.3. _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. If the caller does not ask for any + entropy, then this is a startup indication and firstValue should be reset. */ +/* 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; + int OK = 1; + if(amount == 0) + { + firstValue = 1; + return 0; + } + // Only provide entropy 32 bits at a time to test the ability + // of the caller to deal with partial results. + rndNum = rand(); + if(firstValue) + firstValue = 0; + else + OK = (rndNum != lastEntropy); + if(OK) + { + lastEntropy = rndNum; + if(amount > sizeof(rndNum)) + amount = sizeof(rndNum); + memcpy(entropy, &rndNum, amount); + } + return (OK) ? (int32_t)amount : -1; +} diff --git a/src/tpm2/EphemeralCommands.c b/src/tpm2/EphemeralCommands.c new file mode 100644 index 00000000..15f459cd --- /dev/null +++ b/src/tpm2/EphemeralCommands.c @@ -0,0 +1,194 @@ +/********************************************************************************/ +/* */ +/* */ +/* Written by Ken Goldman */ +/* IBM Thomas J. Watson Research Center */ +/* $Id: EphemeralCommands.c 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 */ +/* */ +/********************************************************************************/ + +#include "Tpm.h" +#include "Commit_fp.h" +#ifdef TPM_CC_Commit // Conditional expansion of this file +#ifdef TPM_ALG_ECC +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 +#endif // CC_Commit +#include "Tpm.h" +#include "EC_Ephemeral_fp.h" +#ifdef TPM_CC_EC_Ephemeral // Conditional expansion of this file +#ifdef TPM_ALG_ECC +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 +#endif // CC_EC_Ephemeral diff --git a/src/tpm2/EventSequenceComplete_fp.h b/src/tpm2/EventSequenceComplete_fp.h new file mode 100644 index 00000000..aa75a81d --- /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 00000000..e3e1fcb0 --- /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 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 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 00000000..9939650e --- /dev/null +++ b/src/tpm2/ExecCommand.c @@ -0,0 +1,313 @@ +/********************************************************************************/ +/* */ +/* */ +/* Written by Ken Goldman */ +/* IBM Thomas J. Watson Research Center */ +/* $Id: ExecCommand.c 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 */ +/* */ +/********************************************************************************/ + +/* 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" +/* 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 BuildResponseSessions() 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) + { +#ifdef 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 00000000..6b3efedb --- /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 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 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 00000000..8e3a2dcb --- /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 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 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 00000000..52b81d3d --- /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 00000000..e3467ca1 --- /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 00000000..27326d08 --- /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 00000000..412ce4b2 --- /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 00000000..fcc9f0fc --- /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 827 2016-11-18 20:45: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-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 00000000..0aeba2a1 --- /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 00000000..4d49be5f --- /dev/null +++ b/src/tpm2/Global.c @@ -0,0 +1,200 @@ +/********************************************************************************/ +/* */ +/* TPM variables that are not stack allocated */ +/* Written by Ken Goldman */ +/* IBM Thomas J. Watson Research Center */ +/* $Id: Global.c 953 2017-03-06 20:31: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, 2017 */ +/* */ +/********************************************************************************/ + +/* 9.5 Global.c */ +/* 9.5.1 Description */ +/* This file will instance the TPM variables that are not stack allocated. The descriptions for + these variables is in Global.h. */ +/* 9.5.2 Includes and Defines */ +#define GLOBAL_C +#include "Tpm.h" +/* 9.5.3 Global Data Values */ +/* These values are visible across multiple modules. */ +BOOL g_phEnable; +const UINT16 g_rcIndex[15] = {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 +}; +TPM_HANDLE g_exclusiveAuditSession; +UINT64 g_time; +#ifdef CLOCK_STOPS +CLOCK_NONCE g_timeEpoch; +#endif +BOOL g_timeNewEpochNeeded; +BOOL g_pcrReConfig; +TPMI_DH_OBJECT g_DRTMHandle; +BOOL g_DrtmPreStartup; +BOOL g_StartupLocality3; +#ifdef USE_DA_USED +BOOL g_daUsed; +#endif +BOOL g_powerWasLost; +BOOL g_clearOrderly; +TPM_SU g_prevOrderlyState; +UPDATE_TYPE g_updateNV; +BOOL g_nvOk; +TPM_RC g_NvStatus; +TPM2B_AUTH g_platformUniqueDetails; +STATE_CLEAR_DATA gc; +STATE_RESET_DATA gr; +PERSISTENT_DATA gp; +ORDERLY_DATA go; +/* 9.5.4 Private Values */ +/* 9.5.4.1 SessionProcess.c */ +#ifndef __IGNORE_STATE__ // DO NOT DEFINE THIS VALUE +/* These values do not need to be retained between commands. */ +TPM_HANDLE s_sessionHandles[MAX_SESSION_NUM]; +TPMA_SESSION s_attributes[MAX_SESSION_NUM]; +TPM_HANDLE s_associatedHandles[MAX_SESSION_NUM]; +TPM2B_NONCE s_nonceCaller[MAX_SESSION_NUM]; +TPM2B_AUTH s_inputAuthValues[MAX_SESSION_NUM]; +SESSION *s_usedSessions[MAX_SESSION_NUM]; +UINT32 s_encryptSessionIndex; +UINT32 s_decryptSessionIndex; +UINT32 s_auditSessionIndex; +UINT32 s_sessionNum; +#endif // __IGNORE_STATE__ +BOOL s_DAPendingOnNV; +#ifdef TPM_CC_GetCommandAuditDigest +TPM2B_DIGEST s_cpHashForCommandAudit; +#endif +/* 9.5.4.2 DA.c */ +#ifndef ACCUMULATE_SELF_HEAL_TIMER +UINT64 s_selfHealTimer; +UINT64 s_lockoutTimer; +#endif // !ACCUMULATE_SELF_HEAL_TIMER +/* 9.5.4.3 NV.c */ +UINT64 s_maxCounter; +NV_REF s_evictNvEnd; +TPM_RC g_NvStatus; +BYTE s_indexOrderlyRam[RAM_INDEX_SPACE]; +NV_INDEX s_cachedNvIndex; +NV_REF s_cachedNvRef; +BYTE *s_cachedNvRamRef; +/* 9.5.4.4 Object.c */ +OBJECT s_objects[MAX_LOADED_OBJECTS]; +/* 9.5.4.5 PCR.c */ +PCR s_pcrs[IMPLEMENTATION_PCR]; +/* 9.5.4.6 Session.c */ +SESSION_SLOT s_sessions[MAX_LOADED_SESSIONS]; +UINT32 s_oldestSavedSession; +int s_freeSessionSlots; +/* 9.5.4.7 MemoryLib.c */ +/* The s_actionOutputBuffer should not be modifiable by the host system until the TPM has returned a + response code. The s_actionOutputBuffer should not be accessible until response parameter + encryption, if any, is complete. This memory is not used between commands */ +#ifndef __IGNORE_STATE__ // DO NOT DEFINE THIS VALUE +UINT32 s_actionInputBuffer[1024]; // action input buffer +UINT32 s_actionOutputBuffer[1024]; // action output buffer +#endif +/* 9.5.4.8 SelfTest.c */ +ALGORITHM_VECTOR g_implementedAlgorithms; +ALGORITHM_VECTOR g_toTest; +/* 9.5.4.9 g_cryptoSelfTestState */ +/* This structure contains the cryptographic self-test state values. */ +CRYPTO_SELF_TEST_STATE g_cryptoSelfTestState; +ALGORITHM_VECTOR AlgToTest; +/* 9.5.4.10 TpmFail.c */ +#ifdef SIMULATION +BOOL g_forceFailureMode; +#endif +BOOL g_inFailureMode; +UINT32 s_failFunction; +UINT32 s_failLine; +UINT32 s_failCode; +#if 0 +#ifdef TPM_ALG_ECC +/* 9.5.4.11 ECC Curves */ +ECC_CURVE c_curves[ECC_CURVE_COUNT]; +#endif +#endif // 0 +/* 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. */ +RAND_STATE *s_random; +/* 9.5.4.12 Manufacture.c */ +/* The values is here rather than in the simulator or platform files in order to make it easier to + find the TPM state. This is significant when trying to do TPM virtualization when the TPM state + has to be moved along with virtual machine with which it is associated. */ +BOOL g_manufactured = FALSE; +/* 9.5.4.13 Power.c */ +/* This is here for the same reason that g_manufactured is here. Both of these values can be + provided by the actual platform-specific code or by hardware indications. */ +BOOL g_initialized; +/* 9.5.4.14 Purpose String Constants */ +/* These string constants are shared across functions to make sure that they are all using + consistent sting values. */ +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"); +#ifdef SELF_TEST +TPM2B_STRING(OAEP_TEST_STRING, "OAEP Test Value"); +#endif // SELF_TEST diff --git a/src/tpm2/Global.h b/src/tpm2/Global.h new file mode 100644 index 00000000..06b35770 --- /dev/null +++ b/src/tpm2/Global.h @@ -0,0 +1,1093 @@ +/********************************************************************************/ +/* */ +/* Internal Global Type Definitions */ +/* Written by Ken Goldman */ +/* IBM Thomas J. Watson Research Center */ +/* $Id: Global.h 953 2017-03-06 20:31: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, 2017 */ +/* */ +/********************************************************************************/ + +/* 5.12 Global.h */ + +#if !defined _TPM_H_ +#error "Should not be called" +#endif + +#ifndef GLOBAL_H +#define GLOBAL_H +//#define SELF_TEST +_REDUCE_WARNING_LEVEL_(2) +#include +//#include +#include +_NORMAL_WARNING_LEVEL_ +#ifdef SIMULATION +#undef CONTEXT_SLOT +# define CONTEXT_SLOT UINT8 +#endif +#include "Capabilities.h" +#include "TpmTypes.h" +#include "CommandAttributes.h" +#include "CryptTest.h" +#include "BnValues.h" +#include "CryptHash.h" +#include "CryptRand.h" +#include "CryptEcc.h" +#include "CryptRsa.h" +#include "CryptTest.h" +#include "TpmError.h" +#include "NV.h" +//** Defines and Types +//*** Crypto Self-Test Values +extern ALGORITHM_VECTOR g_implementedAlgorithms; +extern ALGORITHM_VECTOR g_toTest; +//*** 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)]; +/* 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. */ +#ifdef CLOCK_STOPS +typedef UINT64 CLOCK_NONCE; +#else +typedef UINT32 CLOCK_NONCE; +#endif +/* 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 +{ + 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 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(); +} OBJECT_ATTRIBUTES; +/* 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 +#ifdef TPM_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. +} OBJECT; +/* 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)]; +/* 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)]; +/* 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)) +/* 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 +{ + 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; //3) 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. +} SESSION_ATTRIBUTES; +/* 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)]; +/* 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. */ +typedef struct PCR_SAVE +{ +#ifdef TPM_ALG_SHA1 + BYTE sha1[NUM_STATIC_PCR][SHA1_DIGEST_SIZE]; +#endif +#ifdef TPM_ALG_SHA256 + BYTE sha256[NUM_STATIC_PCR][SHA256_DIGEST_SIZE]; +#endif +#ifdef TPM_ALG_SHA384 + BYTE sha384[NUM_STATIC_PCR][SHA384_DIGEST_SIZE]; +#endif +#ifdef TPM_ALG_SHA512 + BYTE sha512[NUM_STATIC_PCR][SHA512_DIGEST_SIZE]; +#endif +#ifdef TPM_ALG_SM3_256 + BYTE sm3_256[NUM_STATIC_PCR][SM3_256_DIGEST_SIZE]; +#endif + // 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; +#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; + TPM2B_DIGEST policy[NUM_POLICY_PCR_GROUP]; +} PCR_POLICY; +#endif +/* 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; +/* 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; +/* 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; +/* 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; +/* This structure deals with the possible endianess 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 == YES +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; + +/* 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. */ +#ifdef TPM_ALG_ECC +#define COMMIT_INDEX_MASK ((UINT16)((sizeof(gr.commitArray)*8)-1)) +#endif +/* 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. */ +extern const UINT16 g_rcIndex[15]; +/* 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; +/* This is the value in which we keep the current command time. This is initialized at the start of + each command. The time is in mS. */ +extern UINT64 g_time; +/* 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. */ +#ifdef CLOCK_STOPS +extern CLOCK_NONCE g_timeEpoch; +#else +#define g_timeEpoch gp.timeEpoch +#endif +/* 5.12.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.12.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.12.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.12.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.12.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.12.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.12.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.12.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 +#ifdef USE_DA_USED +/* 5.12.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 that gp.orderly is set to SU_NONE_VALUE */ +extern BOOL g_daUsed; +#endif +/* 5.12.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.12.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.12.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.12.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.12.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.12.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 + +/* 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; + // Note there is a nullSeed in the state_reset memory. + // Hierarchy proofs + TPM2B_AUTH phProof; + TPM2B_AUTH shProof; + TPM2B_AUTH 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. +#ifndef CLOCK_STOPS + CLOCK_NONCE timeEpoch; +#endif +} PERSISTENT_DATA; +extern PERSISTENT_DATA gp; +/* 5.12.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. +#ifdef 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 +} ORDERLY_DATA; +#ifdef 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.12.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; +} STATE_CLEAR_DATA; +extern STATE_CLEAR_DATA gc; +/* 5.12.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_AUTH 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 + // 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. +#ifndef NDEBUG +#undef CONTEXT_SLOT +#define CONTEXT_SLOT BYTE +#endif + 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. +#ifdef TPM_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 //TPM_ALG_ECC +} STATE_RESET_DATA; +extern STATE_RESET_DATA gr; +/* 5.12.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 */ +#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 (NV_ORDERLY_DATA + sizeof(ORDERLY_DATA)) +#define NV_USER_DYNAMIC (NV_INDEX_RAM_DATA + sizeof(s_indexOrderlyRam)) +#define NV_USER_DYNAMIC_END NV_MEMORY_SIZE +/* 5.12.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)) +typedef struct _COMMAND_FLAGS_ +{ + 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. +} COMMAND_FLAGS; +/* This structure is used to avoid having to manage a large number of parameters being passed + through various levels of the command input processing. */ +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 +#if ALG_SHA1 + TPM2B_SHA1_DIGEST sha1CpHash; + TPM2B_SHA1_DIGEST sha1RpHash; +#endif +#if ALG_SHA256 + TPM2B_SHA256_DIGEST sha256CpHash; + TPM2B_SHA256_DIGEST sha256RpHash; +#endif +#if ALG_SHA384 + TPM2B_SHA384_DIGEST sha384CpHash; + TPM2B_SHA384_DIGEST sha384RpHash; +#endif +#if ALG_SHA512 + TPM2B_SHA512_DIGEST sha512CpHash; + TPM2B_SHA512_DIGEST sha512RpHash; +#endif +#if ALG_SM3_256 + TPM2B_SM3_256_DIGEST sm3_256CpHash; + TPM2B_SM3_256_DIGEST sm3_256RpHash; +#endif +} COMMAND; +/* Global sting constants for consistency in KDF function calls. */ +extern const TPM2B *PRIMARY_OBJECT_CREATION; +extern const TPM2B *SECRET_KEY; +extern const TPM2B *SESSION_KEY; +extern const TPM2B *STORAGE_KEY; +extern const TPM2B *INTEGRITY_KEY; +extern const TPM2B *CONTEXT_KEY; +extern const TPM2B *CFB_KEY; +extern const TPM2B *XOR_KEY; +extern const TPM2B *DUPLICATE_STRING; +extern const TPM2B *OBFUSCATE_STRING; +extern const TPM2B *IDENTITY_STRING; +extern const TPM2B *COMMIT_STRING; +#ifdef SELF_TEST +extern const TPM2B *OAEP_TEST_STRING; +#endif // SELF_TEST +/* 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.12.14 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 */ +#ifdef TPM_CC_GetCommandAuditDigest +extern TPM2B_DIGEST s_cpHashForCommandAudit; +#endif +/* Number of authorization sessions present in the command */ +/* extern UINT32 s_sessionNum; Flag indicating if NV update is pending for the lockOutAuthEnabled or + failedTries DA parameter */ +extern BOOL s_DAPendingOnNV; +#endif // SESSION_PROCESS_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. */ +#ifndef 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 +#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 +#if defined OBJECT_C || defined GLOBAL_C +/* From Object.c */ +/* This type is the container for an object. */ +extern OBJECT s_objects[MAX_LOADED_OBJECTS]; +#endif // OBJECT_C +#if defined PCR_C || defined GLOBAL_C +/* From PCR.c */ +typedef struct +{ +#ifdef TPM_ALG_SHA1 + // SHA1 PCR + BYTE sha1Pcr[SHA1_DIGEST_SIZE]; +#endif +#ifdef TPM_ALG_SHA256 + // SHA256 PCR + BYTE sha256Pcr[SHA256_DIGEST_SIZE]; +#endif +#ifdef TPM_ALG_SHA384 + // SHA384 PCR + BYTE sha384Pcr[SHA384_DIGEST_SIZE]; +#endif +#ifdef TPM_ALG_SHA512 + // SHA512 PCR + BYTE sha512Pcr[SHA512_DIGEST_SIZE]; +#endif +#ifdef TPM_ALG_SM3_256 + // SHA256 PCR + BYTE sm3_256Pcr[SM3_256_DIGEST_SIZE]; +#endif +} 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 +#if defined SESSION_C || defined GLOBAL_C +/* From Session.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 conextArray 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 +#if defined IO_BUFFER_C || defined GLOBAL_C +/* The s_actionOutputBuffer should not be modifiable by the host system until the TPM has returned a + response code. The s_actionOutputBuffer should not be accessible until response parameter + encryption, if any, is complete. */ +extern UINT32 s_actionInputBuffer[1024]; // action input buffer +extern UINT32 s_actionOutputBuffer[1024]; // action output buffer +#endif // MEMORY_LIB_C +/* 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 +#ifdef 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 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 00000000..75f320d2 --- /dev/null +++ b/src/tpm2/GpMacros.h @@ -0,0 +1,233 @@ +/********************************************************************************/ +/* */ +/* This file is a collection of miscellaneous macros. */ +/* Written by Ken Goldman */ +/* IBM Thomas J. Watson Research Center */ +/* $Id: GpMacros.h 960 2017-03-10 19:08:17Z kgoldman $ */ +/* */ +/* Licenses and Notices */ +/* */ +/* 1. Copyright Licenses: */ +/* */ +/* - Trusted Computing Group (TCG) grants to the user of the source code in */ +/* this specification (the "Source Code") a worldwide, irrevocable, */ +/* nonexclusive, royalty free, copyright license to reproduce, create */ +/* derivative works, distribute, display and perform the Source Code and */ +/* derivative works thereof, and to grant others the rights granted herein. */ +/* */ +/* - The TCG grants to the user of the other parts of the specification */ +/* (other than the Source Code) the rights to reproduce, distribute, */ +/* display, and perform the specification solely for the purpose of */ +/* developing products based on such documents. */ +/* */ +/* 2. Source Code Distribution Conditions: */ +/* */ +/* - Redistributions of Source Code must retain the above copyright licenses, */ +/* this list of conditions and the following disclaimers. */ +/* */ +/* - Redistributions in binary form must reproduce the above copyright */ +/* licenses, this list of conditions and the following disclaimers in the */ +/* documentation and/or other materials provided with the distribution. */ +/* */ +/* 3. Disclaimers: */ +/* */ +/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */ +/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */ +/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */ +/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */ +/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */ +/* information on specification licensing rights available through TCG */ +/* membership agreements. */ +/* */ +/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */ +/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */ +/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */ +/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */ +/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */ +/* */ +/* - Without limitation, TCG and its members and licensors disclaim all */ +/* liability, including liability for infringement of any proprietary */ +/* rights, relating to use of information in this specification and to the */ +/* implementation of this specification, and TCG disclaims all liability for */ +/* cost of procurement of substitute goods or services, lost profits, loss */ +/* of use, loss of data or any incidental, consequential, direct, indirect, */ +/* or special damages, whether under contract, tort, warranty 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 */ +/* */ +/********************************************************************************/ + +#ifndef GPMACROS_H +#define GPMACROS_H + +/* 5.11 GpMacros.h */ + +/* This file is a collection of miscellaneous macros. */ +#ifndef NULL +#define NULL 0 +#endif +#include "swap.h" +#include "VendorString.h" +/* 5.13.2 For Self-test */ +/* These macros are used in CryptUtil() to invoke the incremental self test. */ +#ifdef 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 != ALG_NULL_VALUE)) \ + CryptTestAlgorithm(alg, NULL) +#else +# define TEST(alg) +# define TEST_HASH(alg) +#endif // SELF_TEST +/* 5.13.3 For Failures */ +#if 0 +#if defined _POSIX_ +# define FUNCTION_NAME 0 +#else +# define FUNCTION_NAME __FUNCTION__ +#endif +#endif + +#if defined ( WIN32 ) +#define __func__ __FUNCTION__ +#endif +# define FUNCTION_NAME __func__ + +#ifdef NO_FAIL_TRACE +# define FAIL(errorCode) (TpmFail(errorCode)) +#else +# define FAIL(errorCode) (TpmFail(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) +# define pAssert(a) ((void)0) +#else +# define pAssert(a) {if(!(a)) FAIL(FATAL_ERROR_PARAMETER);} +#endif +/* 5.13.4 Derived from Vendor-specific values */ +/* Values derived from vendor specific settings in Implementation.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 PRIVATE_VENDOR_SPECIFIC_BYTES \ + ((MAX_RSA_KEY_BYTES/2) * (3 + CRT_FORMAT_RSA * 2)) +/* 5.13.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 */ +#ifdef 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 +/* 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 +/* Need an unambiguous definition for DEBUG. Don't change this */ +#if !defined NDEBUG && !defined DEBUG +# define DEBUG YES +#endif +#define STD_RESPONSE_HEADER (sizeof(TPM_ST) + sizeof(UINT32) + sizeof(TPM_RC)) +#ifndef CONTEXT_HASH_ALGORITHM +# if defined ALG_SHA512 && ALG_SHA512 == YES +# define CONTEXT_HASH_ALGORITHM SHA512 +# elif defined ALG_SHA384 && ALG_SHA384 == YES +# define CONTEXT_HASH_ALGORITHM SHA384 +# 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 +#endif +#define JOIN(x,y) x##y +#define CONCAT(x,y) JOIN(x, y) + +/* If CONTEXT_INTEGRITY_HASH_ALG is defined, then the vendor is using the old style table */ + +#ifndef CONTEXT_INTEGRITY_HASH_ALG +#define CONTEXT_INTEGRITY_HASH_ALG CONCAT(TPM_ALG_, CONTEXT_HASH_ALGORITHM) +#define CONTEXT_INTEGRITY_HASH_SIZE CONCAT(CONTEXT_HASH_ALGORITHM, _DIGEST_SIZE) +#endif +#define PROOF_SIZE CONTEXT_INTEGRITY_HASH_SIZE + +/* If CONTEXT_ENCRYP_ALG is defined, then the vendor is using the old style table */ + +#ifndef CONTEXT_ENCRYPT_ALG +#define CONTEXT_ENCRYPT_ALG CONCAT(TPM_ALG_, CONTEXT_ENCRYPT_ALGORITHM) +#define CONTEXT_ENCRYPT_KEY_BITS \ + CONCAT(CONCAT(MAX_, CONTEXT_ENCRYPT_ALGORITHM), _KEY_BITS) +#define CONTEXT_ENCRYPT_KEY_BYTES ((CONTEXT_ENCRYPT_KEY_BITS+7)/8) +#endif +#if ALG_ECC +# define LABEL_MAX_BUFFER MAX_ECC_KEY_BYTES +#else +# define LABEL_MAX_BUFFER MAX_DIGEST_SIZE +#endif + +#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 00000000..a05ddf15 --- /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 00000000..8640714a --- /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 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_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 00000000..9d7aac5b --- /dev/null +++ b/src/tpm2/Handle.c @@ -0,0 +1,208 @@ +/********************************************************************************/ +/* */ +/* fUnctions that return the type of a handle. */ +/* Written by Ken Goldman */ +/* IBM Thomas J. Watson Research Center */ +/* $Id: Handle.c 953 2017-03-06 20:31: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, 2017 */ +/* */ +/********************************************************************************/ + +/* 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: */ +/* Return Values Meaning */ +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 + 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 00000000..23e36f34 --- /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 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 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 00000000..da470eb6 --- /dev/null +++ b/src/tpm2/HashCommands.c @@ -0,0 +1,329 @@ +/********************************************************************************/ +/* */ +/* */ +/* Written by Ken Goldman */ +/* IBM Thomas J. Watson Research Center */ +/* $Id: HashCommands.c 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 */ +/* */ +/********************************************************************************/ + +#include "Tpm.h" +#include "HMAC_Start_fp.h" +#ifdef TPM_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(publicArea->objectAttributes.restricted == SET) + return TPM_RCS_ATTRIBUTES + RC_HMAC_Start_handle; + // and that it is a signing key + if(publicArea->objectAttributes.sign != SET) + 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 "HashSequenceStart_fp.h" +#ifdef TPM_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" +#ifdef TPM_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 hash/HMAC stack + CryptDigestUpdate2B(&hashObject->state.hmacState.hashState, + &in->buffer.b); + } + } + return TPM_RC_SUCCESS; +} +#endif // CC_SequenceUpdate +#include "Tpm.h" +#include "SequenceComplete_fp.h" +#ifdef TPM_CC_SequenceComplete // Conditional expansion of this file +TPM_RC +TPM2_SequenceComplete( + SequenceComplete_In *in, // IN: input parameter list + SequenceComplete_Out *out // OUT: output parameter list + ) +{ + OBJECT *object; + // Input validation + // Get hash object pointer + object = HandleToObject(in->sequenceHandle); + // input handle must be a hash or HMAC sequence object. + if(object->attributes.hashSeq == CLEAR + && object->attributes.hmacSeq == CLEAR) + return TPM_RCS_MODE + RC_SequenceComplete_sequenceHandle; + // Command Output + if(object->attributes.hashSeq == SET) // sequence object for hash + { + // Update last piece of data + HASH_OBJECT *hashObject = (HASH_OBJECT *)object; + // Get the hash algorithm before the algorithm is lost in CryptHashEnd + TPM_ALG_ID hashAlg = hashObject->state.hashState[0].hashAlg; + CryptDigestUpdate2B(&hashObject->state.hashState[0], &in->buffer.b); + // Complete hash + out->result.t.size + = CryptHashGetDigestSize( + CryptHashGetContextAlg(&hashObject->state.hashState[0])); + CryptHashEnd2B(&hashObject->state.hashState[0], &out->result.b); + // 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(object->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 + { + HASH_OBJECT *hashObject = (HASH_OBJECT *)object; + // Update last piece of data + CryptDigestUpdate2B(&hashObject->state.hmacState.hashState, &in->buffer.b); + // Complete hash/HMAC + out->result.t.size = + CryptHashGetDigestSize( + CryptHashGetContextAlg(&hashObject->state.hmacState.hashState)); + CryptHmacEnd2B(&(hashObject->state.hmacState), &out->result.b); + // 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 + object->attributes.evict = SET; + return TPM_RC_SUCCESS; +} +#endif // CC_SequenceComplete +#include "Tpm.h" +#include "EventSequenceComplete_fp.h" +#ifdef TPM_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 00000000..9f7d9fc1 --- /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 00000000..e38b7ee9 --- /dev/null +++ b/src/tpm2/HashTestData.h @@ -0,0 +1,119 @@ +/********************************************************************************/ +/* */ +/* */ +/* Written by Ken Goldman */ +/* IBM Thomas J. Watson Research Center */ +/* $Id: HashTestData.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 HASHTESTDATA_H +#define HASHTESTDATA_H + +/* 10.1.8 HashTestData.h */ +/* Hash Test Vectors */ +TPM2B_TYPE(HASH_TEST_KEY, 96); // Twice the largest digest size +TPM2B_HASH_TEST_KEY c_hashTestKey = {{96, { + 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 + }}}; +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_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_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 + + +#endif diff --git a/src/tpm2/Hash_fp.h b/src/tpm2/Hash_fp.h new file mode 100644 index 00000000..54e070f8 --- /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 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 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 00000000..ff8e33d8 --- /dev/null +++ b/src/tpm2/Hierarchy.c @@ -0,0 +1,246 @@ +/********************************************************************************/ +/* */ +/* */ +/* Written by Ken Goldman */ +/* IBM Thomas J. Watson Research Center */ +/* $Id: Hierarchy.c 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 */ +/* */ +/********************************************************************************/ +/* 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 = PRIMARY_SEED_SIZE; + CryptRandomGenerate(PRIMARY_SEED_SIZE, gp.EPSeed.t.buffer); + gp.SPSeed.t.size = PRIMARY_SEED_SIZE; + CryptRandomGenerate(PRIMARY_SEED_SIZE, gp.SPSeed.t.buffer); + gp.PPSeed.t.size = PRIMARY_SEED_SIZE; +#ifdef USE_PLATFORM_EPS + _plat__GetEPS(PRIMARY_SEED_SIZE, gp.EPSeed.t.buffer); +#else + CryptRandomGenerate(PRIMARY_SEED_SIZE, gp.PPSeed.t.buffer); +#endif + // Initialize owner, endorsement and lockout auth + 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 = PROOF_SIZE; + gp.shProof.t.size = PROOF_SIZE; + gp.ehProof.t.size = PROOF_SIZE; + 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(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. */ +void +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; + // 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 = PROOF_SIZE; + CryptRandomGenerate(gr.nullProof.t.size, + gr.nullProof.t.buffer); + gr.nullSeed.t.size = PRIMARY_SEED_SIZE; + CryptRandomGenerate(PRIMARY_SEED_SIZE, gr.nullSeed.t.buffer); + } + return; +} +/* 8.3.3.3 HierarchyGetProof() */ +/* This function finds the proof value associated with a hierarchy.It returns a pointer to the proof + value. */ +TPM2B_AUTH * +HierarchyGetProof( + TPMI_RH_HIERARCHY hierarchy // IN: hierarchy constant + ) +{ + TPM2B_AUTH *auth = NULL; + switch(hierarchy) + { + case TPM_RH_PLATFORM: + // phProof for TPM_RH_PLATFORM + auth = &gp.phProof; + break; + case TPM_RH_ENDORSEMENT: + // ehProof for TPM_RH_ENDORSEMENT + auth = &gp.ehProof; + break; + case TPM_RH_OWNER: + // shProof for TPM_RH_OWNER + auth = &gp.shProof; + break; + case TPM_RH_NULL: + // nullProof for TPM_RH_NULL + auth = &gr.nullProof; + break; + default: + FAIL(FATAL_ERROR_INTERNAL); + break; + } + return auth; +} +/* 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; + case TPM_RH_NULL: + return &gr.nullSeed; + default: + FAIL(FATAL_ERROR_INTERNAL); + break; + } + return seed; +} +/* 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: + FAIL(FATAL_ERROR_INTERNAL); + break; + } + return enabled; +} diff --git a/src/tpm2/HierarchyChangeAuth_fp.h b/src/tpm2/HierarchyChangeAuth_fp.h new file mode 100644 index 00000000..74f03973 --- /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 00000000..5e870d31 --- /dev/null +++ b/src/tpm2/HierarchyCommands.c @@ -0,0 +1,496 @@ +/********************************************************************************/ +/* */ +/* Hierarchy Commands */ +/* Written by Ken Goldman */ +/* IBM Thomas J. Watson Research Center */ +/* $Id: HierarchyCommands.c 953 2017-03-06 20:31: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, 2017 */ +/* */ +/********************************************************************************/ + +#include "Tpm.h" +#include "CreatePrimary_fp.h" +#ifdef TPM_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 + ) +{ + // Local variables + 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. + DRBG_InstantiateSeeded(&rand, + &HierarchyGetPrimarySeed(in->primaryHandle)->b, + PRIMARY_OBJECT_CREATION, + (TPM2B *)PublicMarshalAndComputeName(publicArea, &name), + &in->inSensitive.sensitive.data.b); + 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); + return result; +} +#endif // CC_CreatePrimary +#include "Tpm.h" +#include "HierarchyControl_fp.h" +#ifdef TPM_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" +#ifdef TPM_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 PLATFROM 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; + default: + FAIL(FATAL_ERROR_INTERNAL); + break; + } + return TPM_RC_SUCCESS; +} +#endif // CC_SetPrimaryPolicy +#include "Tpm.h" +#include "ChangePPS_fp.h" +#ifdef TPM_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); + // in = NULL; kgold + // Internal Data Update + // Reset platform hierarchy seed from RNG + CryptRandomGenerate(PRIMARY_SEED_SIZE, gp.PPSeed.t.buffer); + // Create a new phProof value from RNG to prevent the saved platform + // hierarchy contexts being loaded + CryptRandomGenerate(PROOF_SIZE, 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(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" +#ifdef TPM_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(PRIMARY_SEED_SIZE, gp.EPSeed.t.buffer); + // Create new ehProof value from RNG + CryptRandomGenerate(PROOF_SIZE, 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(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" +#ifdef TPM_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(PRIMARY_SEED_SIZE, gp.SPSeed.t.buffer); + // Create new shProof and ehProof value from RNG + CryptRandomGenerate(PROOF_SIZE, gp.shProof.t.buffer); + CryptRandomGenerate(PROOF_SIZE, 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" +#ifdef TPM_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" +#ifdef TPM_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 00000000..ab22a35a --- /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 00000000..6d765155 --- /dev/null +++ b/src/tpm2/Hierarchy_fp.h @@ -0,0 +1,87 @@ +/********************************************************************************/ +/* */ +/* */ +/* Written by Ken Goldman */ +/* IBM Thomas J. Watson Research Center */ +/* $Id: Hierarchy_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 HIERARCHY_FP_H +#define HIERARCHY_FP_H + +void +HierarchyPreInstall_Init( + void + ); +void +HierarchyStartup( + STARTUP_TYPE type // IN: start up type + ); +TPM2B_AUTH * +HierarchyGetProof( + TPMI_RH_HIERARCHY hierarchy // IN: hierarchy constant + ); +TPM2B_SEED * +HierarchyGetPrimarySeed( + TPMI_RH_HIERARCHY hierarchy // IN: hierarchy + ); +BOOL +HierarchyIsEnabled( + TPMI_RH_HIERARCHY hierarchy // IN: hierarchy + ); + + +#endif diff --git a/src/tpm2/Implementation.h b/src/tpm2/Implementation.h new file mode 100644 index 00000000..ef0d8683 --- /dev/null +++ b/src/tpm2/Implementation.h @@ -0,0 +1,1501 @@ +/********************************************************************************/ +/* */ +/* */ +/* Written by Ken Goldman */ +/* IBM Thomas J. Watson Research Center */ +/* $Id: Implementation.h 953 2017-03-06 20:31: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, 2017 */ +/* */ +/********************************************************************************/ + +/* A.2 Implementation.h */ +#ifndef _IMPLEMENTATION_H_ +#define _IMPLEMENTATION_H_ +#include "TpmBuildSwitches.h" +#include "BaseTypes.h" +#include "TPMB.h" +#undef TRUE +#undef FALSE +/* This table is built in to TpmStructures() Change these definitions to turn all algorithms or + commands on or off */ +#define ALG_YES YES +#define ALG_NO NO +#define CC_YES YES +#define CC_NO NO +/* From TPM 2.0 Part 2: Table 4 - Defines for Logic Values */ +#define TRUE 1 +#define FALSE 0 +#define YES 1 +#define NO 0 +#define SET 1 +#define CLEAR 0 +/* From Vendor-Specific: Table 1 - Defines for Processor Values */ +#define BIG_ENDIAN_TPM NO +#define LITTLE_ENDIAN_TPM YES +#define AUTO_ALIGN NO +/* From Vendor-Specific: Table 2 - Defines for Implemented Algorithms */ +#define ALG_RSA ALG_YES +#define ALG_SHA1 ALG_YES +#define ALG_HMAC ALG_YES +#define ALG_TDES ALG_YES +#define ALG_AES ALG_YES +#define ALG_MGF1 ALG_YES +#define ALG_XOR ALG_YES +#define ALG_KEYEDHASH ALG_YES +#define ALG_SHA256 ALG_YES +#define ALG_SHA384 ALG_YES +#define ALG_SHA512 ALG_NO +#define ALG_SM3_256 ALG_NO +#define ALG_SM4 ALG_NO +#define ALG_RSASSA (ALG_YES*ALG_RSA) +#define ALG_RSAES (ALG_YES*ALG_RSA) +#define ALG_RSAPSS (ALG_YES*ALG_RSA) +#define ALG_OAEP (ALG_YES*ALG_RSA) +#define ALG_ECC ALG_YES +#define ALG_ECDH (ALG_YES*ALG_ECC) +#define ALG_ECDSA (ALG_YES*ALG_ECC) +#define ALG_ECDAA (ALG_YES*ALG_ECC) +#define ALG_SM2 (ALG_NO*ALG_ECC) +#define ALG_ECSCHNORR (ALG_YES*ALG_ECC) +#define ALG_ECMQV (ALG_NO*ALG_ECC) +#define ALG_SYMCIPHER ALG_YES +#define ALG_KDF1_SP800_56A (ALG_YES*ALG_ECC) +#define ALG_KDF2 ALG_NO +#define ALG_KDF1_SP800_108 ALG_YES +#define ALG_CTR ALG_YES +#define ALG_OFB ALG_YES +#define ALG_CBC ALG_YES +#define ALG_CFB ALG_YES +#define ALG_ECB ALG_YES + +/* From Vendor-Specific: Table 3 - Defines for Key Size Constants */ +#define RSA_KEY_SIZES_BITS {1024,2048} +#define RSA_KEY_SIZE_BITS_1024 RSA_ALLOWED_KEY_SIZE_1024 +#define RSA_KEY_SIZE_BITS_2048 RSA_ALLOWED_KEY_SIZE_2048 +#define MAX_RSA_KEY_BITS 2048 +#define MAX_RSA_KEY_BYTES 256 +#define TDES_KEY_SIZES_BITS {128,192} +#define TDES_KEY_SIZE_BITS_128 TDES_ALLOWED_KEY_SIZE_128 +#define TDES_KEY_SIZE_BITS_192 TDES_ALLOWED_KEY_SIZE_192 +#define MAX_TDES_KEY_BITS 192 +#define MAX_TDES_KEY_BYTES 24 +#define MAX_TDES_BLOCK_SIZE_BYTES \ + MAX(TDES_128_BLOCK_SIZE_BYTES, \ + MAX(TDES_192_BLOCK_SIZE_BYTES, 0)) +#define AES_KEY_SIZES_BITS {128,256} +#define AES_KEY_SIZE_BITS_128 AES_ALLOWED_KEY_SIZE_128 +#define AES_KEY_SIZE_BITS_256 AES_ALLOWED_KEY_SIZE_256 +#define MAX_AES_KEY_BITS 256 +#define MAX_AES_KEY_BYTES 32 +#define MAX_AES_BLOCK_SIZE_BYTES \ + MAX(AES_128_BLOCK_SIZE_BYTES, \ + MAX(AES_256_BLOCK_SIZE_BYTES, 0)) +#define SM4_KEY_SIZES_BITS {128} +#define SM4_KEY_SIZE_BITS_128 SM4_ALLOWED_KEY_SIZE_128 +#define MAX_SM4_KEY_BITS 128 +#define MAX_SM4_KEY_BYTES 16 +#define MAX_SM4_BLOCK_SIZE_BYTES \ + MAX(SM4_128_BLOCK_SIZE_BYTES, 0) +#define CAMELLIA_KEY_SIZES_BITS {128} +#define CAMELLIA_KEY_SIZE_BITS_128 CAMELLIA_ALLOWED_KEY_SIZE_128 +#define MAX_CAMELLIA_KEY_BITS 128 +#define MAX_CAMELLIA_KEY_BYTES 16 +#define MAX_CAMELLIA_BLOCK_SIZE_BYTES \ + MAX(CAMELLIA_128_BLOCK_SIZE_BYTES, 0) +/* From Vendor-Specific: Table 4 - Defines for Implemented Curves */ +#define ECC_NIST_P192 NO +#define ECC_NIST_P224 NO +#define ECC_NIST_P256 YES +#define ECC_NIST_P384 YES +#define ECC_NIST_P521 NO +#define ECC_BN_P256 YES +#define ECC_BN_P638 NO +#define ECC_SM2_P256 NO +#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) +/* From Vendor-Specific: Table 5 - Defines for Implemented Commands */ +#define CC_ActivateCredential CC_YES +#define CC_Certify CC_YES +#define CC_CertifyCreation CC_YES +#define CC_ChangeEPS CC_YES +#define CC_ChangePPS CC_YES +#define CC_Clear CC_YES +#define CC_ClearControl CC_YES +#define CC_ClockRateAdjust CC_YES +#define CC_ClockSet CC_YES +#define CC_Commit (CC_YES*ALG_ECC) +#define CC_ContextLoad CC_YES +#define CC_ContextSave CC_YES +#define CC_Create CC_YES +#define CC_CreatePrimary CC_YES +#define CC_DictionaryAttackLockReset CC_YES +#define CC_DictionaryAttackParameters CC_YES +#define CC_Duplicate CC_YES +#define CC_ECC_Parameters (CC_YES*ALG_ECC) +#define CC_ECDH_KeyGen (CC_YES*ALG_ECC) +#define CC_ECDH_ZGen (CC_YES*ALG_ECC) +#define CC_EncryptDecrypt CC_YES +#define CC_EventSequenceComplete CC_YES +#define CC_EvictControl CC_YES +#define CC_FieldUpgradeData CC_NO +#define CC_FieldUpgradeStart CC_NO +#define CC_FirmwareRead CC_NO +#define CC_FlushContext CC_YES +#define CC_GetCapability CC_YES +#define CC_GetCommandAuditDigest CC_YES +#define CC_GetRandom CC_YES +#define CC_GetSessionAuditDigest CC_YES +#define CC_GetTestResult CC_YES +#define CC_GetTime CC_YES +#define CC_Hash CC_YES +#define CC_HashSequenceStart CC_YES +#define CC_HierarchyChangeAuth CC_YES +#define CC_HierarchyControl CC_YES +#define CC_HMAC CC_YES +#define CC_HMAC_Start CC_YES +#define CC_Import CC_YES +#define CC_IncrementalSelfTest CC_YES +#define CC_Load CC_YES +#define CC_LoadExternal CC_YES +#define CC_MakeCredential CC_YES +#define CC_NV_Certify CC_YES +#define CC_NV_ChangeAuth CC_YES +#define CC_NV_DefineSpace CC_YES +#define CC_NV_Extend CC_YES +#define CC_NV_GlobalWriteLock CC_YES +#define CC_NV_Increment CC_YES +#define CC_NV_Read CC_YES +#define CC_NV_ReadLock CC_YES +#define CC_NV_ReadPublic CC_YES +#define CC_NV_SetBits CC_YES +#define CC_NV_UndefineSpace CC_YES +#define CC_NV_UndefineSpaceSpecial CC_YES +#define CC_NV_Write CC_YES +#define CC_NV_WriteLock CC_YES +#define CC_ObjectChangeAuth CC_YES +#define CC_PCR_Allocate CC_YES +#define CC_PCR_Event CC_YES +#define CC_PCR_Extend CC_YES +#define CC_PCR_Read CC_YES +#define CC_PCR_Reset CC_YES +#define CC_PCR_SetAuthPolicy CC_YES +#define CC_PCR_SetAuthValue CC_YES +#define CC_PolicyAuthorize CC_YES +#define CC_PolicyAuthValue CC_YES +#define CC_PolicyCommandCode CC_YES +#define CC_PolicyCounterTimer CC_YES +#define CC_PolicyCpHash CC_YES +#define CC_PolicyDuplicationSelect CC_YES +#define CC_PolicyGetDigest CC_YES +#define CC_PolicyLocality CC_YES +#define CC_PolicyNameHash CC_YES +#define CC_PolicyNV CC_YES +#define CC_PolicyOR CC_YES +#define CC_PolicyPassword CC_YES +#define CC_PolicyPCR CC_YES +#define CC_PolicyPhysicalPresence CC_YES +#define CC_PolicyRestart CC_YES +#define CC_PolicySecret CC_YES +#define CC_PolicySigned CC_YES +#define CC_PolicyTicket CC_YES +#define CC_PP_Commands CC_YES +//#define CC_PP_Commands CC_NO // kgold +#define CC_Quote CC_YES +#define CC_ReadClock CC_YES +#define CC_ReadPublic CC_YES +#define CC_Rewrap CC_YES +#define CC_RSA_Decrypt (CC_YES*ALG_RSA) +#define CC_RSA_Encrypt (CC_YES*ALG_RSA) +#define CC_SelfTest CC_YES +#define CC_SequenceComplete CC_YES +#define CC_SequenceUpdate CC_YES +#define CC_SetAlgorithmSet CC_YES +#define CC_SetCommandCodeAuditStatus CC_YES +#define CC_SetPrimaryPolicy CC_YES +#define CC_Shutdown CC_YES +#define CC_Sign CC_YES +#define CC_StartAuthSession CC_YES +#define CC_Startup CC_YES +#define CC_StirRandom CC_YES +#define CC_TestParms CC_YES +#define CC_Unseal CC_YES +#define CC_VerifySignature CC_YES +#define CC_ZGen_2Phase (CC_YES*ALG_ECC) +#define CC_EC_Ephemeral (CC_YES*ALG_ECC) +#define CC_PolicyNvWritten CC_YES +#define CC_PolicyTemplate CC_YES +#define CC_CreateLoaded CC_YES +#define CC_PolicyAuthorizeNV CC_YES +#define CC_EncryptDecrypt2 CC_YES +#define CC_AC_GetCapability CC_NO +#define CC_AC_Send CC_NO +#define CC_Policy_AC_SendSelect CC_NO +#define CC_Vendor_TCG_Test CC_YES + +/* From Vendor-Specific: Table 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 +/* From Vendor-Specific: Table 7 - Defines for Implementation Values */ +#define FIELD_UPGRADE_IMPLEMENTED NO +#ifdef TPM_POSIX +#define RADIX_BITS 64 /* kgold */ +#endif +#ifdef TPM_WINDOWS +#define RADIX_BITS 32 /* kgold */ +#endif +#define HASH_ALIGNMENT 4 +#define SYMMETRIC_ALIGNMENT 4 +#define HASH_LIB OSSL +#define SYM_LIB OSSL +#define MATH_LIB OSSL +#define BSIZE UINT16 +#define IMPLEMENTATION_PCR 24 +#define PLATFORM_PCR 24 +#define DRTM_PCR 17 +#define HCRTM_PCR 0 +#define NUM_LOCALITIES 5 +#define MAX_HANDLE_NUM 3 +#define MAX_ACTIVE_SESSIONS 64 +#define CONTEXT_SLOT UINT16 +#define CONTEXT_COUNTER UINT64 +#define MAX_LOADED_SESSIONS 3 +#define MAX_SESSION_NUM 3 +#define MAX_LOADED_OBJECTS 3 +#define MIN_EVICT_OBJECTS 2 +#define NUM_POLICY_PCR_GROUP 1 +#define NUM_AUTHVALUE_PCR_GROUP 1 +#define MAX_CONTEXT_SIZE 2474 +#define MAX_DIGEST_BUFFER 1024 +#define MAX_NV_INDEX_SIZE 2048 +#define MAX_NV_BUFFER_SIZE 1024 +#define MAX_CAP_BUFFER 1024 +#define NV_MEMORY_SIZE 16384 +#define MIN_COUNTER_INDICES 8 +#define NUM_STATIC_PCR 16 +#define MAX_ALG_LIST_SIZE 64 +#define PRIMARY_SEED_SIZE 32 +#define CONTEXT_ENCRYPT_ALGORITHM AES +#define NV_CLOCK_UPDATE_INTERVAL 12 +#define NUM_POLICY_PCR 1 +#define MAX_COMMAND_SIZE 4096 +#define MAX_RESPONSE_SIZE 4096 +#define ORDERLY_BITS 8 +#define MAX_SYM_DATA 128 +#define MAX_RNG_ENTROPY_SIZE 64 +#define RAM_INDEX_SPACE 512 +#define RSA_DEFAULT_PUBLIC_EXPONENT 0x00010001 +#define ENABLE_PCR_NO_INCREMENT YES +#define CRT_FORMAT_RSA YES +#define VENDOR_COMMAND_COUNT 0 +#define MAX_VENDOR_BUFFER_SIZE 1024 +/* From TCG Algorithm Registry: Table 2 - Definition of TPM_ALG_ID Constants */ +typedef UINT16 TPM_ALG_ID; +#define ALG_ERROR_VALUE 0x0000 +#define TPM_ALG_ERROR (TPM_ALG_ID)(ALG_ERROR_VALUE) +#define ALG_RSA_VALUE 0x0001 +#if defined ALG_RSA && ALG_RSA == YES +#define TPM_ALG_RSA (TPM_ALG_ID)(ALG_RSA_VALUE) +#endif +#define ALG_TDES_VALUE 0x0003 +#if defined ALG_TDES && ALG_TDES == YES +#define TPM_ALG_TDES (TPM_ALG_ID)(ALG_TDES_VALUE) +#endif +#define ALG_SHA_VALUE 0x0004 +#if defined ALG_SHA && ALG_SHA == YES +#define TPM_ALG_SHA (TPM_ALG_ID)(ALG_SHA_VALUE) +#endif +#define ALG_SHA1_VALUE 0x0004 +#if defined ALG_SHA1 && ALG_SHA1 == YES +#define TPM_ALG_SHA1 (TPM_ALG_ID)(ALG_SHA1_VALUE) +#endif +#define ALG_HMAC_VALUE 0x0005 +#if defined ALG_HMAC && ALG_HMAC == YES +#define TPM_ALG_HMAC (TPM_ALG_ID)(ALG_HMAC_VALUE) +#endif +#define ALG_AES_VALUE 0x0006 +#if defined ALG_AES && ALG_AES == YES +#define TPM_ALG_AES (TPM_ALG_ID)(ALG_AES_VALUE) +#endif +#define ALG_MGF1_VALUE 0x0007 +#if defined ALG_MGF1 && ALG_MGF1 == YES +#define TPM_ALG_MGF1 (TPM_ALG_ID)(ALG_MGF1_VALUE) +#endif +#define ALG_KEYEDHASH_VALUE 0x0008 +#if defined ALG_KEYEDHASH && ALG_KEYEDHASH == YES +#define TPM_ALG_KEYEDHASH (TPM_ALG_ID)(ALG_KEYEDHASH_VALUE) +#endif +#define ALG_XOR_VALUE 0x000A +#if defined ALG_XOR && ALG_XOR == YES +#define TPM_ALG_XOR (TPM_ALG_ID)(ALG_XOR_VALUE) +#endif +#define ALG_SHA256_VALUE 0x000B +#if defined ALG_SHA256 && ALG_SHA256 == YES +#define TPM_ALG_SHA256 (TPM_ALG_ID)(ALG_SHA256_VALUE) +#endif +#define ALG_SHA384_VALUE 0x000C +#if defined ALG_SHA384 && ALG_SHA384 == YES +#define TPM_ALG_SHA384 (TPM_ALG_ID)(ALG_SHA384_VALUE) +#endif +#define ALG_SHA512_VALUE 0x000D +#if defined ALG_SHA512 && ALG_SHA512 == YES +#define TPM_ALG_SHA512 (TPM_ALG_ID)(ALG_SHA512_VALUE) +#endif +#define ALG_NULL_VALUE 0x0010 +#define TPM_ALG_NULL (TPM_ALG_ID)(ALG_NULL_VALUE) +#define ALG_SM3_256_VALUE 0x0012 +#if defined ALG_SM3_256 && ALG_SM3_256 == YES +#define TPM_ALG_SM3_256 (TPM_ALG_ID)(ALG_SM3_256_VALUE) +#endif +#define ALG_SM4_VALUE 0x0013 +#if defined ALG_SM4 && ALG_SM4 == YES +#define TPM_ALG_SM4 (TPM_ALG_ID)(ALG_SM4_VALUE) +#endif +#define ALG_RSASSA_VALUE 0x0014 +#if defined ALG_RSASSA && ALG_RSASSA == YES +#define TPM_ALG_RSASSA (TPM_ALG_ID)(ALG_RSASSA_VALUE) +#endif +#define ALG_RSAES_VALUE 0x0015 +#if defined ALG_RSAES && ALG_RSAES == YES +#define TPM_ALG_RSAES (TPM_ALG_ID)(ALG_RSAES_VALUE) +#endif +#define ALG_RSAPSS_VALUE 0x0016 +#if defined ALG_RSAPSS && ALG_RSAPSS == YES +#define TPM_ALG_RSAPSS (TPM_ALG_ID)(ALG_RSAPSS_VALUE) +#endif +#define ALG_OAEP_VALUE 0x0017 +#if defined ALG_OAEP && ALG_OAEP == YES +#define TPM_ALG_OAEP (TPM_ALG_ID)(ALG_OAEP_VALUE) +#endif +#define ALG_ECDSA_VALUE 0x0018 +#if defined ALG_ECDSA && ALG_ECDSA == YES +#define TPM_ALG_ECDSA (TPM_ALG_ID)(ALG_ECDSA_VALUE) +#endif +#define ALG_ECDH_VALUE 0x0019 +#if defined ALG_ECDH && ALG_ECDH == YES +#define TPM_ALG_ECDH (TPM_ALG_ID)(ALG_ECDH_VALUE) +#endif +#define ALG_ECDAA_VALUE 0x001A +#if defined ALG_ECDAA && ALG_ECDAA == YES +#define TPM_ALG_ECDAA (TPM_ALG_ID)(ALG_ECDAA_VALUE) +#endif +#define ALG_SM2_VALUE 0x001B +#if defined ALG_SM2 && ALG_SM2 == YES +#define TPM_ALG_SM2 (TPM_ALG_ID)(ALG_SM2_VALUE) +#endif +#define ALG_ECSCHNORR_VALUE 0x001C +#if defined ALG_ECSCHNORR && ALG_ECSCHNORR == YES +#define TPM_ALG_ECSCHNORR (TPM_ALG_ID)(ALG_ECSCHNORR_VALUE) +#endif +#define ALG_ECMQV_VALUE 0x001D +#if defined ALG_ECMQV && ALG_ECMQV == YES +#define TPM_ALG_ECMQV (TPM_ALG_ID)(ALG_ECMQV_VALUE) +#endif +#define ALG_KDF1_SP800_56A_VALUE 0x0020 +#if defined ALG_KDF1_SP800_56A && ALG_KDF1_SP800_56A == YES +#define TPM_ALG_KDF1_SP800_56A (TPM_ALG_ID)(ALG_KDF1_SP800_56A_VALUE) +#endif +#define ALG_KDF2_VALUE 0x0021 +#if defined ALG_KDF2 && ALG_KDF2 == YES +#define TPM_ALG_KDF2 (TPM_ALG_ID)(ALG_KDF2_VALUE) +#endif +#define ALG_KDF1_SP800_108_VALUE 0x0022 +#if defined ALG_KDF1_SP800_108 && ALG_KDF1_SP800_108 == YES +#define TPM_ALG_KDF1_SP800_108 (TPM_ALG_ID)(ALG_KDF1_SP800_108_VALUE) +#endif +#define ALG_ECC_VALUE 0x0023 +#if defined ALG_ECC && ALG_ECC == YES +#define TPM_ALG_ECC (TPM_ALG_ID)(ALG_ECC_VALUE) +#endif +#define ALG_SYMCIPHER_VALUE 0x0025 +#if defined ALG_SYMCIPHER && ALG_SYMCIPHER == YES +#define TPM_ALG_SYMCIPHER (TPM_ALG_ID)(ALG_SYMCIPHER_VALUE) +#endif +#define ALG_CAMELLIA_VALUE 0x0026 +#if defined ALG_CAMELLIA && ALG_CAMELLIA == YES +#define TPM_ALG_CAMELLIA (TPM_ALG_ID)(ALG_CAMELLIA_VALUE) +#endif +#define ALG_CTR_VALUE 0x0040 +#if defined ALG_CTR && ALG_CTR == YES +#define TPM_ALG_CTR (TPM_ALG_ID)(ALG_CTR_VALUE) +#endif +#define ALG_OFB_VALUE 0x0041 +#if defined ALG_OFB && ALG_OFB == YES +#define TPM_ALG_OFB (TPM_ALG_ID)(ALG_OFB_VALUE) +#endif +#define ALG_CBC_VALUE 0x0042 +#if defined ALG_CBC && ALG_CBC == YES +#define TPM_ALG_CBC (TPM_ALG_ID)(ALG_CBC_VALUE) +#endif +#define ALG_CFB_VALUE 0x0043 +#if defined ALG_CFB && ALG_CFB == YES +#define TPM_ALG_CFB (TPM_ALG_ID)(ALG_CFB_VALUE) +#endif +#define ALG_ECB_VALUE 0x0044 +#if defined ALG_ECB && ALG_ECB == YES +#define TPM_ALG_ECB (TPM_ALG_ID)(ALG_ECB_VALUE) +#endif +#define TPM_ALG_FIRST (TPM_ALG_ID)(0x0001) +#define ALG_FIRST_VALUE 0x0001 +#define TPM_ALG_LAST (TPM_ALG_ID)(0x0044) +#define ALG_LAST_VALUE 0x0044 + +/* From TCG Algorithm Registry: Table 3 - Definition of TPM_ECC_CURVE Constants */ +typedef UINT16 TPM_ECC_CURVE; +#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) +/* From TCG Algorithm Registry: Table 4 - Defines for NIST_P192 ECC Values Data is in CryptEccData.c + From TCG Algorithm Registry: Table 5 - Defines for NIST_P224 ECC Values Data is in CryptEccData.c + From TCG Algorithm Registry: Table 6 - Defines for NIST_P256 ECC Values Data is in CryptEccData.c + From TCG Algorithm Registry: Table 7 - Defines for NIST_P384 ECC Values Data is in CryptEccData.c + From TCG Algorithm Registry: Table 8 - Defines for NIST_P521 ECC Values Data is in CryptEccData.c + From TCG Algorithm Registry: Table 9 - Defines for BN_P256 ECC Values Data is in CryptEccData.c + From TCG Algorithm Registry: Table 10 - Defines for BN_P638 ECC Values Data is in CryptEccData.c + From TCG Algorithm Registry: Table 11 - Defines for SM2_P256 ECC Values Data is in CryptEccData.c + From TCG Algorithm Registry: Table 12 - Defines for SHA1 Hash Values */ +#define SHA1_DIGEST_SIZE 20 +#define SHA1_BLOCK_SIZE 64 +#define SHA1_DER_SIZE 15 +#define SHA1_DER \ + 0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2B, 0x0E, \ + 0x03, 0x02, 0x1A, 0x05, 0x00, 0x04, 0x14 +/* From TCG Algorithm Registry: Table 13 - Defines for SHA256 Hash Values */ +#define SHA256_DIGEST_SIZE 32 +#define SHA256_BLOCK_SIZE 64 +#define SHA256_DER_SIZE 19 +#define SHA256_DER \ + 0x30, 0x31, 0x30, 0x0D, 0x06, 0x09, 0x60, 0x86, \ + 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0x05, \ + 0x00, 0x04, 0x20 +/* From TCG Algorithm Registry: Table 14 - Defines for SHA384 Hash Values */ +#define SHA384_DIGEST_SIZE 48 +#define SHA384_BLOCK_SIZE 128 +#define SHA384_DER_SIZE 19 +#define SHA384_DER \ + 0x30, 0x41, 0x30, 0x0D, 0x06, 0x09, 0x60, 0x86, \ + 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x02, 0x05, \ + 0x00, 0x04, 0x30 +/* From TCG Algorithm Registry: Table 15 - Defines for SHA512 Hash Values */ +#define SHA512_DIGEST_SIZE 64 +#define SHA512_BLOCK_SIZE 128 +#define SHA512_DER_SIZE 19 +#define SHA512_DER \ + 0x30, 0x51, 0x30, 0x0D, 0x06, 0x09, 0x60, 0x86, \ + 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x03, 0x05, \ + 0x00, 0x04, 0x40 +/* From TCG Algorithm Registry: Table 16 - Defines for SM3_256 Hash Values */ +#define SM3_256_DIGEST_SIZE 32 +#define SM3_256_BLOCK_SIZE 64 +#define SM3_256_DER_SIZE 18 +#define SM3_256_DER \ + 0x30, 0x30, 0x30, 0x0C, 0x06, 0x08, 0x2A, 0x81, \ + 0x1C, 0x81, 0x45, 0x01, 0x83, 0x11, 0x05, 0x00, \ + 0x04, 0x20 +/* From TCG Algorithm Registry: Table 17 - Defines for AES Symmetric Cipher Algorithm + Constants */ +#define AES_ALLOWED_KEY_SIZE_128 YES +#define AES_ALLOWED_KEY_SIZE_192 YES +#define AES_ALLOWED_KEY_SIZE_256 YES +#define AES_128_BLOCK_SIZE_BYTES 16 +#define AES_192_BLOCK_SIZE_BYTES 16 +#define AES_256_BLOCK_SIZE_BYTES 16 +/* From TCG Algorithm Registry: Table 18 - Defines for SM4 Symmetric Cipher Algorithm Constants */ +#define SM4_ALLOWED_KEY_SIZE_128 YES +#define SM4_128_BLOCK_SIZE_BYTES 16 +/* From TCG Algorithm Registry: Table 19 - Defines for CAMELLIA Symmetric Cipher Algorithm + Constants */ +#define CAMELLIA_ALLOWED_KEY_SIZE_128 YES +#define CAMELLIA_ALLOWED_KEY_SIZE_192 YES +#define CAMELLIA_ALLOWED_KEY_SIZE_256 YES +#define CAMELLIA_128_BLOCK_SIZE_BYTES 16 +#define CAMELLIA_192_BLOCK_SIZE_BYTES 16 +#define CAMELLIA_256_BLOCK_SIZE_BYTES 16 +/* From TCG Algorithm Registry: Table 17 - Defines for TDES Symmetric Cipher Algorithm + Constants */ +#define TDES_ALLOWED_KEY_SIZE_128 YES +#define TDES_ALLOWED_KEY_SIZE_192 YES +#define TDES_128_BLOCK_SIZE_BYTES 8 +#define TDES_192_BLOCK_SIZE_BYTES 8 +/* From TPM 2.0 Part 2: Table 12 - Definition of TPM_CC Constants */ +typedef UINT32 TPM_CC; +#ifndef CC_NV_UndefineSpaceSpecial +# define CC_NV_UndefineSpaceSpecial NO +#endif +#if CC_NV_UndefineSpaceSpecial == YES +#define TPM_CC_NV_UndefineSpaceSpecial (TPM_CC)(0x0000011f) +#endif +#ifndef CC_EvictControl +# define CC_EvictControl NO +#endif +#if CC_EvictControl == YES +#define TPM_CC_EvictControl (TPM_CC)(0x00000120) +#endif +#ifndef CC_HierarchyControl +# define CC_HierarchyControl NO +#endif +#if CC_HierarchyControl == YES +#define TPM_CC_HierarchyControl (TPM_CC)(0x00000121) +#endif +#ifndef CC_NV_UndefineSpace +# define CC_NV_UndefineSpace NO +#endif +#if CC_NV_UndefineSpace == YES +#define TPM_CC_NV_UndefineSpace (TPM_CC)(0x00000122) +#endif +#ifndef CC_ChangeEPS +# define CC_ChangeEPS NO +#endif +#if CC_ChangeEPS == YES +#define TPM_CC_ChangeEPS (TPM_CC)(0x00000124) +#endif +#ifndef CC_ChangePPS +# define CC_ChangePPS NO +#endif +#if CC_ChangePPS == YES +#define TPM_CC_ChangePPS (TPM_CC)(0x00000125) +#endif +#ifndef CC_Clear +# define CC_Clear NO +#endif +#if CC_Clear == YES +#define TPM_CC_Clear (TPM_CC)(0x00000126) +#endif +#ifndef CC_ClearControl +# define CC_ClearControl NO +#endif +#if CC_ClearControl == YES +#define TPM_CC_ClearControl (TPM_CC)(0x00000127) +#endif +#ifndef CC_ClockSet +# define CC_ClockSet NO +#endif +#if CC_ClockSet == YES +#define TPM_CC_ClockSet (TPM_CC)(0x00000128) +#endif +#ifndef CC_HierarchyChangeAuth +# define CC_HierarchyChangeAuth NO +#endif +#if CC_HierarchyChangeAuth == YES +#define TPM_CC_HierarchyChangeAuth (TPM_CC)(0x00000129) +#endif +#ifndef CC_NV_DefineSpace +# define CC_NV_DefineSpace NO +#endif +#if CC_NV_DefineSpace == YES +#define TPM_CC_NV_DefineSpace (TPM_CC)(0x0000012a) +#endif +#ifndef CC_PCR_Allocate +# define CC_PCR_Allocate NO +#endif +#if CC_PCR_Allocate == YES +#define TPM_CC_PCR_Allocate (TPM_CC)(0x0000012b) +#endif +#ifndef CC_PCR_SetAuthPolicy +# define CC_PCR_SetAuthPolicy NO +#endif +#if CC_PCR_SetAuthPolicy == YES +#define TPM_CC_PCR_SetAuthPolicy (TPM_CC)(0x0000012c) +#endif +#ifndef CC_PP_Commands +# define CC_PP_Commands NO +#endif +#if CC_PP_Commands == YES +#define TPM_CC_PP_Commands (TPM_CC)(0x0000012d) +#endif +#ifndef CC_SetPrimaryPolicy +# define CC_SetPrimaryPolicy NO +#endif +#if CC_SetPrimaryPolicy == YES +#define TPM_CC_SetPrimaryPolicy (TPM_CC)(0x0000012e) +#endif +#ifndef CC_FieldUpgradeStart +# define CC_FieldUpgradeStart NO +#endif +#if CC_FieldUpgradeStart == YES +#define TPM_CC_FieldUpgradeStart (TPM_CC)(0x0000012f) +#endif +#ifndef CC_ClockRateAdjust +# define CC_ClockRateAdjust NO +#endif +#if CC_ClockRateAdjust == YES +#define TPM_CC_ClockRateAdjust (TPM_CC)(0x00000130) +#endif +#ifndef CC_CreatePrimary +# define CC_CreatePrimary NO +#endif +#if CC_CreatePrimary == YES +#define TPM_CC_CreatePrimary (TPM_CC)(0x00000131) +#endif +#ifndef CC_NV_GlobalWriteLock +# define CC_NV_GlobalWriteLock NO +#endif +#if CC_NV_GlobalWriteLock == YES +#define TPM_CC_NV_GlobalWriteLock (TPM_CC)(0x00000132) +#endif +#ifndef CC_GetCommandAuditDigest +# define CC_GetCommandAuditDigest NO +#endif +#if CC_GetCommandAuditDigest == YES +#define TPM_CC_GetCommandAuditDigest (TPM_CC)(0x00000133) +#endif +#ifndef CC_NV_Increment +# define CC_NV_Increment NO +#endif +#if CC_NV_Increment == YES +#define TPM_CC_NV_Increment (TPM_CC)(0x00000134) +#endif +#ifndef CC_NV_SetBits +# define CC_NV_SetBits NO +#endif +#if CC_NV_SetBits == YES +#define TPM_CC_NV_SetBits (TPM_CC)(0x00000135) +#endif +#ifndef CC_NV_Extend +# define CC_NV_Extend NO +#endif +#if CC_NV_Extend == YES +#define TPM_CC_NV_Extend (TPM_CC)(0x00000136) +#endif +#ifndef CC_NV_Write +# define CC_NV_Write NO +#endif +#if CC_NV_Write == YES +#define TPM_CC_NV_Write (TPM_CC)(0x00000137) +#endif +#ifndef CC_NV_WriteLock +# define CC_NV_WriteLock NO +#endif +#if CC_NV_WriteLock == YES +#define TPM_CC_NV_WriteLock (TPM_CC)(0x00000138) +#endif +#ifndef CC_DictionaryAttackLockReset +# define CC_DictionaryAttackLockReset NO +#endif +#if CC_DictionaryAttackLockReset == YES +#define TPM_CC_DictionaryAttackLockReset (TPM_CC)(0x00000139) +#endif +#ifndef CC_DictionaryAttackParameters +# define CC_DictionaryAttackParameters NO +#endif +#if CC_DictionaryAttackParameters == YES +#define TPM_CC_DictionaryAttackParameters (TPM_CC)(0x0000013a) +#endif +#ifndef CC_NV_ChangeAuth +# define CC_NV_ChangeAuth NO +#endif +#if CC_NV_ChangeAuth == YES +#define TPM_CC_NV_ChangeAuth (TPM_CC)(0x0000013b) +#endif +#ifndef CC_PCR_Event +# define CC_PCR_Event NO +#endif +#if CC_PCR_Event == YES +#define TPM_CC_PCR_Event (TPM_CC)(0x0000013c) +#endif +#ifndef CC_PCR_Reset +# define CC_PCR_Reset NO +#endif +#if CC_PCR_Reset == YES +#define TPM_CC_PCR_Reset (TPM_CC)(0x0000013d) +#endif +#ifndef CC_SequenceComplete +# define CC_SequenceComplete NO +#endif +#if CC_SequenceComplete == YES +#define TPM_CC_SequenceComplete (TPM_CC)(0x0000013e) +#endif +#ifndef CC_SetAlgorithmSet +# define CC_SetAlgorithmSet NO +#endif +#if CC_SetAlgorithmSet == YES +#define TPM_CC_SetAlgorithmSet (TPM_CC)(0x0000013f) +#endif +#ifndef CC_SetCommandCodeAuditStatus +# define CC_SetCommandCodeAuditStatus NO +#endif +#if CC_SetCommandCodeAuditStatus == YES +#define TPM_CC_SetCommandCodeAuditStatus (TPM_CC)(0x00000140) +#endif +#ifndef CC_FieldUpgradeData +# define CC_FieldUpgradeData NO +#endif +#if CC_FieldUpgradeData == YES +#define TPM_CC_FieldUpgradeData (TPM_CC)(0x00000141) +#endif +#ifndef CC_IncrementalSelfTest +# define CC_IncrementalSelfTest NO +#endif +#if CC_IncrementalSelfTest == YES +#define TPM_CC_IncrementalSelfTest (TPM_CC)(0x00000142) +#endif +#ifndef CC_SelfTest +# define CC_SelfTest NO +#endif +#if CC_SelfTest == YES +#define TPM_CC_SelfTest (TPM_CC)(0x00000143) +#endif +#ifndef CC_Startup +# define CC_Startup NO +#endif +#if CC_Startup == YES +#define TPM_CC_Startup (TPM_CC)(0x00000144) +#endif +#ifndef CC_Shutdown +# define CC_Shutdown NO +#endif +#if CC_Shutdown == YES +#define TPM_CC_Shutdown (TPM_CC)(0x00000145) +#endif +#ifndef CC_StirRandom +# define CC_StirRandom NO +#endif +#if CC_StirRandom == YES +#define TPM_CC_StirRandom (TPM_CC)(0x00000146) +#endif +#ifndef CC_ActivateCredential +# define CC_ActivateCredential NO +#endif +#if CC_ActivateCredential == YES +#define TPM_CC_ActivateCredential (TPM_CC)(0x00000147) +#endif +#ifndef CC_Certify +# define CC_Certify NO +#endif +#if CC_Certify == YES +#define TPM_CC_Certify (TPM_CC)(0x00000148) +#endif +#ifndef CC_PolicyNV +# define CC_PolicyNV NO +#endif +#if CC_PolicyNV == YES +#define TPM_CC_PolicyNV (TPM_CC)(0x00000149) +#endif +#ifndef CC_CertifyCreation +# define CC_CertifyCreation NO +#endif +#if CC_CertifyCreation == YES +#define TPM_CC_CertifyCreation (TPM_CC)(0x0000014a) +#endif +#ifndef CC_Duplicate +# define CC_Duplicate NO +#endif +#if CC_Duplicate == YES +#define TPM_CC_Duplicate (TPM_CC)(0x0000014b) +#endif +#ifndef CC_GetTime +# define CC_GetTime NO +#endif +#if CC_GetTime == YES +#define TPM_CC_GetTime (TPM_CC)(0x0000014c) +#endif +#ifndef CC_GetSessionAuditDigest +# define CC_GetSessionAuditDigest NO +#endif +#if CC_GetSessionAuditDigest == YES +#define TPM_CC_GetSessionAuditDigest (TPM_CC)(0x0000014d) +#endif +#ifndef CC_NV_Read +# define CC_NV_Read NO +#endif +#if CC_NV_Read == YES +#define TPM_CC_NV_Read (TPM_CC)(0x0000014e) +#endif +#ifndef CC_NV_ReadLock +# define CC_NV_ReadLock NO +#endif +#if CC_NV_ReadLock == YES +#define TPM_CC_NV_ReadLock (TPM_CC)(0x0000014f) +#endif +#ifndef CC_ObjectChangeAuth +# define CC_ObjectChangeAuth NO +#endif +#if CC_ObjectChangeAuth == YES +#define TPM_CC_ObjectChangeAuth (TPM_CC)(0x00000150) +#endif +#ifndef CC_PolicySecret +# define CC_PolicySecret NO +#endif +#if CC_PolicySecret == YES +#define TPM_CC_PolicySecret (TPM_CC)(0x00000151) +#endif +#ifndef CC_Rewrap +# define CC_Rewrap NO +#endif +#if CC_Rewrap == YES +#define TPM_CC_Rewrap (TPM_CC)(0x00000152) +#endif +#ifndef CC_Create +# define CC_Create NO +#endif +#if CC_Create == YES +#define TPM_CC_Create (TPM_CC)(0x00000153) +#endif +#ifndef CC_ECDH_ZGen +# define CC_ECDH_ZGen NO +#endif +#if CC_ECDH_ZGen == YES +#define TPM_CC_ECDH_ZGen (TPM_CC)(0x00000154) +#endif +#ifndef CC_HMAC +# define CC_HMAC NO +#endif +#if CC_HMAC == YES +#define TPM_CC_HMAC (TPM_CC)(0x00000155) +#endif +#ifndef CC_Import +# define CC_Import NO +#endif +#if CC_Import == YES +#define TPM_CC_Import (TPM_CC)(0x00000156) +#endif +#ifndef CC_Load +# define CC_Load NO +#endif +#if CC_Load == YES +#define TPM_CC_Load (TPM_CC)(0x00000157) +#endif +#ifndef CC_Quote +# define CC_Quote NO +#endif +#if CC_Quote == YES +#define TPM_CC_Quote (TPM_CC)(0x00000158) +#endif +#ifndef CC_RSA_Decrypt +# define CC_RSA_Decrypt NO +#endif +#if CC_RSA_Decrypt == YES +#define TPM_CC_RSA_Decrypt (TPM_CC)(0x00000159) +#endif +#ifndef CC_HMAC_Start +# define CC_HMAC_Start NO +#endif +#if CC_HMAC_Start == YES +#define TPM_CC_HMAC_Start (TPM_CC)(0x0000015b) +#endif +#ifndef CC_SequenceUpdate +# define CC_SequenceUpdate NO +#endif +#if CC_SequenceUpdate == YES +#define TPM_CC_SequenceUpdate (TPM_CC)(0x0000015c) +#endif +#ifndef CC_Sign +# define CC_Sign NO +#endif +#if CC_Sign == YES +#define TPM_CC_Sign (TPM_CC)(0x0000015d) +#endif +#ifndef CC_Unseal +# define CC_Unseal NO +#endif +#if CC_Unseal == YES +#define TPM_CC_Unseal (TPM_CC)(0x0000015e) +#endif +#ifndef CC_PolicySigned +# define CC_PolicySigned NO +#endif +#if CC_PolicySigned == YES +#define TPM_CC_PolicySigned (TPM_CC)(0x00000160) +#endif +#ifndef CC_ContextLoad +# define CC_ContextLoad NO +#endif +#if CC_ContextLoad == YES +#define TPM_CC_ContextLoad (TPM_CC)(0x00000161) +#endif +#ifndef CC_ContextSave +# define CC_ContextSave NO +#endif +#if CC_ContextSave == YES +#define TPM_CC_ContextSave (TPM_CC)(0x00000162) +#endif +#ifndef CC_ECDH_KeyGen +# define CC_ECDH_KeyGen NO +#endif +#if CC_ECDH_KeyGen == YES +#define TPM_CC_ECDH_KeyGen (TPM_CC)(0x00000163) +#endif +#ifndef CC_EncryptDecrypt +# define CC_EncryptDecrypt NO +#endif +#if CC_EncryptDecrypt == YES +#define TPM_CC_EncryptDecrypt (TPM_CC)(0x00000164) +#endif +#ifndef CC_FlushContext +# define CC_FlushContext NO +#endif +#if CC_FlushContext == YES +#define TPM_CC_FlushContext (TPM_CC)(0x00000165) +#endif +#ifndef CC_LoadExternal +# define CC_LoadExternal NO +#endif +#if CC_LoadExternal == YES +#define TPM_CC_LoadExternal (TPM_CC)(0x00000167) +#endif +#ifndef CC_MakeCredential +# define CC_MakeCredential NO +#endif +#if CC_MakeCredential == YES +#define TPM_CC_MakeCredential (TPM_CC)(0x00000168) +#endif +#ifndef CC_NV_ReadPublic +# define CC_NV_ReadPublic NO +#endif +#if CC_NV_ReadPublic == YES +#define TPM_CC_NV_ReadPublic (TPM_CC)(0x00000169) +#endif +#ifndef CC_PolicyAuthorize +# define CC_PolicyAuthorize NO +#endif +#if CC_PolicyAuthorize == YES +#define TPM_CC_PolicyAuthorize (TPM_CC)(0x0000016a) +#endif +#ifndef CC_PolicyAuthValue +# define CC_PolicyAuthValue NO +#endif +#if CC_PolicyAuthValue == YES +#define TPM_CC_PolicyAuthValue (TPM_CC)(0x0000016b) +#endif +#ifndef CC_PolicyCommandCode +# define CC_PolicyCommandCode NO +#endif +#if CC_PolicyCommandCode == YES +#define TPM_CC_PolicyCommandCode (TPM_CC)(0x0000016c) +#endif +#ifndef CC_PolicyCounterTimer +# define CC_PolicyCounterTimer NO +#endif +#if CC_PolicyCounterTimer == YES +#define TPM_CC_PolicyCounterTimer (TPM_CC)(0x0000016d) +#endif +#ifndef CC_PolicyCpHash +# define CC_PolicyCpHash NO +#endif +#if CC_PolicyCpHash == YES +#define TPM_CC_PolicyCpHash (TPM_CC)(0x0000016e) +#endif +#ifndef CC_PolicyLocality +# define CC_PolicyLocality NO +#endif +#if CC_PolicyLocality == YES +#define TPM_CC_PolicyLocality (TPM_CC)(0x0000016f) +#endif +#ifndef CC_PolicyNameHash +# define CC_PolicyNameHash NO +#endif +#if CC_PolicyNameHash == YES +#define TPM_CC_PolicyNameHash (TPM_CC)(0x00000170) +#endif +#ifndef CC_PolicyOR +# define CC_PolicyOR NO +#endif +#if CC_PolicyOR == YES +#define TPM_CC_PolicyOR (TPM_CC)(0x00000171) +#endif +#ifndef CC_PolicyTicket +# define CC_PolicyTicket NO +#endif +#if CC_PolicyTicket == YES +#define TPM_CC_PolicyTicket (TPM_CC)(0x00000172) +#endif +#ifndef CC_ReadPublic +# define CC_ReadPublic NO +#endif +#if CC_ReadPublic == YES +#define TPM_CC_ReadPublic (TPM_CC)(0x00000173) +#endif +#ifndef CC_RSA_Encrypt +# define CC_RSA_Encrypt NO +#endif +#if CC_RSA_Encrypt == YES +#define TPM_CC_RSA_Encrypt (TPM_CC)(0x00000174) +#endif +#ifndef CC_StartAuthSession +# define CC_StartAuthSession NO +#endif +#if CC_StartAuthSession == YES +#define TPM_CC_StartAuthSession (TPM_CC)(0x00000176) +#endif +#ifndef CC_VerifySignature +# define CC_VerifySignature NO +#endif +#if CC_VerifySignature == YES +#define TPM_CC_VerifySignature (TPM_CC)(0x00000177) +#endif +#ifndef CC_ECC_Parameters +# define CC_ECC_Parameters NO +#endif +#if CC_ECC_Parameters == YES +#define TPM_CC_ECC_Parameters (TPM_CC)(0x00000178) +#endif +#ifndef CC_FirmwareRead +# define CC_FirmwareRead NO +#endif +#if CC_FirmwareRead == YES +#define TPM_CC_FirmwareRead (TPM_CC)(0x00000179) +#endif +#ifndef CC_GetCapability +# define CC_GetCapability NO +#endif +#if CC_GetCapability == YES +#define TPM_CC_GetCapability (TPM_CC)(0x0000017a) +#endif +#ifndef CC_GetRandom +# define CC_GetRandom NO +#endif +#if CC_GetRandom == YES +#define TPM_CC_GetRandom (TPM_CC)(0x0000017b) +#endif +#ifndef CC_GetTestResult +# define CC_GetTestResult NO +#endif +#if CC_GetTestResult == YES +#define TPM_CC_GetTestResult (TPM_CC)(0x0000017c) +#endif +#ifndef CC_Hash +# define CC_Hash NO +#endif +#if CC_Hash == YES +#define TPM_CC_Hash (TPM_CC)(0x0000017d) +#endif +#ifndef CC_PCR_Read +# define CC_PCR_Read NO +#endif +#if CC_PCR_Read == YES +#define TPM_CC_PCR_Read (TPM_CC)(0x0000017e) +#endif +#ifndef CC_PolicyPCR +# define CC_PolicyPCR NO +#endif +#if CC_PolicyPCR == YES +#define TPM_CC_PolicyPCR (TPM_CC)(0x0000017f) +#endif +#ifndef CC_PolicyRestart +# define CC_PolicyRestart NO +#endif +#if CC_PolicyRestart == YES +#define TPM_CC_PolicyRestart (TPM_CC)(0x00000180) +#endif +#ifndef CC_ReadClock +# define CC_ReadClock NO +#endif +#if CC_ReadClock == YES +#define TPM_CC_ReadClock (TPM_CC)(0x00000181) +#endif +#ifndef CC_PCR_Extend +# define CC_PCR_Extend NO +#endif +#if CC_PCR_Extend == YES +#define TPM_CC_PCR_Extend (TPM_CC)(0x00000182) +#endif +#ifndef CC_PCR_SetAuthValue +# define CC_PCR_SetAuthValue NO +#endif +#if CC_PCR_SetAuthValue == YES +#define TPM_CC_PCR_SetAuthValue (TPM_CC)(0x00000183) +#endif +#ifndef CC_NV_Certify +# define CC_NV_Certify NO +#endif +#if CC_NV_Certify == YES +#define TPM_CC_NV_Certify (TPM_CC)(0x00000184) +#endif +#ifndef CC_EventSequenceComplete +# define CC_EventSequenceComplete NO +#endif +#if CC_EventSequenceComplete == YES +#define TPM_CC_EventSequenceComplete (TPM_CC)(0x00000185) +#endif +#ifndef CC_HashSequenceStart +# define CC_HashSequenceStart NO +#endif +#if CC_HashSequenceStart == YES +#define TPM_CC_HashSequenceStart (TPM_CC)(0x00000186) +#endif +#ifndef CC_PolicyPhysicalPresence +# define CC_PolicyPhysicalPresence NO +#endif +#if CC_PolicyPhysicalPresence == YES +#define TPM_CC_PolicyPhysicalPresence (TPM_CC)(0x00000187) +#endif +#ifndef CC_PolicyDuplicationSelect +# define CC_PolicyDuplicationSelect NO +#endif +#if CC_PolicyDuplicationSelect == YES +#define TPM_CC_PolicyDuplicationSelect (TPM_CC)(0x00000188) +#endif +#ifndef CC_PolicyGetDigest +# define CC_PolicyGetDigest NO +#endif +#if CC_PolicyGetDigest == YES +#define TPM_CC_PolicyGetDigest (TPM_CC)(0x00000189) +#endif +#ifndef CC_TestParms +# define CC_TestParms NO +#endif +#if CC_TestParms == YES +#define TPM_CC_TestParms (TPM_CC)(0x0000018a) +#endif +#ifndef CC_Commit +# define CC_Commit NO +#endif +#if CC_Commit == YES +#define TPM_CC_Commit (TPM_CC)(0x0000018b) +#endif +#ifndef CC_PolicyPassword +# define CC_PolicyPassword NO +#endif +#if CC_PolicyPassword == YES +#define TPM_CC_PolicyPassword (TPM_CC)(0x0000018c) +#endif +#ifndef CC_ZGen_2Phase +# define CC_ZGen_2Phase NO +#endif +#if CC_ZGen_2Phase == YES +#define TPM_CC_ZGen_2Phase (TPM_CC)(0x0000018d) +#endif +#ifndef CC_EC_Ephemeral +# define CC_EC_Ephemeral NO +#endif +#if CC_EC_Ephemeral == YES +#define TPM_CC_EC_Ephemeral (TPM_CC)(0x0000018e) +#endif +#ifndef CC_PolicyNvWritten +# define CC_PolicyNvWritten NO +#endif +#if CC_PolicyNvWritten == YES +#define TPM_CC_PolicyNvWritten (TPM_CC)(0x0000018f) +#endif +#ifndef CC_PolicyTemplate +# define CC_PolicyTemplate NO +#endif +#if CC_PolicyTemplate == YES +#define TPM_CC_PolicyTemplate (TPM_CC)(0x00000190) +#endif +#ifndef CC_CreateLoaded +# define CC_CreateLoaded NO +#endif +#if CC_CreateLoaded == YES +#define TPM_CC_CreateLoaded (TPM_CC)(0x00000191) +#endif +#ifndef CC_PolicyAuthorizeNV +# define CC_PolicyAuthorizeNV NO +#endif +#if CC_PolicyAuthorizeNV == YES +#define TPM_CC_PolicyAuthorizeNV (TPM_CC)(0x00000192) +#endif +#ifndef CC_EncryptDecrypt2 +# define CC_EncryptDecrypt2 NO +#endif +#if CC_EncryptDecrypt2 == YES +#define TPM_CC_EncryptDecrypt2 (TPM_CC)(0x00000193) +#endif +#ifndef CC_AC_Send +# define CC_AC_Send NO +#endif +#if CC_AC_Send == YES +#define TPM_CC_AC_Send (TPM_CC)(0x00000195) +#endif +#ifndef CC_Policy_AC_SendSelect +# define CC_Policy_AC_SendSelect NO +#endif +#if CC_Policy_AC_SendSelect == YES +#define TPM_CC_Policy_AC_SendSelect (TPM_CC)(0x00000196) +#endif +#ifndef CC_SMAC +# define CC_SMAC NO +#endif +#if CC_SMAC == YES +#define TPM_CC_SMAC (TPM_CC)(0x00000197) +#endif +#define CC_VEND (TPM_CC)(0x20000000) +#ifndef CC_Vendor_TCG_Test +# define CC_Vendor_TCG_Test NO +#endif +#if CC_Vendor_TCG_Test == YES +#define TPM_CC_Vendor_TCG_Test (TPM_CC)(0x20000000) +#endif + +#ifndef COMPRESSED_LISTS +#define ADD_FILL 1 +#else +#define ADD_FILL 0 +#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) /* 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) /* 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 /* 0x00000197 */ \ + ) + +#define VENDOR_COMMAND_ARRAY_SIZE ( 0 \ + + CC_Vendor_TCG_Test \ + ) + +#define COMMAND_COUNT \ + (LIBRARY_COMMAND_ARRAY_SIZE + VENDOR_COMMAND_ARRAY_SIZE) +#ifndef MAX +#define MAX(a, b) ((a) > (b) ? (a) : (b)) +#endif +#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_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_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 HASH_COUNT (ALG_SHA1+ALG_SHA256+ALG_SHA384+ALG_SHA512+ALG_SM3_256) +/* 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; +#ifndef MAX +#define MAX(a, b) ((a) > (b) ? (a) : (b)) +#endif +#ifndef ALG_AES +# define ALG_AES NO +#endif +#ifndef MAX_AES_KEY_BITS +# define MAX_AES_KEY_BITS 0 +# define MAX_AES_BLOCK_SIZE_BYTES 0 +#endif +#ifndef ALG_CAMELLIA +# define ALG_CAMELLIA NO +#endif +#ifndef MAX_CAMELLIA_KEY_BITS +# define MAX_CAMELLIA_KEY_BITS 0 +# define MAX_CAMELLIA_BLOCK_SIZE_BYTES 0 +#endif +#ifndef ALG_SM4 +# define ALG_SM4 NO +#endif +#ifndef MAX_SM4_KEY_BITS +# define MAX_SM4_KEY_BITS 0 +# define MAX_SM4_BLOCK_SIZE_BYTES 0 +#endif +#ifndef ALG_TDES +# define ALG_TDES NO +#endif +#ifndef MAX_TDES_KEY_BITS +# define MAX_TDES_KEY_BITS 0 +# define MAX_TDES_BLOCK_SIZE_BYTES 0 +#endif +#define MAX_SYM_KEY_BITS ( \ + MAX(MAX_AES_KEY_BITS * ALG_AES, \ + MAX(MAX_CAMELLIA_KEY_BITS * ALG_CAMELLIA, \ + MAX(MAX_SM4_KEY_BITS * ALG_SM4, \ + MAX(MAX_TDES_KEY_BITS * ALG_TDES, \ + 0))))) +#define MAX_SYM_KEY_BYTES ((MAX_SYM_KEY_BITS + 7) / 8) +#define MAX_SYM_BLOCK_SIZE ( \ + MAX(MAX_AES_BLOCK_SIZE_BYTES * ALG_AES, \ + MAX(MAX_CAMELLIA_BLOCK_SIZE_BYTES * ALG_CAMELLIA, \ + MAX(MAX_SM4_BLOCK_SIZE_BYTES * ALG_SM4, \ + MAX(MAX_TDES_BLOCK_SIZE_BYTES * ALG_TDES, \ + 0))))) +#if MAX_SYM_KEY_BITS == 0 || MAX_SYM_BLOCK_SIZE == 0 +# error Bad size for MAX_SYM_KEY_BITS or MAX_SYM_BLOCK_SIZE +#endif +/* Define the 2B structure for a seed */ +TPM2B_TYPE(SEED, PRIMARY_SEED_SIZE); +#endif // _IMPLEMENTATION_H_ diff --git a/src/tpm2/Import_fp.h b/src/tpm2/Import_fp.h new file mode 100644 index 00000000..f059b98c --- /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 00000000..f8173522 --- /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 00000000..89394b89 --- /dev/null +++ b/src/tpm2/IntegrityCommands.c @@ -0,0 +1,411 @@ +/********************************************************************************/ +/* */ +/* */ +/* Written by Ken Goldman */ +/* IBM Thomas J. Watson Research Center */ +/* $Id: IntegrityCommands.c 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 */ +/* */ +/********************************************************************************/ + +#include "Tpm.h" +#include "PCR_Extend_fp.h" +#ifdef TPM_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" +#ifdef TPM_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" +#ifdef TPM_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" +#ifdef TPM_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" +#ifdef TPM_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" +#ifdef TPM_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" +#ifdef TPM_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 00000000..03ad689c --- /dev/null +++ b/src/tpm2/InternalRoutines.h @@ -0,0 +1,138 @@ +/********************************************************************************/ +/* */ +/* Include Headers for Internal Routines */ +/* Written by Ken Goldman */ +/* IBM Thomas J. Watson Research Center */ +/* $Id: InternalRoutines.h 953 2017-03-06 20:31: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, 2017 */ +/* */ +/********************************************************************************/ + +#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 "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" +#ifdef TPM_CC_AC_Send +# include "AC_spt_fp.h" +#endif // TPM_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 crypto 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" +#ifdef TPM_ALG_RSA +#include "CryptRsa_fp.h" +#include "CryptPrimeSieve_fp.h" +#endif +#ifdef TPM_ALG_ECC +#include "CryptEccMain_fp.h" +#include "CryptEccSignature_fp.h" +#include "CryptEccKeyExchange_fp.h" +#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 00000000..df00256c --- /dev/null +++ b/src/tpm2/IoBuffers.c @@ -0,0 +1,115 @@ +/********************************************************************************/ +/* */ +/* */ +/* Written by Ken Goldman */ +/* IBM Thomas J. Watson Research Center */ +/* $Id: IoBuffers.c 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 */ +/* */ +/********************************************************************************/ + +/* 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" +/* 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.1.1 MemoryGetActionInputBuffer() */ +/* This function returns the address of the buffer into which the command parameters will be + unmarshaled in preparation for calling the command actions. */ +BYTE * +MemoryGetActionInputBuffer( + UINT32 size // Size, in bytes, required for the input + // unmarshaling + ) +{ + pAssert(size <= sizeof(s_actionInputBuffer)); + // In this implementation, a static buffer is set aside for the command action + // input buffer. + memset(s_actionInputBuffer, 0, size); + return (BYTE *)&s_actionInputBuffer[0]; +} +/* 9.7.1.2 MemoryGetActionOutputBuffer() */ +/* This function returns the address of the buffer into which the command action code places its + output values. */ +void * +MemoryGetActionOutputBuffer( + UINT32 size // required size of the buffer + ) +{ + pAssert(size < sizeof(s_actionOutputBuffer)); + // In this implementation, a static buffer is set aside for the command action + // output buffer. + memset(s_actionOutputBuffer, 0, size); + return s_actionOutputBuffer; +} +/* 9.7.1.3 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 Values Meaning */ +/* FALSE string is not null terminated */ +/* TRUE string is null terminated */ +#ifndef INLINE_FUNCTIONS +BOOL +IsLabelProperlyFormatted( + TPM2B *x + ) +{ + return (((x)->size == 0) || ((x)->buffer[(x)->size - 1] == 0)); +} +#endif // INLINE_FUNCTIONS diff --git a/src/tpm2/IoBuffers_fp.h b/src/tpm2/IoBuffers_fp.h new file mode 100644 index 00000000..7d7001d6 --- /dev/null +++ b/src/tpm2/IoBuffers_fp.h @@ -0,0 +1,80 @@ +/********************************************************************************/ +/* */ +/* */ +/* Written by Ken Goldman */ +/* IBM Thomas J. Watson Research Center */ +/* $Id: IoBuffers_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 IOBUFFERS_FP_H +#define IOBUFFERS_FP_H + +BYTE * +MemoryGetActionInputBuffer( + UINT32 size // Size, in bytes, required for the input + // unmarshaling + ); +void * +MemoryGetActionOutputBuffer( + UINT32 size // required size of the buffer + ); +BOOL +IsLabelProperlyFormatted( + TPM2B *x + ); + + +#endif diff --git a/src/tpm2/LoadExternal_fp.h b/src/tpm2/LoadExternal_fp.h new file mode 100644 index 00000000..24651136 --- /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 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 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 00000000..dd94f000 --- /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 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 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 00000000..f69ea481 --- /dev/null +++ b/src/tpm2/Locality.c @@ -0,0 +1,99 @@ +/********************************************************************************/ +/* */ +/* */ +/* Written by Ken Goldman */ +/* IBM Thomas J. Watson Research Center */ +/* $Id: Locality.c 953 2017-03-06 20:31: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 */ +/* */ +/********************************************************************************/ + +/* 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: + locality_attributes.TPM_LOC_ZERO = SET; + break; + case 1: + locality_attributes.TPM_LOC_ONE = SET; + break; + case 2: + locality_attributes.TPM_LOC_TWO = SET; + break; + case 3: + locality_attributes.TPM_LOC_THREE = SET; + break; + case 4: + locality_attributes.TPM_LOC_FOUR = SET; + 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 00000000..47f18e7d --- /dev/null +++ b/src/tpm2/LocalityPlat.c @@ -0,0 +1,88 @@ +/********************************************************************************/ +/* */ +/* */ +/* Written by Ken Goldman */ +/* IBM Thomas J. Watson Research Center */ +/* $Id: LocalityPlat.c 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 */ +/* */ +/********************************************************************************/ + +/* C.5 LocalityPlat.c */ +/* C.5.1. Includes */ +#include "PlatformData.h" +#include "Platform_fp.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 00000000..961450e5 --- /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 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 LOCALITY_FP_H +#define LOCALITY_FP_H + +TPMA_LOCALITY +LocalityGetAttributes( + UINT8 locality // IN: locality value + ); + + +#endif diff --git a/src/tpm2/MakeCredential_fp.h b/src/tpm2/MakeCredential_fp.h new file mode 100644 index 00000000..e824a51c --- /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 00000000..88173eff --- /dev/null +++ b/src/tpm2/ManagementCommands.c @@ -0,0 +1,113 @@ +/********************************************************************************/ +/* */ +/* */ +/* Written by Ken Goldman */ +/* IBM Thomas J. Watson Research Center */ +/* $Id: ManagementCommands.c 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 */ +/* */ +/********************************************************************************/ + +#include "Tpm.h" +#include "PP_Commands_fp.h" +#ifdef TPM_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" +#ifdef TPM_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 00000000..d2f53826 --- /dev/null +++ b/src/tpm2/Manufacture.c @@ -0,0 +1,176 @@ +/********************************************************************************/ +/* */ +/* */ +/* Written by Ken Goldman */ +/* IBM Thomas J. Watson Research Center */ +/* $Id: Manufacture.c 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 */ +/* */ +/********************************************************************************/ + +/* 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" +/* 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 */ +/* 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; +#ifdef RUNTIME_SIZE_CHECKS + // Call the function to verify the sizes of values that result from different + // compile options. + TpmSizeChecks(); +#endif + // If TPM has been manufactured, return indication. + if(!firstTime && g_manufactured) + return 1; + s_DAPendingOnNV = FALSE; + // initialize NV + NvManufacture(); + // Clear the magic value in the DRBG state + go.drbgState.magic = 0; + CryptStartup(SU_RESET); + // 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; +} +/* 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 + ) +{ +#ifdef SIMULATION + HashLibSimulationEnd(); + SymLibSimulationEnd(); + MathLibSimulationEnd(); +#ifdef TPM_ALG_RSA + RsaSimulationEnd(); +#endif +#ifdef TPM_ALG_ECC + EccSimulationEnd(); +#endif +#endif // SIMULATION +} diff --git a/src/tpm2/Manufacture_fp.h b/src/tpm2/Manufacture_fp.h new file mode 100644 index 00000000..cdbc8781 --- /dev/null +++ b/src/tpm2/Manufacture_fp.h @@ -0,0 +1,79 @@ +/********************************************************************************/ +/* */ +/* */ +/* Written by Ken Goldman */ +/* IBM Thomas J. Watson Research Center */ +/* $Id: Manufacture_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 MANUFACTURE_FP_H +#define MANUFACTURE_FP_H + +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 00000000..5220209a --- /dev/null +++ b/src/tpm2/Marshal.c @@ -0,0 +1,2185 @@ +/********************************************************************************/ +/* */ +/* */ +/* Written by Ken Goldman */ +/* IBM Thomas J. Watson Research Center */ +/* $Id: Marshal.c 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 */ +/* */ +/********************************************************************************/ + +/* rev 136 */ + +#include + +#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 +INT8_Marshal(INT8 *source, BYTE **buffer, INT32 *size) +{ + return UINT8_Marshal((UINT8 *)source, buffer, size); +} + +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 +INT32_Marshal(INT32 *source, BYTE **buffer, INT32 *size) +{ + return UINT32_Marshal((UINT32 *)source, buffer, size); +} + +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, BYTE **buffer, INT32 *size) +{ + UINT16 written = 0; + 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_GENERATED Constants (EnumTable()) */ +UINT16 +TPM_GENERATED_Marshal(TPM_GENERATED *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 */ + +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 */ + +#ifdef TPM_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(&source->val, buffer, size); + 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(&source->val, buffer, size); + 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 2:48 - Definition of TPMI_DH_CONTEXT Type (InterfaceTable()) */ + +UINT16 +TPMI_DH_CONTEXT_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) { +#ifdef TPM_ALG_SHA1 + case TPM_ALG_SHA1: + written += Array_Marshal(&source->sha1[0], SHA1_DIGEST_SIZE, buffer, size); + break; +#endif +#ifdef TPM_ALG_SHA256 + case TPM_ALG_SHA256: + written += Array_Marshal(&source->sha256[0], SHA256_DIGEST_SIZE, buffer, size); + break; +#endif +#ifdef TPM_ALG_SHA384 + case TPM_ALG_SHA384: + written += Array_Marshal(&source->sha384[0], SHA384_DIGEST_SIZE, buffer, size); + break; +#endif +#ifdef TPM_ALG_SHA512 + case TPM_ALG_SHA512: + written += Array_Marshal(&source->sha512[0], SHA512_DIGEST_SIZE, buffer, size); + break; +#endif +#ifdef TPM_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, buffer, size); +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, buffer, size); +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, buffer, size); + 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, buffer, size); + 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, buffer, size); + 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, buffer, size); + 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 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: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; + 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 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; + 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_GENERATED_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, buffer, size); + 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; +} + +/* 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) { +#ifdef TPM_ALG_AES + case TPM_ALG_AES: + written += TPMI_AES_KEY_BITS_Marshal(&source->aes, buffer, size); + break; +#endif +#ifdef TPM_ALG_SM4 + case TPM_ALG_SM4: + written += TPMI_SM4_KEY_BITS_Marshal(&source->sm4, buffer, size); + break; +#endif +#ifdef TPM_ALG_CAMELLIA + case TPM_ALG_CAMELLIA: + written += TPMI_CAMELLIA_KEY_BITS_Marshal(&source->camellia, buffer, size); + break; +#endif +#ifdef TPM_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) { +#ifdef TPM_ALG_AES + case TPM_ALG_AES: + written += TPMI_ALG_SYM_MODE_Marshal(&source->aes, buffer, size); + break; +#endif +#ifdef TPM_ALG_SM4 + case TPM_ALG_SM4: + written += TPMI_ALG_SYM_MODE_Marshal(&source->sm4, buffer, size); + break; +#endif +#ifdef TPM_ALG_CAMELLIA + case TPM_ALG_CAMELLIA: + written += TPMI_ALG_SYM_MODE_Marshal(&source->camellia, buffer, size); + break; +#endif +#ifdef TPM_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, buffer, size); + 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, buffer, size); + 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_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) { +#ifdef TPM_ALG_HMAC + case TPM_ALG_HMAC: + written += TPMS_SCHEME_HMAC_Marshal(&source->hmac, buffer, size); + break; +#endif +#ifdef TPM_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; +} + +/* Table 2:155 - Definition of Types for KDF Schemes (TypedefTable()) */ +UINT16 +TPMS_SCHEME_MGF1_Marshal(TPMS_SCHEME_MGF1 *source, BYTE **buffer, INT32 *size) +{ + UINT16 written = 0; + written += TPMS_SCHEME_HASH_Marshal(source, buffer, size); + return written; +} +UINT16 +TPMS_SCHEME_KDF1_SP800_56A_Marshal(TPMS_SCHEME_KDF1_SP800_56A *source, BYTE **buffer, INT32 *size) +{ + UINT16 written = 0; + written += TPMS_SCHEME_HASH_Marshal(source, buffer, size); + return written; +} +UINT16 +TPMS_SCHEME_KDF2_Marshal(TPMS_SCHEME_KDF2 *source, BYTE **buffer, INT32 *size) +{ + UINT16 written = 0; + written += TPMS_SCHEME_HASH_Marshal(source, buffer, size); + return written; +} +UINT16 +TPMS_SCHEME_KDF1_SP800_108_Marshal(TPMS_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) { +#ifdef TPM_ALG_MGF1 + case TPM_ALG_MGF1: + written += TPMS_SCHEME_MGF1_Marshal(&source->mgf1, buffer, size); + break; +#endif +#ifdef TPM_ALG_KDF1_SP800_56A + case TPM_ALG_KDF1_SP800_56A: + written += TPMS_SCHEME_KDF1_SP800_56A_Marshal(&source->kdf1_sp800_56a, buffer, size); + break; +#endif +#ifdef TPM_ALG_KDF2 + case TPM_ALG_KDF2: + written += TPMS_SCHEME_KDF2_Marshal(&source->kdf2, buffer, size); + break; +#endif +#ifdef TPM_ALG_KDF1_SP800_108 + case TPM_ALG_KDF1_SP800_108: + written += TPMS_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) { +#ifdef TPM_ALG_ECDH + case TPM_ALG_ECDH: + written += TPMS_KEY_SCHEME_ECDH_Marshal(&source->ecdh, buffer, size); + break; +#endif +#ifdef TPM_ALG_ECMQV + case TPM_ALG_ECMQV: + written += TPMS_KEY_SCHEME_ECMQV_Marshal(&source->ecmqvh, buffer, size); + break; +#endif +#ifdef TPM_ALG_RSASSA + case TPM_ALG_RSASSA: + written += TPMS_SIG_SCHEME_RSASSA_Marshal(&source->rsassa, buffer, size); + break; +#endif +#ifdef TPM_ALG_RSAPSS + case TPM_ALG_RSAPSS: + written += TPMS_SIG_SCHEME_RSAPSS_Marshal(&source->rsapss, buffer, size); + break; +#endif +#ifdef TPM_ALG_ECDSA + case TPM_ALG_ECDSA: + written += TPMS_SIG_SCHEME_ECDSA_Marshal(&source->ecdsa, buffer, size); + break; +#endif +#ifdef TPM_ALG_ECDAA + case TPM_ALG_ECDAA: + written += TPMS_SIG_SCHEME_ECDAA_Marshal(&source->ecdaa, buffer, size); + break; +#endif +#ifdef TPM_ALG_SM2 + case TPM_ALG_SM2: + written += TPMS_SIG_SCHEME_SM2_Marshal(&source->sm2, buffer, size); + break; +#endif +#ifdef TPM_ALG_ECSCHNORR + case TPM_ALG_ECSCHNORR: + written += TPMS_SIG_SCHEME_ECSCHNORR_Marshal(&source->ecschnorr, buffer, size); + break; +#endif +#ifdef TPM_ALG_RSAES + case TPM_ALG_RSAES: + written += TPMS_ENC_SCHEME_RSAES_Marshal(&source->rsaes, buffer, size); + break; +#endif +#ifdef TPM_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, buffer, size); + 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, buffer, size); + 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, buffer, size); + 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_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) { +#ifdef TPM_ALG_RSASSA + case TPM_ALG_RSASSA: + written += TPMS_SIGNATURE_RSASSA_Marshal(&source->rsassa, buffer, size); + break; +#endif +#ifdef TPM_ALG_RSAPSS + case TPM_ALG_RSAPSS: + written += TPMS_SIGNATURE_RSAPSS_Marshal(&source->rsapss, buffer, size); + break; +#endif +#ifdef TPM_ALG_ECDSA + case TPM_ALG_ECDSA: + written += TPMS_SIGNATURE_ECDSA_Marshal(&source->ecdsa, buffer, size); + break; +#endif +#ifdef TPM_ALG_ECDAA + case TPM_ALG_ECDAA: + written += TPMS_SIGNATURE_ECDAA_Marshal(&source->ecdaa, buffer, size); + break; +#endif +#ifdef TPM_ALG_SM2 + case TPM_ALG_SM2: + written += TPMS_SIGNATURE_SM2_Marshal(&source->sm2, buffer, size); + break; +#endif +#ifdef TPM_ALG_ECSCHNORR + case TPM_ALG_ECSCHNORR: + written += TPMS_SIGNATURE_ECSCHNORR_Marshal(&source->ecschnorr, buffer, size); + break; +#endif +#ifdef TPM_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, buffer, size); + 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) { +#ifdef TPM_ALG_KEYEDHASH + case TPM_ALG_KEYEDHASH: + written += TPM2B_DIGEST_Marshal(&source->keyedHash, buffer, size); + break; +#endif +#ifdef TPM_ALG_SYMCIPHER + case TPM_ALG_SYMCIPHER: + written += TPM2B_DIGEST_Marshal(&source->sym, buffer, size); + break; +#endif +#ifdef TPM_ALG_RSA + case TPM_ALG_RSA: + written += TPM2B_PUBLIC_KEY_RSA_Marshal(&source->rsa, buffer, size); + break; +#endif +#ifdef TPM_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) { +#ifdef TPM_ALG_KEYEDHASH + case TPM_ALG_KEYEDHASH: + written += TPMS_KEYEDHASH_PARMS_Marshal(&source->keyedHashDetail, buffer, size); + break; +#endif +#ifdef TPM_ALG_SYMCIPHER + case TPM_ALG_SYMCIPHER: + written += TPMS_SYMCIPHER_PARMS_Marshal(&source->symDetail, buffer, size); + break; +#endif +#ifdef TPM_ALG_RSA + case TPM_ALG_RSA: + written += TPMS_RSA_PARMS_Marshal(&source->rsaDetail, buffer, size); + break; +#endif +#ifdef TPM_ALG_ECC + case TPM_ALG_ECC: + written += TPMS_ECC_PARMS_Marshal(&source->eccDetail, buffer, size); + break; +#endif + default: + pAssert(FALSE); + } + return written; +} + +/* Table 2:190 - Definition of TPMT_PUBLIC_PARMS Structure (StructuresTable()) */ + +UINT16 +TPMT_PUBLIC_PARMS_Marshal(TPMT_PUBLIC_PARMS *source, BYTE **buffer, INT32 *size) +{ + UINT16 written = 0; + written += TPMI_ALG_PUBLIC_Marshal(&source->type, buffer, size); + written += TPMU_PUBLIC_PARMS_Marshal(&source->parameters, buffer, size, source->type); + 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; + + 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) { +#ifdef TPM_ALG_RSA + case TPM_ALG_RSA: + written += TPM2B_PRIVATE_KEY_RSA_Marshal(&source->rsa, buffer, size); + break; +#endif +#ifdef TPM_ALG_ECC + case TPM_ALG_ECC: + written += TPM2B_ECC_PARAMETER_Marshal(&source->ecc, buffer, size); + break; +#endif +#ifdef TPM_ALG_KEYEDHASH + case TPM_ALG_KEYEDHASH: + written += TPM2B_SENSITIVE_DATA_Marshal(&source->bits, buffer, size); + break; +#endif +#ifdef TPM_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, buffer, size); + 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, buffer, size); + 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(&source->val, buffer, size); + 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, buffer, size); + 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_CONTEXT_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; + + 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; +} + diff --git a/src/tpm2/Marshal_fp.h b/src/tpm2/Marshal_fp.h new file mode 100644 index 00000000..9a2c8f06 --- /dev/null +++ b/src/tpm2/Marshal_fp.h @@ -0,0 +1,378 @@ +/********************************************************************************/ +/* */ +/* */ +/* Written by Ken Goldman */ +/* IBM Thomas J. Watson Research Center */ +/* $Id: Marshal_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 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 + INT8_Marshal(INT8 *source, BYTE **buffer, INT32 *size); + UINT16 + UINT16_Marshal(UINT16 *source, BYTE **buffer, INT32 *size); + UINT16 + UINT32_Marshal(UINT32 *source, BYTE **buffer, INT32 *size); + UINT16 + INT32_Marshal(INT32 *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, BYTE **buffer, INT32 *size); + UINT16 + TPM_KEY_BITS_Marshal(TPM_KEY_BITS *source, BYTE **buffer, INT32 *size); + UINT16 + TPM_GENERATED_Marshal(TPM_GENERATED *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 + TPMI_DH_CONTEXT_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_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_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 + 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 + 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 + 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_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_SCHEME_MGF1_Marshal(TPMS_SCHEME_MGF1 *source, BYTE **buffer, INT32 *size); + UINT16 + TPMS_SCHEME_KDF1_SP800_56A_Marshal(TPMS_SCHEME_KDF1_SP800_56A *source, BYTE **buffer, INT32 *size); + UINT16 + TPMS_SCHEME_KDF2_Marshal(TPMS_SCHEME_KDF2 *source, BYTE **buffer, INT32 *size); + UINT16 + TPMS_SCHEME_KDF1_SP800_108_Marshal(TPMS_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_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_PARMS_Marshal(TPMT_PUBLIC_PARMS *source, BYTE **buffer, INT32 *size); + 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); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/tpm2/MathOnByteBuffers.c b/src/tpm2/MathOnByteBuffers.c new file mode 100644 index 00000000..9c15626b --- /dev/null +++ b/src/tpm2/MathOnByteBuffers.c @@ -0,0 +1,244 @@ +/********************************************************************************/ +/* */ +/* */ +/* Written by Ken Goldman */ +/* IBM Thomas J. Watson Research Center */ +/* $Id: MathOnByteBuffers.c 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 */ +/* */ +/********************************************************************************/ + +/* 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.1.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.1.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.1.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.1.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_SUCCESS operation complete */ +/* 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.1.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; + // This is a request to shift the number to the left (remove leading zeros) + if(num->size == requestedSize) + return requestedSize; + from = num->buffer; + if (num->size > requestedSize) + { + // Find the first non-zero byte. Don't look past the point where removing + // more zeros would make the number smaller than requested. + 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; +} diff --git a/src/tpm2/MathOnByteBuffers_fp.h b/src/tpm2/MathOnByteBuffers_fp.h new file mode 100644 index 00000000..d1df6358 --- /dev/null +++ b/src/tpm2/MathOnByteBuffers_fp.h @@ -0,0 +1,107 @@ +/********************************************************************************/ +/* */ +/* */ +/* Written by Ken Goldman */ +/* IBM Thomas J. Watson Research Center */ +/* $Id: MathOnByteBuffers_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 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 + ); + + +#endif diff --git a/src/tpm2/Memory.c b/src/tpm2/Memory.c new file mode 100644 index 00000000..0e1d3722 --- /dev/null +++ b/src/tpm2/Memory.c @@ -0,0 +1,291 @@ +/********************************************************************************/ +/* */ +/* */ +/* Written by Ken Goldman */ +/* IBM Thomas J. Watson Research Center */ +/* $Id: Memory.c 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 */ +/* */ +/********************************************************************************/ + +/* 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. The #if 0 is used to prevent instantiation of the MemoryCopy() function so that the #define + is always used */ +#ifndef INLINE_FUNCTIONS +void +MemoryCopy( + void *dest, + const void *src, + int sSize + ) +{ + memmove(dest, src, sSize); +} +#endif // INLINE_FUNCTIONS +/* 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 an 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. */ +#ifndef INLINE_FUNCTIONS +void +MemorySet( + void *dest, + int value, + size_t size + ) +{ + memset(dest, value, size); +} +#endif // INLINE_FUNCTIONS +/* 9.12.3.7 MemoryPad2B() */ +/* Function to pad a TPM2B with zeros and adjust the size. */ +#ifndef INLINE_FUNCTIONS +void +MemoryPad2B( + TPM2B *b, + UINT16 newSize + ) +{ + MemorySet(&b->buffer[b->size], 0, newSize - b->size); + b->size = newSize; +} +#endif // INLINE_FUNCTIONS +/* 9.12.3.8 Uint16ToByteArray() */ +/* Function to write an integer to a byte array */ +#ifndef INLINE_FUNCTIONS +void +Uint16ToByteArray( + UINT16 i, + BYTE *a + ) +{ + a[1] = (BYTE)(i); i >>= 8; + a[0] = (BYTE)(i); +} +#endif // INLINE_FUNCTIONS +/* 9.12.3.9 Uint32ToByteArray() */ +/* Function to write an integer to a byte array */ +#ifndef INLINE_FUNCTIONS +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); +} +#endif // INLINE_FUNCTIONS +/* 9.12.3.10 Uint64ToByteArray() */ +/* Function to write an integer to a byte array */ +#ifndef INLINE_FUNCTIONS +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); +} +#endif // INLINE_FUNCTIONS +/* 9.12.3.11 ByteArrayToUint16() */ +/* Function to write an integer to a byte array */ +#ifndef INLINE_FUNCTIONS +UINT16 +ByteArrayToUint16( + BYTE *a + ) +{ + UINT16 retVal; + retVal = a[0]; retVal <<= 8; + retVal += a[1]; + return retVal; +} +#endif // INLINE_FUNCTIONS +/* 9.12.3.12 ByteArrayToUint32() */ +/* Function to write an integer to a byte array */ +#ifndef INLINE_FUNCTIONS +UINT32 +ByteArrayToUint32( + BYTE *a + ) +{ + UINT32 retVal; + retVal = a[0]; retVal <<= 8; + retVal += a[1]; retVal <<= 8; + retVal += a[2]; retVal <<= 8; + retVal += a[3]; + return retVal; +} +#endif // INLINE_FUNCTIONS +/* 9.12.3.13 ByteArrayToUint64() */ +/* Function to write an integer to a byte array */ +#ifndef INLINE_FUNCTIONS +UINT64 +ByteArrayToUint64( + BYTE *a + ) +{ + UINT64 retVal; + retVal = a[0]; retVal <<= 8; + retVal += a[1]; retVal <<= 8; + retVal += a[2]; retVal <<= 8; + retVal += a[3]; retVal <<= 8; + retVal += a[4]; retVal <<= 8; + retVal += a[5]; retVal <<= 8; + retVal += a[6]; retVal <<= 8; + retVal += a[7]; + return retVal; +} +#endif // INLINE_FUNCTIONS diff --git a/src/tpm2/Memory_fp.h b/src/tpm2/Memory_fp.h new file mode 100644 index 00000000..5c0c6cb2 --- /dev/null +++ b/src/tpm2/Memory_fp.h @@ -0,0 +1,135 @@ +/********************************************************************************/ +/* */ +/* */ +/* Written by Ken Goldman */ +/* IBM Thomas J. Watson Research Center */ +/* $Id: Memory_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 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 + ); +UINT16 +ByteArrayToUint16( + BYTE *a + ); +UINT32 +ByteArrayToUint32( + BYTE *a + ); +UINT64 +ByteArrayToUint64( + BYTE *a + ); + + +#endif diff --git a/src/tpm2/NV.h b/src/tpm2/NV.h new file mode 100644 index 00000000..bc9493fa --- /dev/null +++ b/src/tpm2/NV.h @@ -0,0 +1,175 @@ +/********************************************************************************/ +/* */ +/* */ +/* Written by Ken Goldman */ +/* IBM Thomas J. Watson Research Center */ +/* $Id: NV.h 953 2017-03-06 20:31: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, 2017 */ +/* */ +/********************************************************************************/ + +#ifndef NV_H +#define NV_H + +/* 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 +# define NV_ATTRIBUTES_TO_TYPE(attributes) (attributes.TPM_NT) +#else +# define NV_ATTRIBUTES_TO_TYPE(attributes) \ + ( attributes.TPMA_NV_COUNTER \ + + (attributes.TPMA_NV_BITS << 1) \ + + (attributes.TPMA_NV_EXTEND << 2) \ + ) +#endif +/* 5.17.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 */ +#ifdef TPM_NT_ORDINARY +# define IsNvOrdinaryIndex(attributes) (attributes.TPM_NT == TPM_NT_ORDINARY) +#else +# define IsNvOrdinaryIndex(attributes) \ + ((attributes.TPMA_NV_COUNTER == CLEAR) \ + && (attributes.TPMA_NV_BITS == CLEAR) \ + && (attributes.TPMA_NV_EXTEND == CLEAR) +# define TPM_NT_ORDINARY (0) +#endif +#ifdef TPM_NT_COUNTER +# define IsNvCounterIndex(attributes) (attributes.TPM_NT == TPM_NT_COUNTER) +#else +# define IsNvCounterIndex(attributes) (attributes.TPMA_NV_COUNTER == SET) +# define TPM_NT_COUNTER (1) +#endif +#ifdef TPM_NT_BITS +# define IsNvBitsIndex(attributes) (attributes.TPM_NT == TPM_NT_BITS) +#else +# define IsNvBitsIndex(attributes) (attributes.TPMA_NV_BITS == SET) +# define TPM_NT_BITS (2) +#endif +#ifdef TPM_NT_EXTEND +# define IsNvExtendIndex(attributes) (attributes.TPM_NT == TPM_NT_EXTEND) +#else +# define IsNvExtendIndex(attributes) (attributes.TPMA_NV_EXTEND == SET) +# define TPM_NT_EXTEND (4) +#endif +#ifdef TPM_NT_PIN_PASS +# define IsNvPinPassIndex(attributes) (attributes.TPM_NT == TPM_NT_PIN_PASS) +#endif +#ifdef TPM_NT_PIN_FAIL +# define IsNvPinFailIndex(attributes) (attributes.TPM_NT == 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 UIT64m() + maxCounter value. */ +typedef UINT32 NV_LIST_TERMINATOR[3]; + +/* 5.15.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 diff --git a/src/tpm2/NVCommands.c b/src/tpm2/NVCommands.c new file mode 100644 index 00000000..b666df36 --- /dev/null +++ b/src/tpm2/NVCommands.c @@ -0,0 +1,672 @@ +/********************************************************************************/ +/* */ +/* */ +/* Written by Ken Goldman */ +/* IBM Thomas J. Watson Research Center */ +/* $Id: NVCommands.c 847 2016-11-29 21:17:44Z kgoldman $ */ +/* */ +/* Licenses and Notices */ +/* */ +/* 1. Copyright Licenses: */ +/* */ +/* - Trusted Computing Group (TCG) grants to the user of the source code in */ +/* this specification (the "Source Code") a worldwide, irrevocable, */ +/* nonexclusive, royalty free, copyright license to reproduce, create */ +/* derivative works, distribute, display and perform the Source Code and */ +/* derivative works thereof, and to grant others the rights granted herein. */ +/* */ +/* - The TCG grants to the user of the other parts of the specification */ +/* (other than the Source Code) the rights to reproduce, distribute, */ +/* display, and perform the specification solely for the purpose of */ +/* developing products based on such documents. */ +/* */ +/* 2. Source Code Distribution Conditions: */ +/* */ +/* - Redistributions of Source Code must retain the above copyright licenses, */ +/* this list of conditions and the following disclaimers. */ +/* */ +/* - Redistributions in binary form must reproduce the above copyright */ +/* licenses, this list of conditions and the following disclaimers in the */ +/* documentation and/or other materials provided with the distribution. */ +/* */ +/* 3. Disclaimers: */ +/* */ +/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */ +/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */ +/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */ +/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */ +/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */ +/* information on specification licensing rights available through TCG */ +/* membership agreements. */ +/* */ +/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */ +/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */ +/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */ +/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */ +/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */ +/* */ +/* - Without limitation, TCG and its members and licensors disclaim all */ +/* liability, including liability for infringement of any proprietary */ +/* rights, relating to use of information in this specification and to the */ +/* implementation of this specification, and TCG disclaims all liability for */ +/* cost of procurement of substitute goods or services, lost profits, loss */ +/* of use, loss of data or any incidental, consequential, direct, indirect, */ +/* or special damages, whether under contract, tort, warranty 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 "NV_DefineSpace_fp.h" +#ifdef TPM_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(IsNv_TPMA_NV_POLICY_DELETE(attributes)) + 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(NV_ATTRIBUTES_TO_TYPE(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_PolicySigned == 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(NV_ATTRIBUTES_TO_TYPE(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(NV_ATTRIBUTES_TO_TYPE(attributes)) + { + case TPM_NT_COUNTER: + // Counter can't have TPMA_NV_CLEAR_STCLEAR SET (don't clear counters) + if(IsNv_TPMA_NV_CLEAR_STCLEAR(attributes)) + 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(!IsNv_TPMA_NV_NO_DA(attributes)) + return TPM_RCS_ATTRIBUTES + RC_NV_DefineSpace_publicInfo; +#endif +#ifdef TPM_NT_PIN_PASS + case TPM_NT_PIN_PASS: + // AUTHWRITE must be CLEAR (see note above to TPM_NT_PIN_FAIL) + if(IsNv_TPMA_NV_AUTHWRITE(attributes) + || IsNv_TPMA_NV_GLOBALLOCK(attributes) + || IsNv_TPMA_NV_WRITEDEFINE(attributes)) + 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(IsNv_TPMA_NV_WRITTEN(attributes) + || IsNv_TPMA_NV_WRITELOCKED(attributes) + || IsNv_TPMA_NV_READLOCKED(attributes)) + return TPM_RCS_ATTRIBUTES + RC_NV_DefineSpace_publicInfo; + // There must be a way to read the index. + if(!IsNv_TPMA_NV_OWNERREAD(attributes) + && !IsNv_TPMA_NV_PPREAD(attributes) + && !IsNv_TPMA_NV_AUTHREAD(attributes) + && !IsNv_TPMA_NV_POLICYREAD(attributes)) + return TPM_RCS_ATTRIBUTES + RC_NV_DefineSpace_publicInfo; + // There must be a way to write the index + if(!IsNv_TPMA_NV_OWNERWRITE(attributes) + && !IsNv_TPMA_NV_PPWRITE(attributes) + && !IsNv_TPMA_NV_AUTHWRITE(attributes) + && !IsNv_TPMA_NV_POLICYWRITE(attributes)) + return TPM_RCS_ATTRIBUTES + RC_NV_DefineSpace_publicInfo; + // An index with TPMA_NV_CLEAR_STCLEAR can't have TPMA_NV_WRITEDEFINE SET + if(IsNv_TPMA_NV_CLEAR_STCLEAR(attributes) + && IsNv_TPMA_NV_WRITEDEFINE(attributes)) + return TPM_RCS_ATTRIBUTES + RC_NV_DefineSpace_publicInfo; + // Make sure that the creator of the index can delete the index + if((IsNv_TPMA_NV_PLATFORMCREATE(attributes) + && in->authHandle == TPM_RH_OWNER) + || (!IsNv_TPMA_NV_PLATFORMCREATE(attributes) + && 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(IsNv_TPMA_NV_POLICY_DELETE(attributes) + && 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 + && IsNv_TPMA_NV_WRITEALL(attributes)) + 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" +#ifdef TPM_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(IsNv_TPMA_NV_POLICY_DELETE(nvIndex->publicArea.attributes)) + 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 + && IsNv_TPMA_NV_PLATFORMCREATE(nvIndex->publicArea.attributes)) + 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" +#ifdef TPM_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(!IsNv_TPMA_NV_POLICY_DELETE(nvIndex->publicArea.attributes)) + 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" +#ifdef TPM_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" +#ifdef TPM_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(IsNv_TPMA_NV_WRITEALL(attributes) + && 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" +#ifdef TPM_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(!IsNv_TPMA_NV_WRITTEN(nvIndex->publicArea.attributes)) + 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(IsNv_TPMA_NV_ORDERLY(nvIndex->publicArea.attributes) + && (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" +#ifdef TPM_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(IsNv_TPMA_NV_WRITTEN(nvIndex->publicArea.attributes)) + { + 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" +#ifdef TPM_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(!IsNv_TPMA_NV_WRITTEN(nvIndex->publicArea.attributes)) + 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" +#ifdef TPM_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(nvAttributes.TPMA_NV_WRITEDEFINE == CLEAR + && nvAttributes.TPMA_NV_WRITE_STCLEAR == CLEAR) + 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. + nvAttributes.TPMA_NV_WRITELOCKED = SET; + // Write index info back + return NvWriteIndexAttributes(nvIndex->publicArea.nvIndex, locator, + nvAttributes); +} +#endif // CC_NV_WriteLock +#include "Tpm.h" +#include "NV_GlobalWriteLock_fp.h" +#ifdef TPM_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" +#ifdef TPM_CC_NV_Read // Conditional expansion of this file +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" +#ifdef TPM_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(nvAttributes.TPMA_NV_READ_STCLEAR == CLEAR) + return TPM_RCS_ATTRIBUTES + RC_NV_ReadLock_nvIndex; + // Internal Data Update + // Set the READLOCK attribute + nvAttributes.TPMA_NV_READLOCKED = SET; + // Write NV info back + return NvWriteIndexAttributes(nvIndex->publicArea.nvIndex, + locator, + nvAttributes); +} +#endif // CC_NV_ReadLock +#include "Tpm.h" +#include "NV_ChangeAuth_fp.h" +#ifdef TPM_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" +#ifdef TPM_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 + 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); + // NV certify specific fields + // Attestation type + certifyInfo.type = TPM_ST_ATTEST_NV; + // Get the name of the index + NvGetIndexName(nvIndex, &certifyInfo.attested.nv.indexName); + // 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); + // 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 00000000..666cb44d --- /dev/null +++ b/src/tpm2/NVDynamic.c @@ -0,0 +1,1612 @@ +/********************************************************************************/ +/* */ +/* */ +/* Written by Ken Goldman */ +/* IBM Thomas J. Watson Research Center */ +/* $Id: NVDynamic.c 953 2017-03-06 20:31: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, 2017 */ +/* */ +/********************************************************************************/ + +/* 8.4 NVDynamic.c */ +/* 8.4.2 Includes, Defines and Data Definitions */ +#define NV_C +#include "Tpm.h" +#include "PlatformData.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 element 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 + NV_REF *iter, // IN: the iterator + TPM_HT type // IN: the handle type to look for + ) +{ + NV_REF addr; + TPM_HANDLE nvHandle; + 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 indices + 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 + ) +{ + 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)); + MemoryCopy(&listEndMarker[sizeof(UINT32)], &maxCount, sizeof(UINT64)); + pAssert(end + sizeof(NV_LIST_TERMINATOR) <= s_evictNvEnd); + 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 indices, 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 + MemoryCopy(&header, currentAddr, sizeof(NV_RAM_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 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 = 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, 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.8 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)); +} +/* 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)); +} +/* 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)); +} +/* 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 and may reference an owner persistent + object either */ +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(!IsNv_TPMA_NV_PLATFORMCREATE(nvIndex->publicArea.attributes)) + { + 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 + // If the Index is write locked and this is an NV Write operation... + if(IsNv_TPMA_NV_WRITELOCKED(nvIndex->publicArea.attributes) + && 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 + // If the Index is read locked and this is an NV Read operation... + if(IsNv_TPMA_NV_READLOCKED(nvIndex->publicArea.attributes) + && 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; +} +/* 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(nvAttributes.TPMA_NV_WRITTEN == SET); + if(nvAttributes.TPMA_NV_ORDERLY == SET) + { + // 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 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(IsNv_TPMA_NV_ORDERLY(attributes)) + { + 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(locator == s_cachedNvRef) + { + 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(IsNv_TPMA_NV_ORDERLY(s_cachedNvIndex.publicArea.attributes)) + { + 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 indices 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(!IsNv_TPMA_NV_WRITTEN(nvIndex->publicArea.attributes)) + { + // Update the in memory version of the attributes + nvIndex->publicArea.attributes.TPMA_NV_WRITTEN = SET; + // If this is not orderly, then update the NV version of + // the attributes + if(!IsNv_TPMA_NV_ORDERLY(nvIndex->publicArea.attributes)) + { + 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 indices 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(IsNv_TPMA_NV_ORDERLY(nvIndex->publicArea.attributes)) + { + // 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 Indices that are going to be written to NV. + // Orderly indices don't need space. + if(!IsNv_TPMA_NV_ORDERLY(publicArea->attributes)) + 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(IsNv_TPMA_NV_ORDERLY(publicArea->attributes) + && !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(IsNv_TPMA_NV_ORDERLY(publicArea->attributes)) + 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) + && IsNv_TPMA_NV_WRITTEN(nvIndex->publicArea.attributes)) + 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(IsNv_TPMA_NV_ORDERLY(nvIndex->publicArea.attributes)) + 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 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(!IsNv_TPMA_NV_PLATFORMCREATE(nvIndex.publicArea.attributes)) + { + // 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)) + { + // 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 Indices 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 Indices + while((currentAddr = NvNextIndex(NULL, &iter)) != 0) + { + TPMA_NV attributes = NvReadNvIndexAttributes(currentAddr); + // See if it should be locked + if(!IsNv_TPMA_NV_ORDERLY(attributes) + && IsNv_TPMA_NV_GLOBALLOCK(attributes)) + { + attributes.TPMA_NV_WRITELOCKED = SET; + 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(IsNv_TPMA_NV_GLOBALLOCK(attributes)) + { + attributes.TPMA_NV_WRITELOCKED = SET; + 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 Indices is small. For an implementation that may allow + // large number of NV Indices, 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 Indices, starting from handle. Handle must be in + the range of NV Indices, 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 Indices is small. For an implementation that may allow + // large number of NV Indices, 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 indices. */ +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 + attributes.TPMA_NV_READLOCKED = CLEAR; + // 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(IsNv_TPMA_NV_CLEAR_STCLEAR(attributes) + || (IsNv_TPMA_NV_ORDERLY(attributes) && (type == SU_RESET))) + attributes.TPMA_NV_WRITTEN = CLEAR; + } + // Unlock any index that is not written or that does not have + // TPMA_NV_WRITEDEFINE SET. + if(!IsNv_TPMA_NV_WRITTEN(attributes) || !IsNv_TPMA_NV_WRITEDEFINE(attributes)) + attributes.TPMA_NV_WRITELOCKED = CLEAR; + 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. */ +void +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; + // 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(IsNv_TPMA_NV_ORDERLY(attributes)) + continue; + // Set the attributes appropriate for this startup type + attributes = NvSetStartupAttributes(attributes, type); + NvWriteNvIndexAttributes(currentAddr, attributes); + } + // Iterate all the orderly indices 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; +} +/* 8.4.5.30 NvCapGetCounterAvail() */ +/* This function returns an estimate of the number of additional counter type NV Indices 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(); + // 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 insures that it is not possible to roll back + an index. */ +/* The highest counter value is keep 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 00000000..8917c7ce --- /dev/null +++ b/src/tpm2/NVDynamic_fp.h @@ -0,0 +1,245 @@ +/********************************************************************************/ +/* */ +/* */ +/* Written by Ken Goldman */ +/* IBM Thomas J. Watson Research Center */ +/* $Id: NVDynamic_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 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 + ); +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 + ); +void +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/NVMem.c b/src/tpm2/NVMem.c new file mode 100644 index 00000000..e1e19617 --- /dev/null +++ b/src/tpm2/NVMem.c @@ -0,0 +1,314 @@ +/********************************************************************************/ +/* */ +/* */ +/* Written by Ken Goldman */ +/* IBM Thomas J. Watson Research Center */ +/* $Id: NVMem.c 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 */ +/* */ +/********************************************************************************/ + +/* C.6 NVMem.c */ +/* C.6.1. Introduction */ +/* 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 */ +#include +#include +#include +#include "PlatformData.h" +#include "Platform_fp.h" +/* C.6.3. Functions */ +/* C.6.3.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 + ) +{ + s_NV_unrecoverable = unrecoverable; + s_NV_recoverable = recoverable; +} +/* C.6.3.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 + ) +{ + NOT_REFERENCED(platParameter); // to keep compiler quiet + // Start assuming everything is OK + s_NV_unrecoverable = FALSE; + s_NV_recoverable = FALSE; +#ifdef FILE_BACKED_NV + if(s_NVFile != NULL) + return 0; + // Try to open an exist NVChip file for read/write +#if defined _MSC_VER && 1 + if(0 != fopen_s(&s_NVFile, "NVChip", "r+b")) + s_NVFile = NULL; +#else + s_NVFile = fopen("NVChip", "r+b"); +#endif + if(NULL != s_NVFile) + { + // See if the NVChip file is empty + fseek(s_NVFile, 0, SEEK_END); + if(0 == ftell(s_NVFile)) + s_NVFile = NULL; + } + if(s_NVFile == NULL) + { + // Initialize all the byte in the new file to 0 + memset(s_NV, 0, NV_MEMORY_SIZE); + // If NVChip file does not exist, try to create it for read/write +#if defined _MSC_VER && 1 + if(0 != fopen_s(&s_NVFile, "NVChip", "w+b")) + s_NVFile = NULL; +#else + s_NVFile = fopen("NVChip", "w+b"); +#endif + if(s_NVFile != NULL) + { + // Start initialize at the end of new file + fseek(s_NVFile, 0, SEEK_END); + // Write 0s to NVChip file + fwrite(s_NV, 1, NV_MEMORY_SIZE, s_NVFile); + } + } + else + { + // If NVChip file exist, assume the size is correct + fseek(s_NVFile, 0, SEEK_END); + assert(ftell(s_NVFile) == NV_MEMORY_SIZE); + // read NV file data to memory + fseek(s_NVFile, 0, SEEK_SET); + fread(s_NV, NV_MEMORY_SIZE, 1, s_NVFile); + } +#endif + // NV contents have been read 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.3.3. _plat__NVDisable() */ +/* Disable NV memory */ +LIB_EXPORT void +_plat__NVDisable( + void + ) +{ +#ifdef FILE_BACKED_NV + assert(s_NVFile != NULL); + // Close NV file + fclose(s_NVFile); + // Set file handle to NULL + s_NVFile = NULL; +#endif + return; +} +/* C.6.3.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 + ) +{ + // NV is not available if the TPM is in failure mode + if(!s_NvIsAvailable) + return 1; +#ifdef FILE_BACKED_NV + if(s_NVFile == NULL) + return 1; +#endif + return 0; +} +/* C.6.3.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 + ) +{ + assert(startOffset + size <= NV_MEMORY_SIZE); + // Copy data from RAM + memcpy(data, &s_NV[startOffset], size); + return; +} +/* C.6.3.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 + ) +{ + return (memcmp(&s_NV[startOffset], data, size) != 0); +} +/* C.6.3.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 void +_plat__NvMemoryWrite( + unsigned int startOffset, // IN: write start + unsigned int size, // IN: size of bytes to write + void *data // OUT: data buffer + ) +{ + assert(startOffset + size <= NV_MEMORY_SIZE); + // Copy the data to the NV image + memcpy(&s_NV[startOffset], data, size); +} +/* C.6.3.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 + ) +{ + assert(start + size <= NV_MEMORY_SIZE); + // In this implementation, assume that the errase value for NV is all 1s + memset(&s_NV[start], 0xff, size); +} +/* C.6.3.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 + ) +{ + assert(sourceOffset + size <= NV_MEMORY_SIZE); + assert(destOffset + size <= NV_MEMORY_SIZE); + // Move data in RAM + memmove(&s_NV[destOffset], &s_NV[sourceOffset], size); + return; +} +/* C.6.3.10. _plat__NvCommit() */ +/* Update NV chip */ +/* Return Values Meaning */ +/* 0 NV write success */ +/* non-0 NV write fail */ +LIB_EXPORT int +_plat__NvCommit( + void + ) +{ +#ifdef FILE_BACKED_NV + // 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); + fwrite(s_NV, 1, NV_MEMORY_SIZE, s_NVFile); + return 0; +#else + return 0; +#endif +} +/* C.6.3.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 + ) +{ + s_NvIsAvailable = TRUE; + return; +} +/* C.6.3.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 + ) +{ + s_NvIsAvailable = FALSE; + return; +} diff --git a/src/tpm2/NVReserved.c b/src/tpm2/NVReserved.c new file mode 100644 index 00000000..b7f77418 --- /dev/null +++ b/src/tpm2/NVReserved.c @@ -0,0 +1,224 @@ +/********************************************************************************/ +/* */ +/* */ +/* Written by Ken Goldman */ +/* IBM Thomas J. Watson Research Center */ +/* $Id: NVReserved.c 953 2017-03-06 20:31: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, 2017 */ +/* */ +/********************************************************************************/ + +// 8.5 NVReserved.c +/* 8.5.2 Includes, Defines and Data Definitions */ +#define NV_C +#include "Tpm.h" +/* 8.5.2.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 Externally Accessible Functions */ +/* 8.5.3.1 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.2 NvCommit */ +/* This is a wrapper for the platform function to commit pending NV writes. */ +BOOL +NvCommit( + void + ) +{ + return (_plat__NvCommit() == 0); +} +/* 8.5.3.3 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) + FAIL(FATAL_ERROR_NV_UNRECOVERABLE); + NvInitStatic(); + } + return nvError == 0; +} +/* 8.5.3.4 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 + ) +{ +#ifdef 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.5 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.6 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. */ +void +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 + pAssert(nvOffset + size <= NV_MEMORY_SIZE); + _plat__NvMemoryWrite(nvOffset, size, inBuffer); + // Set the flag that a NV write happened + SET_NV_UPDATE(UT_NV); + return; +} +/* 8.5.3.7 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.8 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 + ) +{ + MemorySet((&gp) + offset, 0, size); + NvWrite(offset, size, (&gp) + offset); +} +/* 8.5.3.9 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 00000000..036952e6 --- /dev/null +++ b/src/tpm2/NVReserved_fp.h @@ -0,0 +1,111 @@ +/********************************************************************************/ +/* */ +/* */ +/* Written by Ken Goldman */ +/* IBM Thomas J. Watson Research Center */ +/* $Id: NVReserved_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 NVRESERVED_FP_H +#define NVRESERVED_FP_H + +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 + ); +void +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 00000000..a58af301 --- /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 00000000..fb26a733 --- /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 00000000..03d81c32 --- /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 00000000..58d4c2fa --- /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 00000000..4f6b26b2 --- /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 00000000..50fe2ef1 --- /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 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_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 00000000..f50479bf --- /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 00000000..bcad3062 --- /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 00000000..660fbd15 --- /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 00000000..b860d644 --- /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 00000000..d2016a42 --- /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 00000000..fc6897e0 --- /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 00000000..b22d6e0d --- /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 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_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 00000000..2880c6ea --- /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 00000000..17a21b39 --- /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 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 */ +/* */ +/********************************************************************************/ + +/* 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(IsNv_TPMA_NV_READLOCKED(attributes)) + 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(!IsNv_TPMA_NV_OWNERREAD(attributes)) + return TPM_RC_NV_AUTHORIZATION; + } + else if(authHandle == TPM_RH_PLATFORM) + { + // If Platform provided authorization then PPWRITE must be SET + if(!IsNv_TPMA_NV_PPREAD(attributes)) + 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(!IsNv_TPMA_NV_WRITTEN(attributes)) + 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(IsNv_TPMA_NV_WRITELOCKED(attributes)) + 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(!IsNv_TPMA_NV_OWNERWRITE(attributes)) + return TPM_RC_NV_AUTHORIZATION; + } + else if(authHandle == TPM_RH_PLATFORM) + { + // If Platform provided authorization then PPWRITE must be SET + if(!IsNv_TPMA_NV_PPWRITE(attributes)) + 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 00000000..4857ccf5 --- /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 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 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/Object.c b/src/tpm2/Object.c new file mode 100644 index 00000000..8c00b5ba --- /dev/null +++ b/src/tpm2/Object.c @@ -0,0 +1,926 @@ +/********************************************************************************/ +/* */ +/* Manage the object store of the TPM. */ +/* Written by Ken Goldman */ +/* IBM Thomas J. Watson Research Center */ +/* $Id: Object.c 953 2017-03-06 20:31: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, 2017 */ +/* */ +/********************************************************************************/ + +/* 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" +/* 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; + // MemorySet(&object->attributes, 0, sizeof(OBJECT_ATTRIBUTES)); +} +/* 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. */ +void +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; +} +/* 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.8 ObjectGetNameAlg() */ +/* This function is used to get the Name algorithm of a object. */ +/* This function requires that object references a loaded object. */ +TPMI_ALG_HASH +ObjectGetNameAlg( + OBJECT *object // IN: handle of the object + ) +{ + return object->publicArea.nameAlg; +} +/* 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 GetHeriarchy() */ +/* 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 but ObjectGetHierarchy() takes an + pointer to an object. */ +/* This function requires that handle references a loaded object. */ +TPMI_RH_HIERARCHY +GetHeriarchy( + 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)); + 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 + ) +{ + OBJECT *parent = HandleToObject(parentHandle); + // Copy the stClear attribute from the public area. This could be overwritten + // if the parent has stClear SET + object->attributes.stClear = object->publicArea.objectAttributes.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 = + (object->publicArea.objectAttributes.stClear == SET + || (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(object->publicArea.objectAttributes.restricted + && !object->attributes.publicOnly + && object->publicArea.objectAttributes.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 + { + // 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 = parent->publicArea.objectAttributes.fixedTPM == CLEAR; + 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; +#ifdef TPM_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 + // 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. + object->objectAttributes.noDA = SET; + // 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 */ +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; + CryptHmacStart(&hmacObject->state.hmacState, hashAlg, + keyObject->sensitive.sensitive.bits.b.size, + keyObject->sensitive.sensitive.bits.b.buffer); + return TPM_RC_SUCCESS; +} +/* 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 crypto 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 */ +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; +} +/* 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 area + TPM_ALG_ID nameAlg, // IN: the hash algorithm to use + TPM2B_NAME *name // OUT: Computed name + ) +{ + HASH_STATE hashState; // hash state + // Start hash stack + name->t.size = CryptHashStart(&hashState, nameAlg); + // Adding public area + CryptDigestUpdate(&hashState, size, publicArea); + // Complete hash leaving room for the name algorithm + CryptHashEnd(&hashState, name->t.size, &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.27 AlgOfName() */ +/* This function as a macro returns the nameAlg from a TPM2B_NAME. */ +TPMI_ALG_HASH +AlgOfName( + TPM2B_NAME *name + ) +{ + return BYTE_ARRAY_TO_UINT16(name->t.name); +} +/* 8.6.3.28 ComputeQualifiedName() */ +/* This function computes the qualified name of an object. */ +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 + ) +{ + HASH_STATE hashState; // hash state + TPM2B_NAME parentName; + if(parentHandle == TPM_RH_UNASSIGNED) + { + *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 ObjectIsAsymParent() */ +/* This function determines if an object has the attributes associated with an asymmetric parent. An + asymmetric parent is an asymmetric 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 + && publicArea->objectAttributes.restricted == SET + && publicArea->objectAttributes.decrypt == SET + && publicArea->objectAttributes.sign == CLEAR + && (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; +} +OBJECT_ATTRIBUTES +ObjectGetProperties( + TPM_HANDLE handle + ) +{ + return HandleToObject(handle)->attributes; +} diff --git a/src/tpm2/ObjectChangeAuth_fp.h b/src/tpm2/ObjectChangeAuth_fp.h new file mode 100644 index 00000000..05a97c3c --- /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 00000000..e7b2c749 --- /dev/null +++ b/src/tpm2/ObjectCommands.c @@ -0,0 +1,535 @@ +/********************************************************************************/ +/* */ +/* Object Commands */ +/* Written by Ken Goldman */ +/* IBM Thomas J. Watson Research Center */ +/* $Id: ObjectCommands.c 953 2017-03-06 20:31: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, 2017 */ +/* */ +/********************************************************************************/ + +#include "Tpm.h" +#include "Object_spt_fp.h" +#include "Create_fp.h" +#ifdef TPM_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.b, 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" +#ifdef TPM_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; + 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); + } + return result; +} +#endif // CC_Load +#include "Tpm.h" +#include "LoadExternal_fp.h" +#ifdef TPM_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(in->inPublic.publicArea.objectAttributes.fixedTPM != CLEAR + || in->inPublic.publicArea.objectAttributes.fixedParent != CLEAR + || in->inPublic.publicArea.objectAttributes.restricted != CLEAR) + 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); + } + return result; +} +#endif // CC_LoadExternal +#include "Tpm.h" +#include "ReadPublic_fp.h" +#ifdef TPM_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" +#ifdef TPM_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) + || object->publicArea.objectAttributes.decrypt == CLEAR + || object->publicArea.objectAttributes.restricted == CLEAR) + 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" +#ifdef TPM_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) + || object->publicArea.objectAttributes.decrypt == CLEAR + || object->publicArea.objectAttributes.restricted == CLEAR) + 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" +#ifdef TPM_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(object->publicArea.objectAttributes.decrypt == SET + || object->publicArea.objectAttributes.sign == SET + || object->publicArea.objectAttributes.restricted == SET) + 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" +#ifdef TPM_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.b, HandleToObject(in->parentHandle), + object->publicArea.nameAlg, + &out->outPrivate); + return TPM_RC_SUCCESS; +} +#endif // CC_ObjectChangeAuth +#include "Tpm.h" +#include "CreateLoaded_fp.h" +#ifdef TPM_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 + ) +{ + // Local variables + TPM_RC result = TPM_RC_SUCCESS; + // These are the values used in object creation + OBJECT *parent = HandleToObject(in->parentHandle); + OBJECT *newObject; + BOOL derivation; + TPMT_PUBLIC *publicArea; + RAND_STATE randState; + RAND_STATE *rand = &randState; + TPMS_DERIVE labelContext; + // 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); + 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 == ALG_RSA_VALUE) + 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(publicArea->objectAttributes.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, publicArea, + &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); + // Clear the sensitive size so that the creation functions will not try + // to use this value. + in->inSensitive.sensitive.data.t.size = 0; + } + 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; + // If so, use the primary seed and the digest of the template + // to seed the DRBG + DRBG_InstantiateSeeded((DRBG_STATE *)rand, + &HierarchyGetPrimarySeed(in->parentHandle)->b, + PRIMARY_OBJECT_CREATION, + (TPM2B *)PublicMarshalAndComputeName(publicArea, + &name), + &in->inSensitive.sensitive.data.b); + } + 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.b, + 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); + return result; +} +#endif // CC_CreatePrimary diff --git a/src/tpm2/Object_fp.h b/src/tpm2/Object_fp.h new file mode 100644 index 00000000..10982f71 --- /dev/null +++ b/src/tpm2/Object_fp.h @@ -0,0 +1,231 @@ +/********************************************************************************/ +/* */ +/* */ +/* Written by Ken Goldman */ +/* IBM Thomas J. Watson Research Center */ +/* $Id: Object_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 OBJECT_FP_H +#define OBJECT_FP_H + +void +ObjectFlush( + OBJECT *object + ); +void +ObjectSetInUse( + OBJECT *object + ); +void +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 + ); +TPMI_ALG_HASH +ObjectGetNameAlg( + OBJECT *object // IN: handle 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 +GetHeriarchy( + 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 + ); +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 + ); +OBJECT * +ObjectContextLoad( + ANY_OBJECT_BUFFER *object, // IN: pointer to object structure in saved + // context + TPMI_DH_OBJECT *handle // OUT: object handle + ); +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 00000000..7709761d --- /dev/null +++ b/src/tpm2/Object_spt.c @@ -0,0 +1,1417 @@ +/********************************************************************************/ +/* */ +/* Object Command Support */ +/* Written by Ken Goldman */ +/* IBM Thomas J. Watson Research Center */ +/* $Id: Object_spt.c 953 2017-03-06 20:31: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, 2017 */ +/* */ +/********************************************************************************/ + +/* 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 + 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((attributes.sensitiveDataOrigin == CLEAR) + && (sensitiveDataSize == 0)) + return TPM_RCS_ATTRIBUTES; + // For an ordinary object, data can only be provided when sensitiveDataOrigin + // is CLEAR + if((parentObject != NULL) + && (attributes.sensitiveDataOrigin == SET) + && (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(!attributes.sign && !attributes.decrypt + && attributes.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(attributes.restricted) + if(!attributes.sensitiveDataOrigin) + if(attributes.fixedParent || attributes.fixedTPM) + result = TPM_RCS_ATTRIBUTES; + break; + default: // Asymmetric keys cannot have the sensitive portion provided + if(!attributes.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(). */ +/* Return Values Meaning This function TPM_RC */ +/* TPM_RC_ASYMMETRIC non-duplicable storage key and its parent have different public parameters */ +/* 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; + break; + case TPM_ALG_KEYEDHASH: + scheme = parms->keyedHashDetail.scheme.scheme; + // if both sign and decrypt + if(attributes.sign == attributes.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(attributes.sign && scheme != TPM_ALG_HMAC) + return TPM_RCS_SCHEME; + else if(attributes.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(attributes.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(attributes.sign == attributes.decrypt) + { + // scheme must be TPM_ALG_NULL + if(scheme != TPM_ALG_NULL) + return TPM_RCS_SCHEME; + } + else if(attributes.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(attributes.restricted || scheme != TPM_ALG_NULL) + return TPM_RCS_SCHEME; + } + } + else if(attributes.decrypt) + { + if(attributes.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(!attributes.restricted || !attributes.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 +#ifdef TPM_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 && attributes.restricted && attributes.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 P2 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(attributes.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 = {0}; + 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 || parentAttributes.fixedTPM == SET) + { + if(attributes.fixedParent != attributes.fixedTPM) + return TPM_RCS_ATTRIBUTES; + } + else + { + // The parent is not fixedTPM so the object can't be fixedTPM + if(attributes.fixedTPM == SET) + return TPM_RCS_ATTRIBUTES; + } + // See if sign and decrypt are the same + if(attributes.sign == attributes.decrypt) + { + // a restricted key cannot have both SET or both CLEAR + if(attributes.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 && !attributes.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(attributes.fixedTPM == SET && attributes.encryptedDuplication == SET) + 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 && parentAttributes.fixedTPM == CLEAR) + { + if(attributes.encryptedDuplication != parentAttributes.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(attributes.fixedTPM != parentAttributes.fixedTPM) + return TPM_RCS_ATTRIBUTES; + // A derived object is required to be fixedParent + if(!attributes.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 + performs: */ +/* a) Add IV before sensitive area if required */ +/* b) encrypt sensitive data, if iv is required, encrypt by iv. otherwise, encrypted by a NULL + iv */ +/* c) add HMAC integrity at the beginning of the buffer It 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, // 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->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 = ObjectGetNameAlg(parent); + } + // 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, hashAlg, NULL, + TRUE, dataSize, outPrivate->t.buffer); + return; +} +/* 7.6.3.12 PrivateToSensitive() */ +/* Unwrap a 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 = ObjectGetNameAlg(parent); + } + // 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 = ObjectGetNameAlg(parent); + // 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 = ObjectGetNameAlg(protector); + // 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 = ObjectGetNameAlg(protector); + // 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, // OUT: the recovered label and context + TPMT_PUBLIC *publicArea, // IN/OUT: the public area containing the + // unmarshaled template + TPM2B_SENSITIVE_DATA *sensitive // IN: the sensitive data + ) +{ + TPM_RC result; + INT32 size; + BYTE *buff; + // + // In case neither the sensitive nor publicArea have a label or a context + labelContext->label.b.size = 0; + labelContext->context.b.size = 0; + // 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(labelContext, &buff, &size); + if(result != TPM_RC_SUCCESS) + return result; + } + // If there is a label string in publicArea, it overrides + if(publicArea->unique.derive.label.t.size != 0) + MemoryCopy2B(&labelContext->label.b, &publicArea->unique.derive.label.b, + sizeof(labelContext->label.t.buffer)); + // if there is a context string in publicArea, it overrides + if(publicArea->unique.derive.context.t.size != 0) + MemoryCopy2B(&labelContext->context.b, + &publicArea->unique.derive.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 + ) +{ + 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 a TPMT_PUBLIC but don't allow a nameAlg of TPM_ALG_NULL + result = TPMT_PUBLIC_Unmarshal(tOut, &buffer, &size, FALSE); + if((result == TPM_RC_SUCCESS) && (derivation == TRUE)) + { + // Make sure that the unmarshaled value is a valid label (not too big) + if(tOut->unique.derive.label.t.size + > sizeof(tOut->unique.derive.label.t.buffer)) + { + result = TPM_RC_SIZE; + } + else + { +#if ALG_ECC + // If we just unmarshaled an ECC public key, then the label value is in the + // correct spot but the context value is in the wrong place if the + // maximum ECC parameter size is larger than the largest digest. + // So, move it. + if(tOut->type == ALG_ECC_VALUE) +#if LABEL_MAX_BUFFER != MAX_ECC_KEY_BYTES + { + TPM2B_LABEL context; + // Make sure that the context is not too big + if(tOut->unique.ecc.y.t.size > sizeof(context.t.buffer)) + { + result = TPM_RC_SIZE; + } + else + { + // This could probably be a direct copy because we are moving + // data to lower addresses but, just to be safe... + MemoryCopy2B(&context.b, &tOut->unique.ecc.y.b, + sizeof(context.t.buffer)); + MemoryCopy2B(&tOut->unique.derive.context.b, &context.b, + sizeof(tOut->unique.derive.context.t.buffer)); + } + } +#else + { + // if the label buffer and ECC key sizes match, everything is where it + // should be so nothing else to do + } +#endif // LABEL_MAX_BUFFER != MAX_ECC_KEY_BYTES + else +#endif // ALG_ECC + // For object types other than ECC, should have completed + // unmarshaling with data left in the buffer so try to unmarshal + // the remainder as a TPM2B_LABEL into the context + result = TPM2B_LABEL_Unmarshal(&tOut->unique.derive.context, + &buffer, &size); + } + } + return result; +} +/* 7.6.3.20 ObjectSetExternal() */ +/* Set the external attributes for an object. */ +void +ObjectSetExternal( + OBJECT *object + ) +{ + object->attributes.external = SET; +} diff --git a/src/tpm2/Object_spt_fp.h b/src/tpm2/Object_spt_fp.h new file mode 100644 index 00000000..d295b372 --- /dev/null +++ b/src/tpm2/Object_spt_fp.h @@ -0,0 +1,249 @@ +/********************************************************************************/ +/* */ +/* */ +/* Written by Ken Goldman */ +/* IBM Thomas J. Watson Research Center */ +/* $Id: Object_spt_fp.h 953 2017-03-06 20:31: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, 2017 */ +/* */ +/********************************************************************************/ + +#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, // 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 + TPMT_PUBLIC *publicArea, // IN/OUT: the public area containing + // the unmarshaled template + 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 + ); +void +ObjectSetHierarchy( + OBJECT *object, + TPM_HANDLE parentHandle, + OBJECT *parent + ); +void +ObjectSetExternal( + OBJECT *object + ); + + +#endif diff --git a/src/tpm2/PCR.c b/src/tpm2/PCR.c new file mode 100644 index 00000000..61a7da73 --- /dev/null +++ b/src/tpm2/PCR.c @@ -0,0 +1,1224 @@ +/********************************************************************************/ +/* */ +/* */ +/* Written by Ken Goldman */ +/* IBM Thomas J. Watson Research Center */ +/* $Id: PCR.c 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 */ +/* */ +/********************************************************************************/ + +/* 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.3 Functions */ +/* 8.7.3.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 Values Meaning */ +/* 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.3.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 a policy group */ +/* FALSE: PCR does not belong 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.3.3 PCRBelongsTCBGroup() */ +/* This function indicates if a PCR belongs to the TCB group. */ +/* Return Values Meaning */ +/* TRUE: PCR belongs to TCB group */ +/* FALSE: PCR does not belong to TCB group */ +static BOOL +PCRBelongsTCBGroup( + TPMI_DH_PCR handle // IN: handle of PCR + ) +{ +#if ENABLE_PCR_NO_INCREMENT == YES + // 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 + return FALSE; +} +/* 8.7.3.4 PCRPolicyIsAvailable() */ +/* This function indicates if a policy is available for a PCR. */ +/* Return Values Meaning */ +/* TRUE the PCR should 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.3.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.3.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.3.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 + ) +{ + switch(alg) + { +#ifdef TPM_ALG_SHA1 + case TPM_ALG_SHA1: + return gc.pcrSave.sha1[pcrIndex]; + break; +#endif +#ifdef TPM_ALG_SHA256 + case TPM_ALG_SHA256: + return gc.pcrSave.sha256[pcrIndex]; + break; +#endif +#ifdef TPM_ALG_SHA384 + case TPM_ALG_SHA384: + return gc.pcrSave.sha384[pcrIndex]; + break; +#endif +#ifdef TPM_ALG_SHA512 + case TPM_ALG_SHA512: + return gc.pcrSave.sha512[pcrIndex]; + break; +#endif +#ifdef TPM_ALG_SM3_256 + case TPM_ALG_SM3_256: + return gc.pcrSave.sm3_256[pcrIndex]; + break; +#endif + default: + break; + } + FAIL(FATAL_ERROR_INTERNAL); +} +/* 8.7.3.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) + { +#ifdef TPM_ALG_SHA1 + case TPM_ALG_SHA1: + pcr = s_pcrs[pcrNumber].sha1Pcr; + break; +#endif +#ifdef TPM_ALG_SHA256 + case TPM_ALG_SHA256: + pcr = s_pcrs[pcrNumber].sha256Pcr; + break; +#endif +#ifdef TPM_ALG_SHA384 + case TPM_ALG_SHA384: + pcr = s_pcrs[pcrNumber].sha384Pcr; + break; +#endif +#ifdef TPM_ALG_SHA512 + case TPM_ALG_SHA512: + pcr = s_pcrs[pcrNumber].sha512Pcr; + break; +#endif +#ifdef TPM_ALG_SM3_256 + case TPM_ALG_SM3_256: + pcr = s_pcrs[pcrNumber].sm3_256Pcr; + break; +#endif + default: + FAIL(FATAL_ERROR_INTERNAL); + break; + } + return pcr; +} +/* 8.7.3.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.3.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.3.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.3.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.3.15 PCRStartup() */ +/* This function initializes the PCR subsystem at TPM2_Startup(). */ +void +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); + 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(); +} +/* 8.7.3.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.3.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.3.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.3.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.3.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.3.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.3.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.3.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.3.24 PcrWrite() */ +/* This function is used by _TPM_Hash_End() to set a PCR to the computed hash of the H-CRTM + event. */ +void +PcrWrite( + TPMI_DH_PCR handle, // IN: PCR handle to be extended + TPMI_ALG_HASH hash, // IN: hash algorithm of PCR + TPM2B_DIGEST *digest // IN: the new value + ) +{ + UINT32 pcr = handle - PCR_FIRST; + BYTE *pcrData; + // Copy value to the PCR if it is allocated + pcrData = GetPcrPointer(hash, pcr); + if(pcrData != NULL) + { + MemoryCopy(pcrData, digest->t.buffer, digest->t.size); + } + return; +} +/* 8.7.3.25 PCRAllocate() */ +/* This function is used to change the PCR allocation. */ +/* Error Returns Meaning */ +/* TPM_RC_SUCCESS allocate success */ +/* TPM_RC_NO_RESULTS 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.3.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.3.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.3.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.3.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.3.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.3.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.3.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 00000000..f9fe1f1c --- /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 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_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 00000000..3c36851f --- /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 00000000..37ca3f94 --- /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 00000000..ec3ef404 --- /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 00000000..835d2a02 --- /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 00000000..3d8a02b3 --- /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 00000000..a06c3f6a --- /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 00000000..249225a2 --- /dev/null +++ b/src/tpm2/PCR_fp.h @@ -0,0 +1,203 @@ +/********************************************************************************/ +/* */ +/* */ +/* Written by Ken Goldman */ +/* IBM Thomas J. Watson Research Center */ +/* $Id: PCR_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 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 + ); +void +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 + ); +void +PcrWrite( + TPMI_DH_PCR handle, // IN: PCR handle to be extended + TPMI_ALG_HASH hash, // IN: hash algorithm of PCR + TPM2B_DIGEST *digest // IN: the new value + ); +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 00000000..aaba8cb4 --- /dev/null +++ b/src/tpm2/PP.c @@ -0,0 +1,182 @@ +/********************************************************************************/ +/* */ +/* */ +/* Written by Ken Goldman */ +/* IBM Thomas J. Watson Research Center */ +/* $Id: PP.c 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 */ +/* */ +/********************************************************************************/ + +/* 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 00000000..0679a462 --- /dev/null +++ b/src/tpm2/PPPlat.c @@ -0,0 +1,102 @@ +/********************************************************************************/ +/* */ +/* */ +/* Written by Ken Goldman */ +/* IBM Thomas J. Watson Research Center */ +/* $Id: PPPlat.c 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 */ +/* */ +/********************************************************************************/ + +/* C.10 PPPlat.c */ +/* C.10.1. Description */ +/* This module simulates the physical present interface pins on the TPM. */ +/* C.10.2. Includes */ +#include "PlatformData.h" +#include "Platform_fp.h" +/* 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 + ) +{ + // Do not know how to check physical presence without real hardware. + // so always return TRUE; + return s_physicalPresence; +} +/* 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; +} diff --git a/src/tpm2/PP_Commands_fp.h b/src/tpm2/PP_Commands_fp.h new file mode 100644 index 00000000..9672f3be --- /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 827 2016-11-18 20:45: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 */ +/* */ +/********************************************************************************/ + +#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 00000000..a4f4cfeb --- /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 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 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 00000000..dd7282f0 --- /dev/null +++ b/src/tpm2/PRNG_TestVectors.h @@ -0,0 +1,111 @@ +/********************************************************************************/ +/* */ +/* */ +/* Written by Ken Goldman */ +/* IBM Thomas J. Watson Research Center */ +/* $Id: PRNG_TestVectors.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 PRNG_TESTVECTORS_H +#define 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 +#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_ALGORITHM == TPM_ALG_AES && DRBG_KEY_BITS == 128 +#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 + + +#endif diff --git a/src/tpm2/PlatformData.c b/src/tpm2/PlatformData.c new file mode 100644 index 00000000..264da085 --- /dev/null +++ b/src/tpm2/PlatformData.c @@ -0,0 +1,99 @@ +/********************************************************************************/ +/* */ +/* */ +/* Written by Ken Goldman */ +/* IBM Thomas J. Watson Research Center */ +/* $Id: PlatformData.c 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 */ +/* */ +/********************************************************************************/ + +/* 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 */ +#include "Implementation.h" +#include "PlatformData.h" +/* From Cancel.c */ +BOOL s_isCanceled; +/* From Clock.c */ +unsigned int s_adjustRate; +BOOL s_timerReset; +BOOL s_timerStopped; +#ifndef HARDWARE_CLOCK +#include +clock_t s_realTimePrevious; +clock_t s_tpmTime; +#endif +/* From LocalityPlat.c */ +unsigned char s_locality; +/* From Power.c */ +BOOL s_powerLost; +/* From Entropy.c */ +uint32_t lastEntropy; +int firstValue; +/* From NVMem.c */ +#ifdef VTPM +# undef FILE_BACKED_NV +#endif +#ifdef FILE_BACKED_NV +FILE *s_NVFile = NULL; +#endif +unsigned char s_NV[NV_MEMORY_SIZE]; +BOOL s_NvIsAvailable; +BOOL s_NV_unrecoverable; +BOOL s_NV_recoverable; +/* From PPPlat.c */ +BOOL s_physicalPresence; diff --git a/src/tpm2/PlatformData.h b/src/tpm2/PlatformData.h new file mode 100644 index 00000000..85aa9c50 --- /dev/null +++ b/src/tpm2/PlatformData.h @@ -0,0 +1,137 @@ +/********************************************************************************/ +/* */ +/* */ +/* Written by Ken Goldman */ +/* IBM Thomas J. Watson Research Center */ +/* $Id: PlatformData.h 953 2017-03-06 20:31: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 */ +/* */ +/********************************************************************************/ + +#ifndef PLATFORMDATA_H +#define PLATFORMDATA_H + +/* A.1 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_ +#include "Implementation.h" +/* From Cancel.c Cancel flag. It is initialized as FALSE, which indicate the command is not being + canceled */ +extern int s_isCanceled; +#include +typedef struct { + time_t tv_sec; // Seconds - >= 0 + long tv_nsec; // Nanoseconds - [0, 999999999] +} timespec_t; +#ifndef HARDWARE_CLOCK +/* 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 clock_t s_realTimePrevious; +/* 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 clock_t s_tpmTime; +#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; +/* 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 +/* 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. */ +#define FILE_BACKED_NV +#if defined FILE_BACKED_NV +#include +/* A file to emulate NV storage */ +extern FILE* s_NVFile; +#endif +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; +extern int firstValue; +#endif // _PLATFORM_DATA_H_ + + +#endif diff --git a/src/tpm2/Platform_fp.h b/src/tpm2/Platform_fp.h new file mode 100644 index 00000000..8c2a762c --- /dev/null +++ b/src/tpm2/Platform_fp.h @@ -0,0 +1,369 @@ +/********************************************************************************/ +/* */ +/* */ +/* Written by Ken Goldman */ +/* IBM Thomas J. Watson Research Center */ +/* $Id: Platform_fp.h 953 2017-03-06 20:31: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, 2017 */ +/* */ +/********************************************************************************/ + +/* 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. */ +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__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(). */ +/* The code in this function should be replaced by a read of a hardware tick timer. */ +LIB_EXPORT uint64_t +_plat__TimerRead( + void + ); +/* C.8.2.4. _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 BOOL +_plat__TimerWasReset( + void + ); +/* C.8.2.5. _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 BOOL +_plat__TimerWasStopped( + void + ); +/* C.8.2.6. _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 */ +/* 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.5. From LocalityPlat.c */ +/* C.8.5.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.5.2. _plat__LocalitySet() */ +/* Set the most recent command locality in locality value form */ +LIB_EXPORT void +_plat__LocalitySet( + unsigned char locality + ); +/* C.8.6. From NVMem.c */ +/* C.8.6.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 + ); +/* C.8.6.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 + ); +/* C.8.6.3. _plat__NVDisable() */ +/* Disable NV memory */ +LIB_EXPORT void +_plat__NVDisable( + void + ); +/* 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.6.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.6.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.6.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 void +_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.6.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.6.10. _plat__NvCommit() */ +/* Update NV chip */ +/* Return Values Meaning */ +/* 0 NV write success */ +/* non-0 NV write fail */ +LIB_EXPORT int +_plat__NvCommit( + void + ); +/* C.8.6.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.6.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.8.8. From PowerPlat.c */ +/* C.8.8.1. _plat__Signal_PowerOn() */ +/* Signal platform power on */ +LIB_EXPORT int +_plat__Signal_PowerOn( + void + ); +/* C.8.8.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.8.3. _plat_Signal_Reset() */ +/* This a TPM reset without a power loss. */ +LIB_EXPORT int +_plat__Signal_Reset( + void + ); +/* C.8.8.4. _plat__Signal_PowerOff() */ +/* Signal platform power off */ +LIB_EXPORT void +_plat__Signal_PowerOff( + void + ); +/* C.8.9. From PPPlat.c */ +/* C.8.10. Functions */ +/* C.8.10.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 + ); +/* C.8.10.2. _plat__Signal_PhysicalPresenceOn() */ +/* Signal physical presence on */ +LIB_EXPORT void +_plat__Signal_PhysicalPresenceOn( + void + ); +/* C.8.10.3. _plat__Signal_PhysicalPresenceOff() */ +/* Signal physical presence off */ +LIB_EXPORT void +_plat__Signal_PhysicalPresenceOff( + void + ); +/* C.8.11. From RunCommand.c */ +/* C.8.11.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.11.2. _plat__Fail() */ +/* This is the platform depended failure exit for the TPM. */ +LIB_EXPORT NORETURN void +_plat__Fail( + void + ); +/* C.8.12. From Unique.c */ +/* C.8.13. _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 + ); +#endif // _PLATFORM_FP_H_ diff --git a/src/tpm2/PolicyAuthValue_fp.h b/src/tpm2/PolicyAuthValue_fp.h new file mode 100644 index 00000000..836cea0a --- /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 00000000..03ebe52b --- /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 00000000..42b67043 --- /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 00000000..698c5a58 --- /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 00000000..2302b652 --- /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 00000000..e0569382 --- /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 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 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 00000000..c1010daf --- /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 00000000..921d55eb --- /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 00000000..c9f0cc4d --- /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 00000000..4666e950 --- /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 00000000..89945b1f --- /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 00000000..2e78a147 --- /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 00000000..5af84b9e --- /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 00000000..cc53313e --- /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 00000000..7671a5ef --- /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 00000000..aa59a6a2 --- /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 00000000..279b7ce0 --- /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 00000000..14125713 --- /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 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 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 00000000..59c8edcf --- /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 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 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 00000000..d56825b7 --- /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 00000000..96e4464e --- /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 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 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 00000000..6a7b68ea --- /dev/null +++ b/src/tpm2/Policy_spt.c @@ -0,0 +1,293 @@ +/********************************************************************************/ +/* */ +/* */ +/* Written by Ken Goldman */ +/* IBM Thomas J. Watson Research Center */ +/* $Id: Policy_spt.c 953 2017-03-06 20:31: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 */ +/* */ +/********************************************************************************/ + +/* 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) + 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); +} +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 00000000..1822677a --- /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 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 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 00000000..d8da0aed --- /dev/null +++ b/src/tpm2/Power.c @@ -0,0 +1,109 @@ +/********************************************************************************/ +/* */ +/* */ +/* Written by Ken Goldman */ +/* IBM Thomas J. Watson Research Center */ +/* $Id: Power.c 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 */ +/* */ +/********************************************************************************/ + +/* 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. */ +#ifndef INLINE_FUNCTIONS +void +TPMInit( + void + ) +{ + // Set state as not initialized. This means that Startup is required + g_initialized = FALSE; + return; +} +#endif // INLINE_FUNCTIONS +/* 9.13.3.2 TPMRegisterStartup() */ +/* This function registers the fact that the TPM has been initialized (a TPM2_Startup() has + completed successfully). */ +#ifndef INLINE_FUNCTIONS +void +TPMRegisterStartup( + void + ) +{ + g_initialized = TRUE; + return; +} +#endif // INLINE_FUNCTIONS +/* 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 */ +#ifndef INLINE_FUNCTIONS +BOOL +TPMIsStarted( + void + ) +{ + return g_initialized; +} +#endif // INLINE_FUNCTIONS diff --git a/src/tpm2/PowerPlat.c b/src/tpm2/PowerPlat.c new file mode 100644 index 00000000..1d06a08a --- /dev/null +++ b/src/tpm2/PowerPlat.c @@ -0,0 +1,126 @@ +/********************************************************************************/ +/* */ +/* */ +/* Written by Ken Goldman */ +/* IBM Thomas J. Watson Research Center */ +/* $Id: PowerPlat.c 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 */ +/* */ +/********************************************************************************/ + +/* C.7 PowerPlat.c */ +/* C.7.1. Includes and Function Prototypes */ +#include "PlatformData.h" +#include "Platform_fp.h" +#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 + ) +{ + BOOL 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(); + return; +} diff --git a/src/tpm2/Power_fp.h b/src/tpm2/Power_fp.h new file mode 100644 index 00000000..e769594f --- /dev/null +++ b/src/tpm2/Power_fp.h @@ -0,0 +1,79 @@ +/********************************************************************************/ +/* */ +/* */ +/* Written by Ken Goldman */ +/* IBM Thomas J. Watson Research Center */ +/* $Id: Power_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 POWER_FP_H +#define POWER_FP_H + +void +TPMInit( + void + ); +void +TPMRegisterStartup( + void + ); +BOOL +TPMIsStarted( + void + ); + + +#endif diff --git a/src/tpm2/PrimeData.c b/src/tpm2/PrimeData.c new file mode 100644 index 00000000..ca823c87 --- /dev/null +++ b/src/tpm2/PrimeData.c @@ -0,0 +1,441 @@ +/********************************************************************************/ +/* */ +/* */ +/* Written by Ken Goldman */ +/* IBM Thomas J. Watson Research Center */ +/* $Id: PrimeData.c 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 */ +/* */ +/********************************************************************************/ + +#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 the 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 defined RSA_KEY_SIEVE && defined SIMULATION +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 00000000..58aaccbf --- /dev/null +++ b/src/tpm2/PropertyCap.c @@ -0,0 +1,593 @@ +/********************************************************************************/ +/* */ +/* */ +/* Written by Ken Goldman */ +/* IBM Thomas J. Watson Research Center */ +/* $Id: PropertyCap.c 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 */ +/* */ +/********************************************************************************/ + +/* 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" +/* 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 + *value = ((UINT32)1 << (sizeof(CONTEXT_SLOT) * 8)) - 1; + 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 = {{0}}; + attributes.att.sharedNV = SET; + attributes.att.objectCopiedToRam = SET; + // Copy the bytes of the TPMA_MEMORY to the 32 bit integer assuming + // that the structure is going to be packed and, because the union + // contains a UINT32, it will be properly aligned. Note: this will + // get and could get byte swapped if the CPU is little-endian. + *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; +#ifdef TPM_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. + { +#ifdef 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 + { +#ifdef 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: +#ifdef 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 + { + TPMA_PERMANENT flags = {0}; + if(gp.ownerAuth.t.size != 0) + flags.ownerAuthSet = SET; + if(gp.endorsementAuth.t.size != 0) + flags.endorsementAuthSet = SET; + if(gp.lockoutAuth.t.size != 0) + flags.lockoutAuthSet = SET; + if(gp.disableClear) + flags.disableClear = SET; + if(gp.failedTries >= gp.maxTries) + flags.inLockout = SET; + // In this implementation, EPS is always generated by TPM + flags.tpmGeneratedEPS = SET; + // Note: Different compilers may require a different method to cast + // a bit field structure to a UINT32. + *value = *(UINT32 *)&flags; + break; + } + case TPM_PT_STARTUP_CLEAR: + // TPMA_STARTUP_CLEAR + { + TPMA_STARTUP_CLEAR flags = {0}; + if(g_phEnable) + flags.phEnable = SET; + if(gc.shEnable) + flags.shEnable = SET; + if(gc.ehEnable) + flags.ehEnable = SET; + if(gc.phEnableNV) + flags.phEnableNV = SET; + if(g_prevOrderlyState != SU_NONE_VALUE) + flags.orderly = SET; + // Note: Different compilers may require a different method to cast + // a bit field structure to a UINT32. + *value = *(UINT32 *)&flags; + 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: +#ifdef TPM_ALG_ECC + // number of loaded ECC curves + *value = ECC_CURVE_COUNT; +#else // TPM_ALG_ECC + *value = 0; +#endif // TPM_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 00000000..c382c7c5 --- /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 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 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 00000000..b347f2fa --- /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 00000000..1f583956 --- /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 00000000..a1f03737 --- /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 00000000..e7bad4d4 --- /dev/null +++ b/src/tpm2/RandomCommands.c @@ -0,0 +1,94 @@ +/********************************************************************************/ +/* */ +/* */ +/* Written by Ken Goldman */ +/* IBM Thomas J. Watson Research Center */ +/* $Id: RandomCommands.c 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 */ +/* */ +/********************************************************************************/ + +#include "Tpm.h" +#include "GetRandom_fp.h" +#ifdef TPM_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" +#ifdef TPM_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 00000000..3d01b54b --- /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 00000000..1365f87b --- /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 00000000..118ef2b0 --- /dev/null +++ b/src/tpm2/Response.c @@ -0,0 +1,105 @@ +/********************************************************************************/ +/* */ +/* */ +/* Written by Ken Goldman */ +/* IBM Thomas J. Watson Research Center */ +/* $Id: Response.c 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 */ +/* */ +/********************************************************************************/ + +/* 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 reponse 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 00000000..d753444a --- /dev/null +++ b/src/tpm2/ResponseCodeProcessing.c @@ -0,0 +1,83 @@ +/********************************************************************************/ +/* */ +/* */ +/* Written by Ken Goldman */ +/* IBM Thomas J. Watson Research Center */ +/* $Id: ResponseCodeProcessing.c 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 */ +/* */ +/********************************************************************************/ + +/* 9.15 ResponseCodeProcessing.c */ +/* 9.15.1 Description */ +/* This file contains the miscellaneous functions for processing response codes. */ +/* NOTE: Currently, there is only one. */ +/* 9.15.2 Includes and Defines */ +#include "Tpm.h" +/* 9.15.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. */ +#ifndef INLINE_RcSafeAddToResult +TPM_RC +RcSafeAddToResult( + TPM_RC responseCode, + TPM_RC modifier + ) +{ + if((responseCode & RC_FMT1) && !(responseCode & 0xf40)) + return responseCode + modifier; + else + return responseCode; +} +#endif // INLINE_RcSafeAddToResult diff --git a/src/tpm2/ResponseCodeProcessing_fp.h b/src/tpm2/ResponseCodeProcessing_fp.h new file mode 100644 index 00000000..da50c52f --- /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 00000000..54605317 --- /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 00000000..6a29a5c9 --- /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 00000000..dc801557 --- /dev/null +++ b/src/tpm2/RsaTestData.h @@ -0,0 +1,386 @@ +/********************************************************************************/ +/* */ +/* */ +/* Written by Ken Goldman */ +/* IBM Thomas J. Watson Research Center */ +/* $Id: RsaTestData.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 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}; +#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_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}}; +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_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_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}}; +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_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_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}}; +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 + +#endif diff --git a/src/tpm2/RunCommand.c b/src/tpm2/RunCommand.c new file mode 100644 index 00000000..3b3018fc --- /dev/null +++ b/src/tpm2/RunCommand.c @@ -0,0 +1,106 @@ +/********************************************************************************/ +/* */ +/* Platform specific entry and fail processing */ +/* Written by Ken Goldman */ +/* IBM Thomas J. Watson Research Center */ +/* $Id: RunCommand.c 953 2017-03-06 20:31: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, 2017 */ +/* */ +/********************************************************************************/ + +/* 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 + settup 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 "PlatformData.h" +#include "Platform_fp.h" +#include +#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 00000000..04c2ec6e --- /dev/null +++ b/src/tpm2/SelfTest.h @@ -0,0 +1,154 @@ +/********************************************************************************/ +/* */ +/* */ +/* Written by Ken Goldman */ +/* IBM Thomas J. Watson Research Center */ +/* $Id: SelfTest.h 953 2017-03-06 20:31: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 */ +/* */ +/********************************************************************************/ + +#ifndef SELFTEST_H +#define SELFTEST_H + +/* 5.18.1 Introduction */ +/* This file contains the structure definitions for the self-test. It also contains macros for use + when the self-test is implemented. */ +/* 5.18.2 Defines */ +/* Was typing this a lot */ +#define SELF_TEST_FAILURE FAIL(FATAL_ERROR_SELF_TEST) +/* Use the definition of key sizes to set algorithm values for key size. Need to do this to avoid a + lot of #ifdefs in the code. Also, define the index for each of the algorithms. */ +#if ALG_AES && defined AES_KEY_SIZE_BITS_128 +# define AES_128 YES +# define AES_128_INDEX 0 +#else +# define AES_128 NO +#endif +#if ALG_AES && defined AES_KEY_SIZE_BITS_192 +# define AES_192 YES +# define AES_192_INDEX (AES_128) +#else +# define AES_192 NO +#endif +#if ALG_AES && defined AES_KEY_SIZE_BITS_256 +# define AES_256 YES +# define AES_256_INDEX (AES_128 + AES_192) +#else +# define AES_256 NO +#endif +#if ALG_SM4 && defined SM4_KEY_SIZE_BITS_128 +# define SM4_128 YES +# define SM4_128_INDEX (AES_128 + AES_192 + AES_256) +#else +# define SM4_128 NO +#endif +#define NUM_SYMS (AES_128 + AES_192 + AES_256 + SM4_128) +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 TPM_SYM_MODE_FIRST and TPM_SYM_MODE_LAST */ +#define TPM_SYM_MODE_FIRST ALG_CTR_VALUE +#define TPM_SYM_MODE_LAST ALG_ECB_VALUE +#define NUM_SYM_MODES (TPM_SYM_MODE_LAST - TPM_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 { + 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; +#ifdef TPM_ALG_RSA +extern const RSA_KEY c_rsaTestKey; // This is a constant structure +#endif +#define SYM_TEST_VALUE_REF(value, alg, keyBits, mode) \ + SIZED_REFERENCE(value##_##alg##keyBits##_##mode) +typedef struct { + TPM_ALG_ID alg; + UINT16 keySizeBits; +} SYM_ALG; +#define SET_ALG(ALG, v) MemorySetBit((v), ALG, sizeof(v) * 8) +#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 00000000..63ecb2c1 --- /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 00000000..efe59656 --- /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 00000000..bedff796 --- /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 00000000..f2d0d759 --- /dev/null +++ b/src/tpm2/Session.c @@ -0,0 +1,828 @@ +/********************************************************************************/ +/* */ +/* Manage the session context counter */ +/* Written by Ken Goldman */ +/* IBM Thomas J. Watson Research Center */ +/* $Id: Session.c 953 2017-03-06 20:31: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, 2017 */ +/* */ +/********************************************************************************/ + +/* 8.9.2 Includes, Defines, and Local Variables */ +#define SESSION_C +#include "Tpm.h" +/* 8.9.3 File Scope Function -- ContextIdSetOldest() */ +/* This function is called when the oldest contextID is being loaded or deleted. Once a saved + context becomes the oldest, it stays the oldest until it is deleted. Finding the oldest is a bit + tricky. It is not just the numeric comparison of values but is dependent on the value of + contextCounter. Assume we have a small contextArray with 8, 4-bit values with values 1 and 2 used + to indicate the loaded context slot number. Also assume that the array contains hex values of (0 + 0 1 0 3 0 9 F) and that the contextCounter is an 8-bit counter with a value of 0x37. Since the + low nibble is 7, that means that values above 7 are older than values below it and, in this + example, 9 is the oldest value. Note if we subtract the counter value, from each slot that + contains a saved contextID we get (- - - - B - 2 - 8) and the oldest entry is now easy to + find. */ +static void +ContextIdSetOldest( + void + ) +{ + CONTEXT_SLOT lowBits; + CONTEXT_SLOT entry; + CONTEXT_SLOT smallest = ((CONTEXT_SLOT)~0); + UINT32 i; + // Set oldestSaveContext to a value indicating none assigned + s_oldestSavedSession = MAX_ACTIVE_SESSIONS + 1; + lowBits = (CONTEXT_SLOT)gr.contextCounter; + 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)(entry - lowBits)) <= smallest) + { + smallest = (entry - lowBits); + 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(). */ +void +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; + } + return; +} +/* 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: An 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 SequenceNumbereForSavedContextIsValid() */ +BOOL +SequenceNumbereForSavedContextIsValid( + TPMS_CONTEXT *context // IN: pointer to a context + // structure to be validated + ) +{ +#define MAX_CONTEXT_GAP ((UINT64)((CONTEXT_SLOT) ~0) + 1) + 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)context->sequence + // 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. */ +/* return type TPM_RC */ +/* TPM_RC_SUCCESS context ID was assigned */ +/* 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)gr.contextCounter + == 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)(sessionIndex + 1); + 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) + FAIL(FATAL_ERROR_INTERNAL); + // 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)); + // 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)gr.contextCounter) + 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)gr.contextCounter; + // 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)gr.contextCounter) == 0) + 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(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); + 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)gr.contextCounter == gr.contextArray[s_oldestSavedSession] + && 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 00000000..f8db2800 --- /dev/null +++ b/src/tpm2/SessionCommands.c @@ -0,0 +1,175 @@ +/********************************************************************************/ +/* */ +/* */ +/* Written by Ken Goldman */ +/* IBM Thomas J. Watson Research Center */ +/* $Id: SessionCommands.c 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 */ +/* */ +/********************************************************************************/ + +#include "Tpm.h" +#include "StartAuthSession_fp.h" +#ifdef TPM_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(tpmKey->publicArea.objectAttributes.decrypt != SET) + 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" +#ifdef TPM_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 00000000..8eaa60a3 --- /dev/null +++ b/src/tpm2/SessionProcess.c @@ -0,0 +1,1972 @@ +/********************************************************************************/ +/* */ +/* Process the Authorization Sessions */ +/* Written by Ken Goldman */ +/* IBM Thomas J. Watson Research Center */ +/* $Id: SessionProcess.c 953 2017-03-06 20:31: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, 2017 */ +/* */ +/********************************************************************************/ + +/* 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" +/* 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: + { + result = (ObjectGetPublicAttributes(handle).noDA == SET); + break; + } + case TPM_HT_NV_INDEX: + { + NV_INDEX *nvIndex = NvGetIndexInfo(handle, NULL); + result = (nvIndex->publicArea.attributes.TPMA_NV_NO_DA == SET); + 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(object->publicArea.objectAttributes.adminWithPolicy == CLEAR) + 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; + 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; + object = HandleToObject(handle); + // authValue is always available for a sequence object. + // An alternative for this is to SET + // object->publicArea.objectAttributes.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 + && (object->publicArea.objectAttributes.userWithAuth == SET + || (CommandAuthRole(commandIndex, sessionIndex) == AUTH_ADMIN + && object->publicArea.objectAttributes.adminWithPolicy + == CLEAR))) + 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(nvAttributes.TPMA_NV_AUTHWRITE == SET) + 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(nvAttributes.TPMA_NV_WRITTEN != SET) + break; // return false + // get the index values + pin.intVal = NvGetUINT64Data(nvIndex, locator); + if(pin.pin.pinCount < pin.pin.pinLimit) + result = TRUE; + } + // For non-PIN Indices, need to allow use of the authValue + else if(nvAttributes.TPMA_NV_AUTHREAD == SET) + 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; +} +/* 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; + 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 attributes = 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(IsNv_TPMA_NV_POLICYWRITE(attributes)) + result = TRUE; + } + else + { + if(IsNv_TPMA_NV_POLICYREAD(attributes)) + 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 + ) +{ +#if ALG_SHA1 + command->sha1CpHash.t.size = 0; + command->sha1RpHash.t.size = 0; +#endif +#if ALG_SHA256 + command->sha256CpHash.t.size = 0; + command->sha256RpHash.t.size = 0; +#endif +#if ALG_SHA384 + command->sha384CpHash.t.size = 0; + command->sha384RpHash.t.size = 0; +#endif +#if ALG_SHA512 + command->sha512CpHash.t.size = 0; + command->sha512RpHash.t.size = 0; +#endif +#if ALG_SM3_256 + command->sm3_256CpHash.t.size = 0; + command->sm3_256RpHash.t.size = 0; +#endif +} +/* 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 + ) +{ + switch(hashAlg) + { +#if ALG_SHA1 + case TPM_ALG_SHA1: + return (TPM2B_DIGEST *)&command->sha1CpHash; +#endif +#if ALG_SHA256 + case TPM_ALG_SHA256: + return (TPM2B_DIGEST *)&command->sha256CpHash; +#endif +#if ALG_SHA384 + case TPM_ALG_SHA384: + return (TPM2B_DIGEST *)&command->sha384CpHash; +#endif +#if ALG_SHA512 + case TPM_ALG_SHA512: + return (TPM2B_DIGEST *)&command->sha512CpHash; +#endif +#if ALG_SM3_256 + case TPM_ALG_SM3_256: + return (TPM2B_DIGEST *)&command->sm3_256CpHash; +#endif + default: + break; + } + return NULL; +} +/* 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 + ) +{ + switch(hashAlg) + { +#if ALG_SHA1 + case TPM_ALG_SHA1: + return (TPM2B_DIGEST *)&command->sha1RpHash; +#endif +#if ALG_SHA256 + case TPM_ALG_SHA256: + return (TPM2B_DIGEST *)&command->sha256RpHash; +#endif +#if ALG_SHA384 + case TPM_ALG_SHA384: + return (TPM2B_DIGEST *)&command->sha384RpHash; +#endif +#if ALG_SHA512 + case TPM_ALG_SHA512: + return (TPM2B_DIGEST *)&command->sha512RpHash; +#endif +#if ALG_SM3_256 + case TPM_ALG_SM3_256: + return (TPM2B_DIGEST *)&command->sm3_256RpHash; +#endif + default: + break; + } + return NULL; +} +/* 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_Derive() */ +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 +#ifdef TPM_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; // Code analysis says that this is not initialized + 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((IsNv_TPMA_NV_WRITTEN(nvIndex->publicArea.attributes)) + != (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; + 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; + if(s_sessionHandles[sessionIndex] == TPM_RS_PW) + { + // A PWAP session needs additional processing. + // Can't have any attributes set other than continueSession bit + if(s_attributes[sessionIndex].encrypt + || s_attributes[sessionIndex].decrypt + || s_attributes[sessionIndex].audit + || s_attributes[sessionIndex].auditExclusive + || s_attributes[sessionIndex].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 indices. + // First process decrypt. + if(s_attributes[sessionIndex].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(s_attributes[sessionIndex].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(s_attributes[sessionIndex].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(s_attributes[sessionIndex].auditReset == CLEAR + && session->attributes.isAudit == SET) + { + // Not first use or reset. If auditExlusive is SET, then this + // session must be the current exclusive session. + if(s_attributes[sessionIndex].auditExclusive == SET + && 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; +#ifdef 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); + 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); + } + } + // If the authorization session is going to use an authValue, then make sure + // that access to that authValue isn't locked out. + // Note: session == NULL for a PW session. + if(session == NULL || session->attributes.includeAuth) + { + // 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: IsAutPolciyAvalable 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(session == NULL || session->attributes.isPasswordNeeded == SET) + result = CheckPWAuthSession(sessionIndex); + else + result = CheckSessionHMAC(command, sessionIndex); + // Do processing for PIN indices 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. + // See if we need to do anything to a PIN index + if(TPM_HT_NV_INDEX == HandleGetType(associatedHandle)) + { + 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) && nvAttributes.TPMA_NV_WRITTEN == SET) + { + 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 for anything other than NV_Read. + // 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) + && nvAttributes.TPMA_NV_WRITTEN == SET + && 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; +} +#ifdef TPM_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(s_attributes[sessionIndex].audit == SET + || s_attributes[sessionIndex].encrypt == SET + || s_attributes[sessionIndex].decrypt == SET) + 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(s_attributes[sessionIndex].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(s_attributes[sessionIndex].audit == CLEAR + && s_attributes[sessionIndex].encrypt == CLEAR + && s_attributes[sessionIndex].decrypt == CLEAR) + 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); + } + } +#ifdef TPM_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; + } +#ifdef TPM_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; +} +#ifdef TPM_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(s_attributes[i].audit == SET) + { + // 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 + || s_attributes[i].auditReset == SET) + { + 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) + { + s_attributes[i].auditExclusive = SET; + } + else + { + s_attributes[i].auditExclusive = CLEAR; + } + // 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. + // Get the authValue with trailing zeros removed + TPM2B_AUTH authValue; + 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 + && s_attributes[i].continueSession != CLEAR) + { + // 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); +#ifdef TPM_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) + { + s_attributes[i].continueSession = SET; + 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(s_attributes[i].continueSession == CLEAR) + 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 00000000..c51b12ec --- /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 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 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 00000000..22974c9d --- /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 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 SESSION_FP_H +#define SESSION_FP_H + +void +SessionStartup( + STARTUP_TYPE type + ); +BOOL +SessionIsLoaded( + TPM_HANDLE handle // IN: session handle + ); +BOOL +SessionIsSaved( + TPM_HANDLE handle // IN: session handle + ); +BOOL +SequenceNumbereForSavedContextIsValid( + 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 00000000..dab38ffa --- /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 00000000..af6cfc3c --- /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 00000000..3b1d22e7 --- /dev/null +++ b/src/tpm2/SetPrimaryPolicy_fp.h @@ -0,0 +1,82 @@ +/********************************************************************************/ +/* */ +/* */ +/* Written by Ken Goldman */ +/* IBM Thomas J. Watson Research Center */ +/* $Id: SetPrimaryPolicy_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 SETPRIMARYPOLICY_FP_H +#define SETPRIMARYPOLICY_FP_H + +typedef struct { + TPMI_RH_HIERARCHY_AUTH 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 00000000..ceb6a8e8 --- /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 00000000..f32edcb7 --- /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 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 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 00000000..e594a469 --- /dev/null +++ b/src/tpm2/SigningCommands.c @@ -0,0 +1,151 @@ +/********************************************************************************/ +/* */ +/* */ +/* Written by Ken Goldman */ +/* IBM Thomas J. Watson Research Center */ +/* $Id: SigningCommands.c 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 */ +/* */ +/********************************************************************************/ + +#include "Tpm.h" +#include "VerifySignature_fp.h" +#ifdef TPM_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(signObject->publicArea.objectAttributes.sign != SET) + 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 = GetHeriarchy(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" +#ifdef TPM_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; + // 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 + || signObject->publicArea.objectAttributes.restricted == SET) + { + // 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 00000000..72416ab6 --- /dev/null +++ b/src/tpm2/Simulator_fp.h @@ -0,0 +1,200 @@ +/********************************************************************************/ +/* */ +/* */ +/* Written by Ken Goldman */ +/* IBM Thomas J. Watson Research Center */ +/* $Id: Simulator_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 */ +/* */ +/********************************************************************************/ + +/* D.2 Simulator_fp.h */ +#ifndef _SIMULATOR_FP_H_ +#define _SIMULATOR_FP_H_ + +#include "BaseTypes.h" + +#ifdef TPM_WINDOWS +#include +#include +#endif + +#ifdef TPM_POSIX +#include +#include +#include +#include +#include +#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 + ); +/* 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 + ); +/* Command interface Entry of a RPC call */ +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 + ); +/* 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.2.2.15. _rpc__Shutdown() */ +/* This function is used to stop the TPM simulator. */ +void +_rpc__Shutdown( + void + ); +/* 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 // _SIMULATOR_FP_H_ + diff --git a/src/tpm2/StartAuthSession_fp.h b/src/tpm2/StartAuthSession_fp.h new file mode 100644 index 00000000..c2848647 --- /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 00000000..a76e2e60 --- /dev/null +++ b/src/tpm2/StartupCommands.c @@ -0,0 +1,319 @@ +/********************************************************************************/ +/* */ +/* Startup Commands */ +/* Written by Ken Goldman */ +/* IBM Thomas J. Watson Research Center */ +/* $Id: StartupCommands.c 953 2017-03-06 20:31: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, 2017 */ +/* */ +/********************************************************************************/ + +/* 9.2 _TPM_Init */ +#include "Tpm.h" +#include "_TPM_Init_fp.h" +// This function is used to process a _TPM_Init indication. +LIB_EXPORT void +_TPM_Init( + void + ) +{ + g_powerWasLost = g_powerWasLost | _plat__WasPowerLost(); +#if defined SIMULATION && !defined NDEBUG + // 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 +#ifdef SIMULATION + // Clear the flag that forces failure on self-test + g_forceFailureMode = FALSE; +#endif + // 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); + 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(); + } + return; +} +#include "Tpm.h" +#include "Startup_fp.h" +#ifdef TPM_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(); + // 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); +#ifdef USE_DA_USED + // If there was no orderly shutdown, then their 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 this is a Resume, + if(in->startupType == TPM_SU_STATE) + { + // Turn of the startup modifiers in the recovered state. This will modify + // the SU_NONE_VALUE but not make it anything that would be recognized as + // a valid shutdown + g_prevOrderlyState &= ~(PRE_STARTUP_FLAG | STARTUP_LOCALITY_3); + // 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; + 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. + CryptStartup(startup); + // When the cryptographic library has been started, indicate that a TPM2_Startup + // command has been received. + 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 + TimeStartup(startup); + // Start dictionary attack subsystem + DAStartup(startup); + // Enable hierarchies + HierarchyStartup(startup); + // Restore/Initialize PCR + PCRStartup(startup, locality); + // Restore/Initialize command audit information + CommandAuditStartup(startup); + //// The following code was moved from Time.c where it made no sense + 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(gp.totalResetCount == 0) + FAIL(FATAL_ERROR_INTERNAL); + // Write total reset counter to NV + NV_SYNC_PERSISTENT(totalResetCount); + // Reset restartCount + gr.restartCount = 0; + break; + } + //// + // Initialize session table + SessionStartup(startup); + // Initialize object table + ObjectStartup(); + // Initialize index/evict data. This function clears read/write locks + // in NV index + NvEntityStartup(startup); + // Initialize the orderly shut down flag for this cycle to SU_NONE_VALUE. + gp.orderlyState = SU_NONE_VALUE; + 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. + g_powerWasLost = FALSE; + return TPM_RC_SUCCESS; +} +#endif // CC_Startup +#include "Tpm.h" +#include "Shutdown_fp.h" +#ifdef TPM_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; + // PCR private date state save + PCRStateSave(in->shutdownType); + // Save RAM backed NV index data + NvUpdateIndexOrderlyData(); +#ifdef 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; + } + else if(in->shutdownType == TPM_SU_CLEAR) + { + // Save STATE_RESET data + NvWrite(NV_STATE_RESET_DATA, sizeof(STATE_RESET_DATA), &gr); + } + else + FAIL(FATAL_ERROR_INTERNAL); + 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 00000000..78d1dd70 --- /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 827 2016-11-18 20:45: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 */ +/* */ +/********************************************************************************/ + +/* 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/StirRandom_fp.h b/src/tpm2/StirRandom_fp.h new file mode 100644 index 00000000..40ee129b --- /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 00000000..7152f5fd --- /dev/null +++ b/src/tpm2/SupportLibraryFunctionPrototypes_fp.h @@ -0,0 +1,131 @@ +/********************************************************************************/ +/* */ +/* */ +/* Written by Ken Goldman */ +/* IBM Thomas J. Watson Research Center */ +/* $Id: SupportLibraryFunctionPrototypes_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 SUPPORTLIBRARYFUNCTIONPROTOTYPES_FP_H +#define SUPPORTLIBRARYFUNCTIONPROTOTYPES_FP_H + + +/* This file contains the function prototypes for the functions that need to be present in the + selected match 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. */ +#ifndef SUPPORT_LIBRARY_FUNCTION_PROTOTYPES_H +#define SUPPORT_LIBRARY_FUNCTION_PROTOTYPES_H +LIB_EXPORT int SupportLibInit(void); +/* 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. */ +void +MathLibraryCompatibilityCheck( + void + ); +/* 5.19.2 BnModMult() */ +/* Does multiply and divide returning the remainder of the divide. */ +LIB_EXPORT BOOL +BnModMult(bigNum result, bigConst op1, bigConst op2, bigConst modulus); +/* 5.19.3 BnMult() */ +/* Multiplies two numbers */ +LIB_EXPORT BOOL BnMult(bigNum result, bigConst multiplicand, bigConst multiplier); +/* 5.19.4 BnDiv() */ +/* This function divides two bigNum values. The function always returns TRUE. */ +LIB_EXPORT BOOL BnDiv(bigNum quotient, bigNum remainder, + bigConst dividend, bigConst divisor); +/* 5.19.5 BnMod() */ +#define BnMod(a, b) BnDiv(NULL, (a), (a), (b)) +#ifdef TPM_ALG_RSA +/* 5.19.6 BnGcd() */ +/* Get the greatest common divisor of two numbers */ +LIB_EXPORT BOOL BnGcd(bigNum gcd, bigConst number1, bigConst number2); +/* 5.19.7 BnModExp() */ +/* Do modular exponentiation using bigNum values. */ +LIB_EXPORT BOOL BnModExp(bigNum result, bigConst number, + bigConst exponent, bigConst modulus); +/* 5.19.8 BnModInverse() */ +/* Modular multiplicative inverse */ +LIB_EXPORT BOOL BnModInverse(bigNum result, bigConst number, + bigConst modulus); +#endif // TPM_ALG_RSA +#ifdef TPM_ALG_ECC +/* 5.19.9 BnEccModMult() */ +/* This function does a point multiply of the form R = [d]S */ +/* Return Value Meaning */ +/* FALSE failure in operation; treat as result being point at infinity */ +LIB_EXPORT BOOL BnEccModMult(bigPoint R, pointConst S, bigConst d, bigCurve E); +/* 5.19.10 BnEccModMult2() */ +/* This function does a point multiply of the form R = [d]S + [u]Q */ +/* Return Value Meaning */ +/* FALSE failure in operation; treat as result being point at infinity */ +LIB_EXPORT BOOL BnEccModMult2(bigPoint R, pointConst S, bigConst d, + pointConst Q, bigConst u, bigCurve E); +/* 5.19.11 BnEccAdd() */ +/* This function does a point add R = S + Q */ +/* Return Values Meaning */ +/* FALSE failure in operation; treat as result being point at infinity */ +LIB_EXPORT BOOL BnEccAdd(bigPoint R, pointConst S, pointConst Q, bigCurve E); +/* 5.19.12 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. */ +LIB_EXPORT bigCurve BnCurveInitialize(bigCurve E, TPM_ECC_CURVE curveId); +#endif // TPM_ALG_ECC +#endif + +#endif diff --git a/src/tpm2/SymmetricCommands.c b/src/tpm2/SymmetricCommands.c new file mode 100644 index 00000000..c9f110c9 --- /dev/null +++ b/src/tpm2/SymmetricCommands.c @@ -0,0 +1,293 @@ +/********************************************************************************/ +/* */ +/* Symmetric Commands */ +/* Written by Ken Goldman */ +/* IBM Thomas J. Watson Research Center */ +/* $Id: SymmetricCommands.c 953 2017-03-06 20:31: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, 2017 */ +/* */ +/********************************************************************************/ + +#include "Tpm.h" +#include "EncryptDecrypt_fp.h" +#ifdef TPM_CC_EncryptDecrypt2 +#include "EncryptDecrypt_spt_fp.h" +#endif +#ifdef TPM_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 + ) +{ +#ifdef TPM_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; + // Input Validation + symKey = HandleToObject(in->keyHandle); + 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 = symKey->publicArea.objectAttributes.restricted != SET; + if(YES == in->decrypt) + OK = OK && symKey->publicArea.objectAttributes.decrypt == SET; + else + OK = OK && symKey->publicArea.objectAttributes.sign == SET; + 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); + // 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 ALG_xxx_VALUE for + // the algorithm is always defined. Both have the same numeric value. + // ALG_xxx_VALUE 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 == ALG_ECB_VALUE) && (in->ivIn.t.size != 0)) + || ((mode != ALG_ECB_VALUE) && (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 == ALG_CBC_VALUE) || (mode == ALG_ECB_VALUE)) + && ((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_fp.h" +// #include "EncryptDecrypt_spt_fp.h" kgold +#ifdef TPM_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" +#ifdef TPM_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) + && !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" +#ifdef TPM_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(publicArea->objectAttributes.restricted == SET) + return TPM_RCS_ATTRIBUTES + RC_HMAC_handle; + // and that it is a signing key + if(publicArea->objectAttributes.sign != SET) + 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 diff --git a/src/tpm2/SymmetricTest.h b/src/tpm2/SymmetricTest.h new file mode 100644 index 00000000..b489c2c6 --- /dev/null +++ b/src/tpm2/SymmetricTest.h @@ -0,0 +1,111 @@ +/********************************************************************************/ +/* */ +/* Structures and data definitions for the symmetric tests */ +/* Written by Ken Goldman */ +/* IBM Thomas J. Watson Research Center */ +/* $Id: SymmetricTest.h 953 2017-03-06 20:31: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, 2017 */ +/* */ +/********************************************************************************/ + +/* 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. */ + +/* 10.1.11 SymmetricTest.h */ +#ifndef SELF_TEST_DATA +#error "This file many only be included in AlgorithmTests.c" +#endif +#ifndef _SYMMETRIC_TEST_H +#define _SYMMETRIC_TEST_H +#include "SymmetricTestData.h" + +/* 10.1.11.2 Structures */ + +const SYMMETRIC_TEST_VECTOR c_symTestValues[NUM_SYMS] = { +#undef COMMA +#if AES_128 + {ALG_AES_VALUE, 128, key_AES128, 16, sizeof(dataIn_AES128), dataIn_AES128, + {dataOut_AES128_CTR, dataOut_AES128_OFB, dataOut_AES128_CBC, + dataOut_AES128_CFB, dataOut_AES128_ECB}} +# define COMMA , +#endif +#if AES_192 + COMMA + {ALG_AES_VALUE, 192, key_AES192, 16, sizeof(dataIn_AES192), dataIn_AES192, + {dataOut_AES192_CTR, dataOut_AES192_OFB, dataOut_AES192_CBC, + dataOut_AES192_CFB, dataOut_AES192_ECB}} +# undef COMMA +# define COMMA , +#endif +#if AES_256 + COMMA + {ALG_AES_VALUE, 256, key_AES256, 16, sizeof(dataIn_AES256), dataIn_AES256, + {dataOut_AES256_CTR, dataOut_AES256_OFB, dataOut_AES256_CBC, + dataOut_AES256_CFB, dataOut_AES256_ECB}} +# undef COMMA +# define COMMA , +#endif +#if SM4_128 + COMMA + {ALG_SM4_VALUE, 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 +}; +#undef COMMA + +#endif // _SYMMETRIC_TEST_H + diff --git a/src/tpm2/SymmetricTestData.h b/src/tpm2/SymmetricTestData.h new file mode 100644 index 00000000..46b4ad9f --- /dev/null +++ b/src/tpm2/SymmetricTestData.h @@ -0,0 +1,181 @@ +/********************************************************************************/ +/* */ +/* */ +/* Written by Ken Goldman */ +/* IBM Thomas J. Watson Research Center */ +/* $Id: SymmetricTestData.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 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 + +#endif diff --git a/src/tpm2/TPMB.h b/src/tpm2/TPMB.h new file mode 100644 index 00000000..21e0a5bf --- /dev/null +++ b/src/tpm2/TPMB.h @@ -0,0 +1,104 @@ +/********************************************************************************/ +/* */ +/* */ +/* Written by Ken Goldman */ +/* IBM Thomas J. Watson Research Center */ +/* $Id: TPMB.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 TPMB_H +#define TPMB_H + +/* 5.20 TPMB.h */ +/* This file contains extra TPM2B structures */ +#ifndef _TPMB_H +#define _TPMB_H +/* 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. */ +#define TPM2B_STRING(name, value) \ + static const union { \ + struct { \ + UINT16 size; \ + BYTE buffer[sizeof(value)]; \ + } t; \ + TPM2B b; \ + } name##_ = {{sizeof(value), {value}}}; \ + const TPM2B *name = &name##_.b +/* Macro to 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 + +#endif diff --git a/src/tpm2/TPMCmdp.c b/src/tpm2/TPMCmdp.c new file mode 100644 index 00000000..b08b1d73 --- /dev/null +++ b/src/tpm2/TPMCmdp.c @@ -0,0 +1,332 @@ +/********************************************************************************/ +/* */ +/* Process the commands */ +/* Written by Ken Goldman */ +/* IBM Thomas J. Watson Research Center */ +/* $Id: TPMCmdp.c 953 2017-03-06 20:31: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, 2017 */ +/* */ +/********************************************************************************/ + +/* 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 +#include +#include +#include "Implementation.h" +#include "TpmBuildSwitches.h" +#ifdef TPM_WINDOWS +#include +#include +#endif +#include "Platform_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" +#endif +#ifdef TPM_POSIX +#include "TcpServerPosix_fp.h" +#endif + +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; +} +/* 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(); +} +/* 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) return; + // Pass power off signal to platform + _plat__Signal_PowerOff(); + s_isPowerOn = FALSE; + return; +} +/* 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(); +} +/* 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 is power off, reject this signal + if(!s_isPowerOn) return; + // 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 is power off, reject this signal + if(!s_isPowerOn) return; + // 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 is power off, reject this signal + if(!s_isPowerOn) return; + // 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 is power off, reject this signal + if(!s_isPowerOn) return; + // 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 is power off, reject this signal + if(!s_isPowerOn) return; + // Pass _TPM_HashEnd signal to TPM + _TPM_Hash_End(); + return; +} +/* Command interface Entry of a RPC call */ +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) return; + // 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 is power off, reject this signal + if(!s_isPowerOn) return; + // 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 is power off, reject this signal + if(!s_isPowerOn) return; + _plat__SetNvAvail(); + return; +} +/* 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 is power off, reject this signal + if(!s_isPowerOn) return; + _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 + ) +{ +#ifdef USE_RSA_KEY_CACHE + RsaKeyCacheControl(state); +#else + NOT_REFERENCED(state); +#endif +} +/* D.4.3.15. _rpc__Shutdown() */ +/* This function is used to stop the TPM simulator. */ +void +_rpc__Shutdown( + void + ) +{ +#if 0 /* kgold bypass for now */ + RPC_STATUS status; + // Stop TPM + TPM_TearDown(); + status = RpcMgmtStopServerListening(NULL); + if(status != RPC_S_OK) + { + printf("RpcMgmtStopServerListening returned: 0x%x\n", status); + exit(status); + } + status = RpcServerUnregisterIf(NULL, NULL, FALSE); + if(status != RPC_S_OK) + { + printf("RpcServerUnregisterIf returned 0x%x\n", status); + exit(status); + } +#endif + return; +} diff --git a/src/tpm2/TcpServer.c b/src/tpm2/TcpServer.c new file mode 100644 index 00000000..dfe25b61 --- /dev/null +++ b/src/tpm2/TcpServer.c @@ -0,0 +1,580 @@ +/********************************************************************************/ +/* */ +/* */ +/* Written by Ken Goldman */ +/* IBM Thomas J. Watson Research Center */ +/* $Id: TcpServer.c 812 2016-11-16 21:28: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 */ +/* */ +/********************************************************************************/ + +/* D.3 TcpServer.c */ +/* D.3.1. Description */ +/* This file contains the socket interface to a TPM simulator. */ +/* D.3.2. Includes, Locals, Defines and Function Prototypes */ +#include "TpmBuildSwitches.h" +#include + +#include +#include + +#include +#include +#include + +#include "Implementation.h" /* kgold */ +#include "TpmTcpProtocol.h" +#include "Manufacture_fp.h" +#include "Simulator_fp.h" +#include "TcpServer_fp.h" + +/* To access key cache control in TPM */ +void RsaKeyCacheControl(int state); +#ifndef __IGNORE_STATE__ +static uint32_t ServerVersion = 1; +#define MAX_BUFFER 1048576 +char InputBuffer[MAX_BUFFER]; //The input data buffer for the simulator. +char OutputBuffer[MAX_BUFFER]; //The output data buffer for the simulator. +struct +{ + uint32_t largestCommandSize; + uint32_t largestCommand; + uint32_t largestResponseSize; + uint32_t largestResponse; +} CommandResponseSizes = {0}; +#endif // __IGNORE_STATE___ +/* D.3.3. Functions */ +/* D.3.3.1. CreateSocket() */ +/* This function creates a socket listening on PortNumber. */ +static int +CreateSocket( + int PortNumber, + SOCKET *listenSocket + ) +{ + WSADATA wsaData; + struct sockaddr_in MyAddress; + int res; + // Initialize Winsock + res = WSAStartup(MAKEWORD(2, 2), &wsaData); + if(res != 0) + { + printf("WSAStartup failed with error: %d\n", res); + return -1; + } + // create listening socket + *listenSocket = socket(PF_INET, SOCK_STREAM, 0); + if(INVALID_SOCKET == *listenSocket) + { + printf("Cannot create server listen socket. Error is 0x%x\n", + WSAGetLastError()); + return -1; + } + // bind the listening socket to the specified port + ZeroMemory(&MyAddress, sizeof(MyAddress)); + MyAddress.sin_port = htons((short)PortNumber); + MyAddress.sin_family = AF_INET; + res = bind(*listenSocket, (struct sockaddr*) &MyAddress, sizeof(MyAddress)); + if(res == SOCKET_ERROR) + { + printf("Bind error. Error is 0x%x\n", WSAGetLastError()); + return -1; + }; + // listen/wait for server connections + res = listen(*listenSocket, 3); + if(res == SOCKET_ERROR) + { + printf("Listen error. Error is 0x%x\n", WSAGetLastError()); + return -1; + }; + return 0; +} +/* D.3.3.2. PlatformServer() */ +/* This function processes incoming platform requests. */ +BOOL +PlatformServer( + SOCKET s + ) +{ + BOOL OK = TRUE; + uint32_t Command; + for(;;) + { + OK = ReadBytes(s, (char*)&Command, 4); + // client disconnected (or other error). We stop processing this client + // and return to our caller who can stop the server or listen for another + // connection. + if(!OK) return TRUE; + Command = ntohl(Command); + switch(Command) + { + case TPM_SIGNAL_POWER_ON: + _rpc__Signal_PowerOn(FALSE); + break; + case TPM_SIGNAL_POWER_OFF: + _rpc__Signal_PowerOff(); + break; + case TPM_SIGNAL_RESET: + _rpc__Signal_PowerOn(TRUE); + break; + case TPM_SIGNAL_RESTART: + _rpc__Signal_Restart(); + break; + case TPM_SIGNAL_PHYS_PRES_ON: + _rpc__Signal_PhysicalPresenceOn(); + break; + case TPM_SIGNAL_PHYS_PRES_OFF: + _rpc__Signal_PhysicalPresenceOff(); + break; + case TPM_SIGNAL_CANCEL_ON: + _rpc__Signal_CancelOn(); + break; + case TPM_SIGNAL_CANCEL_OFF: + _rpc__Signal_CancelOff(); + break; + case TPM_SIGNAL_NV_ON: + _rpc__Signal_NvOn(); + break; + case TPM_SIGNAL_NV_OFF: + _rpc__Signal_NvOff(); + break; + case TPM_SIGNAL_KEY_CACHE_ON: + _rpc__RsaKeyCacheControl(TRUE); + break; + case TPM_SIGNAL_KEY_CACHE_OFF: + _rpc__RsaKeyCacheControl(FALSE); + break; + case TPM_SESSION_END: + // Client signaled end-of-session + TpmEndSimulation(); + return TRUE; + case TPM_STOP: + // Client requested the simulator to exit + return FALSE; + case TPM_TEST_FAILURE_MODE: + _rpc__ForceFailureMode(); + break; + case TPM_GET_COMMAND_RESPONSE_SIZES: + OK = WriteVarBytes(s, (char *)&CommandResponseSizes, + sizeof(CommandResponseSizes)); + memset(&CommandResponseSizes, 0, sizeof(CommandResponseSizes)); + if(!OK) + return TRUE; + break; + default: + printf("Unrecognized platform interface command %d\n", + (int)Command); + WriteUINT32(s, 1); + return TRUE; + } + WriteUINT32(s, 0); + } + return FALSE; +} +/* D.3.3.3. PlatformSvcRoutine() */ +/* This function is called to set up the socket interfaces to listen for commands. */ +DWORD WINAPI +PlatformSvcRoutine( + LPVOID port + ) +{ + int PortNumber = (int)(INT_PTR)port; + SOCKET listenSocket, serverSocket; + struct sockaddr_in HerAddress; + int res; + int length; + BOOL continueServing; + res = CreateSocket(PortNumber, &listenSocket); + if(res != 0) + { + printf("Create platform service socket fail\n"); + return res; + } + // Loop accepting connections one-by-one until we are killed or asked to stop + // Note the platform service is single-threaded so we don't listen for a new + // connection until the prior connection drops. + do + { + printf("Platform server listening on port %d\n", PortNumber); + // blocking accept + length = sizeof(HerAddress); + serverSocket = accept(listenSocket, + (struct sockaddr*) &HerAddress, + &length); + if(serverSocket == SOCKET_ERROR) + { + printf("Accept error. Error is 0x%x\n", WSAGetLastError()); + return -1; + }; + printf("Client accepted\n"); + // normal behavior on client disconnection is to wait for a new client + // to connect + continueServing = PlatformServer(serverSocket); + closesocket(serverSocket); + } while(continueServing); + return 0; +} +/* D.3.3.4. PlatformSignalService() */ +/* This function starts a new thread waiting for platform signals. Platform signals are processed + one at a time in the order in which they are received. */ +int +PlatformSignalService( + int PortNumberPlatform + ) +{ + HANDLE hPlatformSvc; + int ThreadId; + int port = PortNumberPlatform; + // Create service thread for platform signals + hPlatformSvc = CreateThread(NULL, 0, + (LPTHREAD_START_ROUTINE)PlatformSvcRoutine, + (LPVOID)(INT_PTR)port, 0, (LPDWORD)&ThreadId); + if(hPlatformSvc == NULL) + { + printf("Thread Creation failed\n"); + return -1; + } + return 0; +} +/* D.3.3.5. RegularCommandService() */ +/* This function services regular commands. */ +int +RegularCommandService( + int PortNumber + ) +{ + SOCKET listenSocket; + SOCKET serverSocket; + struct sockaddr_in HerAddress; + int res, length; + BOOL continueServing; + res = CreateSocket(PortNumber, &listenSocket); + if(res != 0) + { + printf("Create platform service socket fail\n"); + return res; + } + // Loop accepting connections one-by-one until we are killed or asked to stop + // Note the TPM command service is single-threaded so we don't listen for + // a new connection until the prior connection drops. + do + { + printf("TPM command server listening on port %d\n", PortNumber); + // blocking accept + length = sizeof(HerAddress); + serverSocket = accept(listenSocket, + (struct sockaddr*) &HerAddress, + &length); + if(serverSocket == SOCKET_ERROR) + { + printf("Accept error. Error is 0x%x\n", WSAGetLastError()); + return -1; + }; + printf("Client accepted\n"); + // normal behavior on client disconnection is to wait for a new client + // to connect + continueServing = TpmServer(serverSocket); + closesocket(serverSocket); + } while(continueServing); + return 0; +} +/* D.3.3.6. StartTcpServer() */ +/* Main entry-point to the TCP server. The server listens on port specified. Note that there is no + way to specify the network interface in this implementation. */ +int +StartTcpServer( + int *PortNumber, + int *PortNumberPlatform + ) +{ + int res; + // Start Platform Signal Processing Service + res = PlatformSignalService(*PortNumberPlatform); + if(res != 0) + { + printf("PlatformSignalService failed\n"); + return res; + } + // Start Regular/DRTM TPM command service + res = RegularCommandService(*PortNumber); + if(res != 0) + { + printf("RegularCommandService failed\n"); + return res; + } + return 0; +} +/* D.3.3.7. ReadBytes() */ +/* This function reads the indicated number of bytes (NumBytes) into buffer from the indicated + socket. */ +BOOL +ReadBytes( + SOCKET s, + char *buffer, + int NumBytes + ) +{ + int res; + int numGot = 0; + while(numGot < NumBytes) + { + res = recv(s, buffer + numGot, NumBytes - numGot, 0); + if(res == -1) + { + printf("Receive error. Error is 0x%x\n", WSAGetLastError()); + return FALSE; + } + if(res == 0) + { + return FALSE; + } + numGot += res; + } + return TRUE; +} +/* D.3.3.8. WriteBytes() */ +/* This function will send the indicated number of bytes (NumBytes) to the indicated socket */ +BOOL +WriteBytes( + SOCKET s, + char *buffer, + int NumBytes + ) +{ + int res; + int numSent = 0; + while(numSent < NumBytes) + { + res = send(s, buffer + numSent, NumBytes - numSent, 0); + if(res == -1) + { + if(WSAGetLastError() == 0x2745) + { + printf("Client disconnected\n"); + } + else + { + printf("Send error. Error is 0x%x\n", WSAGetLastError()); + } + return FALSE; + } + numSent += res; + } + return TRUE; +} +/* D.3.3.9. WriteUINT32() */ +/* Send 4 bytes containing hton(1) */ +BOOL +WriteUINT32( + SOCKET s, + uint32_t val + ) +{ + UINT32 netVal = htonl(val); + return WriteBytes(s, (char*)&netVal, 4); +} +/* D.3.3.10. ReadVarBytes() */ +/* Get a UINT32-length-prepended binary array. Note that the 4-byte length is in network byte order + (big-endian). */ +BOOL +ReadVarBytes( + SOCKET s, + char *buffer, + uint32_t *BytesReceived, + int MaxLen + ) +{ + int length; + BOOL res; + res = ReadBytes(s, (char*)&length, 4); + if(!res) return res; + length = ntohl(length); + *BytesReceived = length; + if(length > MaxLen) + { + printf("Buffer too big. Client says %d\n", length); + return FALSE; + } + if(length == 0) return TRUE; + res = ReadBytes(s, buffer, length); + if(!res) return res; + return TRUE; +} +/* D.3.3.11. WriteVarBytes() */ +/* Send a UINT32-length-prepended binary array. Note that the 4-byte length is in network byte + order (big-endian). */ +BOOL +WriteVarBytes( + SOCKET s, + char *buffer, + int BytesToSend + ) +{ + uint32_t netLength = htonl(BytesToSend); + BOOL res; + res = WriteBytes(s, (char*)&netLength, 4); + if(!res) return res; + res = WriteBytes(s, buffer, BytesToSend); + if(!res) return res; + return TRUE; +} +/* D.3.3.12. TpmServer() */ +/* Processing incoming TPM command requests using the protocol / interface defined above. */ +BOOL +TpmServer( + SOCKET s + ) +{ + uint32_t length; + uint32_t Command; + BYTE locality; + BOOL OK; + int result; + int clientVersion; + _IN_BUFFER InBuffer; + _OUT_BUFFER OutBuffer; + for(;;) + { + OK = ReadBytes(s, (char*)&Command, 4); + // client disconnected (or other error). We stop processing this client + // and return to our caller who can stop the server or listen for another + // connection. + if(!OK) + return TRUE; + Command = ntohl(Command); + switch(Command) + { + case TPM_SIGNAL_HASH_START: + _rpc__Signal_Hash_Start(); + break; + case TPM_SIGNAL_HASH_END: + _rpc__Signal_HashEnd(); + break; + case TPM_SIGNAL_HASH_DATA: + OK = ReadVarBytes(s, InputBuffer, &length, MAX_BUFFER); + if(!OK) return TRUE; + InBuffer.Buffer = (BYTE*)InputBuffer; + InBuffer.BufferSize = length; + _rpc__Signal_Hash_Data(InBuffer); + break; + case TPM_SEND_COMMAND: + OK = ReadBytes(s, (char*)&locality, 1); + if(!OK) + return TRUE; + OK = ReadVarBytes(s, InputBuffer, &length, MAX_BUFFER); + if(!OK) + return TRUE; + InBuffer.Buffer = (BYTE*)InputBuffer; + InBuffer.BufferSize = length; + OutBuffer.BufferSize = MAX_BUFFER; + OutBuffer.Buffer = (_OUTPUT_BUFFER)OutputBuffer; + // record the number of bytes in the command if it is the largest + // we have seen so far. + if(InBuffer.BufferSize > CommandResponseSizes.largestCommandSize) + { + CommandResponseSizes.largestCommandSize = InBuffer.BufferSize; + memcpy(&CommandResponseSizes.largestCommand, + &InputBuffer[6], sizeof(UINT32)); + } + _rpc__Send_Command(locality, InBuffer, &OutBuffer); + // record the number of bytes in the response if it is the largest + // we have seen so far. + if(OutBuffer.BufferSize > CommandResponseSizes.largestResponseSize) + { + CommandResponseSizes.largestResponseSize + = OutBuffer.BufferSize; + memcpy(&CommandResponseSizes.largestResponse, + &OutputBuffer[6], sizeof(UINT32)); + } + OK = WriteVarBytes(s, + (char*)OutBuffer.Buffer, + OutBuffer.BufferSize); + if(!OK) + return TRUE; + break; + case TPM_REMOTE_HANDSHAKE: + OK = ReadBytes(s, (char*)&clientVersion, 4); + if(!OK) + return TRUE; + if(clientVersion == 0) + { + printf("Unsupported client version (0).\n"); + return TRUE; + } + OK &= WriteUINT32(s, ServerVersion); + OK &= WriteUINT32(s, tpmInRawMode + | tpmPlatformAvailable | tpmSupportsPP); + break; + case TPM_SET_ALTERNATIVE_RESULT: + OK = ReadBytes(s, (char*)&result, 4); + if(!OK) + return TRUE; + // Alternative result is not applicable to the simulator. + break; + case TPM_SESSION_END: + // Client signaled end-of-session + return TRUE; + case TPM_STOP: + // Client requested the simulator to exit + return FALSE; + default: + printf("Unrecognized TPM interface command %d\n", (int)Command); + return TRUE; + } + OK = WriteUINT32(s, 0); + if(!OK) + return TRUE; + } + return FALSE; +} diff --git a/src/tpm2/TcpServerPosix.c b/src/tpm2/TcpServerPosix.c new file mode 100644 index 00000000..ce63ec66 --- /dev/null +++ b/src/tpm2/TcpServerPosix.c @@ -0,0 +1,664 @@ +/********************************************************************************/ +/* */ +/* */ +/* Written by Ken Goldman */ +/* IBM Thomas J. Watson Research Center */ +/* $Id: TcpServerPosix.c 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-2016 */ +/* */ +/********************************************************************************/ + +// D.3 TcpServer.c +// D.3.1. Description +// This file contains the socket interface to a TPM simulator. +// D.3.2. Includes, Locals, Defines and Function Prototypes + +#include +/* FIXME need Posix TCP socket code */ +#include +#include +#include +#include +#include + +#include "string.h" +#include +#include +#include + +#include "Implementation.h" /* kgold */ +#include "TpmTcpProtocol.h" +#include "TcpServerPosix_fp.h" +#include "Simulator_fp.h" + +#ifndef __IGNORE_STATE__ +static UINT32 ServerVersion = 1; +#define MAX_BUFFER 1048576 +char InputBuffer[MAX_BUFFER]; //The input data buffer for the simulator. +char OutputBuffer[MAX_BUFFER]; //The output data buffer for the simulator. + +struct { + UINT32 largestCommandSize; + UINT32 largestCommand; + UINT32 largestResponseSize; + UINT32 largestResponse; +} CommandResponseSizes = {0}; + +#endif // __IGNORE_STATE___ + +// D.3.3. Functions +// D.3.3.1. CreateSocket() +// This function creates a socket listening on PortNumber. + +static int +CreateSocket( + int PortNumber, + SOCKET *listenSocket + ) +{ + struct sockaddr_in MyAddress; + int opt; + + int res; + + // create listening socket + *listenSocket = socket(PF_INET, SOCK_STREAM, 0); + if(*listenSocket == -1) + { + printf("Cannot create server listen socket. Erroris %d %s\n", + errno, strerror(errno)); + return -1; + } + + // bind the listening socket to the specified port + memset((char *)&MyAddress, 0, sizeof(MyAddress)); + MyAddress.sin_port=htons((short) PortNumber); + MyAddress.sin_family=AF_INET; + MyAddress.sin_addr.s_addr = htonl(INADDR_ANY); /* host to network byte order for long */ + opt = 1; + /* Set SO_REUSEADDR before calling bind() for servers that bind to a fixed port number. */ + res = setsockopt(*listenSocket, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)); + if (res != 0) { + printf("setsockopt error. Error is %d %s\n", errno, strerror(errno)); + return -1; + } + + res= bind(*listenSocket,(struct sockaddr*) &MyAddress,sizeof(MyAddress)); + if(res != 0) + { + close(*listenSocket); + *listenSocket = -1; + printf("Bind error. Error is %d %s\n", errno, strerror(errno)); + return -1; + }; + + // listen/wait for server connections + res= listen(*listenSocket,3); + if(res != 0) + { + close(*listenSocket); + *listenSocket = -1; + printf("Listen error. Error is %d %s\n", errno, strerror(errno)); + return -1; + }; + + return 0; +} + +// D.3.3.2. PlatformServer() +// This function processes incoming platform requests. + +BOOL +PlatformServer( + SOCKET s + ) +{ + BOOL ok = TRUE; + // UINT32 length = 0; kgold - unused + UINT32 Command; + + for(;;) + { + ok = ReadBytes(s, (char*) &Command, 4); + // client disconnected (or other error). We stop processing this client + // and return to our caller who can stop the server or listen for another + // connection. + if(!ok) return TRUE; + Command = ntohl(Command); + switch(Command) + { + case TPM_SIGNAL_POWER_ON: + _rpc__Signal_PowerOn(FALSE); + break; + + case TPM_SIGNAL_POWER_OFF: + _rpc__Signal_PowerOff(); + break; + + case TPM_SIGNAL_RESET: + _rpc__Signal_PowerOn(TRUE); + break; + + case TPM_SIGNAL_PHYS_PRES_ON: + _rpc__Signal_PhysicalPresenceOn(); + break; + + case TPM_SIGNAL_PHYS_PRES_OFF: + _rpc__Signal_PhysicalPresenceOff(); + break; + + case TPM_SIGNAL_CANCEL_ON: + _rpc__Signal_CancelOn(); + break; + + case TPM_SIGNAL_CANCEL_OFF: + _rpc__Signal_CancelOff(); + break; + + case TPM_SIGNAL_NV_ON: + _rpc__Signal_NvOn(); + break; + + case TPM_SIGNAL_NV_OFF: + _rpc__Signal_NvOff(); + break; + + case TPM_SESSION_END: + // Client signaled end-of-session + return TRUE; + + case TPM_STOP: + // Client requested the simulator to exit + return FALSE; + + case TPM_TEST_FAILURE_MODE: + _rpc__ForceFailureMode(); + break; + + case TPM_GET_COMMAND_RESPONSE_SIZES: + ok = WriteVarBytes(s, (char *)&CommandResponseSizes, + sizeof(CommandResponseSizes)); + memset(&CommandResponseSizes, 0, sizeof(CommandResponseSizes)); + if(!ok) + return TRUE; + break; + + default: + printf("Unrecognized platform interface command %08x\n", Command); + WriteUINT32(s, 1); + return TRUE; + } + WriteUINT32(s,0); + } + return FALSE; +} + +// D.3.3.3. PlatformSvcRoutine() +// This function is called to set up the socket interfaces to listen for commands. + +int +PlatformSvcRoutine( + void *port + ) +{ + int PortNumber = *(int *)port; + SOCKET listenSocket, serverSocket; + struct sockaddr_in HerAddress; + int res; + socklen_t length; + BOOL continueServing; + + res = CreateSocket(PortNumber, &listenSocket); + if(res != 0) + { + printf("Create platform service socket fail\n"); + return res; + } + + // Loop accepting connections one-by-one until we are killed or asked to stop + // Note the platform service is single-threaded so we don't listen for a new + // connection until the prior connection drops. + do + { + printf("Platform server listening on port %d\n", PortNumber); + + // blocking accept + length = sizeof(HerAddress); + serverSocket = accept(listenSocket, + (struct sockaddr*) &HerAddress, + &length); + if(serverSocket < 0) + { + printf("Accept error. Error is %d %s\n", errno, strerror(errno)); + return -1; + }; + printf("Client accepted\n"); + + // normal behavior on client disconnection is to wait for a new client + // to connect + continueServing = PlatformServer(serverSocket); + close(serverSocket); + serverSocket = -1; + } + while(continueServing); + + return 0; +} + +// D.3.3.4. PlatformSignalService() + +// This function starts a new thread waiting for platform signals. Platform signals are processed +// one at a time in the order in which they are received. + +int +PlatformSignalService( + int *PortNumberPlatform + ) +{ + unsigned long thread; + int irc = 0; + pthread_t *pthread = (pthread_t *)&thread; + + irc = pthread_create(pthread, + NULL, + (void * (*)(void *))PlatformSvcRoutine, /* thread entry function */ + (void *)PortNumberPlatform); /* thread function parameters */ + if (irc != 0) { + printf("Thread Creation failed\n"); + return -1; + } + return 0; + + +#if 0 + int ThreadId; + HANDLE hPlatformSvc; + // Create service thread for platform signals + hPlatformSvc = CreateThread(NULL, 0, + (LPTHREAD_START_ROUTINE)PlatformSvcRoutine, + (LPVOID) (INT_PTR) port, 0, (LPDWORD)&ThreadId); + if(hPlatformSvc == NULL) + { + printf("Thread Creation failed\n"); + return -1; + } + + return 0; + + +#endif +} + +// D.3.3.5. RegularCommandService() +// This funciton services regular commands. + +int +RegularCommandService( + int *PortNumber + ) +{ + SOCKET listenSocket; + SOCKET serverSocket; + struct sockaddr_in HerAddress; + + int res; + socklen_t length; + BOOL continueServing; + + res = CreateSocket(*PortNumber, &listenSocket); + if(res != 0) + { + printf("Create platform service socket fail\n"); + return res; + } + + // Loop accepting connections one-by-one until we are killed or asked to stop + // Note the TPM command service is single-threaded so we don't listen for + // a new connection until the prior connection drops. + do + { + printf("TPM command server listening on port %d\n", *PortNumber); + + // blocking accept + length = sizeof(HerAddress); + serverSocket = accept(listenSocket, + (struct sockaddr*) &HerAddress, + &length); + if(serverSocket < 0) + { + printf("Accept error. Error is %d %s\n", errno, strerror(errno)); + return -1; + }; + printf("Client accepted\n"); + + // normal behavior on client disconnection is to wait for a new client + // to connect + continueServing = TpmServer(serverSocket); + close(serverSocket); + serverSocket = -1; + } + while(continueServing); + + return 0; +} + +// D.3.3.6. StartTcpServer() + +// Main entry-point to the TCP server. The server listens on port specified. Note that there is no +// way to specify the network interface in this implementation. + +int +StartTcpServer( + int *PortNumber, + int *PortNumberPlatform + ) +{ + int res; + + // Start Platform Signal Processing Service + res = PlatformSignalService(PortNumberPlatform); + if (res != 0) + { + printf("PlatformSignalService failed\n"); + return res; + } + + // Start Regular/DRTM TPM command service + res = RegularCommandService(PortNumber); + if (res != 0) + { + printf("RegularCommandService failed\n"); + return res; + } + + return 0; +} + +// D.3.3.7. ReadBytes() +// This function reads the indicated number of bytes (NumBytes) into buffer from the indicated socket. + +BOOL +ReadBytes( + SOCKET s, + char *buffer, + int NumBytes + ) +{ + int res; + int numGot = 0; + + while(numGotMaxLen) + { + printf("Buffer too big. Client says %d\n", length); + return FALSE; + } + if(length==0) return TRUE; + res = ReadBytes(s, buffer, length); + if(!res) return res; + return TRUE; +} + +// D.3.3.11. WriteVarBytes() +// Send a UINT32-length-prepended binary array. Note that the 4-byte length is in network byte order (big-endian). + +BOOL +WriteVarBytes( + SOCKET s, + char *buffer, + int BytesToSend + ) +{ + UINT32 netLength = htonl(BytesToSend); + BOOL res; + + res = WriteBytes(s, (char*) &netLength, 4); + if(!res) return res; + res = WriteBytes(s, buffer, BytesToSend); + if(!res) return res; + return TRUE; +} + +// D.3.3.12. TpmServer() +// Processing incoming TPM command requests using the protocol / interface defined above. + +BOOL +TpmServer( + SOCKET s + ) +{ + UINT32 length; + UINT32 Command; + BYTE locality; + BOOL ok; + int result; + int clientVersion; + _IN_BUFFER InBuffer; + _OUT_BUFFER OutBuffer; + + for(;;) + { + ok = ReadBytes(s, (char*) &Command, 4); + // client disconnected (or other error). We stop processing this client + // and return to our caller who can stop the server or listen for another + // connection. + if(!ok) + return TRUE; + Command = ntohl(Command); + switch(Command) + { + case TPM_SIGNAL_HASH_START: + _rpc__Signal_Hash_Start(); + break; + + case TPM_SIGNAL_HASH_END: + _rpc__Signal_HashEnd(); + break; + + case TPM_SIGNAL_HASH_DATA: + ok = ReadVarBytes(s, InputBuffer, &length, MAX_BUFFER); + if(!ok) return TRUE; + InBuffer.Buffer = (BYTE*) InputBuffer; + InBuffer.BufferSize = length; + _rpc__Signal_Hash_Data(InBuffer); + break; + + case TPM_SEND_COMMAND: + ok = ReadBytes(s, (char*) &locality, 1); + if(!ok) + return TRUE; + + ok = ReadVarBytes(s, InputBuffer, &length, MAX_BUFFER); + if(!ok) + return TRUE; + InBuffer.Buffer = (BYTE*) InputBuffer; + InBuffer.BufferSize = length; + OutBuffer.BufferSize = MAX_BUFFER; + OutBuffer.Buffer = (_OUTPUT_BUFFER) OutputBuffer; + // record the number of bytes in the command if it is the largest + // we have seen so far. + if(InBuffer.BufferSize > CommandResponseSizes.largestCommandSize) + { + CommandResponseSizes.largestCommandSize = InBuffer.BufferSize; + memcpy(&CommandResponseSizes.largestCommand, + &InputBuffer[6], sizeof(UINT32)); + } + + _rpc__Send_Command(locality, InBuffer, &OutBuffer); + // record the number of bytes in the response if it is the largest + // we have seen so far. + if(OutBuffer.BufferSize > CommandResponseSizes.largestResponseSize) + { + CommandResponseSizes.largestResponseSize + = OutBuffer.BufferSize; + memcpy(&CommandResponseSizes.largestResponse, + &OutputBuffer[6], sizeof(UINT32)); + } + ok = WriteVarBytes(s, + (char*) OutBuffer.Buffer, + OutBuffer.BufferSize); + if(!ok) + return TRUE; + break; + + case TPM_REMOTE_HANDSHAKE: + ok = ReadBytes(s, (char*)&clientVersion, 4); + if(!ok) + return TRUE; + if( clientVersion == 0 ) + { + printf("Unsupported client version (0).\n"); + return TRUE; + } + ok &= WriteUINT32(s, ServerVersion); + ok &= WriteUINT32(s, + tpmInRawMode | tpmPlatformAvailable | tpmSupportsPP); + break; + + case TPM_SET_ALTERNATIVE_RESULT: + ok = ReadBytes(s, (char*)&result, 4); + if(!ok) + return TRUE; + // Alternative result is not applicable to the simulator. + break; + + case TPM_SESSION_END: + // Client signaled end-of-session + return TRUE; + + case TPM_STOP: + // Client requested the simulator to exit + return FALSE; + default: + printf("Unrecognized TPM interface command %08x\n", Command); + return TRUE; + } + ok = WriteUINT32(s,0); + if(!ok) + return TRUE; + } + return FALSE; +} diff --git a/src/tpm2/TcpServerPosix_fp.h b/src/tpm2/TcpServerPosix_fp.h new file mode 100644 index 00000000..f05b2b04 --- /dev/null +++ b/src/tpm2/TcpServerPosix_fp.h @@ -0,0 +1,131 @@ +/********************************************************************************/ +/* */ +/* */ +/* Written by Ken Goldman */ +/* IBM Thomas J. Watson Research Center */ +/* $Id: TcpServerPosix_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 TCPSERVERPOSIX_FP_H +#define TCPSERVERPOSIX_FP_H + +#include +#include +#include +#include +#include + +#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 00000000..c71f67e5 --- /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 00000000..77d5251e --- /dev/null +++ b/src/tpm2/TestingCommands.c @@ -0,0 +1,108 @@ +/********************************************************************************/ +/* */ +/* */ +/* Written by Ken Goldman */ +/* IBM Thomas J. Watson Research Center */ +/* $Id: TestingCommands.c 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 */ +/* */ +/********************************************************************************/ + +#include "Tpm.h" +#include "SelfTest_fp.h" +#ifdef TPM_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" +#ifdef TPM_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" +#ifdef TPM_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 00000000..19422444 --- /dev/null +++ b/src/tpm2/Ticket.c @@ -0,0 +1,236 @@ +/********************************************************************************/ +/* */ +/* */ +/* Written by Ken Goldman */ +/* IBM Thomas J. Watson Research Center */ +/* $Id: Ticket.c 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 */ +/* */ +/********************************************************************************/ + +/* 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_GENERATED 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_GENERATED_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_AUTH *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_AUTH *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_AUTH *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_AUTH *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 00000000..c3b4dad3 --- /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 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 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 00000000..0e3462b8 --- /dev/null +++ b/src/tpm2/Time.c @@ -0,0 +1,264 @@ +/********************************************************************************/ +/* */ +/* Functions relating to the TPM's time functions */ +/* Written by Ken Goldman */ +/* IBM Thomas J. Watson Research Center */ +/* $Id: Time.c 953 2017-03-06 20:31: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, 2017 */ +/* */ +/********************************************************************************/ + +/* 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 "PlatformData.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 + ) +{ +#ifdef 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. */ +void +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; +} +/* 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 + ) +{ +#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; + NvWrite(NV_ORDERLY_DATA, sizeof(go), &go); + } + 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 00000000..025c2861 --- /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 953 2017-03-06 20:31: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, 2017 */ +/* */ +/********************************************************************************/ + +#ifndef TIME_FP_H +#define TIME_FP_H + +void +TimePowerOn( + void + ); +void +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 00000000..5e474c14 --- /dev/null +++ b/src/tpm2/Tpm.h @@ -0,0 +1,73 @@ +/********************************************************************************/ +/* */ +/* Root header file for building any TPM.lib code */ +/* Written by Ken Goldman */ +/* IBM Thomas J. Watson Research Center */ +/* $Id: Tpm.h 953 2017-03-06 20:31: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, 2017 */ +/* */ +/********************************************************************************/ + +/* 5.20 Tpm.h */ +/* Root header file for building any TPM.lib code */ +#ifndef _TPM_H_ +#define _TPM_H_ +#include "Implementation.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/TpmBuildSwitches.h b/src/tpm2/TpmBuildSwitches.h new file mode 100644 index 00000000..046d738e --- /dev/null +++ b/src/tpm2/TpmBuildSwitches.h @@ -0,0 +1,190 @@ +/********************************************************************************/ +/* */ +/* Build Switches */ +/* Written by Ken Goldman */ +/* IBM Thomas J. Watson Research Center */ +/* $Id: TpmBuildSwitches.h 953 2017-03-06 20:31: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, 2017 */ +/* */ +/********************************************************************************/ + +#ifndef TPMBUILDSWITCHES_H +#define 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. */ +/* Many of the #defines are guarded so that they can be set on the command line without causing + consternation in the compiler. */ +#ifndef INLINE_FUNCTIONS +//# define INLINE_FUNCTIONS +#endif +/* Don't move this include ahead of the INLINE_FUNCTIONS definition. */ +#include "CompilerDependencies.h" +/* This definition is required for the re-factored code */ +#define USE_BN_ECC_DATA +/* Comment these out as needed */ +#ifndef SIMULATION +# define SIMULATION +#endif +/* Define this to run the function that checks the format compatibility for the chosen big number + math library. Not all ports use this. */ +#if !defined LIBRARY_COMPATIBILITY_CHECK && defined SIMULATION +# define LIBRARY_COMPATABILITY_CHECK +#endif +#ifndef FIPS_COMPLIANT +//# define FIPS_COMPLIANT +#endif +/* Definition to allow alternate behavior for non-orderly startup. If there is a chance that the TPM + could not update failedTries */ +#ifndef USE_DA_USED +# define USE_DA_USED +#endif +/* Define TABLE_DRIVEN_DISPATCH to use tables rather than case statements for command dispatch and + handle unmarshaling */ +#ifndef TABLE_DRIVEN_DISPATCH +# define TABLE_DRIVEN_DISPATCH +#endif +/* This switch is used to enable the self-test capability in AlgorithmTests.c */ +#ifndef SELF_TEST +#define SELF_TEST +#endif +/* Enable the generation of RSA primes using a sieve. */ +#ifndef RSA_KEY_SIEVE +# define RSA_KEY_SIEVE +#endif +/* Enable the instrumentation of the sieve process. This is used to tune the sieve variables.*/ +#if !defined RSA_INSTRUMENT && defined RSA_KEY_SIEVE && defined SIMULATION +//#define RSA_INSTRUMENT +#endif +#if defined RSA_KEY_SIEVE && !defined NDEBUG && !defined RSA_INSTRUMENT +//# define RSA_INSTRUMENT +#endif +/* This switch enables the RNG state save and restore */ +#ifndef _DRBG_STATE_SAVE +# define _DRBG_STATE_SAVE // Comment this out if no state save is wanted +#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. */ +#ifndef COMPRESSED_LISTS +# define COMPRESSED_LISTS +#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. */ +#ifndef CLOCK_STOPS +//# define CLOCK_STOPS +#endif +/* The switches in this group can only be enabled when running a simulation */ +#ifdef SIMULATION +/* Enables use of the key cache */ +# ifndef USE_RSA_KEY_CACHE +# define USE_RSA_KEY_CACHE +# endif +# if defined USE_RSA_KEY_CACHE && !defined USE_KEY_CACHE_FILE +# define USE_KEY_CACHE_FILE +# endif +# if !defined NDEBUG && !defined USE_DEBUG_RNG +/* 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. */ +# define USE_DEBUG_RNG +# endif +#else +# undef USE_RSA_KEY_CACHE +# undef USE_KEY_CACHE_FILE +# undef USE_DEBUG_RNG +# undef RSA_INSTRUMENT +#endif // SIMULATION +#ifndef NDEBUG +/* In some cases, the relationship between two values may be dependent on things that change based + on various selections like the chosen crypto 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. */ +#ifndef COMPILER_CHECKS +//# define COMPILER_CHECKS +#endif +/* Some of the values (such as sizes) are the result of different options set in + Implementation.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. */ +#ifndef RUNTIME_SIZE_CHECKS +#define RUNTIME_SIZE_CHECKS +#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) */ +#ifndef DRBG_DEBUG_PRINT +//# define DRBG_DEBUG_PRINT +#endif + +/* If an assertion event it not going to produce any trace information (function and line number) + then define NO_FAIL_TRACE */ +#ifndef NO_FAIL_TRACE +# define NO_FAIL_TRACE +#endif +#endif // NDEBUG +/* If the implementation is going to give lockout time credit for time up to the last orderly + shutdown, then uncomment this variable */ +#ifndef ACCUMULATE_SELF_HEAL_TIMER +#define ACCUMULATE_SELF_HEAL_TIMER +#endif // ACCUMULATE_SELF_HEAL_TIMER +#endif // _TPM_BUILD_SWITCHES_H_ + diff --git a/src/tpm2/TpmError.h b/src/tpm2/TpmError.h new file mode 100644 index 00000000..11d1fbb5 --- /dev/null +++ b/src/tpm2/TpmError.h @@ -0,0 +1,84 @@ +/********************************************************************************/ +/* */ +/* */ +/* Written by Ken Goldman */ +/* IBM Thomas J. Watson Research Center */ +/* $Id: TpmError.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 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 00000000..dd1911aa --- /dev/null +++ b/src/tpm2/TpmFail.c @@ -0,0 +1,413 @@ +/********************************************************************************/ +/* */ +/* */ +/* Written by Ken Goldman */ +/* IBM Thomas J. Watson Research Center */ +/* $Id: TpmFail.c 953 2017-03-06 20:31: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, 2017 */ +/* */ +/********************************************************************************/ + +/* 9.17 TpmFail.c */ +/* 9.17.1 Includes, Defines, and Types */ +#define TPM_FAIL_C +#include "Tpm.h" +#include +/* 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" +/* 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 + ) +{ + return UINT16_Marshal(&integer, buffer, NULL); +} +/* 9.17.3.2 MarshalUint32() */ +/* Function to marshal a 32 bit value to the output buffer. */ +static INT32 +MarshalUint32( + UINT32 integer, + BYTE **buffer + ) +{ + return UINT32_Marshal(&integer, buffer, NULL); +} +/* 9.17.3.3 UnmarshalHeader() */ +/* function to unmarshal the 10-byte command header. */ +static BOOL +UnmarshalHeader( + HEADER *header, + BYTE **buffer, + INT32 *size + ) +{ + UINT32 usize; + TPM_RC ucode; + if(UINT16_Unmarshal(&header->tag, buffer, size) != TPM_RC_SUCCESS + || UINT32_Unmarshal(&usize, buffer, size) != TPM_RC_SUCCESS + || UINT32_Unmarshal(&ucode, buffer, size) != TPM_RC_SUCCESS) + return FALSE; + header->size = usize; + header->code = ucode; + return TRUE; +} +/* 9.17.4 Public Functions */ +#ifdef SIMULATION +/* 9.17.4.1 SetForceFailureMode() */ +/* This function is called by the simulator to enable failure mode testing. */ +LIB_EXPORT void +SetForceFailureMode( + void + ) +{ + g_forceFailureMode = TRUE; + return; +} +#endif +/* 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( +#ifndef NO_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. +#ifndef NO_FAIL_TRACE + s_failFunction = *(UINT32*)&function; + s_failLine = line; +#else + s_failFunction = 0; /* kgold was 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. +#ifdef SIMULATION +# ifndef NDEBUG + assert(g_forceFailureMode); +# endif + // Clear this flag + g_forceFailureMode = FALSE; +#endif + // Jump to the failure mode code. + // Note: only get here if asserts are off or if we are testing failure mode + _plat__Fail(); +} +/* 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 + ) +{ + BYTE *buffer; + UINT32 marshalSize; + UINT32 capability; + HEADER header; // unmarshaled command header + UINT32 pt; // unmarshaled property type + UINT32 count; // unmarshaled property count + // 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; + buffer = inRequest; + if(!UnmarshalHeader(&header, &inRequest, (INT32 *)&inRequestSize)) + 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 + || TPM_RC_SUCCESS != UINT32_Unmarshal(&capability, &inRequest, + (INT32 *)&inRequestSize) + || capability != TPM_CAP_TPM_PROPERTIES + || TPM_RC_SUCCESS != UINT32_Unmarshal(&pt, &inRequest, + (INT32 *)&inRequestSize) + || TPM_RC_SUCCESS != UINT32_Unmarshal(&count, &inRequest, + (INT32 *)&inRequestSize)) + 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; +} +/* 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); +} diff --git a/src/tpm2/TpmFail_fp.h b/src/tpm2/TpmFail_fp.h new file mode 100644 index 00000000..2f509bfb --- /dev/null +++ b/src/tpm2/TpmFail_fp.h @@ -0,0 +1,94 @@ +/********************************************************************************/ +/* */ +/* */ +/* Written by Ken Goldman */ +/* IBM Thomas J. Watson Research Center */ +/* $Id: TpmFail_fp.h 953 2017-03-06 20:31: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 */ +/* */ +/********************************************************************************/ + +#ifndef TPMFAIL_FP_H +#define TPMFAIL_FP_H + +#include "BaseTypes.h" + +LIB_EXPORT void +SetForceFailureMode( + void + ); +NORETURN void +TpmFail( +#ifndef NO_FAIL_TRACE + 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 + ); +void +UnmarshalFail( + void *type, + BYTE **buffer, + INT32 *size + ); + + +#endif diff --git a/src/tpm2/TpmSizeChecks.c b/src/tpm2/TpmSizeChecks.c new file mode 100644 index 00000000..bc6f31c7 --- /dev/null +++ b/src/tpm2/TpmSizeChecks.c @@ -0,0 +1,71 @@ +/********************************************************************************/ +/* */ +/* */ +/* Written by Ken Goldman */ +/* IBM Thomas J. Watson Research Center */ +/* $Id: TpmSizeChecks.c 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 */ +/* */ +/********************************************************************************/ + +#include "TpmSizeChecks_fp.h" + +/* Some of the values (such as sizes) are the result of different options set in + Implementation.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. */ +void TpmSizeChecks(void) +{ + return; +} diff --git a/src/tpm2/TpmSizeChecks_fp.h b/src/tpm2/TpmSizeChecks_fp.h new file mode 100644 index 00000000..836f9d70 --- /dev/null +++ b/src/tpm2/TpmSizeChecks_fp.h @@ -0,0 +1,68 @@ +/********************************************************************************/ +/* */ +/* */ +/* Written by Ken Goldman */ +/* IBM Thomas J. Watson Research Center */ +/* $Id: TpmSizeChecks_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 TPMSIZECHECKS_FP_H +#define TPMSIZECHECKS_FP_H + +void TpmSizeChecks(void); + + +#endif diff --git a/src/tpm2/TpmTcpProtocol.h b/src/tpm2/TpmTcpProtocol.h new file mode 100644 index 00000000..3917b5ea --- /dev/null +++ b/src/tpm2/TpmTcpProtocol.h @@ -0,0 +1,127 @@ +/********************************************************************************/ +/* */ +/* TPM commands are communicated as BYTE streams on a TCP connection */ +/* Written by Ken Goldman */ +/* IBM Thomas J. Watson Research Center */ +/* $Id: TpmTcpProtocol.h 953 2017-03-06 20:31: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, 2017 */ +/* */ +/********************************************************************************/ + +/* D.2 TpmTcpProtocol.h */ +/* D.2.1. Introduction */ +/* TPM commands are communicated as BYTE 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 with one of the values below. Most commands take no parameters return no TPM errors. In + these cases the TPM interface protocol acknowledges that command processing is complete by + returning a UINT32=0. The command TPM_SIGNAL_HASH_DATA takes a UINT32-prepended variable length + BYTE array and the interface protocol acknowledges command completion with a UINT32=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=0 to the TPM response for + regularity. */ +/* D.2.2. Typedefs and Defines */ +#ifndef TCP_TPM_PROTOCOL_H +#define TCP_TPM_PROTOCOL_H +/* TPM Commands. All commands acknowledge processing by returning a UINT32 == 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 BufferSize, BYTE[BufferSize] Buffer} +#define TPM_SIGNAL_HASH_END 7 +#define TPM_SEND_COMMAND 8 + // {BYTE Locality, UINT32 InBufferSize, BYTE[InBufferSize] InBuffer} -> + // {UINT32 OutBufferSize, BYTE[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_TEST_FAILURE_MODE 30 + enum TpmEndPointInfo + { + tpmPlatformAvailable = 0x01, + tpmUsesTbs = 0x02, + tpmInRawMode = 0x04, + tpmSupportsPP = 0x08 + }; +// 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; +#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 00000000..15c3d918 --- /dev/null +++ b/src/tpm2/TpmTypes.h @@ -0,0 +1,1891 @@ +/********************************************************************************/ +/* */ +/* TPM Part 2 Headers */ +/* Written by Ken Goldman */ +/* IBM Thomas J. Watson Research Center */ +/* $Id: TpmTypes.h 953 2017-03-06 20:31: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, 2017 */ +/* */ +/********************************************************************************/ + +#ifndef TPMTYPES_H +#define TPMTYPES_H + +#include "BaseTypes.h" /* kgold */ +#include "Implementation.h" /* kgold */ +#include "GpMacros.h" +#include "Capabilities.h" + +/* Table 2:5 - Definition of Types for Documentation Clarity (TypedefTable()) */ +typedef UINT32 TPM_ALGORITHM_ID; +typedef UINT32 TPM_MODIFIER_INDICATOR; +typedef UINT32 TPM_AUTHORIZATION_SIZE; +typedef UINT32 TPM_PARAMETER_SIZE; +typedef UINT16 TPM_KEY_SIZE; +typedef UINT16 TPM_KEY_BITS; +/* Table 2:6 - Definition of TPM_SPEC Constants (EnumTable()) */ +typedef UINT32 TPM_SPEC; +#define SPEC_FAMILY 0x322E3000 +#define TPM_SPEC_FAMILY (TPM_SPEC)(SPEC_FAMILY) +#define SPEC_LEVEL 00 +#define TPM_SPEC_LEVEL (TPM_SPEC)(SPEC_LEVEL) +#define SPEC_VERSION 142 +#define TPM_SPEC_VERSION (TPM_SPEC)(SPEC_VERSION) +#define SPEC_YEAR 2017 +#define TPM_SPEC_YEAR (TPM_SPEC)(SPEC_YEAR) +#define SPEC_DAY_OF_YEAR 35 +#define TPM_SPEC_DAY_OF_YEAR (TPM_SPEC)(SPEC_DAY_OF_YEAR) +/* Table 2:7 - Definition of TPM_GENERATED Constants (EnumTable()) */ +typedef UINT32 TPM_GENERATED; +#define TPM_GENERATED_VALUE (TPM_GENERATED)(0xFF544347) +/* Table 2:16 - Definition of TPM_RC Constants (EnumTable()) */ +typedef UINT32 TPM_RC; +#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 (EnumTable()) */ +typedef INT8 TPM_CLOCK_ADJUST; +#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 (EnumTable()) */ +typedef UINT16 TPM_EO; +#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 (EnumTable()) */ +typedef UINT16 TPM_ST; +#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_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 (EnumTable()) */ +typedef UINT16 TPM_SU; +#define TPM_SU_CLEAR (TPM_SU)(0x0000) +#define TPM_SU_STATE (TPM_SU)(0x0001) +/* Table 2:21 - Definition of TPM_SE Constants (EnumTable()) */ +typedef UINT8 TPM_SE; +#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 (EnumTable()) */ +typedef UINT32 TPM_CAP; +#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_LAST (TPM_CAP)(0x00000009) +#define TPM_CAP_VENDOR_PROPERTY (TPM_CAP)(0x00000100) +/* Table 2:23 - Definition of TPM_PT Constants (EnumTable()) */ +typedef UINT32 TPM_PT; +#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 (EnumTable()) */ +typedef UINT32 TPM_PT_PCR; +#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 (EnumTable()) */ +typedef UINT32 TPM_PS; +#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 (TypedefTable()) */ +typedef UINT32 TPM_HANDLE; +/* Table 2:27 - Definition of TPM_HT Constants (EnumTable()) */ +typedef UINT8 TPM_HT; +#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 (EnumTable()) */ +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_LAST (TPM_RH)(0x4000010F) +/* Table 2:29 - Definition of TPM_HC Constants (EnumTable()) */ +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< */ +typedef union { + struct { + UINT16 size; + BYTE credential[sizeof(TPMS_ID_OBJECT)]; + } t; + TPM2B b; +} TPM2B_ID_OBJECT; +/* Table 2:202 - Definition of TPM_NV_INDEX Bits (BitsTable()) */ +typedef struct { + unsigned index : 24; + unsigned RH_NV : 8 ; +} TPM_NV_INDEX; +/* Table 2:203 - Definition of TPM_NT Constants (EnumTable()) */ +typedef UINT32 TPM_NT; +#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:204 - Definition of TPMS_NV_PIN_COUNTER_PARAMETERS Structure (StructuresTable()) */ +typedef struct { + UINT32 pinCount; + UINT32 pinLimit; +} TPMS_NV_PIN_COUNTER_PARAMETERS; +/* Table 2:205 - Definition of TPMA_NV Bits (BitsTable()) */ +typedef union { + struct { + unsigned TPMA_NV_PPWRITE : 1 ; + unsigned TPMA_NV_OWNERWRITE : 1 ; + unsigned TPMA_NV_AUTHWRITE : 1 ; + unsigned TPMA_NV_POLICYWRITE : 1 ; + unsigned TPM_NT : 4 ; + unsigned Reserved_at_bit_8 : 2 ; + unsigned TPMA_NV_POLICY_DELETE : 1 ; + unsigned TPMA_NV_WRITELOCKED : 1 ; + unsigned TPMA_NV_WRITEALL : 1 ; + unsigned TPMA_NV_WRITEDEFINE : 1 ; + unsigned TPMA_NV_WRITE_STCLEAR : 1 ; + unsigned TPMA_NV_GLOBALLOCK : 1 ; + unsigned TPMA_NV_PPREAD : 1 ; + unsigned TPMA_NV_OWNERREAD : 1 ; + unsigned TPMA_NV_AUTHREAD : 1 ; + unsigned TPMA_NV_POLICYREAD : 1 ; + unsigned Reserved_at_bit_20 : 5 ; + unsigned TPMA_NV_NO_DA : 1 ; + unsigned TPMA_NV_ORDERLY : 1 ; + unsigned TPMA_NV_CLEAR_STCLEAR : 1 ; + unsigned TPMA_NV_READLOCKED : 1 ; + unsigned TPMA_NV_WRITTEN : 1 ; + unsigned TPMA_NV_PLATFORMCREATE : 1 ; + unsigned TPMA_NV_READ_STCLEAR : 1 ; + }; + UINT32 val; +} TPMA_NV; + +#define TPMA_NVA_PPWRITE 0x00000001 +#define TPMA_NVA_OWNERWRITE 0x00000002 +#define TPMA_NVA_AUTHWRITE 0x00000004 +#define TPMA_NVA_POLICYWRITE 0x00000008 +#define TPMA_NVA_ORDINARY 0x00000000 +#define TPMA_NVA_COUNTER 0x00000010 +#define TPMA_NVA_BITS 0x00000020 +#define TPMA_NVA_EXTEND 0x00000040 +#define TPMA_NVA_PIN_FAIL 0x00000080 +#define TPMA_NVA_PIN_PASS 0x00000090 +#define TPMA_NVA_RESERVED1 0x00000300 +#define TPMA_NVA_POLICY_DELETE 0x00000400 +#define TPMA_NVA_WRITELOCKED 0x00000800 +#define TPMA_NVA_WRITEALL 0x00001000 +#define TPMA_NVA_WRITEDEFINE 0x00002000 +#define TPMA_NVA_WRITE_STCLEAR 0x00004000 +#define TPMA_NVA_GLOBALLOCK 0x00008000 +#define TPMA_NVA_PPREAD 0x00010000 +#define TPMA_NVA_OWNERREAD 0x00020000 +#define TPMA_NVA_AUTHREAD 0x00040000 +#define TPMA_NVA_POLICYREAD 0x00080000 +#define TPMA_NVA_RESERVED2 0x01f00000 +#define TPMA_NVA_NO_DA 0x02000000 +#define TPMA_NVA_ORDERLY 0x04000000 +#define TPMA_NVA_CLEAR_STCLEAR 0x08000000 +#define TPMA_NVA_READLOCKED 0x10000000 +#define TPMA_NVA_WRITTEN 0x20000000 +#define TPMA_NVA_PLATFORMCREATE 0x40000000 +#define TPMA_NVA_READ_STCLEAR 0x80000000 + +#define TPMA_NVA_TPM_NT_MASK 0x000000f0 +#define TPMA_NV_RESERVED (TPMA_NVA_RESERVED1 | TPMA_NVA_RESERVED2) + +#define IsNv_TPMA_NV_PPWRITE(attribute) \ + ((attribute.TPMA_NV_PPWRITE) != 0) +#define IsNv_TPMA_NV_OWNERWRITE(attribute) \ + ((attribute.TPMA_NV_OWNERWRITE) != 0) +#define IsNv_TPMA_NV_AUTHWRITE(attribute) \ + ((attribute.TPMA_NV_AUTHWRITE) != 0) +#define IsNv_TPMA_NV_POLICYWRITE(attribute) \ + ((attribute.TPMA_NV_POLICYWRITE) != 0) +#define IsNv_TPMA_NV_POLICY_DELETE(attribute) \ + ((attribute.TPMA_NV_POLICY_DELETE) != 0) +#define IsNv_TPMA_NV_WRITELOCKED(attribute) \ + ((attribute.TPMA_NV_WRITELOCKED) != 0) +#define IsNv_TPMA_NV_WRITEALL(attribute) \ + ((attribute.TPMA_NV_WRITEALL) != 0) +#define IsNv_TPMA_NV_WRITEDEFINE(attribute) \ + ((attribute.TPMA_NV_WRITEDEFINE) != 0) +#define IsNv_TPMA_NV_WRITE_STCLEAR(attribute) \ + ((attribute.TPMA_NV_WRITE_STCLEAR) != 0) +#define IsNv_TPMA_NV_GLOBALLOCK(attribute) \ + ((attribute.TPMA_NV_GLOBALLOCK) != 0) +#define IsNv_TPMA_NV_PPREAD(attribute) \ + ((attribute.TPMA_NV_PPREAD) != 0) +#define IsNv_TPMA_NV_OWNERREAD(attribute) \ + ((attribute.TPMA_NV_OWNERREAD) != 0) +#define IsNv_TPMA_NV_AUTHREAD(attribute) \ + ((attribute.TPMA_NV_AUTHREAD) != 0) +#define IsNv_TPMA_NV_POLICYREAD(attribute) \ + ((attribute.TPMA_NV_POLICYREAD) != 0) +#define IsNv_TPMA_NV_NO_DA(attribute) \ + ((attribute.TPMA_NV_NO_DA) != 0) +#define IsNv_TPMA_NV_ORDERLY(attribute) \ + ((attribute.TPMA_NV_ORDERLY) != 0) +#define IsNv_TPMA_NV_CLEAR_STCLEAR(attribute) \ + ((attribute.TPMA_NV_CLEAR_STCLEAR) != 0) +#define IsNv_TPMA_NV_READLOCKED(attribute) \ + ((attribute.TPMA_NV_READLOCKED) != 0) +#define IsNv_TPMA_NV_WRITTEN(attribute) \ + ((attribute.TPMA_NV_WRITTEN) != 0) +#define IsNv_TPMA_NV_PLATFORMCREATE(attribute) \ + ((attribute.TPMA_NV_PLATFORMCREATE) != 0) +#define IsNv_TPMA_NV_READ_STCLEAR(attribute) \ + ((attribute.TPMA_NV_READ_STCLEAR) != 0) +/* Table 2:206 - Definition of TPMS_NV_PUBLIC Structure (StructuresTable()) */ +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 (StructuresTable()) */ +typedef struct { + UINT16 size; + TPMS_NV_PUBLIC nvPublic; +} TPM2B_NV_PUBLIC; +/* Table 2:208 - Definition of TPM2B_CONTEXT_SENSITIVE Structure (StructuresTable()) */ +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 (StructuresTable()) */ +typedef struct { + TPM2B_DIGEST integrity; + TPM2B_CONTEXT_SENSITIVE encrypted; +} TPMS_CONTEXT_DATA; +/* Table 2:210 - Definition of TPM2B_CONTEXT_DATA Structure (StructuresTable()) */ +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 (StructuresTable()) */ +typedef struct { + UINT64 sequence; + TPMI_DH_CONTEXT savedHandle; + TPMI_RH_HIERARCHY hierarchy; + TPM2B_CONTEXT_DATA contextBlob; +} TPMS_CONTEXT; +/* Table 2:213 - Definition of TPMS_CREATION_DATA Structure (StructuresTable()) */ +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 (StructuresTable()) */ +typedef struct { + UINT16 size; + TPMS_CREATION_DATA creationData; +} TPM2B_CREATION_DATA; +/* Table 2:215 - Definition of TPM_AT Constants (EnumTable()) */ +typedef UINT32 TPM_AT; +#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:216 - Definition of TPM_AE Constants (EnumTable()) */ +typedef UINT32 TPM_AE; +#define TPM_AE_NONE (TPM_AE)(0x00000000) +/* Table 2:217 - Definition of TPMS_AC_OUTPUT Structure (StructuresTable()) */ +typedef struct { + TPM_AT tag; + UINT32 data; +} TPMS_AC_OUTPUT; +#ifdef TPM_CC_AC_GetCapability +/* Table 2:218 - Definition of TPML_AC_CAPABILITIES Structure (StructuresTable()) */ +typedef struct { + UINT32 count; + TPMS_AC_OUTPUT acCapabilities[MAX_AC_CAPABILITIES]; +} TPML_AC_CAPABILITIES; +#endif + +#endif diff --git a/src/tpm2/Unique.c b/src/tpm2/Unique.c new file mode 100644 index 00000000..a2397550 --- /dev/null +++ b/src/tpm2/Unique.c @@ -0,0 +1,110 @@ +/********************************************************************************/ +/* */ +/* */ +/* Written by Ken Goldman */ +/* IBM Thomas J. Watson Research Center */ +/* $Id: Unique.c 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 */ +/* */ +/********************************************************************************/ + +/* 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 "PlatformData.h" +#include "Platform_fp.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 00000000..41ada567 --- /dev/null +++ b/src/tpm2/Unmarshal.c @@ -0,0 +1,4325 @@ +/********************************************************************************/ +/* */ +/* Parameter Unmarshaling */ +/* Written by Ken Goldman */ +/* IBM Thomas J. Watson Research Center */ +/* $Id: Unmarshal.c 953 2017-03-06 20:31:40Z kgoldman $ */ +/* */ +/* (c) Copyright IBM Corporation 2015, 2016 */ +/* */ +/* 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 + +/* TSS needs TPM_TSS for TSS side structures */ +#include "Unmarshal_fp.h" + +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 +INT32_Unmarshal(INT32 *target, BYTE **buffer, INT32 *size) +{ + return UINT32_Unmarshal((UINT32 *)target, buffer, size); +} + + +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; + } + } + 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 */ + +TPM_RC +TPM_GENERATED_Unmarshal(TPM_GENERATED *target, BYTE **buffer, INT32 *size) +{ + TPM_RC rc = TPM_RC_SUCCESS; + + 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; + } + } + return rc; +} + +/* Table 9 - Definition of (UINT16) TPM_ALG_ID Constants */ + +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 */ + +#ifdef TPM_ALG_ECC +TPM_RC +TPM_ECC_CURVE_Unmarshal(TPM_ECC_CURVE *target, BYTE **buffer, INT32 *size) +{ + TPM_RC rc = TPM_RC_SUCCESS; + + 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; + } + } + return rc; +} +#endif + +/* Table 13 - Definition of (UINT32) TPM_CC Constants (Numeric Order) */ + +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 17 - Definition of (UINT32) TPM_RC Constants (Actions) */ + +TPM_RC +TPM_RC_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 */ + +TPM_RC +TPM_CLOCK_ADJUST_Unmarshal(TPM_CLOCK_ADJUST *target, BYTE **buffer, INT32 *size) +{ + TPM_RC rc = TPM_RC_SUCCESS; + + 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; + } + } + return rc; +} + +/* Table 19 - Definition of (UINT16) TPM_EO Constants */ + +TPM_RC +TPM_EO_Unmarshal(TPM_EO *target, BYTE **buffer, INT32 *size) +{ + TPM_RC rc = TPM_RC_SUCCESS; + + 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; + } + } + return rc; +} + +/* Table 20 - Definition of (UINT16) TPM_ST Constants */ + +TPM_RC +TPM_ST_Unmarshal(TPM_ST *target, BYTE **buffer, INT32 *size) +{ + TPM_RC rc = TPM_RC_SUCCESS; + + 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; + } + } + return rc; +} + +/* Table 20 - Definition of (UINT16) TPM_SU Constants */ + +TPM_RC +TPM_SU_Unmarshal(TPM_SU *target, BYTE **buffer, INT32 *size) +{ + TPM_RC rc = TPM_RC_SUCCESS; + + 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; + } + } + return rc; +} + +/* Table 21 - Definition of (UINT8) TPM_SE Constants */ + +TPM_RC +TPM_SE_Unmarshal(TPM_SE *target, BYTE **buffer, INT32 *size) +{ + TPM_RC rc = TPM_RC_SUCCESS; + + 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; + } + } + 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; + + 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_VENDOR_PROPERTY: + break; + default: + rc = TPM_RC_VALUE; + } + } + return rc; +} + +/* Table 24 - Definition of (UINT32) TPM_PT Constants */ + +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 */ + +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; + + if (rc == TPM_RC_SUCCESS) { + rc = UINT32_Unmarshal((UINT32 *)target, buffer, size); + } + if (rc == TPM_RC_SUCCESS) { + if (*(UINT32 *)target & TPMA_ALGORITHM_RESERVED) { + rc = TPM_RC_RESERVED_BITS; + } + } + 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; + + if (rc == TPM_RC_SUCCESS) { + rc = UINT32_Unmarshal((UINT32 *)target, buffer, size); + } + if (rc == TPM_RC_SUCCESS) { + if (*(UINT32 *)target & TPMA_OBJECT_RESERVED) { + rc = TPM_RC_RESERVED_BITS; + } + } + return rc; +} + +/* Table 33 - Definition of (UINT8) TPMA_SESSION Bits */ + +TPM_RC +TPMA_SESSION_Unmarshal(TPMA_SESSION *target, BYTE **buffer, INT32 *size) +{ + TPM_RC rc = TPM_RC_SUCCESS; + + if (rc == TPM_RC_SUCCESS) { + rc = UINT8_Unmarshal(&target->val, buffer, size); + } + if (rc == TPM_RC_SUCCESS) { + if (target->val & TPMA_SESSION_RESERVED) { + rc = TPM_RC_RESERVED_BITS; + } + } + return rc; +} + +/* Table 34 - Definition of (UINT8) TPMA_LOCALITY Bits */ + +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(&target->val, buffer, size); + } + return rc; +} + +/* Table 38 - Definition of (TPM_CC) TPMA_CC Bits */ + +TPM_RC +TPMA_CC_Unmarshal(TPMA_CC *target, BYTE **buffer, INT32 *size) +{ + TPM_RC rc = TPM_RC_SUCCESS; + + if (rc == TPM_RC_SUCCESS) { + rc = UINT32_Unmarshal((UINT32 *)target, buffer, size); + } + if (rc == TPM_RC_SUCCESS) { + if (*(UINT32 *)target & TPMA_CC_RESERVED) { + rc = TPM_RC_RESERVED_BITS; + } + } + 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; + + 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; + } + } + 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; + + 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; + } + } + 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; + + 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; + } + } + 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; + + 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; + } + } + return rc; +} + +/* Table 42 - Definition of (TPM_HANDLE) TPMI_DH_ENTITY Type */ + +TPM_RC +TPMI_DH_ENTITY_Unmarshal(TPMI_DH_ENTITY *target, BYTE **buffer, INT32 *size, BOOL allowNull) +{ + TPM_RC rc = TPM_RC_SUCCESS; + + 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; + } + } + return rc; +} + +/* Table 43 - Definition of (TPM_HANDLE) TPMI_DH_PCR Type */ + +TPM_RC +TPMI_DH_PCR_Unmarshal(TPMI_DH_PCR *target, BYTE **buffer, INT32 *size, BOOL allowNull) +{ + TPM_RC rc = TPM_RC_SUCCESS; + + 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; + } + } + return rc; +} + +/* Table 44 - Definition of (TPM_HANDLE) TPMI_SH_AUTH_SESSION Type */ + +TPM_RC +TPMI_SH_AUTH_SESSION_Unmarshal(TPMI_SH_AUTH_SESSION *target, BYTE **buffer, INT32 *size, BOOL allowPwd) +{ + TPM_RC rc = TPM_RC_SUCCESS; + + 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; + } + } + return rc; +} + +/* Table 45 - Definition of (TPM_HANDLE) TPMI_SH_HMAC Type */ + +TPM_RC +TPMI_SH_HMAC_Unmarshal(TPMI_SH_HMAC *target, BYTE **buffer, INT32 *size, BOOL allowNull) +{ + TPM_RC rc = TPM_RC_SUCCESS; + 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); + if (isNotHmacSession) { + rc = TPM_RC_VALUE; + } + } + return rc; +} + +/* Table 46 - Definition of (TPM_HANDLE) TPMI_SH_POLICY Type */ + +TPM_RC +TPMI_SH_POLICY_Unmarshal(TPMI_SH_POLICY *target, BYTE **buffer, INT32 *size, BOOL allowNull) +{ + TPM_RC rc = TPM_RC_SUCCESS; + allowNull = allowNull; + + 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; + } + } + 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, BOOL allowNull) +{ + TPM_RC rc = TPM_RC_SUCCESS; + 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 isNotTransient = (*target < TRANSIENT_FIRST) || (*target > TRANSIENT_LAST); + if (isNotHmacSession && + isNotPolicySession && + isNotTransient) { + rc = TPM_RC_VALUE; + } + } + 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; + + 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; + } + } + 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; + + 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; + } + } + return rc; +} + +/* Table 50 - Definition of (TPM_HANDLE) TPMI_RH_HIERARCHY_AUTH Type */ + +TPM_RC +TPMI_RH_HIERARCHY_AUTH_Unmarshal(TPMI_RH_HIERARCHY_AUTH *target, BYTE **buffer, INT32 *size, BOOL allowNull) +{ + TPM_RC rc = TPM_RC_SUCCESS; + allowNull = allowNull; + + 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; + } + } + return rc; +} + +/* Table 51 - Definition of (TPM_HANDLE) TPMI_RH_PLATFORM Type */ + +TPM_RC +TPMI_RH_PLATFORM_Unmarshal(TPMI_RH_PLATFORM *target, BYTE **buffer, INT32 *size, BOOL allowNull) +{ + TPM_RC rc = TPM_RC_SUCCESS; + allowNull = allowNull; + + 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; + } + } + return rc; +} + +/* Table 53 - Definition of (TPM_HANDLE) TPMI_RH_ENDORSEMENT Type */ + +TPM_RC +TPMI_RH_ENDORSEMENT_Unmarshal(TPMI_RH_ENDORSEMENT *target, BYTE **buffer, INT32 *size, BOOL allowNull) +{ + TPM_RC rc = TPM_RC_SUCCESS; + + 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; + } + } + return rc; +} + +/* Table 54 - Definition of (TPM_HANDLE) TPMI_RH_PROVISION Type */ + +TPM_RC +TPMI_RH_PROVISION_Unmarshal(TPMI_RH_PROVISION *target, BYTE **buffer, INT32 *size, BOOL allowNull) +{ + TPM_RC rc = TPM_RC_SUCCESS; + allowNull = allowNull; + + 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; + } + } + return rc; +} + +/* Table 55 - Definition of (TPM_HANDLE) TPMI_RH_CLEAR Type */ + +TPM_RC +TPMI_RH_CLEAR_Unmarshal(TPMI_RH_CLEAR *target, BYTE **buffer, INT32 *size, BOOL allowNull) +{ + TPM_RC rc = TPM_RC_SUCCESS; + allowNull = allowNull; + + 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; + } + } + return rc; +} + +/* Table 56 - Definition of (TPM_HANDLE) TPMI_RH_NV_AUTH Type */ + +TPM_RC +TPMI_RH_NV_AUTH_Unmarshal(TPMI_RH_NV_AUTH *target, BYTE **buffer, INT32 *size, BOOL allowNull) +{ + TPM_RC rc = TPM_RC_SUCCESS; + allowNull = allowNull; + + 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; + } + } + } + } + return rc; +} + +/* Table 57 - Definition of (TPM_HANDLE) TPMI_RH_LOCKOUT Type */ + +TPM_RC +TPMI_RH_LOCKOUT_Unmarshal(TPMI_RH_LOCKOUT *target, BYTE **buffer, INT32 *size, BOOL allowNull) +{ + TPM_RC rc = TPM_RC_SUCCESS; + allowNull = allowNull; + + 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; + } + } + return rc; +} + +/* Table 58 - Definition of (TPM_HANDLE) TPMI_RH_NV_INDEX Type */ + +TPM_RC +TPMI_RH_NV_INDEX_Unmarshal(TPMI_RH_NV_INDEX *target, BYTE **buffer, INT32 *size, BOOL allowNull) +{ + TPM_RC rc = TPM_RC_SUCCESS; + allowNull = allowNull; + + 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; + } + } + 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; + + if (rc == TPM_RC_SUCCESS) { + rc = TPM_ALG_ID_Unmarshal(target, buffer, size); + } + if (rc == TPM_RC_SUCCESS) { + switch (*target) { +#ifdef TPM_ALG_SHA1 + case TPM_ALG_SHA1: +#endif +#ifdef TPM_ALG_SHA256 + case TPM_ALG_SHA256: +#endif +#ifdef TPM_ALG_SHA384 + case TPM_ALG_SHA384: +#endif +#ifdef TPM_ALG_SHA512 + case TPM_ALG_SHA512: +#endif +#ifdef TPM_ALG_SM3_256 + case TPM_ALG_SM3_256: +#endif + break; + case TPM_ALG_NULL: + if (allowNull) { + break; + } + default: + rc = TPM_RC_HASH; + } + } + 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; + + if (rc == TPM_RC_SUCCESS) { + rc = TPM_ALG_ID_Unmarshal(target, buffer, size); + } + if (rc == TPM_RC_SUCCESS) { + switch (*target) { +#ifdef TPM_ALG_AES + case TPM_ALG_AES: +#endif +#ifdef TPM_ALG_SM4 + case TPM_ALG_SM4: +#endif +#ifdef TPM_ALG_CAMELLIA + case TPM_ALG_CAMELLIA: +#endif +#ifdef TPM_ALG_XOR + case TPM_ALG_XOR: +#endif + break; + case TPM_ALG_NULL: + if (allowNull) { + break; + } + default: + rc = TPM_RC_SYMMETRIC; + } + } + 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; + + if (rc == TPM_RC_SUCCESS) { + rc = TPM_ALG_ID_Unmarshal(target, buffer, size); + } + if (rc == TPM_RC_SUCCESS) { + switch (*target) { +#ifdef TPM_ALG_AES + case TPM_ALG_AES: +#endif +#ifdef TPM_ALG_SM4 + case TPM_ALG_SM4: +#endif +#ifdef TPM_ALG_CAMELLIA + case TPM_ALG_CAMELLIA: +#endif + break; + case TPM_ALG_NULL: + if (allowNull) { + break; + } + default: + rc = TPM_RC_SYMMETRIC; + } + } + 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; + + if (rc == TPM_RC_SUCCESS) { + rc = TPM_ALG_ID_Unmarshal(target, buffer, size); + } + if (rc == TPM_RC_SUCCESS) { + switch (*target) { +#ifdef TPM_ALG_CTR + case TPM_ALG_CTR: +#endif +#ifdef TPM_ALG_OFB + case TPM_ALG_OFB: +#endif +#ifdef TPM_ALG_CBC + case TPM_ALG_CBC: +#endif +#ifdef TPM_ALG_CFB + case TPM_ALG_CFB: +#endif +#ifdef TPM_ALG_ECB + case TPM_ALG_ECB: +#endif + break; + case TPM_ALG_NULL: + if (allowNull) { + break; + } + default: + rc = TPM_RC_MODE; + } + } + 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; + + if (rc == TPM_RC_SUCCESS) { + rc = TPM_ALG_ID_Unmarshal(target, buffer, size); + } + if (rc == TPM_RC_SUCCESS) { + switch (*target) { +#ifdef TPM_ALG_MGF1 + case TPM_ALG_MGF1: +#endif +#ifdef TPM_ALG_KDF1_SP800_56A + case TPM_ALG_KDF1_SP800_56A: +#endif +#ifdef TPM_ALG_KDF2 + case TPM_ALG_KDF2: +#endif +#ifdef TPM_ALG_KDF1_SP800_108 + case TPM_ALG_KDF1_SP800_108: +#endif + break; + case TPM_ALG_NULL: + if (allowNull) { + break; + } + default: + rc = TPM_RC_KDF; + } + } + 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; + + if (rc == TPM_RC_SUCCESS) { + rc = TPM_ALG_ID_Unmarshal(target, buffer, size); + } + if (rc == TPM_RC_SUCCESS) { + switch (*target) { +#ifdef TPM_ALG_HMAC + case TPM_ALG_HMAC: +#endif +#ifdef TPM_ALG_RSASSA + case TPM_ALG_RSASSA: +#endif +#ifdef TPM_ALG_RSAPSS + case TPM_ALG_RSAPSS: +#endif +#ifdef TPM_ALG_ECDSA + case TPM_ALG_ECDSA: +#endif +#ifdef TPM_ALG_ECDAA + case TPM_ALG_ECDAA: +#endif +#ifdef TPM_ALG_SM2 + case TPM_ALG_SM2: +#endif +#ifdef TPM_ALG_ECSCHNORR + case TPM_ALG_ECSCHNORR: +#endif + break; + case TPM_ALG_NULL: + if (allowNull) { + break; + } + default: + rc = TPM_RC_SCHEME; + } + } + 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; + + if (rc == TPM_RC_SUCCESS) { + rc = TPM_ALG_ID_Unmarshal(target, buffer, size); + } + if (rc == TPM_RC_SUCCESS) { + switch (*target) { +#ifdef TPM_ALG_ECDH + case TPM_ALG_ECDH: +#endif +#ifdef TPM_ALG_ECMQV + case TPM_ALG_ECMQV: +#endif +#ifdef TPM_ALG_SM2 + case TPM_ALG_SM2: +#endif + break; + case TPM_ALG_NULL: + if (allowNull) { + break; + } + default: + rc = TPM_RC_SCHEME; + } + } + 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; + + 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; + } + } + return rc; +} + +/* Table 68 - Definition of TPMS_EMPTY Structure */ + +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 */ + +TPM_RC +TPMU_HA_Unmarshal(TPMU_HA *target, BYTE **buffer, INT32 *size, UINT32 selector) +{ + TPM_RC rc = TPM_RC_SUCCESS; + + switch (selector) { +#ifdef TPM_ALG_SHA1 + case TPM_ALG_SHA1: + rc = Array_Unmarshal(target->sha1, SHA1_DIGEST_SIZE, buffer, size); + break; +#endif +#ifdef TPM_ALG_SHA256 + case TPM_ALG_SHA256: + rc = Array_Unmarshal(target->sha256, SHA256_DIGEST_SIZE, buffer, size); + break; +#endif +#ifdef TPM_ALG_SHA384 + case TPM_ALG_SHA384: + rc = Array_Unmarshal(target->sha384, SHA384_DIGEST_SIZE, buffer, size); + break; +#endif +#ifdef TPM_ALG_SHA512 + case TPM_ALG_SHA512: + rc = Array_Unmarshal(target->sha512, SHA512_DIGEST_SIZE, buffer, size); + break; +#endif +#ifdef TPM_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 */ + +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 76 - Definition of Types for TPM2B_OPERAND */ + +TPM_RC +TPM2B_OPERAND_Unmarshal(TPM2B_OPERAND *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 */ + +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_DIGEST_Unmarshal(target, buffer, size); + } + return rc; +} + +/* Table 81 - Definition of TPM2B_IV Structure */ + +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; + } + } + 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; + + 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; + } + } + 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; + + 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; + } + } + 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; + + 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; + } + } + 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; + + 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; + } + } + 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 */ + +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; +} + +/* Table 93 - Definition of TPMS_TAGGED_PROPERTY Structure */ + +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; +} + +/* Table 94 - Definition of TPMS_TAGGED_PCR_SELECT Structure */ + +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; +} + +/* 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; + } + } + 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()) */ + +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; +} + +/* Table 96 - Definition of TPML_CCA Structure */ + +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; + } + } + for (i = 0 ; (rc == TPM_RC_SUCCESS) && (i < target->count) ; i++) { + rc = TPMA_CC_Unmarshal(&target->commandAttributes[i], buffer, size); + } + return rc; +} + +/* 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; + } + } + 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 */ + +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; + } + } + for (i = 0 ; (rc == TPM_RC_SUCCESS) && (i < target->count) ; i++) { + rc = TPM_HANDLE_Unmarshal(&target->handle[i], buffer, size); + } + return rc; +} + +/* 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 +#ifdef TPM_TSS + , uint32_t minCount +#endif + ) +{ + 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) { +#ifdef TPM_TSS + /* TSS side permits the caller to specify the minimum */ + if (target->count < minCount) { + rc = TPM_RC_SIZE; + } +#else + /* TPM side is hard coded to 2 minimum */ + if (target->count < 2) { + rc = TPM_RC_SIZE; + } +#endif + } + if (rc == TPM_RC_SUCCESS) { + if (target->count > 8) { + rc = TPM_RC_SIZE; + } + } + 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; + } + } + 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; + } + } + for (i = 0 ; (rc == TPM_RC_SUCCESS) && (i < target->count) ; i++) { + rc = TPMS_PCR_SELECTION_Unmarshal(&target->pcrSelections[i], buffer, size); + } + return rc; +} + +/* Table 103 - Definition of TPML_ALG_PROPERTY Structure */ + +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; + } + } + 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 */ + +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; + } + } + 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 */ + +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; + } + } + 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 */ + +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; + } + } + 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; + } + } + 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 */ + +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 */ + +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 */ + +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 */ + +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 */ + +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 */ + +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 */ + +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 */ + +TPM_RC +TPMI_ST_ATTEST_Unmarshal(TPMI_ST_ATTEST *target, BYTE **buffer, INT32 *size) +{ + TPM_RC rc = TPM_RC_SUCCESS; + + 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; + } + } + return rc; +} + +/* Table 119 - Definition of TPMU_ATTEST Union */ + +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 */ + +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 */ + +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; +} + +/* Table 123 - Definition of TPMS_AUTH_RESPONSE Structure */ + +TPM_RC +TPMS_AUTH_RESPONSE_Unmarshal(TPMS_AUTH_RESPONSE *target, BYTE **buffer, INT32 *size) +{ + TPM_RC rc = TPM_RC_SUCCESS; + + if (rc == TPM_RC_SUCCESS) { + rc = TPM2B_NONCE_Unmarshal(&target->nonce, buffer, size); + } + if (rc == TPM_RC_SUCCESS) { + rc = TPMA_SESSION_Unmarshal(&target->sessionAttributes, buffer, size); + } + if (rc == TPM_RC_SUCCESS) { + rc = TPM2B_AUTH_Unmarshal(&target->hmac, buffer, size); + } + return rc; +} + +/* Table 124 - Definition of {!ALG.S} (TPM_KEY_BITS) TPMI_!ALG.S_KEY_BITS Type */ + +#ifdef TPM_ALG_AES +TPM_RC +TPMI_AES_KEY_BITS_Unmarshal(TPMI_AES_KEY_BITS *target, BYTE **buffer, INT32 *size) +{ + TPM_RC rc = TPM_RC_SUCCESS; + + if (rc == TPM_RC_SUCCESS) { + rc = TPM_KEY_BITS_Unmarshal(target, buffer, size); + } + if (rc == TPM_RC_SUCCESS) { + switch (*target) { + case 128: + case 256: + break; + default: + rc = TPM_RC_VALUE; + } + } + return rc; +} +#endif + +#ifdef TPM_ALG_CAMELLIA +TPM_RC +TPMI_CAMELLIA_KEY_BITS_Unmarshal(TPMI_CAMELLIA_KEY_BITS *target, BYTE **buffer, INT32 *size) +{ + TPM_RC rc = TPM_RC_SUCCESS; + + 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; + } + } + return rc; +} +#endif + +#ifdef TPM_ALG_SM4 +TPM_RC +TPMI_SM4_KEY_BITS_Unmarshal(TPMI_SM4_KEY_BITS *target, BYTE **buffer, INT32 *size) +{ + TPM_RC rc = TPM_RC_SUCCESS; + + 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; + } + } + return rc; +} +#endif + +/* 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) { +#ifdef TPM_ALG_AES + case TPM_ALG_AES: + rc = TPMI_AES_KEY_BITS_Unmarshal(&target->aes, buffer, size); + break; +#endif +#ifdef TPM_ALG_SM4 + case TPM_ALG_SM4: + rc = TPMI_SM4_KEY_BITS_Unmarshal(&target->sm4, buffer, size); + break; +#endif +#ifdef TPM_ALG_CAMELLIA + case TPM_ALG_CAMELLIA: + rc = TPMI_CAMELLIA_KEY_BITS_Unmarshal(&target->camellia, buffer, size); + break; +#endif +#ifdef TPM_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) { +#ifdef TPM_ALG_AES + case TPM_ALG_AES: + rc = TPMI_ALG_SYM_MODE_Unmarshal(&target->aes, buffer, size, YES); + break; +#endif +#ifdef TPM_ALG_SM4 + case TPM_ALG_SM4: + rc = TPMI_ALG_SYM_MODE_Unmarshal(&target->sm4, buffer, size, YES); + break; +#endif +#ifdef TPM_ALG_CAMELLIA + case TPM_ALG_CAMELLIA: + rc = TPMI_ALG_SYM_MODE_Unmarshal(&target->camellia, buffer, size, YES); + break; +#endif + 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 2:137 - Definition of TPM2B_DERIVE Structure (StructuresTable()) */ + +TPM_RC +TPM2B_DERIVE_Unmarshal(TPM2B_DERIVE *target, BYTE **buffer, INT32 *size) +{ + TPM_RC rc = TPM_RC_SUCCESS; + + if (rc == TPM_RC_SUCCESS) { + rc = TPM2B_Unmarshal(&target->b, sizeof(TPMS_DERIVE), 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 */ + +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 */ + +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; + } + } + 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; + + if (rc == TPM_RC_SUCCESS) { + rc = TPM_ALG_ID_Unmarshal(target, buffer, size); + } + if (rc == TPM_RC_SUCCESS) { + switch (*target) { +#ifdef TPM_ALG_HMAC + case TPM_ALG_HMAC: +#endif +#ifdef TPM_ALG_XOR + case TPM_ALG_XOR: +#endif + break; + case TPM_ALG_NULL: + if (allowNull) { + break; + } + default: + rc = TPM_RC_VALUE; + } + } + 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, YES); + } + 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 */ + +TPM_RC +TPMU_SCHEME_KEYEDHASH_Unmarshal(TPMU_SCHEME_KEYEDHASH *target, BYTE **buffer, INT32 *size, UINT32 selector) +{ + TPM_RC rc = TPM_RC_SUCCESS; + + switch (selector) { +#ifdef TPM_ALG_HMAC + case TPM_ALG_HMAC: + rc = TPMS_SCHEME_HMAC_Unmarshal(&target->hmac, buffer, size); + break; +#endif +#ifdef TPM_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 */ + +TPM_RC +TPMU_SIG_SCHEME_Unmarshal(TPMU_SIG_SCHEME *target, BYTE **buffer, INT32 *size, UINT32 selector) +{ + TPM_RC rc = TPM_RC_SUCCESS; + + switch (selector) { +#ifdef TPM_ALG_RSASSA + case TPM_ALG_RSASSA: + rc = TPMS_SIG_SCHEME_RSASSA_Unmarshal(&target->rsassa, buffer, size); + break; +#endif +#ifdef TPM_ALG_RSAPSS + case TPM_ALG_RSAPSS: + rc = TPMS_SIG_SCHEME_RSAPSS_Unmarshal(&target->rsapss, buffer, size); + break; +#endif +#ifdef TPM_ALG_ECDSA + case TPM_ALG_ECDSA: + rc = TPMS_SIG_SCHEME_ECDSA_Unmarshal(&target->ecdsa, buffer, size); + break; +#endif +#ifdef TPM_ALG_ECDAA + case TPM_ALG_ECDAA: + rc = TPMS_SIG_SCHEME_ECDAA_Unmarshal(&target->ecdaa, buffer, size); + break; +#endif +#ifdef TPM_ALG_SM2 + case TPM_ALG_SM2: + rc = TPMS_SIG_SCHEME_SM2_Unmarshal(&target->sm2, buffer, size); + break; +#endif +#ifdef TPM_ALG_ECSCHNORR + case TPM_ALG_ECSCHNORR: + rc = TPMS_SIG_SCHEME_ECSCHNORR_Unmarshal(&target->ecschnorr, buffer, size); + break; +#endif +#ifdef TPM_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_SCHEME_KDF1_SP800_108_Unmarshal(TPMS_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_SCHEME_KDF1_SP800_56A_Unmarshal(TPMS_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_SCHEME_KDF2_Unmarshal(TPMS_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_SCHEME_MGF1_Unmarshal(TPMS_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 */ + +TPM_RC +TPMU_KDF_SCHEME_Unmarshal(TPMU_KDF_SCHEME *target, BYTE **buffer, INT32 *size, UINT32 selector) +{ + TPM_RC rc = TPM_RC_SUCCESS; + + switch (selector) { +#ifdef TPM_ALG_MGF1 + case TPM_ALG_MGF1: + rc = TPMS_SCHEME_MGF1_Unmarshal(&target->mgf1, buffer, size); + break; +#endif +#ifdef TPM_ALG_KDF1_SP800_56A + case TPM_ALG_KDF1_SP800_56A: + rc = TPMS_SCHEME_KDF1_SP800_56A_Unmarshal(&target->kdf1_sp800_56a, buffer, size); + break; +#endif +#ifdef TPM_ALG_KDF2 + case TPM_ALG_KDF2: + rc = TPMS_SCHEME_KDF2_Unmarshal(&target->kdf2, buffer, size); + break; +#endif +#ifdef TPM_ALG_KDF1_SP800_108 + case TPM_ALG_KDF1_SP800_108: + rc = TPMS_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; + + if (rc == TPM_RC_SUCCESS) { + rc = TPM_ALG_ID_Unmarshal(target, buffer, size); + } + if (rc == TPM_RC_SUCCESS) { + switch (*target) { +#ifdef TPM_ALG_ECDH + case TPM_ALG_ECDH: +#endif +#ifdef TPM_ALG_ECMQV + case TPM_ALG_ECMQV: +#endif +#ifdef TPM_ALG_RSASSA + case TPM_ALG_RSASSA: +#endif +#ifdef TPM_ALG_RSAPSS + case TPM_ALG_RSAPSS: +#endif +#ifdef TPM_ALG_ECDSA + case TPM_ALG_ECDSA: +#endif +#ifdef TPM_ALG_ECDAA + case TPM_ALG_ECDAA: +#endif +#ifdef TPM_ALG_SM2 + case TPM_ALG_SM2: +#endif +#ifdef TPM_ALG_ECSCHNORR + case TPM_ALG_ECSCHNORR: +#endif +#ifdef TPM_ALG_RSAES + case TPM_ALG_RSAES: +#endif +#ifdef TPM_ALG_OAEP + case TPM_ALG_OAEP: +#endif + break; + case TPM_ALG_NULL: + if (allowNull) { + break; + } + default: + rc = TPM_RC_VALUE; + } + } + 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) { +#ifdef TPM_ALG_ECDH + case TPM_ALG_ECDH: + rc = TPMS_KEY_SCHEME_ECDH_Unmarshal(&target->ecdh, buffer, size); + break; +#endif +#ifdef TPM_ALG_ECMQV + case TPM_ALG_ECMQV: + rc = TPMS_KEY_SCHEME_ECMQV_Unmarshal(&target->ecmqvh, buffer, size); + break; +#endif +#ifdef TPM_ALG_RSASSA + case TPM_ALG_RSASSA: + rc = TPMS_SIG_SCHEME_RSASSA_Unmarshal(&target->rsassa, buffer, size); + break; +#endif +#ifdef TPM_ALG_RSAPSS + case TPM_ALG_RSAPSS: + rc = TPMS_SIG_SCHEME_RSAPSS_Unmarshal(&target->rsapss, buffer, size); + break; +#endif +#ifdef TPM_ALG_ECDSA + case TPM_ALG_ECDSA: + rc = TPMS_SIG_SCHEME_ECDSA_Unmarshal(&target->ecdsa, buffer, size); + break; +#endif +#ifdef TPM_ALG_ECDAA + case TPM_ALG_ECDAA: + rc = TPMS_SIG_SCHEME_ECDAA_Unmarshal(&target->ecdaa, buffer, size); + break; +#endif +#ifdef TPM_ALG_SM2 + case TPM_ALG_SM2: + rc = TPMS_SIG_SCHEME_SM2_Unmarshal(&target->sm2, buffer, size); + break; +#endif +#ifdef TPM_ALG_ECSCHNORR + case TPM_ALG_ECSCHNORR: + rc = TPMS_SIG_SCHEME_ECSCHNORR_Unmarshal(&target->ecschnorr, buffer, size); + break; +#endif +#ifdef TPM_ALG_RSAES + case TPM_ALG_RSAES: + rc = TPMS_ENC_SCHEME_RSAES_Unmarshal(&target->rsaes, buffer, size); + break; +#endif +#ifdef TPM_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 153 - Definition of TPMT_ASYM_SCHEME Structure <> */ + +#if 0 +TPM_RC +TPMT_ASYM_SCHEME_Unmarshal(TPMT_ASYM_SCHEME *target, BYTE **buffer, INT32 *size, BOOL allowNull) +{ + TPM_RC rc = TPM_RC_SUCCESS; + + if (rc == TPM_RC_SUCCESS) { + rc = TPMI_ALG_ASYM_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; +} +#endif + +/* 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; + + if (rc == TPM_RC_SUCCESS) { + rc = TPM_ALG_ID_Unmarshal(target, buffer, size); + } + if (rc == TPM_RC_SUCCESS) { + switch (*target) { +#ifdef TPM_ALG_RSASSA + case TPM_ALG_RSASSA: +#endif +#ifdef TPM_ALG_RSAPSS + case TPM_ALG_RSAPSS: +#endif +#ifdef TPM_ALG_RSAES + case TPM_ALG_RSAES: +#endif +#ifdef TPM_ALG_OAEP + case TPM_ALG_OAEP: +#endif + break; + case TPM_ALG_NULL: + if (allowNull) { + break; + } + default: + rc = TPM_RC_VALUE; + } + } + 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; + + if (rc == TPM_RC_SUCCESS) { + rc = TPM_ALG_ID_Unmarshal(target, buffer, size); + } + if (rc == TPM_RC_SUCCESS) { + switch (*target) { +#ifdef TPM_ALG_RSAES + case TPM_ALG_RSAES: +#endif +#ifdef TPM_ALG_OAEP + case TPM_ALG_OAEP: +#endif + break; + case TPM_ALG_NULL: + if (allowNull) { + break; + } + default: + rc = TPM_RC_VALUE; + } + } + 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; + + if (rc == TPM_RC_SUCCESS) { + rc = TPM_KEY_BITS_Unmarshal(target, buffer, size); + } + if (rc == TPM_RC_SUCCESS) { + switch (*target) { + case 1024: + case 2048: + break; + default: + rc = TPM_RC_VALUE; + } + } + 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; + } + } + 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; + + if (rc == TPM_RC_SUCCESS) { + rc = TPM_ALG_ID_Unmarshal(target, buffer, size); + } + if (rc == TPM_RC_SUCCESS) { + switch (*target) { +#ifdef TPM_ALG_ECDSA + case TPM_ALG_ECDSA: +#endif +#ifdef TPM_ALG_SM2 + case TPM_ALG_SM2: +#endif +#ifdef TPM_ALG_ECDAA + case TPM_ALG_ECDAA: +#endif +#ifdef TPM_ALG_ECSCHNORR + case TPM_ALG_ECSCHNORR: +#endif +#ifdef TPM_ALG_ECDH + case TPM_ALG_ECDH: +#endif +#ifdef TPM_ALG_ECMQV + case TPM_ALG_ECMQV: +#endif + break; + case TPM_ALG_NULL: + if (allowNull) { + break; + } + default: + rc = TPM_RC_SCHEME; + } + } + 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; + + if (rc == TPM_RC_SUCCESS) { + rc = TPM_ECC_CURVE_Unmarshal(target, buffer, size); + } + if (rc == TPM_RC_SUCCESS) { + switch (*target) { +#ifdef TPM_ECC_BN_P256 + case TPM_ECC_BN_P256: +#endif +#ifdef TPM_ECC_NIST_P256 + case TPM_ECC_NIST_P256: +#endif +#ifdef TPM_ECC_NIST_P384 + case TPM_ECC_NIST_P384: +#endif + break; + default: + rc = TPM_RC_CURVE; + } + } + 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 167 - Definition of {ECC} TPMS_ALGORITHM_DETAIL_ECC Structure */ + +TPM_RC +TPMS_ALGORITHM_DETAIL_ECC_Unmarshal(TPMS_ALGORITHM_DETAIL_ECC *target, BYTE **buffer, INT32 *size) +{ + TPM_RC rc = TPM_RC_SUCCESS; + + if (rc == TPM_RC_SUCCESS) { + rc = TPM_ECC_CURVE_Unmarshal(&target->curveID, buffer, size); + } + if (rc == TPM_RC_SUCCESS) { + rc = UINT16_Unmarshal(&target->keySize, buffer, size); + } + if (rc == TPM_RC_SUCCESS) { + rc = TPMT_KDF_SCHEME_Unmarshal(&target->kdf, buffer, size, YES); + } + if (rc == TPM_RC_SUCCESS) { + rc = TPMT_ECC_SCHEME_Unmarshal(&target->sign, buffer, size, YES); + } + if (rc == TPM_RC_SUCCESS) { + rc = TPM2B_ECC_PARAMETER_Unmarshal(&target->p, buffer, size); + } + if (rc == TPM_RC_SUCCESS) { + rc = TPM2B_ECC_PARAMETER_Unmarshal(&target->a, buffer, size); + } + if (rc == TPM_RC_SUCCESS) { + rc = TPM2B_ECC_PARAMETER_Unmarshal(&target->b, buffer, size); + } + if (rc == TPM_RC_SUCCESS) { + rc = TPM2B_ECC_PARAMETER_Unmarshal(&target->gX, buffer, size); + } + if (rc == TPM_RC_SUCCESS) { + rc = TPM2B_ECC_PARAMETER_Unmarshal(&target->gY, buffer, size); + } + if (rc == TPM_RC_SUCCESS) { + rc = TPM2B_ECC_PARAMETER_Unmarshal(&target->n, buffer, size); + } + if (rc == TPM_RC_SUCCESS) { + rc = TPM2B_ECC_PARAMETER_Unmarshal(&target->h, buffer, size); + } + 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 */ + +TPM_RC +TPMU_SIGNATURE_Unmarshal(TPMU_SIGNATURE *target, BYTE **buffer, INT32 *size, UINT32 selector) +{ + TPM_RC rc = TPM_RC_SUCCESS; + + switch (selector) { +#ifdef TPM_ALG_RSASSA + case TPM_ALG_RSASSA: + rc = TPMS_SIGNATURE_RSASSA_Unmarshal(&target->rsassa, buffer, size); + break; +#endif +#ifdef TPM_ALG_RSAPSS + case TPM_ALG_RSAPSS: + rc = TPMS_SIGNATURE_RSAPSS_Unmarshal(&target->rsapss, buffer, size); + break; +#endif +#ifdef TPM_ALG_ECDSA + case TPM_ALG_ECDSA: + rc = TPMS_SIGNATURE_ECDSA_Unmarshal(&target->ecdsa, buffer, size); + break; +#endif +#ifdef TPM_ALG_ECDAA + case TPM_ALG_ECDAA: + rc = TPMS_SIGNATURE_ECDAA_Unmarshal(&target->ecdaa, buffer, size); + break; +#endif +#ifdef TPM_ALG_SM2 + case TPM_ALG_SM2: + rc = TPMS_SIGNATURE_SM2_Unmarshal(&target->sm2, buffer, size); + break; +#endif +#ifdef TPM_ALG_ECSCHNORR + case TPM_ALG_ECSCHNORR: + rc = TPMS_SIGNATURE_ECSCHNORR_Unmarshal(&target->ecschnorr, buffer, size); + break; +#endif +#ifdef TPM_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; + + if (rc == TPM_RC_SUCCESS) { + rc = TPM_ALG_ID_Unmarshal(target, buffer, size); + } + if (rc == TPM_RC_SUCCESS) { + switch (*target) { +#ifdef TPM_ALG_KEYEDHASH + case TPM_ALG_KEYEDHASH: +#endif +#ifdef TPM_ALG_RSA + case TPM_ALG_RSA: +#endif +#ifdef TPM_ALG_ECC + case TPM_ALG_ECC: +#endif +#ifdef TPM_ALG_SYMCIPHER + case TPM_ALG_SYMCIPHER: +#endif + break; + default: + rc = TPM_RC_TYPE; + } + } + return rc; +} + +/* Table 177 - Definition of TPMU_PUBLIC_ID Union */ + +TPM_RC +TPMU_PUBLIC_ID_Unmarshal(TPMU_PUBLIC_ID *target, BYTE **buffer, INT32 *size, UINT32 selector) +{ + TPM_RC rc = TPM_RC_SUCCESS; + + switch (selector) { +#ifdef TPM_ALG_KEYEDHASH + case TPM_ALG_KEYEDHASH: + rc = TPM2B_DIGEST_Unmarshal(&target->keyedHash, buffer, size); + break; +#endif +#ifdef TPM_ALG_SYMCIPHER + case TPM_ALG_SYMCIPHER: + rc = TPM2B_DIGEST_Unmarshal(&target->sym, buffer, size); + break; +#endif +#ifdef TPM_ALG_RSA + case TPM_ALG_RSA: + rc = TPM2B_PUBLIC_KEY_RSA_Unmarshal(&target->rsa, buffer, size); + break; +#endif +#ifdef TPM_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 179 - Definition of TPMS_ASYM_PARMS Structure <> */ + +#if 0 +TPM_RC +TPMS_ASYM_PARMS_Unmarshal(TPMS_ASYM_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_ASYM_SCHEME_Unmarshal(&target->scheme, buffer, size, YES); + } + return rc; +} +#endif + +/* 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 */ + +TPM_RC +TPMU_PUBLIC_PARMS_Unmarshal(TPMU_PUBLIC_PARMS *target, BYTE **buffer, INT32 *size, UINT32 selector) +{ + TPM_RC rc = TPM_RC_SUCCESS; + + switch (selector) { +#ifdef TPM_ALG_KEYEDHASH + case TPM_ALG_KEYEDHASH: + rc = TPMS_KEYEDHASH_PARMS_Unmarshal(&target->keyedHashDetail, buffer, size); + break; +#endif +#ifdef TPM_ALG_SYMCIPHER + case TPM_ALG_SYMCIPHER: + rc = TPMS_SYMCIPHER_PARMS_Unmarshal(&target->symDetail, buffer, size); + break; +#endif +#ifdef TPM_ALG_RSA + case TPM_ALG_RSA: + rc = TPMS_RSA_PARMS_Unmarshal(&target->rsaDetail, buffer, size); + break; +#endif +#ifdef TPM_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; + } + } + 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 186 - Definition of TPM2B_PRIVATE_VENDOR_SPECIFIC Structure<> */ + +#if 0 +TPM_RC +TPM2B_PRIVATE_VENDOR_SPECIFIC_Unmarshal(TPM2B_PRIVATE_VENDOR_SPECIFIC *target, BYTE **buffer, INT32 *size) +{ + TPM_RC rc = TPM_RC_SUCCESS; + + if (rc == TPM_RC_SUCCESS) { + rc = TPM2B_Unmarshal(&target->b, PRIVATE_VENDOR_SPECIFIC_BYTES, buffer, size); + } + return rc; +} +#endif + +/* Table 187 - Definition of TPMU_SENSITIVE_COMPOSITE Union */ + +TPM_RC +TPMU_SENSITIVE_COMPOSITE_Unmarshal(TPMU_SENSITIVE_COMPOSITE *target, BYTE **buffer, INT32 *size, UINT32 selector) +{ + TPM_RC rc = TPM_RC_SUCCESS; + + switch (selector) { +#ifdef TPM_ALG_RSA + case TPM_ALG_RSA: + rc = TPM2B_PRIVATE_KEY_RSA_Unmarshal(&target->rsa, buffer, size); + break; +#endif +#ifdef TPM_ALG_ECC + case TPM_ALG_ECC: + rc = TPM2B_ECC_PARAMETER_Unmarshal(&target->ecc, buffer, size); + break; +#endif +#ifdef TPM_ALG_KEYEDHASH + case TPM_ALG_KEYEDHASH: + rc = TPM2B_SENSITIVE_DATA_Unmarshal(&target->bits, buffer, size); + break; +#endif +#ifdef TPM_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 */ + +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; + } + } + } + return rc; +} + +/* Table 191 - Definition of TPM2B_PRIVATE Structure */ + +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 */ + +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; + + if (rc == TPM_RC_SUCCESS) { + rc = UINT32_Unmarshal(&target->val, buffer, size); + } + if (rc == TPM_RC_SUCCESS) { + if (target->val & TPMA_NV_RESERVED) { + rc = TPM_RC_RESERVED_BITS; + } + } + 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, NO); + } + 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; + } + } + 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; + } + } + return rc; +} + +/* Table 199 - Definition of TPM2B_CONTEXT_SENSITIVE Structure */ + +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; +} + +/* Table 200 - Definition of TPMS_CONTEXT_DATA Structure */ + +TPM_RC +TPMS_CONTEXT_DATA_Unmarshal(TPMS_CONTEXT_DATA *target, BYTE **buffer, INT32 *size) +{ + TPM_RC rc = TPM_RC_SUCCESS; + + if (rc == TPM_RC_SUCCESS) { + rc = TPM2B_DIGEST_Unmarshal(&target->integrity, buffer, size); + } + if (rc == TPM_RC_SUCCESS) { + rc = TPM2B_CONTEXT_SENSITIVE_Unmarshal(&target->encrypted, buffer, size); + } + return rc; +} + +/* Table 201 - Definition of TPM2B_CONTEXT_DATA Structure */ + +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; + + if (rc == TPM_RC_SUCCESS) { + rc = UINT64_Unmarshal(&target->sequence, buffer, size); + } + if (rc == TPM_RC_SUCCESS) { + rc = TPMI_DH_CONTEXT_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); + } + return rc; +} + +/* Table 204 - Definition of TPMS_CREATION_DATA Structure */ + +TPM_RC +TPMS_CREATION_DATA_Unmarshal(TPMS_CREATION_DATA *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); + } + if (rc == TPM_RC_SUCCESS) { + rc = TPMA_LOCALITY_Unmarshal(&target->locality, buffer, size); + } + if (rc == TPM_RC_SUCCESS) { + rc = TPM_ALG_ID_Unmarshal(&target->parentNameAlg, buffer, size); + } + if (rc == TPM_RC_SUCCESS) { + rc = TPM2B_NAME_Unmarshal(&target->parentName, buffer, size); + } + if (rc == TPM_RC_SUCCESS) { + rc = TPM2B_NAME_Unmarshal(&target->parentQualifiedName, buffer, size); + } + if (rc == TPM_RC_SUCCESS) { + rc = TPM2B_DATA_Unmarshal(&target->outsideInfo, buffer, size); + } + return rc; +} + +/* Table 205 - Definition of TPM2B_CREATION_DATA Structure */ + +TPM_RC +TPM2B_CREATION_DATA_Unmarshal(TPM2B_CREATION_DATA *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_CREATION_DATA_Unmarshal(&target->creationData, buffer, size); + } + if (rc == TPM_RC_SUCCESS) { + if (target->size != startSize - *size) { + rc = TPM_RC_SIZE; + } + } + return rc; +} + diff --git a/src/tpm2/Unmarshal_fp.h b/src/tpm2/Unmarshal_fp.h new file mode 100644 index 00000000..bd087ce0 --- /dev/null +++ b/src/tpm2/Unmarshal_fp.h @@ -0,0 +1,484 @@ +/********************************************************************************/ +/* */ +/* */ +/* Written by Ken Goldman */ +/* IBM Thomas J. Watson Research Center */ +/* $Id: Unmarshal_fp.h 953 2017-03-06 20:31: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, 2012-2015 */ +/* */ +/********************************************************************************/ + +/* rev 136 */ + +#ifndef UNMARSHAL_FP_H +#define UNMARSHAL_FP_H + +#ifndef TPM_TSS +#include "TpmTypes.h" +#else +#include "TPM_Types.h" +#endif + +#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 + INT32_Unmarshal(INT32 *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); + LIB_EXPORT TPM_RC + TPM_GENERATED_Unmarshal(TPM_GENERATED *target, BYTE **buffer, INT32 *size); + 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_RC_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, BOOL allowNull); + LIB_EXPORT TPM_RC + TPMI_SH_POLICY_Unmarshal(TPMI_SH_POLICY *target, BYTE **buffer, INT32 *size, BOOL allowNull); + LIB_EXPORT TPM_RC + TPMI_DH_CONTEXT_Unmarshal(TPMI_DH_CONTEXT *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, BOOL allowNull); + LIB_EXPORT TPM_RC + TPMI_RH_PLATFORM_Unmarshal(TPMI_RH_PLATFORM *target, BYTE **buffer, INT32 *size, BOOL allowNull); + 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, BOOL allowNull); + LIB_EXPORT TPM_RC + TPMI_RH_CLEAR_Unmarshal(TPMI_RH_CLEAR *target, BYTE **buffer, INT32 *size, BOOL allowNull); + LIB_EXPORT TPM_RC + TPMI_RH_NV_AUTH_Unmarshal(TPMI_RH_NV_AUTH *target, BYTE **buffer, INT32 *size, BOOL allowNull); + LIB_EXPORT TPM_RC + TPMI_RH_LOCKOUT_Unmarshal(TPMI_RH_LOCKOUT *target, BYTE **buffer, INT32 *size, BOOL allowNull); + LIB_EXPORT TPM_RC + TPMI_RH_NV_INDEX_Unmarshal(TPMI_RH_NV_INDEX *target, BYTE **buffer, INT32 *size, BOOL allowNull); + 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 + 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_OPERAND_Unmarshal(TPM2B_OPERAND *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 +#ifdef TPM_TSS + ,uint32_t minCount +#endif + ); + 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); + 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); + LIB_EXPORT TPM_RC + TPMS_AUTH_RESPONSE_Unmarshal(TPMS_AUTH_RESPONSE *target, BYTE **buffer, INT32 *size); + LIB_EXPORT TPM_RC + TPMI_AES_KEY_BITS_Unmarshal(TPMI_AES_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_DERIVE_Unmarshal(TPM2B_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_SCHEME_KDF1_SP800_108_Unmarshal(TPMS_SCHEME_KDF1_SP800_108 *target, BYTE **buffer, INT32 *size); + LIB_EXPORT TPM_RC + TPMS_SCHEME_KDF1_SP800_56A_Unmarshal(TPMS_SCHEME_KDF1_SP800_56A *target, BYTE **buffer, INT32 *size); + LIB_EXPORT TPM_RC + TPMS_SCHEME_KDF2_Unmarshal(TPMS_SCHEME_KDF2 *target, BYTE **buffer, INT32 *size); + LIB_EXPORT TPM_RC + TPMS_SCHEME_MGF1_Unmarshal(TPMS_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); + LIB_EXPORT TPM_RC + TPMI_ALG_ASYM_SCHEME_Unmarshal(TPMI_ALG_ASYM_SCHEME *target, BYTE **buffer, INT32 *size, BOOL allowNull); + LIB_EXPORT TPM_RC + TPMU_ASYM_SCHEME_Unmarshal(TPMU_ASYM_SCHEME *target, BYTE **buffer, INT32 *size, UINT32 selector); + LIB_EXPORT TPM_RC + TPMT_ASYM_SCHEME_Unmarshal(TPMT_ASYM_SCHEME *target, BYTE **buffer, INT32 *size, BOOL allowNull); + 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_ALGORITHM_DETAIL_ECC_Unmarshal(TPMS_ALGORITHM_DETAIL_ECC *target, BYTE **buffer, INT32 *size); + 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_ASYM_PARMS_Unmarshal(TPMS_ASYM_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 + TPM2B_PRIVATE_VENDOR_SPECIFIC_Unmarshal(TPM2B_PRIVATE_VENDOR_SPECIFIC *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 + TPMS_CONTEXT_DATA_Unmarshal(TPMS_CONTEXT_DATA *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 + TPMS_CREATION_DATA_Unmarshal(TPMS_CREATION_DATA *target, BYTE **buffer, INT32 *size); + LIB_EXPORT TPM_RC + TPM2B_CREATION_DATA_Unmarshal(TPM2B_CREATION_DATA *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 00000000..84fa0a4a --- /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/VendorString.h b/src/tpm2/VendorString.h new file mode 100644 index 00000000..c617b356 --- /dev/null +++ b/src/tpm2/VendorString.h @@ -0,0 +1,103 @@ +/********************************************************************************/ +/* */ +/* */ +/* Written by Ken Goldman */ +/* IBM Thomas J. Watson Research Center */ +/* $Id: VendorString.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 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 include\VendorString.h to provide a specific \ + manufacturer name. +#endif +/* Define up to 4, 4-octet, vendor-specific values. The values must each be 4 octet 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 */ +/* A vendor-specific string should be provided here. */ +#define VENDOR_STRING_1 "SW " +#define VENDOR_STRING_2 " TPM" +/* The vendor strings 2-4 may also be defined as needed. */ +//#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. +#endif +/* A vendor-specific FIRMWARE_V1 is required here. It is the more significant 32-bits of a + vendor-specific value indicating the version of the firmware */ +#define FIRMWARE_V1 (0x20160511) +/* A vendor-specific FIRMWARE_V2 may be provided here. If present, it is the less significant + 32-bits of the version of the firmware. */ +#define FIRMWARE_V2 (0x00162800) +/* The following macro is just to insure that a FIRMWARE_V1 value is provided. */ +#ifndef FIRMWARE_V1 +#error FIRMWARE_V1 is not provided. \ + Please modify include\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 00000000..71b9ce50 --- /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 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 */ +/* */ +/********************************************************************************/ + +#include "Tpm.h" +#include "Vendor_TCG_Test_fp.h" +#include "Marshal_fp.h" +#if defined TPM_CC_Vendor_TCG_Test // Conditional expansion of this file +/* 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 00000000..d50d0376 --- /dev/null +++ b/src/tpm2/Vendor_TCG_Test_fp.h @@ -0,0 +1,79 @@ +/********************************************************************************/ +/* */ +/* */ +/* Written by Ken Goldman */ +/* IBM Thomas J. Watson Research Center */ +/* $Id: Vendor_TCG_Test_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 VENDOR_TCG_TEST_FP_H +#define VENDOR_TCG_TEST_FP_H + +typedef struct { + UINT8 inputData; +} Vendor_TCG_Test_In; + +typedef struct { + UINT8 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 00000000..d90c83a0 --- /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/ZGen_2Phase_fp.h b/src/tpm2/ZGen_2Phase_fp.h new file mode 100644 index 00000000..6bfb9746 --- /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 00000000..dadddba9 --- /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 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 _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 00000000..d35878ca --- /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 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 _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 00000000..4539fa8c --- /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 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 _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 00000000..785ce425 --- /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 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 _TPM_INIT_FP_H +#define _TPM_INIT_FP_H + +LIB_EXPORT void +_TPM_Init( + void + ); + + + + +#endif diff --git a/src/tpm2/crypto/CryptDes_fp.h b/src/tpm2/crypto/CryptDes_fp.h new file mode 100644 index 00000000..1c1c3cd4 --- /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 00000000..121307e5 --- /dev/null +++ b/src/tpm2/crypto/CryptEcc.h @@ -0,0 +1,96 @@ +/********************************************************************************/ +/* */ +/* */ +/* Written by Ken Goldman */ +/* IBM Thomas J. Watson Research Center */ +/* $Id: CryptEcc.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 CRYPTECC_H +#define CRYPTECC_H + + +/* 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.1.1 ECC-related Structures */ +/* This is used to define the macro that may or may not be in the data set for the curve + (BnEccData.c). If there is a mismatch, the compiler will warn that there is to much/not enough + initialization data in the curve. The macro is used because not all versions of the + CryptEccData.c need the curve name. */ +#ifdef NAMED_CURVES +#define CURVE_NAME(a) , a +#define CURVE_NAME_DEF const char *name; +#else +# define CURVE_NAME(a) +# define CURVE_NAME_DEF +#endif +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 + CURVE_NAME_DEF +} ECC_CURVE; +extern const ECC_CURVE eccCurves[ECC_CURVE_COUNT]; +#endif + +#endif diff --git a/src/tpm2/crypto/CryptEccKeyExchange_fp.h b/src/tpm2/crypto/CryptEccKeyExchange_fp.h new file mode 100644 index 00000000..e4f0b5a2 --- /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 00000000..f58411b1 --- /dev/null +++ b/src/tpm2/crypto/CryptEccMain_fp.h @@ -0,0 +1,217 @@ +/********************************************************************************/ +/* */ +/* */ +/* Written by Ken Goldman */ +/* IBM Thomas J. Watson Research Center */ +/* $Id: CryptEccMain_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 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 + ); +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 + // 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 + ); + + +#endif diff --git a/src/tpm2/crypto/CryptEccSignature_fp.h b/src/tpm2/crypto/CryptEccSignature_fp.h new file mode 100644 index 00000000..5ee813eb --- /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 00000000..03271649 --- /dev/null +++ b/src/tpm2/crypto/CryptHash.h @@ -0,0 +1,233 @@ +/********************************************************************************/ +/* */ +/* Hash structure definitions */ +/* Written by Ken Goldman */ +/* IBM Thomas J. Watson Research Center */ +/* $Id: CryptHash.h 953 2017-03-06 20:31: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, 2017 */ +/* */ +/********************************************************************************/ + +#ifndef CRYPTHASH_H +#define CRYPTHASH_H + +/* 10.1.3 CryptHash.h */ +/* 10.1.3.1 Hash Related Structures */ +typedef struct +{ + const TPM_ALG_ID alg; + const UINT16 digestSize; + const UINT16 blockSize; + const UINT16 derSize; + const BYTE der[20]; +} HASH_INFO; +typedef union +{ +#ifdef TPM_ALG_SHA1 + tpmHashStateSHA1_t Sha1; +#endif +#ifdef TPM_ALG_SHA256 + tpmHashStateSHA256_t Sha256; +#endif +#ifdef TPM_ALG_SHA384 + tpmHashStateSHA384_t Sha384; +#endif +#ifdef TPM_ALG_SHA512 + tpmHashStateSHA512_t Sha512; +#endif + // to force structure alignment to be no worse than HASH_ALIGNMENT +#if HASH_ALIGNMENT == 4 + uint32_t align; +#else + uint64_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; +#if ALG_SHA1 +TPM2B_TYPE(SHA1_DIGEST, SHA1_DIGEST_SIZE); +#endif +#if ALG_SHA256 +TPM2B_TYPE(SHA256_DIGEST, SHA256_DIGEST_SIZE); +#endif +#if ALG_SHA384 +TPM2B_TYPE(SHA384_DIGEST, SHA384_DIGEST_SIZE); +#endif +#if ALG_SHA512 +TPM2B_TYPE(SHA512_DIGEST, SHA512_DIGEST_SIZE); +#endif +#if ALG_SM3_256 +TPM2B_TYPE(SM3_256_DIGEST, SM3_256_DIGEST_SIZE); +#endif +typedef const struct +{ + HASH_METHODS method; + uint16_t blockSize; + uint16_t digestSize; + uint16_t contextSize; + uint16_t hashAlg; +} 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_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} +/* These definitions are for the types that can be in a hash state structure. These types are + used in the crypto 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) +/* 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. */ +typedef struct _HASH_STATE +{ + PHASH_DEF def; + TPM_ALG_ID hashAlg; + HASH_STATE_TYPE type; // type of the context + ANY_HASH_STATE state; +} HASH_STATE, *PHASH_STATE; +typedef const HASH_STATE *PCHASH_STATE; +/* 10.1.3.2 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 +{ + HASH_STATE hashState; // the hash state + TPM2B_HASH_BLOCK hmacKey; // the HMAC key +} HMAC_STATE, *PHMAC_STATE; +extern const HASH_INFO g_hashData[HASH_COUNT + 1]; +/* 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. There is a run time check that makes sure + that this i. */ +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/CryptHashData.h b/src/tpm2/crypto/CryptHashData.h new file mode 100644 index 00000000..37724887 --- /dev/null +++ b/src/tpm2/crypto/CryptHashData.h @@ -0,0 +1,93 @@ +/********************************************************************************/ +/* */ +/* */ +/* Written by Ken Goldman */ +/* IBM Thomas J. Watson Research Center */ +/* $Id: CryptHashData.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 CRYPTHASHDATA_H +#define CRYPTHASHDATA_H + + +/* 10.1.4 CryptHashData.h */ +#ifdef GLOBAL_C +const HASH_INFO g_hashData[HASH_COUNT + 1] = { +#ifdef TPM_ALG_SHA1 + {TPM_ALG_SHA1, SHA1_DIGEST_SIZE, SHA1_BLOCK_SIZE, + SHA1_DER_SIZE, {SHA1_DER}}, +#endif +#ifdef TPM_ALG_SHA256 + {TPM_ALG_SHA256, SHA256_DIGEST_SIZE, SHA256_BLOCK_SIZE, + SHA256_DER_SIZE, {SHA256_DER}}, +#endif +#ifdef TPM_ALG_SHA512 + {TPM_ALG_SHA512, SHA512_DIGEST_SIZE, SHA512_BLOCK_SIZE, + SHA512_DER_SIZE, {SHA512_DER}}, +#endif +#ifdef TPM_ALG_SHA384 + {TPM_ALG_SHA384, SHA384_DIGEST_SIZE, SHA384_BLOCK_SIZE, + SHA384_DER_SIZE, {SHA384_DER}}, +#endif +#ifdef TPM_ALG_SM3_256 + {TPM_ALG_SM3_256, SM3_256_DIGEST_SIZE, SM3_256_BLOCK_SIZE, + SM3_256_DER_SIZE, {SM3_256_DER}}, +#endif + {TPM_ALG_NULL,0,0,0,{0}} +}; +#endif // GLOBAL_C + +#endif diff --git a/src/tpm2/crypto/CryptHash_fp.h b/src/tpm2/crypto/CryptHash_fp.h new file mode 100644 index 00000000..0e7bee7e --- /dev/null +++ b/src/tpm2/crypto/CryptHash_fp.h @@ -0,0 +1,223 @@ +/********************************************************************************/ +/* */ +/* */ +/* Written by Ken Goldman */ +/* IBM Thomas J. Watson Research Center */ +/* $Id: CryptHash_fp.h 953 2017-03-06 20:31: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 */ +/* */ +/********************************************************************************/ + +#ifndef CRYPTHASH_FP_H +#define CRYPTHASH_FP_H + +BOOL +CryptHashInit( + void + ); +BOOL +CryptHashStartup( + void + ); +PHASH_DEF +CryptGetHashDef( + TPM_ALG_ID hashAlg + ); +BOOL +CryptHashIsImplemented( + 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 UINT16 +CryptHashGetDer( + TPM_ALG_ID hashAlg, // IN: the algorithm to look up + const BYTE **p + ); +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 +CryptMGF1( + 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 + ); +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. + BOOL once // IN: TRUE - only 1 iteration is performed + // FALSE if iteration count determined by + // "sizeInBits" + ); +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 00000000..66639a38 --- /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 00000000..8cd23f5e --- /dev/null +++ b/src/tpm2/crypto/CryptPrime_fp.h @@ -0,0 +1,103 @@ +/********************************************************************************/ +/* */ +/* */ +/* Written by Ken Goldman */ +/* IBM Thomas J. Watson Research Center */ +/* $Id: CryptPrime_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 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 + ); +void +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 00000000..709db66c --- /dev/null +++ b/src/tpm2/crypto/CryptRand.h @@ -0,0 +1,194 @@ +/********************************************************************************/ +/* */ +/* DRBG with a behavior according to SP800-90A */ +/* Written by Ken Goldman */ +/* IBM Thomas J. Watson Research Center */ +/* $Id: CryptRand.h 953 2017-03-06 20:31: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, 2017 */ +/* */ +/********************************************************************************/ + +#ifndef CRYPTRAND_H +#define CRYPTRAND_H + +/* 10.1.5 CryptRand.h */ +/* 10.1.5.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 MAX_AES_KEY_BITS +#define DRBG_IV_SIZE_BITS (MAX_AES_BLOCK_SIZE_BYTES * 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 + 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 +{ + UINT64 counter; + UINT32 magic; + TPM2B *seed; + const TPM2B *label; + TPM2B *context; + TPM_ALG_ID hash; + TPM_ALG_ID kdf; +} 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 */ +#ifdef 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 + + +#endif diff --git a/src/tpm2/crypto/CryptRand_fp.h b/src/tpm2/crypto/CryptRand_fp.h new file mode 100644 index 00000000..620e62e7 --- /dev/null +++ b/src/tpm2/crypto/CryptRand_fp.h @@ -0,0 +1,164 @@ +/********************************************************************************/ +/* */ +/* */ +/* Written by Ken Goldman */ +/* IBM Thomas J. Watson Research Center */ +/* $Id: CryptRand_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 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 + ); +void +EncryptDRBG( + BYTE *dOut, + UINT32 dOutBytes, + DRBG_KEY_SCHEDULE *keySchedule, + DRBG_IV *iv, + UINT32 *lastValue // Points to the last output value + ); +void +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 + ); +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( + UINT32 additionalDataSize, + BYTE *additionalData + ); +LIB_EXPORT UINT16 +CryptRandomGenerate( + INT32 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 + ); +LIB_EXPORT void +DRBG_AdditionalData( + DRBG_STATE *drbgState, // IN:OUT state to update + TPM2B *additionalData // IN: value to incorporate + ); +LIB_EXPORT BOOL +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 + ); +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 + ); +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 00000000..3a83e55c --- /dev/null +++ b/src/tpm2/crypto/CryptRsa.h @@ -0,0 +1,100 @@ +/********************************************************************************/ +/* */ +/* RSA-related structures and defines */ +/* Written by Ken Goldman */ +/* IBM Thomas J. Watson Research Center */ +/* $Id: CryptRsa.h 953 2017-03-06 20:31: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, 2017 */ +/* */ +/********************************************************************************/ + +#ifndef CRYPTRSA_H +#define CRYPTRSA_H + +/* 10.1.6 CryptRsa.h */ +#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 + + +#endif diff --git a/src/tpm2/crypto/CryptRsa_fp.h b/src/tpm2/crypto/CryptRsa_fp.h new file mode 100644 index 00000000..7e7897b6 --- /dev/null +++ b/src/tpm2/crypto/CryptRsa_fp.h @@ -0,0 +1,128 @@ +/********************************************************************************/ +/* */ +/* */ +/* Written by Ken Goldman */ +/* IBM Thomas J. Watson Research Center */ +/* $Id: CryptRsa_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 CRYPTRSA_FP_H +#define CRYPTRSA_FP_H + +BOOL +CryptRsaInit( + void + ); +BOOL +CryptRsaStartup( + void + ); +void +RsaInitializeExponent( + privateExponent_t *pExp + ); +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 + ); + + +#endif diff --git a/src/tpm2/crypto/CryptSelfTest_fp.h b/src/tpm2/crypto/CryptSelfTest_fp.h new file mode 100644 index 00000000..06a5523f --- /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 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 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/CryptSym_fp.h b/src/tpm2/crypto/CryptSym_fp.h new file mode 100644 index 00000000..ec4989ad --- /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 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 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 00000000..07be58f5 --- /dev/null +++ b/src/tpm2/crypto/CryptTest.h @@ -0,0 +1,94 @@ +/********************************************************************************/ +/* */ +/* constant definitions used for self-test. */ +/* Written by Ken Goldman */ +/* IBM Thomas J. Watson Research Center */ +/* $Id: CryptTest.h 953 2017-03-06 20:31: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, 2017 */ +/* */ +/********************************************************************************/ + +#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 */ +#define ALGORITHM_VECTOR_BYTES ((ALG_LAST_VALUE + 8) / 8) +typedef BYTE ALGORITHM_VECTOR[ALGORITHM_VECTOR_BYTES]; +#ifdef TEST_SELF_TEST +LIB_EXPORT extern ALGORITHM_VECTOR LibToTest; +#endif +/* 10.1.7.2 Self-test */ +/* 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; +#ifdef TPM_ALG_RSA + UINT32 rsa; +#endif +#ifdef TPM_ALG_ECC + UINT32 ecc; +#endif +} CRYPTO_SELF_TEST_STATE; +/* 10.1.7.2.1 g_cryptoSelfTestState */ +/* This structure contains the cryptographic self-test state values. */ +extern CRYPTO_SELF_TEST_STATE g_cryptoSelfTestState; +#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 00000000..93ed5efe --- /dev/null +++ b/src/tpm2/crypto/CryptUtil_fp.h @@ -0,0 +1,225 @@ +/********************************************************************************/ +/* */ +/* */ +/* Written by Ken Goldman */ +/* IBM Thomas J. Watson Research Center */ +/* $Id: CryptUtil_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 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 + ); +BOOL +CryptIsUniqueSizeValid( + TPMT_PUBLIC *publicArea // IN: the public area to check + ); +BOOL +CryptIsSensitiveSizeValid( + TPMT_PUBLIC *publicArea, // IN: the object's public part + TPMT_SENSITIVE *sensitiveArea // IN: the object's sensitive part + ); +TPM_RC +CryptValidateKeys( + TPMT_PUBLIC *publicArea, + TPMT_SENSITIVE *sensitive, + TPM_RC blamePublic, + TPM_RC blameSensitive + ); +void +CryptAlgsSetImplemented( + void + ); + + +#endif diff --git a/src/tpm2/crypto/openssl/BnConvert_fp.h b/src/tpm2/crypto/openssl/BnConvert_fp.h new file mode 100644 index 00000000..dd60da03 --- /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 00000000..d42a2f6d --- /dev/null +++ b/src/tpm2/crypto/openssl/BnMath_fp.h @@ -0,0 +1,156 @@ +/********************************************************************************/ +/* */ +/* */ +/* 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 + ); + + +#endif diff --git a/src/tpm2/crypto/openssl/BnMemory_fp.h b/src/tpm2/crypto/openssl/BnMemory_fp.h new file mode 100644 index 00000000..82fce3ed --- /dev/null +++ b/src/tpm2/crypto/openssl/BnMemory_fp.h @@ -0,0 +1,104 @@ +/********************************************************************************/ +/* */ +/* */ +/* 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 + ); +LIB_EXPORT bigNum +BnClearTop( + bigNum bn + ); +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 + ); +LIB_EXPORT BOOL +BnPointCopy( + bigPoint pOut, + pointConst pIn + ); +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 00000000..8dc31ae2 --- /dev/null +++ b/src/tpm2/crypto/openssl/BnValues.h @@ -0,0 +1,294 @@ +/********************************************************************************/ +/* */ +/* */ +/* Written by Ken Goldman */ +/* IBM Thomas J. Watson Research Center */ +/* $Id: BnValues.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 BNVALUES_H +#define BNVALUES_H + +/* 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) +#define CRYPT_TO_BYTE_ARRAY UINT64_TO_BYTE_ARRAY +typedef uint64_t crypt_uword_t; +typedef int64_t crypt_word_t; +#elif RADIX_BITS == 32 +#define SWAP_CRYPT_WORD(x) REVERSE_ENDIAN_32((x)) +#define CRYPT_TO_BYTE_ARRAY UINT32_TO_BYTE_ARRAY +typedef uint32_t crypt_uword_t; +typedef int32_t crypt_word_t; +#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 to 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]; \ + } +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_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 created 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 + noting. */ +#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 endianess of the system This is used for + BnEccData.c. */ +/* NOTE: There is no reason to try to optimize this by doing byte at a time shifts because this is + handled at compile time. */ +#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)) \ + ) +#if RADIX_BITS > 32 +# define TO_CRYPT_WORD_64(a, b, c, d, e, f, g, h) \ + BIG_ENDIAN_BYTES_TO_UINT64(a, b, c, d, e, f, g, h) +# define TO_CRYPT_WORD_32(a, b, c, d) TO_CRYPT_WORD_64(0, 0, 0, 0, a, b, c, d) +#else +# 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 +#endif +/* Add implementation dependent definitions for other ECC Values and for linkages. MATH_LIB_H is + defined in LibSupport.h */ +#include MATHLIB_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 +#endif // _BN_NUMBERS_H + + +#endif diff --git a/src/tpm2/crypto/openssl/CryptDataEcc.c b/src/tpm2/crypto/openssl/CryptDataEcc.c new file mode 100644 index 00000000..946cb708 --- /dev/null +++ b/src/tpm2/crypto/openssl/CryptDataEcc.c @@ -0,0 +1,475 @@ +/********************************************************************************/ +/* */ +/* */ +/* Written by Ken Goldman */ +/* IBM Thomas J. Watson Research Center */ +/* $Id: CryptDataEcc.c 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 */ +/* */ +/********************************************************************************/ + +/* 10.2.8 CryptDataEcc.c */ +#include "Tpm.h" +#ifdef TPM_ALG_ECC +/* Defines for the sizes of ECC parameters */ +TPM2B_BYTE_VALUE(1); +TPM2B_BYTE_VALUE(16); +TPM2B_BYTE_VALUE(2); +TPM2B_BYTE_VALUE(24); +TPM2B_BYTE_VALUE(28); +TPM2B_BYTE_VALUE(32); +TPM2B_BYTE_VALUE(4); +TPM2B_BYTE_VALUE(48); +TPM2B_BYTE_VALUE(64); +TPM2B_BYTE_VALUE(66); +TPM2B_BYTE_VALUE(8); +TPM2B_BYTE_VALUE(80); +#if defined ECC_NIST_P192 && ECC_NIST_P192 == YES +const TPM2B_24_BYTE_VALUE NIST_P192_p = {24, + {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}}; +const TPM2B_24_BYTE_VALUE NIST_P192_a = {24, + {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC}}; +const TPM2B_24_BYTE_VALUE NIST_P192_b = {24, + {0x64, 0x21, 0x05, 0x19, 0xE5, 0x9C, 0x80, 0xE7, + 0x0F, 0xA7, 0xE9, 0xAB, 0x72, 0x24, 0x30, 0x49, + 0xFE, 0xB8, 0xDE, 0xEC, 0xC1, 0x46, 0xB9, 0xB1}}; +const TPM2B_24_BYTE_VALUE NIST_P192_gX = {24, + {0x18, 0x8D, 0xA8, 0x0E, 0xB0, 0x30, 0x90, 0xF6, + 0x7C, 0xBF, 0x20, 0xEB, 0x43, 0xA1, 0x88, 0x00, + 0xF4, 0xFF, 0x0A, 0xFD, 0x82, 0xFF, 0x10, 0x12}}; +const TPM2B_24_BYTE_VALUE NIST_P192_gY = {24, + {0x07, 0x19, 0x2B, 0x95, 0xFF, 0xC8, 0xDA, 0x78, + 0x63, 0x10, 0x11, 0xED, 0x6B, 0x24, 0xCD, 0xD5, + 0x73, 0xF9, 0x77, 0xA1, 0x1E, 0x79, 0x48, 0x11}}; +const TPM2B_24_BYTE_VALUE NIST_P192_n = {24, + {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0x99, 0xDE, 0xF8, 0x36, + 0x14, 0x6B, 0xC9, 0xB1, 0xB4, 0xD2, 0x28, 0x31}}; +const TPM2B_1_BYTE_VALUE NIST_P192_h = {1,{1}}; +const ECC_CURVE_DATA NIST_P192 = {&NIST_P192_p.b, &NIST_P192_a.b, &NIST_P192_b.b, + &NIST_P192_gX.b, &NIST_P192_gY.b, &NIST_P192_n.b, + &NIST_P192_h.b}; +#endif // ECC_NIST_P192 +#if defined ECC_NIST_P224 && ECC_NIST_P224 == YES +const TPM2B_28_BYTE_VALUE NIST_P224_p = {28, + {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x01}}; +const TPM2B_28_BYTE_VALUE NIST_P224_a = {28, + {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFE}}; +const TPM2B_28_BYTE_VALUE NIST_P224_b = {28, + {0xB4, 0x05, 0x0A, 0x85, 0x0C, 0x04, 0xB3, 0xAB, + 0xF5, 0x41, 0x32, 0x56, 0x50, 0x44, 0xB0, 0xB7, + 0xD7, 0xBF, 0xD8, 0xBA, 0x27, 0x0B, 0x39, 0x43, + 0x23, 0x55, 0xFF, 0xB4}}; +const TPM2B_28_BYTE_VALUE NIST_P224_gX = {28, + {0xB7, 0x0E, 0x0C, 0xBD, 0x6B, 0xB4, 0xBF, 0x7F, + 0x32, 0x13, 0x90, 0xB9, 0x4A, 0x03, 0xC1, 0xD3, + 0x56, 0xC2, 0x11, 0x22, 0x34, 0x32, 0x80, 0xD6, + 0x11, 0x5C, 0x1D, 0x21}}; +const TPM2B_28_BYTE_VALUE NIST_P224_gY = {28, + {0xBD, 0x37, 0x63, 0x88, 0xB5, 0xF7, 0x23, 0xFB, + 0x4C, 0x22, 0xDF, 0xE6, 0xCD, 0x43, 0x75, 0xA0, + 0x5A, 0x07, 0x47, 0x64, 0x44, 0xD5, 0x81, 0x99, + 0x85, 0x00, 0x7E, 0x34}}; +const TPM2B_28_BYTE_VALUE NIST_P224_n = {28, + {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x16, 0xA2, + 0xE0, 0xB8, 0xF0, 0x3E, 0x13, 0xDD, 0x29, 0x45, + 0x5C, 0x5C, 0x2A, 0x3D}}; +const TPM2B_1_BYTE_VALUE NIST_P224_h = {1,{1}}; +const ECC_CURVE_DATA NIST_P224 = {&NIST_P224_p.b, &NIST_P224_a.b, &NIST_P224_b.b, + &NIST_P224_gX.b, &NIST_P224_gY.b, &NIST_P224_n.b, + &NIST_P224_h.b}; +#endif // ECC_NIST_P224 +#if defined ECC_NIST_P256 && ECC_NIST_P256 == YES +const TPM2B_32_BYTE_VALUE NIST_P256_p = {32, + {0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}}; +const TPM2B_32_BYTE_VALUE NIST_P256_a = {32, + {0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC}}; +const TPM2B_32_BYTE_VALUE NIST_P256_b = {32, + {0x5A, 0xC6, 0x35, 0xD8, 0xAA, 0x3A, 0x93, 0xE7, + 0xB3, 0xEB, 0xBD, 0x55, 0x76, 0x98, 0x86, 0xBC, + 0x65, 0x1D, 0x06, 0xB0, 0xCC, 0x53, 0xB0, 0xF6, + 0x3B, 0xCE, 0x3C, 0x3E, 0x27, 0xD2, 0x60, 0x4B}}; +const TPM2B_32_BYTE_VALUE NIST_P256_gX = {32, + {0x6B, 0x17, 0xD1, 0xF2, 0xE1, 0x2C, 0x42, 0x47, + 0xF8, 0xBC, 0xE6, 0xE5, 0x63, 0xA4, 0x40, 0xF2, + 0x77, 0x03, 0x7D, 0x81, 0x2D, 0xEB, 0x33, 0xA0, + 0xF4, 0xA1, 0x39, 0x45, 0xD8, 0x98, 0xC2, 0x96}}; +const TPM2B_32_BYTE_VALUE NIST_P256_gY = {32, + {0x4F, 0xE3, 0x42, 0xE2, 0xFE, 0x1A, 0x7F, 0x9B, + 0x8E, 0xE7, 0xEB, 0x4A, 0x7C, 0x0F, 0x9E, 0x16, + 0x2B, 0xCE, 0x33, 0x57, 0x6B, 0x31, 0x5E, 0xCE, + 0xCB, 0xB6, 0x40, 0x68, 0x37, 0xBF, 0x51, 0xF5}}; +const TPM2B_32_BYTE_VALUE NIST_P256_n = {32, + {0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xBC, 0xE6, 0xFA, 0xAD, 0xA7, 0x17, 0x9E, 0x84, + 0xF3, 0xB9, 0xCA, 0xC2, 0xFC, 0x63, 0x25, 0x51}}; +const TPM2B_1_BYTE_VALUE NIST_P256_h = {1,{1}}; +const ECC_CURVE_DATA NIST_P256 = {&NIST_P256_p.b, &NIST_P256_a.b, &NIST_P256_b.b, + &NIST_P256_gX.b, &NIST_P256_gY.b, &NIST_P256_n.b, + &NIST_P256_h.b}; +#endif // ECC_NIST_P256 +#if defined ECC_NIST_P384 && ECC_NIST_P384 == YES +const TPM2B_48_BYTE_VALUE NIST_P384_p = {48, + {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, + 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF}}; +const TPM2B_48_BYTE_VALUE NIST_P384_a = {48, + {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, + 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFC}}; +const TPM2B_48_BYTE_VALUE NIST_P384_b = {48, + {0xB3, 0x31, 0x2F, 0xA7, 0xE2, 0x3E, 0xE7, 0xE4, + 0x98, 0x8E, 0x05, 0x6B, 0xE3, 0xF8, 0x2D, 0x19, + 0x18, 0x1D, 0x9C, 0x6E, 0xFE, 0x81, 0x41, 0x12, + 0x03, 0x14, 0x08, 0x8F, 0x50, 0x13, 0x87, 0x5A, + 0xC6, 0x56, 0x39, 0x8D, 0x8A, 0x2E, 0xD1, 0x9D, + 0x2A, 0x85, 0xC8, 0xED, 0xD3, 0xEC, 0x2A, 0xEF}}; +const TPM2B_48_BYTE_VALUE NIST_P384_gX = {48, + {0xAA, 0x87, 0xCA, 0x22, 0xBE, 0x8B, 0x05, 0x37, + 0x8E, 0xB1, 0xC7, 0x1E, 0xF3, 0x20, 0xAD, 0x74, + 0x6E, 0x1D, 0x3B, 0x62, 0x8B, 0xA7, 0x9B, 0x98, + 0x59, 0xF7, 0x41, 0xE0, 0x82, 0x54, 0x2A, 0x38, + 0x55, 0x02, 0xF2, 0x5D, 0xBF, 0x55, 0x29, 0x6C, + 0x3A, 0x54, 0x5E, 0x38, 0x72, 0x76, 0x0A, 0xB7}}; +const TPM2B_48_BYTE_VALUE NIST_P384_gY = {48, + {0x36, 0x17, 0xDE, 0x4A, 0x96, 0x26, 0x2C, 0x6F, + 0x5D, 0x9E, 0x98, 0xBF, 0x92, 0x92, 0xDC, 0x29, + 0xF8, 0xF4, 0x1D, 0xBD, 0x28, 0x9A, 0x14, 0x7C, + 0xE9, 0xDA, 0x31, 0x13, 0xB5, 0xF0, 0xB8, 0xC0, + 0x0A, 0x60, 0xB1, 0xCE, 0x1D, 0x7E, 0x81, 0x9D, + 0x7A, 0x43, 0x1D, 0x7C, 0x90, 0xEA, 0x0E, 0x5F}}; +const TPM2B_48_BYTE_VALUE NIST_P384_n = {48, + {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xC7, 0x63, 0x4D, 0x81, 0xF4, 0x37, 0x2D, 0xDF, + 0x58, 0x1A, 0x0D, 0xB2, 0x48, 0xB0, 0xA7, 0x7A, + 0xEC, 0xEC, 0x19, 0x6A, 0xCC, 0xC5, 0x29, 0x73}}; +const TPM2B_1_BYTE_VALUE NIST_P384_h = {1,{1}}; +const ECC_CURVE_DATA NIST_P384 = {&NIST_P384_p.b, &NIST_P384_a.b, &NIST_P384_b.b, + &NIST_P384_gX.b, &NIST_P384_gY.b, &NIST_P384_n.b, + &NIST_P384_h.b}; +#endif // ECC_NIST_P384 +#if defined ECC_NIST_P521 && ECC_NIST_P521 == YES +const TPM2B_66_BYTE_VALUE NIST_P521_p = {66, + {0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF}}; +const TPM2B_66_BYTE_VALUE NIST_P521_a = {66, + {0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFC}}; +const TPM2B_66_BYTE_VALUE NIST_P521_b = {66, + {0x00, 0x51, 0x95, 0x3E, 0xB9, 0x61, 0x8E, 0x1C, + 0x9A, 0x1F, 0x92, 0x9A, 0x21, 0xA0, 0xB6, 0x85, + 0x40, 0xEE, 0xA2, 0xDA, 0x72, 0x5B, 0x99, 0xB3, + 0x15, 0xF3, 0xB8, 0xB4, 0x89, 0x91, 0x8E, 0xF1, + 0x09, 0xE1, 0x56, 0x19, 0x39, 0x51, 0xEC, 0x7E, + 0x93, 0x7B, 0x16, 0x52, 0xC0, 0xBD, 0x3B, 0xB1, + 0xBF, 0x07, 0x35, 0x73, 0xDF, 0x88, 0x3D, 0x2C, + 0x34, 0xF1, 0xEF, 0x45, 0x1F, 0xD4, 0x6B, 0x50, + 0x3F, 0x00}}; +const TPM2B_66_BYTE_VALUE NIST_P521_gX = {66, + {0x00, 0xC6, 0x85, 0x8E, 0x06, 0xB7, 0x04, 0x04, + 0xE9, 0xCD, 0x9E, 0x3E, 0xCB, 0x66, 0x23, 0x95, + 0xB4, 0x42, 0x9C, 0x64, 0x81, 0x39, 0x05, 0x3F, + 0xB5, 0x21, 0xF8, 0x28, 0xAF, 0x60, 0x6B, 0x4D, + 0x3D, 0xBA, 0xA1, 0x4B, 0x5E, 0x77, 0xEF, 0xE7, + 0x59, 0x28, 0xFE, 0x1D, 0xC1, 0x27, 0xA2, 0xFF, + 0xA8, 0xDE, 0x33, 0x48, 0xB3, 0xC1, 0x85, 0x6A, + 0x42, 0x9B, 0xF9, 0x7E, 0x7E, 0x31, 0xC2, 0xE5, + 0xBD, 0x66}}; +const TPM2B_66_BYTE_VALUE NIST_P521_gY = {66, + {0x01, 0x18, 0x39, 0x29, 0x6A, 0x78, 0x9A, 0x3B, + 0xC0, 0x04, 0x5C, 0x8A, 0x5F, 0xB4, 0x2C, 0x7D, + 0x1B, 0xD9, 0x98, 0xF5, 0x44, 0x49, 0x57, 0x9B, + 0x44, 0x68, 0x17, 0xAF, 0xBD, 0x17, 0x27, 0x3E, + 0x66, 0x2C, 0x97, 0xEE, 0x72, 0x99, 0x5E, 0xF4, + 0x26, 0x40, 0xC5, 0x50, 0xB9, 0x01, 0x3F, 0xAD, + 0x07, 0x61, 0x35, 0x3C, 0x70, 0x86, 0xA2, 0x72, + 0xC2, 0x40, 0x88, 0xBE, 0x94, 0x76, 0x9F, 0xD1, + 0x66, 0x50}}; +const TPM2B_66_BYTE_VALUE NIST_P521_n = {66, + {0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFA, 0x51, 0x86, 0x87, 0x83, 0xBF, 0x2F, + 0x96, 0x6B, 0x7F, 0xCC, 0x01, 0x48, 0xF7, 0x09, + 0xA5, 0xD0, 0x3B, 0xB5, 0xC9, 0xB8, 0x89, 0x9C, + 0x47, 0xAE, 0xBB, 0x6F, 0xB7, 0x1E, 0x91, 0x38, + 0x64, 0x09}}; +const TPM2B_1_BYTE_VALUE NIST_P521_h = {1,{1}}; +const ECC_CURVE_DATA NIST_P521 = {&NIST_P521_p.b, &NIST_P521_a.b, &NIST_P521_b.b, + &NIST_P521_gX.b, &NIST_P521_gY.b, &NIST_P521_n.b, + &NIST_P521_h.b}; +#endif // ECC_NIST_P521 +#if defined ECC_BN_P256 && ECC_BN_P256 == YES +const TPM2B_32_BYTE_VALUE BN_P256_p = {32, + {0xFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFC, 0XF0, 0XCD, + 0X46, 0XE5, 0XF2, 0X5E, 0XEE, 0X71, 0XA4, 0X9F, + 0X0C, 0XDC, 0X65, 0XFB, 0X12, 0X98, 0X0A, 0X82, + 0XD3, 0X29, 0X2D, 0XDB, 0XAE, 0XD3, 0X30, 0X13}}; +const TPM2B_1_BYTE_VALUE BN_P256_a = {1,{0}}; +const TPM2B_1_BYTE_VALUE BN_P256_b = {1,{3}}; +const TPM2B_1_BYTE_VALUE BN_P256_gX = {1,{1}}; +const TPM2B_1_BYTE_VALUE BN_P256_gY = {1,{2}};; +const TPM2B_32_BYTE_VALUE BN_P256_n = {32, + {0xFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFC, 0XF0, 0XCD, + 0X46, 0XE5, 0XF2, 0X5E, 0XEE, 0X71, 0XA4, 0X9E, + 0X0C, 0XDC, 0X65, 0XFB, 0X12, 0X99, 0X92, 0X1A, + 0XF6, 0X2D, 0X53, 0X6C, 0XD1, 0X0B, 0X50, 0X0D}}; +const TPM2B_1_BYTE_VALUE BN_P256_h = {1,{1}}; +const ECC_CURVE_DATA BN_P256 = {&BN_P256_p.b, &BN_P256_a.b, &BN_P256_b.b, + &BN_P256_gX.b, &BN_P256_gY.b, &BN_P256_n.b, + &BN_P256_h.b}; +#endif // ECC_BN_P256 +#if defined ECC_BN_P638 && ECC_BN_P638 == YES +const TPM2B_80_BYTE_VALUE BN_P638_p = {80, + {0x23, 0xFF, 0xFF, 0xFD, 0xC0, 0x00, 0x00, 0x0D, + 0x7F, 0xFF, 0xFF, 0xB8, 0x00, 0x00, 0x01, 0xD3, + 0xFF, 0xFF, 0xF9, 0x42, 0xD0, 0x00, 0x16, 0x5E, + 0x3F, 0xFF, 0x94, 0x87, 0x00, 0x00, 0xD5, 0x2F, + 0xFF, 0xFD, 0xD0, 0xE0, 0x00, 0x08, 0xDE, 0x55, + 0xC0, 0x00, 0x86, 0x52, 0x00, 0x21, 0xE5, 0x5B, + 0xFF, 0xFF, 0xF5, 0x1F, 0xFF, 0xF4, 0xEB, 0x80, + 0x00, 0x00, 0x00, 0x4C, 0x80, 0x01, 0x5A, 0xCD, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xEC, 0xE0, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x67}}; +const TPM2B_1_BYTE_VALUE BN_P638_a = {1,{0}}; +const TPM2B_2_BYTE_VALUE BN_P638_b = {2,{0x01,0x01}}; +const TPM2B_80_BYTE_VALUE BN_P638_gX = {80, + {0x23, 0xFF, 0xFF, 0xFD, 0xC0, 0x00, 0x00, 0x0D, + 0x7F, 0xFF, 0xFF, 0xB8, 0x00, 0x00, 0x01, 0xD3, + 0xFF, 0xFF, 0xF9, 0x42, 0xD0, 0x00, 0x16, 0x5E, + 0x3F, 0xFF, 0x94, 0x87, 0x00, 0x00, 0xD5, 0x2F, + 0xFF, 0xFD, 0xD0, 0xE0, 0x00, 0x08, 0xDE, 0x55, + 0xC0, 0x00, 0x86, 0x52, 0x00, 0x21, 0xE5, 0x5B, + 0xFF, 0xFF, 0xF5, 0x1F, 0xFF, 0xF4, 0xEB, 0x80, + 0x00, 0x00, 0x00, 0x4C, 0x80, 0x01, 0x5A, 0xCD, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xEC, 0xE0, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x66}}; +const TPM2B_1_BYTE_VALUE BN_P638_gY = {1,{0x10}}; +const TPM2B_80_BYTE_VALUE BN_P638_n = {80, + {0x23, 0xFF, 0xFF, 0xFD, 0xC0, 0x00, 0x00, 0x0D, + 0x7F, 0xFF, 0xFF, 0xB8, 0x00, 0x00, 0x01, 0xD3, + 0xFF, 0xFF, 0xF9, 0x42, 0xD0, 0x00, 0x16, 0x5E, + 0x3F, 0xFF, 0x94, 0x87, 0x00, 0x00, 0xD5, 0x2F, + 0xFF, 0xFD, 0xD0, 0xE0, 0x00, 0x08, 0xDE, 0x55, + 0x60, 0x00, 0x86, 0x55, 0x00, 0x21, 0xE5, 0x55, + 0xFF, 0xFF, 0xF5, 0x4F, 0xFF, 0xF4, 0xEA, 0xC0, + 0x00, 0x00, 0x00, 0x49, 0x80, 0x01, 0x54, 0xD9, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xED, 0xA0, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x61}}; +const TPM2B_1_BYTE_VALUE BN_P638_h = {1,{1}}; +const ECC_CURVE_DATA BN_P638 = {&BN_P638_p.b, &BN_P638_a.b, &BN_P638_b.b, + &BN_P638_gX.b, &BN_P638_gY.b, &BN_P638_n.b, + &BN_P638_h.b}; +#endif // ECC_BN_P638 +#if defined ECC_SM2_P256 && ECC_SM2_P256 == YES +const TPM2B_32_BYTE_VALUE SM2_P256_p = {32, + {0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}}; +const TPM2B_32_BYTE_VALUE SM2_P256_a = {32, + {0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC}}; +const TPM2B_32_BYTE_VALUE SM2_P256_b = {32, + {0x28, 0xE9, 0xFA, 0x9E, 0x9D, 0x9F, 0x5E, 0x34, + 0x4D, 0x5A, 0x9E, 0x4B, 0xCF, 0x65, 0x09, 0xA7, + 0xF3, 0x97, 0x89, 0xF5, 0x15, 0xAB, 0x8F, 0x92, + 0xDD, 0xBC, 0xBD, 0x41, 0x4D, 0x94, 0x0E, 0x93}}; +const TPM2B_32_BYTE_VALUE SM2_P256_gX = {32, + {0x32, 0xC4, 0xAE, 0x2C, 0x1F, 0x19, 0x81, 0x19, + 0x5F, 0x99, 0x04, 0x46, 0x6A, 0x39, 0xC9, 0x94, + 0x8F, 0xE3, 0x0B, 0xBF, 0xF2, 0x66, 0x0B, 0xE1, + 0x71, 0x5A, 0x45, 0x89, 0x33, 0x4C, 0x74, 0xC7}}; +const TPM2B_32_BYTE_VALUE SM2_P256_gY = {32, + {0xBC, 0x37, 0x36, 0xA2, 0xF4, 0xF6, 0x77, 0x9C, + 0x59, 0xBD, 0xCE, 0xE3, 0x6B, 0x69, 0x21, 0x53, + 0xD0, 0xA9, 0x87, 0x7C, 0xC6, 0x2A, 0x47, 0x40, + 0x02, 0xDF, 0x32, 0xE5, 0x21, 0x39, 0xF0, 0xA0}}; +const TPM2B_32_BYTE_VALUE SM2_P256_n = {32, + {0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0x72, 0x03, 0xDF, 0x6B, 0x21, 0xC6, 0x05, 0x2B, + 0x53, 0xBB, 0xF4, 0x09, 0x39, 0xD5, 0x41, 0x23}}; +const TPM2B_1_BYTE_VALUE SM2_P256_h = {1,{1}}; +const ECC_CURVE_DATA SM2_P256 = {&SM2_P256_p.b, &SM2_P256_a.b, &SM2_P256_b.b, + &SM2_P256_gX.b, &SM2_P256_gY.b, &SM2_P256_n.b, + &SM2_P256_h.b}; +#endif // ECC_SM2_P256 +#define comma +const ECC_CURVE eccCurves[] = { +#if defined ECC_NIST_P192 && ECC_NIST_P192 == YES + comma + {TPM_ECC_NIST_P192, + 192, + {TPM_ALG_KDF1_SP800_56A,TPM_ALG_SHA256}, + {TPM_ALG_NULL,TPM_ALG_NULL}, + &NIST_P192 CURVE_NAME("NIST_P192")} +# undef comma +# define comma , +#endif // ECC_NIST_P192 +#if defined ECC_NIST_P224 && ECC_NIST_P224 == YES + comma + {TPM_ECC_NIST_P224, + 224, + {TPM_ALG_KDF1_SP800_56A,TPM_ALG_SHA256}, + {TPM_ALG_NULL,TPM_ALG_NULL}, + &NIST_P224 CURVE_NAME("NIST_P224")} +# undef comma +# define comma , +#endif // ECC_NIST_P224 +#if defined ECC_NIST_P256 && ECC_NIST_P256 == YES + comma + {TPM_ECC_NIST_P256, + 256, + {TPM_ALG_KDF1_SP800_56A,TPM_ALG_SHA256}, + {TPM_ALG_NULL,TPM_ALG_NULL}, + &NIST_P256 CURVE_NAME("NIST_P256")} +# undef comma +# define comma , +#endif // ECC_NIST_P256 +#if defined ECC_NIST_P384 && ECC_NIST_P384 == YES + comma + {TPM_ECC_NIST_P384, + 384, + {TPM_ALG_KDF1_SP800_56A,TPM_ALG_SHA384}, + {TPM_ALG_NULL,TPM_ALG_NULL}, + &NIST_P384 CURVE_NAME("NIST_P384")} +# undef comma +# define comma , +#endif // ECC_NIST_P384 +#if defined ECC_NIST_P521 && ECC_NIST_P521 == YES + comma + {TPM_ECC_NIST_P521, + 521, + {TPM_ALG_KDF1_SP800_56A,TPM_ALG_SHA512}, + {TPM_ALG_NULL,TPM_ALG_NULL}, + &NIST_P521 CURVE_NAME("NIST_P521")} +# undef comma +# define comma , +#endif // ECC_NIST_P521 +#if defined ECC_BN_P256 && ECC_BN_P256 == YES + comma + {TPM_ECC_BN_P256, + 256, + {TPM_ALG_NULL,TPM_ALG_NULL}, + {TPM_ALG_NULL,TPM_ALG_NULL}, + &BN_P256 CURVE_NAME("BN_P256")} +# undef comma +# define comma , +#endif // ECC_BN_P256 +#if defined ECC_BN_P638 && ECC_BN_P638 == YES + comma + {TPM_ECC_BN_P638, + 638, + {TPM_ALG_NULL,TPM_ALG_NULL}, + {TPM_ALG_NULL,TPM_ALG_NULL}, + &BN_P638 CURVE_NAME("BN_P638")} +# undef comma +# define comma , +#endif // ECC_BN_P638 +#if defined ECC_SM2_P256 && ECC_SM2_P256 == YES + comma + {TPM_ECC_SM2_P256, + 256, + {TPM_ALG_KDF1_SP800_56A,TPM_ALG_SM3_256}, + {TPM_ALG_NULL,TPM_ALG_NULL}, + &SM2_P256 CURVE_NAME("SM2_P256")} +# undef comma +# define comma , +#endif // ECC_SM2_P256 +}; +#endif // TPM_ALG_ECC diff --git a/src/tpm2/crypto/openssl/CryptDes.c b/src/tpm2/crypto/openssl/CryptDes.c new file mode 100644 index 00000000..da03ff52 --- /dev/null +++ b/src/tpm2/crypto/openssl/CryptDes.c @@ -0,0 +1,180 @@ +/********************************************************************************/ +/* */ +/* */ +/* Written by Ken Goldman */ +/* IBM Thomas J. Watson Research Center */ +/* $Id: CryptDes.c 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 */ +/* */ +/********************************************************************************/ + +/* 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" +#ifdef TPM_ALG_TDES +#define DES_NUM_WEAK 64 +const UINT64 DesWeakKeys[DES_NUM_WEAK] = { + 0x0101010101010101, 0xFEFEFEFEFEFEFEFE, 0xE0E0E0E0F1F1F1F1, 0x1F1F1F1F0E0E0E0E, + 0x011F011F010E010E, 0x1F011F010E010E01, 0x01E001E001F101F1, 0xE001E001F101F101, + 0x01FE01FE01FE01FE, 0xFE01FE01FE01FE01, 0x1FE01FE00EF10EF1, 0xE01FE01FF10EF10E, + 0x1FFE1FFE0EFE0EFE, 0xFE1FFE1FFE0EFE0E, 0xE0FEE0FEF1FEF1FE, 0xFEE0FEE0FEF1FEF1, + 0x01011F1F01010E0E, 0x1F1F01010E0E0101, 0xE0E01F1FF1F10E0E, 0x0101E0E00101F1F1, + 0x1F1FE0E00E0EF1F1, 0xE0E0FEFEF1F1FEFE, 0x0101FEFE0101FEFE, 0x1F1FFEFE0E0EFEFE, + 0xE0FE011FF1FE010E, 0x011F1F01010E0E01, 0x1FE001FE0EF101FE, 0xE0FE1F01F1FE0E01, + 0x011FE0FE010EF1FE, 0x1FE0E01F0EF1F10E, 0xE0FEFEE0F1FEFEF1, 0x011FFEE0010EFEF1, + 0x1FE0FE010EF1FE01, 0xFE0101FEFE0101FE, 0x01E01FFE01F10EFE, 0x1FFE01E00EFE01F1, + 0xFE011FE0FE010EF1, 0xFE01E01FFE01F10E, 0x1FFEE0010EFEF101, 0xFE1F01E0FE0E01F1, + 0x01E0E00101F1F101, 0x1FFEFE1F0EFEFE0E, 0xFE1FE001FE0EF101, 0x01E0FE1F01F1FE0E, + 0xE00101E0F10101F1, 0xFE1F1FFEFE0E0EFE, 0x01FE1FE001FE0EF1, 0xE0011FFEF1010EFE, + 0xFEE0011FFEF1010E, 0x01FEE01F01FEF10E, 0xE001FE1FF101FE0E, 0xFEE01F01FEF10E01, + 0x01FEFE0101FEFE01, 0xE01F01FEF10E01FE, 0xFEE0E0FEFEF1F1FE, 0x1F01011F0E01010E, + 0xE01F1FE0F10E0EF1, 0xFEFE0101FEFE0101, 0x1F01E0FE0E01F1FE, 0xE01FFE01F10EFE01, + 0xFEFE1F1FFEFE0E0E, 0x1F01FEE00E01FEF1, 0xE0E00101F1F10101, 0xFEFEE0E0FEFEF1F1}; +/* 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. */ +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); + 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 + DRBG_Generate(rand, pK, sensitive->sensitive.sym.t.size); + 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 00000000..0c706386 --- /dev/null +++ b/src/tpm2/crypto/openssl/CryptEccKeyExchange.c @@ -0,0 +1,361 @@ +/********************************************************************************/ +/* */ +/* */ +/* Written by Ken Goldman */ +/* IBM Thomas J. Watson Research Center */ +/* $Id: CryptEccKeyExchange.c 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 */ +/* */ +/********************************************************************************/ + +/* 10.2.11 CryptEccKeyExchange.c */ +#include "Tpm.h" +#if CC_ZGen_2Phase == YES //% +#ifdef TPM_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) */ +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_SUCCESS results is valid */ +/* TPM_RC_NO_RESULTS 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); + ECC_CURVE_DATA *C = AccessCurveData(E); + 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); + // 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 // TPM_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; +#ifdef TPM_ALG_ECMQV + case TPM_ALG_ECMQV: + return C_2_2_MQV(outZ1, curveId, dsA, deA, QsB, QeB); + break; +#endif +#ifdef TPM_ALG_SM2 + case TPM_ALG_SM2: + return SM2KeyExchange(outZ1, curveId, dsA, deA, QsB, QeB); + break; +#endif + default: + return TPM_RC_SCHEME; + } +} +#ifdef TPM_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_SUCCESS results is valid */ +/* TPM_RC_NO_RESULTS 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 = (E != NULL) ? AccessCurveData(E) : NULL; + 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); + 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 00000000..71e9d9bc --- /dev/null +++ b/src/tpm2/crypto/openssl/CryptEccMain.c @@ -0,0 +1,754 @@ +/********************************************************************************/ +/* */ +/* */ +/* Written by Ken Goldman */ +/* IBM Thomas J. Watson Research Center */ +/* $Id: CryptEccMain.c 953 2017-03-06 20:31: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, 2017 */ +/* */ +/********************************************************************************/ + +/* 10.2.12 CryptEccMain.c */ +/* 10.2.12.1 Includes and Defines */ +#include "Tpm.h" +#ifdef TPM_ALG_ECC +/* This version requires that the new format for ECC data be used */ +#ifndef USE_BN_ECC_DATA +#error "Need to define USE_BN_ECC_DATA in Implementaion.h" +#endif +/* 10.2.12.2 Functions */ +#ifdef SIMULATION +void +EccSimulationEnd( + void + ) +{ +#ifdef SIMULATION + // put things to be printed at the end of the simulation here +#endif +} +#endif // SIMULATION +/* 10.2.12.2.1 CryptEccInit() */ +/* This function is called at _TPM_Init() */ +BOOL +CryptEccInit( + void + ) +{ + return TRUE; +} +/* 10.2.12.2.2 CryptEccStartup() */ +/* This function is called at TPM2_Startup(). */ +BOOL +CryptEccStartup( + void + ) +{ + return TRUE; +} +/* 10.2.12.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.12.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 value 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.12.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.12.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.12.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.12.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.12.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(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.12.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.12.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 & 0xffffffffffff0000) | *c; + } + // 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; + // Arbitrary upper limit on the number of times that we can look for + // a suitable random value. The normally number of tries will be 1. + for(iterations = 1; iterations < 1000000;) + { + int i; + CryptKDFa(CONTEXT_INTEGRITY_HASH_ALG, &gr.commitNonce.b, COMMIT_STRING, + &name->b, &cntr.b, n.t.size * 8, r->t.buffer, &iterations, FALSE); + // "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.12.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.12.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.12.2.14 CryptEccGetParameters() */ +/* This function returns the ECC parameter details of the given curve */ +/* Return Values Meaning */ +/* TRUE Get parameters 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, ¶meters->p.b, 0); + BnTo2B(data->a, ¶meters->a.b, 0); + BnTo2B(data->b, ¶meters->b.b, 0); + BnTo2B(data->base.x, ¶meters->gX.b, parameters->p.t.size); + BnTo2B(data->base.y, ¶meters->gY.b, parameters->p.t.size); + BnTo2B(data->order, ¶meters->n.b, 0); + BnTo2B(data->h, ¶meters->h.b, 0); + } + return found; +} +/* 10.2.12.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.12.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.12.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.12.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.12.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_RESULTS if the resulting point is the point at infinity. */ +/* Error Returns Meaning */ +/* TPM_RC_NO_RESULTS 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 0 < d < 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, E->C); + OK = OK && ((Q == NULL) || BnIsOnCurve(Q, E->C)); + 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.12.2.20 BnEccGetPrivate() */ +/* This function gets random values with no more bits than are in q (the curve order) until it finds + a value (d) such that 1 <= d < q. This is the method of FIPS 186-3 Section B.1.2 'Key Pair + Generation by Testing Candidates' with minor optimizations to reduce the need for a local + parameter to hold the value of q - 2. */ +/* The execution time of this function is non-deterministic. However, the probability that the + search will take more than one iteration is very small. As a consequence, the weighted-average + run time for this function is significantly less than the method of key pair generation with + extra random bits. */ +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); + // + do + { + BnGetRandomBits(dOut, BnSizeInBits(order), rand); + BnAddWord(dOut, dOut, 1); + } while(BnUnsignedCmp(dOut, order) >= 0); + return TRUE; +} +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; + int limit; + for(limit = 100; (limit > 0) && !OK; limit--) + { + // Get a private scalar + BnEccGetPrivate(bnD, E->C, rand); + // Do a point multiply + OK = BnEccModMult(ecQ, NULL, bnD, E); + } + if(!OK) + BnSetWord(ecQ->z, 0); + else + BnSetWord(ecQ->z, 1); + return OK; +} +/* 10.2.12.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.12.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_RESULTS 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.12.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.12.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_FAIL ??? */ +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); + const UINT32 MaxCount = 100; + UINT32 count = 0; + TPM_RC retVal = TPM_RC_NO_RESULT; + 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; + // Start search for key (should be quick) + for(count = 1; (count < MaxCount) && (retVal != TPM_RC_SUCCESS); count++) + { + if(!BnEccGenerateKeyPair(bnD, ecQ, E, rand)) + FAIL(FATAL_ERROR_INTERNAL); + retVal = TPM_RC_SUCCESS; +#ifdef FIPS_COMPLIANT + // See if PWCT is required + if(publicArea->objectAttributes.sign) + { + ECC_NUM(bnT); + ECC_NUM(bnS); + TPM2B_DIGEST digest; + TEST(TPM_ALG_ECDSA); + digest.t.size = + (UINT16)BITS_TO_BYTES(BnSizeInBits(CurveGetPrime( + AccessCurveData(E)))); + // Get a random value to sign using the current DRBG state + DRBG_Generate(NULL, digest.t.buffer, digest.t.size); + BnSignEcdsa(bnT, bnS, E, bnD, &digest, NULL); + // and make sure that we can validate the signature + retVal = BnValidateSignatureEcdsa(bnT, bnS, E, ecQ, &digest); + } +#endif + } + // if counter maxed out, put the TPM to failure mode + if(count == MaxCount) + FAIL(FATAL_ERROR_INTERNAL); + // Convert results + BnPointTo2B(&publicArea->unique.ecc, ecQ, E); + BnTo2B(bnD, &sensitive->sensitive.ecc.b, publicArea->unique.ecc.x.t.size); + Exit: + CURVE_FREE(E); + return retVal; +} +#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 00000000..ab2e2fc1 --- /dev/null +++ b/src/tpm2/crypto/openssl/CryptEccSignature.c @@ -0,0 +1,885 @@ +/********************************************************************************/ +/* */ +/* */ +/* Written by Ken Goldman */ +/* IBM Thomas J. Watson Research Center */ +/* $Id: CryptEccSignature.c 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 */ +/* */ +/********************************************************************************/ + +/* 10.2.13 CryptEccSignature.c */ +/* 10.2.13.1 Includes and Defines */ +#include "Tpm.h" +#include "CryptEccSignature_fp.h" +#ifdef TPM_ALG_ECC +/* 10.2.13.2 Utility Functions */ +/* 10.2.13.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. */ +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; +} +/* 10.2.13.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.13.3 Signing Functions */ +/* 10.2.13.3.1 BnSignEcdsa() */ +/* This function implements the ECDSA signing algorithm. The method is described in the comments + below. This version works with internal numbers. */ +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_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; +} +#if ALG_ECDAA +/* 10.2.13.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 */ +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 k is not defined until CrypGenerateR() + // is done. + ECC_INITIALIZED(bnR, &r); + do + { + // generate nonceK such that 0 < nonceK < n + // use bnT as a temp. + BnEccGetPrivate(bnT, AccessCurveData(E), rand); + 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); + // 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.13.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.13.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); + // 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 +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.13.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_INITIALIZZED(bnE, digest); // Don't know how big digest might be + ECC_NUM(bnN); + ECC_NUM(bnK); + ECC_NUM(bnX1); + ECC_NUM(bnT); // temp + POINT(Q1); + bigConst order = (E != NULL) + ? CurveGetOrder(AccessCurveData(E)) : NULL; + // +#ifdef _SM2_SIGN_DEBUG + BnFromHex(bnE, + "B524F552CD82B8B028476E005C377FB19A87E6FC682D48BB5D42E3D9B9EFFE76"); + BnFromHex(bnD, + "128B2FA8BD433C6C068C8D803DFF79792A519A55171B1B650C23661D15897263"); +#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 + BnGenerateRandomInRange(bnK, order, rand); +#ifdef _SM2_SIGN_DEBUG + BnFromHex(bnK, + "6CB28D99385C175C94F94E934817663FC176D925DD72B727260DBAAE1FB2F96F"); +#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, bnK, E) != TPM_RC_SUCCESS) + goto loop; + // A5: Figure out r = (e + x1) mod n, + BnAdd(bnR, bnE, bnX1); + BnMod(bnR, order); +#ifdef _SM2_SIGN_DEBUG + pAssert(BnHexEqual(bnR, + "40F1EC59F793D9F49E09DCEF49130D4194F79FB1EED2CAA55BACDB49C4E755D1")); +#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, + "79BFCF3052C80DA7B939E0C6914A18CBB2D96D8555256E83122743A7D4F5F956")); +#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, + "6FC6DAC32C5D5CF10C77DFB20F7C2EB667A457872FB09EC56327A67EC7DEEBE7")); +#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, + "40F1EC59F793D9F49E09DCEF49130D4194F79FB1EED2CAA55BACDB49C4E755D1")); + pAssert(BnHexEqual(bnS, + "6FC6DAC32C5D5CF10C77DFB20F7C2EB667A457872FB09EC56327A67EC7DEEBE7")); +#endif + return TPM_RC_SUCCESS; +} +#endif // ALG_SM2 +/* 10.2.13.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 = AccessCurveData(E); + TPM_RC retVal; + // + NOT_REFERENCED(scheme); + if(E == NULL) + ERROR_RETURN(TPM_RC_VALUE); + 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); + // Prime order for this implementation needs to be a multiple of a byte + // so, no P521 for now. + pAssert((BnSizeInBits(CurveGetPrime(C)) & 7) == 0); + pAssert((BnSizeInBits(CurveGetOrder(C)) & 7) == 0); + TEST(signature->sigAlg); + switch(signature->sigAlg) + { + case ALG_ECDSA_VALUE: + retVal = BnSignEcdsa(bnR, bnS, E, bnD, digest, rand); + break; +#if ALG_ECDAA + case ALG_ECDAA_VALUE: + retVal = BnSignEcdaa(&signature->signature.ecdaa.signatureR, bnS, E, + bnD, digest, scheme, signKey, rand); + bnR = NULL; + break; +#endif +#if ALG_ECSCHNORR + case ALG_ECSCHNORR_VALUE: + retVal = BnSignEcSchnorr(bnR, bnS, E, bnD, digest, + signature->signature.ecschnorr.hash, + rand); + break; +#endif +#if ALG_SM2 + case ALG_SM2_VALUE: + retVal = BnSignEcSm2(bnR, bnS, E, bnD, digest, rand); + break; +#endif + default: + return TPM_RC_SCHEME; + } + // 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.13.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 */ +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_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; +} +#endif //% ALG_ECDSA +#if ALG_SM2 +/* 10.2.13.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, bnT, 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) + BnAdd(bnRp, bnE, P->x); + BnMod(bnRp, order); + // f) verify that r' = r + OK = (BnUnsignedCmp(bnR, bnRp) != 0) & OK; + if(!OK) + return TPM_RC_SIGNATURE; + else + return TPM_RC_SUCCESS; +} +#endif //% ALG_SM2 +#if ALG_ECSCHNORR +/* 10.2.13.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.13.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 ALG_ECDSA_VALUE: +#if ALG_ECSCHNORR + case ALG_ECSCHNORR_VALUE: +#endif +#if ALG_SM2 + case ALG_SM2_VALUE: +#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 ALG_ECDSA_VALUE: + retVal = BnValidateSignatureEcdsa(bnR, bnS, E, ecQ, digest); + break; +#if ALG_ECSCHNORR + case ALG_ECSCHNORR_VALUE: + retVal = BnValidateSignatureEcSchnorr(bnR, bnS, + signature->signature.any.hashAlg, + E, ecQ, digest); + break; +#endif +#if ALG_SM2 + case ALG_SM2_VALUE: + retVal = BnValidateSignatureEcSm2(bnR, bnS, E, ecQ, digest); + break; +#endif + default: + FAIL(FATAL_ERROR_INTERNAL); + } + Exit: + CURVE_FREE(E); + return retVal; +} +/* 10.2.13.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_SUCCESS computations completed normally */ +/* 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); + 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 00000000..6dcf4906 --- /dev/null +++ b/src/tpm2/crypto/openssl/CryptHash.c @@ -0,0 +1,860 @@ +/********************************************************************************/ +/* */ +/* */ +/* Written by Ken Goldman */ +/* IBM Thomas J. Watson Research Center */ +/* $Id: CryptHash.c 953 2017-03-06 20:31: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, 2017 */ +/* */ +/********************************************************************************/ + +/* 10.2.14 CryptHash.c */ +/* 10.2.14.1 Description */ +/* This file contains implementation of cryptographic functions for hashing. */ +/* 10.2.14.2 Includes, Defines, and Types */ +#define _CRYPT_HASH_C_ +#include "Tpm.h" +#define HASH_TABLE_SIZE (HASH_COUNT + 1) +extern const HASH_INFO g_hashData[HASH_COUNT + 1]; +#ifdef TPM_ALG_SHA1 +HASH_DEF_TEMPLATE(SHA1); +#endif +#ifdef TPM_ALG_SHA256 +HASH_DEF_TEMPLATE(SHA256); +#endif +#ifdef TPM_ALG_SHA384 +HASH_DEF_TEMPLATE(SHA384); +#endif +#ifdef TPM_ALG_SHA512 +HASH_DEF_TEMPLATE(SHA512); +#endif +HASH_DEF nullDef = {{0}}; +/* 10.2.14.3 Obligatory Initialization Functions */ +BOOL +CryptHashInit( + void + ) +{ + LibHashInit(); + return TRUE; +} +BOOL +CryptHashStartup( + void + ) +{ + return TRUE; +} +/* 10.2.14.4 Hash Information Access Functions */ +/* 10.2.14.4.1 Introduction */ +/* These functions provide access to the hash algorithm description information. */ +/* 10.2.14.4.2 CryptGetHashDef() */ +/* This function accesses the hash descriptor associated with a hash a algorithm. The function + returns NULL for TPM_ALG_NULL and fails if hashAlg is not a hash algorithm. */ +PHASH_DEF +CryptGetHashDef( + TPM_ALG_ID hashAlg + ) +{ + PHASH_DEF retVal; + switch(hashAlg) + { +#ifdef TPM_ALG_SHA1 + case TPM_ALG_SHA1: + return &SHA1_Def; + break; +#endif +#ifdef TPM_ALG_SHA256 + case TPM_ALG_SHA256: + retVal = &SHA256_Def; + break; +#endif +#ifdef TPM_ALG_SHA384 + case TPM_ALG_SHA384: + retVal = &SHA384_Def; + break; +#endif +#ifdef TPM_ALG_SHA512 + case TPM_ALG_SHA512: + retVal = &SHA512_Def; + break; +#endif + default: + retVal = &nullDef; + break; + } + return retVal; +} +/* 10.2.14.4.3 CryptHashIsImplemented() */ +/* 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 Values Meaning */ +/* TRUE hashAlg is a valid, implemented hash on this TPM. */ +/* FALSE not valid */ +BOOL +CryptHashIsImplemented( + TPM_ALG_ID hashAlg, + BOOL flag + ) +{ + switch(hashAlg) + { +#ifdef TPM_ALG_SHA1 + case TPM_ALG_SHA1: +#endif +#ifdef TPM_ALG_SHA256 + case TPM_ALG_SHA256: +#endif +#ifdef TPM_ALG_SHA384 + case TPM_ALG_SHA384: +#endif +#ifdef TPM_ALG_SHA512 + case TPM_ALG_SHA512: +#endif +#ifdef TPM_ALG_SM3_256 + case TPM_ALG_SHA256: +#endif + return TRUE; + break; + case TPM_ALG_NULL: + return flag; + break; + default: + break; + } + return FALSE; +} +/* 10.2.14.4.4 GetHashInfoPointer() */ +/* This function returns a pointer to the hash info for the algorithm. If the algorithm is not + supported, function returns a pointer to the data block associated with TPM_ALG_NULL. */ +/* NOTE: The data structure must have a digest size of 0 for TPM_ALG_NULL. */ +static +const HASH_INFO * +GetHashInfoPointer( + TPM_ALG_ID hashAlg + ) +{ + UINT32 i; + // + // TPM_ALG_NULL is the stop value so search up to it + for(i = 0; i < HASH_COUNT; i++) + { + if(g_hashData[i].alg == hashAlg) + return &g_hashData[i]; + } + // either the input was TPM_ALG_NUL or we didn't find the requested algorithm + // in either case return a pointer to the TPM_ALG_NULL "hash" descriptor + return &g_hashData[HASH_COUNT]; +} +/* 10.2.14.4.5 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 Values 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 + ) +{ + if(index >= HASH_COUNT) + return TPM_ALG_NULL; + return g_hashData[index].alg; +} +/* 10.2.14.4.6 CryptHashGetDigestSize() */ +/* Returns the size of the digest produced by the hash. If hashAlg is not a hash algorithm, the TPM + will FAIL. */ +/* Return Values 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.14.4.7 CryptHashGetBlockSize() */ +/* Returns the size of the block used by the hash. If hashAlg is not a hash algorithm, the TPM will + FAIL. */ +/* Return Values 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.14.4.8 CryptHashGetDer */ +/* This function returns a pointer to the DER string for the algorithm and indicates its size. */ +LIB_EXPORT UINT16 +CryptHashGetDer( + TPM_ALG_ID hashAlg, // IN: the algorithm to look up + const BYTE **p + ) +{ + const HASH_INFO *q; + q = GetHashInfoPointer(hashAlg); + *p = &q->der[0]; + return q->derSize; +} +/* 10.2.14.4.9 CryptHashGetContextAlg() */ +/* This function returns the hash algorithm associated with a hash context. */ +TPM_ALG_ID +CryptHashGetContextAlg( + PHASH_STATE state // IN: the context to check + ) +{ + return state->hashAlg; +} +/* 10.2.14.5 State Import and Export */ +#if 1 +/* 10.2.14.5.1 CryptHashCopyState */ +/* This function is used to clone a HASH_STATE. */ +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) + { + // Just verify that the hashAlg makes sense (is implemented) + CryptGetHashDef(in->hashAlg); + // ... and copy. + 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 //0 +/* 10.2.14.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)); +#define CopyToOffset(value) \ + memcpy(&outBuf[offsetof(HASH_STATE,value)], &internalFmt->value, \ + sizeof(internalFmt->value)) + CopyToOffset(hashAlg); + CopyToOffset(type); + 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.14.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) + { + 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)); + } + } +} +/* 10.2.14.6 State Modification Functions */ +/* 10.2.14.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) + 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; + // hashState->hashAlg = TPM_ALG_ERROR; + return (UINT16)dOutSize; +} +/* 10.2.14.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 Values 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.14.6.3 CryptDigestUpdate() */ +/* Add data to a hash or HMAC stack. */ +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 + ) +{ + if(hashState->hashAlg != TPM_ALG_NULL) + { + pAssert((hashState->type == HASH_STATE_HASH) + || (hashState->type == HASH_STATE_HMAC)); + hashState->def = CryptGetHashDef(hashState->hashAlg); + HASH_DATA(hashState, dataSize, (BYTE *)data); + } + return; +} +/* 10.2.14.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 Values 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.14.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 Values 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.14.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.14.6.7 CryptHashEnd2B() */ +/* This function is the same as CypteCompleteHash() 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 Values 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.14.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 == YES + intValue = REVERSE_ENDIAN_64(intValue); +#endif + CryptDigestUpdate(state, intSize, &((BYTE *)&intValue)[8 - intSize]); +} +/* 10.2.14.7 HMAC Functions */ +/* 10.2.14.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 Values 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.14.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 Values 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; + 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.14.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 Values 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.14.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 Values 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.14.8 Mask and Key Generation Functions */ +/* 10.2.14.8.1 _crypi_MGF1() */ +/* This function performs MGF1 using the selected hash. MGF1 is T(n) = T(n-1) || H(seed || + counter). This function returns the length of the mask produced which could be zero if the digest + algorithm is not supported */ +/* Return Values Meaning */ +/* 0 hash algorithm was TPM_ALG_NULL */ +/* > 0 should be the same as mSize */ +LIB_EXPORT UINT16 +CryptMGF1( + 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 + ) +{ + HASH_STATE hashState; + PHASH_DEF hDef = CryptGetHashDef(hashAlg); + UINT32 remaining; + UINT32 counter = 0; + BYTE swappedCounter[4]; + // If there is no digest to compute return + if((hashAlg == TPM_ALG_NULL) || (mSize == 0)) + return 0; + for(remaining = mSize; ; remaining -= hDef->digestSize) + { + // Because the system may be either Endian... + UINT32_TO_BYTE_ARRAY(counter, swappedCounter); + // Start the hash and include the seed and counter + CryptHashStart(&hashState, hashAlg); + CryptDigestUpdate(&hashState, seedSize, seed); + CryptDigestUpdate(&hashState, 4, swappedCounter); + // Handling the completion depends on how much space remains in the mask + // buffer. If it can hold the entire digest, put it there. If not + // put the digest in a temp buffer and only copy the amount that + // will fit into the mask buffer. + HashEnd(&hashState, remaining, mask); + if(remaining <= hDef->digestSize) + break; + mask = &mask[hDef->digestSize]; + counter++; + } + return (UINT16)mSize; +} +/* 10.2.14.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 Values 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. + BOOL once // IN: TRUE - only 1 iteration is performed + // FALSE if iteration count determined by + // "sizeInBits" + ) +{ + UINT32 counter = 0; // counter value + INT16 bytes; // number of bytes to produce + BYTE *stream = keyStream; + HMAC_STATE hState; + UINT16 digestSize = CryptHashGetDigestSize(hashAlg); + pAssert(key != NULL && keyStream != NULL); + pAssert(once == FALSE || (sizeInBits & 7) == 0); + 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); + bytes = once ? digestSize : (INT16)((sizeInBits + 7) / 8); + // Generate required bytes + for(; bytes > 0; bytes -= digestSize) + { + counter++; + if(bytes < digestSize) + digestSize = bytes; + // 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); + CryptHmacEnd(&hState, digestSize, stream); + stream = &stream[digestSize]; + } + // Mask off bits if the required bits is not a multiple of byte size + if((sizeInBits % 8) != 0) + keyStream[0] &= ((1 << (sizeInBits % 8)) - 1); + if(counterInOut != NULL) + *counterInOut = counter; + return (UINT16)((sizeInBits + 7) / 8); +} +/* 10.2.14.8.3 CryptKDFe() */ +/* 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 Values 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/CryptHashData.c b/src/tpm2/crypto/openssl/CryptHashData.c new file mode 100644 index 00000000..db782568 --- /dev/null +++ b/src/tpm2/crypto/openssl/CryptHashData.c @@ -0,0 +1,86 @@ +/********************************************************************************/ +/* */ +/* */ +/* Written by Ken Goldman */ +/* IBM Thomas J. Watson Research Center */ +/* $Id: CryptHashData.c 901 2017-01-08 04:14: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 */ +/* */ +/********************************************************************************/ + +/* 10.2.15 CryptHashData.c */ +#include "Tpm.h" +const HASH_INFO g_hashData[HASH_COUNT + 1] = { +#ifdef TPM_ALG_SHA1 + {TPM_ALG_SHA1, SHA1_DIGEST_SIZE, SHA1_BLOCK_SIZE, + SHA1_DER_SIZE, {SHA1_DER}}, +#endif +#ifdef TPM_ALG_SHA256 + {TPM_ALG_SHA256, SHA256_DIGEST_SIZE, SHA256_BLOCK_SIZE, + SHA256_DER_SIZE, {SHA256_DER}}, +#endif +#ifdef TPM_ALG_SHA384 + {TPM_ALG_SHA384, SHA384_DIGEST_SIZE, SHA384_BLOCK_SIZE, + SHA384_DER_SIZE, {SHA384_DER}}, +#endif +#ifdef TPM_ALG_SHA512 + {TPM_ALG_SHA512, SHA512_DIGEST_SIZE, SHA512_BLOCK_SIZE, + SHA512_DER_SIZE, {SHA512_DER}}, +#endif +#ifdef TPM_ALG_SM3_256 + {TPM_ALG_SM3_256, SM3_256_DIGEST_SIZE, SM3_256_BLOCK_SIZE, + SM3_256_DER_SIZE, {SM3_256_DER}}, +#endif + {TPM_ALG_NULL,0,0,0,{0}} +}; diff --git a/src/tpm2/crypto/openssl/CryptPrime.c b/src/tpm2/crypto/openssl/CryptPrime.c new file mode 100644 index 00000000..9b138e5c --- /dev/null +++ b/src/tpm2/crypto/openssl/CryptPrime.c @@ -0,0 +1,343 @@ +/********************************************************************************/ +/* */ +/* Code for prime validation. */ +/* Written by Ken Goldman */ +/* IBM Thomas J. Watson Research Center */ +/* $Id: CryptPrime.c 953 2017-03-06 20:31: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, 2017 */ +/* */ +/********************************************************************************/ + +/* 10.2.16 CryptPrime.c */ +#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.16.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.16.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; +} +/* 10.2.16.1.3 BnIsPrime() */ +/* 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(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); +} +/* 10.2.16.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.16.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 = 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. + do + { + BnGetRandomBits(bnB, wLen, rand); + // 4.2 If ((b <= 1) or (b >= w1)), then go to step 4.1. + } while((BnUnsignedCmpWord(bnB, 1) <= 0) + || (BnUnsignedCmp(bnB, bnWm1) >= 0)); + // 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; +} +#ifdef TPM_ALG_RSA //% +/* 10.2.16.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 + ) +{ +#ifndef 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(TPM_RC_VALUE); + Exit: + return retVal; +#else + return PrimeSelectWithSieve(prime, exponent, rand); +#endif +} +/* 10.2.16.1.7 AdjustPrimeCandiate() */ +/* 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 is approximated with 0xB505 which is, in + fixed point is 0.7071075439453125 or an error of 0.0001%. 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. */ +/* The function also puts the number on a field boundary. */ +LIB_EXPORT void +RsaAdjustPrimeCandidate( + 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.16.1.8 BnGeneratePrimeForRSA() */ +/* Function to generate a prime of the desired size with the proper attributes for an RSA prime. */ +void +BnGeneratePrimeForRSA( + bigNum prime, + UINT32 bits, + UINT32 exponent, + RAND_STATE *rand + ) +{ + 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) + { + DRBG_Generate(rand, (BYTE *)prime->d, (UINT16)BITS_TO_BYTES(bits)); + RsaAdjustPrimeCandidate(prime); + found = RsaCheckPrime(prime, exponent, rand) == 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 00000000..190cd744 --- /dev/null +++ b/src/tpm2/crypto/openssl/CryptPrimeSieve.c @@ -0,0 +1,518 @@ +/********************************************************************************/ +/* */ +/* */ +/* Written by Ken Goldman */ +/* IBM Thomas J. Watson Research Center */ +/* $Id: CryptPrimeSieve.c 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 */ +/* */ +/********************************************************************************/ + +/* 10.2.17 CryptPrimeSieve.c */ +/* 10.2.17.1 Includes and defines */ +#include "Tpm.h" +#define RSA_KEY_SIEVE +#if defined 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. */ +LIB_EXPORT 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; + 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. */ +LIB_EXPORT 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 */ +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 + ) +{ + 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. */ +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 + ) +{ + UINT32 i; /* kgold changed to unsigned */ + 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 = 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 = 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 the field starts at some + // arbitrary offset within the number space. If the field were all numbers, + // then we would have gone through some number of bit clearings before we + // got to the start of this range. We don't know how many there were before, + // but 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 1.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. */ +LIB_EXPORT 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_SUCCESS candidate is probably prime */ +/* TPM_RC_NO_RESULT candidate is not prime and couldn't find and alternative in 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 = 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 = 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 TPM_RC_NO_RESULT; +} +#ifdef 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); +} +LIB_EXPORT 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 +#ifndef RSA_INSTRUMENT +void +RsaSimulationEnd( + void + ) +{ +} +#endif diff --git a/src/tpm2/crypto/openssl/CryptRand.c b/src/tpm2/crypto/openssl/CryptRand.c new file mode 100644 index 00000000..6989e769 --- /dev/null +++ b/src/tpm2/crypto/openssl/CryptRand.c @@ -0,0 +1,782 @@ +/********************************************************************************/ +/* */ +/* DRBG with a behavior according to SP800-90A */ +/* Written by Ken Goldman */ +/* IBM Thomas J. Watson Research Center */ +/* $Id: CryptRand.c 953 2017-03-06 20:31: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, 2017 */ +/* */ +/********************************************************************************/ + +#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.18.3.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.18.3.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.18.3.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[] = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f + /* #if DRBG_KEY_SIZE_WORDS > 4 kgold */ + ,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.18.3.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.18.3.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.18.3.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.18.3.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 + ) +{ +#ifndef 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()) + { + // 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)); + } +#ifndef 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(); +} +/* 10.2.18.3.9 IncrementIv() */ +/* Used by EncryptDRBG() */ +void +IncrementIv( + DRBG_IV *iv + ) +{ + BYTE *ivP = ((BYTE *)iv) + DRBG_IV_SIZE_BYTES; + while((--ivP >= (BYTE *)iv) && ((*ivP = ((*ivP + 1) & 0xFF)) == 0)); +} +/* 10.2.18.3.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. */ +void +EncryptDRBG( + BYTE *dOut, + UINT32 dOutBytes, + DRBG_KEY_SCHEDULE *keySchedule, + DRBG_IV *iv, + UINT32 *lastValue // Points to the last output value + ) +{ +#ifdef 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]) + ) + FAIL(FATAL_ERROR_DRBG); + 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 +} +/* 10.2.18.3.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. */ +void +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; + // + 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) + FAIL(FATAL_ERROR_INTERNAL); + 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 +} +/* 10.2.18.3.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; + BYTE *pSeed = (BYTE *)&seed; + pAssert((drbgState != NULL) && (drbgState->magic == DRBG_MAGIC)); + if(providedEntropy == NULL) + { + if(!DRBG_GetEntropy(sizeof(DRBG_SEED), pSeed)) + return FALSE; + providedEntropy = &seed; + } + if(additionalData != NULL) + { + BYTE *in1 = (BYTE *)providedEntropy; // This might be seed + BYTE *in2 = (BYTE *)additionalData; + int i; + // XOR the provided data with the seed + for(i = sizeof(DRBG_SEED); i > 0; i--) + *pSeed++ = *in1++ ^ *in2++; + } + DRBG_Update(drbgState, NULL, providedEntropy); + drbgState->reseedCounter = 1; + return TRUE; +} +/* 10.2.18.3.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 defined DRBG_DEBUG_PRINT && defined DEBUG + 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 defined DRBG_DEBUG_PRINT && defined DEBUG + 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 defined DRBG_DEBUG_PRINT && defined DEBUG + 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.18.4 Public Interface */ +/* 10.2.18.4.1 Description */ +/* The functions in this section are the interface to the RNG. These are the functions that are used + by TPM.lib. Other functions are only visible to programs in the LtcCryptoEngine(). */ +/* 10.2.18.4.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 S failure of the entropy generator */ +LIB_EXPORT TPM_RC +CryptRandomStir( + UINT32 additionalDataSize, /* kgold chaged from signed */ + BYTE *additionalData + ) +{ + DRBG_SEED tmpBuf; + DRBG_SEED dfResult; + // +#if defined USE_DEBUG_RNG && 1 + // 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. + NOT_REFERENCED(dfResult); + if(additionalDataSize < 0) + additionalDataSize = 0; + else if(additionalDataSize > sizeof(tmpBuf)) + additionalDataSize = sizeof(tmpBuf); + else + memset(&tmpBuf.bytes[additionalDataSize], 0, sizeof(tmpBuf) - additionalDataSize); + memcpy(tmpBuf.bytes, additionalData, additionalDataSize); + memcpy(drbgDefault.seed.bytes, tmpBuf.bytes, sizeof(drbgDefault.seed.bytes)); +#else + // 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)); +#endif + drbgDefault.reseedCounter = 1; + return TPM_RC_SUCCESS; +} +/* 10.2.18.4.3 CryptRandomGenerate() */ +/* Generate a randomSize number or random bytes. */ +LIB_EXPORT UINT16 +CryptRandomGenerate( + INT32 randomSize, + BYTE *buffer + ) +{ + if(randomSize > UINT16_MAX) + randomSize = UINT16_MAX; + return DRBG_Generate((RAND_STATE *)&drbgDefault, buffer, (UINT16)randomSize); +} +/* 10.2.18.4.4 DRBG_InstantiateSeededKdf() */ +/* Function used to instantiate a KDF-based RNG. This is used for derivations */ +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 + ) +{ + state->magic = KDF_MAGIC; + state->seed = seed; + state->hash = hashAlg; + state->kdf = kdf; + state->label = label; + state->context = context; + state->counter = 1; + return TRUE; +} +/* 10.2.18.4.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.18.4.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. */ +LIB_EXPORT BOOL +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 + ) +{ + DF_STATE dfState; + int totalInputSize; + // DRBG should have been tested, but... + if(!IsDrbgTested() && !DRBG_SelfTest()) + FAIL(FATAL_ERROR_SELF_TEST); + // Initialize the DRBG state + memset(drbgState, 0, sizeof(DRBG_STATE)); + drbgState->magic = DRBG_MAGIC; + // 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 TRUE; +} +/* 10.2.18.4.7 CryptRandStartup() */ +/* This function is called when TPM_Startup() is executed. */ +LIB_EXPORT BOOL +CryptRandStartup( + void + ) +{ +#ifndef _DRBG_STATE_SAVE + // If not saved in NV, re-instantiate on each startup + 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) + DRBG_Reseed(&go.drbgState, NULL, NULL); + else + DRBG_Instantiate(&go.drbgState, 0, NULL); +#endif + return TRUE; +} +/* 10.2.18.4.8 CryptRandInit() */ +/* This function is called when _TPM_Init() is being processed */ +LIB_EXPORT BOOL +CryptRandInit( + void + ) +{ + return DRBG_SelfTest(); +} +/* 10.2.18.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. */ +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 the caller used a KDF state, generate a sequence from the KDF + if(state->kdf.magic == KDF_MAGIC) + { + KDF_STATE *kdf = (KDF_STATE *)state; + UINT32 count = (UINT32)kdf->counter; + if((randomSize != 0) && (random != NULL)) + CryptKDFa(kdf->hash, kdf->seed, kdf->label, kdf->context, NULL, + randomSize * 8, random, &count, 0); + kdf->counter = count; + return randomSize; + } + else if(state->drbg.magic == DRBG_MAGIC) + { + DRBG_STATE *drbgState = (DRBG_STATE *)state; + DRBG_KEY_SCHEDULE keySchedule; + DRBG_SEED *seed = &drbgState->seed; + 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. + FAIL(FATAL_ERROR_INTERNAL); + } + // 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) + FAIL(FATAL_ERROR_INTERNAL); + // 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 + { + FAIL(FATAL_ERROR_INTERNAL); + } + return randomSize; +} +/* 10.2.18.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.18.7 DRBG_Uninstantiate() */ +/* This is Uninstantiate_function() from [SP 800-90A 9.4]. */ +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; +} +/* 10.2.18.8 CryptRandMinMax() */ +/* This function generates a value that as not larger than (2^max) - 1 and no smaller than 2^(min - + 1). For example, if max == 4 and min == 2, then the number will be between 0x0010 and 0x1111 + inclusively. If max == 4 and min == 4 then the number will be between 0x1000 and 0x1111. */ +LIB_EXPORT NUMBYTES +CryptRandMinMax( + BYTE *out, + UINT32 max, + UINT32 min, + RAND_STATE *rand + ) +{ + BN_VAR(bn, LARGEST_NUMBER_BITS); + NUMBYTES size = (NUMBYTES)BITS_TO_BYTES(max); + pAssert(max <= LARGEST_NUMBER_BITS); + do + { + BnGetRandomBits(bn, max, rand); + } while(BnSizeInBits(bn) < min); + BnToBytes(bn, out, &size); + return size; +} diff --git a/src/tpm2/crypto/openssl/CryptRsa.c b/src/tpm2/crypto/openssl/CryptRsa.c new file mode 100644 index 00000000..d61c3d78 --- /dev/null +++ b/src/tpm2/crypto/openssl/CryptRsa.c @@ -0,0 +1,1169 @@ +/********************************************************************************/ +/* */ +/* implementation of cryptographic primitives for RSA */ +/* Written by Ken Goldman */ +/* IBM Thomas J. Watson Research Center */ +/* $Id: CryptRsa.c 953 2017-03-06 20:31: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, 2017 */ +/* */ +/********************************************************************************/ + +/* 10.2.19 CryptRsa.c */ +/* 10.2.19.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.19.2 Includes */ +/* Need this define to get the private defines for this function */ +#define CRYPT_RSA_C +#include "Tpm.h" +#ifdef TPM_ALG_RSA +/* 10.2.19.3 Obligatory Initialization Functions */ +/* 10.2.19.3.1 CryptRsaInit() */ +/* Function called at _TPM_Init(). */ +BOOL +CryptRsaInit( + void + ) +{ + return TRUE; +} +/* 10.2.19.3.2 CryptRsaStartup() */ +/* Function called at TPM2_Startup() */ +BOOL +CryptRsaStartup( + void + ) +{ + return TRUE; +} +/* 10.2.19.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.19.4.1 ComputePrivateExponent() */ +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.19.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. */ +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.19.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 */ +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.19.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.19.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; + INT32 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) + CryptMGF1(dbSize, mask, hashAlg, hLen, seed); + // 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(CryptMGF1(hLen, &padded->buffer[1], hashAlg, dbSize, pp) != (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.19.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 + CryptMGF1(hLen, seedMask, hashAlg, padded->size - hLen - 1, + &padded->buffer[hLen + 1]); + // 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 + CryptMGF1(padded->size - hLen - 1, mask, hashAlg, hLen, seedMask); + // 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.19.4.7 PKSC1v1_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_PKSC1v1_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.19.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; +} +/* 10.2.19.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(CryptMGF1(mLen, pOut, hashAlg, hLen, &pOut[mLen]) != 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.19.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; + CryptMGF1(mLen, mask, hashAlg, hLen, &pe[mLen]); + // 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.19.4.11 () 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 PKSC1v1_5 + TPM2B *hIn // IN: digest value to encode + ) +{ + const BYTE *der; + BYTE *eOut; + INT32 derSize = CryptHashGetDer(hashAlg, &der); + 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.19.4.12 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; + const BYTE *der; + BYTE *pe; + INT32 derSize = CryptHashGetDer(hashAlg, &der); + 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; +} +/* 10.2.19.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.19.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(ALG_NULL_VALUE); + // 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; +} +/* 10.2.19.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_PKSC1v1_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.19.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.19.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.19.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; +} +#if defined SIMULATION && defined 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.19.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 defined SIMULATION && defined USE_RSA_KEY_CACHE + if(GET_CACHED_KEY(rsaKey, rand)) + return TPM_RC_SUCCESS; +#endif + // Make sure that key generation has been tested + TEST(ALG_NULL_VALUE); + // 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(publicArea->objectAttributes.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; +} +#endif // TPM_ALG_RSA diff --git a/src/tpm2/crypto/openssl/CryptSym.c b/src/tpm2/crypto/openssl/CryptSym.c new file mode 100644 index 00000000..68b73647 --- /dev/null +++ b/src/tpm2/crypto/openssl/CryptSym.c @@ -0,0 +1,564 @@ +/********************************************************************************/ +/* */ +/* Symmetric block cipher modes */ +/* Written by Ken Goldman */ +/* IBM Thomas J. Watson Research Center */ +/* $Id: CryptSym.c 953 2017-03-06 20:31: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, 2017 */ +/* */ +/********************************************************************************/ + +/* 10.2.20 CryptSym.c */ +/* 10.2.20.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.20.2 Includes, Defines, and Typedefs */ +#include "Tpm.h" +union tpmCryptKeySchedule_t { +#ifdef TPM_ALG_AES + tpmKeyScheduleAES AES; +#endif +#ifdef TPM_ALG_SM4 + tpmKeyScheduleSM4 SM4; +#endif +#ifdef TPM_ALG_CAMELLIA + tpmKeyScheduleCAMELLIA CAMELLIA; +#endif +#ifdef TPM_ALG_TDES + tpmKeyScheduleTDES TDES[3]; +#endif +#if SYMMETRIC_ALIGNMENT == 8 + uint64_t alignment; +#else + uint32_t alignment; +#endif +}; +/* 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) \ + case TPM_ALG_##ALG: \ + TpmCryptSetEncryptKey##ALG(key, keySizeInBits, &keySchedule.ALG); \ + encrypt = (TpmCryptSetSymKeyCall_t)TpmCryptEncrypt##ALG; \ + break; +#define DECRYPT_CASE(ALG) \ + case TPM_ALG_##ALG: \ + TpmCryptSetDecryptKey##ALG(key, keySizeInBits, &keySchedule.ALG); \ + decrypt = (TpmCryptSetSymKeyCall_t)TpmCryptDecrypt##ALG; \ + break; +#ifdef TPM_ALG_AES +#define ENCRYPT_CASE_AES ENCRYPT_CASE(AES) +#define DECRYPT_CASE_AES DECRYPT_CASE(AES) +#else +#define ENCRYPT_CASE_AES +#define DECRYPT_CASE_AES +#endif +#ifdef TPM_ALG_SM4 +#define ENCRYPT_CASE_SM4 ENCRYPT_CASE(SM4) +#define DECRYPT_CASE_SM4 DECRYPT_CASE(SM4) +#else +#define ENCRYPT_CASE_SM4 +#define DECRYPT_CASE_SM4 +#endif +#ifdef TPM_ALG_CAMELLIA +#define ENCRYPT_CASE_CAMELLIA ENCRYPT_CASE(CAMELLIA) +#define DECRYPT_CASE_CAMELLIA DECRYPT_CASE(CAMELLIA) +#else +#define ENCRYPT_CASE_CAMELLIA +#define DECRYPT_CASE_CAMELLIA +#endif +#ifdef TPM_ALG_TDES +#define ENCRYPT_CASE_TDES ENCRYPT_CASE(TDES) +#define DECRYPT_CASE_TDES DECRYPT_CASE(TDES) +#else +#define ENCRYPT_CASE_TDES +#define DECRYPT_CASE_TDES +#endif +/* For each algorithm the case will either be defined or null. */ +#define SELECT(direction) \ + switch(algorithm) \ + { \ + direction##_CASE_AES \ + direction##_CASE_SM4 \ + direction##_CASE_CAMELLIA \ + direction##_CASE_TDES \ + default: \ + return TPM_RC_FAILURE; \ + } +/* 10.2.20.3 Obligatory Initialization Functions */ +/* 10.2.20.3.1 CryptSymInit() */ +/* This function is called to do _TPM_Init() processing */ +BOOL +CryptSymInit( + void + ) +{ + return TRUE; +} +/* 10.2.20.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. */ +/* 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 + ) +{ + switch(symmetricAlg) + { +#ifdef TPM_ALG_AES + case TPM_ALG_AES: + switch(keySizeInBits) + { + case 128: + return AES_128_BLOCK_SIZE_BYTES; + case 192: + return AES_192_BLOCK_SIZE_BYTES; + case 256: + return AES_256_BLOCK_SIZE_BYTES; + default: + break; + } + break; +#endif +#ifdef TPM_ALG_SM4 + case TPM_ALG_SM4: + switch(keySizeInBits) + { + case 128: + return SM4_128_BLOCK_SIZE_BYTES; + default: + break; + } +#endif +#ifdef TPM_ALG_CAMELLIA + case TPM_ALG_CAMELLIA: + switch(keySizeInBits) + { + case 128: + return CAMELLIA_128_BLOCK_SIZE_BYTES; + case 192: + return CAMELLIA_192_BLOCK_SIZE_BYTES; + case 256: + return CAMELLIA_256_BLOCK_SIZE_BYTES; + default: + break; + } +#endif +#ifdef TPM_ALG_TDES + case TPM_ALG_TDES: + switch(keySizeInBits) + { + case 128: + return TDES_128_BLOCK_SIZE_BYTES; + case 192: + return TDES_192_BLOCK_SIZE_BYTES; + default: + break; + } +#endif + default: + break; + } + return 0; +} +/* 10.2.20.5 Symmetric Encryption */ +/* This function performs symmetric encryption based on the mode. */ +/* Error Returns Meaning */ +/* TPM_RC_SUCCESS if success */ +/* 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}; + // + 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 != ALG_ECB_VALUE)) + { + ivInOut->t.size = blockSize; + iv = ivInOut->t.buffer; + } + else + iv = defaultIv; + pIv = iv; + // Create encrypt key schedule and set the encryption function pointer. + SELECT(ENCRYPT); + switch(mode) + { +#ifdef TPM_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 +#ifdef TPM_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 +#ifdef TPM_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; +#ifdef TPM_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_RC_SUCCESS if success */ +/* 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}; + // 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 != ALG_ECB_VALUE)) + { + 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 defined TPM_ALG_CBC || defined TPM_ALG_ECB + case ALG_CBC_VALUE: // decrypt = decrypt + case ALG_ECB_VALUE: + // 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; + SELECT(DECRYPT); + break; +#endif + default: + // For the remaining stream ciphers, use encryption to decrypt + SELECT(ENCRYPT); + break; + } + // Now do the mode-dependent decryption + switch(mode) + { +#ifdef TPM_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; +#ifdef TPM_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 +#ifdef TPM_ALG_ECB + case TPM_ALG_ECB: + for(; dSize > 0; dSize -= blockSize) + { + DECRYPT(&keySchedule, dIn, dOut); + dIn = &dIn[blockSize]; + dOut = &dOut[blockSize]; + } + break; +#endif +#ifdef TPM_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; +} +/* 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; +#ifdef TPM_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/LibSupport.h b/src/tpm2/crypto/openssl/LibSupport.h new file mode 100644 index 00000000..a0e3f6df --- /dev/null +++ b/src/tpm2/crypto/openssl/LibSupport.h @@ -0,0 +1,124 @@ +/********************************************************************************/ +/* */ +/* */ +/* Written by Ken Goldman */ +/* IBM Thomas J. Watson Research Center */ +/* $Id: LibSupport.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 LIBSUPPORT_H +#define LIBSUPPORT_H + +/* 5.15 LibSupport.h */ + +/* This header file is used to select the library code that gets included in the TPM built */ +#ifndef _LIB_SUPPORT_H_ +#define _LIB_SUPPORT_H_ +/* OSSL has a full suite but yields an executable that is much larger than it needs to be. */ +#define OSSL 1 +/* LTC has symmetric support, RSA support, and inadequate ECC support */ +#define LTC 2 +/* MSBN only provides math support so should not be used as the hash or symmetric library */ +#define MSBN 3 +/* SYMCRYPT only provides symmetric cryptography so would need to be combined with another + library that has math support */ +#define SYMCRYPT 4 +#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 +/* Include the options for hashing If all the optional headers were always part of the + distribution then it would not be necessary to do the conditional testing before the + include. )-; */ +#if HASH_LIB == OSSL +# include "TpmToOsslHash.h" +#elif HASH_LIB == LTC +# include "ltc/TpmToLtcHash.h" +#elif HASH_LIB == SYMCRYPT +#include "symcrypt/TpmToSymcryptHash.h" +#else +# error "No hash library selected" +#endif +/* Set the linkage for the selected symmetric library */ +#if SYM_LIB == OSSL +# include "TpmToOsslSym.h" +#elif SYM_LIB == LTC +# include "ltc/TpmToLtcSym.h" +#elif SYM_LIB == SYMCRYPT +#include "symcrypt/TpmToSymcryptSym.h" +#else +# error "No symmetric library selected" +#endif +#undef MIN +#undef MIN +/* Select a big number Library. This uses a define rather than an include so that the header + will not be included until the required values have been defined. */ +#if MATH_LIB == OSSL +# define MATHLIB_H "TpmToOsslMath.h" +#elif MATH_LIB == LTC +# define MATHLIB_H "ltc/TpmToLtcMath.h" +#elif MATH_LIB == MSBN +#define MATHLIB_H "msbn/TpmToMsBnMath.h" +#else +# error "No math library selected" +#endif +#endif // _LIB_SUPPORT_H_ + + +#endif diff --git a/src/tpm2/crypto/openssl/TpmToOsslDesSupport.c b/src/tpm2/crypto/openssl/TpmToOsslDesSupport.c new file mode 100644 index 00000000..b7dd3bab --- /dev/null +++ b/src/tpm2/crypto/openssl/TpmToOsslDesSupport.c @@ -0,0 +1,117 @@ +/********************************************************************************/ +/* */ +/* */ +/* Written by Ken Goldman */ +/* IBM Thomas J. Watson Research Center */ +/* $Id: TpmToOsslDesSupport.c 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 */ +/* */ +/********************************************************************************/ + +/* 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 SYM_LIB == OSSL && defined TPM_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); +} +/* 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 // 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 00000000..4338fe63 --- /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 00000000..9e7b3cd5 --- /dev/null +++ b/src/tpm2/crypto/openssl/TpmToOsslHash.h @@ -0,0 +1,183 @@ +/********************************************************************************/ +/* */ +/* Used to splice the OpenSSL() hash code into the TPM code */ +/* Written by Ken Goldman */ +/* IBM Thomas J. Watson Research Center */ +/* $Id: TpmToOsslHash.h 953 2017-03-06 20:31: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, 2017 */ +/* */ +/********************************************************************************/ + +#ifndef TPMTOOSSLHASH_H +#define TPMTOOSSLHASH_H + + +/* 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 _TPM_TO_OSSL_HASH_H_ +#define _TPM_TO_OSSL_HASH_H_ +#if HASH_LIB == OSSL +#include +#include +#include +/* 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 +#ifdef TPM_ALG_SM3 +# error "The version of OpenSSL used by this code does not support SM3" +#endif +/* The defines below are only needed when compiling CryptHash.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. */ +/* 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 formate (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. */ +/* Internal External */ +/* Designation Designation */ +#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 +#endif // _CRYPT_HASH_C_ +#define LibHashInit() +/* This definition would change if there were something to report */ +#define HashLibSimulationEnd() +#endif // HASH_LIB == OSSL +#endif // + +#endif diff --git a/src/tpm2/crypto/openssl/TpmToOsslMath.c b/src/tpm2/crypto/openssl/TpmToOsslMath.c new file mode 100644 index 00000000..5c3946c3 --- /dev/null +++ b/src/tpm2/crypto/openssl/TpmToOsslMath.c @@ -0,0 +1,550 @@ +/********************************************************************************/ +/* */ +/* */ +/* Written by Ken Goldman */ +/* IBM Thomas J. Watson Research Center */ +/* $Id: TpmToOsslMath.c 953 2017-03-06 20:31: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, 2017 */ +/* */ +/********************************************************************************/ + +/* B.2.3.2. TpmToOsslMath.c */ +/* B.2.3.2.1. Introduction */ +/* This file contains the math functions that are not implemented in the BnMath() library + (yet). These math functions will call the OpenSSL() library to execute the operations. There is a + difference between the internal format and the OpenSSL() format. To call the OpenSSL() function, + a BIGNUM structure is created for each passed variable. The sizes in the bignum_t are copied and + the d pointer in the BIGNUM is set to point to the d parameter of the bignum_t. On return, + SetSizeOsslToTpm() is used for each returned variable to make sure that the pointers are not + changed. The size of the returned BIGGNUM is copied to bignum_t. */ +/* B.2.3.2.2. Includes and Defines */ +#include "Tpm.h" +#if MATH_LIB == OSSL +#include "TpmToOsslMath_fp.h" +/* B.2.3.2.3. Functions */ +#if 0 +INLINE void +SetSizeOsslToTpm( + bigNum a, + BIGNUM *b + ) +{ + if(a != NULL) + { + pAssert(((crypt_uword_t *)b->d == &a->d[0]) + && ((unsigned)b->top <= a->allocated)); + a->size = b->top; + } +} +#endif +/* 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() used the same format for a big number as does the TPM -- an array of native-endian + words in little-endian order. */ +/* If the array allocated for the OpenSSL() BIGNUM is not the space within the TPM bignum, then the + data is copied. Otherwise, just the size field of the BIGNUM is copied. */ +void +OsslToTpmBn( + bigNum bn, + BIGNUM *osslBn + ) +{ + if(bn != NULL) + { + if((crypt_uword_t *)osslBn->d != bn->d) + { + int i; + pAssert((unsigned)osslBn->top <= BnGetAllocated(bn)); + for(i = 0; i < osslBn->top; i++) + bn->d[i] = osslBn->d[i]; + } + BnSetTop(bn, osslBn->top); + } +} +/* B.2.3.2.3.2. BigInitialized() */ +/* This function initializes an OSSL BIGNUM from a TPM bignum. */ +BIGNUM * +BigInitialized( + BIGNUM *toInit, + bigConst initializer + ) +{ + if(toInit == NULL || initializer == NULL) + return NULL; + toInit->d = (BN_ULONG *)&initializer->d[0]; + toInit->dmax = initializer->allocated; + toInit->top = initializer->size; + toInit->neg = 0; + toInit->flags = 0; + 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 +#ifdef LIBRARY_COMPATIBILITY_CHECK +void +MathLibraryCompatibilityCheck( + void + ) +{ + OSSL_ENTER(); + BIGNUM *osslTemp = BN_CTX_get(CTX); + BN_VAR(tpmTemp, 64 * 8); // allocate some space for a test value + crypt_uword_t i; + TPM2B_TYPE(TEST, 16); + TPM2B_TEST test = {{16, {0x0F, 0x0E, 0x0D, 0x0C, + 0x0B, 0x0A, 0x09, 0x08, + 0x07, 0x06, 0x05, 0x04, + 0x03, 0x02, 0x01, 0x00}}}; + // Convert the test TPM2B to a bigNum + BnFrom2B(tpmTemp, &test.b); + // Convert the test TPM2B to an OpenSSL BIGNUM + BN_bin2bn(test.t.buffer, test.t.size, osslTemp); + // Make sure the values are consistent + cAssert(osslTemp->top == (int)tpmTemp->size); + for(i = 0; i < tpmTemp->size; i++) + cAssert(osslTemp->d[0] == tpmTemp->d[0]); + OSSL_LEAVE(); +} +#endif +/* B.2.3.2.3.2. BnModMult() */ +/* Does multiply and divide returning the remainder of the divide. */ +LIB_EXPORT BOOL +BnModMult( + bigNum result, + bigConst op1, + bigConst op2, + bigConst modulus + ) +{ + OSSL_ENTER(); + BIG_INITIALIZED(bnResult, result); + BIG_INITIALIZED(bnOp1, op1); + BIG_INITIALIZED(bnOp2, op2); + BIG_INITIALIZED(bnMod, modulus); + BIG_VAR(bnTemp, (LARGEST_NUMBER_BITS * 4)); + BOOL OK; + pAssert(BnGetAllocated(result) >= BnGetSize(modulus)); + OK = BN_mul(bnTemp, bnOp1, bnOp2, CTX); + OK = OK && BN_div(NULL, bnResult, bnTemp, bnMod, CTX); + result->size = bnResult->top; + OsslToTpmBn(result, bnResult); + OSSL_LEAVE(); + return OK; +} +/* B.2.3.2.3.3. BnMult() */ +/* Multiplies two numbers */ +LIB_EXPORT BOOL +BnMult( + bigNum result, + bigConst multiplicand, + bigConst multiplier + ) +{ + OSSL_ENTER(); + BN_VAR(temp, (LARGEST_NUMBER_BITS * 2)); + BIG_INITIALIZED(bnTemp, temp); + BIG_INITIALIZED(bnA, multiplicand); + BIG_INITIALIZED(bnB, multiplier); + BOOL OK; + pAssert(result->allocated >= + (BITS_TO_CRYPT_WORDS(BnSizeInBits(multiplicand) + + BnSizeInBits(multiplier)))); + OK = BN_mul(bnTemp, bnA, bnB, CTX); + OsslToTpmBn(temp, bnTemp); + OSSL_LEAVE(); + BnCopy(result, temp); + return OK; +} +/* B.2.3.2.3.4. BnDiv() */ +/* This function divides two bigNum values. The function always returns TRUE. */ +LIB_EXPORT BOOL +BnDiv( + bigNum quotient, + bigNum remainder, + bigConst dividend, + bigConst divisor + ) +{ + OSSL_ENTER(); + BIG_INITIALIZED(bnQ, quotient); + BIG_INITIALIZED(bnR, remainder); + BIG_INITIALIZED(bnDend, dividend); + BIG_INITIALIZED(bnSor, divisor); + BOOL OK; + pAssert(!BnEqualZero(divisor)); + if(BnGetSize(dividend) < BnGetSize(divisor)) + { + if(quotient) + BnSetWord(quotient, 0); + if(remainder) + BnCopy(remainder, dividend); + OK = TRUE; + } + else + { + pAssert((quotient == NULL) + || (quotient->allocated >= (unsigned)(dividend->size + - divisor->size))); + pAssert((remainder == NULL) + || (remainder->allocated >= divisor->size)); + OK = BN_div(bnQ, bnR, bnDend, bnSor, CTX); + OsslToTpmBn(quotient, bnQ); + 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); + OSSL_LEAVE(); + return OK; +} +#ifdef TPM_ALG_RSA +/* B.2.3.2.3.5. BnGcd() */ +/* Get the greatest common divisor of two numbers */ +LIB_EXPORT BOOL +BnGcd( + bigNum gcd, // OUT: the common divisor + bigConst number1, // IN: + bigConst number2 // IN: + ) +{ + OSSL_ENTER(); + BIG_INITIALIZED(bnGcd, gcd); + BIG_INITIALIZED(bn1, number1); + BIG_INITIALIZED(bn2, number2); + BOOL OK; + pAssert(gcd != NULL); + OK = BN_gcd(bnGcd, bn1, bn2, CTX); + OsslToTpmBn(gcd, bnGcd); + gcd->size = bnGcd->top; + OSSL_LEAVE(); + return OK; +} +/* B.2.3.2.3.6. 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 */ +LIB_EXPORT BOOL +BnModExp( + bigNum result, // OUT: the result + bigConst number, // IN: number to exponentiate + bigConst exponent, // IN: + bigConst modulus // IN: + ) +{ + OSSL_ENTER(); + BIG_INITIALIZED(bnResult, result); + BIG_INITIALIZED(bnN, number); + BIG_INITIALIZED(bnE, exponent); + BIG_INITIALIZED(bnM, modulus); + BOOL OK; + // + OK = BN_mod_exp(bnResult, bnN, bnE, bnM, CTX); + OsslToTpmBn(result, bnResult); + OSSL_LEAVE(); + return OK; +} +/* B.2.3.2.3.7. BnModInverse() */ +/* Modular multiplicative inverse */ +LIB_EXPORT BOOL +BnModInverse( + bigNum result, + bigConst number, + bigConst modulus + ) +{ + OSSL_ENTER(); + BIG_INITIALIZED(bnResult, result); + BIG_INITIALIZED(bnN, number); + BIG_INITIALIZED(bnM, modulus); + BOOL OK; + OK = (BN_mod_inverse(bnResult, bnN, bnM, CTX) != NULL); + OsslToTpmBn(result, bnResult); + OSSL_LEAVE(); + return OK; +} +#endif // TPM_ALG_RSA +#ifdef TPM_ALG_ECC +/* B.2.3.2.3.8. PointFromOssl() */ +/* Function to copy the point result from an OSSL function to a bigNum */ +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 + OK = EC_POINT_get_affine_coordinates_GFp(E->G, pIn, x, y, E->CTX); + 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.9. EcPointInitialized() */ +/* Allocate and initialize a point. */ +static EC_POINT * +EcPointInitialized( + pointConst initializer, + bigCurve E + ) +{ + BIG_INITIALIZED(bnX, (initializer != NULL) ? initializer->x : NULL); + BIG_INITIALIZED(bnY, (initializer != NULL) ? initializer->y : NULL); + EC_POINT *P = (initializer != NULL && E != NULL) + ? EC_POINT_new(E->G) : NULL; + pAssert(E != NULL); + if(P != NULL) + EC_POINT_set_affine_coordinates_GFp(E->G, P, bnX, bnY, E->CTX); + return P; +} +/* B.2.3.2.3.10. 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 */ +bigCurve +BnCurveInitialize( + bigCurve E, // IN: curve structure to initialize + TPM_ECC_CURVE curveId // IN: curve identifier + ) +{ + EC_GROUP *group = NULL; + EC_POINT *P = NULL; + const ECC_CURVE_DATA *C = GetCurveData(curveId); + BN_CTX *CTX = NULL; + BIG_INITIALIZED(bnP, C != NULL ? C->prime : NULL); + BIG_INITIALIZED(bnA, C != NULL ? C->a : NULL); + BIG_INITIALIZED(bnB, C != NULL ? C->b : NULL); + BIG_INITIALIZED(bnX, C != NULL ? C->base.x : NULL); + BIG_INITIALIZED(bnY, C != NULL ? C->base.y : NULL); + BIG_INITIALIZED(bnN, C != NULL ? C->order : NULL); + BIG_INITIALIZED(bnH, C != NULL ? C->h : NULL); + int OK = (C != NULL); + // + OK = OK && ((CTX = OsslContextEnter()) != NULL); + // initialize EC group, associate a generator point and initialize the point + // from the parameter data + // Create a group structure + OK = OK && (group = EC_GROUP_new_curve_GFp(bnP, bnA, bnB, CTX)) != NULL; + // Allocate a point in the group that will be used in setting the + // generator. This is not needed after the generator is set. + OK = OK && ((P = EC_POINT_new(group)) != NULL); + // Need to use this in case Montgomery method is being used + OK = OK + && EC_POINT_set_affine_coordinates_GFp(group, P, bnX, bnY, CTX); + // Now set the generator + OK = OK && EC_GROUP_set_generator(group, P, bnN, bnH); + if(P != NULL) + EC_POINT_free(P); + if(!OK && group != NULL) + { + EC_GROUP_free(group); + group = NULL; + } + if(!OK && CTX != NULL) + { + OsslContextLeave(CTX); + CTX = NULL; + } + E->G = group; + E->CTX = CTX; + E->C = C; + return OK ? E : NULL; +} +/* B.2.3.2.3.11. BnEccModMult() */ +/* This function 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_free(pR); + EC_POINT_free(pS); + return !BnEqualZero(R->z); +} +/* B.2.3.2.3.12. BnEccModMult2() */ +/* This function does a point multiply of the form R = [d]G + [u]Q */ +/* Return Values Meaning */ +/* 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)&E->C->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_free(pR); + EC_POINT_free(pS); + EC_POINT_free(pQ); + 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_free(pR); + EC_POINT_free(pS); + EC_POINT_free(pQ); + return !BnEqualZero(R->z); +} +#endif // TPM_ALG_ECC +#endif // MATHLIB OSSL diff --git a/src/tpm2/crypto/openssl/TpmToOsslMath.h b/src/tpm2/crypto/openssl/TpmToOsslMath.h new file mode 100644 index 00000000..af99aadc --- /dev/null +++ b/src/tpm2/crypto/openssl/TpmToOsslMath.h @@ -0,0 +1,123 @@ +/********************************************************************************/ +/* */ +/* */ +/* Written by Ken Goldman */ +/* IBM Thomas J. Watson Research Center */ +/* $Id: TpmToOsslMath.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 TPMTOOSSLMATH_H +#define TPMTOOSSLMATH_H + +/* B.2.2.1. TpmToOsslMath.h */ +/* B.2.2.1.1. Introduction */ +/* This file contains the structure definitions used for ECC in the LibTopCrypt() 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 _TPM_TO_OSSL_MATH_H +#define _TPM_TO_OSSL_MATH_H +#if MATH_LIB == OSSL +#include +#include +#include +/* 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 && (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; \ + BIGNUM *name = BigInitialized(&_##name, \ + 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; \ + BIGNUM *name = BigInitialized(&_##name, initializer) +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) +#define CURVE_INITIALIZED(name, initializer) \ + OSSL_CURVE_DATA _##name; \ + bigCurve name = BnCurveInitialize(&_##name, initializer) +#include "TpmToOsslSupport_fp.h" +#define CURVE_FREE(E) \ + if(E != NULL) \ + { \ + if(E->G != NULL) \ + EC_GROUP_free(E->G); \ + OsslContextLeave(E->CTX); \ + } +#define OSSL_ENTER() BN_CTX *CTX = OsslContextEnter() +#define OSSL_LEAVE() OsslContextLeave(CTX) +/* This definition would change if there were something to report */ +#define MathLibSimulationEnd() +#endif // MATH_LIB == OSSL +#endif + + +#endif diff --git a/src/tpm2/crypto/openssl/TpmToOsslMath_fp.h b/src/tpm2/crypto/openssl/TpmToOsslMath_fp.h new file mode 100644 index 00000000..26ea46bd --- /dev/null +++ b/src/tpm2/crypto/openssl/TpmToOsslMath_fp.h @@ -0,0 +1,148 @@ +/********************************************************************************/ +/* */ +/* */ +/* Written by Ken Goldman */ +/* IBM Thomas J. Watson Research Center */ +/* $Id: TpmToOsslMath_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 TPMTOOSSLMATH_FP_H +#define TPMTOOSSLMATH_FP_H + +void +OsslToTpmBn( + bigNum bn, + BIGNUM *osslBn + ); +BIGNUM * +BigInitialized( + BIGNUM *toInit, + bigConst initializer + ); +void +MathLibraryCompatibilityCheck( + void + ); +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 00000000..f58dcc40 --- /dev/null +++ b/src/tpm2/crypto/openssl/TpmToOsslSupport.c @@ -0,0 +1,110 @@ +/********************************************************************************/ +/* */ +/* */ +/* Written by Ken Goldman */ +/* IBM Thomas J. Watson Research Center */ +/* $Id: TpmToOsslSupport.c 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 */ +/* */ +/********************************************************************************/ + +/* 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 MATH_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 + ) +{ +#ifdef LIBRARY_COMPATIBILITY_CHECK + MathLibraryCompatibilityCheck(); +#endif + 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 *context = BN_CTX_new(); + if(context == NULL) + FAIL(FATAL_ERROR_ALLOCATION); + BN_CTX_start(context); + return context; +} +/* B.2.3.3.2.3. OsslContextLeave() */ +/* This is the companion function to OsslContextEnter(). */ +void +OsslContextLeave( + BN_CTX *context + ) +{ + if(context != NULL) + { + BN_CTX_end(context); + BN_CTX_free(context); + } +} +#endif // MATH_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 00000000..c9779017 --- /dev/null +++ b/src/tpm2/crypto/openssl/TpmToOsslSupport_fp.h @@ -0,0 +1,75 @@ +/********************************************************************************/ +/* */ +/* */ +/* Written by Ken Goldman */ +/* IBM Thomas J. Watson Research Center */ +/* $Id: TpmToOsslSupport_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 TPMTOOSSLSUPPORT_FP_H +#define TPMTOOSSLSUPPORT_FP_H + +BN_CTX * +OsslContextEnter( + void + ); +void +OsslContextLeave( + BN_CTX *context + ); + + +#endif diff --git a/src/tpm2/crypto/openssl/TpmToOsslSym.h b/src/tpm2/crypto/openssl/TpmToOsslSym.h new file mode 100644 index 00000000..dea62328 --- /dev/null +++ b/src/tpm2/crypto/openssl/TpmToOsslSym.h @@ -0,0 +1,128 @@ +/********************************************************************************/ +/* */ +/* */ +/* Written by Ken Goldman */ +/* IBM Thomas J. Watson Research Center */ +/* $Id: TpmToOsslSym.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 TPMTOOSSLSYM_H +#define TPMTOOSSLSYM_H + +/* B.2.2.2. TpmToOsslSym.h */ +/* B.2.2.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. */ +#ifndef _TPM_TO_OSSL_SYM_H_ +#define _TPM_TO_OSSL_SYM_H_ +#if SYM_LIB == OSSL +#include +#include +#include +#include +#ifdef TPM_ALG_SM4 +#error "SM4 is not available" +#endif +#ifdef TPM_ALG_CAMELLIA +#error "Camellia is not available" +#endif +/* 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 + ); +/* 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) +/* Macros to set up the encryption/decryption key schedules */ +/* AES: */ +#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)) +/* TDES: */ +#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 */ +/* 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 +#define TpmCryptEncryptTDES TDES_encrypt +#define TpmCryptDecryptTDES TDES_decrypt +#define tpmKeyScheduleTDES DES_key_schedule +typedef union tpmCryptKeySchedule_t tpmCryptKeySchedule_t; +#ifdef TPM_ALG_TDES +#include "TpmToOsslDesSupport_fp.h" +#endif +/* This definition would change if there were something to report */ +#define SymLibSimulationEnd() +#endif // SYM_LIB == OSSL +#endif // _TPM_TO_OSSL_SYM_H_ + + +#endif diff --git a/src/tpm2/swap.h b/src/tpm2/swap.h new file mode 100644 index 00000000..3b5d869f --- /dev/null +++ b/src/tpm2/swap.h @@ -0,0 +1,120 @@ +/********************************************************************************/ +/* */ +/* */ +/* Written by Ken Goldman */ +/* IBM Thomas J. Watson Research Center */ +/* $Id: swap.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 SWAP_H +#define SWAP_H + +#if LITTLE_ENDIAN_TPM == YES +#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 */ +/* 33 #define UINT8_TO_BYTE_ARRAY(i, b) {*((uint8_t *)(b)) = (i);} */ +/* 34 #define UINT16_TO_BYTE_ARRAY(i, b) {*((uint16_t *)(b)) = (i);} */ +/* 35 #define UINT32_TO_BYTE_ARRAY(i, b) {*((uint32_t *)(b)) = (i);} */ +/* 36 #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