ソースを参照

[Add][GPM][ibmtpm1682 / tpm2-tss-3.2.0 / tpm2-tools-5.1]

2022.10.10 / Folus Wen

Actions:
1. Add tpm2 emulator, software stack, tools for cyber security future.

Files:
1. As follow commit history

Image version: D0.00.XX.XXXX.XX
Image checksum: XXXXXXXX

Hardware PWB P/N : XXXXXXX
Hardware Version : XXXXXXX
Folus Wen 2 年 前
コミット
360e921881
100 ファイル変更29059 行追加0 行削除
  1. 20 0
      EVSE/GPL/Makefile
  2. BIN
      EVSE/GPL/NVChip
  3. 92 0
      EVSE/GPL/ibmtpm1682/LICENSE
  4. BIN
      EVSE/GPL/ibmtpm1682/ibmtpm.doc
  5. BIN
      EVSE/GPL/ibmtpm1682/ibmtpm1682.tar.gz
  6. 257 0
      EVSE/GPL/ibmtpm1682/src/ACT.h
  7. 89 0
      EVSE/GPL/ibmtpm1682/src/ACTCommands.c
  8. 79 0
      EVSE/GPL/ibmtpm1682/src/ACT_SetTimeout_fp.h
  9. 303 0
      EVSE/GPL/ibmtpm1682/src/ACT_spt.c
  10. 95 0
      EVSE/GPL/ibmtpm1682/src/ACT_spt_fp.h
  11. 88 0
      EVSE/GPL/ibmtpm1682/src/ActivateCredential_fp.h
  12. 244 0
      EVSE/GPL/ibmtpm1682/src/AlgorithmCap.c
  13. 78 0
      EVSE/GPL/ibmtpm1682/src/AlgorithmCap_fp.h
  14. 911 0
      EVSE/GPL/ibmtpm1682/src/AlgorithmTests.c
  15. 73 0
      EVSE/GPL/ibmtpm1682/src/AlgorithmTests_fp.h
  16. 377 0
      EVSE/GPL/ibmtpm1682/src/AsymmetricCommands.c
  17. 209 0
      EVSE/GPL/ibmtpm1682/src/Attest_spt.c
  18. 92 0
      EVSE/GPL/ibmtpm1682/src/Attest_spt_fp.h
  19. 587 0
      EVSE/GPL/ibmtpm1682/src/AttestationCommands.c
  20. 120 0
      EVSE/GPL/ibmtpm1682/src/AuditCommands.c
  21. 85 0
      EVSE/GPL/ibmtpm1682/src/BaseTypes.h
  22. 114 0
      EVSE/GPL/ibmtpm1682/src/Bits.c
  23. 98 0
      EVSE/GPL/ibmtpm1682/src/Bits_fp.h
  24. 297 0
      EVSE/GPL/ibmtpm1682/src/BnConvert.c
  25. 108 0
      EVSE/GPL/ibmtpm1682/src/BnConvert_fp.h
  26. 573 0
      EVSE/GPL/ibmtpm1682/src/BnMath.c
  27. 156 0
      EVSE/GPL/ibmtpm1682/src/BnMath_fp.h
  28. 201 0
      EVSE/GPL/ibmtpm1682/src/BnMemory.c
  29. 104 0
      EVSE/GPL/ibmtpm1682/src/BnMemory_fp.h
  30. 327 0
      EVSE/GPL/ibmtpm1682/src/BnValues.h
  31. 100 0
      EVSE/GPL/ibmtpm1682/src/Cancel.c
  32. 76 0
      EVSE/GPL/ibmtpm1682/src/Capabilities.h
  33. 228 0
      EVSE/GPL/ibmtpm1682/src/CapabilityCommands.c
  34. 95 0
      EVSE/GPL/ibmtpm1682/src/CertifyCreation_fp.h
  35. 93 0
      EVSE/GPL/ibmtpm1682/src/CertifyX509_fp.h
  36. 93 0
      EVSE/GPL/ibmtpm1682/src/Certify_fp.h
  37. 79 0
      EVSE/GPL/ibmtpm1682/src/ChangeEPS_fp.h
  38. 79 0
      EVSE/GPL/ibmtpm1682/src/ChangePPS_fp.h
  39. 79 0
      EVSE/GPL/ibmtpm1682/src/ClearControl_fp.h
  40. 78 0
      EVSE/GPL/ibmtpm1682/src/Clear_fp.h
  41. 289 0
      EVSE/GPL/ibmtpm1682/src/Clock.c
  42. 127 0
      EVSE/GPL/ibmtpm1682/src/ClockCommands.c
  43. 81 0
      EVSE/GPL/ibmtpm1682/src/ClockRateAdjust_fp.h
  44. 81 0
      EVSE/GPL/ibmtpm1682/src/ClockSet_fp.h
  45. 986 0
      EVSE/GPL/ibmtpm1682/src/CommandAttributeData.h
  46. 88 0
      EVSE/GPL/ibmtpm1682/src/CommandAttributes.h
  47. 262 0
      EVSE/GPL/ibmtpm1682/src/CommandAudit.c
  48. 97 0
      EVSE/GPL/ibmtpm1682/src/CommandAudit_fp.h
  49. 557 0
      EVSE/GPL/ibmtpm1682/src/CommandCodeAttributes.c
  50. 123 0
      EVSE/GPL/ibmtpm1682/src/CommandCodeAttributes_fp.h
  51. 4736 0
      EVSE/GPL/ibmtpm1682/src/CommandDispatchData.h
  52. 409 0
      EVSE/GPL/ibmtpm1682/src/CommandDispatcher.c
  53. 75 0
      EVSE/GPL/ibmtpm1682/src/CommandDispatcher_fp.h
  54. 468 0
      EVSE/GPL/ibmtpm1682/src/Commands.h
  55. 94 0
      EVSE/GPL/ibmtpm1682/src/Commit_fp.h
  56. 165 0
      EVSE/GPL/ibmtpm1682/src/CompilerDependencies.h
  57. 476 0
      EVSE/GPL/ibmtpm1682/src/ContextCommands.c
  58. 84 0
      EVSE/GPL/ibmtpm1682/src/ContextLoad_fp.h
  59. 84 0
      EVSE/GPL/ibmtpm1682/src/ContextSave_fp.h
  60. 202 0
      EVSE/GPL/ibmtpm1682/src/Context_spt.c
  61. 88 0
      EVSE/GPL/ibmtpm1682/src/Context_spt_fp.h
  62. 90 0
      EVSE/GPL/ibmtpm1682/src/CreateLoaded_fp.h
  63. 96 0
      EVSE/GPL/ibmtpm1682/src/CreatePrimary_fp.h
  64. 96 0
      EVSE/GPL/ibmtpm1682/src/Create_fp.h
  65. 207 0
      EVSE/GPL/ibmtpm1682/src/CryptCmac.c
  66. 86 0
      EVSE/GPL/ibmtpm1682/src/CryptCmac_fp.h
  67. 184 0
      EVSE/GPL/ibmtpm1682/src/CryptDes.c
  68. 82 0
      EVSE/GPL/ibmtpm1682/src/CryptDes_fp.h
  69. 103 0
      EVSE/GPL/ibmtpm1682/src/CryptEcc.h
  70. 233 0
      EVSE/GPL/ibmtpm1682/src/CryptEccCrypt.c
  71. 92 0
      EVSE/GPL/ibmtpm1682/src/CryptEccCrypt_fp.h
  72. 618 0
      EVSE/GPL/ibmtpm1682/src/CryptEccData.c
  73. 373 0
      EVSE/GPL/ibmtpm1682/src/CryptEccKeyExchange.c
  74. 78 0
      EVSE/GPL/ibmtpm1682/src/CryptEccKeyExchange_fp.h
  75. 759 0
      EVSE/GPL/ibmtpm1682/src/CryptEccMain.c
  76. 221 0
      EVSE/GPL/ibmtpm1682/src/CryptEccMain_fp.h
  77. 892 0
      EVSE/GPL/ibmtpm1682/src/CryptEccSignature.c
  78. 111 0
      EVSE/GPL/ibmtpm1682/src/CryptEccSignature_fp.h
  79. 863 0
      EVSE/GPL/ibmtpm1682/src/CryptHash.c
  80. 343 0
      EVSE/GPL/ibmtpm1682/src/CryptHash.h
  81. 219 0
      EVSE/GPL/ibmtpm1682/src/CryptHash_fp.h
  82. 386 0
      EVSE/GPL/ibmtpm1682/src/CryptPrime.c
  83. 552 0
      EVSE/GPL/ibmtpm1682/src/CryptPrimeSieve.c
  84. 101 0
      EVSE/GPL/ibmtpm1682/src/CryptPrimeSieve_fp.h
  85. 103 0
      EVSE/GPL/ibmtpm1682/src/CryptPrime_fp.h
  86. 855 0
      EVSE/GPL/ibmtpm1682/src/CryptRand.c
  87. 192 0
      EVSE/GPL/ibmtpm1682/src/CryptRand.h
  88. 151 0
      EVSE/GPL/ibmtpm1682/src/CryptRand_fp.h
  89. 1255 0
      EVSE/GPL/ibmtpm1682/src/CryptRsa.c
  90. 99 0
      EVSE/GPL/ibmtpm1682/src/CryptRsa.h
  91. 139 0
      EVSE/GPL/ibmtpm1682/src/CryptRsa_fp.h
  92. 225 0
      EVSE/GPL/ibmtpm1682/src/CryptSelfTest.c
  93. 87 0
      EVSE/GPL/ibmtpm1682/src/CryptSelfTest_fp.h
  94. 154 0
      EVSE/GPL/ibmtpm1682/src/CryptSmac.c
  95. 98 0
      EVSE/GPL/ibmtpm1682/src/CryptSmac_fp.h
  96. 489 0
      EVSE/GPL/ibmtpm1682/src/CryptSym.c
  97. 135 0
      EVSE/GPL/ibmtpm1682/src/CryptSym.h
  98. 111 0
      EVSE/GPL/ibmtpm1682/src/CryptSym_fp.h
  99. 93 0
      EVSE/GPL/ibmtpm1682/src/CryptTest.h
  100. 1739 0
      EVSE/GPL/ibmtpm1682/src/CryptUtil.c

+ 20 - 0
EVSE/GPL/Makefile

@@ -298,3 +298,23 @@ linux-pam:
 	make -C linux-pam-1.5.2 CC=$(CROSS_COMPILE)gcc install
 #       cp -r -f linux-pam-1.5.2/release/* ../rootfs/
 
+tpm-tss:
+	echo "tpm2-tss-3.2.0"
+	cd tpm2-tss-3.2.0/;./configure --host=arm-linux-gnueabihf --prefix=$(shell pwd)/tpm2-tss-3.2.0/release CC=$(CROSS_COMPILE)gcc AR=$(CROSS_COMPILE)ar RANLIB=$(CROSS_COMPILE)ranlib STRIP=$(CROSS_COMPILE)strip CXX=$(CROSS_COMPILE)g++ LD=$(CROSS_COMPILE)ld CRYPTO_CFLAGS="-I$(shell pwd)/openssl-1.1.1n/release/include" CRYPTO_LIBS="-L$(shell pwd)/openssl-1.1.1n/release/lib -lssl -lcrypto" JSONC_CFLAGS="-I$(shell pwd)/json-c-json-c-0.13.1-20180305/release/include" JSONC_LIBS="-L$(shell pwd)/json-c-json-c-0.13.1-20180305/release/lib -ljson-c" CURL_CFLAGS="-I$(shell pwd)/curl-7.61.1/release/include" CURL_LIBS="-L$(shell pwd)/curl-7.61.1/release/lib -lcurl" --disable-doxygen-doc --disable-doxygen-man --disable-doxygen-rtf --disable-doxygen-html;cd ../
+	make -C tpm2-tss-3.2.0 CC=$(CROSS_COMPILE)gcc clean
+	make -C tpm2-tss-3.2.0 CC=$(CROSS_COMPILE)gcc
+	make -C tpm2-tss-3.2.0 CC=$(CROSS_COMPILE)gcc install
+#       cp -r -f tpm2-tools-5.1/release/* ../rootfs/
+
+tpm-tools:
+	echo "tpm2-tools-5.1"
+	cd tpm2-tools-5.1/;./configure --host=arm-linux-gnueabihf --prefix=$(shell pwd)/tpm2-tools-5.1/release CC=$(CROSS_COMPILE)gcc AR=$(CROSS_COMPILE)ar RANLIB=$(CROSS_COMPILE)ranlib STRIP=$(CROSS_COMPILE)strip CXX=$(CROSS_COMPILE)g++ LD=$(CROSS_COMPILE)ld CFLAGS="-I$(shell pwd)/tpm2-tss-3.2.0/release/include" TSS2_FAPI_CFLAGS="-I$(shell pwd)/tpm2-tss-3.2.0/release/include" TSS2_FAPI_LIBS="-L$(shell pwd)/tpm2-tss-3.2.0/release/lib -ltss2-fapi" TSS2_MU_CFLAGS="-I$(shell pwd)/tpm2-tss-3.2.0/release/include" TSS2_MU_LIBS="-L$(shell pwd)/tpm2-tss-3.2.0/release/lib -ltss2-mu" TSS2_ESYS_2_3_CFLAGS="-I$(shell pwd)/tpm2-tss-3.2.0/release/include" TSS2_ESYS_2_3_LIBS="-L$(shell pwd)/tpm2-tss-3.2.0/release/lib -ltss2-esys" TSS2_TCTILDR_CFLAGS="-I$(shell pwd)/tpm2-tss-3.2.0/release/include" TSS2_TCTILDR_LIBS="-L$(shell pwd)/tpm2-tss-3.2.0/release/lib -ltss2-tctildr" TSS2_RC_CFLAGS="-I$(shell pwd)/tpm2-tss-3.2.0/release/include" TSS2_RC_LIBS="-L$(shell pwd)/tpm2-tss-3.2.0/release/lib -ltss2-rc" TSS2_SYS_CFLAGS="-I$(shell pwd)/tpm2-tss-3.2.0/release/include" TSS2_SYS_LIBS="-L$(shell pwd)/tpm2-tss-3.2.0/release/lib -ltss2-sys" LIBS="-L$(shell pwd)/json-c-json-c-0.13.1-20180305/release/lib -ljson-c" ;cd ../
+	make -C tpm2-tools-5.1 CC=$(CROSS_COMPILE)gcc clean
+	make -C tpm2-tools-5.1 CC=$(CROSS_COMPILE)gcc
+	make -C tpm2-tools-5.1 CC=$(CROSS_COMPILE)gcc install
+#       cp -r -f tpm2-tools-5.1/release/* ../rootfs/
+
+
+
+
+

BIN
EVSE/GPL/NVChip


+ 92 - 0
EVSE/GPL/ibmtpm1682/LICENSE

@@ -0,0 +1,92 @@
+$Id: LICENSE 679 2016-07-14 12:10:16Z kgoldman $
+
+(c) Copyright IBM Corporation 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.
+	
+--------------------------------------------------------------------
+			    
+A portion of the source code is derived from the TPM specification,
+which has a TCG copyright.  It is reproduced here for reference.
+
+--------------------------------------------------------------------
+
+Licenses and Notices
+Copyright Licenses:
+
+* Trusted Computing Group (TCG) grants to the user of the source code
+in this specification (the "Source Code") a worldwide, irrevocable,
+nonexclusive, royalty free, copyright license to reproduce, create
+derivative works, distribute, display and perform the Source Code and
+derivative works thereof, and to grant others the rights granted
+herein.
+
+* The TCG grants to the user of the other parts of the specification
+(other than the Source Code) the rights to reproduce, distribute,
+display, and perform the specification solely for the purpose of
+developing products based on such documents.  
+
+Source Code Distribution Conditions:
+
+* Redistributions of Source Code must retain the above copyright
+licenses, this list of conditions and the following disclaimers.
+
+* Redistributions in binary form must reproduce the above copyright
+licenses, this list of conditions and the following disclaimers in the
+documentation and/or other materials provided with the distribution.
+
+Disclaimers:
+
+* THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF
+LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH
+RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES)
+THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR
+OTHERWISE. Contact TCG Administration
+(admin@trustedcomputinggroup.org) for information on specification
+licensing rights available through TCG membership agreements.
+
+* THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED
+WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR
+FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR
+NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY
+OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE.
+
+* Without limitation, TCG and its members and licensors disclaim all
+liability, including liability for infringement of any proprietary
+rights, relating to use of information in this specification and to
+the implementation of this specification, and TCG disclaims all
+liability for cost of procurement of substitute goods or services,
+lost profits, loss of use, loss of data or any incidental,
+consequential, direct, indirect, or special damages, whether under
+contract, tort, warranty or otherwise, arising in any way out of use
+or reliance upon this specification or any information herein.
+
+Any marks and brands contained herein are the property of their
+respective owners.

BIN
EVSE/GPL/ibmtpm1682/ibmtpm.doc


BIN
EVSE/GPL/ibmtpm1682/ibmtpm1682.tar.gz


+ 257 - 0
EVSE/GPL/ibmtpm1682/src/ACT.h

@@ -0,0 +1,257 @@
+/********************************************************************************/
+/*										*/
+/*			 Authenticated Countdown Timer				*/
+/*			     Written by Ken Goldman				*/
+/*		       IBM Thomas J. Watson Research Center			*/
+/*            $Id$		*/
+/*										*/
+/*  Licenses and Notices							*/
+/*										*/
+/*  1. Copyright Licenses:							*/
+/*										*/
+/*  - Trusted Computing Group (TCG) grants to the user of the source code in	*/
+/*    this specification (the "Source Code") a worldwide, irrevocable, 		*/
+/*    nonexclusive, royalty free, copyright license to reproduce, create 	*/
+/*    derivative works, distribute, display and perform the Source Code and	*/
+/*    derivative works thereof, and to grant others the rights granted herein.	*/
+/*										*/
+/*  - The TCG grants to the user of the other parts of the specification 	*/
+/*    (other than the Source Code) the rights to reproduce, distribute, 	*/
+/*    display, and perform the specification solely for the purpose of 		*/
+/*    developing products based on such documents.				*/
+/*										*/
+/*  2. Source Code Distribution Conditions:					*/
+/*										*/
+/*  - Redistributions of Source Code must retain the above copyright licenses, 	*/
+/*    this list of conditions and the following disclaimers.			*/
+/*										*/
+/*  - Redistributions in binary form must reproduce the above copyright 	*/
+/*    licenses, this list of conditions	and the following disclaimers in the 	*/
+/*    documentation and/or other materials provided with the distribution.	*/
+/*										*/
+/*  3. Disclaimers:								*/
+/*										*/
+/*  - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF	*/
+/*  LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH	*/
+/*  RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES)	*/
+/*  THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE.		*/
+/*  Contact TCG Administration (admin@trustedcomputinggroup.org) for 		*/
+/*  information on specification licensing rights available through TCG 	*/
+/*  membership agreements.							*/
+/*										*/
+/*  - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED 	*/
+/*    WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR 	*/
+/*    FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR 		*/
+/*    NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY 		*/
+/*    OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE.		*/
+/*										*/
+/*  - Without limitation, TCG and its members and licensors disclaim all 	*/
+/*    liability, including liability for infringement of any proprietary 	*/
+/*    rights, relating to use of information in this specification and to the	*/
+/*    implementation of this specification, and TCG disclaims all liability for	*/
+/*    cost of procurement of substitute goods or services, lost profits, loss 	*/
+/*    of use, loss of data or any incidental, consequential, direct, indirect, 	*/
+/*    or special damages, whether under contract, tort, warranty or otherwise, 	*/
+/*    arising in any way out of use or reliance upon this specification or any 	*/
+/*    information herein.							*/
+/*										*/
+/*  (c) Copyright IBM Corp. and others, 2019					*/
+/*										*/
+/********************************************************************************/
+
+// 5.24	ACT.h
+
+#ifndef _ACT_H_
+#define _ACT_H_
+#include "TpmProfile.h"
+#if !(defined RH_ACT_0) || (RH_ACT_0 != YES)
+#   undef   RH_ACT_0
+#   define  RH_ACT_0 NO
+#   define IF_ACT_0_IMPLEMENTED(op)
+#else
+#   define IF_ACT_0_IMPLEMENTED(op) op(0)
+#endif
+#if !(defined RH_ACT_1) || (RH_ACT_1 != YES)
+#   undef   RH_ACT_1
+#   define  RH_ACT_1 NO
+#   define IF_ACT_1_IMPLEMENTED(op)
+#else
+#   define IF_ACT_1_IMPLEMENTED(op) op(1)
+#endif
+#if !(defined RH_ACT_2) || (RH_ACT_2 != YES)
+#   undef   RH_ACT_2
+#   define  RH_ACT_2 NO
+#   define IF_ACT_2_IMPLEMENTED(op)
+#else
+#   define IF_ACT_2_IMPLEMENTED(op) op(2)
+#endif
+#if !(defined RH_ACT_3) || (RH_ACT_3 != YES)
+#   undef   RH_ACT_3
+#   define  RH_ACT_3 NO
+#   define IF_ACT_3_IMPLEMENTED(op)
+#else
+#   define IF_ACT_3_IMPLEMENTED(op) op(3)
+#endif
+#if !(defined RH_ACT_4) || (RH_ACT_4 != YES)
+#   undef   RH_ACT_4
+#   define  RH_ACT_4 NO
+#   define IF_ACT_4_IMPLEMENTED(op)
+#else
+#   define IF_ACT_4_IMPLEMENTED(op) op(4)
+#endif
+#if !(defined RH_ACT_5) || (RH_ACT_5 != YES)
+#   undef   RH_ACT_5
+#   define  RH_ACT_5 NO
+#   define IF_ACT_5_IMPLEMENTED(op)
+#else
+#   define IF_ACT_5_IMPLEMENTED(op) op(5)
+#endif
+#if !(defined RH_ACT_6) || (RH_ACT_6 != YES)
+#   undef   RH_ACT_6
+#   define  RH_ACT_6 NO
+#   define IF_ACT_6_IMPLEMENTED(op)
+#else
+#   define IF_ACT_6_IMPLEMENTED(op) op(6)
+#endif
+#if !(defined RH_ACT_7) || (RH_ACT_7 != YES)
+#   undef   RH_ACT_7
+#   define  RH_ACT_7 NO
+#   define IF_ACT_7_IMPLEMENTED(op)
+#else
+#   define IF_ACT_7_IMPLEMENTED(op) op(7)
+#endif
+#if !(defined RH_ACT_8) || (RH_ACT_8 != YES)
+#   undef   RH_ACT_8
+#   define  RH_ACT_8 NO
+#   define IF_ACT_8_IMPLEMENTED(op)
+#else
+#   define IF_ACT_8_IMPLEMENTED(op) op(8)
+#endif
+#if !(defined RH_ACT_9) || (RH_ACT_9 != YES)
+#   undef   RH_ACT_9
+#   define  RH_ACT_9 NO
+#   define IF_ACT_9_IMPLEMENTED(op)
+#else
+#   define IF_ACT_9_IMPLEMENTED(op) op(9)
+#endif
+#if !(defined RH_ACT_A) || (RH_ACT_A != YES)
+#   undef   RH_ACT_A
+#   define  RH_ACT_A NO
+#   define IF_ACT_A_IMPLEMENTED(op)
+#else
+#   define IF_ACT_A_IMPLEMENTED(op) op(A)
+#endif
+#if !(defined RH_ACT_B) || (RH_ACT_B != YES)
+#   undef   RH_ACT_B
+#   define  RH_ACT_B NO
+#   define IF_ACT_B_IMPLEMENTED(op)
+#else
+#   define IF_ACT_B_IMPLEMENTED(op) op(B)
+#endif
+#if !(defined RH_ACT_C) || (RH_ACT_C != YES)
+#   undef   RH_ACT_C
+#   define  RH_ACT_C NO
+#   define IF_ACT_C_IMPLEMENTED(op)
+#else
+#   define IF_ACT_C_IMPLEMENTED(op) op(C)
+#endif
+#if !(defined RH_ACT_D) || (RH_ACT_D != YES)
+#   undef   RH_ACT_D
+#   define  RH_ACT_D NO
+#   define IF_ACT_D_IMPLEMENTED(op)
+#else
+#   define IF_ACT_D_IMPLEMENTED(op) op(D)
+#endif
+#if !(defined RH_ACT_E) || (RH_ACT_E != YES)
+#   undef   RH_ACT_E
+#   define  RH_ACT_E NO
+#   define IF_ACT_E_IMPLEMENTED(op)
+#else
+#   define IF_ACT_E_IMPLEMENTED(op) op(E)
+#endif
+#if !(defined RH_ACT_F) || (RH_ACT_F != YES)
+#   undef   RH_ACT_F
+#   define  RH_ACT_F NO
+#   define IF_ACT_F_IMPLEMENTED(op)
+#else
+#   define IF_ACT_F_IMPLEMENTED(op) op(F)
+#endif
+#ifndef TPM_RH_ACT_0
+#error Need numeric definition for TPM_RH_ACT_0
+#endif
+#ifndef TPM_RH_ACT_1
+#   define TPM_RH_ACT_1    (TPM_RH_ACT_0 + 1)
+#endif
+#ifndef TPM_RH_ACT_2
+#   define TPM_RH_ACT_2    (TPM_RH_ACT_0 + 2)
+#endif
+#ifndef TPM_RH_ACT_3
+#   define TPM_RH_ACT_3    (TPM_RH_ACT_0 + 3)
+#endif
+#ifndef TPM_RH_ACT_4
+#   define TPM_RH_ACT_4    (TPM_RH_ACT_0 + 4)
+#endif
+#ifndef TPM_RH_ACT_5
+#   define TPM_RH_ACT_5    (TPM_RH_ACT_0 + 5)
+#endif
+#ifndef TPM_RH_ACT_6
+#   define TPM_RH_ACT_6    (TPM_RH_ACT_0 + 6)
+#endif
+#ifndef TPM_RH_ACT_7
+#   define TPM_RH_ACT_7    (TPM_RH_ACT_0 + 7)
+#endif
+#ifndef TPM_RH_ACT_8
+#   define TPM_RH_ACT_8    (TPM_RH_ACT_0 + 8)
+#endif
+#ifndef TPM_RH_ACT_9
+#   define TPM_RH_ACT_9    (TPM_RH_ACT_0 + 9)
+#endif
+#ifndef TPM_RH_ACT_A
+#   define TPM_RH_ACT_A    (TPM_RH_ACT_0 + 0xA)
+#endif
+#ifndef TPM_RH_ACT_B
+#   define TPM_RH_ACT_B    (TPM_RH_ACT_0 + 0xB)
+#endif
+#ifndef TPM_RH_ACT_C
+#   define TPM_RH_ACT_C    (TPM_RH_ACT_0 + 0xC)
+#endif
+#ifndef TPM_RH_ACT_D
+#   define TPM_RH_ACT_D    (TPM_RH_ACT_0 + 0xD)
+#endif
+#ifndef TPM_RH_ACT_E
+#   define TPM_RH_ACT_E    (TPM_RH_ACT_0 + 0xE)
+#endif
+#ifndef TPM_RH_ACT_F
+#   define TPM_RH_ACT_F    (TPM_RH_ACT_0 + 0xF)
+#endif
+#define FOR_EACH_ACT(op)						\
+    IF_ACT_0_IMPLEMENTED(op)						\
+    IF_ACT_1_IMPLEMENTED(op)						\
+    IF_ACT_2_IMPLEMENTED(op)						\
+    IF_ACT_3_IMPLEMENTED(op)						\
+    IF_ACT_4_IMPLEMENTED(op)						\
+    IF_ACT_5_IMPLEMENTED(op)						\
+    IF_ACT_6_IMPLEMENTED(op)						\
+    IF_ACT_7_IMPLEMENTED(op)						\
+    IF_ACT_8_IMPLEMENTED(op)						\
+    IF_ACT_9_IMPLEMENTED(op)						\
+    IF_ACT_A_IMPLEMENTED(op)						\
+    IF_ACT_B_IMPLEMENTED(op)						\
+    IF_ACT_C_IMPLEMENTED(op)						\
+    IF_ACT_D_IMPLEMENTED(op)						\
+    IF_ACT_E_IMPLEMENTED(op)						\
+    IF_ACT_F_IMPLEMENTED(op)
+
+// This is the mask for ACT that are implemented
+
+//#define ACT_MASK(N)     | (1 << 0x##N)
+//#define ACT_IMPLEMENTED_MASK    (0 FOR_EACH_ACT(ACT_MASK))
+#define CASE_ACT_HANDLE(N)     case TPM_RH_ACT_##N:
+#define CASE_ACT_NUMBER(N)     case 0x##N:
+typedef struct ACT_STATE
+{
+    UINT32          remaining;
+    TPM_ALG_ID      hashAlg;
+    TPM2B_DIGEST    authPolicy;
+} ACT_STATE, *P_ACT_STATE;
+#endif // _ACT_H_

+ 89 - 0
EVSE/GPL/ibmtpm1682/src/ACTCommands.c

@@ -0,0 +1,89 @@
+/********************************************************************************/
+/*										*/
+/*		Authenticated COuntdown Timer Commands	 			*/
+/*			     Written by Ken Goldman				*/
+/*		       IBM Thomas J. Watson Research Center			*/
+/*            $Id: ACTCommands.c 1671 2021-06-03 18:30:41Z kgoldman $		*/
+/*										*/
+/*  Licenses and Notices							*/
+/*										*/
+/*  1. Copyright Licenses:							*/
+/*										*/
+/*  - Trusted Computing Group (TCG) grants to the user of the source code in	*/
+/*    this specification (the "Source Code") a worldwide, irrevocable, 		*/
+/*    nonexclusive, royalty free, copyright license to reproduce, create 	*/
+/*    derivative works, distribute, display and perform the Source Code and	*/
+/*    derivative works thereof, and to grant others the rights granted herein.	*/
+/*										*/
+/*  - The TCG grants to the user of the other parts of the specification 	*/
+/*    (other than the Source Code) the rights to reproduce, distribute, 	*/
+/*    display, and perform the specification solely for the purpose of 		*/
+/*    developing products based on such documents.				*/
+/*										*/
+/*  2. Source Code Distribution Conditions:					*/
+/*										*/
+/*  - Redistributions of Source Code must retain the above copyright licenses, 	*/
+/*    this list of conditions and the following disclaimers.			*/
+/*										*/
+/*  - Redistributions in binary form must reproduce the above copyright 	*/
+/*    licenses, this list of conditions	and the following disclaimers in the 	*/
+/*    documentation and/or other materials provided with the distribution.	*/
+/*										*/
+/*  3. Disclaimers:								*/
+/*										*/
+/*  - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF	*/
+/*  LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH	*/
+/*  RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES)	*/
+/*  THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE.		*/
+/*  Contact TCG Administration (admin@trustedcomputinggroup.org) for 		*/
+/*  information on specification licensing rights available through TCG 	*/
+/*  membership agreements.							*/
+/*										*/
+/*  - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED 	*/
+/*    WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR 	*/
+/*    FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR 		*/
+/*    NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY 		*/
+/*    OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE.		*/
+/*										*/
+/*  - Without limitation, TCG and its members and licensors disclaim all 	*/
+/*    liability, including liability for infringement of any proprietary 	*/
+/*    rights, relating to use of information in this specification and to the	*/
+/*    implementation of this specification, and TCG disclaims all liability for	*/
+/*    cost of procurement of substitute goods or services, lost profits, loss 	*/
+/*    of use, loss of data or any incidental, consequential, direct, indirect, 	*/
+/*    or special damages, whether under contract, tort, warranty or otherwise, 	*/
+/*    arising in any way out of use or reliance upon this specification or any 	*/
+/*    information herein.							*/
+/*										*/
+/*  (c) Copyright IBM Corp. and others, 2019 - 2021				*/
+/*										*/
+/********************************************************************************/
+
+#include "Tpm.h"
+#include "ACT_SetTimeout_fp.h"
+
+extern int verbose;
+
+#if CC_ACT_SetTimeout  // Conditional expansion of this file
+
+/* Error Returns	Meaning */
+/* TPM_RC_RETRY	returned when an update for the selected ACT is already pending */
+/* TPM_RC_VALUE	attempt to disable signaling from an ACT that has not expired */
+TPM_RC
+TPM2_ACT_SetTimeout(
+		    ACT_SetTimeout_In      *in             // IN: input parameter list
+		    )
+{
+    // If 'startTimeout' is UINT32_MAX, then this is an attempt to disable the ACT
+    // and turn off the signaling for the ACT. This is only valid if the ACT
+    // is signaling.
+    if (verbose) {
+	FILE *f = fopen("trace.txt", "a");
+	fprintf(f, "TPM2_ACT_SetTimeout: actHandle %08x\n", in->actHandle);
+	fclose(f);
+    }
+    if((in->startTimeout == UINT32_MAX) && !ActGetSignaled(in->actHandle))
+	return TPM_RC_VALUE + RC_ACT_SetTimeout_startTimeout;
+    return ActCounterUpdate(in->actHandle, in->startTimeout);
+}
+#endif // CC_ACT_SetTimeout

+ 79 - 0
EVSE/GPL/ibmtpm1682/src/ACT_SetTimeout_fp.h

@@ -0,0 +1,79 @@
+/********************************************************************************/
+/*										*/
+/*	 		TPM2_ACT_SetTimeout Header				*/
+/*			     Written by Ken Goldman				*/
+/*		       IBM Thomas J. Watson Research Center			*/
+/*            $Id$	*/
+/*										*/
+/*  Licenses and Notices							*/
+/*										*/
+/*  1. Copyright Licenses:							*/
+/*										*/
+/*  - Trusted Computing Group (TCG) grants to the user of the source code in	*/
+/*    this specification (the "Source Code") a worldwide, irrevocable, 		*/
+/*    nonexclusive, royalty free, copyright license to reproduce, create 	*/
+/*    derivative works, distribute, display and perform the Source Code and	*/
+/*    derivative works thereof, and to grant others the rights granted herein.	*/
+/*										*/
+/*  - The TCG grants to the user of the other parts of the specification 	*/
+/*    (other than the Source Code) the rights to reproduce, distribute, 	*/
+/*    display, and perform the specification solely for the purpose of 		*/
+/*    developing products based on such documents.				*/
+/*										*/
+/*  2. Source Code Distribution Conditions:					*/
+/*										*/
+/*  - Redistributions of Source Code must retain the above copyright licenses, 	*/
+/*    this list of conditions and the following disclaimers.			*/
+/*										*/
+/*  - Redistributions in binary form must reproduce the above copyright 	*/
+/*    licenses, this list of conditions	and the following disclaimers in the 	*/
+/*    documentation and/or other materials provided with the distribution.	*/
+/*										*/
+/*  3. Disclaimers:								*/
+/*										*/
+/*  - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF	*/
+/*  LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH	*/
+/*  RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES)	*/
+/*  THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE.		*/
+/*  Contact TCG Administration (admin@trustedcomputinggroup.org) for 		*/
+/*  information on specification licensing rights available through TCG 	*/
+/*  membership agreements.							*/
+/*										*/
+/*  - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED 	*/
+/*    WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR 	*/
+/*    FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR 		*/
+/*    NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY 		*/
+/*    OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE.		*/
+/*										*/
+/*  - Without limitation, TCG and its members and licensors disclaim all 	*/
+/*    liability, including liability for infringement of any proprietary 	*/
+/*    rights, relating to use of information in this specification and to the	*/
+/*    implementation of this specification, and TCG disclaims all liability for	*/
+/*    cost of procurement of substitute goods or services, lost profits, loss 	*/
+/*    of use, loss of data or any incidental, consequential, direct, indirect, 	*/
+/*    or special damages, whether under contract, tort, warranty or otherwise, 	*/
+/*    arising in any way out of use or reliance upon this specification or any 	*/
+/*    information herein.							*/
+/*										*/
+/*  (c) Copyright IBM Corp. and others, 2019					*/
+/*										*/
+/********************************************************************************/
+
+#ifndef ACT_SETTIMEOUT_FP_H
+#define ACT_SETTIMEOUT_FP_H
+
+typedef struct {
+    TPMI_RH_ACT		actHandle;
+    UINT32		startTimeout;
+} ACT_SetTimeout_In;
+
+#define RC_ACT_SetTimeout_actHandle 	(TPM_RC_H + TPM_RC_1)
+#define RC_ACT_SetTimeout_startTimeout 	(TPM_RC_H + TPM_RC_2)
+
+TPM_RC
+TPM2_ACT_SetTimeout(
+		    ACT_SetTimeout_In      *in             // IN: input parameter list
+		    );
+
+
+#endif

+ 303 - 0
EVSE/GPL/ibmtpm1682/src/ACT_spt.c

@@ -0,0 +1,303 @@
+/********************************************************************************/
+/*										*/
+/*			    ACT Command Support 				*/
+/*			     Written by Ken Goldman				*/
+/*		       IBM Thomas J. Watson Research Center			*/
+/*            $Id: Object_spt.c 1490 2019-07-26 21:13:22Z kgoldman $		*/
+/*										*/
+/*  Licenses and Notices							*/
+/*										*/
+/*  1. Copyright Licenses:							*/
+/*										*/
+/*  - Trusted Computing Group (TCG) grants to the user of the source code in	*/
+/*    this specification (the "Source Code") a worldwide, irrevocable, 		*/
+/*    nonexclusive, royalty free, copyright license to reproduce, create 	*/
+/*    derivative works, distribute, display and perform the Source Code and	*/
+/*    derivative works thereof, and to grant others the rights granted herein.	*/
+/*										*/
+/*  - The TCG grants to the user of the other parts of the specification 	*/
+/*    (other than the Source Code) the rights to reproduce, distribute, 	*/
+/*    display, and perform the specification solely for the purpose of 		*/
+/*    developing products based on such documents.				*/
+/*										*/
+/*  2. Source Code Distribution Conditions:					*/
+/*										*/
+/*  - Redistributions of Source Code must retain the above copyright licenses, 	*/
+/*    this list of conditions and the following disclaimers.			*/
+/*										*/
+/*  - Redistributions in binary form must reproduce the above copyright 	*/
+/*    licenses, this list of conditions	and the following disclaimers in the 	*/
+/*    documentation and/or other materials provided with the distribution.	*/
+/*										*/
+/*  3. Disclaimers:								*/
+/*										*/
+/*  - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF	*/
+/*  LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH	*/
+/*  RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES)	*/
+/*  THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE.		*/
+/*  Contact TCG Administration (admin@trustedcomputinggroup.org) for 		*/
+/*  information on specification licensing rights available through TCG 	*/
+/*  membership agreements.							*/
+/*										*/
+/*  - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED 	*/
+/*    WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR 	*/
+/*    FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR 		*/
+/*    NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY 		*/
+/*    OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE.		*/
+/*										*/
+/*  - Without limitation, TCG and its members and licensors disclaim all 	*/
+/*    liability, including liability for infringement of any proprietary 	*/
+/*    rights, relating to use of information in this specification and to the	*/
+/*    implementation of this specification, and TCG disclaims all liability for	*/
+/*    cost of procurement of substitute goods or services, lost profits, loss 	*/
+/*    of use, loss of data or any incidental, consequential, direct, indirect, 	*/
+/*    or special damages, whether under contract, tort, warranty or otherwise, 	*/
+/*    arising in any way out of use or reliance upon this specification or any 	*/
+/*    information herein.							*/
+/*										*/
+/*  (c) Copyright IBM Corp. and others, 2016 - 2020				*/
+/*										*/
+/********************************************************************************/
+
+/* 7.8	ACT Support (ACT_spt.c) */
+/* 7.8.1	Introduction */
+/* This code implements the ACT update code. It does not use a mutex. This code uses a platform
+   service (_plat__ACT_UpdateCounter()) that returns false if the update is not accepted. If this
+   occurs, then TPM_RC_RETRY should be sent to the caller so that they can retry the operation
+   later. The implementation of this is platform dependent but the reference uses a simple flag to
+   indicate that an update is pending and the only process that can clear that flag is the process
+   that does the actual update. */
+
+/* 7.8.2	Includes */
+
+#include "Tpm.h"
+#include "ACT_spt_fp.h"
+#include "Platform_fp.h"
+#include "PlatformACT_fp.h"		/* added kgold */
+
+/* 7.8.3	Functions */
+/* 7.8.3.1	_ActResume() */
+/* This function does the resume processing for an ACT. It updates the saved count and turns
+   signaling back on if necessary. */
+static void
+_ActResume(
+	   UINT32              act,            //IN: the act number
+	   ACT_STATE          *actData         //IN: pointer to the saved ACT data
+	   )
+{
+    // If the act was non-zero, then restore the counter value.
+    if(actData->remaining > 0)
+	_plat__ACT_UpdateCounter(act, actData->remaining);
+    // if the counter was zero and the ACT signaling, enable the signaling.
+    else if(go.signaledACT & (1 << act))
+	_plat__ACT_SetSignaled(act, TRUE);
+}
+/* 7.8.3.2	ActStartup() */
+/* This function is called by TPM2_Startup() to initialize the ACT counter values. */
+BOOL
+ActStartup(
+	   STARTUP_TYPE        type
+	   )
+{
+    // Reset all the ACT hardware
+    _plat__ACT_Initialize();
+
+    // If this not a cold start, copy all the current 'signaled' settings to
+    // 'preservedSignaled'.
+    if (g_powerWasLost)
+	go.preservedSignaled = 0;
+    else
+	go.preservedSignaled |= go.signaledACT;
+    
+    // For TPM_RESET or TPM_RESTART, the ACTs will all be disabled and the output
+    // de-asserted.
+    if(type != SU_RESUME)
+	{
+	    go.signaledACT = 0;
+#define CLEAR_ACT_POLICY(N)						\
+	    go.ACT_##N.hashAlg = TPM_ALG_NULL;				\
+	    go.ACT_##N.authPolicy.b.size = 0;
+	    
+	    FOR_EACH_ACT(CLEAR_ACT_POLICY)
+		
+		}
+    else
+	{
+	    // Resume each of the implemented ACT
+#define RESUME_ACT(N)   _ActResume(0x##N, &go.ACT_##N);
+	    
+	    FOR_EACH_ACT(RESUME_ACT)
+		}
+    // set no ACT updated since last startup. This is to enable the halving of the
+    // timeout value
+    s_ActUpdated = 0;
+    _plat__ACT_EnableTicks(TRUE);
+    return TRUE;
+}
+/* 7.8.3.3	_ActSaveState() */
+/* Get the counter state and the signaled state for an ACT. If the ACT has not been updated since
+   the last time it was saved, then divide the count by 2. */
+static void
+_ActSaveState(
+	      UINT32              act,
+	      P_ACT_STATE         actData
+	      )
+{
+    actData->remaining = _plat__ACT_GetRemaining(act);
+    // If the ACT hasn't been updated since the last startup, then it should be
+    // be halved.
+    if((s_ActUpdated & (1 << act)) == 0)
+	{
+	    // Don't halve if the count is set to max or if halving would make it zero
+	    if((actData->remaining != UINT32_MAX) && (actData->remaining > 1))
+		actData->remaining /= 2;
+	}
+    if(_plat__ACT_GetSignaled(act))
+	go.signaledACT |= (1 << act);
+}
+/* 7.8.3.4	ActGetSignaled() */
+/* This function returns the state of the signaled flag associated with an ACT. */
+BOOL
+ActGetSignaled(
+	       TPM_RH              actHandle
+	       )
+{
+    UINT32              act = actHandle - TPM_RH_ACT_0;
+    //
+    return _plat__ACT_GetSignaled(act);
+}
+/* 7.8.3.5	ActShutdown() */
+/* This function saves the current state of the counters */
+BOOL
+ActShutdown(
+	    TPM_SU              state       //IN: the type of the shutdown.
+	    )
+{
+    // if this is not shutdown state, then the only type of startup is TPM_RESTART
+    // so the timer values will be cleared. If this is shutdown state, get the current
+    // countdown and signaled values. Plus, if the counter has not been updated
+    // since the last restart, divide the time by 2 so that there is no attack on the
+    // countdown by saving the countdown state early and then not using the TPM.
+    if(state == TPM_SU_STATE)
+	{
+	    // This will be populated as each of the ACT is queried
+	    go.signaledACT = 0;
+	    // Get the current count and the signaled state
+#define SAVE_ACT_STATE(N) _ActSaveState(0x##N, &go.ACT_##N);
+	    
+	    FOR_EACH_ACT(SAVE_ACT_STATE);
+	}
+    return TRUE;
+}
+/* 7.8.3.6	ActIsImplemented() */
+/* This function determines if an ACT is implemented in both the TPM and the platform code. */
+BOOL
+ActIsImplemented(
+		 UINT32          act
+		 )
+{
+#define CASE_ACT_
+    // This switch accounts for the TPM implemented values.
+    switch(act)
+	{
+	    FOR_EACH_ACT(CASE_ACT_NUMBER)
+		// This ensures that the platorm implemented the values implemented by
+		// the TPM
+		return _plat__ACT_GetImplemented(act);
+	  default:
+	    break;
+	}
+    return FALSE;
+}
+/* 7.8.3.7	ActCounterUpdate() */
+/* This function updates the ACT counter. If the counter already has a pending update, it returns
+   TPM_RC_RETRY so that the update can be tried again later. */
+TPM_RC
+ActCounterUpdate(
+		 TPM_RH          handle,         //IN: the handle of the act
+		 UINT32          newValue        //IN: the value to set in the ACT
+		 )
+{
+    UINT32          act;
+    TPM_RC          result;
+    //
+    act = handle - TPM_RH_ACT_0;
+    // This should never fail, but...
+    if(!_plat__ACT_GetImplemented(act))
+	result = TPM_RC_VALUE;
+    else
+	{
+	    // Will need to clear orderly so fail if we are orderly and NV is not available
+	    if(NV_IS_ORDERLY)
+		RETURN_IF_NV_IS_NOT_AVAILABLE;
+	    // if the attempt to update the counter fails, it means that there is an
+	    // update pending so wait until it has occurred and then do an update.
+	    if(!_plat__ACT_UpdateCounter(act, newValue))
+		result = TPM_RC_RETRY;
+	    else
+	        {
+	            // Indicate that the ACT has been updated since last TPM2_Startup().
+	            s_ActUpdated |= (UINT16)(1 << act);
+
+		    // Clear the preservedSignaled attribute.
+		    go.preservedSignaled &= ~((UINT16)(1 << act));
+		    
+	            // Need to clear the orderly flag
+	            g_clearOrderly = TRUE;
+		    
+	            result = TPM_RC_SUCCESS;
+	        }
+	}
+    return result;
+}
+/* 7.8.3.8	ActGetCapabilityData() */
+/* This function returns the list of ACT data */
+/* Return Value	Meaning */
+/* YES	if more ACT data is available */
+/* NO	if no more ACT data to */
+TPMI_YES_NO
+ActGetCapabilityData(
+		     TPM_HANDLE       actHandle,     // IN: the handle for the starting ACT
+		     UINT32           maxCount,      // IN: maximum allowed return values
+		     TPML_ACT_DATA   *actList        // OUT: ACT data list
+		     )
+{
+    // Initialize output property list
+    actList->count = 0;
+    
+    // Make sure that the starting handle value is in range (again)
+    if((actHandle < TPM_RH_ACT_0) || (actHandle > TPM_RH_ACT_F))
+	return FALSE;
+    // The maximum count of curves we may return is MAX_ECC_CURVES
+    if(maxCount > MAX_ACT_DATA)
+	maxCount = MAX_ACT_DATA;
+    // Scan the ACT data from the starting ACT
+    for(; actHandle <= TPM_RH_ACT_F; actHandle++)
+	{
+	    UINT32          act = actHandle - TPM_RH_ACT_0;
+	    if(actList->count < maxCount)
+	        {
+	            if(ActIsImplemented(act))
+			{
+			    TPMS_ACT_DATA    *actData = &actList->actData[actList->count];
+			    //
+			    memset(&actData->attributes, 0, sizeof(actData->attributes));
+			    actData->handle = actHandle;
+			    actData->timeout = _plat__ACT_GetRemaining(act);
+			    if (_plat__ACT_GetSignaled(act))
+				SET_ATTRIBUTE(actData->attributes, TPMA_ACT, signaled);
+			    else
+				CLEAR_ATTRIBUTE(actData->attributes, TPMA_ACT, signaled);
+			    actList->count++;
+			}
+		}
+	    else
+		{
+		    if(_plat__ACT_GetImplemented(act))
+			return YES;
+		}
+	}
+    // If we get here, either all of the ACT values were put in the list, or the list
+    // was filled and there are no more ACT values to return
+    return NO;
+}

+ 95 - 0
EVSE/GPL/ibmtpm1682/src/ACT_spt_fp.h

@@ -0,0 +1,95 @@
+/********************************************************************************/
+/*										*/
+/*			 ACT Command Support   					*/
+/*			     Written by Ken Goldman				*/
+/*		       IBM Thomas J. Watson Research Center			*/
+/*            $Id$		*/
+/*										*/
+/*  Licenses and Notices							*/
+/*										*/
+/*  1. Copyright Licenses:							*/
+/*										*/
+/*  - Trusted Computing Group (TCG) grants to the user of the source code in	*/
+/*    this specification (the "Source Code") a worldwide, irrevocable, 		*/
+/*    nonexclusive, royalty free, copyright license to reproduce, create 	*/
+/*    derivative works, distribute, display and perform the Source Code and	*/
+/*    derivative works thereof, and to grant others the rights granted herein.	*/
+/*										*/
+/*  - The TCG grants to the user of the other parts of the specification 	*/
+/*    (other than the Source Code) the rights to reproduce, distribute, 	*/
+/*    display, and perform the specification solely for the purpose of 		*/
+/*    developing products based on such documents.				*/
+/*										*/
+/*  2. Source Code Distribution Conditions:					*/
+/*										*/
+/*  - Redistributions of Source Code must retain the above copyright licenses, 	*/
+/*    this list of conditions and the following disclaimers.			*/
+/*										*/
+/*  - Redistributions in binary form must reproduce the above copyright 	*/
+/*    licenses, this list of conditions	and the following disclaimers in the 	*/
+/*    documentation and/or other materials provided with the distribution.	*/
+/*										*/
+/*  3. Disclaimers:								*/
+/*										*/
+/*  - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF	*/
+/*  LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH	*/
+/*  RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES)	*/
+/*  THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE.		*/
+/*  Contact TCG Administration (admin@trustedcomputinggroup.org) for 		*/
+/*  information on specification licensing rights available through TCG 	*/
+/*  membership agreements.							*/
+/*										*/
+/*  - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED 	*/
+/*    WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR 	*/
+/*    FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR 		*/
+/*    NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY 		*/
+/*    OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE.		*/
+/*										*/
+/*  - Without limitation, TCG and its members and licensors disclaim all 	*/
+/*    liability, including liability for infringement of any proprietary 	*/
+/*    rights, relating to use of information in this specification and to the	*/
+/*    implementation of this specification, and TCG disclaims all liability for	*/
+/*    cost of procurement of substitute goods or services, lost profits, loss 	*/
+/*    of use, loss of data or any incidental, consequential, direct, indirect, 	*/
+/*    or special damages, whether under contract, tort, warranty or otherwise, 	*/
+/*    arising in any way out of use or reliance upon this specification or any 	*/
+/*    information herein.							*/
+/*										*/
+/*  (c) Copyright IBM Corp. and others, 2019					*/
+/*										*/
+/********************************************************************************/
+
+#ifndef ACT_SPT_FP_H
+#define ACT_SPT_FP_H
+
+BOOL
+ActStartup(
+	   STARTUP_TYPE        type
+	   );
+BOOL
+ActGetSignaled(
+	       TPM_RH              actHandle
+	       );
+BOOL
+ActShutdown(
+	    TPM_SU              state       //IN: the type of the shutdown.
+	    );
+BOOL
+ActIsImplemented(
+		 UINT32          act
+		 );
+TPM_RC
+ActCounterUpdate(
+		 TPM_RH          handle,         //IN: the handle of the act
+		 UINT32          newValue        //IN: the value to set in the ACT
+		 );
+TPMI_YES_NO
+ActGetCapabilityData(
+		     TPM_HANDLE       actHandle,     // IN: the handle for the starting ACT
+		     UINT32           maxCount,      // IN: maximum allowed return values
+		     TPML_ACT_DATA   *actList        // OUT: ACT data list
+		     );
+
+
+
+#endif

+ 88 - 0
EVSE/GPL/ibmtpm1682/src/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

+ 244 - 0
EVSE/GPL/ibmtpm1682/src/AlgorithmCap.c

@@ -0,0 +1,244 @@
+/********************************************************************************/
+/*										*/
+/*			 Algorithm Property Definitions 			*/
+/*			     Written by Ken Goldman				*/
+/*		       IBM Thomas J. Watson Research Center			*/
+/*            $Id: AlgorithmCap.c 1594 2020-03-26 22:15:48Z kgoldman $		*/
+/*										*/
+/*  Licenses and Notices							*/
+/*										*/
+/*  1. Copyright Licenses:							*/
+/*										*/
+/*  - Trusted Computing Group (TCG) grants to the user of the source code in	*/
+/*    this specification (the "Source Code") a worldwide, irrevocable, 		*/
+/*    nonexclusive, royalty free, copyright license to reproduce, create 	*/
+/*    derivative works, distribute, display and perform the Source Code and	*/
+/*    derivative works thereof, and to grant others the rights granted herein.	*/
+/*										*/
+/*  - The TCG grants to the user of the other parts of the specification 	*/
+/*    (other than the Source Code) the rights to reproduce, distribute, 	*/
+/*    display, and perform the specification solely for the purpose of 		*/
+/*    developing products based on such documents.				*/
+/*										*/
+/*  2. Source Code Distribution Conditions:					*/
+/*										*/
+/*  - Redistributions of Source Code must retain the above copyright licenses, 	*/
+/*    this list of conditions and the following disclaimers.			*/
+/*										*/
+/*  - Redistributions in binary form must reproduce the above copyright 	*/
+/*    licenses, this list of conditions	and the following disclaimers in the 	*/
+/*    documentation and/or other materials provided with the distribution.	*/
+/*										*/
+/*  3. Disclaimers:								*/
+/*										*/
+/*  - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF	*/
+/*  LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH	*/
+/*  RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES)	*/
+/*  THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE.		*/
+/*  Contact TCG Administration (admin@trustedcomputinggroup.org) for 		*/
+/*  information on specification licensing rights available through TCG 	*/
+/*  membership agreements.							*/
+/*										*/
+/*  - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED 	*/
+/*    WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR 	*/
+/*    FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR 		*/
+/*    NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY 		*/
+/*    OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE.		*/
+/*										*/
+/*  - Without limitation, TCG and its members and licensors disclaim all 	*/
+/*    liability, including liability for infringement of any proprietary 	*/
+/*    rights, relating to use of information in this specification and to the	*/
+/*    implementation of this specification, and TCG disclaims all liability for	*/
+/*    cost of procurement of substitute goods or services, lost profits, loss 	*/
+/*    of use, loss of data or any incidental, consequential, direct, indirect, 	*/
+/*    or special damages, whether under contract, tort, warranty or otherwise, 	*/
+/*    arising in any way out of use or reliance upon this specification or any 	*/
+/*    information herein.							*/
+/*										*/
+/*  (c) Copyright IBM Corp. and others, 2016 - 2020				*/
+/*										*/
+/********************************************************************************/
+
+/* 9.1 AlgorithmCap.c */
+/* 9.1.1 Description */
+/* This file contains the algorithm property definitions for the algorithms and the code for the
+   TPM2_GetCapability() to return the algorithm properties. */
+/* 9.1.2 Includes and Defines */
+#include "Tpm.h"
+typedef struct
+{
+    TPM_ALG_ID          algID;
+    TPMA_ALGORITHM      attributes;
+} ALGORITHM;
+static const ALGORITHM    s_algorithms[] =
+    {
+	// The entries in this table need to be in ascending order but the table doesn't
+	// need to be full (gaps are allowed). One day, a tool might exist to fill in the
+	// table from the TPM_ALG description
+#if ALG_RSA
+	{TPM_ALG_RSA,           TPMA_ALGORITHM_INITIALIZER(1, 0, 0, 1, 0, 0, 0, 0, 0)},
+#endif
+#if ALG_TDES
+	{TPM_ALG_TDES,          TPMA_ALGORITHM_INITIALIZER(0, 1, 0, 0, 0, 0, 0, 0, 0)},
+#endif
+#if ALG_SHA1
+	{TPM_ALG_SHA1,          TPMA_ALGORITHM_INITIALIZER(0, 0, 1, 0, 0, 0, 0, 0, 0)},
+#endif
+	{TPM_ALG_HMAC,          TPMA_ALGORITHM_INITIALIZER(0, 0, 1, 0, 0, 1, 0, 0, 0)},
+#if ALG_AES
+	{TPM_ALG_AES,           TPMA_ALGORITHM_INITIALIZER(0, 1, 0, 0, 0, 0, 0, 0, 0)},
+#endif
+#if ALG_MGF1
+	{TPM_ALG_MGF1,          TPMA_ALGORITHM_INITIALIZER(0, 0, 1, 0, 0, 0, 0, 1, 0)},
+#endif
+	{TPM_ALG_KEYEDHASH,     TPMA_ALGORITHM_INITIALIZER(0, 0, 1, 1, 0, 1, 1, 0, 0)},
+#if ALG_XOR
+	{TPM_ALG_XOR,           TPMA_ALGORITHM_INITIALIZER(0, 1, 1, 0, 0, 0, 0, 0, 0)},
+#endif
+#if ALG_SHA256
+	{TPM_ALG_SHA256,        TPMA_ALGORITHM_INITIALIZER(0, 0, 1, 0, 0, 0, 0, 0, 0)},
+#endif
+#if ALG_SHA384
+	{TPM_ALG_SHA384,        TPMA_ALGORITHM_INITIALIZER(0, 0, 1, 0, 0, 0, 0, 0, 0)},
+#endif
+#if ALG_SHA512
+	{TPM_ALG_SHA512,        TPMA_ALGORITHM_INITIALIZER(0, 0, 1, 0, 0, 0, 0, 0, 0)},
+#endif
+#if ALG_SM3_256
+	{TPM_ALG_SM3_256,       TPMA_ALGORITHM_INITIALIZER(0, 0, 1, 0, 0, 0, 0, 0, 0)},
+#endif
+#if ALG_SM4
+	{TPM_ALG_SM4,           TPMA_ALGORITHM_INITIALIZER(0, 1, 0, 0, 0, 0, 0, 0, 0)},
+#endif
+#if ALG_RSASSA
+	{TPM_ALG_RSASSA,        TPMA_ALGORITHM_INITIALIZER(1, 0, 0, 0, 0, 1, 0, 0, 0)},
+#endif
+#if ALG_RSAES
+	{TPM_ALG_RSAES,         TPMA_ALGORITHM_INITIALIZER(1, 0, 0, 0, 0, 0, 1, 0, 0)},
+#endif
+#if ALG_RSAPSS
+	{TPM_ALG_RSAPSS,        TPMA_ALGORITHM_INITIALIZER(1, 0, 0, 0, 0, 1, 0, 0, 0)},
+#endif
+#if ALG_OAEP
+	{TPM_ALG_OAEP,          TPMA_ALGORITHM_INITIALIZER(1, 0, 0, 0, 0, 0, 1, 0, 0)},
+#endif
+#if ALG_ECDSA
+	{TPM_ALG_ECDSA,         TPMA_ALGORITHM_INITIALIZER(1, 0, 0, 0, 0, 1, 0, 0, 0)},
+#endif
+#if ALG_ECDH
+	{TPM_ALG_ECDH,          TPMA_ALGORITHM_INITIALIZER(1, 0, 0, 0, 0, 0, 0, 1, 0)},
+#endif
+#if ALG_ECDAA
+	{TPM_ALG_ECDAA,         TPMA_ALGORITHM_INITIALIZER(1, 0, 0, 0, 0, 1, 0, 0, 0)},
+#endif
+#if ALG_SM2
+	{TPM_ALG_SM2,           TPMA_ALGORITHM_INITIALIZER(1, 0, 0, 0, 0, 1, 0, 1, 0)},
+#endif
+#if ALG_ECSCHNORR
+	{TPM_ALG_ECSCHNORR,      TPMA_ALGORITHM_INITIALIZER(1, 0, 0, 0, 0, 1, 0, 0, 0)},
+#endif
+#if ALG_ECMQV
+	{TPM_ALG_ECMQV,          TPMA_ALGORITHM_INITIALIZER(1, 0, 0, 0, 0, 0, 0, 1, 0)},
+#endif
+#if ALG_KDF1_SP800_56A
+	{TPM_ALG_KDF1_SP800_56A, TPMA_ALGORITHM_INITIALIZER(0, 0, 1, 0, 0, 0, 0, 1, 0)},
+#endif
+#if ALG_KDF2
+	{TPM_ALG_KDF2,           TPMA_ALGORITHM_INITIALIZER(0, 0, 1, 0, 0, 0, 0, 1, 0)},
+#endif
+#if ALG_KDF1_SP800_108
+	{TPM_ALG_KDF1_SP800_108, TPMA_ALGORITHM_INITIALIZER(0, 0, 1, 0, 0, 0, 0, 1, 0)},
+#endif
+#if ALG_ECC
+	{TPM_ALG_ECC,            TPMA_ALGORITHM_INITIALIZER(1, 0, 0, 1, 0, 0, 0, 0, 0)},
+#endif
+	{TPM_ALG_SYMCIPHER,      TPMA_ALGORITHM_INITIALIZER(0, 0, 0, 1, 0, 0, 0, 0, 0)},
+#if ALG_CAMELLIA
+	{TPM_ALG_CAMELLIA,       TPMA_ALGORITHM_INITIALIZER(0, 1, 0, 0, 0, 0, 0, 0, 0)},
+#endif
+#if ALG_CMAC
+	{TPM_ALG_CMAC,           TPMA_ALGORITHM_INITIALIZER(0, 1, 0, 0, 0, 1, 0, 0, 0)},
+#endif
+#if ALG_CTR
+	{TPM_ALG_CTR,            TPMA_ALGORITHM_INITIALIZER(0, 1, 0, 0, 0, 0, 1, 0, 0)},
+#endif
+#if ALG_OFB
+	{TPM_ALG_OFB,            TPMA_ALGORITHM_INITIALIZER(0, 1, 0, 0, 0, 0, 1, 0, 0)},
+#endif
+#if ALG_CBC
+	{TPM_ALG_CBC,            TPMA_ALGORITHM_INITIALIZER(0, 1, 0, 0, 0, 0, 1, 0, 0)},
+#endif
+#if ALG_CFB
+	{TPM_ALG_CFB,            TPMA_ALGORITHM_INITIALIZER(0, 1, 0, 0, 0, 0, 1, 0, 0)},
+#endif
+#if ALG_ECB
+	{TPM_ALG_ECB,            TPMA_ALGORITHM_INITIALIZER(0, 1, 0, 0, 0, 0, 1, 0, 0)},
+#endif
+    };
+/* 9.1.3 AlgorithmCapGetImplemented() */
+/* This function is used by TPM2_GetCapability() to return a list of the implemented algorithms. */
+/* Return Values Meaning */
+/* YES more algorithms to report */
+/* NO no more algorithms to report */
+TPMI_YES_NO
+AlgorithmCapGetImplemented(
+			   TPM_ALG_ID                   algID,     // IN: the starting algorithm ID
+			   UINT32                       count,     // IN: count of returned algorithms
+			   TPML_ALG_PROPERTY           *algList    // OUT: algorithm list
+			   )
+{
+    TPMI_YES_NO     more = NO;
+    UINT32          i;
+    UINT32          algNum;
+    // initialize output algorithm list
+    algList->count = 0;
+    // The maximum count of algorithms we may return is MAX_CAP_ALGS.
+    if(count > MAX_CAP_ALGS)
+	count = MAX_CAP_ALGS;
+    // Compute how many algorithms are defined in s_algorithms array.
+    algNum = sizeof(s_algorithms) / sizeof(s_algorithms[0]);
+    // Scan the implemented algorithm list to see if there is a match to 'algID'.
+    for(i = 0; i < algNum; i++)
+	{
+	    // If algID is less than the starting algorithm ID, skip it
+	    if(s_algorithms[i].algID < algID)
+		continue;
+	    if(algList->count < count)
+		{
+		    // If we have not filled up the return list, add more algorithms
+		    // to it
+		    algList->algProperties[algList->count].alg = s_algorithms[i].algID;
+		    algList->algProperties[algList->count].algProperties =
+			s_algorithms[i].attributes;
+		    algList->count++;
+		}
+	    else
+		{
+		    // If the return list is full but we still have algorithms
+		    // available, report this and stop scanning.
+		    more = YES;
+		    break;
+		}
+	}
+    return more;
+}
+/* 9.1.4 AlgorithmGetImplementedVector()
+
+   This function returns the bit vector of the implemented algorithms.
+*/
+LIB_EXPORT
+void
+AlgorithmGetImplementedVector(
+			      ALGORITHM_VECTOR    *implemented    // OUT: the implemented bits are SET
+			      )
+{
+    int                      index;
+    // Nothing implemented until we say it is
+    MemorySet(implemented, 0, sizeof(ALGORITHM_VECTOR));
+    // Go through the list of implemented algorithms and SET the corresponding bit in
+    // in the implemented vector
+    for(index = (sizeof(s_algorithms) / sizeof(s_algorithms[0])) - 1;
+	index >= 0; index--)
+	SET_BIT(s_algorithms[index].algID, *implemented);
+    return;
+}

+ 78 - 0
EVSE/GPL/ibmtpm1682/src/AlgorithmCap_fp.h

@@ -0,0 +1,78 @@
+/********************************************************************************/
+/*										*/
+/*			     				*/
+/*			     Written by Ken Goldman				*/
+/*		       IBM Thomas J. Watson Research Center			*/
+/*            $Id: AlgorithmCap_fp.h 1490 2019-07-26 21:13:22Z kgoldman $	*/
+/*										*/
+/*  Licenses and Notices							*/
+/*										*/
+/*  1. Copyright Licenses:							*/
+/*										*/
+/*  - Trusted Computing Group (TCG) grants to the user of the source code in	*/
+/*    this specification (the "Source Code") a worldwide, irrevocable, 		*/
+/*    nonexclusive, royalty free, copyright license to reproduce, create 	*/
+/*    derivative works, distribute, display and perform the Source Code and	*/
+/*    derivative works thereof, and to grant others the rights granted herein.	*/
+/*										*/
+/*  - The TCG grants to the user of the other parts of the specification 	*/
+/*    (other than the Source Code) the rights to reproduce, distribute, 	*/
+/*    display, and perform the specification solely for the purpose of 		*/
+/*    developing products based on such documents.				*/
+/*										*/
+/*  2. Source Code Distribution Conditions:					*/
+/*										*/
+/*  - Redistributions of Source Code must retain the above copyright licenses, 	*/
+/*    this list of conditions and the following disclaimers.			*/
+/*										*/
+/*  - Redistributions in binary form must reproduce the above copyright 	*/
+/*    licenses, this list of conditions	and the following disclaimers in the 	*/
+/*    documentation and/or other materials provided with the distribution.	*/
+/*										*/
+/*  3. Disclaimers:								*/
+/*										*/
+/*  - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF	*/
+/*  LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH	*/
+/*  RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES)	*/
+/*  THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE.		*/
+/*  Contact TCG Administration (admin@trustedcomputinggroup.org) for 		*/
+/*  information on specification licensing rights available through TCG 	*/
+/*  membership agreements.							*/
+/*										*/
+/*  - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED 	*/
+/*    WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR 	*/
+/*    FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR 		*/
+/*    NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY 		*/
+/*    OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE.		*/
+/*										*/
+/*  - Without limitation, TCG and its members and licensors disclaim all 	*/
+/*    liability, including liability for infringement of any proprietary 	*/
+/*    rights, relating to use of information in this specification and to the	*/
+/*    implementation of this specification, and TCG disclaims all liability for	*/
+/*    cost of procurement of substitute goods or services, lost profits, loss 	*/
+/*    of use, loss of data or any incidental, consequential, direct, indirect, 	*/
+/*    or special damages, whether under contract, tort, warranty or otherwise, 	*/
+/*    arising in any way out of use or reliance upon this specification or any 	*/
+/*    information herein.							*/
+/*										*/
+/*  (c) Copyright IBM Corp. and others, 2016					*/
+/*										*/
+/********************************************************************************/
+
+#ifndef ALGORITHMCAP_FP_H
+#define ALGORITHMCAP_FP_H
+
+TPMI_YES_NO
+AlgorithmCapGetImplemented(
+			   TPM_ALG_ID                   algID,     // IN: the starting algorithm ID
+			   UINT32                       count,     // IN: count of returned algorithms
+			   TPML_ALG_PROPERTY           *algList    // OUT: algorithm list
+			   );
+LIB_EXPORT
+void
+AlgorithmGetImplementedVector(
+			      ALGORITHM_VECTOR    *implemented    // OUT: the implemented bits are SET
+			      );
+
+
+#endif

+ 911 - 0
EVSE/GPL/ibmtpm1682/src/AlgorithmTests.c

@@ -0,0 +1,911 @@
+/********************************************************************************/
+/*										*/
+/*			  Code to perform the various self-test functions.	*/
+/*			     Written by Ken Goldman				*/
+/*		       IBM Thomas J. Watson Research Center			*/
+/*            $Id: AlgorithmTests.c 1658 2021-01-22 23:14:01Z kgoldman $	*/
+/*										*/
+/*  Licenses and Notices							*/
+/*										*/
+/*  1. Copyright Licenses:							*/
+/*										*/
+/*  - Trusted Computing Group (TCG) grants to the user of the source code in	*/
+/*    this specification (the "Source Code") a worldwide, irrevocable, 		*/
+/*    nonexclusive, royalty free, copyright license to reproduce, create 	*/
+/*    derivative works, distribute, display and perform the Source Code and	*/
+/*    derivative works thereof, and to grant others the rights granted herein.	*/
+/*										*/
+/*  - The TCG grants to the user of the other parts of the specification 	*/
+/*    (other than the Source Code) the rights to reproduce, distribute, 	*/
+/*    display, and perform the specification solely for the purpose of 		*/
+/*    developing products based on such documents.				*/
+/*										*/
+/*  2. Source Code Distribution Conditions:					*/
+/*										*/
+/*  - Redistributions of Source Code must retain the above copyright licenses, 	*/
+/*    this list of conditions and the following disclaimers.			*/
+/*										*/
+/*  - Redistributions in binary form must reproduce the above copyright 	*/
+/*    licenses, this list of conditions	and the following disclaimers in the 	*/
+/*    documentation and/or other materials provided with the distribution.	*/
+/*										*/
+/*  3. Disclaimers:								*/
+/*										*/
+/*  - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF	*/
+/*  LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH	*/
+/*  RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES)	*/
+/*  THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE.		*/
+/*  Contact TCG Administration (admin@trustedcomputinggroup.org) for 		*/
+/*  information on specification licensing rights available through TCG 	*/
+/*  membership agreements.							*/
+/*										*/
+/*  - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED 	*/
+/*    WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR 	*/
+/*    FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR 		*/
+/*    NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY 		*/
+/*    OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE.		*/
+/*										*/
+/*  - Without limitation, TCG and its members and licensors disclaim all 	*/
+/*    liability, including liability for infringement of any proprietary 	*/
+/*    rights, relating to use of information in this specification and to the	*/
+/*    implementation of this specification, and TCG disclaims all liability for	*/
+/*    cost of procurement of substitute goods or services, lost profits, loss 	*/
+/*    of use, loss of data or any incidental, consequential, direct, indirect, 	*/
+/*    or special damages, whether under contract, tort, warranty or otherwise, 	*/
+/*    arising in any way out of use or reliance upon this specification or any 	*/
+/*    information herein.							*/
+/*										*/
+/*  (c) Copyright IBM Corp. and others, 2016 - 2021				*/
+/*										*/
+/********************************************************************************/
+
+/* 10.2.1 AlgorithmTests.c */
+/* 10.2.1.1 Introduction */
+/* This file contains the code to perform the various self-test functions. */
+/* 10.2.1.2 Includes and Defines */
+#include    "Tpm.h"
+#define     SELF_TEST_DATA
+#if SELF_TEST
+/* These includes pull in the data structures. They contain data definitions for the various
+   tests. */
+#include    "SelfTest.h"
+#include    "SymmetricTest.h"
+#include    "RsaTestData.h"
+#include    "EccTestData.h"
+#include    "HashTestData.h"
+#include    "KdfTestData.h"
+#define TEST_DEFAULT_TEST_HASH(vector)					\
+    if(TEST_BIT(DEFAULT_TEST_HASH, g_toTest))				\
+	TestHash(DEFAULT_TEST_HASH, vector);
+/* Make sure that the algorithm has been tested */
+#define CLEAR_BOTH(alg)     {   CLEAR_BIT(alg, *toTest);		\
+	if(toTest != &g_toTest)						\
+	    CLEAR_BIT(alg, g_toTest); }
+#define SET_BOTH(alg)     {   SET_BIT(alg, *toTest);			\
+	if(toTest != &g_toTest)						\
+	    SET_BIT(alg, g_toTest); }
+#define TEST_BOTH(alg)       ((toTest != &g_toTest)			\
+			      ? TEST_BIT(alg, *toTest) || TEST_BIT(alg, g_toTest) \
+			      : TEST_BIT(alg, *toTest))
+/* Can only cancel if doing a list. */
+#define CHECK_CANCELED							\
+    if(_plat__IsCanceled() && toTest != &g_toTest)			\
+	return TPM_RC_CANCELED;
+/* 10.2.1.3 Hash Tests */
+/* 10.2.1.3.1 Description */
+/* The hash test does a known-value HMAC using the specified hash algorithm. */
+/* 10.2.1.3.2 TestHash() */
+/* The hash test function. */
+static TPM_RC
+TestHash(
+	 TPM_ALG_ID          hashAlg,
+	 ALGORITHM_VECTOR    *toTest
+	 )
+{
+    TPM2B_DIGEST      computed;  // value computed
+    HMAC_STATE        state;
+    UINT16            digestSize;
+    const TPM2B       *testDigest = NULL;
+    //    TPM2B_TYPE(HMAC_BLOCK, DEFAULT_TEST_HASH_BLOCK_SIZE);
+    pAssert(hashAlg != TPM_ALG_NULL);
+#define HASH_CASE_FOR_TEST(HASH, hash)        case ALG_##HASH##_VALUE:	\
+    testDigest = &c_##HASH##_digest.b;					\
+    break;
+    switch(hashAlg)
+	{
+	    FOR_EACH_HASH(HASH_CASE_FOR_TEST)
+
+	  default:
+	    FAIL(FATAL_ERROR_INTERNAL);
+	}
+    // Clear the to-test bits
+    CLEAR_BOTH(hashAlg);
+
+    // If there is an algorithm without test vectors, then assume that things are OK.
+    if(testDigest == NULL || testDigest->size == 0)
+	return TPM_RC_SUCCESS;
+
+    // Set the HMAC key to twice the digest size
+    digestSize = CryptHashGetDigestSize(hashAlg);
+    CryptHmacStart(&state, hashAlg, digestSize * 2,
+		   (BYTE *)c_hashTestKey.t.buffer);
+    CryptDigestUpdate(&state.hashState, 2 * CryptHashGetBlockSize(hashAlg),
+		      (BYTE *)c_hashTestData.t.buffer);
+    computed.t.size = digestSize;
+    CryptHmacEnd(&state, digestSize, computed.t.buffer);
+    if((testDigest->size != computed.t.size)
+       || (memcmp(testDigest->buffer, computed.t.buffer, computed.b.size) != 0)) {
+	SELF_TEST_FAILURE;
+    }
+    return TPM_RC_SUCCESS;
+}
+/* 10.2.1.4 Symmetric Test Functions */
+/* 10.2.1.4.1 MakeIv() */
+/* Internal function to make the appropriate IV depending on the mode. */
+static UINT32
+MakeIv(
+       TPM_ALG_ID    mode,     // IN: symmetric mode
+       UINT32        size,     // IN: block size of the algorithm
+       BYTE         *iv        // OUT: IV to fill in
+       )
+{
+    BYTE          i;
+    if(mode == TPM_ALG_ECB)
+	return 0;
+    if(mode == TPM_ALG_CTR)
+	{
+	    // The test uses an IV that has 0xff in the last byte
+	    for(i = 1; i <= size; i++)
+		*iv++ = 0xff - (BYTE)(size - i);
+	}
+    else
+	{
+	    for(i = 0; i < size; i++)
+		*iv++ = i;
+	}
+    return size;
+}
+/* 10.2.1.4.2 TestSymmetricAlgorithm() */
+/* Function to test a specific algorithm, key size, and mode. */
+static void
+TestSymmetricAlgorithm(
+		       const SYMMETRIC_TEST_VECTOR     *test,          //
+		       TPM_ALG_ID                       mode           //
+		       )
+{
+    BYTE                            encrypted[MAX_SYM_BLOCK_SIZE * 2];
+    BYTE                            decrypted[MAX_SYM_BLOCK_SIZE * 2];
+    TPM2B_IV                        iv;
+    //
+    // Get the appropriate IV
+    iv.t.size = (UINT16)MakeIv(mode, test->ivSize, iv.t.buffer);
+    // Encrypt known data
+    CryptSymmetricEncrypt(encrypted, test->alg, test->keyBits, test->key, &iv,
+			  mode, test->dataInOutSize, test->dataIn);
+    // Check that it matches the expected value
+    if(!MemoryEqual(encrypted, test->dataOut[mode - TPM_ALG_CTR],
+		    test->dataInOutSize)) {
+	SELF_TEST_FAILURE;
+    }
+    // Reinitialize the iv for decryption
+    MakeIv(mode, test->ivSize, iv.t.buffer);
+    CryptSymmetricDecrypt(decrypted, test->alg, test->keyBits, test->key, &iv,
+			  mode, test->dataInOutSize,
+			  test->dataOut[mode - TPM_ALG_CTR]);
+    // Make sure that it matches what we started with
+    if(!MemoryEqual(decrypted, test->dataIn, test->dataInOutSize)) {
+	SELF_TEST_FAILURE;
+    }
+}
+/* 10.2.1.4.3 AllSymsAreDone() */
+/* Checks if both symmetric algorithms have been tested. This is put here so that addition of a
+   symmetric algorithm will be relatively easy to handle */
+/* Return Value	Meaning */
+/* TRUE(1)	all symmetric algorithms tested */
+/* FALSE(0)	not all symmetric algorithms tested */
+static BOOL
+AllSymsAreDone(
+	       ALGORITHM_VECTOR        *toTest
+	       )
+{
+    return (!TEST_BOTH(TPM_ALG_AES) && !TEST_BOTH(TPM_ALG_SM4));
+}
+/* 10.2.1.4.4 AllModesAreDone() */
+/* Checks if all the modes have been tested */
+/* Return Value	Meaning */
+/* TRUE(1)	all modes tested */
+/* FALSE(0)	all modes not tested */
+static BOOL
+AllModesAreDone(
+		ALGORITHM_VECTOR            *toTest
+		)
+{
+    TPM_ALG_ID                  alg;
+    for(alg = SYM_MODE_FIRST; alg <= SYM_MODE_LAST; alg++)
+	if(TEST_BOTH(alg))
+	    return FALSE;
+    return TRUE;
+}
+/* 10.2.1.4.5 TestSymmetric() */
+/* If alg is a symmetric block cipher, then all of the modes that are selected are tested. If alg is
+   a mode, then all algorithms of that mode are tested. */
+static TPM_RC
+TestSymmetric(
+	      TPM_ALG_ID                   alg,
+	      ALGORITHM_VECTOR            *toTest
+	      )
+{
+    SYM_INDEX                    index;
+    TPM_ALG_ID                   mode;
+    //
+    if(!TEST_BIT(alg, *toTest))
+	return TPM_RC_SUCCESS;
+    if(alg == TPM_ALG_AES || alg == TPM_ALG_SM4 || alg == TPM_ALG_CAMELLIA)
+	{
+	    // Will test the algorithm for all modes and key sizes
+	    CLEAR_BOTH(alg);
+	    // A test this algorithm for all modes
+	    for(index = 0; index < NUM_SYMS; index++)
+		{
+		    if(c_symTestValues[index].alg == alg)
+			{
+			    for(mode = SYM_MODE_FIRST;
+				mode <= SYM_MODE_LAST;
+				mode++)
+				{
+				    if(TEST_BIT(mode, *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 = SYM_MODE_FIRST; alg <= SYM_MODE_LAST; alg++)
+			CLEAR_BOTH(alg);
+		}
+	}
+    else if(SYM_MODE_FIRST <= alg && alg <= SYM_MODE_LAST)
+	{
+	    // Test this mode for all key sizes and algorithms
+	    for(index = 0; index < NUM_SYMS; index++)
+		{
+		    // The mode testing only comes into play when doing self tests
+		    // by command. When doing self tests by command, the block ciphers are
+		    // tested first. That means that all of their modes would have been
+		    // tested for all key sizes. If there is no block cipher left to
+		    // test, then clear this mode bit.
+		    if(!TEST_BIT(TPM_ALG_AES, *toTest)
+		       && !TEST_BIT(TPM_ALG_SM4, *toTest))
+			{
+			    CLEAR_BOTH(alg);
+			}
+		    else
+			{
+			    for(index = 0; index < NUM_SYMS; index++)
+				{
+				    if(TEST_BIT(c_symTestValues[index].alg, *toTest))
+					TestSymmetricAlgorithm(&c_symTestValues[index], alg);
+				}
+			    // have tested this mode for all algorithms
+			    CLEAR_BOTH(alg);
+			}
+		}
+	    if(AllModesAreDone(toTest))
+		{
+		    CLEAR_BOTH(TPM_ALG_AES);
+		    CLEAR_BOTH(TPM_ALG_SM4);
+		}
+	}
+    else
+	pAssert(alg == 0 && alg != 0);
+    return TPM_RC_SUCCESS;
+}
+/* 10.2.1.5 RSA Tests */
+#if ALG_RSA
+/* 10.2.1.5.1 Introduction */
+/* The tests are for public key only operations and for private key operations. Signature
+   verification and encryption are public key operations. They are tested by using a KVT. For
+   signature verification, this means that a known good signature is checked by
+   CryptRsaValidateSignature(). If it fails, then the TPM enters failure mode. For encryption, the
+   TPM encrypts known values using the selected scheme and checks that the returned value matches
+   the expected value. */
+/* For private key operations, a full scheme check is used. For a signing key, a known key is used
+   to sign a known message. Then that signature is verified. since the signature may involve use of
+   random values, the signature will be different each time and we can't always check that the
+   signature matches a known value. The same technique is used for decryption (RSADP/RSAEP). */
+/* When an operation uses the public key and the verification has not been tested, the TPM will do a
+   KVT. */
+/* The test for the signing algorithm is built into the call for the algorithm */
+/* 10.2.1.5.2 RsaKeyInitialize() */
+/* The test key is defined by a public modulus and a private prime. The TPM's RSA code computes the
+   second prime and the private exponent. */
+static void
+RsaKeyInitialize(
+		 OBJECT          *testObject
+		 )
+{
+    MemoryCopy2B(&testObject->publicArea.unique.rsa.b, (P2B)&c_rsaPublicModulus,
+		 sizeof(c_rsaPublicModulus));
+    MemoryCopy2B(&testObject->sensitive.sensitive.rsa.b, (P2B)&c_rsaPrivatePrime,
+		 sizeof(testObject->sensitive.sensitive.rsa.t.buffer));
+    testObject->publicArea.parameters.rsaDetail.keyBits = RSA_TEST_KEY_SIZE * 8;
+    // Use the default exponent
+    testObject->publicArea.parameters.rsaDetail.exponent = 0;
+    testObject->attributes.privateExp = 0;
+}
+/* 10.2.1.5.3 TestRsaEncryptDecrypt() */
+/* These tests are for a public key encryption that uses a random value. */
+static TPM_RC
+TestRsaEncryptDecrypt(
+		      TPM_ALG_ID           scheme,            // IN: the scheme
+		      ALGORITHM_VECTOR    *toTest             //
+		      )
+{
+    TPM2B_PUBLIC_KEY_RSA             testInput;
+    TPM2B_PUBLIC_KEY_RSA             testOutput;
+    OBJECT                           testObject;
+    const TPM2B_RSA_TEST_KEY        *kvtValue = NULL;
+    TPM_RC                           result = TPM_RC_SUCCESS;
+    const TPM2B                     *testLabel = NULL;
+    TPMT_RSA_DECRYPT                 rsaScheme;
+    //
+    // Don't need to initialize much of the test object but do need to initialize
+    // the flag indicating that the private exponent has been computed.
+    testObject.attributes.privateExp = CLEAR;
+    RsaKeyInitialize(&testObject);
+    rsaScheme.scheme = scheme;
+    rsaScheme.details.anySig.hashAlg = DEFAULT_TEST_HASH;
+    CLEAR_BOTH(scheme);
+    CLEAR_BOTH(TPM_ALG_NULL);
+    if(scheme == TPM_ALG_NULL)
+	{
+	    // This is an encryption scheme using the private key without any encoding.
+	    memcpy(testInput.t.buffer, c_RsaTestValue, sizeof(c_RsaTestValue));
+	    testInput.t.size = sizeof(c_RsaTestValue);
+	    if(TPM_RC_SUCCESS != CryptRsaEncrypt(&testOutput, &testInput.b,
+						 &testObject, &rsaScheme, NULL, NULL)) {
+		SELF_TEST_FAILURE;
+	    }
+	    if(!MemoryEqual(testOutput.t.buffer, c_RsaepKvt.buffer, c_RsaepKvt.size)) {
+		SELF_TEST_FAILURE;
+	    }
+	    MemoryCopy2B(&testInput.b, &testOutput.b, sizeof(testInput.t.buffer));
+	    if(TPM_RC_SUCCESS != CryptRsaDecrypt(&testOutput.b, &testInput.b,
+						 &testObject, &rsaScheme, NULL)) {
+		SELF_TEST_FAILURE;
+	    }
+	    if(!MemoryEqual(testOutput.t.buffer, c_RsaTestValue,
+			    sizeof(c_RsaTestValue))) {
+		SELF_TEST_FAILURE;
+	    }
+	}
+    else
+	{
+	    // TPM_ALG_RSAES:
+	    // This is an decryption scheme using padding according to
+	    // PKCS#1v2.1, 7.2. This padding uses random bits. To test a public
+	    // key encryption that uses random data, encrypt a value and then
+	    // decrypt the value and see that we get the encrypted data back.
+	    // The hash is not used by this encryption so it can be TMP_ALG_NULL
+	    // TPM_ALG_OAEP_:
+	    // This is also an decryption scheme and it also uses a
+	    // pseudo-random
+	    // value. However, this also uses a hash algorithm. So, we may need
+	    // to test that algorithm before use.
+	    if(scheme == TPM_ALG_OAEP)
+		{
+		    TEST_DEFAULT_TEST_HASH(toTest);
+		    kvtValue = &c_OaepKvt;
+		    testLabel = OAEP_TEST_STRING;
+		}
+	    else if(scheme == TPM_ALG_RSAES)
+		{
+		    kvtValue = &c_RsaesKvt;
+		    testLabel = NULL;
+		}
+	    else {
+		SELF_TEST_FAILURE;
+	    }
+	    // Only use a digest-size portion of the test value
+	    memcpy(testInput.t.buffer, c_RsaTestValue, DEFAULT_TEST_DIGEST_SIZE);
+	    testInput.t.size = DEFAULT_TEST_DIGEST_SIZE;
+	    // See if the encryption works
+	    if(TPM_RC_SUCCESS != CryptRsaEncrypt(&testOutput, &testInput.b,
+						 &testObject, &rsaScheme, testLabel,
+						 NULL)) {
+		SELF_TEST_FAILURE;
+	    }
+	    MemoryCopy2B(&testInput.b, &testOutput.b, sizeof(testInput.t.buffer));
+	    // see if we can decrypt this value and get the original data back
+	    if(TPM_RC_SUCCESS != CryptRsaDecrypt(&testOutput.b, &testInput.b,
+						 &testObject, &rsaScheme, testLabel)) {
+		SELF_TEST_FAILURE;
+	    }
+	    // See if the results compare
+	    if(testOutput.t.size != DEFAULT_TEST_DIGEST_SIZE
+	       || !MemoryEqual(testOutput.t.buffer, c_RsaTestValue,
+			       DEFAULT_TEST_DIGEST_SIZE)) {
+		SELF_TEST_FAILURE;
+	    }
+	    // Now check that the decryption works on a known value
+	    MemoryCopy2B(&testInput.b, (P2B)kvtValue,
+			 sizeof(testInput.t.buffer));
+	    if(TPM_RC_SUCCESS != CryptRsaDecrypt(&testOutput.b, &testInput.b,
+						 &testObject, &rsaScheme, testLabel)) {
+		SELF_TEST_FAILURE;
+	    }
+	    if(testOutput.t.size != DEFAULT_TEST_DIGEST_SIZE
+	       || !MemoryEqual(testOutput.t.buffer, c_RsaTestValue,
+			       DEFAULT_TEST_DIGEST_SIZE)) {
+		SELF_TEST_FAILURE;
+	    }
+	}
+    return result;
+}
+/* 10.2.1.5.4 TestRsaSignAndVerify() */
+/* This function does the testing of the RSA sign and verification functions. This test does a
+   KVT. */
+static TPM_RC
+TestRsaSignAndVerify(
+		     TPM_ALG_ID               scheme,
+		     ALGORITHM_VECTOR        *toTest
+		     )
+{
+    TPM_RC                      result = TPM_RC_SUCCESS;
+    OBJECT                      testObject;
+    TPM2B_DIGEST                testDigest;
+    TPMT_SIGNATURE              testSig;
+    // Do a sign and signature verification.
+    // RSASSA:
+    // This is a signing scheme according to PKCS#1-v2.1 8.2. It does not
+    // use random data so there is a KVT for the signing operation. On
+    // first use of the scheme for signing, use the TPM's RSA key to
+    // sign a portion of c_RsaTestData and compare the results to c_RsassaKvt. Then
+    // decrypt the data to see that it matches the starting value. This verifies
+    // the signature with a KVT
+    // Clear the bits indicating that the function has not been checked. This is to
+    // prevent looping
+    CLEAR_BOTH(scheme);
+    CLEAR_BOTH(TPM_ALG_NULL);
+    CLEAR_BOTH(TPM_ALG_RSA);
+    RsaKeyInitialize(&testObject);
+    memcpy(testDigest.t.buffer, (BYTE *)c_RsaTestValue, DEFAULT_TEST_DIGEST_SIZE);
+    testDigest.t.size = DEFAULT_TEST_DIGEST_SIZE;
+    testSig.sigAlg = scheme;
+    testSig.signature.rsapss.hash = DEFAULT_TEST_HASH;
+    // RSAPSS:
+    // This is a signing scheme a according to PKCS#1-v2.2 8.1 it uses
+    // random data in the signature so there is no KVT for the signing
+    // operation. To test signing, the TPM will use the TPM's RSA key
+    // to sign a portion of c_RsaTestValue and then it will verify the
+    // signature. For verification, c_RsapssKvt is verified before the
+    // user signature blob is verified. The worst case for testing of this
+    // algorithm is two private and one public key operation.
+    // The process is to sign known data. If RSASSA is being done, verify that the
+    // signature matches the precomputed value. For both, use the signed value and
+    // see that the verification says that it is a good signature. Then
+    // if testing RSAPSS, do a verify of a known good signature. This ensures that
+    // the validation function works.
+    if(TPM_RC_SUCCESS != CryptRsaSign(&testSig, &testObject, &testDigest, NULL)) {
+	SELF_TEST_FAILURE;
+    }
+    // For RSASSA, make sure the results is what we are looking for
+    if(testSig.sigAlg == TPM_ALG_RSASSA)
+	{
+	    if(testSig.signature.rsassa.sig.t.size != RSA_TEST_KEY_SIZE
+	       || !MemoryEqual(c_RsassaKvt.buffer,
+			       testSig.signature.rsassa.sig.t.buffer,
+			       RSA_TEST_KEY_SIZE)) {
+		SELF_TEST_FAILURE;
+	    }
+	}
+    // See if the TPM will validate its own signatures
+    if(TPM_RC_SUCCESS != CryptRsaValidateSignature(&testSig, &testObject,
+						   &testDigest)) {
+	SELF_TEST_FAILURE;
+    }
+    // If this is RSAPSS, check the verification with known signature
+    // Have to copy because  CrytpRsaValidateSignature() eats the signature
+    if(TPM_ALG_RSAPSS == scheme)
+	{
+	    MemoryCopy2B(&testSig.signature.rsapss.sig.b, (P2B)&c_RsapssKvt,
+			 sizeof(testSig.signature.rsapss.sig.t.buffer));
+	    if(TPM_RC_SUCCESS != CryptRsaValidateSignature(&testSig, &testObject,
+							   &testDigest)) {
+		SELF_TEST_FAILURE;
+	    }
+	}
+    return result;
+}
+/* 10.2.1.5.5 TestRSA() */
+/* Function uses the provided vector to indicate which tests to run. It will clear the vector after
+   each test is run and also clear g_toTest */
+static TPM_RC
+TestRsa(
+	TPM_ALG_ID               alg,
+	ALGORITHM_VECTOR        *toTest
+	)
+{
+    TPM_RC                  result = TPM_RC_SUCCESS;
+    //
+    switch(alg)
+	{
+	  case TPM_ALG_NULL:
+	    // This is the RSAEP/RSADP function. If we are processing a list, don't
+	    // need to test these now because any other test will validate
+	    // RSAEP/RSADP. Can tell this is list of test by checking to see if
+	    // 'toTest' is pointing at g_toTest. If so, this is an isolated test
+	    // an need to go ahead and do the test;
+	    if((toTest == &g_toTest)
+	       || (!TEST_BIT(TPM_ALG_RSASSA, *toTest)
+		   && !TEST_BIT(TPM_ALG_RSAES, *toTest)
+		   && !TEST_BIT(TPM_ALG_RSAPSS, *toTest)
+		   && !TEST_BIT(TPM_ALG_OAEP, *toTest)))
+		// Not running a list of tests or no other tests on the list
+		// so run the test now
+		result = TestRsaEncryptDecrypt(alg, toTest);
+	    // if not running the test now, leave the bit on, just in case things
+	    // get interrupted
+	    break;
+	  case TPM_ALG_OAEP:
+	  case TPM_ALG_RSAES:
+	    result = TestRsaEncryptDecrypt(alg, toTest);
+	    break;
+	  case TPM_ALG_RSAPSS:
+	  case TPM_ALG_RSASSA:
+	    result = TestRsaSignAndVerify(alg, toTest);
+	    break;
+	  default:
+	    SELF_TEST_FAILURE;
+	}
+    return result;
+}
+#endif // TPM_ALG_RSA
+/* 10.2.1.6 ECC Tests */
+#if ALG_ECC
+/* 10.2.1.6.1 LoadEccParameter() */
+/* This function is mostly for readability and type checking */
+static void
+LoadEccParameter(
+		 TPM2B_ECC_PARAMETER          *to,       // target
+		 const TPM2B_EC_TEST          *from      // source
+		 )
+{
+    MemoryCopy2B(&to->b, &from->b, sizeof(to->t.buffer));
+}
+/* 10.2.1.6.2 LoadEccPoint() */
+static void
+LoadEccPoint(
+	     TPMS_ECC_POINT               *point,       // target
+	     const TPM2B_EC_TEST          *x,             // source
+	     const TPM2B_EC_TEST           *y
+	     )
+{
+    MemoryCopy2B(&point->x.b, (TPM2B *)x, sizeof(point->x.t.buffer));
+    MemoryCopy2B(&point->y.b, (TPM2B *)y, sizeof(point->y.t.buffer));
+}
+/* 10.2.1.6.3 TestECDH() */
+/* This test does a KVT on a point multiply. */
+static TPM_RC
+TestECDH(
+	 TPM_ALG_ID          scheme,         // IN: for consistency
+	 ALGORITHM_VECTOR    *toTest         // IN/OUT: modified after test is run
+	 )
+{
+    TPMS_ECC_POINT          Z;
+    TPMS_ECC_POINT          Qe;
+    TPM2B_ECC_PARAMETER     ds;
+    TPM_RC                  result = TPM_RC_SUCCESS;
+    //
+    NOT_REFERENCED(scheme);
+    CLEAR_BOTH(TPM_ALG_ECDH);
+    LoadEccParameter(&ds, &c_ecTestKey_ds);
+    LoadEccPoint(&Qe, &c_ecTestKey_QeX, &c_ecTestKey_QeY);
+    if(TPM_RC_SUCCESS != CryptEccPointMultiply(&Z, c_testCurve, &Qe, &ds,
+					       NULL, NULL)) {
+	SELF_TEST_FAILURE;
+    }
+    if(!MemoryEqual2B(&c_ecTestEcdh_X.b, &Z.x.b)
+       || !MemoryEqual2B(&c_ecTestEcdh_Y.b, &Z.y.b)) {
+	SELF_TEST_FAILURE;
+    }
+    return result;
+}
+/* 10.2.1.6.4	TestEccSignAndVerify() */
+static TPM_RC
+TestEccSignAndVerify(
+		     TPM_ALG_ID                   scheme,
+		     ALGORITHM_VECTOR            *toTest
+		     )
+{
+    OBJECT                       testObject;
+    TPMT_SIGNATURE               testSig;
+    TPMT_ECC_SCHEME              eccScheme;
+    testSig.sigAlg = scheme;
+    testSig.signature.ecdsa.hash = DEFAULT_TEST_HASH;
+    eccScheme.scheme = scheme;
+    eccScheme.details.anySig.hashAlg = DEFAULT_TEST_HASH;
+    CLEAR_BOTH(scheme);
+    CLEAR_BOTH(TPM_ALG_ECDH);
+    // ECC signature verification testing uses a KVT.
+    switch(scheme)
+	{
+	  case TPM_ALG_ECDSA:
+	    LoadEccParameter(&testSig.signature.ecdsa.signatureR, &c_TestEcDsa_r);
+	    LoadEccParameter(&testSig.signature.ecdsa.signatureS, &c_TestEcDsa_s);
+	    break;
+	  case TPM_ALG_ECSCHNORR:
+	    LoadEccParameter(&testSig.signature.ecschnorr.signatureR,
+			     &c_TestEcSchnorr_r);
+	    LoadEccParameter(&testSig.signature.ecschnorr.signatureS,
+			     &c_TestEcSchnorr_s);
+	    break;
+	  case TPM_ALG_SM2:
+	    // don't have a test for SM2
+	    return TPM_RC_SUCCESS;
+	  default:
+	    SELF_TEST_FAILURE;
+	    break;
+	}
+    TEST_DEFAULT_TEST_HASH(toTest);
+    // Have to copy the key. This is because the size used in the test vectors
+    // is the size of the ECC parameter for the test key while the size of a point
+    // is TPM dependent
+    MemoryCopy2B(&testObject.sensitive.sensitive.ecc.b, &c_ecTestKey_ds.b,
+		 sizeof(testObject.sensitive.sensitive.ecc.t.buffer));
+    LoadEccPoint(&testObject.publicArea.unique.ecc, &c_ecTestKey_QsX,
+		 &c_ecTestKey_QsY);
+    testObject.publicArea.parameters.eccDetail.curveID = c_testCurve;
+    if(TPM_RC_SUCCESS != CryptEccValidateSignature(&testSig, &testObject,
+						   (TPM2B_DIGEST *)&c_ecTestValue.b))
+	{
+	    SELF_TEST_FAILURE;
+	}
+    CHECK_CANCELED;
+    // Now sign and verify some data
+    if(TPM_RC_SUCCESS != CryptEccSign(&testSig, &testObject,
+				      (TPM2B_DIGEST *)&c_ecTestValue,
+				      &eccScheme, NULL)) {
+	SELF_TEST_FAILURE;
+    }
+    CHECK_CANCELED;
+    if(TPM_RC_SUCCESS != CryptEccValidateSignature(&testSig, &testObject,
+						   (TPM2B_DIGEST *)&c_ecTestValue)) {
+	SELF_TEST_FAILURE;
+    }
+    CHECK_CANCELED;
+    return TPM_RC_SUCCESS;
+}
+/* 10.2.1.6.5	TestKDFa() */
+
+static TPM_RC
+TestKDFa(
+	 ALGORITHM_VECTOR        *toTest
+	 )
+{
+    static TPM2B_KDF_TEST_KEY   keyOut;
+    UINT32                      counter = 0;
+    //
+    CLEAR_BOTH(TPM_ALG_KDF1_SP800_108);
+    keyOut.t.size = CryptKDFa(KDF_TEST_ALG, &c_kdfTestKeyIn.b, &c_kdfTestLabel.b,
+			      &c_kdfTestContextU.b, &c_kdfTestContextV.b,
+			      TEST_KDF_KEY_SIZE * 8, keyOut.t.buffer,
+			      &counter, FALSE);
+    if (   keyOut.t.size != TEST_KDF_KEY_SIZE
+	   || !MemoryEqual(keyOut.t.buffer, c_kdfTestKeyOut.t.buffer,
+			   TEST_KDF_KEY_SIZE))
+	SELF_TEST_FAILURE;
+    return TPM_RC_SUCCESS;
+}
+/* 10.2.1.6.6	TestEcc() */
+static TPM_RC
+TestEcc(
+	TPM_ALG_ID              alg,
+	ALGORITHM_VECTOR        *toTest
+	)
+{
+    TPM_RC                  result = TPM_RC_SUCCESS;
+    NOT_REFERENCED(toTest);
+    switch(alg)
+	{
+	  case TPM_ALG_ECC:
+	  case TPM_ALG_ECDH:
+	    // If this is in a loop then see if another test is going to deal with
+	    // this.
+	    // If toTest is not a self-test list
+	    if((toTest == &g_toTest)
+	       // or this is the only ECC test in the list
+	       || !(TEST_BIT(TPM_ALG_ECDSA, *toTest)
+		    || TEST_BIT(TPM_ALG_ECSCHNORR, *toTest)
+		    || TEST_BIT(TPM_ALG_SM2, *toTest)))
+		{
+		    result = TestECDH(alg, toTest);
+		}
+	    break;
+	  case TPM_ALG_ECDSA:
+	  case TPM_ALG_ECSCHNORR:
+	  case TPM_ALG_SM2:
+	    result = TestEccSignAndVerify(alg, toTest);
+	    break;
+	  default:
+	    SELF_TEST_FAILURE;
+	    break;
+	}
+    return result;
+}
+#endif // TPM_ALG_ECC
+/* 10.2.1.6.4 TestAlgorithm() */
+/* Dispatches to the correct test function for the algorithm or gets a list of testable
+   algorithms. */
+/* If toTest is not NULL, then the test decisions are based on the algorithm selections in
+   toTest. Otherwise, g_toTest is used. When bits are clear in g_toTest they will also be cleared
+   toTest. */
+/* If there doesn't happen to be a test for the algorithm, its associated bit is quietly cleared. */
+/* If alg is zero (TPM_ALG_ERROR), then the toTest vector is cleared of any bits for which there is
+   no test (i.e. no tests are actually run but the vector is cleared). */
+/* NOTE: toTest will only ever have bits set for implemented algorithms but alg can be anything. */
+/* Error Returns Meaning */
+/* TPM_RC_CANCELED test was canceled */
+LIB_EXPORT
+TPM_RC
+TestAlgorithm(
+	      TPM_ALG_ID               alg,
+	      ALGORITHM_VECTOR        *toTest
+	      )
+{
+    TPM_ALG_ID              first = (alg == TPM_ALG_ERROR) ? TPM_ALG_FIRST : alg;
+    TPM_ALG_ID              last = (alg == TPM_ALG_ERROR) ? TPM_ALG_LAST : alg;
+    BOOL                    doTest = (alg != TPM_ALG_ERROR);
+    TPM_RC                  result = TPM_RC_SUCCESS;
+    if(toTest == NULL)
+	toTest = &g_toTest;
+    // This is kind of strange. This function will either run a test of the selected
+    // algorithm or just clear a bit if there is no test for the algorithm. So,
+    // either this loop will be executed once for the selected algorithm or once for
+    // each of the possible algorithms. If it is executed more than once ('alg' ==
+    // TPM_ALG_ERROR), then no test will be run but bits will be cleared for
+    // unimplemented algorithms. This was done this way so that there is only one
+    // case statement with all of the algorithms. It was easier to have one case
+    // statement than to have multiple ones to manage whenever an algorithm ID is
+    // added.
+    for(alg = first; (alg <= last); alg++)
+	{
+	    // if 'alg' was TPM_ALG_ERROR, then we will be cycling through
+	    // values, some of which may not be implemented. If the bit in toTest
+	    // happens to be set, then we could either generated an assert, or just
+	    // silently CLEAR it. Decided to just clear.
+	    if(!TEST_BIT(alg, g_implementedAlgorithms))
+		{
+		    CLEAR_BIT(alg, *toTest);
+		    continue;
+		}
+	    // Process whatever is left.
+	    // NOTE: since this switch will only be called if the algorithm is
+	    // implemented, it is not necessary to modify this list except to comment
+	    // out the algorithms for which there is no test
+	    switch(alg)
+		{
+		    // Symmetric block ciphers
+#if ALG_AES
+		  case TPM_ALG_AES:
+#endif
+#if ALG_SM4
+		    // if SM4 is implemented, its test is like other block ciphers but there
+		    // aren't any test vectors for it yet
+		    //            case TPM_ALG_SM4:
+#endif
+#if ALG_CAMELLIA
+		    // no test vectors for camellia
+		    //            case TPM_ALG_CAMELLIA:
+#endif
+		    // Symmetric modes
+#if !ALG_CFB
+#   error   CFB is required in all TPM implementations
+#endif // !TPM_ALG_CFB
+		  case TPM_ALG_CFB:
+		    if(doTest)
+			result = TestSymmetric(alg, toTest);
+		    break;
+#if ALG_CTR
+		  case TPM_ALG_CTR:
+#endif // TPM_ALG_CRT
+#if ALG_OFB
+		  case TPM_ALG_OFB:
+#endif // TPM_ALG_OFB
+#if ALG_CBC
+		  case TPM_ALG_CBC:
+#endif // TPM_ALG_CBC
+#if ALG_ECB
+		  case TPM_ALG_ECB:
+#endif
+		    if(doTest)
+			result = TestSymmetric(alg, toTest);
+		    else
+			// If doing the initialization of g_toTest vector, only need
+			// to test one of the modes for the symmetric algorithms. If
+			// initializing for a SelfTest(FULL_TEST), allow all the modes.
+			if(toTest == &g_toTest)
+			    CLEAR_BIT(alg, *toTest);
+		    break;
+#if !ALG_HMAC
+#   error   HMAC is required in all TPM implementations
+#endif
+		  case TPM_ALG_HMAC:
+		    // Clear the bit that indicates that HMAC is required because
+		    // HMAC is used as the basic test for all hash algorithms.
+		    CLEAR_BOTH(alg);
+		    // Testing HMAC means test the default hash
+		    if(doTest)
+			TestHash(DEFAULT_TEST_HASH, toTest);
+		    else
+			// If not testing, then indicate that the hash needs to be
+			// tested because this uses HMAC
+			SET_BOTH(DEFAULT_TEST_HASH);
+		    break;
+		    // Have to use two arguments for the macro even though only the first is used in the
+		    // expansion.
+#define HASH_CASE_TEST(HASH, hash)					\
+	            case ALG_##HASH##_VALUE:
+		    FOR_EACH_HASH(HASH_CASE_TEST)
+#undef HASH_CASE_TEST
+	                if(doTest)
+	                    result = TestHash(alg, toTest);
+		    break;
+		    // RSA-dependent
+#if ALG_RSA
+		  case TPM_ALG_RSA:
+		    CLEAR_BOTH(alg);
+		    if(doTest)
+			result = TestRsa(TPM_ALG_NULL, toTest);
+		    else
+			SET_BOTH(TPM_ALG_NULL);
+		    break;
+		  case TPM_ALG_RSASSA:
+		  case TPM_ALG_RSAES:
+		  case TPM_ALG_RSAPSS:
+		  case TPM_ALG_OAEP:
+		  case TPM_ALG_NULL:    // used or RSADP
+		    if(doTest)
+			result = TestRsa(alg, toTest);
+		    break;
+#endif // ALG_RSA
+#if ALG_KDF1_SP800_108
+		  case TPM_ALG_KDF1_SP800_108:
+		    if(doTest)
+			result = TestKDFa(toTest);
+		    break;
+#endif // ALG_KDF1_SP800_108
+#if ALG_ECC
+		    // ECC dependent but no tests
+		    //        case TPM_ALG_ECDAA:
+		    //        case TPM_ALG_ECMQV:
+		    //        case TPM_ALG_KDF1_SP800_56a:
+		    //        case TPM_ALG_KDF2:
+		    //        case TPM_ALG_MGF1:
+		  case TPM_ALG_ECC:
+		    CLEAR_BOTH(alg);
+		    if(doTest)
+			result = TestEcc(TPM_ALG_ECDH, toTest);
+		    else
+			SET_BOTH(TPM_ALG_ECDH);
+		    break;
+		  case TPM_ALG_ECDSA:
+		  case TPM_ALG_ECDH:
+		  case TPM_ALG_ECSCHNORR:
+		    //            case TPM_ALG_SM2:
+		    if(doTest)
+			result = TestEcc(alg, toTest);
+		    break;
+#endif // ALG_ECC
+		  default:
+		    CLEAR_BIT(alg, *toTest);
+		    break;
+		}
+	    if(result != TPM_RC_SUCCESS)
+		break;
+	}
+    return result;
+}
+#endif // SELF_TESTS

+ 73 - 0
EVSE/GPL/ibmtpm1682/src/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

+ 377 - 0
EVSE/GPL/ibmtpm1682/src/AsymmetricCommands.c

@@ -0,0 +1,377 @@
+/********************************************************************************/
+/*										*/
+/*			  Asymmetric Commands   				*/
+/*			     Written by Ken Goldman				*/
+/*		       IBM Thomas J. Watson Research Center			*/
+/*            $Id: AsymmetricCommands.c 1681 2022-04-14 21:45:26Z kgold $	*/
+/*										*/
+/*  Licenses and Notices							*/
+/*										*/
+/*  1. Copyright Licenses:							*/
+/*										*/
+/*  - Trusted Computing Group (TCG) grants to the user of the source code in	*/
+/*    this specification (the "Source Code") a worldwide, irrevocable, 		*/
+/*    nonexclusive, royalty free, copyright license to reproduce, create 	*/
+/*    derivative works, distribute, display and perform the Source Code and	*/
+/*    derivative works thereof, and to grant others the rights granted herein.	*/
+/*										*/
+/*  - The TCG grants to the user of the other parts of the specification 	*/
+/*    (other than the Source Code) the rights to reproduce, distribute, 	*/
+/*    display, and perform the specification solely for the purpose of 		*/
+/*    developing products based on such documents.				*/
+/*										*/
+/*  2. Source Code Distribution Conditions:					*/
+/*										*/
+/*  - Redistributions of Source Code must retain the above copyright licenses, 	*/
+/*    this list of conditions and the following disclaimers.			*/
+/*										*/
+/*  - Redistributions in binary form must reproduce the above copyright 	*/
+/*    licenses, this list of conditions	and the following disclaimers in the 	*/
+/*    documentation and/or other materials provided with the distribution.	*/
+/*										*/
+/*  3. Disclaimers:								*/
+/*										*/
+/*  - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF	*/
+/*  LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH	*/
+/*  RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES)	*/
+/*  THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE.		*/
+/*  Contact TCG Administration (admin@trustedcomputinggroup.org) for 		*/
+/*  information on specification licensing rights available through TCG 	*/
+/*  membership agreements.							*/
+/*										*/
+/*  - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED 	*/
+/*    WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR 	*/
+/*    FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR 		*/
+/*    NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY 		*/
+/*    OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE.		*/
+/*										*/
+/*  - Without limitation, TCG and its members and licensors disclaim all 	*/
+/*    liability, including liability for infringement of any proprietary 	*/
+/*    rights, relating to use of information in this specification and to the	*/
+/*    implementation of this specification, and TCG disclaims all liability for	*/
+/*    cost of procurement of substitute goods or services, lost profits, loss 	*/
+/*    of use, loss of data or any incidental, consequential, direct, indirect, 	*/
+/*    or special damages, whether under contract, tort, warranty or otherwise, 	*/
+/*    arising in any way out of use or reliance upon this specification or any 	*/
+/*    information herein.							*/
+/*										*/
+/*  (c) Copyright IBM Corp. and others, 2016 - 2022				*/
+/*										*/
+/********************************************************************************/
+
+#include "Tpm.h"
+#include "RSA_Encrypt_fp.h"
+
+extern int verbose;
+
+#if CC_RSA_Encrypt  // Conditional expansion of this file
+TPM_RC
+TPM2_RSA_Encrypt(
+		 RSA_Encrypt_In      *in,            // IN: input parameter list
+		 RSA_Encrypt_Out     *out            // OUT: output parameter list
+		 )
+{
+    TPM_RC                  result;
+    OBJECT                  *rsaKey;
+    TPMT_RSA_DECRYPT        *scheme;
+    if (verbose) {
+	FILE *f = fopen("trace.txt", "a");
+	fprintf(f, "TPM2_RSA_Encrypt: keyHandle %08x\n", in->keyHandle);
+	fclose(f);
+    }
+    // Input Validation
+    rsaKey = HandleToObject(in->keyHandle);
+    // selected key must be an RSA key
+    if(rsaKey->publicArea.type != TPM_ALG_RSA)
+	return TPM_RCS_KEY + RC_RSA_Encrypt_keyHandle;
+    // selected key must have the decryption attribute
+    if(!IS_ATTRIBUTE(rsaKey->publicArea.objectAttributes, TPMA_OBJECT, decrypt))
+	return TPM_RCS_ATTRIBUTES + RC_RSA_Encrypt_keyHandle;
+    // Is there a label?
+    if(!IsLabelProperlyFormatted(&in->label.b))
+	return TPM_RCS_VALUE + RC_RSA_Encrypt_label;
+    // Command Output
+    // Select a scheme for encryption
+    scheme = CryptRsaSelectScheme(in->keyHandle, &in->inScheme);
+    if(scheme == NULL)
+	return TPM_RCS_SCHEME + RC_RSA_Encrypt_inScheme;
+    // Encryption.  TPM_RC_VALUE, or TPM_RC_SCHEME errors my be returned buy
+    // CryptEncyptRSA.
+    out->outData.t.size = sizeof(out->outData.t.buffer);
+    result = CryptRsaEncrypt(&out->outData, &in->message.b, rsaKey, scheme,
+			     &in->label.b, NULL);
+    return result;
+}
+#endif // CC_RSA_Encrypt
+#include "Tpm.h"
+#include "RSA_Decrypt_fp.h"
+#if CC_RSA_Decrypt  // Conditional expansion of this file
+TPM_RC
+TPM2_RSA_Decrypt(
+		 RSA_Decrypt_In      *in,            // IN: input parameter list
+		 RSA_Decrypt_Out     *out            // OUT: output parameter list
+		 )
+{
+    TPM_RC                       result;
+    OBJECT                      *rsaKey;
+    TPMT_RSA_DECRYPT            *scheme;
+    if (verbose) {
+	FILE *f = fopen("trace.txt", "a");
+	fprintf(f, "TPM2_RSA_Decrypt: keyHandle %08x\n", in->keyHandle);
+	fclose(f);
+    }
+    // Input Validation
+    rsaKey = HandleToObject(in->keyHandle);
+    // The selected key must be an RSA key
+    if(rsaKey->publicArea.type != TPM_ALG_RSA)
+	return TPM_RCS_KEY + RC_RSA_Decrypt_keyHandle;
+    // The selected key must be an unrestricted decryption key
+    if(IS_ATTRIBUTE(rsaKey->publicArea.objectAttributes, TPMA_OBJECT, restricted)
+       || !IS_ATTRIBUTE(rsaKey->publicArea.objectAttributes, TPMA_OBJECT, decrypt))
+	return TPM_RCS_ATTRIBUTES + RC_RSA_Decrypt_keyHandle;
+    // NOTE: Proper operation of this command requires that the sensitive area
+    // of the key is loaded. This is assured because authorization is required
+    // to use the sensitive area of the key. In order to check the authorization,
+    // the sensitive area has to be loaded, even if authorization is with policy.
+    // If label is present, make sure that it is a NULL-terminated string
+    if(!IsLabelProperlyFormatted(&in->label.b))
+	return TPM_RCS_VALUE + RC_RSA_Decrypt_label;
+    // Command Output
+    // Select a scheme for decrypt.
+    scheme = CryptRsaSelectScheme(in->keyHandle, &in->inScheme);
+    if(scheme == NULL)
+	return TPM_RCS_SCHEME + RC_RSA_Decrypt_inScheme;
+    // Decryption.  TPM_RC_VALUE, TPM_RC_SIZE, and TPM_RC_KEY error may be
+    // returned by CryptRsaDecrypt.
+    // NOTE: CryptRsaDecrypt can also return TPM_RC_ATTRIBUTES or TPM_RC_BINDING
+    // when the key is not a decryption key but that was checked above.
+    out->message.t.size = sizeof(out->message.t.buffer);
+    result = CryptRsaDecrypt(&out->message.b, &in->cipherText.b, rsaKey,
+			     scheme, &in->label.b);
+    return result;
+}
+#endif // CC_RSA_Decrypt
+#include "Tpm.h"
+#include "ECDH_KeyGen_fp.h"
+#if CC_ECDH_KeyGen  // Conditional expansion of this file
+TPM_RC
+TPM2_ECDH_KeyGen(
+		 ECDH_KeyGen_In      *in,            // IN: input parameter list
+		 ECDH_KeyGen_Out     *out            // OUT: output parameter list
+		 )
+{
+    OBJECT                  *eccKey;
+    TPM2B_ECC_PARAMETER      sensitive;
+    TPM_RC                   result;
+    if (verbose) {
+	FILE *f = fopen("trace.txt", "a");
+	fprintf(f, "TPM2_ECDH_KeyGen: keyHandle %08x\n", in->keyHandle);
+	fclose(f);
+    }
+    // Input Validation
+    eccKey = HandleToObject(in->keyHandle);
+    // Referenced key must be an ECC key
+    if(eccKey->publicArea.type != TPM_ALG_ECC)
+	return TPM_RCS_KEY + RC_ECDH_KeyGen_keyHandle;
+    // Command Output
+    do
+	{
+	    TPMT_PUBLIC         *keyPublic = &eccKey->publicArea;
+	    // Create ephemeral ECC key
+	    result = CryptEccNewKeyPair(&out->pubPoint.point, &sensitive,
+					keyPublic->parameters.eccDetail.curveID);
+	    if(result == TPM_RC_SUCCESS)
+	        {
+	            // Compute Z
+	            result = CryptEccPointMultiply(&out->zPoint.point,
+	                                           keyPublic->parameters.eccDetail.curveID,
+	                                           &keyPublic->unique.ecc,
+	                                           &sensitive,
+	                                           NULL, NULL);
+		    // The point in the key is not on the curve. Indicate
+		    // that the key is bad.
+	            if(result == TPM_RC_ECC_POINT)
+	                return TPM_RCS_KEY + RC_ECDH_KeyGen_keyHandle;
+		    // The other possible error from CryptEccPointMultiply is
+		    // TPM_RC_NO_RESULT indicating that the multiplication resulted in
+		    // the point at infinity, so get a new random key and start over
+		    // BTW, this never happens.
+	        }
+	} while(result == TPM_RC_NO_RESULT);
+    return result;
+}
+#endif // CC_ECDH_KeyGen
+#include "Tpm.h"
+#include "ECDH_ZGen_fp.h"
+#if CC_ECDH_ZGen  // Conditional expansion of this file
+TPM_RC
+TPM2_ECDH_ZGen(
+	       ECDH_ZGen_In    *in,            // IN: input parameter list
+	       ECDH_ZGen_Out   *out            // OUT: output parameter list
+	       )
+{
+    TPM_RC                   result;
+    OBJECT                  *eccKey;
+    if (verbose) {
+	FILE *f = fopen("trace.txt", "a");
+	fprintf(f, "TPM2_ECDH_ZGen: keyHandle %08x\n", in->keyHandle);
+	fclose(f);
+    }
+    // Input Validation
+    eccKey = HandleToObject(in->keyHandle);
+    // Selected key must be a non-restricted, decrypt ECC key
+    if(eccKey->publicArea.type != TPM_ALG_ECC)
+	return TPM_RCS_KEY + RC_ECDH_ZGen_keyHandle;
+    // Selected key needs to be unrestricted with the 'decrypt' attribute
+    if(IS_ATTRIBUTE(eccKey->publicArea.objectAttributes, TPMA_OBJECT, restricted)
+       || !IS_ATTRIBUTE(eccKey->publicArea.objectAttributes, TPMA_OBJECT, decrypt))
+	return TPM_RCS_ATTRIBUTES + RC_ECDH_ZGen_keyHandle;
+    // Make sure the scheme allows this use
+    if(eccKey->publicArea.parameters.eccDetail.scheme.scheme != TPM_ALG_ECDH
+       &&  eccKey->publicArea.parameters.eccDetail.scheme.scheme != TPM_ALG_NULL)
+	return TPM_RCS_SCHEME + RC_ECDH_ZGen_keyHandle;
+    // Command Output
+    // Compute Z. TPM_RC_ECC_POINT or TPM_RC_NO_RESULT may be returned here.
+    result = CryptEccPointMultiply(&out->outPoint.point,
+				   eccKey->publicArea.parameters.eccDetail.curveID,
+				   &in->inPoint.point,
+				   &eccKey->sensitive.sensitive.ecc,
+				   NULL, NULL);
+    if(result != TPM_RC_SUCCESS)
+	return RcSafeAddToResult(result, RC_ECDH_ZGen_inPoint);
+    return result;
+}
+#endif // CC_ECDH_ZGen
+#include "Tpm.h"
+#include "ECC_Parameters_fp.h"
+#if CC_ECC_Parameters  // Conditional expansion of this file
+TPM_RC
+TPM2_ECC_Parameters(
+		    ECC_Parameters_In   *in,            // IN: input parameter list
+		    ECC_Parameters_Out  *out            // OUT: output parameter list
+		    )
+{
+    // Command Output
+    // Get ECC curve parameters
+    if(CryptEccGetParameters(in->curveID, &out->parameters))
+	return TPM_RC_SUCCESS;
+    else
+	return TPM_RCS_VALUE + RC_ECC_Parameters_curveID;
+}
+#endif // CC_ECC_Parameters
+#include "Tpm.h"
+#include "ZGen_2Phase_fp.h"
+#if CC_ZGen_2Phase  // Conditional expansion of this file
+TPM_RC
+TPM2_ZGen_2Phase(
+		 ZGen_2Phase_In      *in,            // IN: input parameter list
+		 ZGen_2Phase_Out     *out            // OUT: output parameter list
+		 )
+{
+    TPM_RC                   result;
+    OBJECT                  *eccKey;
+    TPM2B_ECC_PARAMETER      r;
+    TPM_ALG_ID               scheme;
+    if (verbose) {
+	FILE *f = fopen("trace.txt", "a");
+	fprintf(f, "TPM2_ZGen_2Phase: keyA %08x\n", in->keyA);
+	fclose(f);
+    }
+    // Input Validation
+    eccKey = HandleToObject(in->keyA);
+    // keyA must be an ECC key
+    if(eccKey->publicArea.type != TPM_ALG_ECC)
+	return TPM_RCS_KEY + RC_ZGen_2Phase_keyA;
+    // keyA must not be restricted and must be a decrypt key
+    if(IS_ATTRIBUTE(eccKey->publicArea.objectAttributes, TPMA_OBJECT, restricted)
+       || !IS_ATTRIBUTE(eccKey->publicArea.objectAttributes, TPMA_OBJECT, decrypt))
+	return TPM_RCS_ATTRIBUTES + RC_ZGen_2Phase_keyA;
+    // if the scheme of keyA is TPM_ALG_NULL, then use the input scheme; otherwise
+    // the input scheme must be the same as the scheme of keyA
+    scheme = eccKey->publicArea.parameters.asymDetail.scheme.scheme;
+    if(scheme != TPM_ALG_NULL)
+	{
+	    if(scheme != in->inScheme)
+		return TPM_RCS_SCHEME + RC_ZGen_2Phase_inScheme;
+	}
+    else
+	scheme = in->inScheme;
+    if(scheme == TPM_ALG_NULL)
+	return TPM_RCS_SCHEME + RC_ZGen_2Phase_inScheme;
+    // Input points must be on the curve of keyA
+    if(!CryptEccIsPointOnCurve(eccKey->publicArea.parameters.eccDetail.curveID,
+			       &in->inQsB.point))
+	return TPM_RCS_ECC_POINT + RC_ZGen_2Phase_inQsB;
+    if(!CryptEccIsPointOnCurve(eccKey->publicArea.parameters.eccDetail.curveID,
+			       &in->inQeB.point))
+	return TPM_RCS_ECC_POINT + RC_ZGen_2Phase_inQeB;
+    if(!CryptGenerateR(&r, &in->counter,
+		       eccKey->publicArea.parameters.eccDetail.curveID,
+		       NULL))
+	return TPM_RCS_VALUE + RC_ZGen_2Phase_counter;
+    // Command Output
+    result = CryptEcc2PhaseKeyExchange(&out->outZ1.point,
+				       &out->outZ2.point,
+				       eccKey->publicArea.parameters.eccDetail.curveID,
+				       scheme,
+				       &eccKey->sensitive.sensitive.ecc,
+				       &r,
+				       &in->inQsB.point,
+				       &in->inQeB.point);
+    if(result == TPM_RC_SCHEME)
+	return TPM_RCS_SCHEME + RC_ZGen_2Phase_inScheme;
+    if(result == TPM_RC_SUCCESS)
+	CryptEndCommit(in->counter);
+    return result;
+}
+#endif // CC_ZGen_2Phase
+#include "Tpm.h"
+#include "ECC_Encrypt_fp.h"
+
+#if CC_ECC_Encrypt  // Conditional expansion of this file
+TPM_RC
+TPM2_ECC_Encrypt(
+		 ECC_Encrypt_In   *in,            // IN: input parameter list
+		 ECC_Encrypt_Out  *out            // OUT: output parameter list
+		 )
+{
+    OBJECT          *pubKey = HandleToObject(in->keyHandle);
+    // Parameter validation
+    if (pubKey->publicArea.type != TPM_ALG_ECC)
+	return TPM_RC_KEY + RC_ECC_Encrypt_keyHandle;
+    // Have to have a scheme selected
+    if(!CryptEccSelectScheme(pubKey, &in->inScheme))
+	return TPM_RCS_SCHEME + RC_ECC_Encrypt_inScheme;
+    //  Command Output
+    return CryptEccEncrypt(pubKey, &in->inScheme, &in->plainText,
+			   &out->C1.point, &out->C2, &out->C3);
+}
+#endif // CC_ECC_Encrypt
+#include "Tpm.h"
+#include "ECC_Decrypt_fp.h"
+#include "CryptEccCrypt_fp.h"
+
+#if CC_ECC_Decrypt  // Conditional expansion of this file
+TPM_RC
+TPM2_ECC_Decrypt(
+		 ECC_Decrypt_In   *in,            // IN: input parameter list
+		 ECC_Decrypt_Out  *out            // OUT: output parameter list
+		 )
+{
+    OBJECT          *key = HandleToObject(in->keyHandle);
+    // Parameter validation
+    // Must be the correct type of key with correct attributes
+    if (key->publicArea.type != TPM_ALG_ECC)
+	return TPM_RC_KEY + RC_ECC_Decrypt_keyHandle;
+    if (IS_ATTRIBUTE(key->publicArea.objectAttributes, TPMA_OBJECT, restricted)
+	|| !IS_ATTRIBUTE(key->publicArea.objectAttributes, TPMA_OBJECT, decrypt))
+	return TPM_RCS_ATTRIBUTES + RC_ECC_Decrypt_keyHandle;
+    // Have to have a scheme selected
+    if(!CryptEccSelectScheme(key, &in->inScheme))
+	return TPM_RCS_SCHEME + RC_ECC_Decrypt_inScheme;
+    //  Command Output
+    return CryptEccDecrypt(key, &in->inScheme, &out->plainText,
+			   &in->C1.point, &in->C2, &in->C3);
+}
+#endif // CC_ECC_Decrypt
+

+ 209 - 0
EVSE/GPL/ibmtpm1682/src/Attest_spt.c

@@ -0,0 +1,209 @@
+/********************************************************************************/
+/*										*/
+/*			     				*/
+/*			     Written by Ken Goldman				*/
+/*		       IBM Thomas J. Watson Research Center			*/
+/*            $Id: Attest_spt.c 1490 2019-07-26 21:13:22Z kgoldman $		*/
+/*										*/
+/*  Licenses and Notices							*/
+/*										*/
+/*  1. Copyright Licenses:							*/
+/*										*/
+/*  - Trusted Computing Group (TCG) grants to the user of the source code in	*/
+/*    this specification (the "Source Code") a worldwide, irrevocable, 		*/
+/*    nonexclusive, royalty free, copyright license to reproduce, create 	*/
+/*    derivative works, distribute, display and perform the Source Code and	*/
+/*    derivative works thereof, and to grant others the rights granted herein.	*/
+/*										*/
+/*  - The TCG grants to the user of the other parts of the specification 	*/
+/*    (other than the Source Code) the rights to reproduce, distribute, 	*/
+/*    display, and perform the specification solely for the purpose of 		*/
+/*    developing products based on such documents.				*/
+/*										*/
+/*  2. Source Code Distribution Conditions:					*/
+/*										*/
+/*  - Redistributions of Source Code must retain the above copyright licenses, 	*/
+/*    this list of conditions and the following disclaimers.			*/
+/*										*/
+/*  - Redistributions in binary form must reproduce the above copyright 	*/
+/*    licenses, this list of conditions	and the following disclaimers in the 	*/
+/*    documentation and/or other materials provided with the distribution.	*/
+/*										*/
+/*  3. Disclaimers:								*/
+/*										*/
+/*  - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF	*/
+/*  LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH	*/
+/*  RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES)	*/
+/*  THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE.		*/
+/*  Contact TCG Administration (admin@trustedcomputinggroup.org) for 		*/
+/*  information on specification licensing rights available through TCG 	*/
+/*  membership agreements.							*/
+/*										*/
+/*  - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED 	*/
+/*    WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR 	*/
+/*    FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR 		*/
+/*    NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY 		*/
+/*    OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE.		*/
+/*										*/
+/*  - Without limitation, TCG and its members and licensors disclaim all 	*/
+/*    liability, including liability for infringement of any proprietary 	*/
+/*    rights, relating to use of information in this specification and to the	*/
+/*    implementation of this specification, and TCG disclaims all liability for	*/
+/*    cost of procurement of substitute goods or services, lost profits, loss 	*/
+/*    of use, loss of data or any incidental, consequential, direct, indirect, 	*/
+/*    or special damages, whether under contract, tort, warranty or otherwise, 	*/
+/*    arising in any way out of use or reliance upon this specification or any 	*/
+/*    information herein.							*/
+/*										*/
+/*  (c) Copyright IBM Corp. and others, 2016 - 2018				*/
+/*										*/
+/********************************************************************************/
+
+#include "Tpm.h"
+#include "Attest_spt_fp.h"
+/* 7.2.2 Functions */
+/* 7.2.2.1 FillInAttestInfo() */
+/* Fill in common fields of TPMS_ATTEST structure. */
+void
+FillInAttestInfo(
+		 TPMI_DH_OBJECT       signHandle,    // IN: handle of signing object
+		 TPMT_SIG_SCHEME     *scheme,        // IN/OUT: scheme to be used for signing
+		 TPM2B_DATA          *data,          // IN: qualifying data
+		 TPMS_ATTEST         *attest         // OUT: attest structure
+		 )
+{
+    OBJECT              *signObject = HandleToObject(signHandle);
+    // Magic number
+    attest->magic = TPM_GENERATED_VALUE;
+    if(signObject == NULL)
+	{
+	    // The name for a null handle is TPM_RH_NULL
+	    // This is defined because UINT32_TO_BYTE_ARRAY does a cast. If the
+	    // size of the cast is smaller than a constant, the compiler warns
+	    // about the truncation of a constant value.
+	    TPM_HANDLE      nullHandle = TPM_RH_NULL;
+	    attest->qualifiedSigner.t.size = sizeof(TPM_HANDLE);
+	    UINT32_TO_BYTE_ARRAY(nullHandle, attest->qualifiedSigner.t.name);
+	}
+    else
+	{
+	    // Certifying object qualified name
+	    // if the scheme is anonymous, this is an empty buffer
+	    if(CryptIsSchemeAnonymous(scheme->scheme))
+		attest->qualifiedSigner.t.size = 0;
+	    else
+		attest->qualifiedSigner = signObject->qualifiedName;
+	}
+    // current clock in plain text
+    TimeFillInfo(&attest->clockInfo);
+    // Firmware version in plain text
+    attest->firmwareVersion = ((UINT64)gp.firmwareV1 << (sizeof(UINT32) * 8));
+    attest->firmwareVersion += gp.firmwareV2;
+    // Check the hierarchy of sign object.  For NULL sign handle, the hierarchy
+    // will be TPM_RH_NULL
+    if((signObject == NULL)
+       || (!signObject->attributes.epsHierarchy
+	   && !signObject->attributes.ppsHierarchy))
+	{
+	    // For signing key that is not in platform or endorsement hierarchy,
+	    // obfuscate the reset, restart and firmware version information
+	    UINT64          obfuscation[2];
+	    CryptKDFa(CONTEXT_INTEGRITY_HASH_ALG, &gp.shProof.b, OBFUSCATE_STRING,
+		      &attest->qualifiedSigner.b, NULL, 128,
+		      (BYTE *)&obfuscation[0], NULL, FALSE);
+	    // Obfuscate data
+	    attest->firmwareVersion += obfuscation[0];
+	    attest->clockInfo.resetCount += (UINT32)(obfuscation[1] >> 32);
+	    attest->clockInfo.restartCount += (UINT32)obfuscation[1];
+	}
+    // External data
+    if(CryptIsSchemeAnonymous(scheme->scheme))
+	attest->extraData.t.size = 0;
+    else
+	{
+	    // If we move the data to the attestation structure, then it is not
+	    // used in the signing operation except as part of the signed data
+	    attest->extraData = *data;
+	    data->t.size = 0;
+	}
+}
+/* 7.2.2.2 SignAttestInfo() */
+/* Sign a TPMS_ATTEST structure. If signHandle is TPM_RH_NULL, a null signature is returned. */
+/* Error Returns Meaning */
+/* TPM_RC_ATTRIBUTES signHandle references not a signing key */
+/* TPM_RC_SCHEME scheme is not compatible with signHandle type */
+/* TPM_RC_VALUE digest generated for the given scheme is greater than the modulus of signHandle (for
+   an RSA key); invalid commit status or failed to generate r value (for an ECC key) */
+TPM_RC
+SignAttestInfo(
+	       OBJECT              *signKey,           // IN: sign object
+	       TPMT_SIG_SCHEME     *scheme,            // IN: sign scheme
+	       TPMS_ATTEST         *certifyInfo,       // IN: the data to be signed
+	       TPM2B_DATA          *qualifyingData,    // IN: extra data for the signing
+	       //     process
+	       TPM2B_ATTEST        *attest,            // OUT: marshaled attest blob to be
+	       //     signed
+	       TPMT_SIGNATURE      *signature          // OUT: signature
+	       )
+{
+    BYTE                    *buffer;
+    HASH_STATE              hashState;
+    TPM2B_DIGEST            digest;
+    TPM_RC                  result;
+    // Marshal TPMS_ATTEST structure for hash
+    buffer = attest->t.attestationData;
+    attest->t.size = TPMS_ATTEST_Marshal(certifyInfo, &buffer, NULL);
+    if(signKey == NULL)
+	{
+	    signature->sigAlg = TPM_ALG_NULL;
+	    result = TPM_RC_SUCCESS;
+	}
+    else
+	{
+	    TPMI_ALG_HASH           hashAlg;
+	    // Compute hash
+	    hashAlg = scheme->details.any.hashAlg;
+	    // need to set the receive buffer to get something put in it
+	    digest.t.size = sizeof(digest.t.buffer);
+	    digest.t.size = CryptHashBlock(hashAlg, attest->t.size,
+					   attest->t.attestationData,
+					   digest.t.size, digest.t.buffer);
+	    // If there is qualifying data, need to rehash the data
+	    // hash(qualifyingData || hash(attestationData))
+	    if(qualifyingData->t.size != 0)
+		{
+		    CryptHashStart(&hashState, hashAlg);
+		    CryptDigestUpdate2B(&hashState, &qualifyingData->b);
+		    CryptDigestUpdate2B(&hashState, &digest.b);
+		    CryptHashEnd2B(&hashState, &digest.b);
+		}
+	    // Sign the hash. A TPM_RC_VALUE, TPM_RC_SCHEME, or
+	    // TPM_RC_ATTRIBUTES error may be returned at this point
+	    result = CryptSign(signKey, scheme, &digest, signature);
+	    // Since the clock is used in an attestation, the state in NV is no longer
+	    // "orderly" with respect to the data in RAM if the signature is valid
+	    if(result == TPM_RC_SUCCESS)
+		{
+		    // Command uses the clock so need to clear the orderly state if it is
+		    // set.
+		    result = NvClearOrderly();
+		}
+	}
+    return result;
+}
+/* 7.2.2.3 IsSigningObject() */
+/* Checks to see if the object is OK for signing. This is here rather than in Object_spt.c because
+   all the attestation commands use this file but not Object_spt.c. */
+/* Return Values Meaning */
+/* TRUE object may sign */
+/* FALSE object may not sign */
+BOOL
+IsSigningObject(
+		OBJECT          *object         // IN:
+		)
+{
+    return ((object == NULL)
+	    || ((IS_ATTRIBUTE(object->publicArea.objectAttributes, TPMA_OBJECT, sign)
+		 && object->publicArea.type != TPM_ALG_SYMCIPHER)));
+}
+

+ 92 - 0
EVSE/GPL/ibmtpm1682/src/Attest_spt_fp.h

@@ -0,0 +1,92 @@
+/********************************************************************************/
+/*										*/
+/*			     				*/
+/*			     Written by Ken Goldman				*/
+/*		       IBM Thomas J. Watson Research Center			*/
+/*            $Id: Attest_spt_fp.h 1490 2019-07-26 21:13:22Z kgoldman $			*/
+/*										*/
+/*  Licenses and Notices							*/
+/*										*/
+/*  1. Copyright Licenses:							*/
+/*										*/
+/*  - Trusted Computing Group (TCG) grants to the user of the source code in	*/
+/*    this specification (the "Source Code") a worldwide, irrevocable, 		*/
+/*    nonexclusive, royalty free, copyright license to reproduce, create 	*/
+/*    derivative works, distribute, display and perform the Source Code and	*/
+/*    derivative works thereof, and to grant others the rights granted herein.	*/
+/*										*/
+/*  - The TCG grants to the user of the other parts of the specification 	*/
+/*    (other than the Source Code) the rights to reproduce, distribute, 	*/
+/*    display, and perform the specification solely for the purpose of 		*/
+/*    developing products based on such documents.				*/
+/*										*/
+/*  2. Source Code Distribution Conditions:					*/
+/*										*/
+/*  - Redistributions of Source Code must retain the above copyright licenses, 	*/
+/*    this list of conditions and the following disclaimers.			*/
+/*										*/
+/*  - Redistributions in binary form must reproduce the above copyright 	*/
+/*    licenses, this list of conditions	and the following disclaimers in the 	*/
+/*    documentation and/or other materials provided with the distribution.	*/
+/*										*/
+/*  3. Disclaimers:								*/
+/*										*/
+/*  - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF	*/
+/*  LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH	*/
+/*  RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES)	*/
+/*  THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE.		*/
+/*  Contact TCG Administration (admin@trustedcomputinggroup.org) for 		*/
+/*  information on specification licensing rights available through TCG 	*/
+/*  membership agreements.							*/
+/*										*/
+/*  - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED 	*/
+/*    WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR 	*/
+/*    FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR 		*/
+/*    NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY 		*/
+/*    OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE.		*/
+/*										*/
+/*  - Without limitation, TCG and its members and licensors disclaim all 	*/
+/*    liability, including liability for infringement of any proprietary 	*/
+/*    rights, relating to use of information in this specification and to the	*/
+/*    implementation of this specification, and TCG disclaims all liability for	*/
+/*    cost of procurement of substitute goods or services, lost profits, loss 	*/
+/*    of use, loss of data or any incidental, consequential, direct, indirect, 	*/
+/*    or special damages, whether under contract, tort, warranty or otherwise, 	*/
+/*    arising in any way out of use or reliance upon this specification or any 	*/
+/*    information herein.							*/
+/*										*/
+/*  (c) Copyright IBM Corp. and others, 2016					*/
+/*										*/
+/********************************************************************************/
+
+#ifndef ATTEST_SPT_FP_H
+#define ATTEST_SPT_FP_H
+
+void
+FillInAttestInfo(
+		 TPMI_DH_OBJECT       signHandle,    // IN: handle of signing object
+		 TPMT_SIG_SCHEME     *scheme,        // IN/OUT: scheme to be used for signing
+		 TPM2B_DATA          *data,          // IN: qualifying data
+		 TPMS_ATTEST         *attest         // OUT: attest structure
+		 );
+TPM_RC
+SignAttestInfo(
+	       OBJECT              *signKey,           // IN: sign object
+	       TPMT_SIG_SCHEME     *scheme,            // IN: sign scheme
+	       TPMS_ATTEST         *certifyInfo,       // IN: the data to be signed
+	       TPM2B_DATA          *qualifyingData,    // IN: extra data for the signing
+	       //     process
+	       TPM2B_ATTEST        *attest,            // OUT: marshaled attest blob to be
+	       //     signed
+	       TPMT_SIGNATURE      *signature          // OUT: signature
+	       );
+BOOL
+IsSigningObject(
+		OBJECT          *object         // IN:
+		);
+
+
+
+
+
+#endif

+ 587 - 0
EVSE/GPL/ibmtpm1682/src/AttestationCommands.c

@@ -0,0 +1,587 @@
+
+/********************************************************************************/
+/*										*/
+/*			   Attestation Commands  				*/
+/*			     Written by Ken Goldman				*/
+/*		       IBM Thomas J. Watson Research Center			*/
+/*            $Id: AttestationCommands.c 1681 2022-04-14 21:45:26Z kgold $	*/
+/*										*/
+/*  Licenses and Notices							*/
+/*										*/
+/*  1. Copyright Licenses:							*/
+/*										*/
+/*  - Trusted Computing Group (TCG) grants to the user of the source code in	*/
+/*    this specification (the "Source Code") a worldwide, irrevocable, 		*/
+/*    nonexclusive, royalty free, copyright license to reproduce, create 	*/
+/*    derivative works, distribute, display and perform the Source Code and	*/
+/*    derivative works thereof, and to grant others the rights granted herein.	*/
+/*										*/
+/*  - The TCG grants to the user of the other parts of the specification 	*/
+/*    (other than the Source Code) the rights to reproduce, distribute, 	*/
+/*    display, and perform the specification solely for the purpose of 		*/
+/*    developing products based on such documents.				*/
+/*										*/
+/*  2. Source Code Distribution Conditions:					*/
+/*										*/
+/*  - Redistributions of Source CoDe must retain the above copyright licenses, 	*/
+/*    this list of conditions and the following disclaimers.			*/
+/*										*/
+/*  - Redistributions in binary form must reproduce the above copyright 	*/
+/*    licenses, this list of conditions	and the following disclaimers in the 	*/
+/*    documentation and/or other materials provided with the distribution.	*/
+/*										*/
+/*  3. Disclaimers:								*/
+/*										*/
+/*  - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF	*/
+/*  LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH	*/
+/*  RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES)	*/
+/*  THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE.		*/
+/*  Contact TCG Administration (admin@trustedcomputinggroup.org) for 		*/
+/*  information on specification licensing rights available through TCG 	*/
+/*  membership agreements.							*/
+/*										*/
+/*  - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED 	*/
+/*    WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR 	*/
+/*    FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR 		*/
+/*    NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY 		*/
+/*    OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE.		*/
+/*										*/
+/*  - Without limitation, TCG and its members and licensors disclaim all 	*/
+/*    liability, including liability for infringement of any proprietary 	*/
+/*    rights, relating to use of information in this specification and to the	*/
+/*    implementation of this specification, and TCG disclaims all liability for	*/
+/*    cost of procurement of substitute goods or services, lost profits, loss 	*/
+/*    of use, loss of data or any incidental, consequential, direct, indirect, 	*/
+/*    or special damages, whether under contract, tort, warranty or otherwise, 	*/
+/*    arising in any way out of use or reliance upon this specification or any 	*/
+/*    information herein.							*/
+/*										*/
+/*  (c) Copyright IBM Corp. and others, 2016 - 2021				*/
+/*										*/
+/********************************************************************************/
+
+#include "Tpm.h"
+#include "Attest_spt_fp.h"
+#include "Certify_fp.h"
+
+extern int verbose;
+
+#if CC_Certify  // Conditional expansion of this file
+TPM_RC
+TPM2_Certify(
+	     Certify_In      *in,            // IN: input parameter list
+	     Certify_Out     *out            // OUT: output parameter list
+	     )
+{
+    TPMS_ATTEST             certifyInfo;
+    OBJECT                  *signObject = HandleToObject(in->signHandle);
+    OBJECT                  *certifiedObject = HandleToObject(in->objectHandle);
+    if (verbose) {
+	FILE *f = fopen("trace.txt", "a");
+	fprintf(f, "TPM2_Certify: signHandle %08x\n", in->signHandle);
+	fprintf(f, "TPM2_Certify: objectHandle %08x\n", in->objectHandle);
+	fclose(f);
+    }
+    // Input validation
+    if(!IsSigningObject(signObject))
+	return TPM_RCS_KEY + RC_Certify_signHandle;
+    if(!CryptSelectSignScheme(signObject, &in->inScheme))
+	return TPM_RCS_SCHEME + RC_Certify_inScheme;
+    // Command Output
+    // Filling in attest information
+    // Common fields
+    FillInAttestInfo(in->signHandle, &in->inScheme, &in->qualifyingData,
+		     &certifyInfo);
+    // Certify specific fields
+    certifyInfo.type = TPM_ST_ATTEST_CERTIFY;
+    // NOTE: the certified object is not allowed to be TPM_ALG_NULL so
+    // 'certifiedObject' will never be NULL
+    certifyInfo.attested.certify.name = certifiedObject->name;
+
+    // When using an anonymous signing scheme, need to set the qualified Name to the
+    // empty buffer to avoid correlation between keys
+    if(CryptIsSchemeAnonymous(in->inScheme.scheme))
+	certifyInfo.attested.certify.qualifiedName.t.size = 0;
+    else
+	certifyInfo.attested.certify.qualifiedName = certifiedObject->qualifiedName;
+
+    // Sign attestation structure.  A NULL signature will be returned if
+    // signHandle is TPM_RH_NULL.  A TPM_RC_NV_UNAVAILABLE, TPM_RC_NV_RATE,
+    // TPM_RC_VALUE, TPM_RC_SCHEME or TPM_RC_ATTRIBUTES error may be returned
+    // by SignAttestInfo()
+    return SignAttestInfo(signObject, &in->inScheme, &certifyInfo,
+			  &in->qualifyingData, &out->certifyInfo, &out->signature);
+}
+#endif // CC_Certify
+#include "Tpm.h"
+#include "Attest_spt_fp.h"
+#include "CertifyCreation_fp.h"
+#if CC_CertifyCreation  // Conditional expansion of this file
+TPM_RC
+TPM2_CertifyCreation(
+		     CertifyCreation_In      *in,            // IN: input parameter list
+		     CertifyCreation_Out     *out            // OUT: output parameter list
+		     )
+{
+    TPMT_TK_CREATION        ticket;
+    TPMS_ATTEST             certifyInfo;
+    OBJECT                  *certified = HandleToObject(in->objectHandle);
+    OBJECT                  *signObject = HandleToObject(in->signHandle);
+    if (verbose) {
+	FILE *f = fopen("trace.txt", "a");
+	fprintf(f, "TPM2_CertifyCreation: signHandle %08x\n", in->signHandle);
+	fprintf(f, "TPM2_CertifyCreation: objectHandle %08x\n", in->objectHandle);
+	fclose(f);
+    }
+    // Input Validation
+    if(!IsSigningObject(signObject))
+	return TPM_RCS_KEY + RC_CertifyCreation_signHandle;
+    if(!CryptSelectSignScheme(signObject, &in->inScheme))
+	return TPM_RCS_SCHEME + RC_CertifyCreation_inScheme;
+    // CertifyCreation specific input validation
+    // Re-compute ticket
+    TicketComputeCreation(in->creationTicket.hierarchy, &certified->name,
+			  &in->creationHash, &ticket);
+    // Compare ticket
+    if(!MemoryEqual2B(&ticket.digest.b, &in->creationTicket.digest.b))
+	return TPM_RCS_TICKET + RC_CertifyCreation_creationTicket;
+    // Command Output
+    // Common fields
+    FillInAttestInfo(in->signHandle, &in->inScheme, &in->qualifyingData,
+		     &certifyInfo);
+    // CertifyCreation specific fields
+    // Attestation type
+    certifyInfo.type = TPM_ST_ATTEST_CREATION;
+    certifyInfo.attested.creation.objectName = certified->name;
+    // Copy the creationHash
+    certifyInfo.attested.creation.creationHash = in->creationHash;
+    // Sign attestation structure.  A NULL signature will be returned if
+    // signObject is TPM_RH_NULL.  A TPM_RC_NV_UNAVAILABLE, TPM_RC_NV_RATE,
+    // TPM_RC_VALUE, TPM_RC_SCHEME or TPM_RC_ATTRIBUTES error may be returned at
+    // this point
+    return SignAttestInfo(signObject, &in->inScheme, &certifyInfo,
+			  &in->qualifyingData, &out->certifyInfo,
+			  &out->signature);
+}
+#endif // CC_CertifyCreation
+#include "Tpm.h"
+#include "Attest_spt_fp.h"
+#include "Quote_fp.h"
+#if CC_Quote  // Conditional expansion of this file
+TPM_RC
+TPM2_Quote(
+	   Quote_In        *in,            // IN: input parameter list
+	   Quote_Out       *out            // OUT: output parameter list
+	   )
+{
+    TPMI_ALG_HASH            hashAlg;
+    TPMS_ATTEST              quoted;
+    OBJECT                 *signObject = HandleToObject(in->signHandle);
+    if (verbose) {
+	FILE *f = fopen("trace.txt", "a");
+	fprintf(f, "TPM2_Quote: signHandle %08x\n", in->signHandle);
+	fclose(f);
+    }
+    // Input Validation
+    if(!IsSigningObject(signObject))
+	return TPM_RCS_KEY + RC_Quote_signHandle;
+    if(!CryptSelectSignScheme(signObject, &in->inScheme))
+	return TPM_RCS_SCHEME + RC_Quote_inScheme;
+    // Command Output
+    // Filling in attest information
+    // Common fields
+    // FillInAttestInfo may return TPM_RC_SCHEME or TPM_RC_KEY
+    FillInAttestInfo(in->signHandle, &in->inScheme, &in->qualifyingData, &quoted);
+    // Quote specific fields
+    // Attestation type
+    quoted.type = TPM_ST_ATTEST_QUOTE;
+    // Get hash algorithm in sign scheme.  This hash algorithm is used to
+    // compute PCR digest. If there is no algorithm, then the PCR cannot
+    // be digested and this command returns TPM_RC_SCHEME
+    hashAlg = in->inScheme.details.any.hashAlg;
+    if(hashAlg == TPM_ALG_NULL)
+	return TPM_RCS_SCHEME + RC_Quote_inScheme;
+    // Compute PCR digest
+    PCRComputeCurrentDigest(hashAlg, &in->PCRselect,
+			    &quoted.attested.quote.pcrDigest);
+    // Copy PCR select.  "PCRselect" is modified in PCRComputeCurrentDigest
+    // function
+    quoted.attested.quote.pcrSelect = in->PCRselect;
+    // Sign attestation structure.  A NULL signature will be returned if
+    // signObject is NULL.
+    return SignAttestInfo(signObject, &in->inScheme, &quoted, &in->qualifyingData,
+			  &out->quoted, &out->signature);
+}
+#endif // CC_Quote
+#include "Tpm.h"
+#include "Attest_spt_fp.h"
+#include "GetSessionAuditDigest_fp.h"
+#if CC_GetSessionAuditDigest  // Conditional expansion of this file
+TPM_RC
+TPM2_GetSessionAuditDigest(
+			   GetSessionAuditDigest_In    *in,            // IN: input parameter list
+			   GetSessionAuditDigest_Out   *out            // OUT: output parameter list
+			   )
+{
+    SESSION                 *session = SessionGet(in->sessionHandle);
+    TPMS_ATTEST              auditInfo;
+    OBJECT                 *signObject = HandleToObject(in->signHandle);
+    if (verbose) {
+	FILE *f = fopen("trace.txt", "a");
+	fprintf(f, "TPM2_GetSessionAuditDigest: signHandle %08x\n", in->signHandle);
+	fprintf(f, "TPM2_GetSessionAuditDigest: sessionHandle %08x\n", in->sessionHandle);
+	fclose(f);
+    }
+    // Input Validation
+    if(!IsSigningObject(signObject))
+	return TPM_RCS_KEY + RC_GetSessionAuditDigest_signHandle;
+    if(!CryptSelectSignScheme(signObject, &in->inScheme))
+	return TPM_RCS_SCHEME + RC_GetSessionAuditDigest_inScheme;
+    // session must be an audit session
+    if(session->attributes.isAudit == CLEAR)
+	return TPM_RCS_TYPE + RC_GetSessionAuditDigest_sessionHandle;
+    // Command Output
+    // Fill in attest information common fields
+    FillInAttestInfo(in->signHandle, &in->inScheme, &in->qualifyingData,
+		     &auditInfo);
+    // SessionAuditDigest specific fields
+    auditInfo.type = TPM_ST_ATTEST_SESSION_AUDIT;
+    auditInfo.attested.sessionAudit.sessionDigest = session->u2.auditDigest;
+    // Exclusive audit session
+    auditInfo.attested.sessionAudit.exclusiveSession
+	= (g_exclusiveAuditSession == in->sessionHandle);
+    // Sign attestation structure.  A NULL signature will be returned if
+    // signObject is NULL.
+    return SignAttestInfo(signObject, &in->inScheme, &auditInfo,
+			  &in->qualifyingData, &out->auditInfo,
+			  &out->signature);
+}
+#endif // CC_GetSessionAuditDigest
+#include "Tpm.h"
+#include "Attest_spt_fp.h"
+#include "GetCommandAuditDigest_fp.h"
+#if CC_GetCommandAuditDigest  // Conditional expansion of this file
+TPM_RC
+TPM2_GetCommandAuditDigest(
+			   GetCommandAuditDigest_In    *in,            // IN: input parameter list
+			   GetCommandAuditDigest_Out   *out            // OUT: output parameter list
+			   )
+{
+    TPM_RC                  result;
+    TPMS_ATTEST             auditInfo;
+    OBJECT                 *signObject = HandleToObject(in->signHandle);
+    if (verbose) {
+	FILE *f = fopen("trace.txt", "a");
+	fprintf(f, "TPM2_GetCommandAuditDigest: signHandle %08x\n", in->signHandle);
+	fclose(f);
+    }
+    // Input validation
+    if(!IsSigningObject(signObject))
+	return TPM_RCS_KEY + RC_GetCommandAuditDigest_signHandle;
+    if(!CryptSelectSignScheme(signObject, &in->inScheme))
+	return TPM_RCS_SCHEME + RC_GetCommandAuditDigest_inScheme;
+    // Command Output
+    // Fill in attest information common fields
+    FillInAttestInfo(in->signHandle, &in->inScheme, &in->qualifyingData,
+		     &auditInfo);
+    // CommandAuditDigest specific fields
+    auditInfo.type = TPM_ST_ATTEST_COMMAND_AUDIT;
+    auditInfo.attested.commandAudit.digestAlg = gp.auditHashAlg;
+    auditInfo.attested.commandAudit.auditCounter = gp.auditCounter;
+    // Copy command audit log
+    auditInfo.attested.commandAudit.auditDigest = gr.commandAuditDigest;
+    CommandAuditGetDigest(&auditInfo.attested.commandAudit.commandDigest);
+    // Sign attestation structure.  A NULL signature will be returned if
+    // signHandle is TPM_RH_NULL.  A TPM_RC_NV_UNAVAILABLE, TPM_RC_NV_RATE,
+    // TPM_RC_VALUE, TPM_RC_SCHEME or TPM_RC_ATTRIBUTES error may be returned at
+    // this point
+    result = SignAttestInfo(signObject, &in->inScheme, &auditInfo,
+			    &in->qualifyingData, &out->auditInfo,
+			    &out->signature);
+    // Internal Data Update
+    if(result == TPM_RC_SUCCESS && in->signHandle != TPM_RH_NULL)
+	// Reset log
+	gr.commandAuditDigest.t.size = 0;
+    return result;
+}
+#endif // CC_GetCommandAuditDigest
+#include "Tpm.h"
+#include "Attest_spt_fp.h"
+#include "GetTime_fp.h"
+#if CC_GetTime  // Conditional expansion of this file
+TPM_RC
+TPM2_GetTime(
+	     GetTime_In      *in,            // IN: input parameter list
+	     GetTime_Out     *out            // OUT: output parameter list
+	     )
+{
+    TPMS_ATTEST             timeInfo;
+    OBJECT                 *signObject = HandleToObject(in->signHandle);
+    if (verbose) {
+	FILE *f = fopen("trace.txt", "a");
+	fprintf(f, "TPM2_GetTime: signHandle %08x\n", in->signHandle);
+	fclose(f);
+    }
+    // Input Validation
+    if(!IsSigningObject(signObject))
+	return TPM_RCS_KEY + RC_GetTime_signHandle;
+    if(!CryptSelectSignScheme(signObject, &in->inScheme))
+	return TPM_RCS_SCHEME + RC_GetTime_inScheme;
+    // Command Output
+    // Fill in attest common fields
+    FillInAttestInfo(in->signHandle, &in->inScheme, &in->qualifyingData, &timeInfo);
+    // GetClock specific fields
+    timeInfo.type = TPM_ST_ATTEST_TIME;
+    timeInfo.attested.time.time.time = g_time;
+    TimeFillInfo(&timeInfo.attested.time.time.clockInfo);
+    // Firmware version in plain text
+    timeInfo.attested.time.firmwareVersion
+	= (((UINT64)gp.firmwareV1) << 32) + gp.firmwareV2;
+    // Sign attestation structure.  A NULL signature will be returned if
+    // signObject is NULL.
+    return SignAttestInfo(signObject, &in->inScheme, &timeInfo, &in->qualifyingData,
+			  &out->timeInfo, &out->signature);
+}
+#endif // CC_GetTime
+#include "Tpm.h"
+#include "CertifyX509_fp.h"
+#include "X509.h"
+#include "TpmAsn1_fp.h"
+#include "X509_spt_fp.h"
+#include "Attest_spt_fp.h"
+#include "Platform_fp.h"
+#if CC_CertifyX509 // Conditional expansion of this file
+#if CERTIFYX509_DEBUG
+#include "DebugHelpers_fp.h"
+#endif
+
+/* Error Returns	Meaning*/
+/* TPM_RC_ATTRIBUTES	the attributes of objectHandle are not compatible with the KeyUsage() or TPMA_OBJECT values in the extensions fields */
+/* TPM_RC_BINDING	the public and private portions of the key are not properly bound. */
+/* TPM_RC_HASH	the hash algorithm in the scheme is not supported */
+/* TPM_RC_KEY	signHandle does not reference a signing key; */
+/* TPM_RC_SCHEME	the scheme is not compatible with sign key type, or input scheme is not compatible with default scheme, or the chosen scheme is not a valid sign scheme */
+    /* TPM_RC_VALUE	most likely a problem with the format of partialCertificate */
+TPM_RC
+TPM2_CertifyX509(
+		 CertifyX509_In          *in,          // IN: input parameter list
+		 CertifyX509_Out         *out            // OUT: output parameter list
+		 )
+{
+    TPM_RC                   result;
+    OBJECT                  *signKey = HandleToObject(in->signHandle);
+    OBJECT                  *object = HandleToObject(in->objectHandle);
+    HASH_STATE               hash;
+    INT16                    length;        // length for a tagged element
+    ASN1UnmarshalContext     ctx;
+    ASN1MarshalContext       ctxOut;
+    // certTBS holds an array of pointers and lengths. Each entry references the
+    // corresponding value in a TBSCertificate structure. For example, the 1th
+    // element references the version number
+    stringRef                certTBS[REF_COUNT] = {{0}};
+#define ALLOWED_SEQUENCES   (SUBJECT_PUBLIC_KEY_REF - SIGNATURE_REF)
+    stringRef                partial[ALLOWED_SEQUENCES] = {{0}};
+    INT16                    countOfSequences = 0;
+    INT16                    i;
+    //
+    if (verbose) {
+	FILE *f = fopen("trace.txt", "a");
+	fprintf(f, "TPM2_CertifyX509: signHandle %08x\n", in->signHandle);
+	fprintf(f, "TPM2_CertifyX509: objectHandle %08x\n", in->objectHandle);
+	fclose(f);
+    }
+#if CERTIFYX509_DEBUG
+    DebugFileInit();
+    DebugDumpBuffer(in->partialCertificate.t.size, in->partialCertificate.t.buffer,
+		    "partialCertificate");
+#endif
+
+    // Input Validation
+    if(in->reserved.b.size != 0)
+	return TPM_RC_SIZE + RC_CertifyX509_reserved;
+    // signing key must be able to sign
+    if(!IsSigningObject(signKey))
+	return TPM_RCS_KEY + RC_CertifyX509_signHandle;
+    // Pick a scheme for sign.  If the input sign scheme is not compatible with
+    // the default scheme, return an error.
+    if(!CryptSelectSignScheme(signKey, &in->inScheme))
+	return TPM_RCS_SCHEME + RC_CertifyX509_inScheme;
+    // Make sure that the public Key encoding is known
+    if(X509AddPublicKey(NULL, object) == 0)
+	return TPM_RCS_ASYMMETRIC + RC_CertifyX509_objectHandle;
+    // Unbundle 'partialCertificate'.
+    // Initialize the unmarshaling context
+    if(!ASN1UnmarshalContextInitialize(&ctx, in->partialCertificate.t.size,
+				       in->partialCertificate.t.buffer))
+	return TPM_RCS_VALUE + RC_CertifyX509_partialCertificate;
+    // Make sure that this is a constructed SEQUENCE
+    length = ASN1NextTag(&ctx);
+    // Must be a constructed SEQUENCE that uses all of the input parameter
+    if((ctx.tag != (ASN1_CONSTRUCTED_SEQUENCE))
+       || ((ctx.offset + length) != in->partialCertificate.t.size))
+	return TPM_RCS_SIZE + RC_CertifyX509_partialCertificate;
+    
+    // This scans through the contents of the outermost SEQUENCE. This would be the
+    // 'issuer', 'validity', 'subject', 'issuerUniqueID' (optional),
+    // 'subjectUniqueID' (optional), and 'extensions.'
+    while(ctx.offset < ctx.size)
+	{
+	    INT16           startOfElement = ctx.offset;
+	    //
+	    // Read the next tag and length field.
+	    length = ASN1NextTag(&ctx);
+	    if(length < 0)
+		break;
+	    if(ctx.tag == ASN1_CONSTRUCTED_SEQUENCE)
+	        {
+	            partial[countOfSequences].buf = &ctx.buffer[startOfElement];
+	            ctx.offset += length;
+	            partial[countOfSequences].len = (INT16)ctx.offset - startOfElement;
+	            if(++countOfSequences > ALLOWED_SEQUENCES)
+	                break;
+	        }
+	    else if(ctx.tag  == X509_EXTENSIONS)
+	        {
+	            if(certTBS[EXTENSIONS_REF].len != 0)
+	                return TPM_RCS_VALUE + RC_CertifyX509_partialCertificate;
+	            certTBS[EXTENSIONS_REF].buf = &ctx.buffer[startOfElement];
+	            ctx.offset += length;
+	            certTBS[EXTENSIONS_REF].len =
+	                (INT16)ctx.offset - startOfElement;
+	        }
+	    else
+		return TPM_RCS_VALUE + RC_CertifyX509_partialCertificate;
+	}
+    // Make sure that we used all of the data and found at least the required
+    // number of elements.
+    if((ctx.offset != ctx.size) || (countOfSequences < 3)
+       || (countOfSequences > 4)
+       || (certTBS[EXTENSIONS_REF].buf == NULL))
+	return TPM_RCS_VALUE + RC_CertifyX509_partialCertificate;
+    // Now that we know how many sequences there were, we can put them where they
+    // belong
+    for(i = 0; i < countOfSequences; i++)
+	certTBS[SUBJECT_KEY_REF - i] = partial[countOfSequences - 1 - i];
+
+    // If only three SEQUENCES, then the TPM needs to produce the signature algorithm.
+    // See if it can
+    if((countOfSequences == 3) &&
+       (X509AddSigningAlgorithm(NULL, signKey, &in->inScheme) == 0))
+	return TPM_RCS_SCHEME + RC_CertifyX509_signHandle;
+
+    // Process the extensions
+    result = X509ProcessExtensions(object, &certTBS[EXTENSIONS_REF]);
+    if(result != TPM_RC_SUCCESS)
+	// If the extension has the TPMA_OBJECT extension and the attributes don't
+	// match, then the error code will be TPM_RCS_ATTRIBUTES. Otherwise, the error
+	// indicates a malformed partialCertificate.
+	return result + ((result == TPM_RCS_ATTRIBUTES)
+			 ? RC_CertifyX509_objectHandle
+			 : RC_CertifyX509_partialCertificate);
+    // Command Output
+    // Create the addedToCertificate values
+
+    // Build the addedToCertificate from the bottom up.
+    // Initialize the context structure
+    ASN1InitialializeMarshalContext(&ctxOut, sizeof(out->addedToCertificate.t.buffer),
+				    out->addedToCertificate.t.buffer);
+    // Place a marker for the overall context
+    ASN1StartMarshalContext(&ctxOut);  // SEQUENCE for addedToCertificate
+
+    // Add the subject public key descriptor
+    certTBS[SUBJECT_PUBLIC_KEY_REF].len = X509AddPublicKey(&ctxOut, object);
+    certTBS[SUBJECT_PUBLIC_KEY_REF].buf = ctxOut.buffer + ctxOut.offset;
+    // If the caller didn't provide the algorithm identifier, create it
+    if(certTBS[SIGNATURE_REF].len == 0)
+	{
+	    certTBS[SIGNATURE_REF].len = X509AddSigningAlgorithm(&ctxOut, signKey,
+								 &in->inScheme);
+	    certTBS[SIGNATURE_REF].buf = ctxOut.buffer + ctxOut.offset;
+	}
+    // Create the serial number value. Use the out->tbsDigest as scratch.
+    {
+	TPM2B                   *digest = &out->tbsDigest.b;
+	//
+	digest->size = (INT16)CryptHashStart(&hash, signKey->publicArea.nameAlg);
+	pAssert(digest->size != 0);
+
+	// The serial number size is the smaller of the digest and the vendor-defined
+	// value
+	digest->size = MIN(digest->size, SIZE_OF_X509_SERIAL_NUMBER);
+	// Add all the parts of the certificate other than the serial number
+	// and version number
+	for(i = SIGNATURE_REF; i < REF_COUNT; i++)
+	    CryptDigestUpdate(&hash, certTBS[i].len, certTBS[i].buf);
+	// throw in the Name of the signing key...
+	CryptDigestUpdate2B(&hash, &signKey->name.b);
+	// ...and the Name of the signed key.
+	CryptDigestUpdate2B(&hash, &object->name.b);
+	// Done
+	CryptHashEnd2B(&hash, digest);
+    }
+
+    // Add the serial number
+    certTBS[SERIAL_NUMBER_REF].len =
+	ASN1PushInteger(&ctxOut, out->tbsDigest.t.size, out->tbsDigest.t.buffer);
+    certTBS[SERIAL_NUMBER_REF].buf = ctxOut.buffer + ctxOut.offset;
+
+    // Add the static version number
+    ASN1StartMarshalContext(&ctxOut);
+    ASN1PushUINT(&ctxOut, 2);
+    certTBS[VERSION_REF].len =
+	ASN1EndEncapsulation(&ctxOut, ASN1_APPLICAIION_SPECIFIC);
+    certTBS[VERSION_REF].buf = ctxOut.buffer + ctxOut.offset;
+
+    // Create a fake tag and length for the TBS in the space used for
+    // 'addedToCertificate'
+    {
+	for(length = 0, i = 0; i < REF_COUNT; i++)
+	    length += certTBS[i].len;
+	// Put a fake tag and length into the buffer for use in the tbsDigest
+	certTBS[ENCODED_SIZE_REF].len =
+	    ASN1PushTagAndLength(&ctxOut, ASN1_CONSTRUCTED_SEQUENCE, length);
+	certTBS[ENCODED_SIZE_REF].buf = ctxOut.buffer + ctxOut.offset;
+	// Restore the buffer pointer to add back the number of octets used for the
+	// tag and length
+	ctxOut.offset += certTBS[ENCODED_SIZE_REF].len;
+    }
+    // sanity check
+    if(ctxOut.offset < 0)
+	return TPM_RC_FAILURE;
+    // Create the tbsDigest to sign
+    out->tbsDigest.t.size = CryptHashStart(&hash, in->inScheme.details.any.hashAlg);
+    for(i = 0; i < REF_COUNT; i++)
+	CryptDigestUpdate(&hash, certTBS[i].len, certTBS[i].buf);
+    CryptHashEnd2B(&hash, &out->tbsDigest.b);
+
+#if CERTIFYX509_DEBUG
+    {
+	BYTE                 fullTBS[4096];
+	BYTE                *fill = fullTBS;
+	int                  j;
+	for (j = 0; j < REF_COUNT; j++)
+	    {
+		MemoryCopy(fill, certTBS[j].buf, certTBS[j].len);
+		fill += certTBS[j].len;
+	    }
+	DebugDumpBuffer((int)(fill - &fullTBS[0]), fullTBS, "\nfull TBS");
+    }
+#endif
+
+    // Finish up the processing of addedToCertificate
+    // Create the actual tag and length for the addedToCertificate structure
+    out->addedToCertificate.t.size =
+	ASN1EndEncapsulation(&ctxOut, ASN1_CONSTRUCTED_SEQUENCE);
+    // Now move all the addedToContext to the start of the buffer
+    MemoryCopy(out->addedToCertificate.t.buffer, ctxOut.buffer + ctxOut.offset,
+	       out->addedToCertificate.t.size);
+#if CERTIFYX509_DEBUG
+    DebugDumpBuffer(out->addedToCertificate.t.size, out->addedToCertificate.t.buffer,
+		    "\naddedToCertificate");
+#endif
+    // only thing missing is the signature
+    result = CryptSign(signKey, &in->inScheme, &out->tbsDigest, &out->signature);
+
+    return result;
+}
+#endif // CC_CertifyX509

+ 120 - 0
EVSE/GPL/ibmtpm1682/src/AuditCommands.c

@@ -0,0 +1,120 @@
+/********************************************************************************/
+/*										*/
+/*			   	Command Audit  					*/
+/*			     Written by Ken Goldman				*/
+/*		       IBM Thomas J. Watson Research Center			*/
+/*            $Id: AuditCommands.c 1681 2022-04-14 21:45:26Z kgold $		*/
+/*										*/
+/*  Licenses and Notices							*/
+/*										*/
+/*  1. Copyright Licenses:							*/
+/*										*/
+/*  - Trusted Computing Group (TCG) grants to the user of the source code in	*/
+/*    this specification (the "Source Code") a worldwide, irrevocable, 		*/
+/*    nonexclusive, royalty free, copyright license to reproduce, create 	*/
+/*    derivative works, distribute, display and perform the Source Code and	*/
+/*    derivative works thereof, and to grant others the rights granted herein.	*/
+/*										*/
+/*  - The TCG grants to the user of the other parts of the specification 	*/
+/*    (other than the Source Code) the rights to reproduce, distribute, 	*/
+/*    display, and perform the specification solely for the purpose of 		*/
+/*    developing products based on such documents.				*/
+/*										*/
+/*  2. Source Code Distribution Conditions:					*/
+/*										*/
+/*  - Redistributions of Source Code must retain the above copyright licenses, 	*/
+/*    this list of conditions and the following disclaimers.			*/
+/*										*/
+/*  - Redistributions in binary form must reproduce the above copyright 	*/
+/*    licenses, this list of conditions	and the following disclaimers in the 	*/
+/*    documentation and/or other materials provided with the distribution.	*/
+/*										*/
+/*  3. Disclaimers:								*/
+/*										*/
+/*  - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF	*/
+/*  LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH	*/
+/*  RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES)	*/
+/*  THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE.		*/
+/*  Contact TCG Administration (admin@trustedcomputinggroup.org) for 		*/
+/*  information on specification licensing rights available through TCG 	*/
+/*  membership agreements.							*/
+/*										*/
+/*  - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED 	*/
+/*    WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR 	*/
+/*    FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR 		*/
+/*    NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY 		*/
+/*    OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE.		*/
+/*										*/
+/*  - Without limitation, TCG and its members and licensors disclaim all 	*/
+/*    liability, including liability for infringement of any proprietary 	*/
+/*    rights, relating to use of information in this specification and to the	*/
+/*    implementation of this specification, and TCG disclaims all liability for	*/
+/*    cost of procurement of substitute goods or services, lost profits, loss 	*/
+/*    of use, loss of data or any incidental, consequential, direct, indirect, 	*/
+/*    or special damages, whether under contract, tort, warranty or otherwise, 	*/
+/*    arising in any way out of use or reliance upon this specification or any 	*/
+/*    information herein.							*/
+/*										*/
+/*  (c) Copyright IBM Corp. and others, 2016 - 2021				*/
+/*										*/
+/********************************************************************************/
+
+#include "Tpm.h"
+#include "SetCommandCodeAuditStatus_fp.h"
+
+extern int verbose;
+
+#if CC_SetCommandCodeAuditStatus  // Conditional expansion of this file
+TPM_RC
+TPM2_SetCommandCodeAuditStatus(
+			       SetCommandCodeAuditStatus_In    *in	// IN: input parameter list
+			       )
+{
+    if (verbose) {
+	FILE *f = fopen("trace.txt", "a");
+	fprintf(f, "TPM2_SetCommandCodeAuditStatus:\n");
+	fclose(f);
+    }
+    // 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

+ 85 - 0
EVSE/GPL/ibmtpm1682/src/BaseTypes.h

@@ -0,0 +1,85 @@
+/********************************************************************************/
+/*										*/
+/*			 Basic Typedefs		    				*/
+/*			     Written by Ken Goldman				*/
+/*		       IBM Thomas J. Watson Research Center			*/
+/*            $Id: BaseTypes.h 1531 2019-11-21 23:54:38Z kgoldman $		*/
+/*										*/
+/*  Licenses and Notices							*/
+/*										*/
+/*  1. Copyright Licenses:							*/
+/*										*/
+/*  - Trusted Computing Group (TCG) grants to the user of the source code in	*/
+/*    this specification (the "Source Code") a worldwide, irrevocable, 		*/
+/*    nonexclusive, royalty free, copyright license to reproduce, create 	*/
+/*    derivative works, distribute, display and perform the Source Code and	*/
+/*    derivative works thereof, and to grant others the rights granted herein.	*/
+/*										*/
+/*  - The TCG grants to the user of the other parts of the specification 	*/
+/*    (other than the Source Code) the rights to reproduce, distribute, 	*/
+/*    display, and perform the specification solely for the purpose of 		*/
+/*    developing products based on such documents.				*/
+/*										*/
+/*  2. Source Code Distribution Conditions:					*/
+/*										*/
+/*  - Redistributions of Source Code must retain the above copyright licenses, 	*/
+/*    this list of conditions and the following disclaimers.			*/
+/*										*/
+/*  - Redistributions in binary form must reproduce the above copyright 	*/
+/*    licenses, this list of conditions	and the following disclaimers in the 	*/
+/*    documentation and/or other materials provided with the distribution.	*/
+/*										*/
+/*  3. Disclaimers:								*/
+/*										*/
+/*  - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF	*/
+/*  LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH	*/
+/*  RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES)	*/
+/*  THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE.		*/
+/*  Contact TCG Administration (admin@trustedcomputinggroup.org) for 		*/
+/*  information on specification licensing rights available through TCG 	*/
+/*  membership agreements.							*/
+/*										*/
+/*  - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED 	*/
+/*    WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR 	*/
+/*    FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR 		*/
+/*    NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY 		*/
+/*    OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE.		*/
+/*										*/
+/*  - Without limitation, TCG and its members and licensors disclaim all 	*/
+/*    liability, including liability for infringement of any proprietary 	*/
+/*    rights, relating to use of information in this specification and to the	*/
+/*    implementation of this specification, and TCG disclaims all liability for	*/
+/*    cost of procurement of substitute goods or services, lost profits, loss 	*/
+/*    of use, loss of data or any incidental, consequential, direct, indirect, 	*/
+/*    or special damages, whether under contract, tort, warranty or otherwise, 	*/
+/*    arising in any way out of use or reliance upon this specification or any 	*/
+/*    information herein.							*/
+/*										*/
+/*  (c) Copyright IBM Corp. and others, 2016 - 2019				*/
+/*										*/
+/********************************************************************************/
+
+/* 5.2	BaseTypes.h */
+
+#ifndef BASETYPES_H
+#define BASETYPES_H
+
+#include <stdint.h>
+
+/* NULL definition */
+
+#ifndef         NULL
+#define         NULL        (0)
+#endif
+typedef  uint8_t            UINT8;
+typedef  uint8_t            BYTE;
+typedef  int8_t             INT8;
+typedef  int                BOOL;
+typedef  uint16_t           UINT16;
+typedef  int16_t            INT16;
+typedef  uint32_t           UINT32;
+typedef  int32_t            INT32;
+typedef  uint64_t           UINT64;
+typedef  int64_t            INT64;
+
+#endif

+ 114 - 0
EVSE/GPL/ibmtpm1682/src/Bits.c

@@ -0,0 +1,114 @@
+/********************************************************************************/
+/*										*/
+/*			  Bit Manipulation Routines   				*/
+/*			     Written by Ken Goldman				*/
+/*		       IBM Thomas J. Watson Research Center			*/
+/*            $Id: Bits.c 1490 2019-07-26 21:13:22Z kgoldman $			*/
+/*										*/
+/*  Licenses and Notices							*/
+/*										*/
+/*  1. Copyright Licenses:							*/
+/*										*/
+/*  - Trusted Computing Group (TCG) grants to the user of the source code in	*/
+/*    this specification (the "Source Code") a worldwide, irrevocable, 		*/
+/*    nonexclusive, royalty free, copyright license to reproduce, create 	*/
+/*    derivative works, distribute, display and perform the Source Code and	*/
+/*    derivative works thereof, and to grant others the rights granted herein.	*/
+/*										*/
+/*  - The TCG grants to the user of the other parts of the specification 	*/
+/*    (other than the Source Code) the rights to reproduce, distribute, 	*/
+/*    display, and perform the specification solely for the purpose of 		*/
+/*    developing products based on such documents.				*/
+/*										*/
+/*  2. Source Code Distribution Conditions:					*/
+/*										*/
+/*  - Redistributions of Source Code must retain the above copyright licenses, 	*/
+/*    this list of conditions and the following disclaimers.			*/
+/*										*/
+/*  - Redistributions in binary form must reproduce the above copyright 	*/
+/*    licenses, this list of conditions	and the following disclaimers in the 	*/
+/*    documentation and/or other materials provided with the distribution.	*/
+/*										*/
+/*  3. Disclaimers:								*/
+/*										*/
+/*  - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF	*/
+/*  LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH	*/
+/*  RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES)	*/
+/*  THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE.		*/
+/*  Contact TCG Administration (admin@trustedcomputinggroup.org) for 		*/
+/*  information on specification licensing rights available through TCG 	*/
+/*  membership agreements.							*/
+/*										*/
+/*  - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED 	*/
+/*    WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR 	*/
+/*    FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR 		*/
+/*    NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY 		*/
+/*    OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE.		*/
+/*										*/
+/*  - Without limitation, TCG and its members and licensors disclaim all 	*/
+/*    liability, including liability for infringement of any proprietary 	*/
+/*    rights, relating to use of information in this specification and to the	*/
+/*    implementation of this specification, and TCG disclaims all liability for	*/
+/*    cost of procurement of substitute goods or services, lost profits, loss 	*/
+/*    of use, loss of data or any incidental, consequential, direct, indirect, 	*/
+/*    or special damages, whether under contract, tort, warranty or otherwise, 	*/
+/*    arising in any way out of use or reliance upon this specification or any 	*/
+/*    information herein.							*/
+/*										*/
+/*  (c) Copyright IBM Corp. and others, 2016 - 2018				*/
+/*										*/
+/********************************************************************************/
+
+/* 9.2 Bits.c */
+/* 9.2.1 Introduction */
+/* This file contains bit manipulation routines.  They operate on bit arrays. */
+/* The 0th bit in the array is the right-most bit in the 0th octet in the array. */
+/* NOTE: If pAssert() is defined, the functions will assert if the indicated bit number is outside
+   of the range of bArray. How the assert is handled is implementation dependent. */
+/* 9.2.2 Includes */
+#include "Tpm.h"
+/* 9.2.3 Functions */
+/* 9.2.3.1 TestBit() */
+/* This function is used to check the setting of a bit in an array of bits. */
+/* Return Values Meaning */
+/* TRUE bit is set */
+/* FALSE bit is not set */
+
+BOOL
+TestBit(
+	unsigned int     bitNum,        // IN: number of the bit in 'bArray'
+	BYTE            *bArray,        // IN: array containing the bits
+	unsigned int     bytesInArray   // IN: size in bytes of 'bArray'
+	)
+{
+    pAssert(bytesInArray > (bitNum >> 3));
+    return((bArray[bitNum >> 3] & (1 << (bitNum & 7))) != 0);
+}
+
+/* 9.2.3.2 SetBit() */
+/* This function will set the indicated bit in bArray. */
+
+void
+SetBit(
+       unsigned int     bitNum,        // IN: number of the bit in 'bArray'
+       BYTE            *bArray,        // IN: array containing the bits
+       unsigned int     bytesInArray   // IN: size in bytes of 'bArray'
+       )
+{
+    pAssert(bytesInArray > (bitNum >> 3));
+    bArray[bitNum >> 3] |= (1 << (bitNum & 7));
+}
+
+/* 9.2.3.3 ClearBit() */
+/* This function will clear the indicated bit in bArray. */
+
+void
+ClearBit(
+	 unsigned int     bitNum,        // IN: number of the bit in 'bArray'.
+	 BYTE            *bArray,        // IN: array containing the bits
+	 unsigned int     bytesInArray   // IN: size in bytes of 'bArray'
+	 )
+{
+    pAssert(bytesInArray > (bitNum >> 3));
+    bArray[bitNum >> 3] &= ~(1 << (bitNum & 7));
+}

+ 98 - 0
EVSE/GPL/ibmtpm1682/src/Bits_fp.h

@@ -0,0 +1,98 @@
+/********************************************************************************/
+/*										*/
+/*			  Bit Handling		  				*/
+/*			     Written by Ken Goldman				*/
+/*		       IBM Thomas J. Watson Research Center			*/
+/*            $Id: Bits_fp.h 803 2016-11-15 20:19:26Z kgoldman 			*/
+/*										*/
+/*  Licenses and Notices							*/
+/*										*/
+/*  1. Copyright Licenses:							*/
+/*										*/
+/*  - Trusted Computing Group (TCG) grants to the user of the source code in	*/
+/*    this specification (the "Source Code") a worldwide, irrevocable, 		*/
+/*    nonexclusive, royalty free, copyright license to reproduce, create 	*/
+/*    derivative works, distribute, display and perform the Source Code and	*/
+/*    derivative works thereof, and to grant others the rights granted herein.	*/
+/*										*/
+/*  - The TCG grants to the user of the other parts of the specification 	*/
+/*    (other than the Source Code) the rights to reproduce, distribute, 	*/
+/*    display, and perform the specification solely for the purpose of 		*/
+/*    developing products based on such documents.				*/
+/*										*/
+/*  2. Source Code Distribution Conditions:					*/
+/*										*/
+/*  - Redistributions of Source Code must retain the above copyright licenses, 	*/
+/*    this list of conditions and the following disclaimers.			*/
+/*										*/
+/*  - Redistributions in binary form must reproduce the above copyright 	*/
+/*    licenses, this list of conditions	and the following disclaimers in the 	*/
+/*    documentation and/or other materials provided with the distribution.	*/
+/*										*/
+/*  3. Disclaimers:								*/
+/*										*/
+/*  - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF	*/
+/*  LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH	*/
+/*  RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES)	*/
+/*  THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE.		*/
+/*  Contact TCG Administration (admin@trustedcomputinggroup.org) for 		*/
+/*  information on specification licensing rights available through TCG 	*/
+/*  membership agreements.							*/
+/*										*/
+/*  - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED 	*/
+/*    WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR 	*/
+/*    FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR 		*/
+/*    NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY 		*/
+/*    OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE.		*/
+/*										*/
+/*  - Without limitation, TCG and its members and licensors disclaim all 	*/
+/*    liability, including liability for infringement of any proprietary 	*/
+/*    rights, relating to use of information in this specification and to the	*/
+/*    implementation of this specification, and TCG disclaims all liability for	*/
+/*    cost of procurement of substitute goods or services, lost profits, loss 	*/
+/*    of use, loss of data or any incidental, consequential, direct, indirect, 	*/
+/*    or special damages, whether under contract, tort, warranty or otherwise, 	*/
+/*    arising in any way out of use or reliance upon this specification or any 	*/
+/*    information herein.							*/
+/*										*/
+/*  (c) Copyright IBM Corp. and others, 2016 - 2018				*/
+/*										*/
+/********************************************************************************/
+
+#ifndef BITS_FP_H
+#define BITS_FP_H
+
+/* 5.3.1 TestBit() */
+/* This function is used to check the setting of a bit in an array of bits. */
+/* Return Value Meaning */
+/* TRUE bit is set */
+/* FALSE bit is not set */
+
+BOOL
+TestBit(
+	unsigned int     bitNum,        // IN: number of the bit in 'bArray'
+	BYTE            *bArray,        // IN: array containing the bits
+	unsigned int     bytesInArray   // IN: size in bytes of 'bArray'
+	);
+
+/* 5.3.2 SetBit() */
+/* This function will set the indicated bit in bArray. */
+
+void
+SetBit(
+       unsigned int     bitNum,        // IN: number of the bit in 'bArray'
+       BYTE            *bArray,        // IN: array containing the bits
+       unsigned int     bytesInArray   // IN: size in bytes of 'bArray'
+       );
+
+/* 5.3.3 ClearBit() */
+/* This function will clear the indicated bit in bArray. */
+
+void
+ClearBit(
+	 unsigned int     bitNum,        // IN: number of the bit in 'bArray'.
+	 BYTE            *bArray,        // IN: array containing the bits
+	 unsigned int     bytesInArray   // IN: size in bytes of 'bArray'
+	 );
+
+#endif

+ 297 - 0
EVSE/GPL/ibmtpm1682/src/BnConvert.c

@@ -0,0 +1,297 @@
+/********************************************************************************/
+/*										*/
+/*	conversion functions that will convert TPM2B to/from internal format	*/
+/*			     Written by Ken Goldman				*/
+/*		       IBM Thomas J. Watson Research Center			*/
+/*            $Id: BnConvert.c 1519 2019-11-15 20:43:51Z kgoldman $		*/
+/*										*/
+/*  Licenses and Notices							*/
+/*										*/
+/*  1. Copyright Licenses:							*/
+/*										*/
+/*  - Trusted Computing Group (TCG) grants to the user of the source code in	*/
+/*    this specification (the "Source Code") a worldwide, irrevocable, 		*/
+/*    nonexclusive, royalty free, copyright license to reproduce, create 	*/
+/*    derivative works, distribute, display and perform the Source Code and	*/
+/*    derivative works thereof, and to grant others the rights granted herein.	*/
+/*										*/
+/*  - The TCG grants to the user of the other parts of the specification 	*/
+/*    (other than the Source Code) the rights to reproduce, distribute, 	*/
+/*    display, and perform the specification solely for the purpose of 		*/
+/*    developing products based on such documents.				*/
+/*										*/
+/*  2. Source Code Distribution Conditions:					*/
+/*										*/
+/*  - Redistributions of Source Code must retain the above copyright licenses, 	*/
+/*    this list of conditions and the following disclaimers.			*/
+/*										*/
+/*  - Redistributions in binary form must reproduce the above copyright 	*/
+/*    licenses, this list of conditions	and the following disclaimers in the 	*/
+/*    documentation and/or other materials provided with the distribution.	*/
+/*										*/
+/*  3. Disclaimers:								*/
+/*										*/
+/*  - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF	*/
+/*  LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH	*/
+/*  RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES)	*/
+/*  THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE.		*/
+/*  Contact TCG Administration (admin@trustedcomputinggroup.org) for 		*/
+/*  information on specification licensing rights available through TCG 	*/
+/*  membership agreements.							*/
+/*										*/
+/*  - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED 	*/
+/*    WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR 	*/
+/*    FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR 		*/
+/*    NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY 		*/
+/*    OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE.		*/
+/*										*/
+/*  - Without limitation, TCG and its members and licensors disclaim all 	*/
+/*    liability, including liability for infringement of any proprietary 	*/
+/*    rights, relating to use of information in this specification and to the	*/
+/*    implementation of this specification, and TCG disclaims all liability for	*/
+/*    cost of procurement of substitute goods or services, lost profits, loss 	*/
+/*    of use, loss of data or any incidental, consequential, direct, indirect, 	*/
+/*    or special damages, whether under contract, tort, warranty or otherwise, 	*/
+/*    arising in any way out of use or reliance upon this specification or any 	*/
+/*    information herein.							*/
+/*										*/
+/*  (c) Copyright IBM Corp. and others, 2016 - 2019				*/
+/*										*/
+/********************************************************************************/
+
+/* 10.2.2 BnConvert.c */
+/* 10.2.2.1 Introduction */
+/* This file contains the basic conversion functions that will convert TPM2B to/from the internal
+   format. The internal format is a bigNum, */
+/* 10.2.2.2 Includes */
+#include "Tpm.h"
+/* 10.2.2.3 Functions */
+/* 10.2.2.3.1 BnFromBytes() */
+/* This function will convert a big-endian byte array to the internal number format. If bn is NULL,
+   then the output is NULL. If bytes is null or the required size is 0, then the output is set to
+   zero */
+LIB_EXPORT bigNum
+BnFromBytes(
+	    bigNum           bn,
+	    const BYTE      *bytes,
+	    NUMBYTES         nBytes
+	    )
+{
+    const BYTE      *pFrom; // 'p' points to the least significant bytes of source
+    BYTE            *pTo;   // points to least significant bytes of destination
+    crypt_uword_t    size;
+    //
+    size = (bytes != NULL) ? BYTES_TO_CRYPT_WORDS(nBytes) : 0;
+    // If nothing in, nothing out
+    if(bn == NULL)
+	return NULL;
+    // make sure things fit
+    pAssert(BnGetAllocated(bn) >= size);
+    if(size > 0)
+	{
+	    // Clear the topmost word in case it is not filled with data
+	    bn->d[size - 1] = 0;
+	    // Moving the input bytes from the end of the list (LSB) end
+	    pFrom = bytes + nBytes - 1;
+	    // To the LS0 of the LSW of the bigNum.
+	    pTo = (BYTE *)bn->d;
+	    for(; nBytes != 0; nBytes--)
+		*pTo++ = *pFrom--;
+	    // For a little-endian machine, the conversion is a straight byte
+	    // reversal. For a big-endian machine, we have to put the words in
+	    // big-endian byte order
+#if BIG_ENDIAN_TPM
+	    {
+		crypt_word_t   t;
+		for(t = (crypt_word_t)size - 1; t >= 0; t--)
+		    bn->d[t] = SWAP_CRYPT_WORD(bn->d[t]);
+	    }
+#endif
+	}
+    BnSetTop(bn, size);
+    return bn;
+}
+/* 10.2.2.3.2 BnFrom2B() */
+/* Convert an TPM2B to a BIG_NUM. If the input value does not exist, or the output does not exist,
+   or the input will not fit into the output the function returns NULL */
+LIB_EXPORT bigNum
+BnFrom2B(
+	 bigNum           bn,         // OUT:
+	 const TPM2B     *a2B         // IN: number to convert
+	 )
+{
+    if(a2B != NULL)
+	return BnFromBytes(bn, a2B->buffer, a2B->size);
+    // Make sure that the number has an initialized value rather than whatever
+    // was there before
+    BnSetTop(bn, 0);    // Function accepts NULL
+    return NULL;
+}
+/* 10.2.2.3.3 BnFromHex() */
+/* Convert a hex string into a bigNum. This is primarily used in debugging. */
+LIB_EXPORT bigNum
+BnFromHex(
+	  bigNum          bn,         // OUT:
+	  const char      *hex        // IN:
+	  )
+{
+#define FromHex(a)  ((a) - (((a) > 'a') ? ('a' + 10)			\
+			    : ((a) > 'A') ? ('A' - 10) : '0'))
+    unsigned             i;
+    unsigned             wordCount;
+    const char          *p;
+    BYTE                *d = (BYTE *)&(bn->d[0]);
+    //
+    pAssert(bn && hex);
+    i = (unsigned)strlen(hex);
+    wordCount = BYTES_TO_CRYPT_WORDS((i + 1) / 2);
+    if((i == 0) || (wordCount >= BnGetAllocated(bn)))
+	BnSetWord(bn, 0);
+    else
+	{
+	    bn->d[wordCount - 1] = 0;
+	    p = hex + i - 1;
+	    for(;i > 1; i -= 2)
+		{
+		    BYTE a;
+		    a = FromHex(*p);
+		    p--;
+		    *d++ = a + (FromHex(*p) << 4);
+		    p--;
+		}
+	    if(i == 1)
+		*d = FromHex(*p);
+	}
+#if !BIG_ENDIAN_TPM
+    for(i = 0; i < wordCount; i++)
+	bn->d[i] = SWAP_CRYPT_WORD(bn->d[i]);
+#endif // BIG_ENDIAN_TPM
+    BnSetTop(bn, wordCount);
+    return bn;
+}
+/* 10.2.2.3.4 BnToBytes() */
+/* This function converts a BIG_NUM to a byte array. It converts the bigNum to a big-endian byte
+   string and sets size to the normalized value. If size is an input 0, then the receiving buffer is
+   guaranteed to be large enough for the result and the size will be set to the size required for
+   bigNum (leading zeros suppressed). */
+/* The conversion for a little-endian machine simply requires that all significant bytes of the
+   bigNum be reversed. For a big-endian machine, rather than unpack each word individually,
+   the bigNum is converted to little-endian words, copied, and then converted back to big-endian. */
+LIB_EXPORT BOOL
+BnToBytes(
+	  bigConst             bn,
+	  BYTE                *buffer,
+	  NUMBYTES            *size           // This the number of bytes that are
+	  // available in the buffer. The result
+	  // should be this big.
+	  )
+{
+    crypt_uword_t        requiredSize;
+    BYTE                *pFrom;
+    BYTE                *pTo;
+    crypt_uword_t        count;
+    //
+    // validate inputs
+    pAssert(bn && buffer && size);
+    requiredSize = (BnSizeInBits(bn) + 7) / 8;
+    if(requiredSize == 0)
+	{
+	    // If the input value is 0, return a byte of zero
+	    *size = 1;
+	    *buffer = 0;
+	}
+    else
+	{
+#if BIG_ENDIAN_TPM
+	    // Copy the constant input value into a modifiable value
+	    BN_VAR(bnL, LARGEST_NUMBER_BITS * 2);
+	    BnCopy(bnL, bn);
+	    // byte swap the words in the local value to make them little-endian
+	    for(count = 0; count < bnL->size; count++)
+		bnL->d[count] = SWAP_CRYPT_WORD(bnL->d[count]);
+	    bn = (bigConst)bnL;
+#endif
+	    if(*size == 0)
+		*size = (NUMBYTES)requiredSize;
+	    pAssert(requiredSize <= *size);
+	    // Byte swap the number (not words but the whole value)
+	    count = *size;
+	    // Start from the least significant word and offset to the most significant
+	    // byte which is in some high word
+	    pFrom = (BYTE *)(&bn->d[0]) + requiredSize - 1;
+	    pTo = buffer;
+	    // If the number of output bytes is larger than the number bytes required
+	    // for the input number, pad with zeros
+	    for(count = *size; count > requiredSize; count--)
+		*pTo++ = 0;
+	    // Move the most significant byte at the end of the BigNum to the next most
+	    // significant byte position of the 2B and repeat for all significant bytes.
+	    for(; requiredSize > 0; requiredSize--)
+		*pTo++ = *pFrom--;
+	}
+    return TRUE;
+}
+/* 10.2.2.3.5 BnTo2B() */
+/* Function to convert a BIG_NUM to TPM2B. The TPM2B size is set to the requested size which may
+   require padding. If size is non-zero and less than required by the value in bn then an error is
+   returned. If size is zero, then the TPM2B is assumed to be large enough for the data and
+   a2b->size will be adjusted accordingly. */
+LIB_EXPORT BOOL
+BnTo2B(
+       bigConst         bn,                // IN:
+       TPM2B           *a2B,               // OUT:
+       NUMBYTES         size               // IN: the desired size
+       )
+{
+    // Set the output size
+    if(bn && a2B)
+	{
+	    a2B->size = size;
+	    return BnToBytes(bn, a2B->buffer, &a2B->size);
+	}
+    return FALSE;
+}
+#if ALG_ECC
+/* 10.2.2.3.6 BnPointFrom2B() */
+/* Function to create a BIG_POINT structure from a 2B point. A point is going to be two ECC values
+   in the same buffer. The values are going to be the size of the modulus.  They are in modular
+   form. */
+LIB_EXPORT bn_point_t   *
+BnPointFrom2B(
+	      bigPoint             ecP,         // OUT: the preallocated point structure
+	      TPMS_ECC_POINT      *p            // IN: the number to convert
+	      )
+{
+    if(p == NULL)
+	return NULL;
+    if(NULL != ecP)
+	{
+	    BnFrom2B(ecP->x, &p->x.b);
+	    BnFrom2B(ecP->y, &p->y.b);
+	    BnSetWord(ecP->z, 1);
+	}
+    return ecP;
+}
+/* 10.2.2.3.7 BnPointTo2B() */
+/* This function converts a BIG_POINT into a TPMS_ECC_POINT. A TPMS_ECC_POINT contains two
+   TPM2B_ECC_PARAMETER values. The maximum size of the parameters is dependent on the maximum EC key
+   size used in an implementation. The presumption is that the TPMS_ECC_POINT is large enough to
+   hold 2 TPM2B values, each as large as a MAX_ECC_PARAMETER_BYTES */
+LIB_EXPORT BOOL
+BnPointTo2B(
+	    TPMS_ECC_POINT  *p,             // OUT: the converted 2B structure
+	    bigPoint         ecP,           // IN: the values to be converted
+	    bigCurve         E              // IN: curve descriptor for the point
+	    )
+{
+    UINT16           size;
+    //
+    pAssert(p && ecP && E);
+    pAssert(BnEqualWord(ecP->z, 1));
+    // BnMsb is the bit number of the MSB. This is one less than the number of bits
+    size = (UINT16)BITS_TO_BYTES(BnSizeInBits(CurveGetOrder(AccessCurveData(E))));
+    BnTo2B(ecP->x, &p->x.b, size);
+    BnTo2B(ecP->y, &p->y.b, size);
+    return TRUE;
+}
+#endif // TPM_ALG_ECC

+ 108 - 0
EVSE/GPL/ibmtpm1682/src/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

+ 573 - 0
EVSE/GPL/ibmtpm1682/src/BnMath.c

@@ -0,0 +1,573 @@
+/********************************************************************************/
+/*										*/
+/*			Simple Operations on Big Numbers     			*/
+/*			     Written by Ken Goldman				*/
+/*		       IBM Thomas J. Watson Research Center			*/
+/*            $Id: BnMath.c 1682 2022-07-06 15:06:36Z kgold $		*/
+/*										*/
+/*  Licenses and Notices							*/
+/*										*/
+/*  1. Copyright Licenses:							*/
+/*										*/
+/*  - Trusted Computing Group (TCG) grants to the user of the source code in	*/
+/*    this specification (the "Source Code") a worldwide, irrevocable, 		*/
+/*    nonexclusive, royalty free, copyright license to reproduce, create 	*/
+/*    derivative works, distribute, display and perform the Source Code and	*/
+/*    derivative works thereof, and to grant others the rights granted herein.	*/
+/*										*/
+/*  - The TCG grants to the user of the other parts of the specification 	*/
+/*    (other than the Source Code) the rights to reproduce, distribute, 	*/
+/*    display, and perform the specification solely for the purpose of 		*/
+/*    developing products based on such documents.				*/
+/*										*/
+/*  2. Source Code Distribution Conditions:					*/
+/*										*/
+/*  - Redistributions of Source Code must retain the above copyright licenses, 	*/
+/*    this list of conditions and the following disclaimers.			*/
+/*										*/
+/*  - Redistributions in binary form must reproduce the above copyright 	*/
+/*    licenses, this list of conditions	and the following disclaimers in the 	*/
+/*    documentation and/or other materials provided with the distribution.	*/
+/*										*/
+/*  3. Disclaimers:								*/
+/*										*/
+/*  - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF	*/
+/*  LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH	*/
+/*  RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES)	*/
+/*  THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE.		*/
+/*  Contact TCG Administration (admin@trustedcomputinggroup.org) for 		*/
+/*  information on specification licensing rights available through TCG 	*/
+/*  membership agreements.							*/
+/*										*/
+/*  - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED 	*/
+/*    WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR 	*/
+/*    FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR 		*/
+/*    NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY 		*/
+/*    OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE.		*/
+/*										*/
+/*  - Without limitation, TCG and its members and licensors disclaim all 	*/
+/*    liability, including liability for infringement of any proprietary 	*/
+/*    rights, relating to use of information in this specification and to the	*/
+/*    implementation of this specification, and TCG disclaims all liability for	*/
+/*    cost of procurement of substitute goods or services, lost profits, loss 	*/
+/*    of use, loss of data or any incidental, consequential, direct, indirect, 	*/
+/*    or special damages, whether under contract, tort, warranty or otherwise, 	*/
+/*    arising in any way out of use or reliance upon this specification or any 	*/
+/*    information herein.							*/
+/*										*/
+/*  (c) Copyright IBM Corp. and others, 2016 - 2019				*/
+/*										*/
+/********************************************************************************/
+
+/* 10.2.3 BnMath.c */
+
+/* 10.2.3.1	Introduction */
+/* The simulator code uses the canonical form whenever possible in order to make the code in Part 3
+   more accessible. The canonical data formats are simple and not well suited for complex big number
+   computations. When operating on big numbers, the data format is changed for easier
+   manipulation. The format is native words in little-endian format. As the magnitude of the number
+   decreases, the length of the array containing the number decreases but the starting address
+   doesn't change. */
+/* The functions in this file perform simple operations on these big numbers. Only the more complex
+   operations are passed to the underlying support library. Although the support library would have
+   most of these functions, the interface code to convert the format for the values is greater than
+   the size of the code to implement the functions here. So, rather than incur the overhead of
+   conversion, they are done here. */
+/* If an implementer would prefer, the underlying library can be used simply by making code
+   substitutions here. */
+/* NOTE: There is an intention to continue to augment these functions so that there would be no need
+   to use an external big number library. */
+/* Many of these functions have no error returns and will always return TRUE. This is to allow them
+   to be used in guarded sequences. That is: OK = OK || BnSomething(s); where the BnSomething()
+   function should not be called if OK isn't true. */
+
+/* 10.2.3.2 Includes */
+#include "Tpm.h"
+/* A constant value of zero as a stand in for NULL bigNum values */
+const bignum_t   BnConstZero = {1, 0, {0}};
+/* 10.2.3.3 Functions */
+/* 10.2.3.3.1 AddSame() */
+/* Adds two values that are the same size. This function allows result to be the same as either of
+   the addends. This is a nice function to put into assembly because handling the carry for
+   multi-precision stuff is not as easy in C (unless there is a REALLY smart compiler). It would be
+   nice if there were idioms in a language that a compiler could recognize what is going on and
+   optimize loops like this. */
+/* Return Values Meaning */
+/* 0 no carry out */
+/* 1 carry out */
+static BOOL
+AddSame(
+	crypt_uword_t           *result,
+	const crypt_uword_t     *op1,
+	const crypt_uword_t     *op2,
+	int                      count
+	)
+{
+    int         carry = 0;
+    int         i;
+    for(i = 0; i < count; i++)
+	{
+	    crypt_uword_t        a = op1[i];
+	    crypt_uword_t        sum = a + op2[i];
+	    result[i] = sum + carry;
+	    // generate a carry if the sum is less than either of the inputs
+	    // propagate a carry if there was a carry and the sum + carry is zero
+	    // do this using bit operations rather than logical operations so that
+	    // the time is about the same.
+	    //             propagate term      | generate term
+	    carry = ((result[i] == 0) & carry) | (sum < a);
+	}
+    return carry;
+}
+/* 10.2.3.3.2 CarryProp() */
+/* Propagate a carry */
+static int
+CarryProp(
+	  crypt_uword_t           *result,
+	  const crypt_uword_t     *op,
+	  int                      count,
+	  int                      carry
+	  )
+{
+    for(; count; count--)
+	carry = ((*result++ = *op++ + carry) == 0) & carry;
+    return carry;
+}
+static void
+CarryResolve(
+	     bigNum          result,
+	     int             stop,
+	     int             carry
+	     )
+{
+    if(carry)
+	{
+	    pAssert((unsigned)stop < result->allocated);
+	    result->d[stop++] = 1;
+	}
+    BnSetTop(result, stop);
+}
+/* 10.2.3.3.3 BnAdd() */
+/* This function adds two bigNum values. Always returns TRUE */
+LIB_EXPORT BOOL
+BnAdd(
+      bigNum           result,
+      bigConst         op1,
+      bigConst         op2
+      )
+{
+    crypt_uword_t    stop;
+    int              carry;
+    const bignum_t   *n1 = op1;
+    const bignum_t   *n2 = op2;
+    //
+    if(n2->size > n1->size)
+	{
+	    n1 = op2;
+	    n2 = op1;
+	}
+    pAssert(result->allocated >= n1->size);
+    stop = MIN(n1->size, n2->allocated);
+    carry = (int)AddSame(result->d, n1->d, n2->d, (int)stop);
+    if(n1->size > stop)
+	carry = CarryProp(&result->d[stop], &n1->d[stop], (int)(n1->size - stop), carry);
+    CarryResolve(result, (int)n1->size, carry);
+    return TRUE;
+}
+/* 10.2.3.3.4 BnAddWord() */
+/* Adds a word value to a bigNum. */
+LIB_EXPORT BOOL
+BnAddWord(
+	  bigNum           result,
+	  bigConst         op,
+	  crypt_uword_t    word
+	  )
+{
+    int              carry;
+    //
+    carry = (result->d[0] = op->d[0] + word) < word;
+    carry = CarryProp(&result->d[1], &op->d[1], (int)(op->size - 1), carry);
+    CarryResolve(result, (int)op->size, carry);
+    return TRUE;
+}
+/* 10.2.3.3.5 SubSame() */
+/* Subtract two values that have the same size. */
+static int
+SubSame(
+	crypt_uword_t           *result,
+	const crypt_uword_t     *op1,
+	const crypt_uword_t     *op2,
+	int                      count
+	)
+{
+    int                  borrow = 0;
+    int                  i;
+    for(i = 0; i < count; i++)
+	{
+	    crypt_uword_t    a = op1[i];
+	    crypt_uword_t    diff = a - op2[i];
+	    result[i] = diff - borrow;
+	    //       generate   |      propagate
+	    borrow = (diff > a) | ((diff == 0) & borrow);
+	}
+    return borrow;
+}
+/* 10.2.3.3.6 BorrowProp() */
+/* This propagates a borrow. If borrow is true when the end of the array is reached, then it means
+   that op2 was larger than op1 and we don't handle that case so an assert is generated. This design
+   choice was made because our only bigNum computations are on large positive numbers (primes) or on
+   fields. Propagate a borrow. */
+static int
+BorrowProp(
+	   crypt_uword_t           *result,
+	   const crypt_uword_t     *op,
+	   int                      size,
+	   int                      borrow
+	   )
+{
+    for(; size > 0; size--)
+	borrow = ((*result++ = *op++ - borrow) == MAX_CRYPT_UWORD) && borrow;
+    return borrow;
+}
+/* 10.2.3.3.7 BnSub() */
+/* This function does subtraction of two bigNum values and returns result = op1 - op2 when op1 is
+   greater than op2. If op2 is greater than op1, then a fault is generated. This function always
+   returns TRUE. */
+
+LIB_EXPORT BOOL
+BnSub(
+      bigNum           result,
+      bigConst         op1,
+      bigConst         op2
+      )
+{
+    int             borrow;
+    int             stop = (int)MIN(op1->size, op2->allocated);
+    //
+    // Make sure that op2 is not obviously larger than op1
+    pAssert(op1->size >= op2->size);
+    borrow = SubSame(result->d, op1->d, op2->d, stop);
+    if(op1->size > (crypt_uword_t)stop)
+	borrow = BorrowProp(&result->d[stop], &op1->d[stop], (int)(op1->size - stop),
+			    borrow);
+    pAssert(!borrow);
+    BnSetTop(result, op1->size);
+    return TRUE;
+}
+/* 10.2.3.3.8 BnSubWord() */
+/* This function subtracts a word value from a bigNum. This function always returns TRUE. */
+LIB_EXPORT BOOL
+BnSubWord(
+	  bigNum           result,
+	  bigConst     op,
+	  crypt_uword_t    word
+	  )
+{
+    int             borrow;
+    //
+    pAssert(op->size > 1 || word <= op->d[0]);
+    borrow = word > op->d[0];
+    result->d[0] = op->d[0] - word;
+    borrow = BorrowProp(&result->d[1], &op->d[1], (int)(op->size - 1), borrow);
+    pAssert(!borrow);
+    BnSetTop(result, op->size);
+    return TRUE;
+}
+/* 10.2.3.3.9 BnUnsignedCmp() */
+/* This function performs a comparison of op1 to op2. The compare is approximately constant time if
+   the size of the values used in the compare is consistent across calls (from the same line in the
+   calling code). */
+/* Return Values Meaning */
+/* < 0 op1 is less than op2 */
+/* 0 op1 is equal to op2 */
+/* > 0 op1 is greater than op2 */
+LIB_EXPORT int
+BnUnsignedCmp(
+	      bigConst               op1,
+	      bigConst               op2
+	      )
+{
+    int             retVal;
+    int             diff;
+    int              i;
+    //
+    pAssert((op1 != NULL) && (op2 != NULL));
+    retVal = (int)(op1->size - op2->size);
+    if(retVal == 0)
+	{
+	    for(i = (int)(op1->size - 1); i >= 0; i--)
+		{
+		    diff = (op1->d[i] < op2->d[i]) ? -1 : (op1->d[i] != op2->d[i]);
+		    retVal = retVal == 0 ? diff : retVal;
+		}
+	}
+    else
+	retVal = (retVal < 0) ? -1 : 1;
+    return retVal;
+}
+/* 10.2.3.3.10 BnUnsignedCmpWord() */
+/* Compare a bigNum to a crypt_uword_t. */
+/* Return Value	Meaning */
+/* -1	op1 is less that word */
+/* 0	op1 is equal to word */
+/* 1	op1 is greater than word */
+LIB_EXPORT int
+BnUnsignedCmpWord(
+		  bigConst             op1,
+		  crypt_uword_t        word
+		  )
+{
+    if(op1->size > 1)
+	return 1;
+    else if(op1->size == 1)
+	return (op1->d[0] < word) ? -1 : (op1->d[0] > word);
+    else // op1 is zero
+	// equal if word is zero
+	return (word == 0) ? 0 : -1;
+}
+/* 10.2.3.3.11 BnModWord() */
+/* This function does modular division of a big number when the modulus is a word value. */
+LIB_EXPORT crypt_word_t
+BnModWord(
+	  bigConst         numerator,
+	  crypt_word_t     modulus
+	  )
+{
+    BN_MAX(remainder);
+    BN_VAR(mod, RADIX_BITS);
+    //
+    mod->d[0] = modulus;
+    mod->size = (modulus != 0);
+    BnDiv(NULL, remainder, numerator, mod);
+    return remainder->d[0];
+}
+/* 10.2.3.3.12 Msb() */
+/* Returns the bit number of the most significant bit of a crypt_uword_t. The number for the least
+   significant bit of any bigNum value is 0. The maximum return value is RADIX_BITS - 1, */
+/* Return Values Meaning */
+/* -1 the word was zero */
+/* n the bit number of the most significant bit in the word */
+LIB_EXPORT int
+Msb(
+    crypt_uword_t           word
+    )
+{
+    int             retVal = -1;
+    //
+#if RADIX_BITS == 64
+    if(word & 0xffffffff00000000) { retVal += 32; word >>= 32; }
+#endif
+    if(word & 0xffff0000) { retVal += 16; word >>= 16; }
+    if(word & 0x0000ff00) { retVal += 8; word >>= 8; }
+    if(word & 0x000000f0) { retVal += 4; word >>= 4; }
+    if(word & 0x0000000c) { retVal += 2; word >>= 2; }
+    if(word & 0x00000002) { retVal += 1; word >>= 1; }
+    return retVal + (int)word;
+}
+/* 10.2.3.3.13 BnMsb() */
+/* This function returns the number of the MSb() of a bigNum value. */
+/*     Return Value	Meaning */
+/*     -1	the word was zero or bn was NULL */
+/*     n	the bit number of the most significant bit in the word */
+
+LIB_EXPORT int
+BnMsb(
+      bigConst            bn
+      )
+{
+    // If the value is NULL, or the size is zero then treat as zero and return -1
+    if(bn != NULL && bn->size > 0)
+	{
+	    int         retVal = Msb(bn->d[bn->size - 1]);
+	    retVal += (int)(bn->size - 1) * RADIX_BITS;
+	    return retVal;
+	}
+    else
+	return -1;
+}
+/* 10.2.3.3.14 BnSizeInBits() */
+/* Returns the number of bits required to hold a number. It is one greater than the Msb. */
+LIB_EXPORT unsigned
+BnSizeInBits(
+	     bigConst                 n
+	     )
+{
+    int     bits = BnMsb(n) + 1;
+    //
+    return bits < 0 ? 0 : (unsigned)bits;
+}
+/* 10.2.3.3.15 BnSetWord() */
+/* Change the value of a bignum_t to a word value. */
+LIB_EXPORT bigNum
+BnSetWord(
+	  bigNum               n,
+	  crypt_uword_t        w
+	  )
+{
+    if(n != NULL)
+	{
+	    pAssert(n->allocated > 1);
+	    n->d[0] = w;
+	    BnSetTop(n, (w != 0) ? 1 : 0);
+	}
+    return n;
+}
+/* 10.2.3.3.16 BnSetBit() */
+/* SET a bit in a bigNum. Bit 0 is the least-significant bit in the 0th digit_t. The function always
+   return TRUE */
+LIB_EXPORT BOOL
+BnSetBit(
+	 bigNum           bn,        // IN/OUT: big number to modify
+	 unsigned int     bitNum     // IN: Bit number to SET
+	 )
+{
+    crypt_uword_t            offset = bitNum / RADIX_BITS;
+    pAssert(bn->allocated * RADIX_BITS >= bitNum);
+    // Grow the number if necessary to set the bit.
+    while(bn->size <= offset)
+	bn->d[bn->size++] = 0;
+    bn->d[offset] |= ((crypt_uword_t)1 << RADIX_MOD(bitNum));
+    return TRUE;
+}
+/* 10.2.3.3.17 BnTestBit() */
+/* Check to see if a bit is SET in a bignum_t. The 0th bit is the LSb() of d[0]. */
+/* Return Values Meaning */
+/* TRUE the bit is set */
+/* FALSE the bit is not set or the number is out of range */
+LIB_EXPORT BOOL
+BnTestBit(
+	  bigNum               bn,        // IN: number to check
+	  unsigned int         bitNum     // IN: bit to test
+	  )
+{
+    crypt_uword_t         offset = RADIX_DIV(bitNum);
+    //
+    if(bn->size > offset)
+	return ((bn->d[offset] & (((crypt_uword_t)1) << RADIX_MOD(bitNum))) != 0);
+    else
+	return FALSE;
+}
+/* 10.2.3.3.18 BnMaskBits() */
+/* Function to mask off high order bits of a big number. The returned value will have no more than
+   maskBit bits set. */
+/* NOTE: There is a requirement that unused words of a bignum_t are set to zero. */
+/* Return Values Meaning */
+/* TRUE result masked */
+/* FALSE the input was not as large as the mask */
+LIB_EXPORT BOOL
+BnMaskBits(
+	   bigNum           bn,        // IN/OUT: number to mask
+	   crypt_uword_t    maskBit    // IN: the bit number for the mask.
+	   )
+{
+    crypt_uword_t    finalSize;
+    BOOL             retVal;
+    finalSize = BITS_TO_CRYPT_WORDS(maskBit);
+    retVal = (finalSize <= bn->allocated);
+    if(retVal && (finalSize > 0))
+	{
+	    crypt_uword_t   mask;
+	    mask = ~((crypt_uword_t)0) >> RADIX_MOD(maskBit);
+	    bn->d[finalSize - 1] &= mask;
+	}
+    BnSetTop(bn, finalSize);
+    return retVal;
+}
+/* 10.2.3.3.19 BnShiftRight() */
+/* Function will shift a bigNum to the right by the shiftAmount. This function always returns
+   TRUE. */
+LIB_EXPORT BOOL
+BnShiftRight(
+	     bigNum           result,
+	     bigConst         toShift,
+	     uint32_t         shiftAmount
+	     )
+{
+    uint32_t         offset = (shiftAmount >> RADIX_LOG2);
+    uint32_t         i;
+    uint32_t         shiftIn;
+    crypt_uword_t    finalSize;
+    //
+    shiftAmount = shiftAmount & RADIX_MASK;
+    shiftIn = RADIX_BITS - shiftAmount;
+    // The end size is toShift->size - offset less one additional
+    // word if the shiftAmount would make the upper word == 0
+    if(toShift->size > offset)
+	{
+	    finalSize = toShift->size - offset;
+	    finalSize -= (toShift->d[toShift->size - 1] >> shiftAmount) == 0 ? 1 : 0;
+	}
+    else
+	finalSize = 0;
+    pAssert(finalSize <= result->allocated);
+    if(finalSize != 0)
+	{
+	    for(i = 0; i < finalSize; i++)
+		{
+		    result->d[i] = (toShift->d[i + offset] >> shiftAmount)
+				   | (toShift->d[i + offset + 1] << shiftIn);
+		}
+	    if(offset == 0)
+		result->d[i] = toShift->d[i] >> shiftAmount;
+	}
+    BnSetTop(result, finalSize);
+    return TRUE;
+}
+/* 10.2.3.3.20	BnGetRandomBits() */
+/* Return Value	Meaning */
+/* TRUE(1)	success */
+/* FALSE(0)	failure */
+LIB_EXPORT BOOL
+BnGetRandomBits(
+		bigNum           n,
+		size_t           bits,
+		RAND_STATE      *rand
+		)
+{
+    // Since this could be used for ECC key generation using the extra bits method,
+    // make sure that the value is large enough
+    TPM2B_TYPE(LARGEST, LARGEST_NUMBER + 8);
+    TPM2B_LARGEST    large;
+    //
+    large.b.size = (UINT16)BITS_TO_BYTES(bits);
+    if(DRBG_Generate(rand, large.t.buffer, large.t.size) == large.t.size)
+	{
+	    if(BnFrom2B(n, &large.b) != NULL)
+		{
+		    if(BnMaskBits(n, (crypt_uword_t)bits))
+			return TRUE;
+		}
+	}
+    return FALSE;
+}
+/* 10.2.3.3.21 BnGenerateRandomInRange() */
+/* Function to generate a random number r in the range 1 <= r < limit. The function gets a random
+   number of bits that is the size of limit. There is some some probability that the returned number
+   is going to be greater than or equal to the limit. If it is, try again. There is no more than 50%
+   chance that the next number is also greater, so try again. We keep trying until we get a value
+   that meets the criteria. Since limit is very often a number with a LOT of high order ones, this
+   rarely would need a second try. */
+/* Return Value	Meaning */
+/* TRUE(1)	success */
+/* FALSE(0)	failure */
+LIB_EXPORT BOOL
+BnGenerateRandomInRange(
+			bigNum           dest,
+			bigConst         limit,
+			RAND_STATE      *rand
+			)
+{
+    size_t   bits = BnSizeInBits(limit);
+    //
+    if(bits < 2)
+	{
+	    BnSetWord(dest, 0);
+	    return FALSE;
+	}
+    else
+	{
+	    while(BnGetRandomBits(dest, bits, rand)
+		  && (BnEqualZero(dest) || (BnUnsignedCmp(dest, limit) >= 0)));
+	}
+    return !g_inFailureMode;
+}

+ 156 - 0
EVSE/GPL/ibmtpm1682/src/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

+ 201 - 0
EVSE/GPL/ibmtpm1682/src/BnMemory.c

@@ -0,0 +1,201 @@
+/********************************************************************************/
+/*										*/
+/*			     				*/
+/*			     Written by Ken Goldman				*/
+/*		       IBM Thomas J. Watson Research Center			*/
+/*            $Id: BnMemory.c 1262 2018-07-11 21:03:43Z kgoldman $			*/
+/*										*/
+/*  Licenses and Notices							*/
+/*										*/
+/*  1. Copyright Licenses:							*/
+/*										*/
+/*  - Trusted Computing Group (TCG) grants to the user of the source code in	*/
+/*    this specification (the "Source Code") a worldwide, irrevocable, 		*/
+/*    nonexclusive, royalty free, copyright license to reproduce, create 	*/
+/*    derivative works, distribute, display and perform the Source Code and	*/
+/*    derivative works thereof, and to grant others the rights granted herein.	*/
+/*										*/
+/*  - The TCG grants to the user of the other parts of the specification 	*/
+/*    (other than the Source Code) the rights to reproduce, distribute, 	*/
+/*    display, and perform the specification solely for the purpose of 		*/
+/*    developing products based on such documents.				*/
+/*										*/
+/*  2. Source Code Distribution Conditions:					*/
+/*										*/
+/*  - Redistributions of Source Code must retain the above copyright licenses, 	*/
+/*    this list of conditions and the following disclaimers.			*/
+/*										*/
+/*  - Redistributions in binary form must reproduce the above copyright 	*/
+/*    licenses, this list of conditions	and the following disclaimers in the 	*/
+/*    documentation and/or other materials provided with the distribution.	*/
+/*										*/
+/*  3. Disclaimers:								*/
+/*										*/
+/*  - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF	*/
+/*  LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH	*/
+/*  RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES)	*/
+/*  THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE.		*/
+/*  Contact TCG Administration (admin@trustedcomputinggroup.org) for 		*/
+/*  information on specification licensing rights available through TCG 	*/
+/*  membership agreements.							*/
+/*										*/
+/*  - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED 	*/
+/*    WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR 	*/
+/*    FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR 		*/
+/*    NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY 		*/
+/*    OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE.		*/
+/*										*/
+/*  - Without limitation, TCG and its members and licensors disclaim all 	*/
+/*    liability, including liability for infringement of any proprietary 	*/
+/*    rights, relating to use of information in this specification and to the	*/
+/*    implementation of this specification, and TCG disclaims all liability for	*/
+/*    cost of procurement of substitute goods or services, lost profits, loss 	*/
+/*    of use, loss of data or any incidental, consequential, direct, indirect, 	*/
+/*    or special damages, whether under contract, tort, warranty or otherwise, 	*/
+/*    arising in any way out of use or reliance upon this specification or any 	*/
+/*    information herein.							*/
+/*										*/
+/*  (c) Copyright IBM Corp. and others, 2016					*/
+/*										*/
+/********************************************************************************/
+
+/* 10.2.5 BnMemory.c */
+/* 10.2.5.1 Introduction */
+/* This file contains the memory setup functions used by the bigNum functions in CryptoEngine() */
+/* 10.2.5.2 Includes */
+#include "Tpm.h"
+/* 10.2.5.3 Functions */
+/* 10.2.5.3.1 BnSetTop() */
+/* This function is used when the size of a bignum_t is changed. It makes sure that the unused words
+   are set to zero and that any significant words of zeros are eliminated from the used size
+   indicator. */
+LIB_EXPORT bigNum
+BnSetTop(
+	 bigNum           bn,        // IN/OUT: number to clean
+	 crypt_uword_t    top        // IN: the new top
+	 )
+{
+    if(bn != NULL)
+	{
+	    pAssert(top <= bn->allocated);
+	    // If forcing the size to be decreased, make sure that the words being
+	    // discarded are being set to 0
+	    while(bn->size > top)
+		bn->d[--bn->size] = 0;
+	    bn->size = top;
+	    // Now make sure that the words that are left are 'normalized' (no high-order
+	    // words of zero.
+	    while((bn->size > 0) && (bn->d[bn->size - 1] == 0))
+		bn->size -= 1;
+	}
+    return bn;
+}
+/* 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;
+}
+#if 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

+ 104 - 0
EVSE/GPL/ibmtpm1682/src/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

+ 327 - 0
EVSE/GPL/ibmtpm1682/src/BnValues.h

@@ -0,0 +1,327 @@
+/********************************************************************************/
+/*										*/
+/*			  For defining the internal BIGNUM structure   		*/
+/*			     Written by Ken Goldman				*/
+/*		       IBM Thomas J. Watson Research Center			*/
+/*            $Id: BnValues.h 1658 2021-01-22 23:14:01Z kgoldman $		*/
+/*										*/
+/*  Licenses and Notices							*/
+/*										*/
+/*  1. Copyright Licenses:							*/
+/*										*/
+/*  - Trusted Computing Group (TCG) grants to the user of the source code in	*/
+/*    this specification (the "Source Code") a worldwide, irrevocable, 		*/
+/*    nonexclusive, royalty free, copyright license to reproduce, create 	*/
+/*    derivative works, distribute, display and perform the Source Code and	*/
+/*    derivative works thereof, and to grant others the rights granted herein.	*/
+/*										*/
+/*  - The TCG grants to the user of the other parts of the specification 	*/
+/*    (other than the Source Code) the rights to reproduce, distribute, 	*/
+/*    display, and perform the specification solely for the purpose of 		*/
+/*    developing products based on such documents.				*/
+/*										*/
+/*  2. Source Code Distribution Conditions:					*/
+/*										*/
+/*  - Redistributions of Source Code must retain the above copyright licenses, 	*/
+/*    this list of conditions and the following disclaimers.			*/
+/*										*/
+/*  - Redistributions in binary form must reproduce the above copyright 	*/
+/*    licenses, this list of conditions	and the following disclaimers in the 	*/
+/*    documentation and/or other materials provided with the distribution.	*/
+/*										*/
+/*  3. Disclaimers:								*/
+/*										*/
+/*  - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF	*/
+/*  LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH	*/
+/*  RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES)	*/
+/*  THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE.		*/
+/*  Contact TCG Administration (admin@trustedcomputinggroup.org) for 		*/
+/*  information on specification licensing rights available through TCG 	*/
+/*  membership agreements.							*/
+/*										*/
+/*  - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED 	*/
+/*    WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR 	*/
+/*    FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR 		*/
+/*    NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY 		*/
+/*    OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE.		*/
+/*										*/
+/*  - Without limitation, TCG and its members and licensors disclaim all 	*/
+/*    liability, including liability for infringement of any proprietary 	*/
+/*    rights, relating to use of information in this specification and to the	*/
+/*    implementation of this specification, and TCG disclaims all liability for	*/
+/*    cost of procurement of substitute goods or services, lost profits, loss 	*/
+/*    of use, loss of data or any incidental, consequential, direct, indirect, 	*/
+/*    or special damages, whether under contract, tort, warranty or otherwise, 	*/
+/*    arising in any way out of use or reliance upon this specification or any 	*/
+/*    information herein.							*/
+/*										*/
+/*  (c) Copyright IBM Corp. and others, 2016 - 2021				*/
+/*										*/
+/********************************************************************************/
+
+/* 10.1.1 BnValues.h */
+/* This file contains the definitions needed for defining the internal BIGNUM structure. A BIGNUM is
+   a pointer to a structure. The structure has three fields. The last field is and array (d) of
+   crypt_uword_t. Each word is in machine format (big- or little-endian) with the words in ascending
+   significance (i.e. words in little-endian order). This is the order that seems to be used in
+   every big number library in the worlds, so... */
+/* The first field in the structure (allocated) is the number of words in d. This is the upper limit
+   on the size of the number that can be held in the structure. This differs from libraries like
+   OpenSSL() as this is not intended to deal with numbers of arbitrary size; just numbers that are
+   needed to deal with the algorithms that are defined in the TPM implementation. */
+/* The second field in the structure (size) is the number of significant words in n. When this
+   number is zero, the number is zero. The word at used-1 should never be zero. All words between
+   d[size] and d[allocated-1] should be zero. */
+#ifndef _BN_NUMBERS_H
+#define _BN_NUMBERS_H
+#if RADIX_BITS == 64
+# define RADIX_LOG2         6
+#elif RADIX_BITS == 32
+#define RADIX_LOG2          5
+#else
+# error "Unsupported radix"
+#endif
+#define RADIX_MOD(x)        ((x) & ((1 << RADIX_LOG2) - 1))
+#define RADIX_DIV(x)        ((x) >> RADIX_LOG2)
+#define RADIX_MASK  ((((crypt_uword_t)1) << RADIX_LOG2) - 1)
+#define BITS_TO_CRYPT_WORDS(bits)       RADIX_DIV((bits) + (RADIX_BITS - 1))
+#define BYTES_TO_CRYPT_WORDS(bytes)     BITS_TO_CRYPT_WORDS(bytes * 8)
+#define SIZE_IN_CRYPT_WORDS(thing)      BYTES_TO_CRYPT_WORDS(sizeof(thing))
+#if RADIX_BITS == 64
+#define SWAP_CRYPT_WORD(x)  REVERSE_ENDIAN_64(x)
+typedef uint64_t    crypt_uword_t;
+typedef int64_t     crypt_word_t;
+#   define TO_CRYPT_WORD_64             BIG_ENDIAN_BYTES_TO_UINT64
+#   define TO_CRYPT_WORD_32(a, b, c, d) TO_CRYPT_WORD_64(0, 0, 0, 0, a, b, c, d)
+#elif RADIX_BITS == 32
+#define SWAP_CRYPT_WORD(x)  REVERSE_ENDIAN_32((x))
+typedef uint32_t    crypt_uword_t;
+typedef int32_t     crypt_word_t;
+#   define TO_CRYPT_WORD_64(a, b, c, d, e, f, g, h)			\
+    BIG_ENDIAN_BYTES_TO_UINT32(e, f, g, h),				\
+    BIG_ENDIAN_BYTES_TO_UINT32(a, b, c, d)
+#  define TO_CRYPT_WORD_32 		BIG_ENDIAN_BYTES_TO_UINT32
+#endif
+#define MAX_CRYPT_UWORD (~((crypt_uword_t)0))
+#define MAX_CRYPT_WORD  ((crypt_word_t)(MAX_CRYPT_UWORD >> 1))
+#define MIN_CRYPT_WORD  (~MAX_CRYPT_WORD)
+#define LARGEST_NUMBER (MAX((ALG_RSA * MAX_RSA_KEY_BYTES),		\
+			    MAX((ALG_ECC * MAX_ECC_KEY_BYTES), MAX_DIGEST_SIZE)))
+#define LARGEST_NUMBER_BITS (LARGEST_NUMBER * 8)
+#define MAX_ECC_PARAMETER_BYTES (MAX_ECC_KEY_BYTES * ALG_ECC)
+/* These are the basic big number formats. This is convertible to the library- specific format
+   without too much difficulty. For the math performed using these numbers, the value is always
+   positive. */
+#define BN_STRUCT_DEF(count) struct {			    \
+	crypt_uword_t       allocated;			    \
+	crypt_uword_t       size;			    \
+	crypt_uword_t       d[count];			    \
+    }
+typedef BN_STRUCT_DEF(1) bignum_t;
+#ifndef bigNum
+typedef bignum_t       *bigNum;
+typedef const bignum_t *bigConst;
+#endif
+extern const bignum_t   BnConstZero;
+/* The Functions to access the properties of a big number. Get number of allocated words */
+#define BnGetAllocated(x)   (unsigned)((x)->allocated)
+/* Get number of words used */
+#define BnGetSize(x)        ((x)->size)
+/* Get a pointer to the data array */
+#define BnGetArray(x)       ((crypt_uword_t *)&((x)->d[0]))
+/* Get the nth word of a BIGNUM (zero-based) */
+#define BnGetWord(x, i)     (crypt_uword_t)((x)->d[i])
+/* Some things that are done often. Test to see if a bignum_t is equal to zero */
+#define BnEqualZero(bn)   (BnGetSize(bn) == 0)
+/* Test to see if a bignum_t is equal to a word type */
+#define BnEqualWord(bn, word)						\
+    ((BnGetSize(bn) == 1) && (BnGetWord(bn, 0) == (crypt_uword_t)word))
+/* Determine if a BIGNUM is even. A zero is even. Although the indication that a number is zero is
+   that its size is zero, all words of the number are 0 so this test works on zero. */
+#define BnIsEven(n)     ((BnGetWord(n, 0) & 1) == 0)
+/* The macros below are used to define BIGNUM values of the required size. The values are allocated
+   on the stack so they can be treated like simple local values. This will call the initialization
+   function for a defined bignum_t. This sets the allocated and used fields and clears the words of
+   n. */
+#define BN_INIT(name)							\
+    (bigNum)BnInit((bigNum)&(name),					\
+		   BYTES_TO_CRYPT_WORDS(sizeof(name.d)))
+/* In some cases, a function will need the address of the structure associated with a variable. The
+   structure for a BIGNUM variable of name is name_. Generally, when the structure is created, it is
+   initialized and a parameter is created with a pointer to the structure. The pointer has the name
+   and the structure it points to is name_ */
+#define BN_ADDRESS(name) (bigNum)&name##_
+
+#define BN_CONST(name, words, initializer)				\
+    typedef const struct name##_type {					\
+	crypt_uword_t       allocated;					\
+	crypt_uword_t       size;					\
+	crypt_uword_t       d[words < 1 ? 1 : words];			\
+    } name##_type;							\
+    name##_type name = {(words < 1 ? 1 : words), words, {initializer}};
+
+#define BN_STRUCT_ALLOCATION(bits) (BITS_TO_CRYPT_WORDS(bits) + 1)
+/* Create a structure of the correct size. */
+#define BN_STRUCT(bits)					\
+    BN_STRUCT_DEF(BN_STRUCT_ALLOCATION(bits))
+/* Define a BIGNUM type with a specific allocation */
+#define BN_TYPE(name, bits)				\
+    typedef BN_STRUCT(bits) bn_##name##_t
+/* This creates a local BIGNUM variable of a specific size and initializes it from a TPM2B input
+   parameter. */
+#define BN_INITIALIZED(name, bits, initializer)				\
+    BN_STRUCT(bits)  name##_;						\
+    bigNum           name = BnFrom2B(BN_INIT(name##_),			\
+				     (const TPM2B *)initializer)
+/* Create a local variable that can hold a number with bits */
+#define BN_VAR(name, bits)						\
+    BN_STRUCT(bits)  _##name;						\
+    bigNum           name = BN_INIT(_##name)
+/* Create a type that can hold the largest number defined by the implementation. */
+#define BN_MAX(name)   BN_VAR(name, LARGEST_NUMBER_BITS)
+#define BN_MAX_INITIALIZED(name, initializer)				\
+    BN_INITIALIZED(name, LARGEST_NUMBER_BITS, initializer)
+/* A word size value is useful */
+#define BN_WORD(name)      BN_VAR(name, RADIX_BITS)
+/* This is used to create a word-size BIGNUM and initialize it with an input parameter to a
+   function. */
+#define BN_WORD_INITIALIZED(name, initial)				\
+    BN_STRUCT(RADIX_BITS)  name##_;					\
+    bigNum                 name = BnInitializeWord((bigNum)&name##_,	\
+						   BN_STRUCT_ALLOCATION(RADIX_BITS), initial)
+/* ECC-Specific Values This is the format for a point. It is always in affine format. The Z value is
+   carried as part of the point, primarily to simplify the interface to the support library. Rather
+   than have the interface layer have to create space for the point each time it is used... The x,
+   y, and z values are pointers to bigNum values and not in-line versions of the numbers. This is a
+   relic of the days when there was no standard TPM format for the numbers */
+typedef struct _bn_point_t
+{
+    bigNum          x;
+    bigNum          y;
+    bigNum          z;
+} bn_point_t;
+typedef bn_point_t          *bigPoint;
+typedef const bn_point_t    *pointConst;
+typedef struct constant_point_t
+{
+    bigConst        x;
+    bigConst        y;
+    bigConst        z;
+} constant_point_t;
+#define ECC_BITS    (MAX_ECC_KEY_BYTES * 8)
+BN_TYPE(ecc, ECC_BITS);
+#define ECC_NUM(name)       BN_VAR(name, ECC_BITS)
+#define ECC_INITIALIZED(name, initializer)		\
+    BN_INITIALIZED(name, ECC_BITS, initializer)
+#define POINT_INSTANCE(name, bits)					\
+    BN_STRUCT (bits)    name##_x =					\
+    {BITS_TO_CRYPT_WORDS ( bits ), 0,{0}};				\
+    BN_STRUCT ( bits )    name##_y =					\
+    {BITS_TO_CRYPT_WORDS ( bits ), 0,{0}};				\
+    BN_STRUCT ( bits )    name##_z =					\
+    {BITS_TO_CRYPT_WORDS ( bits ), 0,{0}};				\
+    bn_point_t name##_
+#define POINT_INITIALIZER(name)						\
+    BnInitializePoint(&name##_, (bigNum)&name##_x,			\
+		      (bigNum)&name##_y, (bigNum)&name##_z)
+#define POINT_INITIALIZED(name, initValue)				\
+    POINT_INSTANCE(name, MAX_ECC_KEY_BITS);				\
+    bigPoint             name = BnPointFrom2B(				\
+					      POINT_INITIALIZER(name),	\
+					      initValue)
+#define POINT_VAR(name, bits)						\
+    POINT_INSTANCE (name, bits);					\
+    bigPoint            name = POINT_INITIALIZER(name)
+#define POINT(name)      POINT_VAR(name, MAX_ECC_KEY_BITS)
+/* Structure for the curve parameters. This is an analog to the TPMS_ALGORITHM_DETAIL_ECC */
+typedef struct
+{
+    bigConst             prime;     // a prime number
+    bigConst             order;     // the order of the curve
+    bigConst             h;         // cofactor
+    bigConst             a;         // linear coefficient
+    bigConst             b;         // constant term
+    constant_point_t     base;      // base point
+} ECC_CURVE_DATA;
+/* Access macros for the ECC_CURVE structure. The parameter C is a pointer to an ECC_CURVE_DATA
+   structure. In some libraries, the curve structure contains a pointer to an ECC_CURVE_DATA
+   structure as well as some other bits. For those cases, the AccessCurveData() macro is used in the
+   code to first get the pointer to the ECC_CURVE_DATA for access. In some cases, the macro does
+   nothing. */
+#define CurveGetPrime(C)    ((C)->prime)
+#define CurveGetOrder(C)    ((C)->order)
+#define CurveGetCofactor(C) ((C)->h)
+#define CurveGet_a(C)       ((C)->a)
+#define CurveGet_b(C)       ((C)->b)
+#define CurveGetG(C)        ((pointConst)&((C)->base))
+#define CurveGetGx(C)       ((C)->base.x)
+#define CurveGetGy(C)       ((C)->base.y)
+/* Convert bytes in initializers according to the endianess of the system. This is used for
+   CryptEccData.c. */
+#define     BIG_ENDIAN_BYTES_TO_UINT32(a, b, c, d)			\
+    (    ((UINT32)(a) << 24)						\
+	 +    ((UINT32)(b) << 16)					\
+	 +    ((UINT32)(c) << 8)					\
+	 +    ((UINT32)(d))						\
+	 )
+#define     BIG_ENDIAN_BYTES_TO_UINT64(a, b, c, d, e, f, g, h)		\
+    (    ((UINT64)(a) << 56)						\
+	 +    ((UINT64)(b) << 48)					\
+	 +    ((UINT64)(c) << 40)					\
+	 +    ((UINT64)(d) << 32)					\
+	 +    ((UINT64)(e) << 24)					\
+	 +    ((UINT64)(f) << 16)					\
+	 +    ((UINT64)(g) << 8)					\
+	 +    ((UINT64)(h))						\
+	 )
+
+#ifndef RADIX_BYTES
+#   if RADIX_BITS == 32
+#       define RADIX_BYTES 4
+#   elif RADIX_BITS == 64
+#       define RADIX_BYTES 8
+#   else
+#       error "RADIX_BITS must either be 32 or 64"
+#   endif
+#endif
+
+/* These macros are used for data initialization of big number ECC constants These two macros
+   combine a macro for data definition with a macro for structure initilization. The a parameter is
+   a macro that gives numbers to each of the bytes of the initializer and defines where each of the
+   numberd bytes will show up in the final structure. The b value is a structure that contains the
+   requisite number of bytes in big endian order. S, the MJOIN and JOIND macros will combine a macro
+   defining a data layout with a macro defining the data to be places. Generally, these macros will
+   only need expansion when CryptEccData().c gets compiled. */
+#define JOINED(a,b) a b
+#define MJOIN(a,b) a b
+
+#define B4_TO_BN(a, b, c, d)  (((((a << 8) + b) << 8) + c) + d)
+#if RADIX_BYTES == 64
+#define B8_TO_BN(a, b, c, d, e, f, g, h)				\
+    (UINT64)(((((((((((((((a) << 8) | b) << 8) | c) << 8) | d) << 8)	\
+		   e) << 8) | f) << 8) | g) << 8) | h)
+#define B1_TO_BN(a)                     B8_TO_BN(0, 0, 0, 0, 0, 0, 0, a)
+#define B2_TO_BN(a, b)                  B8_TO_BN(0, 0, 0, 0, 0, 0, a, b)
+#define B3_TO_BN(a, b, c)               B8_TO_BN(0, 0, 0, 0, 0, a, b, c)
+#define B4_TO_BN(a, b, c, d)            B8_TO_BN(0, 0, 0, 0, a, b, c, d)
+#define B5_TO_BN(a, b, c, d, e)         B8_TO_BN(0, 0, 0, a, b, c, d, e)
+#define B6_TO_BN(a, b, c, d, e, f)      B8_TO_BN(0, 0, a, b, c, d, e, f)
+#define B7_TO_BN(a, b, c, d, e, f, g)   B8_TO_BN(0, a, b, c, d, e, f, g)
+#else
+#define B1_TO_BN(a)                 B4_TO_BN(0, 0, 0, a)
+#define B2_TO_BN(a, b)              B4_TO_BN(0, 0, a, b)
+#define B3_TO_BN(a, b, c)           B4_TO_BN(0, a, b, c)
+#define B4_TO_BN(a, b, c, d)        (((((a << 8) + b) << 8) + c) + d)
+#define B5_TO_BN(a, b, c, d, e)          B4_TO_BN(b, c, d, e), B1_TO_BN(a)
+#define B6_TO_BN(a, b, c, d, e, f)       B4_TO_BN(c, d, e, f), B2_TO_BN(a, b)
+#define B7_TO_BN(a, b, c, d, e, f, g)    B4_TO_BN(d, e, f, g), B3_TO_BN(a, b, c)
+#define B8_TO_BN(a, b, c, d, e, f, g, h) B4_TO_BN(e, f, g, h), B4_TO_BN(a, b, c, d)
+
+#endif
+
+/* Add implementation dependent definitions for other ECC Values and for linkages */
+
+#include LIB_INCLUDE(MATH_LIB, Math)
+
+#endif // _BN_NUMBERS_H
+

+ 100 - 0
EVSE/GPL/ibmtpm1682/src/Cancel.c

@@ -0,0 +1,100 @@
+/********************************************************************************/
+/*										*/
+/*			Simulates the cancel pins on the TPM.	 		*/
+/*			     Written by Ken Goldman				*/
+/*		       IBM Thomas J. Watson Research Center			*/
+/*            $Id: Cancel.c 1490 2019-07-26 21:13:22Z kgoldman $		*/
+/*										*/
+/*  Licenses and Notices							*/
+/*										*/
+/*  1. Copyright Licenses:							*/
+/*										*/
+/*  - Trusted Computing Group (TCG) grants to the user of the source code in	*/
+/*    this specification (the "Source Code") a worldwide, irrevocable, 		*/
+/*    nonexclusive, royalty free, copyright license to reproduce, create 	*/
+/*    derivative works, distribute, display and perform the Source Code and	*/
+/*    derivative works thereof, and to grant others the rights granted herein.	*/
+/*										*/
+/*  - The TCG grants to the user of the other parts of the specification 	*/
+/*    (other than the Source Code) the rights to reproduce, distribute, 	*/
+/*    display, and perform the specification solely for the purpose of 		*/
+/*    developing products based on such documents.				*/
+/*										*/
+/*  2. Source Code Distribution Conditions:					*/
+/*										*/
+/*  - Redistributions of Source Code must retain the above copyright licenses, 	*/
+/*    this list of conditions and the following disclaimers.			*/
+/*										*/
+/*  - Redistributions in binary form must reproduce the above copyright 	*/
+/*    licenses, this list of conditions	and the following disclaimers in the 	*/
+/*    documentation and/or other materials provided with the distribution.	*/
+/*										*/
+/*  3. Disclaimers:								*/
+/*										*/
+/*  - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF	*/
+/*  LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH	*/
+/*  RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES)	*/
+/*  THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE.		*/
+/*  Contact TCG Administration (admin@trustedcomputinggroup.org) for 		*/
+/*  information on specification licensing rights available through TCG 	*/
+/*  membership agreements.							*/
+/*										*/
+/*  - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED 	*/
+/*    WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR 	*/
+/*    FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR 		*/
+/*    NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY 		*/
+/*    OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE.		*/
+/*										*/
+/*  - Without limitation, TCG and its members and licensors disclaim all 	*/
+/*    liability, including liability for infringement of any proprietary 	*/
+/*    rights, relating to use of information in this specification and to the	*/
+/*    implementation of this specification, and TCG disclaims all liability for	*/
+/*    cost of procurement of substitute goods or services, lost profits, loss 	*/
+/*    of use, loss of data or any incidental, consequential, direct, indirect, 	*/
+/*    or special damages, whether under contract, tort, warranty or otherwise, 	*/
+/*    arising in any way out of use or reliance upon this specification or any 	*/
+/*    information herein.							*/
+/*										*/
+/*  (c) Copyright IBM Corp. and others, 2016 - 2019				*/
+/*										*/
+/********************************************************************************/
+
+/* C.2 Cancel.c */
+/* C.2.1. Description */
+/* This module simulates the cancel pins on the TPM. */
+/* C.2.2. Includes, Typedefs, Structures, and Defines */
+#include "Platform.h"
+/* C.2.3. Functions */
+/* C.2.3.1. _plat__IsCanceled() */
+/* Check if the cancel flag is set */
+/* Return Values Meaning */
+/* TRUE(1) if cancel flag is set */
+/* FALSE(0) if cancel flag is not set */
+LIB_EXPORT int
+_plat__IsCanceled(
+		  void
+		  )
+{
+    // return cancel flag
+    return s_isCanceled;
+}
+/* C.2.3.2. _plat__SetCancel() */
+/* Set cancel flag. */
+LIB_EXPORT void
+_plat__SetCancel(
+		 void
+		 )
+{
+    s_isCanceled = TRUE;
+    return;
+}
+/* C.2.3.3. _plat__ClearCancel() */
+/* Clear cancel flag */
+LIB_EXPORT void
+_plat__ClearCancel(
+		   void
+		   )
+{
+    s_isCanceled = FALSE;
+    return;
+}

+ 76 - 0
EVSE/GPL/ibmtpm1682/src/Capabilities.h

@@ -0,0 +1,76 @@
+/********************************************************************************/
+/*										*/
+/*	Number of capability values that will fit into the largest data buffer	*/
+/*			     Written by Ken Goldman				*/
+/*		       IBM Thomas J. Watson Research Center			*/
+/*            $Id: Capabilities.h 1519 2019-11-15 20:43:51Z kgoldman $		*/
+/*										*/
+/*  Licenses and Notices							*/
+/*										*/
+/*  1. Copyright Licenses:							*/
+/*										*/
+/*  - Trusted Computing Group (TCG) grants to the user of the source code in	*/
+/*    this specification (the "Source Code") a worldwide, irrevocable, 		*/
+/*    nonexclusive, royalty free, copyright license to reproduce, create 	*/
+/*    derivative works, distribute, display and perform the Source Code and	*/
+/*    derivative works thereof, and to grant others the rights granted herein.	*/
+/*										*/
+/*  - The TCG grants to the user of the other parts of the specification 	*/
+/*    (other than the Source Code) the rights to reproduce, distribute, 	*/
+/*    display, and perform the specification solely for the purpose of 		*/
+/*    developing products based on such documents.				*/
+/*										*/
+/*  2. Source Code Distribution Conditions:					*/
+/*										*/
+/*  - Redistributions of Source Code must retain the above copyright licenses, 	*/
+/*    this list of conditions and the following disclaimers.			*/
+/*										*/
+/*  - Redistributions in binary form must reproduce the above copyright 	*/
+/*    licenses, this list of conditions	and the following disclaimers in the 	*/
+/*    documentation and/or other materials provided with the distribution.	*/
+/*										*/
+/*  3. Disclaimers:								*/
+/*										*/
+/*  - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF	*/
+/*  LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH	*/
+/*  RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES)	*/
+/*  THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE.		*/
+/*  Contact TCG Administration (admin@trustedcomputinggroup.org) for 		*/
+/*  information on specification licensing rights available through TCG 	*/
+/*  membership agreements.							*/
+/*										*/
+/*  - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED 	*/
+/*    WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR 	*/
+/*    FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR 		*/
+/*    NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY 		*/
+/*    OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE.		*/
+/*										*/
+/*  - Without limitation, TCG and its members and licensors disclaim all 	*/
+/*    liability, including liability for infringement of any proprietary 	*/
+/*    rights, relating to use of information in this specification and to the	*/
+/*    implementation of this specification, and TCG disclaims all liability for	*/
+/*    cost of procurement of substitute goods or services, lost profits, loss 	*/
+/*    of use, loss of data or any incidental, consequential, direct, indirect, 	*/
+/*    or special damages, whether under contract, tort, warranty or otherwise, 	*/
+/*    arising in any way out of use or reliance upon this specification or any 	*/
+/*    information herein.							*/
+/*										*/
+/*  (c) Copyright IBM Corp. and others, 2016 - 2019				*/
+/*										*/
+/********************************************************************************/
+
+#ifndef     _CAPABILITIES_H
+#define     _CAPABILITIES_H
+
+#define    MAX_CAP_DATA         (MAX_CAP_BUFFER - sizeof(TPM_CAP)-sizeof(UINT32))
+#define    MAX_CAP_ALGS         (MAX_CAP_DATA / sizeof(TPMS_ALG_PROPERTY))
+#define    MAX_CAP_HANDLES      (MAX_CAP_DATA / sizeof(TPM_HANDLE))
+#define    MAX_CAP_CC           (MAX_CAP_DATA / sizeof(TPM_CC))
+#define    MAX_TPM_PROPERTIES   (MAX_CAP_DATA / sizeof(TPMS_TAGGED_PROPERTY))
+#define    MAX_PCR_PROPERTIES   (MAX_CAP_DATA / sizeof(TPMS_TAGGED_PCR_SELECT))
+#define    MAX_ECC_CURVES       (MAX_CAP_DATA / sizeof(TPM_ECC_CURVE))
+#define    MAX_TAGGED_POLICIES  (MAX_CAP_DATA / sizeof(TPMS_TAGGED_POLICY))
+#define    MAX_ACT_DATA		(MAX_CAP_DATA / sizeof(TPMS_ACT_DATA))
+#define    MAX_AC_CAPABILITIES  (MAX_CAP_DATA / sizeof(TPMS_AC_OUTPUT))
+
+#endif

+ 228 - 0
EVSE/GPL/ibmtpm1682/src/CapabilityCommands.c

@@ -0,0 +1,228 @@
+/********************************************************************************/
+/*										*/
+/*			  	Capability Commands   				*/
+/*			     Written by Ken Goldman				*/
+/*		       IBM Thomas J. Watson Research Center			*/
+/*            $Id: CapabilityCommands.c 1671 2021-06-03 18:30:41Z kgoldman $	*/
+/*										*/
+/*  Licenses and Notices							*/
+/*										*/
+/*  1. Copyright Licenses:							*/
+/*										*/
+/*  - Trusted Computing Group (TCG) grants to the user of the source code in	*/
+/*    this specification (the "Source Code") a worldwide, irrevocable, 		*/
+/*    nonexclusive, royalty free, copyright license to reproduce, create 	*/
+/*    derivative works, distribute, display and perform the Source Code and	*/
+/*    derivative works thereof, and to grant others the rights granted herein.	*/
+/*										*/
+/*  - The TCG grants to the user of the other parts of the specification 	*/
+/*    (other than the Source Code) the rights to reproduce, distribute, 	*/
+/*    display, and perform the specification solely for the purpose of 		*/
+/*    developing products based on such documents.				*/
+/*										*/
+/*  2. Source Code Distribution Conditions:					*/
+/*										*/
+/*  - Redistributions of Source Code must retain the above copyright licenses, 	*/
+/*    this list of conditions and the following disclaimers.			*/
+/*										*/
+/*  - Redistributions in binary form must reproduce the above copyright 	*/
+/*    licenses, this list of conditions	and the following disclaimers in the 	*/
+/*    documentation and/or other materials provided with the distribution.	*/
+/*										*/
+/*  3. Disclaimers:								*/
+/*										*/
+/*  - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF	*/
+/*  LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH	*/
+/*  RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES)	*/
+/*  THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE.		*/
+/*  Contact TCG Administration (admin@trustedcomputinggroup.org) for 		*/
+/*  information on specification licensing rights available through TCG 	*/
+/*  membership agreements.							*/
+/*										*/
+/*  - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED 	*/
+/*    WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR 	*/
+/*    FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR 		*/
+/*    NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY 		*/
+/*    OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE.		*/
+/*										*/
+/*  - Without limitation, TCG and its members and licensors disclaim all 	*/
+/*    liability, including liability for infringement of any proprietary 	*/
+/*    rights, relating to use of information in this specification and to the	*/
+/*    implementation of this specification, and TCG disclaims all liability for	*/
+/*    cost of procurement of substitute goods or services, lost profits, loss 	*/
+/*    of use, loss of data or any incidental, consequential, direct, indirect, 	*/
+/*    or special damages, whether under contract, tort, warranty or otherwise, 	*/
+/*    arising in any way out of use or reliance upon this specification or any 	*/
+/*    information herein.							*/
+/*										*/
+/*  (c) Copyright IBM Corp. and others, 2016 - 2021				*/
+/*										*/
+/********************************************************************************/
+
+#include "Tpm.h"
+#include "GetCapability_fp.h"
+
+extern int verbose;
+
+#if CC_GetCapability  // Conditional expansion of this file
+TPM_RC
+TPM2_GetCapability(
+		   GetCapability_In    *in,            // IN: input parameter list
+		   GetCapability_Out   *out            // OUT: output parameter list
+		   )
+{
+    TPMU_CAPABILITIES   *data = &out->capabilityData.data;
+    if (verbose) {
+	FILE *f = fopen("trace.txt", "a");
+	fprintf(f, "TPM2_GetCapability: capability %x\n", in->capability);
+	fclose(f);
+    }
+    // Command Output
+    // Set output capability type the same as input type
+    out->capabilityData.capability = in->capability;
+    switch(in->capability)
+	{
+	  case TPM_CAP_ALGS:
+	    out->moreData = AlgorithmCapGetImplemented((TPM_ALG_ID)in->property,
+						       in->propertyCount,
+						       &data->algorithms);
+	    break;
+	  case TPM_CAP_HANDLES:
+	    switch(HandleGetType((TPM_HANDLE)in->property))
+		{
+		  case TPM_HT_TRANSIENT:
+		    // Get list of handles of loaded transient objects
+		    out->moreData = ObjectCapGetLoaded((TPM_HANDLE)in->property,
+						       in->propertyCount,
+						       &data->handles);
+		    break;
+		  case TPM_HT_PERSISTENT:
+		    // Get list of handles of persistent objects
+		    out->moreData = NvCapGetPersistent((TPM_HANDLE)in->property,
+						       in->propertyCount,
+						       &data->handles);
+		    break;
+		  case TPM_HT_NV_INDEX:
+		    // Get list of defined NV index
+		    out->moreData = NvCapGetIndex((TPM_HANDLE)in->property,
+						  in->propertyCount,
+						  &data->handles);
+		    break;
+		  case TPM_HT_LOADED_SESSION:
+		    // Get list of handles of loaded sessions
+		    out->moreData = SessionCapGetLoaded((TPM_HANDLE)in->property,
+							in->propertyCount,
+							&data->handles);
+		    break;
+#ifdef TPM_HT_SAVED_SESSION
+		  case TPM_HT_SAVED_SESSION:
+#else
+		  case TPM_HT_ACTIVE_SESSION:
+#endif
+	            // Get list of handles of
+		    out->moreData = SessionCapGetSaved((TPM_HANDLE)in->property,
+						       in->propertyCount,
+						       &data->handles);
+		    break;
+		  case TPM_HT_PCR:
+		    // Get list of handles of PCR
+		    out->moreData = PCRCapGetHandles((TPM_HANDLE)in->property,
+						     in->propertyCount,
+						     &data->handles);
+		    break;
+		  case TPM_HT_PERMANENT:
+		    // Get list of permanent handles
+		    out->moreData = PermanentCapGetHandles((TPM_HANDLE)in->property,
+							   in->propertyCount,
+							   &data->handles);
+		    break;
+		  default:
+		    // Unsupported input handle type
+		    return TPM_RCS_HANDLE + RC_GetCapability_property;
+		    break;
+		}
+	    break;
+	  case TPM_CAP_COMMANDS:
+	    out->moreData = CommandCapGetCCList((TPM_CC)in->property,
+						in->propertyCount,
+						&data->command);
+	    break;
+	  case TPM_CAP_PP_COMMANDS:
+	    out->moreData = PhysicalPresenceCapGetCCList((TPM_CC)in->property,
+							 in->propertyCount,
+							 &data->ppCommands);
+	    break;
+	  case TPM_CAP_AUDIT_COMMANDS:
+	    out->moreData = CommandAuditCapGetCCList((TPM_CC)in->property,
+						     in->propertyCount,
+						     &data->auditCommands);
+	    break;
+	  case TPM_CAP_PCRS:
+	    // Input property must be 0
+	    if(in->property != 0)
+		return TPM_RCS_VALUE + RC_GetCapability_property;
+	    out->moreData = PCRCapGetAllocation(in->propertyCount,
+						&data->assignedPCR);
+	    break;
+	  case TPM_CAP_PCR_PROPERTIES:
+	    out->moreData = PCRCapGetProperties((TPM_PT_PCR)in->property,
+						in->propertyCount,
+						&data->pcrProperties);
+	    break;
+	  case TPM_CAP_TPM_PROPERTIES:
+	    out->moreData = TPMCapGetProperties((TPM_PT)in->property,
+						in->propertyCount,
+						&data->tpmProperties);
+	    break;
+#if ALG_ECC
+	  case TPM_CAP_ECC_CURVES:
+	    out->moreData = CryptCapGetECCCurve((TPM_ECC_CURVE)in->property,
+						in->propertyCount,
+						&data->eccCurves);
+	    break;
+#endif // TPM_ALG_ECC
+	  case TPM_CAP_AUTH_POLICIES:
+	    if(HandleGetType((TPM_HANDLE)in->property) != TPM_HT_PERMANENT)
+		return TPM_RCS_VALUE + RC_GetCapability_property;
+	    out->moreData = PermanentHandleGetPolicy((TPM_HANDLE)in->property,
+						     in->propertyCount,
+						     &data->authPolicies);
+	    break;
+	  case TPM_CAP_ACT:
+	    if(((TPM_RH)in->property < TPM_RH_ACT_0)
+	       || ((TPM_RH)in->property > TPM_RH_ACT_F))
+		return TPM_RCS_VALUE + RC_GetCapability_property;
+	    out->moreData = ActGetCapabilityData((TPM_HANDLE)in->property,
+						 in->propertyCount,
+						 &data->actData);
+	    break;
+	  case TPM_CAP_VENDOR_PROPERTY:
+	    // vendor property is not implemented
+	  default:
+	    // Unsupported TPM_CAP value
+	    return TPM_RCS_VALUE + RC_GetCapability_capability;
+	    break;
+	}
+    return TPM_RC_SUCCESS;
+}
+#endif // CC_GetCapability
+#include "Tpm.h"
+#include "TestParms_fp.h"
+#if CC_TestParms  // Conditional expansion of this file
+TPM_RC
+TPM2_TestParms(
+	       TestParms_In    *in             // IN: input parameter list
+	       )
+{
+    if (verbose) {
+	FILE *f = fopen("trace.txt", "a");
+	fprintf(f, "TPM2_TestParms:\n");
+	fclose(f);
+    }
+    // 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

+ 95 - 0
EVSE/GPL/ibmtpm1682/src/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

+ 93 - 0
EVSE/GPL/ibmtpm1682/src/CertifyX509_fp.h

@@ -0,0 +1,93 @@
+/********************************************************************************/
+/*										*/
+/*		TPM2_CertifyX509 Command Header	     				*/
+/*			     Written by Ken Goldman				*/
+/*		       IBM Thomas J. Watson Research Center			*/
+/*            $Id: CertifyX509_fp.h 1519 2019-11-15 20:43:51Z kgoldman $	*/
+/*										*/
+/*  Licenses and Notices							*/
+/*										*/
+/*  1. Copyright Licenses:							*/
+/*										*/
+/*  - Trusted Computing Group (TCG) grants to the user of the source code in	*/
+/*    this specification (the "Source Code") a worldwide, irrevocable, 		*/
+/*    nonexclusive, royalty free, copyright license to reproduce, create 	*/
+/*    derivative works, distribute, display and perform the Source Code and	*/
+/*    derivative works thereof, and to grant others the rights granted herein.	*/
+/*										*/
+/*  - The TCG grants to the user of the other parts of the specification 	*/
+/*    (other than the Source Code) the rights to reproduce, distribute, 	*/
+/*    display, and perform the specification solely for the purpose of 		*/
+/*    developing products based on such documents.				*/
+/*										*/
+/*  2. Source Code Distribution Conditions:					*/
+/*										*/
+/*  - Redistributions of Source Code must retain the above copyright licenses, 	*/
+/*    this list of conditions and the following disclaimers.			*/
+/*										*/
+/*  - Redistributions in binary form must reproduce the above copyright 	*/
+/*    licenses, this list of conditions	and the following disclaimers in the 	*/
+/*    documentation and/or other materials provided with the distribution.	*/
+/*										*/
+/*  3. Disclaimers:								*/
+/*										*/
+/*  - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF	*/
+/*  LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH	*/
+/*  RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES)	*/
+/*  THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE.		*/
+/*  Contact TCG Administration (admin@trustedcomputinggroup.org) for 		*/
+/*  information on specification licensing rights available through TCG 	*/
+/*  membership agreements.							*/
+/*										*/
+/*  - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED 	*/
+/*    WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR 	*/
+/*    FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR 		*/
+/*    NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY 		*/
+/*    OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE.		*/
+/*										*/
+/*  - Without limitation, TCG and its members and licensors disclaim all 	*/
+/*    liability, including liability for infringement of any proprietary 	*/
+/*    rights, relating to use of information in this specification and to the	*/
+/*    implementation of this specification, and TCG disclaims all liability for	*/
+/*    cost of procurement of substitute goods or services, lost profits, loss 	*/
+/*    of use, loss of data or any incidental, consequential, direct, indirect, 	*/
+/*    or special damages, whether under contract, tort, warranty or otherwise, 	*/
+/*    arising in any way out of use or reliance upon this specification or any 	*/
+/*    information herein.							*/
+/*										*/
+/*  (c) Copyright IBM Corp. and others, 2019					*/
+/*										*/
+/********************************************************************************/
+
+/* rev 155 */
+
+#ifndef CERTIFYX509_FP_H
+#define CERTIFYX509_FP_H
+
+typedef struct {
+    TPMI_DH_OBJECT	objectHandle;
+    TPMI_DH_OBJECT	signHandle;
+    TPM2B_DATA		reserved;
+    TPMT_SIG_SCHEME	inScheme;
+    TPM2B_MAX_BUFFER	partialCertificate;
+} CertifyX509_In;
+
+#define RC_CertifyX509_signHandle		(TPM_RC_H + TPM_RC_1)
+#define RC_CertifyX509_objectHandle 		(TPM_RC_H + TPM_RC_2)
+#define RC_CertifyX509_reserved			(TPM_RC_P + TPM_RC_1)
+#define RC_CertifyX509_inScheme			(TPM_RC_P + TPM_RC_2)
+#define RC_CertifyX509_partialCertificate	(TPM_RC_P + TPM_RC_3)
+
+typedef struct {
+    TPM2B_MAX_BUFFER	addedToCertificate;
+    TPM2B_DIGEST	tbsDigest;
+    TPMT_SIGNATURE	signature;
+} CertifyX509_Out;
+
+TPM_RC
+TPM2_CertifyX509(
+	     CertifyX509_In      *in,            // IN: input parameter list
+	     CertifyX509_Out     *out            // OUT: output parameter list
+	     );
+
+#endif

+ 93 - 0
EVSE/GPL/ibmtpm1682/src/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

+ 79 - 0
EVSE/GPL/ibmtpm1682/src/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

+ 79 - 0
EVSE/GPL/ibmtpm1682/src/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

+ 79 - 0
EVSE/GPL/ibmtpm1682/src/ClearControl_fp.h

@@ -0,0 +1,79 @@
+/********************************************************************************/
+/*										*/
+/*			     				*/
+/*			     Written by Ken Goldman				*/
+/*		       IBM Thomas J. Watson Research Center			*/
+/*            $Id: ClearControl_fp.h 1521 2019-11-15 21:00:47Z kgoldman $	*/
+/*										*/
+/*  Licenses and Notices							*/
+/*										*/
+/*  1. Copyright Licenses:							*/
+/*										*/
+/*  - Trusted Computing Group (TCG) grants to the user of the source code in	*/
+/*    this specification (the "Source Code") a worldwide, irrevocable, 		*/
+/*    nonexclusive, royalty free, copyright license to reproduce, create 	*/
+/*    derivative works, distribute, display and perform the Source Code and	*/
+/*    derivative works thereof, and to grant others the rights granted herein.	*/
+/*										*/
+/*  - The TCG grants to the user of the other parts of the specification 	*/
+/*    (other than the Source Code) the rights to reproduce, distribute, 	*/
+/*    display, and perform the specification solely for the purpose of 		*/
+/*    developing products based on such documents.				*/
+/*										*/
+/*  2. Source Code Distribution Conditions:					*/
+/*										*/
+/*  - Redistributions of Source Code must retain the above copyright licenses, 	*/
+/*    this list of conditions and the following disclaimers.			*/
+/*										*/
+/*  - Redistributions in binary form must reproduce the above copyright 	*/
+/*    licenses, this list of conditions	and the following disclaimers in the 	*/
+/*    documentation and/or other materials provided with the distribution.	*/
+/*										*/
+/*  3. Disclaimers:								*/
+/*										*/
+/*  - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF	*/
+/*  LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH	*/
+/*  RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES)	*/
+/*  THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE.		*/
+/*  Contact TCG Administration (admin@trustedcomputinggroup.org) for 		*/
+/*  information on specification licensing rights available through TCG 	*/
+/*  membership agreements.							*/
+/*										*/
+/*  - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED 	*/
+/*    WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR 	*/
+/*    FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR 		*/
+/*    NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY 		*/
+/*    OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE.		*/
+/*										*/
+/*  - Without limitation, TCG and its members and licensors disclaim all 	*/
+/*    liability, including liability for infringement of any proprietary 	*/
+/*    rights, relating to use of information in this specification and to the	*/
+/*    implementation of this specification, and TCG disclaims all liability for	*/
+/*    cost of procurement of substitute goods or services, lost profits, loss 	*/
+/*    of use, loss of data or any incidental, consequential, direct, indirect, 	*/
+/*    or special damages, whether under contract, tort, warranty or otherwise, 	*/
+/*    arising in any way out of use or reliance upon this specification or any 	*/
+/*    information herein.							*/
+/*										*/
+/*  (c) Copyright IBM Corp. and others, 2012-2015				*/
+/*										*/
+/********************************************************************************/
+
+/* rev 119 */
+
+#ifndef CLEARCONTROL_FP_H
+#define CLEARCONTROL_FP_H
+
+typedef struct {
+    TPMI_RH_CLEAR	auth;
+    TPMI_YES_NO		disable;
+} ClearControl_In;
+
+#define RC_ClearControl_auth	(TPM_RC_H + TPM_RC_1)
+#define RC_ClearControl_disable	(TPM_RC_P + TPM_RC_1)
+
+TPM_RC
+TPM2_ClearControl(
+		  ClearControl_In     *in             // IN: input parameter list
+		  );
+#endif

+ 78 - 0
EVSE/GPL/ibmtpm1682/src/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

+ 289 - 0
EVSE/GPL/ibmtpm1682/src/Clock.c

@@ -0,0 +1,289 @@
+/********************************************************************************/
+/*										*/
+/*		 Used by the simulator to mimic a hardware clock  		*/
+/*			     Written by Ken Goldman				*/
+/*		       IBM Thomas J. Watson Research Center			*/
+/*            $Id: Clock.c 1529 2019-11-21 23:29:01Z kgoldman $			*/
+/*										*/
+/*  Licenses and Notices							*/
+/*										*/
+/*  1. Copyright Licenses:							*/
+/*										*/
+/*  - Trusted Computing Group (TCG) grants to the user of the source code in	*/
+/*    this specification (the "Source Code") a worldwide, irrevocable, 		*/
+/*    nonexclusive, royalty free, copyright license to reproduce, create 	*/
+/*    derivative works, distribute, display and perform the Source Code and	*/
+/*    derivative works thereof, and to grant others the rights granted herein.	*/
+/*										*/
+/*  - The TCG grants to the user of the other parts of the specification 	*/
+/*    (other than the Source Code) the rights to reproduce, distribute, 	*/
+/*    display, and perform the specification solely for the purpose of 		*/
+/*    developing products based on such documents.				*/
+/*										*/
+/*  2. Source Code Distribution Conditions:					*/
+/*										*/
+/*  - Redistributions of Source Code must retain the above copyright licenses, 	*/
+/*    this list of conditions and the following disclaimers.			*/
+/*										*/
+/*  - Redistributions in binary form must reproduce the above copyright 	*/
+/*    licenses, this list of conditions	and the following disclaimers in the 	*/
+/*    documentation and/or other materials provided with the distribution.	*/
+/*										*/
+/*  3. Disclaimers:								*/
+/*										*/
+/*  - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF	*/
+/*  LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH	*/
+/*  RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES)	*/
+/*  THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE.		*/
+/*  Contact TCG Administration (admin@trustedcomputinggroup.org) for 		*/
+/*  information on specification licensing rights available through TCG 	*/
+/*  membership agreements.							*/
+/*										*/
+/*  - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED 	*/
+/*    WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR 	*/
+/*    FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR 		*/
+/*    NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY 		*/
+/*    OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE.		*/
+/*										*/
+/*  - Without limitation, TCG and its members and licensors disclaim all 	*/
+/*    liability, including liability for infringement of any proprietary 	*/
+/*    rights, relating to use of information in this specification and to the	*/
+/*    implementation of this specification, and TCG disclaims all liability for	*/
+/*    cost of procurement of substitute goods or services, lost profits, loss 	*/
+/*    of use, loss of data or any incidental, consequential, direct, indirect, 	*/
+/*    or special damages, whether under contract, tort, warranty or otherwise, 	*/
+/*    arising in any way out of use or reliance upon this specification or any 	*/
+/*    information herein.							*/
+/*										*/
+/*  (c) Copyright IBM Corp. and others, 2016 - 2019				*/
+/*										*/
+/********************************************************************************/
+
+/* added for portability because Linux clock is 32 bits */
+
+#include <stdint.h>
+#include <stdio.h>
+#include <time.h>
+
+/* C.3 Clock.c */
+/* C.3.1. Description */
+/* This file contains the routines that are used by the simulator to mimic a hardware clock on a
+   TPM. In this implementation, all the time values are measured in millisecond. However, the
+   precision of the clock functions may be implementation dependent. */
+/* C.3.2. Includes and Data Definitions */
+#include <assert.h>
+#include "Platform.h"
+#include "TpmFail_fp.h"
+/* C.3.3. Simulator Functions */
+/* C.3.3.1. Introduction */
+/* This set of functions is intended to be called by the simulator environment in order to simulate
+   hardware events. */
+/* C.3.3.2. _plat__TimerReset() */
+/* This function sets current system clock time as t0 for counting TPM time. This function is called
+   at a power on event to reset the clock.  When the clock is reset, the indication that the clock
+   was stopped is also set. */
+LIB_EXPORT void
+_plat__TimerReset(
+		  void
+		  )
+{
+    s_lastSystemTime = 0;
+    s_tpmTime = 0;
+    s_adjustRate = CLOCK_NOMINAL;
+    s_timerReset = TRUE;
+    s_timerStopped = TRUE;
+    return;
+}
+/* C.3.3.3. _plat__TimerRestart() */
+/* This function should be called in order to simulate the restart of the timer should it be stopped
+   while power is still applied. */
+LIB_EXPORT void
+_plat__TimerRestart(
+		    void
+		    )
+{
+    s_timerStopped = TRUE;
+    return;
+}
+
+/* C.3.4. Functions Used by TPM */
+/* C.3.4.1. Introduction */
+/* These functions are called by the TPM code. They should be replaced by appropriated hardware
+   functions. */
+
+clock_t     debugTime;
+/* C.3.4.2.	_plat__Time() */
+/* This is another, probably futile, attempt to define a portable function that will return a 64-bit
+   clock value that has mSec resolution. */
+LIB_EXPORT uint64_t
+_plat__RealTime(
+		void
+		)
+{
+    clock64_t           time;
+    //#ifdef _MSC_VER	kgold
+#ifdef TPM_WINDOWS
+    #include <sys/timeb.h>
+    struct _timeb       sysTime;
+    //
+    _ftime(&sysTime);	/* kgold, mingw doesn't have _ftime_s */
+    time = (clock64_t)(sysTime.time) * 1000 + sysTime.millitm;
+    // set the time back by one hour if daylight savings
+    if(sysTime.dstflag)
+	time -= 1000 * 60 * 60;  // mSec/sec * sec/min * min/hour = ms/hour
+#else
+    // hopefully, this will work with most UNIX systems
+    struct timespec     systime;
+    //
+    clock_gettime(CLOCK_MONOTONIC, &systime);
+    time = (clock64_t)systime.tv_sec * 1000 + (systime.tv_nsec / 1000000);
+#endif
+    return time;
+}
+
+
+
+/* C.3.4.3. _plat__TimerRead() */
+/* This function provides access to the tick timer of the platform. The TPM code uses this value to
+   drive the TPM Clock. */
+/* The tick timer is supposed to run when power is applied to the device. This timer should not be
+   reset by time events including _TPM_Init(). It should only be reset when TPM power is
+   re-applied. */
+/* If the TPM is run in a protected environment, that environment may provide the tick time to the
+   TPM as long as the time provided by the environment is not allowed to go backwards. If the time
+   provided by the system can go backwards during a power discontinuity, then the
+   _plat__Signal_PowerOn() should call _plat__TimerReset(). */
+LIB_EXPORT uint64_t
+_plat__TimerRead(
+		 void
+		 )
+{
+#ifdef HARDWARE_CLOCK
+#error      "need a defintion for reading the hardware clock"
+    return HARDWARE_CLOCK
+#else
+    clock64_t         timeDiff;
+    clock64_t         adjustedTimeDiff;
+    clock64_t         timeNow;
+    clock64_t         readjustedTimeDiff;
+    // This produces a timeNow that is basically locked to the system clock.
+    timeNow = _plat__RealTime();
+    // if this hasn't been initialized, initialize it
+    if(s_lastSystemTime == 0)
+	{
+	    s_lastSystemTime = timeNow;
+	    debugTime = clock();
+	    s_lastReportedTime = 0;
+	    s_realTimePrevious = 0;
+	}
+    // The system time can bounce around and that's OK as long as we don't allow
+    // time to go backwards. When the time does appear to go backwards, set
+    // lastSystemTime to be the new value and then update the reported time.
+    if(timeNow < s_lastReportedTime)
+	s_lastSystemTime = timeNow;
+    s_lastReportedTime = s_lastReportedTime + timeNow - s_lastSystemTime;
+    s_lastSystemTime = timeNow;
+    timeNow = s_lastReportedTime;
+    // The code above produces a timeNow that is similar to the value returned
+    // by Clock(). The difference is that timeNow does not max out, and it is
+    // at a ms. rate rather than at a CLOCKS_PER_SEC rate. The code below
+    // uses that value and does the rate adjustment on the time value.
+    // If there is no difference in time, then skip all the computations
+    if(s_realTimePrevious >= timeNow)
+	return s_tpmTime;
+    // Compute the amount of time since the last update of the system clock
+    timeDiff = timeNow - s_realTimePrevious;
+    // Do the time rate adjustment and conversion from CLOCKS_PER_SEC to mSec
+    adjustedTimeDiff = (timeDiff * CLOCK_NOMINAL) / ((uint64_t)s_adjustRate);
+    // update the TPM time with the adjusted timeDiff
+    s_tpmTime += (clock64_t)adjustedTimeDiff;
+    // Might have some rounding error that would loose CLOCKS. See what is not
+    // being used. As mentioned above, this could result in putting back more than
+    // is taken out. Here, we are trying to recreate timeDiff.
+    readjustedTimeDiff = (adjustedTimeDiff * (uint64_t)s_adjustRate )
+			 / CLOCK_NOMINAL;
+    // adjusted is now converted back to being the amount we should advance the
+    // previous sampled time. It should always be less than or equal to timeDiff.
+    // That is, we could not have use more time than we started with.
+    s_realTimePrevious = s_realTimePrevious + readjustedTimeDiff;
+#ifdef  DEBUGGING_TIME
+    // Put this in so that TPM time will pass much faster than real time when
+    // doing debug.
+    // A value of 1000 for DEBUG_TIME_MULTIPLER will make each ms into a second
+    // A good value might be 100
+    return (s_tpmTime * DEBUG_TIME_MULTIPLIER);
+#endif
+    return s_tpmTime;
+#endif
+}
+
+
+/* C.3.4.3. _plat__TimerWasReset() */
+/* This function is used to interrogate the flag indicating if the tick timer has been reset. */
+/* If the resetFlag parameter is SET, then the flag will be CLEAR before the function returns. */
+LIB_EXPORT int
+_plat__TimerWasReset(
+		     void
+		     )
+{
+    int retVal = s_timerReset;
+    s_timerReset = FALSE;
+    return retVal;
+}
+/* C.3.4.4. _plat__TimerWasStopped() */
+/* This function is used to interrogate the flag indicating if the tick timer has been stopped. If
+   so, this is typically a reason to roll the nonce. */
+/* This function will CLEAR the s_timerStopped flag before returning. This provides functionality
+   that is similar to status register that is cleared when read. This is the model used here because
+   it is the one that has the most impact on the TPM code as the flag can only be accessed by one
+   entity in the TPM. Any other implementation of the hardware can be made to look like a read-once
+   register. */
+LIB_EXPORT int
+_plat__TimerWasStopped(
+		       void
+		       )
+{
+    BOOL         retVal = s_timerStopped;
+    s_timerStopped = FALSE;
+    return retVal;
+}
+/* C.3.4.5. _plat__ClockAdjustRate() */
+/* Adjust the clock rate */
+LIB_EXPORT void
+_plat__ClockAdjustRate(
+		       int	adjust         // IN: the adjust number.  It could be positive
+		       //     or negative
+		       )
+{
+    // We expect the caller should only use a fixed set of constant values to
+    // adjust the rate
+    switch(adjust)
+	{
+	  case CLOCK_ADJUST_COARSE:
+	    s_adjustRate += CLOCK_ADJUST_COARSE;
+	    break;
+	  case -CLOCK_ADJUST_COARSE:
+	    s_adjustRate -= CLOCK_ADJUST_COARSE;
+	    break;
+	  case CLOCK_ADJUST_MEDIUM:
+	    s_adjustRate += CLOCK_ADJUST_MEDIUM;
+	    break;
+	  case -CLOCK_ADJUST_MEDIUM:
+	    s_adjustRate -= CLOCK_ADJUST_MEDIUM;
+	    break;
+	  case CLOCK_ADJUST_FINE:
+	    s_adjustRate += CLOCK_ADJUST_FINE;
+	    break;
+	  case -CLOCK_ADJUST_FINE:
+	    s_adjustRate -= CLOCK_ADJUST_FINE;
+	    break;
+	  default:
+	    // ignore any other values;
+	    break;
+	}
+    if(s_adjustRate > (CLOCK_NOMINAL + CLOCK_ADJUST_LIMIT))
+	s_adjustRate = CLOCK_NOMINAL + CLOCK_ADJUST_LIMIT;
+    if(s_adjustRate < (CLOCK_NOMINAL - CLOCK_ADJUST_LIMIT))
+	s_adjustRate = CLOCK_NOMINAL - CLOCK_ADJUST_LIMIT;
+    return;
+}

+ 127 - 0
EVSE/GPL/ibmtpm1682/src/ClockCommands.c

@@ -0,0 +1,127 @@
+/********************************************************************************/
+/*										*/
+/*			    Clocks and Timers	 				*/
+/*			     Written by Ken Goldman				*/
+/*		       IBM Thomas J. Watson Research Center			*/
+/*            $Id: ClockCommands.c 1671 2021-06-03 18:30:41Z kgoldman $		*/
+/*										*/
+/*  Licenses and Notices							*/
+/*										*/
+/*  1. Copyright Licenses:							*/
+/*										*/
+/*  - Trusted Computing Group (TCG) grants to the user of the source code in	*/
+/*    this specification (the "Source Code") a worldwide, irrevocable, 		*/
+/*    nonexclusive, royalty free, copyright license to reproduce, create 	*/
+/*    derivative works, distribute, display and perform the Source Code and	*/
+/*    derivative works thereof, and to grant others the rights granted herein.	*/
+/*										*/
+/*  - The TCG grants to the user of the other parts of the specification 	*/
+/*    (other than the Source Code) the rights to reproduce, distribute, 	*/
+/*    display, and perform the specification solely for the purpose of 		*/
+/*    developing products based on such documents.				*/
+/*										*/
+/*  2. Source Code Distribution Conditions:					*/
+/*										*/
+/*  - Redistributions of Source Code must retain the above copyright licenses, 	*/
+/*    this list of conditions and the following disclaimers.			*/
+/*										*/
+/*  - Redistributions in binary form must reproduce the above copyright 	*/
+/*    licenses, this list of conditions	and the following disclaimers in the 	*/
+/*    documentation and/or other materials provided with the distribution.	*/
+/*										*/
+/*  3. Disclaimers:								*/
+/*										*/
+/*  - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF	*/
+/*  LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH	*/
+/*  RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES)	*/
+/*  THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE.		*/
+/*  Contact TCG Administration (admin@trustedcomputinggroup.org) for 		*/
+/*  information on specification licensing rights available through TCG 	*/
+/*  membership agreements.							*/
+/*										*/
+/*  - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED 	*/
+/*    WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR 	*/
+/*    FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR 		*/
+/*    NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY 		*/
+/*    OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE.		*/
+/*										*/
+/*  - Without limitation, TCG and its members and licensors disclaim all 	*/
+/*    liability, including liability for infringement of any proprietary 	*/
+/*    rights, relating to use of information in this specification and to the	*/
+/*    implementation of this specification, and TCG disclaims all liability for	*/
+/*    cost of procurement of substitute goods or services, lost profits, loss 	*/
+/*    of use, loss of data or any incidental, consequential, direct, indirect, 	*/
+/*    or special damages, whether under contract, tort, warranty or otherwise, 	*/
+/*    arising in any way out of use or reliance upon this specification or any 	*/
+/*    information herein.							*/
+/*										*/
+/*  (c) Copyright IBM Corp. and others, 2016 - 2021				*/
+/*										*/
+/********************************************************************************/
+
+#include "Tpm.h"
+#include "ReadClock_fp.h"
+
+extern int verbose;
+
+#if CC_ReadClock  // Conditional expansion of this file
+TPM_RC
+TPM2_ReadClock(
+	       ReadClock_Out   *out            // OUT: output parameter list
+	       )
+{
+    if (verbose) {
+	FILE *f = fopen("trace.txt", "a");
+	fprintf(f, "TPM2_ReadClock:\n");
+	fclose(f);
+    }
+    // Command Output
+    out->currentTime.time = g_time;
+    TimeFillInfo(&out->currentTime.clockInfo);
+    return TPM_RC_SUCCESS;
+}
+#endif // CC_ReadClock
+#include "Tpm.h"
+#include "ClockSet_fp.h"
+#if CC_ClockSet  // Conditional expansion of this file
+TPM_RC
+TPM2_ClockSet(
+	      ClockSet_In     *in             // IN: input parameter list
+	      )
+{
+    if (verbose) {
+	FILE *f = fopen("trace.txt", "a");
+	fprintf(f, "TPM2_ClockSet:\n");
+	fclose(f);
+    }
+    // Input Validation
+    // new time can not be bigger than 0xFFFF000000000000 or smaller than
+    // current clock
+    if(in->newTime > 0xFFFF000000000000ULL
+       || in->newTime < go.clock)
+	return TPM_RCS_VALUE + RC_ClockSet_newTime;
+    // Internal Data Update
+    // Can't modify the clock if NV is not available.
+    RETURN_IF_NV_IS_NOT_AVAILABLE;
+    TimeClockUpdate(in->newTime);
+    return TPM_RC_SUCCESS;
+}
+#endif // CC_ClockSet
+#include "Tpm.h"
+#include "ClockRateAdjust_fp.h"
+#if CC_ClockRateAdjust  // Conditional expansion of this file
+TPM_RC
+TPM2_ClockRateAdjust(
+		     ClockRateAdjust_In  *in             // IN: input parameter list
+		     )
+{
+    if (verbose) {
+	FILE *f = fopen("trace.txt", "a");
+	fprintf(f, "TPM2_ClockRateAdjust:\n");
+	fclose(f);
+    }
+    // Internal Data Update
+    TimeSetAdjustRate(in->rateAdjust);
+    return TPM_RC_SUCCESS;
+}
+#endif // CC_ClockRateAdjust

+ 81 - 0
EVSE/GPL/ibmtpm1682/src/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

+ 81 - 0
EVSE/GPL/ibmtpm1682/src/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

+ 986 - 0
EVSE/GPL/ibmtpm1682/src/CommandAttributeData.h

@@ -0,0 +1,986 @@
+/********************************************************************************/
+/*										*/
+/*		Command code attribute array for GetCapability	    		*/
+/*			     Written by Ken Goldman				*/
+/*		       IBM Thomas J. Watson Research Center			*/
+/*            $Id: CommandAttributeData.h 1594 2020-03-26 22:15:48Z kgoldman $	*/
+/*										*/
+/*  Licenses and Notices							*/
+/*										*/
+/*  1. Copyright Licenses:							*/
+/*										*/
+/*  - Trusted Computing Group (TCG) grants to the user of the source code in	*/
+/*    this specification (the "Source Code") a worldwide, irrevocable, 		*/
+/*    nonexclusive, royalty free, copyright license to reproduce, create 	*/
+/*    derivative works, distribute, display and perform the Source Code and	*/
+/*    derivative works thereof, and to grant others the rights granted herein.	*/
+/*										*/
+/*  - The TCG grants to the user of the other parts of the specification 	*/
+/*    (other than the Source Code) the rights to reproduce, distribute, 	*/
+/*    display, and perform the specification solely for the purpose of 		*/
+/*    developing products based on such documents.				*/
+/*										*/
+/*  2. Source Code Distribution Conditions:					*/
+/*										*/
+/*  - Redistributions of Source Code must retain the above copyright licenses, 	*/
+/*    this list of conditions and the following disclaimers.			*/
+/*										*/
+/*  - Redistributions in binary form must reproduce the above copyright 	*/
+/*    licenses, this list of conditions	and the following disclaimers in the 	*/
+/*    documentation and/or other materials provided with the distribution.	*/
+/*										*/
+/*  3. Disclaimers:								*/
+/*										*/
+/*  - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF	*/
+/*  LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH	*/
+/*  RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES)	*/
+/*  THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE.		*/
+/*  Contact TCG Administration (admin@trustedcomputinggroup.org) for 		*/
+/*  information on specification licensing rights available through TCG 	*/
+/*  membership agreements.							*/
+/*										*/
+/*  - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED 	*/
+/*    WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR 	*/
+/*    FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR 		*/
+/*    NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY 		*/
+/*    OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE.		*/
+/*										*/
+/*  - Without limitation, TCG and its members and licensors disclaim all 	*/
+/*    liability, including liability for infringement of any proprietary 	*/
+/*    rights, relating to use of information in this specification and to the	*/
+/*    implementation of this specification, and TCG disclaims all liability for	*/
+/*    cost of procurement of substitute goods or services, lost profits, loss 	*/
+/*    of use, loss of data or any incidental, consequential, direct, indirect, 	*/
+/*    or special damages, whether under contract, tort, warranty or otherwise, 	*/
+/*    arising in any way out of use or reliance upon this specification or any 	*/
+/*    information herein.							*/
+/*										*/
+/*  (c) Copyright IBM Corp. and others, 2016 - 2020				*/
+/*										*/
+/********************************************************************************/
+
+/* 5.6	CommandAttributeData.h */
+/* This file should only be included by CommandCodeAttibutes.c */
+
+#ifdef _COMMAND_CODE_ATTRIBUTES_
+#include "CommandAttributes.h"
+#if COMPRESSED_LISTS
+#   define      PAD_LIST    0
+#else
+#   define      PAD_LIST    1
+#endif
+
+/* This is the command code attribute array for GetCapability(). Both this array and
+   s_commandAttributes provides command code attributes, but tuned for different purpose */
+
+const TPMA_CC    s_ccAttr [] = {
+#if (PAD_LIST  || CC_NV_UndefineSpaceSpecial)
+    TPMA_CC_INITIALIZER(0x011f, 0, 1, 0, 0, 2, 0, 0, 0),
+#endif
+#if (PAD_LIST  || CC_EvictControl)
+    TPMA_CC_INITIALIZER(0x0120, 0, 1, 0, 0, 2, 0, 0, 0),
+#endif
+#if (PAD_LIST  || CC_HierarchyControl)
+    TPMA_CC_INITIALIZER(0x0121, 0, 1, 1, 0, 1, 0, 0, 0),
+#endif
+#if (PAD_LIST  || CC_NV_UndefineSpace)
+    TPMA_CC_INITIALIZER(0x0122, 0, 1, 0, 0, 2, 0, 0, 0),
+#endif
+#if (PAD_LIST )
+    TPMA_CC_INITIALIZER(0x0123, 0, 0, 0, 0, 0, 0, 0, 0),
+#endif
+#if (PAD_LIST  || CC_ChangeEPS)
+    TPMA_CC_INITIALIZER(0x0124, 0, 1, 1, 0, 1, 0, 0, 0),
+#endif
+#if (PAD_LIST  || CC_ChangePPS)
+    TPMA_CC_INITIALIZER(0x0125, 0, 1, 1, 0, 1, 0, 0, 0),
+#endif
+#if (PAD_LIST  || CC_Clear)
+    TPMA_CC_INITIALIZER(0x0126, 0, 1, 1, 0, 1, 0, 0, 0),
+#endif
+#if (PAD_LIST  || CC_ClearControl)
+    TPMA_CC_INITIALIZER(0x0127, 0, 1, 0, 0, 1, 0, 0, 0),
+#endif
+#if (PAD_LIST  || CC_ClockSet)
+    TPMA_CC_INITIALIZER(0x0128, 0, 1, 0, 0, 1, 0, 0, 0),
+#endif
+#if (PAD_LIST  || CC_HierarchyChangeAuth)
+    TPMA_CC_INITIALIZER(0x0129, 0, 1, 0, 0, 1, 0, 0, 0),
+#endif
+#if (PAD_LIST  || CC_NV_DefineSpace)
+    TPMA_CC_INITIALIZER(0x012a, 0, 1, 0, 0, 1, 0, 0, 0),
+#endif
+#if (PAD_LIST  || CC_PCR_Allocate)
+    TPMA_CC_INITIALIZER(0x012b, 0, 1, 0, 0, 1, 0, 0, 0),
+#endif
+#if (PAD_LIST  || CC_PCR_SetAuthPolicy)
+    TPMA_CC_INITIALIZER(0x012c, 0, 1, 0, 0, 1, 0, 0, 0),
+#endif
+#if (PAD_LIST  || CC_PP_Commands)
+    TPMA_CC_INITIALIZER(0x012d, 0, 1, 0, 0, 1, 0, 0, 0),
+#endif
+#if (PAD_LIST  || CC_SetPrimaryPolicy)
+    TPMA_CC_INITIALIZER(0x012e, 0, 1, 0, 0, 1, 0, 0, 0),
+#endif
+#if (PAD_LIST  || CC_FieldUpgradeStart)
+    TPMA_CC_INITIALIZER(0x012f, 0, 0, 0, 0, 2, 0, 0, 0),
+#endif
+#if (PAD_LIST  || CC_ClockRateAdjust)
+    TPMA_CC_INITIALIZER(0x0130, 0, 0, 0, 0, 1, 0, 0, 0),
+#endif
+#if (PAD_LIST  || CC_CreatePrimary)
+    TPMA_CC_INITIALIZER(0x0131, 0, 0, 0, 0, 1, 1, 0, 0),
+#endif
+#if (PAD_LIST  || CC_NV_GlobalWriteLock)
+    TPMA_CC_INITIALIZER(0x0132, 0, 1, 0, 0, 1, 0, 0, 0),
+#endif
+#if (PAD_LIST  || CC_GetCommandAuditDigest)
+    TPMA_CC_INITIALIZER(0x0133, 0, 1, 0, 0, 2, 0, 0, 0),
+#endif
+#if (PAD_LIST  || CC_NV_Increment)
+    TPMA_CC_INITIALIZER(0x0134, 0, 1, 0, 0, 2, 0, 0, 0),
+#endif
+#if (PAD_LIST  || CC_NV_SetBits)
+    TPMA_CC_INITIALIZER(0x0135, 0, 1, 0, 0, 2, 0, 0, 0),
+#endif
+#if (PAD_LIST  || CC_NV_Extend)
+    TPMA_CC_INITIALIZER(0x0136, 0, 1, 0, 0, 2, 0, 0, 0),
+#endif
+#if (PAD_LIST  || CC_NV_Write)
+    TPMA_CC_INITIALIZER(0x0137, 0, 1, 0, 0, 2, 0, 0, 0),
+#endif
+#if (PAD_LIST  || CC_NV_WriteLock)
+    TPMA_CC_INITIALIZER(0x0138, 0, 1, 0, 0, 2, 0, 0, 0),
+#endif
+#if (PAD_LIST  || CC_DictionaryAttackLockReset)
+    TPMA_CC_INITIALIZER(0x0139, 0, 1, 0, 0, 1, 0, 0, 0),
+#endif
+#if (PAD_LIST  || CC_DictionaryAttackParameters)
+    TPMA_CC_INITIALIZER(0x013a, 0, 1, 0, 0, 1, 0, 0, 0),
+#endif
+#if (PAD_LIST  || CC_NV_ChangeAuth)
+    TPMA_CC_INITIALIZER(0x013b, 0, 1, 0, 0, 1, 0, 0, 0),
+#endif
+#if (PAD_LIST  || CC_PCR_Event)
+    TPMA_CC_INITIALIZER(0x013c, 0, 1, 0, 0, 1, 0, 0, 0),
+#endif
+#if (PAD_LIST  || CC_PCR_Reset)
+    TPMA_CC_INITIALIZER(0x013d, 0, 1, 0, 0, 1, 0, 0, 0),
+#endif
+#if (PAD_LIST  || CC_SequenceComplete)
+    TPMA_CC_INITIALIZER(0x013e, 0, 0, 0, 1, 1, 0, 0, 0),
+#endif
+#if (PAD_LIST  || CC_SetAlgorithmSet)
+    TPMA_CC_INITIALIZER(0x013f, 0, 1, 0, 0, 1, 0, 0, 0),
+#endif
+#if (PAD_LIST  || CC_SetCommandCodeAuditStatus)
+    TPMA_CC_INITIALIZER(0x0140, 0, 1, 0, 0, 1, 0, 0, 0),
+#endif
+#if (PAD_LIST  || CC_FieldUpgradeData)
+    TPMA_CC_INITIALIZER(0x0141, 0, 1, 0, 0, 0, 0, 0, 0),
+#endif
+#if (PAD_LIST  || CC_IncrementalSelfTest)
+    TPMA_CC_INITIALIZER(0x0142, 0, 1, 0, 0, 0, 0, 0, 0),
+#endif
+#if (PAD_LIST  || CC_SelfTest)
+    TPMA_CC_INITIALIZER(0x0143, 0, 1, 0, 0, 0, 0, 0, 0),
+#endif
+#if (PAD_LIST  || CC_Startup)
+    TPMA_CC_INITIALIZER(0x0144, 0, 1, 0, 0, 0, 0, 0, 0),
+#endif
+#if (PAD_LIST  || CC_Shutdown)
+    TPMA_CC_INITIALIZER(0x0145, 0, 1, 0, 0, 0, 0, 0, 0),
+#endif
+#if (PAD_LIST  || CC_StirRandom)
+    TPMA_CC_INITIALIZER(0x0146, 0, 1, 0, 0, 0, 0, 0, 0),
+#endif
+#if (PAD_LIST  || CC_ActivateCredential)
+    TPMA_CC_INITIALIZER(0x0147, 0, 0, 0, 0, 2, 0, 0, 0),
+#endif
+#if (PAD_LIST  || CC_Certify)
+    TPMA_CC_INITIALIZER(0x0148, 0, 0, 0, 0, 2, 0, 0, 0),
+#endif
+#if (PAD_LIST  || CC_PolicyNV)
+    TPMA_CC_INITIALIZER(0x0149, 0, 0, 0, 0, 3, 0, 0, 0),
+#endif
+#if (PAD_LIST  || CC_CertifyCreation)
+    TPMA_CC_INITIALIZER(0x014a, 0, 0, 0, 0, 2, 0, 0, 0),
+#endif
+#if (PAD_LIST  || CC_Duplicate)
+    TPMA_CC_INITIALIZER(0x014b, 0, 0, 0, 0, 2, 0, 0, 0),
+#endif
+#if (PAD_LIST  || CC_GetTime)
+    TPMA_CC_INITIALIZER(0x014c, 0, 0, 0, 0, 2, 0, 0, 0),
+#endif
+#if (PAD_LIST  || CC_GetSessionAuditDigest)
+    TPMA_CC_INITIALIZER(0x014d, 0, 0, 0, 0, 3, 0, 0, 0),
+#endif
+#if (PAD_LIST  || CC_NV_Read)
+    TPMA_CC_INITIALIZER(0x014e, 0, 0, 0, 0, 2, 0, 0, 0),
+#endif
+#if (PAD_LIST  || CC_NV_ReadLock)
+    TPMA_CC_INITIALIZER(0x014f, 0, 1, 0, 0, 2, 0, 0, 0),
+#endif
+#if (PAD_LIST  || CC_ObjectChangeAuth)
+    TPMA_CC_INITIALIZER(0x0150, 0, 0, 0, 0, 2, 0, 0, 0),
+#endif
+#if (PAD_LIST  || CC_PolicySecret)
+    TPMA_CC_INITIALIZER(0x0151, 0, 0, 0, 0, 2, 0, 0, 0),
+#endif
+#if (PAD_LIST  || CC_Rewrap)
+    TPMA_CC_INITIALIZER(0x0152, 0, 0, 0, 0, 2, 0, 0, 0),
+#endif
+#if (PAD_LIST  || CC_Create)
+    TPMA_CC_INITIALIZER(0x0153, 0, 0, 0, 0, 1, 0, 0, 0),
+#endif
+#if (PAD_LIST  || CC_ECDH_ZGen)
+    TPMA_CC_INITIALIZER(0x0154, 0, 0, 0, 0, 1, 0, 0, 0),
+#endif
+#if (PAD_LIST  || (CC_HMAC || CC_MAC))
+    TPMA_CC_INITIALIZER(0x0155, 0, 0, 0, 0, 1, 0, 0, 0),
+#endif
+#if (PAD_LIST  || CC_Import)
+    TPMA_CC_INITIALIZER(0x0156, 0, 0, 0, 0, 1, 0, 0, 0),
+#endif
+#if (PAD_LIST  || CC_Load)
+    TPMA_CC_INITIALIZER(0x0157, 0, 0, 0, 0, 1, 1, 0, 0),
+#endif
+#if (PAD_LIST  || CC_Quote)
+    TPMA_CC_INITIALIZER(0x0158, 0, 0, 0, 0, 1, 0, 0, 0),
+#endif
+#if (PAD_LIST  || CC_RSA_Decrypt)
+    TPMA_CC_INITIALIZER(0x0159, 0, 0, 0, 0, 1, 0, 0, 0),
+#endif
+#if (PAD_LIST )
+    TPMA_CC_INITIALIZER(0x015a, 0, 0, 0, 0, 0, 0, 0, 0),
+#endif
+#if (PAD_LIST  || (CC_HMAC_Start || CC_MAC_Start))
+    TPMA_CC_INITIALIZER(0x015b, 0, 0, 0, 0, 1, 1, 0, 0),
+#endif
+#if (PAD_LIST  || CC_SequenceUpdate)
+    TPMA_CC_INITIALIZER(0x015c, 0, 0, 0, 0, 1, 0, 0, 0),
+#endif
+#if (PAD_LIST  || CC_Sign)
+    TPMA_CC_INITIALIZER(0x015d, 0, 0, 0, 0, 1, 0, 0, 0),
+#endif
+#if (PAD_LIST  || CC_Unseal)
+    TPMA_CC_INITIALIZER(0x015e, 0, 0, 0, 0, 1, 0, 0, 0),
+#endif
+#if (PAD_LIST )
+    TPMA_CC_INITIALIZER(0x015f, 0, 0, 0, 0, 0, 0, 0, 0),
+#endif
+#if (PAD_LIST  || CC_PolicySigned)
+    TPMA_CC_INITIALIZER(0x0160, 0, 0, 0, 0, 2, 0, 0, 0),
+#endif
+#if (PAD_LIST  || CC_ContextLoad)
+    TPMA_CC_INITIALIZER(0x0161, 0, 0, 0, 0, 0, 1, 0, 0),
+#endif
+#if (PAD_LIST  || CC_ContextSave)
+    TPMA_CC_INITIALIZER(0x0162, 0, 0, 0, 0, 1, 0, 0, 0),
+#endif
+#if (PAD_LIST  || CC_ECDH_KeyGen)
+    TPMA_CC_INITIALIZER(0x0163, 0, 0, 0, 0, 1, 0, 0, 0),
+#endif
+#if (PAD_LIST  || CC_EncryptDecrypt)
+    TPMA_CC_INITIALIZER(0x0164, 0, 0, 0, 0, 1, 0, 0, 0),
+#endif
+#if (PAD_LIST  || CC_FlushContext)
+    TPMA_CC_INITIALIZER(0x0165, 0, 0, 0, 0, 0, 0, 0, 0),
+#endif
+#if (PAD_LIST )
+    TPMA_CC_INITIALIZER(0x0166, 0, 0, 0, 0, 0, 0, 0, 0),
+#endif
+#if (PAD_LIST  || CC_LoadExternal)
+    TPMA_CC_INITIALIZER(0x0167, 0, 0, 0, 0, 0, 1, 0, 0),
+#endif
+#if (PAD_LIST  || CC_MakeCredential)
+    TPMA_CC_INITIALIZER(0x0168, 0, 0, 0, 0, 1, 0, 0, 0),
+#endif
+#if (PAD_LIST  || CC_NV_ReadPublic)
+    TPMA_CC_INITIALIZER(0x0169, 0, 0, 0, 0, 1, 0, 0, 0),
+#endif
+#if (PAD_LIST  || CC_PolicyAuthorize)
+    TPMA_CC_INITIALIZER(0x016a, 0, 0, 0, 0, 1, 0, 0, 0),
+#endif
+#if (PAD_LIST  || CC_PolicyAuthValue)
+    TPMA_CC_INITIALIZER(0x016b, 0, 0, 0, 0, 1, 0, 0, 0),
+#endif
+#if (PAD_LIST  || CC_PolicyCommandCode)
+    TPMA_CC_INITIALIZER(0x016c, 0, 0, 0, 0, 1, 0, 0, 0),
+#endif
+#if (PAD_LIST  || CC_PolicyCounterTimer)
+    TPMA_CC_INITIALIZER(0x016d, 0, 0, 0, 0, 1, 0, 0, 0),
+#endif
+#if (PAD_LIST  || CC_PolicyCpHash)
+    TPMA_CC_INITIALIZER(0x016e, 0, 0, 0, 0, 1, 0, 0, 0),
+#endif
+#if (PAD_LIST  || CC_PolicyLocality)
+    TPMA_CC_INITIALIZER(0x016f, 0, 0, 0, 0, 1, 0, 0, 0),
+#endif
+#if (PAD_LIST  || CC_PolicyNameHash)
+    TPMA_CC_INITIALIZER(0x0170, 0, 0, 0, 0, 1, 0, 0, 0),
+#endif
+#if (PAD_LIST  || CC_PolicyOR)
+    TPMA_CC_INITIALIZER(0x0171, 0, 0, 0, 0, 1, 0, 0, 0),
+#endif
+#if (PAD_LIST  || CC_PolicyTicket)
+    TPMA_CC_INITIALIZER(0x0172, 0, 0, 0, 0, 1, 0, 0, 0),
+#endif
+#if (PAD_LIST  || CC_ReadPublic)
+    TPMA_CC_INITIALIZER(0x0173, 0, 0, 0, 0, 1, 0, 0, 0),
+#endif
+#if (PAD_LIST  || CC_RSA_Encrypt)
+    TPMA_CC_INITIALIZER(0x0174, 0, 0, 0, 0, 1, 0, 0, 0),
+#endif
+#if (PAD_LIST )
+    TPMA_CC_INITIALIZER(0x0175, 0, 0, 0, 0, 0, 0, 0, 0),
+#endif
+#if (PAD_LIST  || CC_StartAuthSession)
+    TPMA_CC_INITIALIZER(0x0176, 0, 0, 0, 0, 2, 1, 0, 0),
+#endif
+#if (PAD_LIST  || CC_VerifySignature)
+    TPMA_CC_INITIALIZER(0x0177, 0, 0, 0, 0, 1, 0, 0, 0),
+#endif
+#if (PAD_LIST  || CC_ECC_Parameters)
+    TPMA_CC_INITIALIZER(0x0178, 0, 0, 0, 0, 0, 0, 0, 0),
+#endif
+#if (PAD_LIST  || CC_FirmwareRead)
+    TPMA_CC_INITIALIZER(0x0179, 0, 0, 0, 0, 0, 0, 0, 0),
+#endif
+#if (PAD_LIST  || CC_GetCapability)
+    TPMA_CC_INITIALIZER(0x017a, 0, 0, 0, 0, 0, 0, 0, 0),
+#endif
+#if (PAD_LIST  || CC_GetRandom)
+    TPMA_CC_INITIALIZER(0x017b, 0, 0, 0, 0, 0, 0, 0, 0),
+#endif
+#if (PAD_LIST  || CC_GetTestResult)
+    TPMA_CC_INITIALIZER(0x017c, 0, 0, 0, 0, 0, 0, 0, 0),
+#endif
+#if (PAD_LIST  || CC_Hash)
+    TPMA_CC_INITIALIZER(0x017d, 0, 0, 0, 0, 0, 0, 0, 0),
+#endif
+#if (PAD_LIST  || CC_PCR_Read)
+    TPMA_CC_INITIALIZER(0x017e, 0, 0, 0, 0, 0, 0, 0, 0),
+#endif
+#if (PAD_LIST  || CC_PolicyPCR)
+    TPMA_CC_INITIALIZER(0x017f, 0, 0, 0, 0, 1, 0, 0, 0),
+#endif
+#if (PAD_LIST  || CC_PolicyRestart)
+    TPMA_CC_INITIALIZER(0x0180, 0, 0, 0, 0, 1, 0, 0, 0),
+#endif
+#if (PAD_LIST  || CC_ReadClock)
+    TPMA_CC_INITIALIZER(0x0181, 0, 0, 0, 0, 0, 0, 0, 0),
+#endif
+#if (PAD_LIST  || CC_PCR_Extend)
+    TPMA_CC_INITIALIZER(0x0182, 0, 1, 0, 0, 1, 0, 0, 0),
+#endif
+#if (PAD_LIST  || CC_PCR_SetAuthValue)
+    TPMA_CC_INITIALIZER(0x0183, 0, 0, 0, 0, 1, 0, 0, 0),
+#endif
+#if (PAD_LIST  || CC_NV_Certify)
+    TPMA_CC_INITIALIZER(0x0184, 0, 0, 0, 0, 3, 0, 0, 0),
+#endif
+#if (PAD_LIST  || CC_EventSequenceComplete)
+    TPMA_CC_INITIALIZER(0x0185, 0, 1, 0, 1, 2, 0, 0, 0),
+#endif
+#if (PAD_LIST  || CC_HashSequenceStart)
+    TPMA_CC_INITIALIZER(0x0186, 0, 0, 0, 0, 0, 1, 0, 0),
+#endif
+#if (PAD_LIST  || CC_PolicyPhysicalPresence)
+    TPMA_CC_INITIALIZER(0x0187, 0, 0, 0, 0, 1, 0, 0, 0),
+#endif
+#if (PAD_LIST  || CC_PolicyDuplicationSelect)
+    TPMA_CC_INITIALIZER(0x0188, 0, 0, 0, 0, 1, 0, 0, 0),
+#endif
+#if (PAD_LIST  || CC_PolicyGetDigest)
+    TPMA_CC_INITIALIZER(0x0189, 0, 0, 0, 0, 1, 0, 0, 0),
+#endif
+#if (PAD_LIST  || CC_TestParms)
+    TPMA_CC_INITIALIZER(0x018a, 0, 0, 0, 0, 0, 0, 0, 0),
+#endif
+#if (PAD_LIST  || CC_Commit)
+    TPMA_CC_INITIALIZER(0x018b, 0, 0, 0, 0, 1, 0, 0, 0),
+#endif
+#if (PAD_LIST  || CC_PolicyPassword)
+    TPMA_CC_INITIALIZER(0x018c, 0, 0, 0, 0, 1, 0, 0, 0),
+#endif
+#if (PAD_LIST  || CC_ZGen_2Phase)
+    TPMA_CC_INITIALIZER(0x018d, 0, 0, 0, 0, 1, 0, 0, 0),
+#endif
+#if (PAD_LIST  || CC_EC_Ephemeral)
+    TPMA_CC_INITIALIZER(0x018e, 0, 0, 0, 0, 0, 0, 0, 0),
+#endif
+#if (PAD_LIST  || CC_PolicyNvWritten)
+    TPMA_CC_INITIALIZER(0x018f, 0, 0, 0, 0, 1, 0, 0, 0),
+#endif
+#if (PAD_LIST  || CC_PolicyTemplate)
+    TPMA_CC_INITIALIZER(0x0190, 0, 0, 0, 0, 1, 0, 0, 0),
+#endif
+#if (PAD_LIST  || CC_CreateLoaded)
+    TPMA_CC_INITIALIZER(0x0191, 0, 0, 0, 0, 1, 1, 0, 0),
+#endif
+#if (PAD_LIST  || CC_PolicyAuthorizeNV)
+    TPMA_CC_INITIALIZER(0x0192, 0, 0, 0, 0, 3, 0, 0, 0),
+#endif
+#if (PAD_LIST  || CC_EncryptDecrypt2)
+    TPMA_CC_INITIALIZER(0x0193, 0, 0, 0, 0, 1, 0, 0, 0),
+#endif
+#if (PAD_LIST  || CC_AC_GetCapability)
+    TPMA_CC_INITIALIZER(0x0194, 0, 0, 0, 0, 1, 0, 0, 0),
+#endif
+#if (PAD_LIST  || CC_AC_Send)
+    TPMA_CC_INITIALIZER(0x0195, 0, 0, 0, 0, 3, 0, 0, 0),
+#endif
+#if (PAD_LIST  || CC_Policy_AC_SendSelect)
+    TPMA_CC_INITIALIZER(0x0196, 0, 0, 0, 0, 1, 0, 0, 0),
+#endif
+#if (PAD_LIST || CC_CertifyX509)
+    TPMA_CC_INITIALIZER(0x0197, 0, 0, 0, 0, 2, 0, 0, 0),
+#endif
+#if (PAD_LIST || CC_ACT_SetTimeout)
+    TPMA_CC_INITIALIZER(0x0198, 0, 0, 0, 0, 1, 0, 0, 0),
+#endif
+#if (PAD_LIST || CC_ECC_Encrypt)
+    TPMA_CC_INITIALIZER(0x0199, 0, 0, 0, 0, 1, 0, 0, 0),
+#endif
+#if (PAD_LIST || CC_ECC_Decrypt)
+    TPMA_CC_INITIALIZER(0x019A, 0, 0, 0, 0, 1, 0, 0, 0),
+#endif
+#if (PAD_LIST  || CC_Vendor_TCG_Test)
+    TPMA_CC_INITIALIZER(0x0000, 0, 0, 0, 0, 0, 0, 1, 0),
+#endif
+
+#ifdef TPM_NUVOTON
+    
+#if (PAD_LIST || CC_NTC2_PreConfig)
+    TPMA_CC_INITIALIZER(0x0211, 0, 1, 0, 0, 0, 0, 1, 0),     // TPM_CC_NTC2_PreConfig
+#endif
+#if (PAD_LIST || CC_NTC2_LockPreConfig)
+    TPMA_CC_INITIALIZER(0x0212, 0, 1, 0, 0, 0, 0, 1, 0),     // TPM_CC_NTC2_LockPreConfig
+#endif
+#if (PAD_LIST || CC_NTC2_GetConfig)
+    TPMA_CC_INITIALIZER(0x0213, 0, 1, 0, 0, 0, 0, 1, 0),     // TPM_CC_NTC2_GetConfig
+#endif
+
+#endif	/* TPM_NUVOTON */
+
+    TPMA_ZERO_INITIALIZER()
+};
+
+/* This is the command code attribute structure. */
+
+const COMMAND_ATTRIBUTES    s_commandAttributes [] = {
+#if (PAD_LIST  || CC_NV_UndefineSpaceSpecial)
+    (COMMAND_ATTRIBUTES)(CC_NV_UndefineSpaceSpecial     *  // 0x011f
+			 (IS_IMPLEMENTED+HANDLE_1_ADMIN+HANDLE_2_USER+PP_COMMAND)),
+#endif
+#if (PAD_LIST  || CC_EvictControl)
+    (COMMAND_ATTRIBUTES)(CC_EvictControl                *  // 0x0120
+			 (IS_IMPLEMENTED+HANDLE_1_USER+PP_COMMAND)),
+#endif
+#if (PAD_LIST  || CC_HierarchyControl)
+    (COMMAND_ATTRIBUTES)(CC_HierarchyControl            *  // 0x0121
+			 (IS_IMPLEMENTED+HANDLE_1_USER+PP_COMMAND)),
+#endif
+#if (PAD_LIST  || CC_NV_UndefineSpace)
+    (COMMAND_ATTRIBUTES)(CC_NV_UndefineSpace            *  // 0x0122
+			 (IS_IMPLEMENTED+HANDLE_1_USER+PP_COMMAND)),
+#endif
+#if (PAD_LIST )
+    (COMMAND_ATTRIBUTES)(0),                               // 0x0123
+#endif
+#if (PAD_LIST  || CC_ChangeEPS)
+    (COMMAND_ATTRIBUTES)(CC_ChangeEPS                   *  // 0x0124
+			 (IS_IMPLEMENTED+HANDLE_1_USER+PP_COMMAND)),
+#endif
+#if (PAD_LIST  || CC_ChangePPS)
+    (COMMAND_ATTRIBUTES)(CC_ChangePPS                   *  // 0x0125
+			 (IS_IMPLEMENTED+HANDLE_1_USER+PP_COMMAND)),
+#endif
+#if (PAD_LIST  || CC_Clear)
+    (COMMAND_ATTRIBUTES)(CC_Clear                       *  // 0x0126
+			 (IS_IMPLEMENTED+HANDLE_1_USER+PP_COMMAND)),
+#endif
+#if (PAD_LIST  || CC_ClearControl)
+    (COMMAND_ATTRIBUTES)(CC_ClearControl                *  // 0x0127
+			 (IS_IMPLEMENTED+HANDLE_1_USER+PP_COMMAND)),
+#endif
+#if (PAD_LIST  || CC_ClockSet)
+    (COMMAND_ATTRIBUTES)(CC_ClockSet                    *  // 0x0128
+			 (IS_IMPLEMENTED+HANDLE_1_USER+PP_COMMAND)),
+#endif
+#if (PAD_LIST  || CC_HierarchyChangeAuth)
+    (COMMAND_ATTRIBUTES)(CC_HierarchyChangeAuth         *  // 0x0129
+			 (IS_IMPLEMENTED+DECRYPT_2+HANDLE_1_USER+PP_COMMAND)),
+#endif
+#if (PAD_LIST  || CC_NV_DefineSpace)
+    (COMMAND_ATTRIBUTES)(CC_NV_DefineSpace              *  // 0x012a
+			 (IS_IMPLEMENTED+DECRYPT_2+HANDLE_1_USER+PP_COMMAND)),
+#endif
+#if (PAD_LIST  || CC_PCR_Allocate)
+    (COMMAND_ATTRIBUTES)(CC_PCR_Allocate                *  // 0x012b
+			 (IS_IMPLEMENTED+HANDLE_1_USER+PP_COMMAND)),
+#endif
+#if (PAD_LIST  || CC_PCR_SetAuthPolicy)
+    (COMMAND_ATTRIBUTES)(CC_PCR_SetAuthPolicy           *  // 0x012c
+			 (IS_IMPLEMENTED+DECRYPT_2+HANDLE_1_USER+PP_COMMAND)),
+#endif
+#if (PAD_LIST  || CC_PP_Commands)
+    (COMMAND_ATTRIBUTES)(CC_PP_Commands                 *  // 0x012d
+			 (IS_IMPLEMENTED+HANDLE_1_USER+PP_REQUIRED)),
+#endif
+#if (PAD_LIST  || CC_SetPrimaryPolicy)
+    (COMMAND_ATTRIBUTES)(CC_SetPrimaryPolicy            *  // 0x012e
+			 (IS_IMPLEMENTED+DECRYPT_2+HANDLE_1_USER+PP_COMMAND)),
+#endif
+#if (PAD_LIST  || CC_FieldUpgradeStart)
+    (COMMAND_ATTRIBUTES)(CC_FieldUpgradeStart           *  // 0x012f
+			 (IS_IMPLEMENTED+DECRYPT_2+HANDLE_1_ADMIN+PP_COMMAND)),
+#endif
+#if (PAD_LIST  || CC_ClockRateAdjust)
+    (COMMAND_ATTRIBUTES)(CC_ClockRateAdjust             *  // 0x0130
+			 (IS_IMPLEMENTED+HANDLE_1_USER+PP_COMMAND)),
+#endif
+#if (PAD_LIST  || CC_CreatePrimary)
+    (COMMAND_ATTRIBUTES)(CC_CreatePrimary               *  // 0x0131
+			 (IS_IMPLEMENTED+DECRYPT_2+HANDLE_1_USER+PP_COMMAND+ENCRYPT_2+R_HANDLE)),
+#endif
+#if (PAD_LIST  || CC_NV_GlobalWriteLock)
+    (COMMAND_ATTRIBUTES)(CC_NV_GlobalWriteLock          *  // 0x0132
+			 (IS_IMPLEMENTED+HANDLE_1_USER+PP_COMMAND)),
+#endif
+#if (PAD_LIST  || CC_GetCommandAuditDigest)
+    (COMMAND_ATTRIBUTES)(CC_GetCommandAuditDigest       *  // 0x0133
+			 (IS_IMPLEMENTED+DECRYPT_2+HANDLE_1_USER+HANDLE_2_USER+ENCRYPT_2)),
+#endif
+#if (PAD_LIST  || CC_NV_Increment)
+    (COMMAND_ATTRIBUTES)(CC_NV_Increment                *  // 0x0134
+			 (IS_IMPLEMENTED+HANDLE_1_USER)),
+#endif
+#if (PAD_LIST  || CC_NV_SetBits)
+    (COMMAND_ATTRIBUTES)(CC_NV_SetBits                  *  // 0x0135
+			 (IS_IMPLEMENTED+HANDLE_1_USER)),
+#endif
+#if (PAD_LIST  || CC_NV_Extend)
+    (COMMAND_ATTRIBUTES)(CC_NV_Extend                   *  // 0x0136
+			 (IS_IMPLEMENTED+DECRYPT_2+HANDLE_1_USER)),
+#endif
+#if (PAD_LIST  || CC_NV_Write)
+    (COMMAND_ATTRIBUTES)(CC_NV_Write                    *  // 0x0137
+			 (IS_IMPLEMENTED+DECRYPT_2+HANDLE_1_USER)),
+#endif
+#if (PAD_LIST  || CC_NV_WriteLock)
+    (COMMAND_ATTRIBUTES)(CC_NV_WriteLock                *  // 0x0138
+			 (IS_IMPLEMENTED+HANDLE_1_USER)),
+#endif
+#if (PAD_LIST  || CC_DictionaryAttackLockReset)
+    (COMMAND_ATTRIBUTES)(CC_DictionaryAttackLockReset   *  // 0x0139
+			 (IS_IMPLEMENTED+HANDLE_1_USER)),
+#endif
+#if (PAD_LIST  || CC_DictionaryAttackParameters)
+    (COMMAND_ATTRIBUTES)(CC_DictionaryAttackParameters  *  // 0x013a
+			 (IS_IMPLEMENTED+HANDLE_1_USER)),
+#endif
+#if (PAD_LIST  || CC_NV_ChangeAuth)
+    (COMMAND_ATTRIBUTES)(CC_NV_ChangeAuth               *  // 0x013b
+			 (IS_IMPLEMENTED+DECRYPT_2+HANDLE_1_ADMIN)),
+#endif
+#if (PAD_LIST  || CC_PCR_Event)
+    (COMMAND_ATTRIBUTES)(CC_PCR_Event                   *  // 0x013c
+			 (IS_IMPLEMENTED+DECRYPT_2+HANDLE_1_USER)),
+#endif
+#if (PAD_LIST  || CC_PCR_Reset)
+    (COMMAND_ATTRIBUTES)(CC_PCR_Reset                   *  // 0x013d
+			 (IS_IMPLEMENTED+HANDLE_1_USER)),
+#endif
+#if (PAD_LIST  || CC_SequenceComplete)
+    (COMMAND_ATTRIBUTES)(CC_SequenceComplete            *  // 0x013e
+			 (IS_IMPLEMENTED+DECRYPT_2+HANDLE_1_USER+ENCRYPT_2)),
+#endif
+#if (PAD_LIST  || CC_SetAlgorithmSet)
+    (COMMAND_ATTRIBUTES)(CC_SetAlgorithmSet             *  // 0x013f
+			 (IS_IMPLEMENTED+HANDLE_1_USER)),
+#endif
+#if (PAD_LIST  || CC_SetCommandCodeAuditStatus)
+    (COMMAND_ATTRIBUTES)(CC_SetCommandCodeAuditStatus   *  // 0x0140
+			 (IS_IMPLEMENTED+HANDLE_1_USER+PP_COMMAND)),
+#endif
+#if (PAD_LIST  || CC_FieldUpgradeData)
+    (COMMAND_ATTRIBUTES)(CC_FieldUpgradeData            *  // 0x0141
+			 (IS_IMPLEMENTED+DECRYPT_2)),
+#endif
+#if (PAD_LIST  || CC_IncrementalSelfTest)
+    (COMMAND_ATTRIBUTES)(CC_IncrementalSelfTest         *  // 0x0142
+			 (IS_IMPLEMENTED)),
+#endif
+#if (PAD_LIST  || CC_SelfTest)
+    (COMMAND_ATTRIBUTES)(CC_SelfTest                    *  // 0x0143
+			 (IS_IMPLEMENTED)),
+#endif
+#if (PAD_LIST  || CC_Startup)
+    (COMMAND_ATTRIBUTES)(CC_Startup                     *  // 0x0144
+			 (IS_IMPLEMENTED+NO_SESSIONS)),
+#endif
+#if (PAD_LIST  || CC_Shutdown)
+    (COMMAND_ATTRIBUTES)(CC_Shutdown                    *  // 0x0145
+			 (IS_IMPLEMENTED)),
+#endif
+#if (PAD_LIST  || CC_StirRandom)
+    (COMMAND_ATTRIBUTES)(CC_StirRandom                  *  // 0x0146
+			 (IS_IMPLEMENTED+DECRYPT_2)),
+#endif
+#if (PAD_LIST  || CC_ActivateCredential)
+    (COMMAND_ATTRIBUTES)(CC_ActivateCredential          *  // 0x0147
+			 (IS_IMPLEMENTED+DECRYPT_2+HANDLE_1_ADMIN+HANDLE_2_USER+ENCRYPT_2)),
+#endif
+#if (PAD_LIST  || CC_Certify)
+    (COMMAND_ATTRIBUTES)(CC_Certify                     *  // 0x0148
+			 (IS_IMPLEMENTED+DECRYPT_2+HANDLE_1_ADMIN+HANDLE_2_USER+ENCRYPT_2)),
+#endif
+#if (PAD_LIST  || CC_PolicyNV)
+    (COMMAND_ATTRIBUTES)(CC_PolicyNV                    *  // 0x0149
+			 (IS_IMPLEMENTED+DECRYPT_2+HANDLE_1_USER+ALLOW_TRIAL)),
+#endif
+#if (PAD_LIST  || CC_CertifyCreation)
+    (COMMAND_ATTRIBUTES)(CC_CertifyCreation             *  // 0x014a
+			 (IS_IMPLEMENTED+DECRYPT_2+HANDLE_1_USER+ENCRYPT_2)),
+#endif
+#if (PAD_LIST  || CC_Duplicate)
+    (COMMAND_ATTRIBUTES)(CC_Duplicate                   *  // 0x014b
+			 (IS_IMPLEMENTED+DECRYPT_2+HANDLE_1_DUP+ENCRYPT_2)),
+#endif
+#if (PAD_LIST  || CC_GetTime)
+    (COMMAND_ATTRIBUTES)(CC_GetTime                     *  // 0x014c
+			 (IS_IMPLEMENTED+DECRYPT_2+HANDLE_1_USER+HANDLE_2_USER+ENCRYPT_2)),
+#endif
+#if (PAD_LIST  || CC_GetSessionAuditDigest)
+    (COMMAND_ATTRIBUTES)(CC_GetSessionAuditDigest       *  // 0x014d
+			 (IS_IMPLEMENTED+DECRYPT_2+HANDLE_1_USER+HANDLE_2_USER+ENCRYPT_2)),
+#endif
+#if (PAD_LIST  || CC_NV_Read)
+    (COMMAND_ATTRIBUTES)(CC_NV_Read                     *  // 0x014e
+			 (IS_IMPLEMENTED+HANDLE_1_USER+ENCRYPT_2)),
+#endif
+#if (PAD_LIST  || CC_NV_ReadLock)
+    (COMMAND_ATTRIBUTES)(CC_NV_ReadLock                 *  // 0x014f
+			 (IS_IMPLEMENTED+HANDLE_1_USER)),
+#endif
+#if (PAD_LIST  || CC_ObjectChangeAuth)
+    (COMMAND_ATTRIBUTES)(CC_ObjectChangeAuth            *  // 0x0150
+			 (IS_IMPLEMENTED+DECRYPT_2+HANDLE_1_ADMIN+ENCRYPT_2)),
+#endif
+#if (PAD_LIST  || CC_PolicySecret)
+    (COMMAND_ATTRIBUTES)(CC_PolicySecret                *  // 0x0151
+			 (IS_IMPLEMENTED+DECRYPT_2+HANDLE_1_USER+ALLOW_TRIAL+ENCRYPT_2)),
+#endif
+#if (PAD_LIST  || CC_Rewrap)
+    (COMMAND_ATTRIBUTES)(CC_Rewrap                      *  // 0x0152
+			 (IS_IMPLEMENTED+DECRYPT_2+HANDLE_1_USER+ENCRYPT_2)),
+#endif
+#if (PAD_LIST  || CC_Create)
+    (COMMAND_ATTRIBUTES)(CC_Create                      *  // 0x0153
+			 (IS_IMPLEMENTED+DECRYPT_2+HANDLE_1_USER+ENCRYPT_2)),
+#endif
+#if (PAD_LIST  || CC_ECDH_ZGen)
+    (COMMAND_ATTRIBUTES)(CC_ECDH_ZGen                   *  // 0x0154
+			 (IS_IMPLEMENTED+DECRYPT_2+HANDLE_1_USER+ENCRYPT_2)),
+#endif
+#if (PAD_LIST  || (CC_HMAC || CC_MAC))
+    (COMMAND_ATTRIBUTES)((CC_HMAC || CC_MAC)            *  // 0x0155
+			 (IS_IMPLEMENTED+DECRYPT_2+HANDLE_1_USER+ENCRYPT_2)),
+#endif
+#if (PAD_LIST  || CC_Import)
+    (COMMAND_ATTRIBUTES)(CC_Import                      *  // 0x0156
+			 (IS_IMPLEMENTED+DECRYPT_2+HANDLE_1_USER+ENCRYPT_2)),
+#endif
+#if (PAD_LIST  || CC_Load)
+    (COMMAND_ATTRIBUTES)(CC_Load                        *  // 0x0157
+			 (IS_IMPLEMENTED+DECRYPT_2+HANDLE_1_USER+ENCRYPT_2+R_HANDLE)),
+#endif
+#if (PAD_LIST  || CC_Quote)
+    (COMMAND_ATTRIBUTES)(CC_Quote                       *  // 0x0158
+			 (IS_IMPLEMENTED+DECRYPT_2+HANDLE_1_USER+ENCRYPT_2)),
+#endif
+#if (PAD_LIST  || CC_RSA_Decrypt)
+    (COMMAND_ATTRIBUTES)(CC_RSA_Decrypt                 *  // 0x0159
+			 (IS_IMPLEMENTED+DECRYPT_2+HANDLE_1_USER+ENCRYPT_2)),
+#endif
+#if (PAD_LIST )
+    (COMMAND_ATTRIBUTES)(0),                               // 0x015a
+#endif
+#if (PAD_LIST  || (CC_HMAC_Start || CC_MAC_Start))
+    (COMMAND_ATTRIBUTES)((CC_HMAC_Start || CC_MAC_Start) *  // 0x015b
+			 (IS_IMPLEMENTED+DECRYPT_2+HANDLE_1_USER+R_HANDLE)),
+#endif
+#if (PAD_LIST  || CC_SequenceUpdate)
+    (COMMAND_ATTRIBUTES)(CC_SequenceUpdate              *  // 0x015c
+			 (IS_IMPLEMENTED+DECRYPT_2+HANDLE_1_USER)),
+#endif
+#if (PAD_LIST  || CC_Sign)
+    (COMMAND_ATTRIBUTES)(CC_Sign                        *  // 0x015d
+			 (IS_IMPLEMENTED+DECRYPT_2+HANDLE_1_USER)),
+#endif
+#if (PAD_LIST  || CC_Unseal)
+    (COMMAND_ATTRIBUTES)(CC_Unseal                      *  // 0x015e
+			 (IS_IMPLEMENTED+HANDLE_1_USER+ENCRYPT_2)),
+#endif
+#if (PAD_LIST )
+    (COMMAND_ATTRIBUTES)(0),                               // 0x015f
+#endif
+#if (PAD_LIST  || CC_PolicySigned)
+    (COMMAND_ATTRIBUTES)(CC_PolicySigned                *  // 0x0160
+			 (IS_IMPLEMENTED+DECRYPT_2+ALLOW_TRIAL+ENCRYPT_2)),
+#endif
+#if (PAD_LIST  || CC_ContextLoad)
+    (COMMAND_ATTRIBUTES)(CC_ContextLoad                 *  // 0x0161
+			 (IS_IMPLEMENTED+NO_SESSIONS+R_HANDLE)),
+#endif
+#if (PAD_LIST  || CC_ContextSave)
+    (COMMAND_ATTRIBUTES)(CC_ContextSave                 *  // 0x0162
+			 (IS_IMPLEMENTED+NO_SESSIONS)),
+#endif
+#if (PAD_LIST  || CC_ECDH_KeyGen)
+    (COMMAND_ATTRIBUTES)(CC_ECDH_KeyGen                 *  // 0x0163
+			 (IS_IMPLEMENTED+ENCRYPT_2)),
+#endif
+#if (PAD_LIST  || CC_EncryptDecrypt)
+    (COMMAND_ATTRIBUTES)(CC_EncryptDecrypt              *  // 0x0164
+			 (IS_IMPLEMENTED+HANDLE_1_USER+ENCRYPT_2)),
+#endif
+#if (PAD_LIST  || CC_FlushContext)
+    (COMMAND_ATTRIBUTES)(CC_FlushContext                *  // 0x0165
+			 (IS_IMPLEMENTED+NO_SESSIONS)),
+#endif
+#if (PAD_LIST )
+    (COMMAND_ATTRIBUTES)(0),                               // 0x0166
+#endif
+#if (PAD_LIST  || CC_LoadExternal)
+    (COMMAND_ATTRIBUTES)(CC_LoadExternal                *  // 0x0167
+			 (IS_IMPLEMENTED+DECRYPT_2+ENCRYPT_2+R_HANDLE)),
+#endif
+#if (PAD_LIST  || CC_MakeCredential)
+    (COMMAND_ATTRIBUTES)(CC_MakeCredential              *  // 0x0168
+			 (IS_IMPLEMENTED+DECRYPT_2+ENCRYPT_2)),
+#endif
+#if (PAD_LIST  || CC_NV_ReadPublic)
+    (COMMAND_ATTRIBUTES)(CC_NV_ReadPublic               *  // 0x0169
+			 (IS_IMPLEMENTED+ENCRYPT_2)),
+#endif
+#if (PAD_LIST  || CC_PolicyAuthorize)
+    (COMMAND_ATTRIBUTES)(CC_PolicyAuthorize             *  // 0x016a
+			 (IS_IMPLEMENTED+DECRYPT_2+ALLOW_TRIAL)),
+#endif
+#if (PAD_LIST  || CC_PolicyAuthValue)
+    (COMMAND_ATTRIBUTES)(CC_PolicyAuthValue             *  // 0x016b
+			 (IS_IMPLEMENTED+ALLOW_TRIAL)),
+#endif
+#if (PAD_LIST  || CC_PolicyCommandCode)
+    (COMMAND_ATTRIBUTES)(CC_PolicyCommandCode           *  // 0x016c
+			 (IS_IMPLEMENTED+ALLOW_TRIAL)),
+#endif
+#if (PAD_LIST  || CC_PolicyCounterTimer)
+    (COMMAND_ATTRIBUTES)(CC_PolicyCounterTimer          *  // 0x016d
+			 (IS_IMPLEMENTED+DECRYPT_2+ALLOW_TRIAL)),
+#endif
+#if (PAD_LIST  || CC_PolicyCpHash)
+    (COMMAND_ATTRIBUTES)(CC_PolicyCpHash                *  // 0x016e
+			 (IS_IMPLEMENTED+DECRYPT_2+ALLOW_TRIAL)),
+#endif
+#if (PAD_LIST  || CC_PolicyLocality)
+    (COMMAND_ATTRIBUTES)(CC_PolicyLocality              *  // 0x016f
+			 (IS_IMPLEMENTED+ALLOW_TRIAL)),
+#endif
+#if (PAD_LIST  || CC_PolicyNameHash)
+    (COMMAND_ATTRIBUTES)(CC_PolicyNameHash              *  // 0x0170
+			 (IS_IMPLEMENTED+DECRYPT_2+ALLOW_TRIAL)),
+#endif
+#if (PAD_LIST  || CC_PolicyOR)
+    (COMMAND_ATTRIBUTES)(CC_PolicyOR                    *  // 0x0171
+			 (IS_IMPLEMENTED+ALLOW_TRIAL)),
+#endif
+#if (PAD_LIST  || CC_PolicyTicket)
+    (COMMAND_ATTRIBUTES)(CC_PolicyTicket                *  // 0x0172
+			 (IS_IMPLEMENTED+DECRYPT_2+ALLOW_TRIAL)),
+#endif
+#if (PAD_LIST  || CC_ReadPublic)
+    (COMMAND_ATTRIBUTES)(CC_ReadPublic                  *  // 0x0173
+			 (IS_IMPLEMENTED+ENCRYPT_2)),
+#endif
+#if (PAD_LIST  || CC_RSA_Encrypt)
+    (COMMAND_ATTRIBUTES)(CC_RSA_Encrypt                 *  // 0x0174
+			 (IS_IMPLEMENTED+DECRYPT_2+ENCRYPT_2)),
+#endif
+#if (PAD_LIST )
+    (COMMAND_ATTRIBUTES)(0),                               // 0x0175
+#endif
+#if (PAD_LIST  || CC_StartAuthSession)
+    (COMMAND_ATTRIBUTES)(CC_StartAuthSession            *  // 0x0176
+			 (IS_IMPLEMENTED+DECRYPT_2+ENCRYPT_2+R_HANDLE)),
+#endif
+#if (PAD_LIST  || CC_VerifySignature)
+    (COMMAND_ATTRIBUTES)(CC_VerifySignature             *  // 0x0177
+			 (IS_IMPLEMENTED+DECRYPT_2)),
+#endif
+#if (PAD_LIST  || CC_ECC_Parameters)
+    (COMMAND_ATTRIBUTES)(CC_ECC_Parameters              *  // 0x0178
+			 (IS_IMPLEMENTED)),
+#endif
+#if (PAD_LIST  || CC_FirmwareRead)
+    (COMMAND_ATTRIBUTES)(CC_FirmwareRead                *  // 0x0179
+			 (IS_IMPLEMENTED+ENCRYPT_2)),
+#endif
+#if (PAD_LIST  || CC_GetCapability)
+    (COMMAND_ATTRIBUTES)(CC_GetCapability               *  // 0x017a
+			 (IS_IMPLEMENTED)),
+#endif
+#if (PAD_LIST  || CC_GetRandom)
+    (COMMAND_ATTRIBUTES)(CC_GetRandom                   *  // 0x017b
+			 (IS_IMPLEMENTED+ENCRYPT_2)),
+#endif
+#if (PAD_LIST  || CC_GetTestResult)
+    (COMMAND_ATTRIBUTES)(CC_GetTestResult               *  // 0x017c
+			 (IS_IMPLEMENTED+ENCRYPT_2)),
+#endif
+#if (PAD_LIST  || CC_Hash)
+    (COMMAND_ATTRIBUTES)(CC_Hash                        *  // 0x017d
+			 (IS_IMPLEMENTED+DECRYPT_2+ENCRYPT_2)),
+#endif
+#if (PAD_LIST  || CC_PCR_Read)
+    (COMMAND_ATTRIBUTES)(CC_PCR_Read                    *  // 0x017e
+			 (IS_IMPLEMENTED)),
+#endif
+#if (PAD_LIST  || CC_PolicyPCR)
+    (COMMAND_ATTRIBUTES)(CC_PolicyPCR                   *  // 0x017f
+			 (IS_IMPLEMENTED+DECRYPT_2+ALLOW_TRIAL)),
+#endif
+#if (PAD_LIST  || CC_PolicyRestart)
+    (COMMAND_ATTRIBUTES)(CC_PolicyRestart               *  // 0x0180
+			 (IS_IMPLEMENTED+ALLOW_TRIAL)),
+#endif
+#if (PAD_LIST  || CC_ReadClock)
+    (COMMAND_ATTRIBUTES)(CC_ReadClock                   *  // 0x0181
+			 (IS_IMPLEMENTED)),
+#endif
+#if (PAD_LIST  || CC_PCR_Extend)
+    (COMMAND_ATTRIBUTES)(CC_PCR_Extend                  *  // 0x0182
+			 (IS_IMPLEMENTED+HANDLE_1_USER)),
+#endif
+#if (PAD_LIST  || CC_PCR_SetAuthValue)
+    (COMMAND_ATTRIBUTES)(CC_PCR_SetAuthValue            *  // 0x0183
+			 (IS_IMPLEMENTED+DECRYPT_2+HANDLE_1_USER)),
+#endif
+#if (PAD_LIST  || CC_NV_Certify)
+    (COMMAND_ATTRIBUTES)(CC_NV_Certify                  *  // 0x0184
+			 (IS_IMPLEMENTED+DECRYPT_2+HANDLE_1_USER+HANDLE_2_USER+ENCRYPT_2)),
+#endif
+#if (PAD_LIST  || CC_EventSequenceComplete)
+    (COMMAND_ATTRIBUTES)(CC_EventSequenceComplete       *  // 0x0185
+			 (IS_IMPLEMENTED+DECRYPT_2+HANDLE_1_USER+HANDLE_2_USER)),
+#endif
+#if (PAD_LIST  || CC_HashSequenceStart)
+    (COMMAND_ATTRIBUTES)(CC_HashSequenceStart           *  // 0x0186
+			 (IS_IMPLEMENTED+DECRYPT_2+R_HANDLE)),
+#endif
+#if (PAD_LIST  || CC_PolicyPhysicalPresence)
+    (COMMAND_ATTRIBUTES)(CC_PolicyPhysicalPresence      *  // 0x0187
+			 (IS_IMPLEMENTED+ALLOW_TRIAL)),
+#endif
+#if (PAD_LIST  || CC_PolicyDuplicationSelect)
+    (COMMAND_ATTRIBUTES)(CC_PolicyDuplicationSelect     *  // 0x0188
+			 (IS_IMPLEMENTED+DECRYPT_2+ALLOW_TRIAL)),
+#endif
+#if (PAD_LIST  || CC_PolicyGetDigest)
+    (COMMAND_ATTRIBUTES)(CC_PolicyGetDigest             *  // 0x0189
+			 (IS_IMPLEMENTED+ALLOW_TRIAL+ENCRYPT_2)),
+#endif
+#if (PAD_LIST  || CC_TestParms)
+    (COMMAND_ATTRIBUTES)(CC_TestParms                   *  // 0x018a
+			 (IS_IMPLEMENTED)),
+#endif
+#if (PAD_LIST  || CC_Commit)
+    (COMMAND_ATTRIBUTES)(CC_Commit                      *  // 0x018b
+			 (IS_IMPLEMENTED+DECRYPT_2+HANDLE_1_USER+ENCRYPT_2)),
+#endif
+#if (PAD_LIST  || CC_PolicyPassword)
+    (COMMAND_ATTRIBUTES)(CC_PolicyPassword              *  // 0x018c
+			 (IS_IMPLEMENTED+ALLOW_TRIAL)),
+#endif
+#if (PAD_LIST  || CC_ZGen_2Phase)
+    (COMMAND_ATTRIBUTES)(CC_ZGen_2Phase                 *  // 0x018d
+			 (IS_IMPLEMENTED+DECRYPT_2+HANDLE_1_USER+ENCRYPT_2)),
+#endif
+#if (PAD_LIST  || CC_EC_Ephemeral)
+    (COMMAND_ATTRIBUTES)(CC_EC_Ephemeral                *  // 0x018e
+			 (IS_IMPLEMENTED+ENCRYPT_2)),
+#endif
+#if (PAD_LIST  || CC_PolicyNvWritten)
+    (COMMAND_ATTRIBUTES)(CC_PolicyNvWritten             *  // 0x018f
+			 (IS_IMPLEMENTED+ALLOW_TRIAL)),
+#endif
+#if (PAD_LIST  || CC_PolicyTemplate)
+    (COMMAND_ATTRIBUTES)(CC_PolicyTemplate              *  // 0x0190
+			 (IS_IMPLEMENTED+DECRYPT_2+ALLOW_TRIAL)),
+#endif
+#if (PAD_LIST  || CC_CreateLoaded)
+    (COMMAND_ATTRIBUTES)(CC_CreateLoaded                *  // 0x0191
+			 (IS_IMPLEMENTED+DECRYPT_2+HANDLE_1_USER+PP_COMMAND+ENCRYPT_2+R_HANDLE)),
+#endif
+#if (PAD_LIST  || CC_PolicyAuthorizeNV)
+    (COMMAND_ATTRIBUTES)(CC_PolicyAuthorizeNV           *  // 0x0192
+			 (IS_IMPLEMENTED+HANDLE_1_USER+ALLOW_TRIAL)),
+#endif
+#if (PAD_LIST  || CC_EncryptDecrypt2)
+    (COMMAND_ATTRIBUTES)(CC_EncryptDecrypt2             *  // 0x0193
+			 (IS_IMPLEMENTED+DECRYPT_2+HANDLE_1_USER+ENCRYPT_2)),
+#endif
+#if (PAD_LIST  || CC_AC_GetCapability)
+    (COMMAND_ATTRIBUTES)(CC_AC_GetCapability            *  // 0x0194
+			 (IS_IMPLEMENTED)),
+#endif
+#if (PAD_LIST  || CC_AC_Send)
+    (COMMAND_ATTRIBUTES)(CC_AC_Send                     *  // 0x0195
+			 (IS_IMPLEMENTED+DECRYPT_2+HANDLE_1_DUP+HANDLE_2_USER)),
+#endif
+#if (PAD_LIST  || CC_Policy_AC_SendSelect)
+    (COMMAND_ATTRIBUTES)(CC_Policy_AC_SendSelect        *  // 0x0196
+			 (IS_IMPLEMENTED+DECRYPT_2+ALLOW_TRIAL)),
+#endif
+#if (PAD_LIST || CC_CertifyX509)
+    (COMMAND_ATTRIBUTES)(CC_CertifyX509                 *  // 0x0197
+			 (IS_IMPLEMENTED+DECRYPT_2+HANDLE_1_ADMIN+HANDLE_2_USER+ENCRYPT_2)),
+#endif
+#if (PAD_LIST || CC_ACT_SetTimeout)
+    (COMMAND_ATTRIBUTES)(CC_ACT_SetTimeout              *  // 0x0198
+			 (IS_IMPLEMENTED+HANDLE_1_USER)),
+#endif
+#if (PAD_LIST || CC_ECC_Encrypt)
+    (COMMAND_ATTRIBUTES)(CC_ECC_Encrypt                 *  // 0x0199
+			 (IS_IMPLEMENTED+DECRYPT_2+ENCRYPT_2)),
+#endif
+#if (PAD_LIST || CC_ECC_Decrypt)
+    (COMMAND_ATTRIBUTES)(CC_ECC_Decrypt                 *  // 0x019A
+			 (IS_IMPLEMENTED+DECRYPT_2+HANDLE_1_USER+ENCRYPT_2)),
+#endif
+#if (PAD_LIST  || CC_Vendor_TCG_Test)
+    (COMMAND_ATTRIBUTES)(CC_Vendor_TCG_Test             *  // 0x0000
+			 (IS_IMPLEMENTED+DECRYPT_2+ENCRYPT_2)),
+#endif
+
+#ifdef TPM_NUVOTON
+#if (PAD_LIST  || CC_NTC2_PreConfig)
+    (COMMAND_ATTRIBUTES)(CC_NTC2_PreConfig             *  // 0x20000211
+			 (IS_IMPLEMENTED+NO_SESSIONS)),
+#endif
+#if (PAD_LIST  || CC_NTC2_LockPreConfig)
+    (COMMAND_ATTRIBUTES)(CC_NTC2_LockPreConfig         *  // 0x20000212
+			 (IS_IMPLEMENTED+NO_SESSIONS)),
+#endif
+#if (PAD_LIST  || CC_NTC2_GetConfig)
+    (COMMAND_ATTRIBUTES)(CC_NTC2_GetConfig             *  // 0x20000213
+			 (IS_IMPLEMENTED+NO_SESSIONS)),
+#endif
+#endif
+    0
+};
+
+#endif  // _COMMAND_CODE_ATTRIBUTES_

+ 88 - 0
EVSE/GPL/ibmtpm1682/src/CommandAttributes.h

@@ -0,0 +1,88 @@
+/********************************************************************************/
+/*										*/
+/*			     Command Attributes					*/
+/*			     Written by Ken Goldman				*/
+/*		       IBM Thomas J. Watson Research Center			*/
+/*            $Id: CommandAttributes.h 1594 2020-03-26 22:15:48Z kgoldman $	*/
+/*										*/
+/*  Licenses and Notices							*/
+/*										*/
+/*  1. Copyright Licenses:							*/
+/*										*/
+/*  - Trusted Computing Group (TCG) grants to the user of the source code in	*/
+/*    this specification (the "Source Code") a worldwide, irrevocable, 		*/
+/*    nonexclusive, royalty free, copyright license to reproduce, create 	*/
+/*    derivative works, distribute, display and perform the Source Code and	*/
+/*    derivative works thereof, and to grant others the rights granted herein.	*/
+/*										*/
+/*  - The TCG grants to the user of the other parts of the specification 	*/
+/*    (other than the Source Code) the rights to reproduce, distribute, 	*/
+/*    display, and perform the specification solely for the purpose of 		*/
+/*    developing products based on such documents.				*/
+/*										*/
+/*  2. Source Code Distribution Conditions:					*/
+/*										*/
+/*  - Redistributions of Source Code must retain the above copyright licenses, 	*/
+/*    this list of conditions and the following disclaimers.			*/
+/*										*/
+/*  - Redistributions in binary form must reproduce the above copyright 	*/
+/*    licenses, this list of conditions	and the following disclaimers in the 	*/
+/*    documentation and/or other materials provided with the distribution.	*/
+/*										*/
+/*  3. Disclaimers:								*/
+/*										*/
+/*  - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF	*/
+/*  LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH	*/
+/*  RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES)	*/
+/*  THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE.		*/
+/*  Contact TCG Administration (admin@trustedcomputinggroup.org) for 		*/
+/*  information on specification licensing rights available through TCG 	*/
+/*  membership agreements.							*/
+/*										*/
+/*  - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED 	*/
+/*    WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR 	*/
+/*    FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR 		*/
+/*    NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY 		*/
+/*    OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE.		*/
+/*										*/
+/*  - Without limitation, TCG and its members and licensors disclaim all 	*/
+/*    liability, including liability for infringement of any proprietary 	*/
+/*    rights, relating to use of information in this specification and to the	*/
+/*    implementation of this specification, and TCG disclaims all liability for	*/
+/*    cost of procurement of substitute goods or services, lost profits, loss 	*/
+/*    of use, loss of data or any incidental, consequential, direct, indirect, 	*/
+/*    or special damages, whether under contract, tort, warranty or otherwise, 	*/
+/*    arising in any way out of use or reliance upon this specification or any 	*/
+/*    information herein.							*/
+/*										*/
+/*  (c) Copyright IBM Corp. and others, 2016 - 2020				*/
+/*										*/
+/********************************************************************************/
+
+#ifndef COMMANDATTRIBUTES_H
+#define COMMANDATTRIBUTES_H
+
+/* 5.7	CommandAttributes.h */
+/* The attributes defined in this file are produced by the parser that creates the structure
+   definitions from Part 3. The attributes are defined in that parser and should track the
+   attributes being tested in CommandCodeAttributes.c. Generally, when an attribute is added to this
+   list, new code will be needed in CommandCodeAttributes.c to test it. */
+
+typedef  UINT16             COMMAND_ATTRIBUTES;
+#define NOT_IMPLEMENTED     (COMMAND_ATTRIBUTES)(0)
+#define ENCRYPT_2           ((COMMAND_ATTRIBUTES)1 << 0)
+#define ENCRYPT_4           ((COMMAND_ATTRIBUTES)1 << 1)
+#define DECRYPT_2           ((COMMAND_ATTRIBUTES)1 << 2)
+#define DECRYPT_4           ((COMMAND_ATTRIBUTES)1 << 3)
+#define HANDLE_1_USER       ((COMMAND_ATTRIBUTES)1 << 4)
+#define HANDLE_1_ADMIN      ((COMMAND_ATTRIBUTES)1 << 5)
+#define HANDLE_1_DUP        ((COMMAND_ATTRIBUTES)1 << 6)
+#define HANDLE_2_USER       ((COMMAND_ATTRIBUTES)1 << 7)
+#define PP_COMMAND          ((COMMAND_ATTRIBUTES)1 << 8)
+#define IS_IMPLEMENTED      ((COMMAND_ATTRIBUTES)1 << 9)
+#define NO_SESSIONS         ((COMMAND_ATTRIBUTES)1 << 10)
+#define NV_COMMAND          ((COMMAND_ATTRIBUTES)1 << 11)
+#define PP_REQUIRED         ((COMMAND_ATTRIBUTES)1 << 12)
+#define R_HANDLE            ((COMMAND_ATTRIBUTES)1 << 13)
+#define ALLOW_TRIAL         ((COMMAND_ATTRIBUTES)1 << 14)
+#endif // COMMAND_ATTRIBUTES_H

+ 262 - 0
EVSE/GPL/ibmtpm1682/src/CommandAudit.c

@@ -0,0 +1,262 @@
+/********************************************************************************/
+/*										*/
+/*			  Functions That Support Command Audit 			*/
+/*			     Written by Ken Goldman				*/
+/*		       IBM Thomas J. Watson Research Center			*/
+/*            $Id: CommandAudit.c 1519 2019-11-15 20:43:51Z kgoldman $		*/
+/*										*/
+/*  Licenses and Notices							*/
+/*										*/
+/*  1. Copyright Licenses:							*/
+/*										*/
+/*  - Trusted Computing Group (TCG) grants to the user of the source code in	*/
+/*    this specification (the "Source Code") a worldwide, irrevocable, 		*/
+/*    nonexclusive, royalty free, copyright license to reproduce, create 	*/
+/*    derivative works, distribute, display and perform the Source Code and	*/
+/*    derivative works thereof, and to grant others the rights granted herein.	*/
+/*										*/
+/*  - The TCG grants to the user of the other parts of the specification 	*/
+/*    (other than the Source Code) the rights to reproduce, distribute, 	*/
+/*    display, and perform the specification solely for the purpose of 		*/
+/*    developing products based on such documents.				*/
+/*										*/
+/*  2. Source Code Distribution Conditions:					*/
+/*										*/
+/*  - Redistributions of Source Code must retain the above copyright licenses, 	*/
+/*    this list of conditions and the following disclaimers.			*/
+/*										*/
+/*  - Redistributions in binary form must reproduce the above copyright 	*/
+/*    licenses, this list of conditions	and the following disclaimers in the 	*/
+/*    documentation and/or other materials provided with the distribution.	*/
+/*										*/
+/*  3. Disclaimers:								*/
+/*										*/
+/*  - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF	*/
+/*  LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH	*/
+/*  RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES)	*/
+/*  THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE.		*/
+/*  Contact TCG Administration (admin@trustedcomputinggroup.org) for 		*/
+/*  information on specification licensing rights available through TCG 	*/
+/*  membership agreements.							*/
+/*										*/
+/*  - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED 	*/
+/*    WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR 	*/
+/*    FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR 		*/
+/*    NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY 		*/
+/*    OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE.		*/
+/*										*/
+/*  - Without limitation, TCG and its members and licensors disclaim all 	*/
+/*    liability, including liability for infringement of any proprietary 	*/
+/*    rights, relating to use of information in this specification and to the	*/
+/*    implementation of this specification, and TCG disclaims all liability for	*/
+/*    cost of procurement of substitute goods or services, lost profits, loss 	*/
+/*    of use, loss of data or any incidental, consequential, direct, indirect, 	*/
+/*    or special damages, whether under contract, tort, warranty or otherwise, 	*/
+/*    arising in any way out of use or reliance upon this specification or any 	*/
+/*    information herein.							*/
+/*										*/
+/*  (c) Copyright IBM Corp. and others, 2016 - 2019				*/
+/*										*/
+/********************************************************************************/
+
+/* 8.1 CommandAudit.c */
+/* 8.1.1 Introduction */
+/* This file contains the functions that support command audit. */
+/* 8.1.2 Includes */
+#include "Tpm.h"
+/* 8.1.3 Functions */
+/* 8.1.3.1 CommandAuditPreInstall_Init() */
+/* This function initializes the command audit list. This function simulates the behavior of
+   manufacturing. A function is used instead of a structure definition because this is easier than
+   figuring out the initialization value for a bit array. */
+/* This function would not be implemented outside of a manufacturing or simulation environment. */
+void
+CommandAuditPreInstall_Init(
+			    void
+			    )
+{
+    // Clear all the audit commands
+    MemorySet(gp.auditCommands, 0x00, sizeof(gp.auditCommands));
+    // TPM_CC_SetCommandCodeAuditStatus always being audited
+    CommandAuditSet(TPM_CC_SetCommandCodeAuditStatus);
+    // Set initial command audit hash algorithm to be context integrity hash
+    // algorithm
+    gp.auditHashAlg = CONTEXT_INTEGRITY_HASH_ALG;
+    // Set up audit counter to be 0
+    gp.auditCounter = 0;
+    // Write command audit persistent data to NV
+    NV_SYNC_PERSISTENT(auditCommands);
+    NV_SYNC_PERSISTENT(auditHashAlg);
+    NV_SYNC_PERSISTENT(auditCounter);
+    return;
+}
+/* 8.1.3.2 CommandAuditStartup() */
+/* This function clears the command audit digest on a TPM Reset. */
+BOOL
+CommandAuditStartup(
+		    STARTUP_TYPE     type           // IN: start up type
+		    )
+{
+    if((type != SU_RESTART) && (type != SU_RESUME))
+	{
+	    // Reset the digest size to initialize the digest
+	    gr.commandAuditDigest.t.size = 0;
+	}
+    return TRUE;
+}
+/* 8.1.3.3 CommandAuditSet() */
+/* This function will SET the audit flag for a command. This function will not SET the audit flag
+   for a command that is not implemented. This ensures that the audit status is not SET when
+   TPM2_GetCapability() is used to read the list of audited commands. */
+/* This function is only used by TPM2_SetCommandCodeAuditStatus(). */
+/* The actions in TPM2_SetCommandCodeAuditStatus() are expected to cause the changes to be saved to
+   NV after it is setting and clearing bits. */
+/* Return Values Meaning */
+/* TRUE the command code audit status was changed */
+/* FALSE the command code audit status was not changed */
+BOOL
+CommandAuditSet(
+		TPM_CC           commandCode    // IN: command code
+		)
+{
+    COMMAND_INDEX        commandIndex = CommandCodeToCommandIndex(commandCode);
+    // Only SET a bit if the corresponding command is implemented
+    if(commandIndex != UNIMPLEMENTED_COMMAND_INDEX)
+	{
+	    // Can't audit shutdown
+	    if(commandCode != TPM_CC_Shutdown)
+		{
+		    if(!TEST_BIT(commandIndex, gp.auditCommands))
+			{
+			    // Set bit
+			    SET_BIT(commandIndex, gp.auditCommands);
+			    return TRUE;
+			}
+		}
+	}
+    // No change
+    return FALSE;
+}
+/* 8.1.3.4 CommandAuditClear() */
+/* This function will CLEAR the audit flag for a command. It will not CLEAR the audit flag for
+   TPM_CC_SetCommandCodeAuditStatus(). */
+/* This function is only used by TPM2_SetCommandCodeAuditStatus(). */
+/* The actions in TPM2_SetCommandCodeAuditStatus() are expected to cause the changes to be saved to
+   NV after it is setting and clearing bits. */
+/* Return Values Meaning */
+/* TRUE the command code audit status was changed */
+/* FALSE the command code audit status was not changed */
+BOOL
+CommandAuditClear(
+		  TPM_CC           commandCode    // IN: command code
+		  )
+{
+    COMMAND_INDEX       commandIndex = CommandCodeToCommandIndex(commandCode);
+    // Do nothing if the command is not implemented
+    if(commandIndex != UNIMPLEMENTED_COMMAND_INDEX)
+	{
+	    // The bit associated with TPM_CC_SetCommandCodeAuditStatus() cannot be
+	    // cleared
+	    if(commandCode != TPM_CC_SetCommandCodeAuditStatus)
+		{
+		    if(TEST_BIT(commandIndex, gp.auditCommands))
+			{
+			    // Clear bit
+			    CLEAR_BIT(commandIndex, gp.auditCommands);
+			    return TRUE;
+			}
+		}
+	}
+    // No change
+    return FALSE;
+}
+/* 8.1.3.5 CommandAuditIsRequired() */
+/* This function indicates if the audit flag is SET for a command. */
+/* Return Values Meaning */
+/* TRUE if command is audited */
+/* FALSE if command is not audited */
+BOOL
+CommandAuditIsRequired(
+		       COMMAND_INDEX    commandIndex   // IN: command index
+		       )
+{
+    // Check the bit map.  If the bit is SET, command audit is required
+    return(TEST_BIT(commandIndex, gp.auditCommands));
+}
+/* 8.1.3.6 CommandAuditCapGetCCList() */
+/* This function returns a list of commands that have their audit bit SET. */
+/* The list starts at the input commandCode. */
+/* Return Values Meaning */
+/* YES if there are more command code available */
+/* NO all the available command code has been returned */
+TPMI_YES_NO
+CommandAuditCapGetCCList(
+			 TPM_CC           commandCode,   // IN: start command code
+			 UINT32           count,         // IN: count of returned TPM_CC
+			 TPML_CC         *commandList    // OUT: list of TPM_CC
+			 )
+{
+    TPMI_YES_NO     more = NO;
+    COMMAND_INDEX   commandIndex;
+    // Initialize output handle list
+    commandList->count = 0;
+    // The maximum count of command we may return is MAX_CAP_CC
+    if(count > MAX_CAP_CC) count = MAX_CAP_CC;
+    // Find the implemented command that has a command code that is the same or
+    // higher than the input
+    // Collect audit commands
+    for(commandIndex = GetClosestCommandIndex(commandCode);
+	commandIndex != UNIMPLEMENTED_COMMAND_INDEX;
+	commandIndex = GetNextCommandIndex(commandIndex))
+	{
+	    if(CommandAuditIsRequired(commandIndex))
+		{
+		    if(commandList->count < count)
+			{
+			    // If we have not filled up the return list, add this command
+			    // code to its
+			    TPM_CC      cc = GET_ATTRIBUTE(s_ccAttr[commandIndex],
+							   TPMA_CC, commandIndex);
+			    if(IS_ATTRIBUTE(s_ccAttr[commandIndex], TPMA_CC, V))
+				cc += (1 << 29);
+			    commandList->commandCodes[commandList->count] = cc;
+			    commandList->count++;
+			}
+		    else
+			{
+			    // If the return list is full but we still have command
+			    // available, report this and stop iterating
+			    more = YES;
+			    break;
+			}
+		}
+	}
+    return more;
+}
+/* 8.1.3.7 CommandAuditGetDigest */
+/* This command is used to create a digest of the commands being audited. The commands are processed
+   in ascending numeric order with a list of TPM_CC being added to a hash. This operates as if all
+   the audited command codes were concatenated and then hashed. */
+void
+CommandAuditGetDigest(
+		      TPM2B_DIGEST    *digest         // OUT: command digest
+		      )
+{
+    TPM_CC                       commandCode;
+    COMMAND_INDEX                commandIndex;
+    HASH_STATE                   hashState;
+    // Start hash
+    digest->t.size = CryptHashStart(&hashState, gp.auditHashAlg);
+    // Add command code
+    for(commandIndex = 0; commandIndex < COMMAND_COUNT; commandIndex++)
+	{
+	    if(CommandAuditIsRequired(commandIndex))
+		{
+		    commandCode = GetCommandCode(commandIndex);
+		    CryptDigestUpdateInt(&hashState, sizeof(commandCode), commandCode);
+		}
+	}
+    // Complete hash
+    CryptHashEnd2B(&hashState, &digest->b);
+    return;
+}

+ 97 - 0
EVSE/GPL/ibmtpm1682/src/CommandAudit_fp.h

@@ -0,0 +1,97 @@
+/********************************************************************************/
+/*										*/
+/*			     				*/
+/*			     Written by Ken Goldman				*/
+/*		       IBM Thomas J. Watson Research Center			*/
+/*            $Id: CommandAudit_fp.h 1490 2019-07-26 21:13:22Z kgoldman $	*/
+/*										*/
+/*  Licenses and Notices							*/
+/*										*/
+/*  1. Copyright Licenses:							*/
+/*										*/
+/*  - Trusted Computing Group (TCG) grants to the user of the source code in	*/
+/*    this specification (the "Source Code") a worldwide, irrevocable, 		*/
+/*    nonexclusive, royalty free, copyright license to reproduce, create 	*/
+/*    derivative works, distribute, display and perform the Source Code and	*/
+/*    derivative works thereof, and to grant others the rights granted herein.	*/
+/*										*/
+/*  - The TCG grants to the user of the other parts of the specification 	*/
+/*    (other than the Source Code) the rights to reproduce, distribute, 	*/
+/*    display, and perform the specification solely for the purpose of 		*/
+/*    developing products based on such documents.				*/
+/*										*/
+/*  2. Source Code Distribution Conditions:					*/
+/*										*/
+/*  - Redistributions of Source Code must retain the above copyright licenses, 	*/
+/*    this list of conditions and the following disclaimers.			*/
+/*										*/
+/*  - Redistributions in binary form must reproduce the above copyright 	*/
+/*    licenses, this list of conditions	and the following disclaimers in the 	*/
+/*    documentation and/or other materials provided with the distribution.	*/
+/*										*/
+/*  3. Disclaimers:								*/
+/*										*/
+/*  - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF	*/
+/*  LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH	*/
+/*  RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES)	*/
+/*  THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE.		*/
+/*  Contact TCG Administration (admin@trustedcomputinggroup.org) for 		*/
+/*  information on specification licensing rights available through TCG 	*/
+/*  membership agreements.							*/
+/*										*/
+/*  - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED 	*/
+/*    WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR 	*/
+/*    FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR 		*/
+/*    NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY 		*/
+/*    OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE.		*/
+/*										*/
+/*  - Without limitation, TCG and its members and licensors disclaim all 	*/
+/*    liability, including liability for infringement of any proprietary 	*/
+/*    rights, relating to use of information in this specification and to the	*/
+/*    implementation of this specification, and TCG disclaims all liability for	*/
+/*    cost of procurement of substitute goods or services, lost profits, loss 	*/
+/*    of use, loss of data or any incidental, consequential, direct, indirect, 	*/
+/*    or special damages, whether under contract, tort, warranty or otherwise, 	*/
+/*    arising in any way out of use or reliance upon this specification or any 	*/
+/*    information herein.							*/
+/*										*/
+/*  (c) Copyright IBM Corp. and others, 2016 - 2019				*/
+/*										*/
+/********************************************************************************/
+
+#ifndef COMMANDAUDIT_FP_H
+#define COMMANDAUDIT_FP_H
+
+void
+CommandAuditPreInstall_Init(
+			    void
+			    );
+BOOL
+CommandAuditStartup(
+		    STARTUP_TYPE     type           // IN: start up type
+		    );
+BOOL
+CommandAuditSet(
+		TPM_CC           commandCode    // IN: command code
+		);
+BOOL
+CommandAuditClear(
+		  TPM_CC           commandCode    // IN: command code
+		  );
+BOOL
+CommandAuditIsRequired(
+		       COMMAND_INDEX    commandIndex   // IN: command index
+		       );
+TPMI_YES_NO
+CommandAuditCapGetCCList(
+			 TPM_CC           commandCode,   // IN: start command code
+			 UINT32           count,         // IN: count of returned TPM_CC
+			 TPML_CC         *commandList    // OUT: list of TPM_CC
+			 );
+void
+CommandAuditGetDigest(
+		      TPM2B_DIGEST    *digest         // OUT: command digest
+		      );
+
+
+#endif

+ 557 - 0
EVSE/GPL/ibmtpm1682/src/CommandCodeAttributes.c

@@ -0,0 +1,557 @@
+/********************************************************************************/
+/*										*/
+/*		Functions for testing various command properties		*/
+/*			     Written by Ken Goldman				*/
+/*		       IBM Thomas J. Watson Research Center			*/
+/*            $Id: CommandCodeAttributes.c 1594 2020-03-26 22:15:48Z kgoldman $	*/
+/*										*/
+/*  Licenses and Notices							*/
+/*										*/
+/*  1. Copyright Licenses:							*/
+/*										*/
+/*  - Trusted Computing Group (TCG) grants to the user of the source code in	*/
+/*    this specification (the "Source Code") a worldwide, irrevocable, 		*/
+/*    nonexclusive, royalty free, copyright license to reproduce, create 	*/
+/*    derivative works, distribute, display and perform the Source Code and	*/
+/*    derivative works thereof, and to grant others the rights granted herein.	*/
+/*										*/
+/*  - The TCG grants to the user of the other parts of the specification 	*/
+/*    (other than the Source Code) the rights to reproduce, distribute, 	*/
+/*    display, and perform the specification solely for the purpose of 		*/
+/*    developing products based on such documents.				*/
+/*										*/
+/*  2. Source Code Distribution Conditions:					*/
+/*										*/
+/*  - Redistributions of Source Code must retain the above copyright licenses, 	*/
+/*    this list of conditions and the following disclaimers.			*/
+/*										*/
+/*  - Redistributions in binary form must reproduce the above copyright 	*/
+/*    licenses, this list of conditions	and the following disclaimers in the 	*/
+/*    documentation and/or other materials provided with the distribution.	*/
+/*										*/
+/*  3. Disclaimers:								*/
+/*										*/
+/*  - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF	*/
+/*  LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH	*/
+/*  RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES)	*/
+/*  THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE.		*/
+/*  Contact TCG Administration (admin@trustedcomputinggroup.org) for 		*/
+/*  information on specification licensing rights available through TCG 	*/
+/*  membership agreements.							*/
+/*										*/
+/*  - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED 	*/
+/*    WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR 	*/
+/*    FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR 		*/
+/*    NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY 		*/
+/*    OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE.		*/
+/*										*/
+/*  - Without limitation, TCG and its members and licensors disclaim all 	*/
+/*    liability, including liability for infringement of any proprietary 	*/
+/*    rights, relating to use of information in this specification and to the	*/
+/*    implementation of this specification, and TCG disclaims all liability for	*/
+/*    cost of procurement of substitute goods or services, lost profits, loss 	*/
+/*    of use, loss of data or any incidental, consequential, direct, indirect, 	*/
+/*    or special damages, whether under contract, tort, warranty or otherwise, 	*/
+/*    arising in any way out of use or reliance upon this specification or any 	*/
+/*    information herein.							*/
+/*										*/
+/*  (c) Copyright IBM Corp. and others, 2016 - 2020				*/
+/*										*/
+/********************************************************************************/
+
+/* 9.3 CommandCodeAttributes.c */
+/* 9.3.1 Introduction */
+/* This file contains the functions for testing various command properties. */
+/* 9.3.2 Includes and Defines */
+#include "Tpm.h"
+#include "CommandCodeAttributes_fp.h"
+/* Set the default value for CC_VEND if not already set */
+#ifndef CC_VEND
+#define     CC_VEND     (TPM_CC)(0x20000000)
+#endif
+typedef UINT16          ATTRIBUTE_TYPE;
+/* The following file is produced from the command tables in part 3 of the specification. It defines
+   the attributes for each of the commands. */
+/* NOTE: This file is currently produced by an automated process. Files produced from Part 2 or Part
+   3 tables through automated processes are not included in the specification so that there is no
+   ambiguity about the table containing the information being the normative definition. */
+#define _COMMAND_CODE_ATTRIBUTES_
+#include    "CommandAttributeData.h"
+/* 9.3.3 Command Attribute Functions */
+/* 9.3.3.1 NextImplementedIndex() */
+/* This function is used when the lists are not compressed. In a compressed list, only the
+   implemented commands are present. So, a search might find a value but that value may not be
+   implemented. This function checks to see if the input commandIndex points to an implemented
+   command and, if not, it searches upwards until it finds one. When the list is compressed, this
+   function gets defined as a no-op. */
+/* Return Value	Meaning */
+/* UNIMPLEMENTED_COMMAND_INDEX	command is not implemented */
+/* other	index of the command */
+
+#if !COMPRESSED_LISTS
+static COMMAND_INDEX
+NextImplementedIndex(
+		     COMMAND_INDEX       commandIndex
+		     )
+{
+    for(;commandIndex < COMMAND_COUNT; commandIndex++)
+	{
+	    if(s_commandAttributes[commandIndex] & IS_IMPLEMENTED)
+		return commandIndex;
+	}
+    return UNIMPLEMENTED_COMMAND_INDEX;
+}
+#else
+#define NextImplementedIndex(x) (x)
+#endif
+/* 9.3.3.2 GetClosestCommandIndex() */
+/* This function returns the command index for the command with a value that is equal to or greater
+   than the input value */
+/* Return Value	Meaning */
+/* UNIMPLEMENTED_COMMAND_INDEX	command is not implemented */
+/* other	index of the command */
+
+COMMAND_INDEX
+GetClosestCommandIndex(
+		       TPM_CC           commandCode    // IN: the command code to start at
+		       )
+{
+    BOOL                vendor = (commandCode & CC_VEND) != 0;
+    COMMAND_INDEX       searchIndex = (COMMAND_INDEX)commandCode;
+    // The commandCode is a UINT32 and the search index is UINT16. We are going to
+    // search for a match but need to make sure that the commandCode value is not
+    // out of range. To do this, need to clear the vendor bit of the commandCode
+    // (if set) and compare the result to the 16-bit searchIndex value. If it is
+    // out of range, indicate that the command is not implemented
+    if((commandCode & ~CC_VEND) != searchIndex)
+	return UNIMPLEMENTED_COMMAND_INDEX;
+    // if there is at least one vendor command, the last entry in the array will
+    // have the v bit set. If the input commandCode is larger than the last
+    // vendor-command, then it is out of range.
+    if(vendor)
+	{
+#if VENDOR_COMMAND_ARRAY_SIZE > 0
+	    COMMAND_INDEX       commandIndex;
+	    COMMAND_INDEX       min;
+	    COMMAND_INDEX       max;
+	    int                 diff;
+#if LIBRARY_COMMAND_ARRAY_SIZE == COMMAND_COUNT
+#error "Constants are not consistent."
+#endif
+	    // Check to see if the value is equal to or below the minimum
+	    // entry.
+	    // Note: Put this check first so that the typical case of only one vendor-
+	    // specific command doesn't waste any more time.
+	    if(GET_ATTRIBUTE(s_ccAttr[LIBRARY_COMMAND_ARRAY_SIZE], TPMA_CC,
+			     commandIndex) >= searchIndex)
+		{
+		    // the vendor array is always assumed to be packed so there is
+		    // no need to check to see if the command is implemented
+		    return LIBRARY_COMMAND_ARRAY_SIZE;
+		}
+	    // See if this is out of range on the top
+	    if(GET_ATTRIBUTE(s_ccAttr[COMMAND_COUNT - 1], TPMA_CC, commandIndex)
+	       < searchIndex)
+		{
+		    return UNIMPLEMENTED_COMMAND_INDEX;
+		}
+	    commandIndex = UNIMPLEMENTED_COMMAND_INDEX; // Needs initialization to keep
+	    // compiler happy
+	    min = LIBRARY_COMMAND_ARRAY_SIZE;       // first vendor command
+	    max = COMMAND_COUNT - 1;                // last vendor command
+	    diff = 1;                               // needs initialization to keep
+	    // compiler happy
+	    while(min <= max)
+		{
+		    commandIndex = (min + max + 1) / 2;
+		    diff = GET_ATTRIBUTE(s_ccAttr[commandIndex], TPMA_CC, commandIndex)
+			   - searchIndex;
+		    if(diff == 0)
+			return commandIndex;
+		    if(diff > 0)
+			max = commandIndex - 1;
+		    else
+			min = commandIndex + 1;
+		}
+	    // didn't find and exact match. commandIndex will be pointing at the last
+	    // item tested. If 'diff' is positive, then the last item tested was
+	    // larger index of the command code so it is the smallest value
+	    // larger than the requested value.
+	    if(diff > 0)
+		return commandIndex;
+	    // if 'diff' is negative, then the value tested was smaller than
+	    // the commandCode index and the next higher value is the correct one.
+	    // Note: this will necessarily be in range because of the earlier check
+	    // that the index was within range.
+	    return commandIndex + 1;
+#else
+	    // If there are no vendor commands so anything with the vendor bit set is out
+	    // of range
+	    return UNIMPLEMENTED_COMMAND_INDEX;
+#endif
+	}
+    // Get here if the V-Bit was not set in 'commandCode'
+    if(GET_ATTRIBUTE(s_ccAttr[LIBRARY_COMMAND_ARRAY_SIZE - 1], TPMA_CC,
+		     commandIndex) < searchIndex)
+	{
+	    // requested index is out of the range to the top
+#if VENDOR_COMMAND_ARRAY_SIZE > 0
+	    // If there are vendor commands, then the first vendor command
+	    // is the next value greater than the commandCode.
+	    // NOTE: we got here if the starting index did not have the V bit but we
+	    // reached the end of the array of library commands (non-vendor). Since
+	    // there is at least one vendor command, and vendor commands are always
+	    // in a compressed list that starts after the library list, the next
+	    // index value contains a valid vendor command.
+	    return LIBRARY_COMMAND_ARRAY_SIZE;
+#else
+	    // if there are no vendor commands, then this is out of range
+	    return UNIMPLEMENTED_COMMAND_INDEX;
+#endif
+	}
+    // If the request is lower than any value in the array, then return
+    // the lowest value (needs to be an index for an implemented command
+    if(GET_ATTRIBUTE(s_ccAttr[0], TPMA_CC, commandIndex) >= searchIndex)
+	{
+	    return NextImplementedIndex(0);
+	}
+    else
+	{
+#if COMPRESSED_LISTS
+	    COMMAND_INDEX       commandIndex = UNIMPLEMENTED_COMMAND_INDEX;
+	    COMMAND_INDEX       min = 0;
+	    COMMAND_INDEX       max = LIBRARY_COMMAND_ARRAY_SIZE - 1;
+	    int                 diff = 1;
+#if LIBRARY_COMMAND_ARRAY_SIZE == 0
+#error  "Something is terribly wrong"
+#endif
+	    // The s_ccAttr array contains an extra entry at the end (a zero value).
+	    // Don't count this as an array entry. This means that max should start
+	    // out pointing to the last valid entry in the array which is - 2
+	    pAssert(max == (sizeof(s_ccAttr) / sizeof(TPMA_CC)
+			    - VENDOR_COMMAND_ARRAY_SIZE - 2));
+	    while(min <= max)
+		{
+		    commandIndex = (min + max + 1) / 2;
+		    diff = GET_ATTRIBUTE(s_ccAttr[commandIndex], TPMA_CC,
+					 commandIndex) - searchIndex;
+		    if(diff == 0)
+			return commandIndex;
+		    if(diff > 0)
+			max = commandIndex - 1;
+		    else
+			min = commandIndex + 1;
+		}
+	    // didn't find and exact match. commandIndex will be pointing at the
+	    // last item tested. If diff is positive, then the last item tested was
+	    // larger index of the command code so it is the smallest value
+	    // larger than the requested value.
+	    if(diff > 0)
+		return commandIndex;
+	    // if diff is negative, then the value tested was smaller than
+	    // the commandCode index and the next higher value is the correct one.
+	    // Note: this will necessarily be in range because of the earlier check
+	    // that the index was within range.
+	    return commandIndex + 1;
+#else
+	    // The list is not compressed so offset into the array by the command
+	    // code value of the first entry in the list. Then go find the first
+	    // implemented command.
+	    return NextImplementedIndex(searchIndex
+					- (COMMAND_INDEX)s_ccAttr[0].commandIndex);
+#endif
+	}
+}
+/* 9.3.3.3 CommandCodeToComandIndex() */
+/* This function returns the index in the various attributes arrays of the command. */
+/* Return Values Meaning */
+/* UNIMPLEMENTED_COMMAND_INDEX command is not implemented */
+/* other index of the command */
+COMMAND_INDEX
+CommandCodeToCommandIndex(
+			  TPM_CC           commandCode    // IN: the command code to look up
+			  )
+{
+    // Extract the low 16-bits of the command code to get the starting search index
+    COMMAND_INDEX       searchIndex = (COMMAND_INDEX)commandCode;
+    BOOL                vendor = (commandCode & CC_VEND) != 0;
+    COMMAND_INDEX       commandIndex;
+#if !COMPRESSED_LISTS
+    if(!vendor)
+	{
+	    commandIndex = searchIndex - (COMMAND_INDEX)s_ccAttr[0].commandIndex;
+	    // Check for out of range or unimplemented.
+	    // Note, since a COMMAND_INDEX is unsigned, if searchIndex is smaller than
+	    // the lowest value of command, it will become a 'negative' number making
+	    // it look like a large unsigned number, this will cause it to fail
+	    // the unsigned check below.
+	    if(commandIndex >= LIBRARY_COMMAND_ARRAY_SIZE
+	       || (s_commandAttributes[commandIndex] & IS_IMPLEMENTED) == 0)
+		return UNIMPLEMENTED_COMMAND_INDEX;
+	    return commandIndex;
+	}
+#endif
+    // Need this code for any vendor code lookup or for compressed lists
+    commandIndex = GetClosestCommandIndex(commandCode);
+    // Look at the returned value from get closest. If it isn't the one that was
+    // requested, then the command is not implemented.
+    if(commandIndex != UNIMPLEMENTED_COMMAND_INDEX)
+	{
+	    if((GET_ATTRIBUTE(s_ccAttr[commandIndex], TPMA_CC, commandIndex)
+		!= searchIndex)
+	       || (IS_ATTRIBUTE(s_ccAttr[commandIndex], TPMA_CC, V)) != vendor)
+		commandIndex = UNIMPLEMENTED_COMMAND_INDEX;
+	}
+    return commandIndex;
+}
+/* 9.3.3.4 GetNextCommandIndex() */
+/* This function returns the index of the next implemented command. */
+/* Return Values Meaning */
+/* UNIMPLEMENTED_COMMAND_INDEX no more implemented commands */
+/* other the index of the next implemented command */
+COMMAND_INDEX
+GetNextCommandIndex(
+		    COMMAND_INDEX    commandIndex   // IN: the starting index
+		    )
+{
+    while(++commandIndex < COMMAND_COUNT)
+	{
+#if !COMPRESSED_LISTS
+	    if(s_commandAttributes[commandIndex] & IS_IMPLEMENTED)
+#endif
+		return commandIndex;
+	}
+    return UNIMPLEMENTED_COMMAND_INDEX;
+}
+/* 9.3.3.5 GetCommandCode() */
+/* This function returns the commandCode associated with the command index */
+TPM_CC
+GetCommandCode(
+	       COMMAND_INDEX    commandIndex   // IN: the command index
+	       )
+{
+    TPM_CC           commandCode = GET_ATTRIBUTE(s_ccAttr[commandIndex],
+						 TPMA_CC, commandIndex);
+    if(IS_ATTRIBUTE(s_ccAttr[commandIndex], TPMA_CC, V))
+	commandCode += CC_VEND;
+    return commandCode;
+}
+/* 9.3.3.6 CommandAuthRole() */
+/* This function returns the authorization role required of a handle. */
+/* Return Values Meaning */
+/* AUTH_NONE no authorization is required */
+/* AUTH_USER user role authorization is required */
+/* AUTH_ADMIN admin role authorization is required */
+/* AUTH_DUP duplication role authorization is required */
+AUTH_ROLE
+CommandAuthRole(
+		COMMAND_INDEX    commandIndex,  // IN: command index
+		UINT32           handleIndex    // IN: handle index (zero based)
+		)
+{
+    if(0 == handleIndex)
+	{
+	    // Any authorization role set?
+	    COMMAND_ATTRIBUTES  properties = s_commandAttributes[commandIndex];
+	    if(properties & HANDLE_1_USER)
+		return AUTH_USER;
+	    if(properties & HANDLE_1_ADMIN)
+		return AUTH_ADMIN;
+	    if(properties & HANDLE_1_DUP)
+		return AUTH_DUP;
+	}
+    else if(1 == handleIndex)
+	{
+	    if(s_commandAttributes[commandIndex] & HANDLE_2_USER)
+		return AUTH_USER;
+	}
+    return AUTH_NONE;
+}
+/* 9.3.3.7 EncryptSize() */
+/* This function returns the size of the decrypt size field. This function returns 0 if encryption
+   is not allowed */
+/* Return Values Meaning */
+/* 0 encryption not allowed */
+/* 2 size field is two bytes */
+/* 4 size field is four bytes */
+
+int
+EncryptSize(
+	    COMMAND_INDEX    commandIndex   // IN: command index
+	    )
+{
+    return ((s_commandAttributes[commandIndex] & ENCRYPT_2) ? 2 :
+	    (s_commandAttributes[commandIndex] & ENCRYPT_4) ? 4 : 0);
+}
+
+/* 9.3.3.8 DecryptSize() */
+/* This function returns the size of the decrypt size field. This function returns 0 if decryption
+   is not allowed */
+/* Return Values Meaning */
+/* 0 encryption not allowed */
+/* 2 size field is two bytes */
+/* 4 size field is four bytes */
+
+int
+DecryptSize(
+	    COMMAND_INDEX    commandIndex   // IN: command index
+	    )
+{
+    return ((s_commandAttributes[commandIndex] & DECRYPT_2) ? 2 :
+	    (s_commandAttributes[commandIndex] & DECRYPT_4) ? 4 : 0);
+}
+
+/* 9.3.3.9 IsSessionAllowed() */
+/* This function indicates if the command is allowed to have sessions. */
+/* This function must not be called if the command is not known to be implemented. */
+/* Return Values Meaning */
+/* TRUE session is allowed with this command */
+/* FALSE session is not allowed with this command */
+
+BOOL
+IsSessionAllowed(
+		 COMMAND_INDEX    commandIndex   // IN: the command to be checked
+		 )
+{
+    return ((s_commandAttributes[commandIndex] & NO_SESSIONS) == 0);
+}
+
+/* 9.3.3.10 IsHandleInResponse() */
+/* This function determines if a command has a handle in the response */
+
+BOOL
+IsHandleInResponse(
+		   COMMAND_INDEX    commandIndex
+		   )
+{
+    return ((s_commandAttributes[commandIndex] & R_HANDLE) != 0);
+}
+
+/* 9.3.3.11 IsWriteOperation() */
+/* Checks to see if an operation will write to an NV Index and is subject to being blocked by
+   read-lock */
+BOOL
+IsWriteOperation(
+		 COMMAND_INDEX    commandIndex   // IN: Command to check
+		 )
+{
+#ifdef  WRITE_LOCK
+    return ((s_commandAttributes[commandIndex] & WRITE_LOCK) != 0);
+#else
+    if(!IS_ATTRIBUTE(s_ccAttr[commandIndex], TPMA_CC, V))
+	{
+	    switch(GET_ATTRIBUTE(s_ccAttr[commandIndex], TPMA_CC, commandIndex))
+		{
+		  case TPM_CC_NV_Write:
+#if CC_NV_Increment
+		  case TPM_CC_NV_Increment:
+#endif
+#if CC_NV_SetBits
+		  case TPM_CC_NV_SetBits:
+#endif
+#if CC_NV_Extend
+		  case TPM_CC_NV_Extend:
+#endif
+#if CC_AC_Send
+		  case TPM_CC_AC_Send:
+#endif
+		    // NV write lock counts as a write operation for authorization purposes.
+		    // We check to see if the NV is write locked before we do the
+		    // authorization. If it is locked, we fail the command early.
+		  case TPM_CC_NV_WriteLock:
+		    return TRUE;
+		  default:
+		    break;
+		}
+	}
+    return FALSE;
+#endif
+}
+/* 9.3.3.12 IsReadOperation() */
+/* Checks to see if an operation will write to an NV Index and is subject to being blocked by
+   write-lock. */
+BOOL
+IsReadOperation(
+		COMMAND_INDEX    commandIndex   // IN: Command to check
+		)
+{
+#ifdef  READ_LOCK
+    return ((s_commandAttributes[commandIndex] & READ_LOCK) != 0);
+#else
+    if(!IS_ATTRIBUTE(s_ccAttr[commandIndex], TPMA_CC, V))
+	{
+	    switch(GET_ATTRIBUTE(s_ccAttr[commandIndex], TPMA_CC, commandIndex))
+		{
+		  case TPM_CC_NV_Read:
+		  case TPM_CC_PolicyNV:
+		  case TPM_CC_NV_Certify:
+		    // NV read lock counts as a read operation for authorization purposes.
+		    // We check to see if the NV is read locked before we do the
+		    // authorization. If it is locked, we fail the command early.
+		  case TPM_CC_NV_ReadLock:
+		    return TRUE;
+		  default:
+		    break;
+		}
+	}
+    return FALSE;
+#endif
+}
+/* 9.3.3.13 CommandCapGetCCList() */
+/* This function returns a list of implemented commands and command attributes starting from the
+   command in commandCode. */
+/* Return Values Meaning */
+/* YES more command attributes are available */
+/* NO no more command attributes are available */
+TPMI_YES_NO
+CommandCapGetCCList(
+		    TPM_CC           commandCode,   // IN: start command code
+		    UINT32           count,         // IN: maximum count for number of entries in
+		    //     'commandList'
+		    TPML_CCA        *commandList    // OUT: list of TPMA_CC
+		    )
+{
+    TPMI_YES_NO      more = NO;
+    COMMAND_INDEX    commandIndex;
+    // initialize output handle list count
+    commandList->count = 0;
+    for(commandIndex = GetClosestCommandIndex(commandCode);
+	commandIndex != UNIMPLEMENTED_COMMAND_INDEX;
+	commandIndex = GetNextCommandIndex(commandIndex))
+	{
+#if !COMPRESSED_LISTS
+	    // this check isn't needed for compressed lists.
+	    if(!(s_commandAttributes[commandIndex] & IS_IMPLEMENTED))
+		continue;
+#endif
+	    if(commandList->count < count)
+		{
+		    // If the list is not full, add the attributes for this command.
+		    commandList->commandAttributes[commandList->count]
+			= s_ccAttr[commandIndex];
+		    commandList->count++;
+		}
+	    else
+		{
+		    // If the list is full but there are more commands to report,
+		    // indicate this and return.
+		    more = YES;
+		    break;
+		}
+	}
+    return more;
+}
+/* 9.3.3.14 IsVendorCommand() */
+/* Function indicates if a command index references a vendor command. */
+/* Return Values Meaning */
+/* TRUE command is a vendor command */
+/* FALSE command is not a vendor command */
+
+BOOL
+IsVendorCommand(
+		COMMAND_INDEX    commandIndex   // IN: command index to check
+		)
+{
+    return (IS_ATTRIBUTE(s_ccAttr[commandIndex], TPMA_CC, V));
+}
+

+ 123 - 0
EVSE/GPL/ibmtpm1682/src/CommandCodeAttributes_fp.h

@@ -0,0 +1,123 @@
+/********************************************************************************/
+/*										*/
+/*			     				*/
+/*			     Written by Ken Goldman				*/
+/*		       IBM Thomas J. Watson Research Center			*/
+/*            $Id: CommandCodeAttributes_fp.h 1490 2019-07-26 21:13:22Z kgoldman $			*/
+/*										*/
+/*  Licenses and Notices							*/
+/*										*/
+/*  1. Copyright Licenses:							*/
+/*										*/
+/*  - Trusted Computing Group (TCG) grants to the user of the source code in	*/
+/*    this specification (the "Source Code") a worldwide, irrevocable, 		*/
+/*    nonexclusive, royalty free, copyright license to reproduce, create 	*/
+/*    derivative works, distribute, display and perform the Source Code and	*/
+/*    derivative works thereof, and to grant others the rights granted herein.	*/
+/*										*/
+/*  - The TCG grants to the user of the other parts of the specification 	*/
+/*    (other than the Source Code) the rights to reproduce, distribute, 	*/
+/*    display, and perform the specification solely for the purpose of 		*/
+/*    developing products based on such documents.				*/
+/*										*/
+/*  2. Source Code Distribution Conditions:					*/
+/*										*/
+/*  - Redistributions of Source Code must retain the above copyright licenses, 	*/
+/*    this list of conditions and the following disclaimers.			*/
+/*										*/
+/*  - Redistributions in binary form must reproduce the above copyright 	*/
+/*    licenses, this list of conditions	and the following disclaimers in the 	*/
+/*    documentation and/or other materials provided with the distribution.	*/
+/*										*/
+/*  3. Disclaimers:								*/
+/*										*/
+/*  - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF	*/
+/*  LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH	*/
+/*  RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES)	*/
+/*  THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE.		*/
+/*  Contact TCG Administration (admin@trustedcomputinggroup.org) for 		*/
+/*  information on specification licensing rights available through TCG 	*/
+/*  membership agreements.							*/
+/*										*/
+/*  - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED 	*/
+/*    WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR 	*/
+/*    FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR 		*/
+/*    NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY 		*/
+/*    OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE.		*/
+/*										*/
+/*  - Without limitation, TCG and its members and licensors disclaim all 	*/
+/*    liability, including liability for infringement of any proprietary 	*/
+/*    rights, relating to use of information in this specification and to the	*/
+/*    implementation of this specification, and TCG disclaims all liability for	*/
+/*    cost of procurement of substitute goods or services, lost profits, loss 	*/
+/*    of use, loss of data or any incidental, consequential, direct, indirect, 	*/
+/*    or special damages, whether under contract, tort, warranty or otherwise, 	*/
+/*    arising in any way out of use or reliance upon this specification or any 	*/
+/*    information herein.							*/
+/*										*/
+/*  (c) Copyright IBM Corp. and others, 2016					*/
+/*										*/
+/********************************************************************************/
+
+#ifndef COMMANDCODEATTRIBUTES_FP_H
+#define COMMANDCODEATTRIBUTES_FP_H
+
+COMMAND_INDEX
+GetClosestCommandIndex(
+		       TPM_CC           commandCode    // IN: the command code to start at
+		       );
+COMMAND_INDEX
+CommandCodeToCommandIndex(
+			  TPM_CC           commandCode    // IN: the command code to look up
+			  );
+COMMAND_INDEX
+GetNextCommandIndex(
+		    COMMAND_INDEX    commandIndex   // IN: the starting index
+		    );
+TPM_CC
+GetCommandCode(
+	       COMMAND_INDEX    commandIndex   // IN: the command index
+	       );
+AUTH_ROLE
+CommandAuthRole(
+		COMMAND_INDEX    commandIndex,  // IN: command index
+		UINT32           handleIndex    // IN: handle index (zero based)
+		);
+int
+EncryptSize(
+	    COMMAND_INDEX    commandIndex   // IN: command index
+	    );
+int
+DecryptSize(
+	    COMMAND_INDEX    commandIndex   // IN: command index
+	    );
+BOOL
+IsSessionAllowed(
+		 COMMAND_INDEX    commandIndex   // IN: the command to be checked
+		 );
+BOOL
+IsHandleInResponse(
+		   COMMAND_INDEX    commandIndex
+		   );
+BOOL
+IsWriteOperation(
+		 COMMAND_INDEX    commandIndex   // IN: Command to check
+		 );
+BOOL
+IsReadOperation(
+		COMMAND_INDEX    commandIndex   // IN: Command to check
+		);
+TPMI_YES_NO
+CommandCapGetCCList(
+		    TPM_CC           commandCode,   // IN: start command code
+		    UINT32           count,         // IN: maximum count for number of entries in
+		    //     'commandList'
+		    TPML_CCA        *commandList    // OUT: list of TPMA_CC
+		    );
+BOOL
+IsVendorCommand(
+		COMMAND_INDEX    commandIndex   // IN: command index to check
+		);
+
+
+#endif

+ 4736 - 0
EVSE/GPL/ibmtpm1682/src/CommandDispatchData.h

@@ -0,0 +1,4736 @@
+/********************************************************************************/
+/*										*/
+/*			     Command DIspatch Data				*/
+/*			     Written by Ken Goldman				*/
+/*		       IBM Thomas J. Watson Research Center			*/
+/*            $Id: CommandDispatchData.h 1658 2021-01-22 23:14:01Z kgoldman $	*/
+/*										*/
+/*  Licenses and Notices							*/
+/*										*/
+/*  1. Copyright Licenses:							*/
+/*										*/
+/*  - Trusted Computing Group (TCG) grants to the user of the source code in	*/
+/*    this specification (the "Source Code") a worldwide, irrevocable, 		*/
+/*    nonexclusive, royalty free, copyright license to reproduce, create 	*/
+/*    derivative works, distribute, display and perform the Source Code and	*/
+/*    derivative works thereof, and to grant others the rights granted herein.	*/
+/*										*/
+/*  - The TCG grants to the user of the other parts of the specification 	*/
+/*    (other than the Source Code) the rights to reproduce, distribute, 	*/
+/*    display, and perform the specification solely for the purpose of 		*/
+/*    developing products based on such documents.				*/
+/*										*/
+/*  2. Source Code Distribution Conditions:					*/
+/*										*/
+/*  - Redistributions of Source Code must retain the above copyright licenses, 	*/
+/*    this list of conditions and the following disclaimers.			*/
+/*										*/
+/*  - Redistributions in binary form must reproduce the above copyright 	*/
+/*    licenses, this list of conditions	and the following disclaimers in the 	*/
+/*    documentation and/or other materials provided with the distribution.	*/
+/*										*/
+/*  3. Disclaimers:								*/
+/*										*/
+/*  - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF	*/
+/*  LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH	*/
+/*  RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES)	*/
+/*  THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE.		*/
+/*  Contact TCG Administration (admin@trustedcomputinggroup.org) for 		*/
+/*  information on specification licensing rights available through TCG 	*/
+/*  membership agreements.							*/
+/*										*/
+/*  - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED 	*/
+/*    WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR 	*/
+/*    FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR 		*/
+/*    NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY 		*/
+/*    OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE.		*/
+/*										*/
+/*  - Without limitation, TCG and its members and licensors disclaim all 	*/
+/*    liability, including liability for infringement of any proprietary 	*/
+/*    rights, relating to use of information in this specification and to the	*/
+/*    implementation of this specification, and TCG disclaims all liability for	*/
+/*    cost of procurement of substitute goods or services, lost profits, loss 	*/
+/*    of use, loss of data or any incidental, consequential, direct, indirect, 	*/
+/*    or special damages, whether under contract, tort, warranty or otherwise, 	*/
+/*    arising in any way out of use or reliance upon this specification or any 	*/
+/*    information herein.							*/
+/*										*/
+/*  (c) Copyright IBM Corp. and others, 2016 - 2021				*/
+/*										*/
+/********************************************************************************/
+
+/* This file should only be included by CommandCodeAttibutes.c */
+#ifdef _COMMAND_TABLE_DISPATCH_
+
+#define END_OF_LIST     0xff
+#define ADD_FLAG        0x80
+
+#ifdef TPM_NUVOTON
+#include "ntc2_fp.h"
+#include "ntc2lib.h"
+#endif
+
+/* These macros provide some variability in how the data is encoded. They also make the lines a
+   little shorter. ;-) */
+
+#if TABLE_DRIVEN_MARSHAL
+#   define UNMARSHAL_DISPATCH(name)   (marshalIndex_t)name##_MARSHAL_REF
+#   define MARSHAL_DISPATCH(name)     (marshalIndex_t)name##_MARSHAL_REF
+#   define _UNMARSHAL_T_    marshalIndex_t
+#   define _MARSHAL_T_      marshalIndex_t
+#
+#else
+#   define UNMARSHAL_DISPATCH(name)   (UNMARSHAL_t)name##_Unmarshal
+#   define MARSHAL_DISPATCH(name)     (MARSHAL_t)name##_Marshal
+#   define _UNMARSHAL_T_    UNMARSHAL_t
+#   define _MARSHAL_T_      MARSHAL_t
+#endif
+
+const _UNMARSHAL_T_ unmarshalArray[] = {
+#define TPMI_DH_CONTEXT_H_UNMARSHAL             0
+					UNMARSHAL_DISPATCH(TPMI_DH_CONTEXT),
+#define TPMI_RH_AC_H_UNMARSHAL                  (TPMI_DH_CONTEXT_H_UNMARSHAL + 1)
+					UNMARSHAL_DISPATCH(TPMI_RH_AC),
+#define TPMI_RH_ACT_H_UNMARSHAL                 (TPMI_RH_AC_H_UNMARSHAL + 1)
+					UNMARSHAL_DISPATCH(TPMI_RH_ACT),
+#define TPMI_RH_CLEAR_H_UNMARSHAL               (TPMI_RH_ACT_H_UNMARSHAL + 1)
+					UNMARSHAL_DISPATCH(TPMI_RH_CLEAR),
+#define TPMI_RH_HIERARCHY_AUTH_H_UNMARSHAL      (TPMI_RH_CLEAR_H_UNMARSHAL + 1)
+					UNMARSHAL_DISPATCH(TPMI_RH_HIERARCHY_AUTH),
+#define TPMI_RH_HIERARCHY_POLICY_H_UNMARSHAL				\
+					(TPMI_RH_HIERARCHY_AUTH_H_UNMARSHAL + 1)
+					UNMARSHAL_DISPATCH(TPMI_RH_HIERARCHY_POLICY),
+#define TPMI_RH_LOCKOUT_H_UNMARSHAL					\
+					(TPMI_RH_HIERARCHY_POLICY_H_UNMARSHAL + 1)
+					UNMARSHAL_DISPATCH(TPMI_RH_LOCKOUT),
+#define TPMI_RH_NV_AUTH_H_UNMARSHAL             (TPMI_RH_LOCKOUT_H_UNMARSHAL + 1)
+					UNMARSHAL_DISPATCH(TPMI_RH_NV_AUTH),
+#define TPMI_RH_NV_INDEX_H_UNMARSHAL            (TPMI_RH_NV_AUTH_H_UNMARSHAL + 1)
+					UNMARSHAL_DISPATCH(TPMI_RH_NV_INDEX),
+#define TPMI_RH_PLATFORM_H_UNMARSHAL            (TPMI_RH_NV_INDEX_H_UNMARSHAL + 1)
+					UNMARSHAL_DISPATCH(TPMI_RH_PLATFORM),
+#define TPMI_RH_PROVISION_H_UNMARSHAL           (TPMI_RH_PLATFORM_H_UNMARSHAL + 1)
+					UNMARSHAL_DISPATCH(TPMI_RH_PROVISION),
+#define TPMI_SH_HMAC_H_UNMARSHAL                (TPMI_RH_PROVISION_H_UNMARSHAL + 1)
+					UNMARSHAL_DISPATCH(TPMI_SH_HMAC),
+#define TPMI_SH_POLICY_H_UNMARSHAL              (TPMI_SH_HMAC_H_UNMARSHAL + 1)
+					UNMARSHAL_DISPATCH(TPMI_SH_POLICY),
+					// HANDLE_FIRST_FLAG_TYPE is the first handle that needs a flag when called.
+#define HANDLE_FIRST_FLAG_TYPE                  (TPMI_SH_POLICY_H_UNMARSHAL + 1)
+#define TPMI_DH_ENTITY_H_UNMARSHAL              (TPMI_SH_POLICY_H_UNMARSHAL + 1)
+					UNMARSHAL_DISPATCH(TPMI_DH_ENTITY),
+#define TPMI_DH_OBJECT_H_UNMARSHAL              (TPMI_DH_ENTITY_H_UNMARSHAL + 1)
+					UNMARSHAL_DISPATCH(TPMI_DH_OBJECT),
+#define TPMI_DH_PARENT_H_UNMARSHAL              (TPMI_DH_OBJECT_H_UNMARSHAL + 1)
+					UNMARSHAL_DISPATCH(TPMI_DH_PARENT),
+#define TPMI_DH_PCR_H_UNMARSHAL                 (TPMI_DH_PARENT_H_UNMARSHAL + 1)
+					UNMARSHAL_DISPATCH(TPMI_DH_PCR),
+#define TPMI_RH_ENDORSEMENT_H_UNMARSHAL         (TPMI_DH_PCR_H_UNMARSHAL + 1)
+					UNMARSHAL_DISPATCH(TPMI_RH_ENDORSEMENT),
+#define TPMI_RH_HIERARCHY_H_UNMARSHAL					\
+					(TPMI_RH_ENDORSEMENT_H_UNMARSHAL + 1)
+					UNMARSHAL_DISPATCH(TPMI_RH_HIERARCHY),
+					// PARAMETER_FIRST_TYPE marks the end of the handle list.
+#define PARAMETER_FIRST_TYPE                    (TPMI_RH_HIERARCHY_H_UNMARSHAL + 1)
+#define TPM2B_DATA_P_UNMARSHAL                  (TPMI_RH_HIERARCHY_H_UNMARSHAL + 1)
+					UNMARSHAL_DISPATCH(TPM2B_DATA),
+#define TPM2B_DIGEST_P_UNMARSHAL                (TPM2B_DATA_P_UNMARSHAL + 1)
+					UNMARSHAL_DISPATCH(TPM2B_DIGEST),
+#define TPM2B_ECC_PARAMETER_P_UNMARSHAL         (TPM2B_DIGEST_P_UNMARSHAL + 1)
+					UNMARSHAL_DISPATCH(TPM2B_ECC_PARAMETER),
+#define TPM2B_ECC_POINT_P_UNMARSHAL					\
+					(TPM2B_ECC_PARAMETER_P_UNMARSHAL + 1)
+					UNMARSHAL_DISPATCH(TPM2B_ECC_POINT),
+#define TPM2B_ENCRYPTED_SECRET_P_UNMARSHAL      (TPM2B_ECC_POINT_P_UNMARSHAL + 1)
+					UNMARSHAL_DISPATCH(TPM2B_ENCRYPTED_SECRET),
+#define TPM2B_EVENT_P_UNMARSHAL						\
+					(TPM2B_ENCRYPTED_SECRET_P_UNMARSHAL + 1)
+					UNMARSHAL_DISPATCH(TPM2B_EVENT),
+#define TPM2B_ID_OBJECT_P_UNMARSHAL             (TPM2B_EVENT_P_UNMARSHAL + 1)
+					UNMARSHAL_DISPATCH(TPM2B_ID_OBJECT),
+#define TPM2B_IV_P_UNMARSHAL                    (TPM2B_ID_OBJECT_P_UNMARSHAL + 1)
+					UNMARSHAL_DISPATCH(TPM2B_IV),
+#define TPM2B_MAX_BUFFER_P_UNMARSHAL            (TPM2B_IV_P_UNMARSHAL + 1)
+					UNMARSHAL_DISPATCH(TPM2B_MAX_BUFFER),
+#define TPM2B_MAX_NV_BUFFER_P_UNMARSHAL         (TPM2B_MAX_BUFFER_P_UNMARSHAL + 1)
+					UNMARSHAL_DISPATCH(TPM2B_MAX_NV_BUFFER),
+#define TPM2B_NAME_P_UNMARSHAL						\
+					(TPM2B_MAX_NV_BUFFER_P_UNMARSHAL + 1)
+					UNMARSHAL_DISPATCH(TPM2B_NAME),
+#define TPM2B_NV_PUBLIC_P_UNMARSHAL             (TPM2B_NAME_P_UNMARSHAL + 1)
+					UNMARSHAL_DISPATCH(TPM2B_NV_PUBLIC),
+#define TPM2B_PRIVATE_P_UNMARSHAL               (TPM2B_NV_PUBLIC_P_UNMARSHAL + 1)
+					UNMARSHAL_DISPATCH(TPM2B_PRIVATE),
+#define TPM2B_PUBLIC_KEY_RSA_P_UNMARSHAL        (TPM2B_PRIVATE_P_UNMARSHAL + 1)
+					UNMARSHAL_DISPATCH(TPM2B_PUBLIC_KEY_RSA),
+#define TPM2B_SENSITIVE_P_UNMARSHAL					\
+					(TPM2B_PUBLIC_KEY_RSA_P_UNMARSHAL + 1)
+					UNMARSHAL_DISPATCH(TPM2B_SENSITIVE),
+#define TPM2B_SENSITIVE_CREATE_P_UNMARSHAL      (TPM2B_SENSITIVE_P_UNMARSHAL + 1)
+					UNMARSHAL_DISPATCH(TPM2B_SENSITIVE_CREATE),
+#define TPM2B_SENSITIVE_DATA_P_UNMARSHAL				\
+					(TPM2B_SENSITIVE_CREATE_P_UNMARSHAL + 1)
+					UNMARSHAL_DISPATCH(TPM2B_SENSITIVE_DATA),
+#define TPM2B_TEMPLATE_P_UNMARSHAL					\
+					(TPM2B_SENSITIVE_DATA_P_UNMARSHAL + 1)
+					UNMARSHAL_DISPATCH(TPM2B_TEMPLATE),
+#define TPM2B_TIMEOUT_P_UNMARSHAL               (TPM2B_TEMPLATE_P_UNMARSHAL + 1)
+					UNMARSHAL_DISPATCH(TPM2B_TIMEOUT),
+#define TPMI_DH_CONTEXT_P_UNMARSHAL             (TPM2B_TIMEOUT_P_UNMARSHAL + 1)
+					UNMARSHAL_DISPATCH(TPMI_DH_CONTEXT),
+#define TPMI_DH_PERSISTENT_P_UNMARSHAL          (TPMI_DH_CONTEXT_P_UNMARSHAL + 1)
+					UNMARSHAL_DISPATCH(TPMI_DH_PERSISTENT),
+#define TPMI_ECC_CURVE_P_UNMARSHAL              (TPMI_DH_PERSISTENT_P_UNMARSHAL + 1)
+					UNMARSHAL_DISPATCH(TPMI_ECC_CURVE),
+#define TPMI_YES_NO_P_UNMARSHAL                 (TPMI_ECC_CURVE_P_UNMARSHAL + 1)
+					UNMARSHAL_DISPATCH(TPMI_YES_NO),
+#define TPML_ALG_P_UNMARSHAL                    (TPMI_YES_NO_P_UNMARSHAL + 1)
+					UNMARSHAL_DISPATCH(TPML_ALG),
+#define TPML_CC_P_UNMARSHAL                     (TPML_ALG_P_UNMARSHAL + 1)
+					UNMARSHAL_DISPATCH(TPML_CC),
+#define TPML_DIGEST_P_UNMARSHAL                 (TPML_CC_P_UNMARSHAL + 1)
+					UNMARSHAL_DISPATCH(TPML_DIGEST),
+#define TPML_DIGEST_VALUES_P_UNMARSHAL          (TPML_DIGEST_P_UNMARSHAL + 1)
+					UNMARSHAL_DISPATCH(TPML_DIGEST_VALUES),
+#define TPML_PCR_SELECTION_P_UNMARSHAL          (TPML_DIGEST_VALUES_P_UNMARSHAL + 1)
+					UNMARSHAL_DISPATCH(TPML_PCR_SELECTION),
+#define TPMS_CONTEXT_P_UNMARSHAL                (TPML_PCR_SELECTION_P_UNMARSHAL + 1)
+					UNMARSHAL_DISPATCH(TPMS_CONTEXT),
+#define TPMT_PUBLIC_PARMS_P_UNMARSHAL           (TPMS_CONTEXT_P_UNMARSHAL + 1)
+					UNMARSHAL_DISPATCH(TPMT_PUBLIC_PARMS),
+#define TPMT_TK_AUTH_P_UNMARSHAL                (TPMT_PUBLIC_PARMS_P_UNMARSHAL + 1)
+					UNMARSHAL_DISPATCH(TPMT_TK_AUTH),
+#define TPMT_TK_CREATION_P_UNMARSHAL            (TPMT_TK_AUTH_P_UNMARSHAL + 1)
+					UNMARSHAL_DISPATCH(TPMT_TK_CREATION),
+#define TPMT_TK_HASHCHECK_P_UNMARSHAL           (TPMT_TK_CREATION_P_UNMARSHAL + 1)
+					UNMARSHAL_DISPATCH(TPMT_TK_HASHCHECK),
+#define TPMT_TK_VERIFIED_P_UNMARSHAL            (TPMT_TK_HASHCHECK_P_UNMARSHAL + 1)
+					UNMARSHAL_DISPATCH(TPMT_TK_VERIFIED),
+#define TPM_AT_P_UNMARSHAL                      (TPMT_TK_VERIFIED_P_UNMARSHAL + 1)
+					UNMARSHAL_DISPATCH(TPM_AT),
+#define TPM_CAP_P_UNMARSHAL                     (TPM_AT_P_UNMARSHAL + 1)
+					UNMARSHAL_DISPATCH(TPM_CAP),
+#define TPM_CLOCK_ADJUST_P_UNMARSHAL            (TPM_CAP_P_UNMARSHAL + 1)
+					UNMARSHAL_DISPATCH(TPM_CLOCK_ADJUST),
+#define TPM_EO_P_UNMARSHAL                      (TPM_CLOCK_ADJUST_P_UNMARSHAL + 1)
+					UNMARSHAL_DISPATCH(TPM_EO),
+#define TPM_SE_P_UNMARSHAL                      (TPM_EO_P_UNMARSHAL + 1)
+					UNMARSHAL_DISPATCH(TPM_SE),
+#define TPM_SU_P_UNMARSHAL                      (TPM_SE_P_UNMARSHAL + 1)
+					UNMARSHAL_DISPATCH(TPM_SU),
+#define UINT16_P_UNMARSHAL                      (TPM_SU_P_UNMARSHAL + 1)
+					UNMARSHAL_DISPATCH(UINT16),
+#define UINT32_P_UNMARSHAL                      (UINT16_P_UNMARSHAL + 1)
+					UNMARSHAL_DISPATCH(UINT32),
+#define UINT64_P_UNMARSHAL                      (UINT32_P_UNMARSHAL + 1)
+					UNMARSHAL_DISPATCH(UINT64),
+#define UINT8_P_UNMARSHAL                       (UINT64_P_UNMARSHAL + 1)
+					UNMARSHAL_DISPATCH(UINT8),
+					// PARAMETER_FIRST_FLAG_TYPE is the first parameter to need a flag.
+#define PARAMETER_FIRST_FLAG_TYPE               (UINT8_P_UNMARSHAL + 1)
+#define TPM2B_PUBLIC_P_UNMARSHAL                (UINT8_P_UNMARSHAL + 1)
+					UNMARSHAL_DISPATCH(TPM2B_PUBLIC),
+#define TPMI_ALG_CIPHER_MODE_P_UNMARSHAL        (TPM2B_PUBLIC_P_UNMARSHAL + 1)
+					UNMARSHAL_DISPATCH(TPMI_ALG_CIPHER_MODE),
+#define TPMI_ALG_HASH_P_UNMARSHAL					\
+					(TPMI_ALG_CIPHER_MODE_P_UNMARSHAL + 1)
+					UNMARSHAL_DISPATCH(TPMI_ALG_HASH),
+#define TPMI_ALG_MAC_SCHEME_P_UNMARSHAL         (TPMI_ALG_HASH_P_UNMARSHAL + 1)
+					UNMARSHAL_DISPATCH(TPMI_ALG_MAC_SCHEME),
+#define TPMI_DH_PCR_P_UNMARSHAL						\
+					(TPMI_ALG_MAC_SCHEME_P_UNMARSHAL + 1)
+					UNMARSHAL_DISPATCH(TPMI_DH_PCR),
+#define TPMI_ECC_KEY_EXCHANGE_P_UNMARSHAL       (TPMI_DH_PCR_P_UNMARSHAL + 1)
+					UNMARSHAL_DISPATCH(TPMI_ECC_KEY_EXCHANGE),
+#define TPMI_RH_ENABLES_P_UNMARSHAL					\
+					(TPMI_ECC_KEY_EXCHANGE_P_UNMARSHAL + 1)
+					UNMARSHAL_DISPATCH(TPMI_RH_ENABLES),
+#define TPMI_RH_HIERARCHY_P_UNMARSHAL           (TPMI_RH_ENABLES_P_UNMARSHAL + 1)
+					UNMARSHAL_DISPATCH(TPMI_RH_HIERARCHY),
+#define TPMT_KDF_SCHEME_P_UNMARSHAL             (TPMI_RH_HIERARCHY_P_UNMARSHAL + 1)
+					UNMARSHAL_DISPATCH(TPMT_KDF_SCHEME),
+#define TPMT_RSA_DECRYPT_P_UNMARSHAL            (TPMT_KDF_SCHEME_P_UNMARSHAL + 1)
+					UNMARSHAL_DISPATCH(TPMT_RSA_DECRYPT),
+#define TPMT_SIGNATURE_P_UNMARSHAL              (TPMT_RSA_DECRYPT_P_UNMARSHAL + 1)
+					UNMARSHAL_DISPATCH(TPMT_SIGNATURE),
+#define TPMT_SIG_SCHEME_P_UNMARSHAL             (TPMT_SIGNATURE_P_UNMARSHAL + 1)
+					UNMARSHAL_DISPATCH(TPMT_SIG_SCHEME),
+#define TPMT_SYM_DEF_P_UNMARSHAL                (TPMT_SIG_SCHEME_P_UNMARSHAL + 1)
+					UNMARSHAL_DISPATCH(TPMT_SYM_DEF),
+#define TPMT_SYM_DEF_OBJECT_P_UNMARSHAL         (TPMT_SYM_DEF_P_UNMARSHAL + 1)
+					UNMARSHAL_DISPATCH(TPMT_SYM_DEF_OBJECT)
+					// PARAMETER_LAST_TYPE is the end of the command parameter list.
+#ifdef TPM_NUVOTON
+,
+#define NTC2_CFG_STRUCT_P_UNMARSHAL	(TPMT_SYM_DEF_OBJECT_P_UNMARSHAL + 1)
+					UNMARSHAL_DISPATCH(NTC2_CFG_STRUCT)
+					
+#define PARAMETER_LAST_TYPE             (NTC2_CFG_STRUCT_P_UNMARSHAL)
+
+#else
+
+    // PARAMETER_LAST_TYPE is the end of the command parameter list.    
+#define PARAMETER_LAST_TYPE             (TPMT_SYM_DEF_OBJECT_P_UNMARSHAL)
+
+#endif	/* TPM_NUVOTON */
+
+};
+
+
+const _MARSHAL_T_ marshalArray[] = {
+
+#define UINT32_H_MARSHAL                        0
+				    MARSHAL_DISPATCH(UINT32),
+				    // RESPONSE_PARAMETER_FIRST_TYPE marks the end of the response handles.
+#define RESPONSE_PARAMETER_FIRST_TYPE           (UINT32_H_MARSHAL + 1)
+#define TPM2B_ATTEST_P_MARSHAL                  (UINT32_H_MARSHAL + 1)
+				    MARSHAL_DISPATCH(TPM2B_ATTEST),
+#define TPM2B_CREATION_DATA_P_MARSHAL           (TPM2B_ATTEST_P_MARSHAL + 1)
+				    MARSHAL_DISPATCH(TPM2B_CREATION_DATA),
+#define TPM2B_DATA_P_MARSHAL                    (TPM2B_CREATION_DATA_P_MARSHAL + 1)
+				    MARSHAL_DISPATCH(TPM2B_DATA),
+#define TPM2B_DIGEST_P_MARSHAL                  (TPM2B_DATA_P_MARSHAL + 1)
+				    MARSHAL_DISPATCH(TPM2B_DIGEST),
+#define TPM2B_ECC_POINT_P_MARSHAL               (TPM2B_DIGEST_P_MARSHAL + 1)
+				    MARSHAL_DISPATCH(TPM2B_ECC_POINT),
+#define TPM2B_ENCRYPTED_SECRET_P_MARSHAL        (TPM2B_ECC_POINT_P_MARSHAL + 1)
+				    MARSHAL_DISPATCH(TPM2B_ENCRYPTED_SECRET),
+#define TPM2B_ID_OBJECT_P_MARSHAL					\
+				    (TPM2B_ENCRYPTED_SECRET_P_MARSHAL + 1)
+				    MARSHAL_DISPATCH(TPM2B_ID_OBJECT),
+#define TPM2B_IV_P_MARSHAL                      (TPM2B_ID_OBJECT_P_MARSHAL + 1)
+				    MARSHAL_DISPATCH(TPM2B_IV),
+#define TPM2B_MAX_BUFFER_P_MARSHAL              (TPM2B_IV_P_MARSHAL + 1)
+				    MARSHAL_DISPATCH(TPM2B_MAX_BUFFER),
+#define TPM2B_MAX_NV_BUFFER_P_MARSHAL           (TPM2B_MAX_BUFFER_P_MARSHAL + 1)
+				    MARSHAL_DISPATCH(TPM2B_MAX_NV_BUFFER),
+#define TPM2B_NAME_P_MARSHAL                    (TPM2B_MAX_NV_BUFFER_P_MARSHAL + 1)
+				    MARSHAL_DISPATCH(TPM2B_NAME),
+#define TPM2B_NV_PUBLIC_P_MARSHAL               (TPM2B_NAME_P_MARSHAL + 1)
+				    MARSHAL_DISPATCH(TPM2B_NV_PUBLIC),
+#define TPM2B_PRIVATE_P_MARSHAL                 (TPM2B_NV_PUBLIC_P_MARSHAL + 1)
+				    MARSHAL_DISPATCH(TPM2B_PRIVATE),
+#define TPM2B_PUBLIC_P_MARSHAL                  (TPM2B_PRIVATE_P_MARSHAL + 1)
+				    MARSHAL_DISPATCH(TPM2B_PUBLIC),
+#define TPM2B_PUBLIC_KEY_RSA_P_MARSHAL          (TPM2B_PUBLIC_P_MARSHAL + 1)
+				    MARSHAL_DISPATCH(TPM2B_PUBLIC_KEY_RSA),
+#define TPM2B_SENSITIVE_DATA_P_MARSHAL          (TPM2B_PUBLIC_KEY_RSA_P_MARSHAL + 1)
+				    MARSHAL_DISPATCH(TPM2B_SENSITIVE_DATA),
+#define TPM2B_TIMEOUT_P_MARSHAL                 (TPM2B_SENSITIVE_DATA_P_MARSHAL + 1)
+				    MARSHAL_DISPATCH(TPM2B_TIMEOUT),
+#define UINT8_P_MARSHAL                         (TPM2B_TIMEOUT_P_MARSHAL + 1)
+				    MARSHAL_DISPATCH(UINT8),
+#define TPML_AC_CAPABILITIES_P_MARSHAL          (UINT8_P_MARSHAL + 1)
+				    MARSHAL_DISPATCH(TPML_AC_CAPABILITIES),
+#define TPML_ALG_P_MARSHAL                      (TPML_AC_CAPABILITIES_P_MARSHAL + 1)
+				    MARSHAL_DISPATCH(TPML_ALG),
+#define TPML_DIGEST_P_MARSHAL                   (TPML_ALG_P_MARSHAL + 1)
+				    MARSHAL_DISPATCH(TPML_DIGEST),
+#define TPML_DIGEST_VALUES_P_MARSHAL            (TPML_DIGEST_P_MARSHAL + 1)
+				    MARSHAL_DISPATCH(TPML_DIGEST_VALUES),
+#define TPML_PCR_SELECTION_P_MARSHAL            (TPML_DIGEST_VALUES_P_MARSHAL + 1)
+				    MARSHAL_DISPATCH(TPML_PCR_SELECTION),
+#define TPMS_AC_OUTPUT_P_MARSHAL                (TPML_PCR_SELECTION_P_MARSHAL + 1)
+				    MARSHAL_DISPATCH(TPMS_AC_OUTPUT),
+#define TPMS_ALGORITHM_DETAIL_ECC_P_MARSHAL     (TPMS_AC_OUTPUT_P_MARSHAL + 1)
+				    MARSHAL_DISPATCH(TPMS_ALGORITHM_DETAIL_ECC),
+#define TPMS_CAPABILITY_DATA_P_MARSHAL					\
+				    (TPMS_ALGORITHM_DETAIL_ECC_P_MARSHAL + 1)
+				    MARSHAL_DISPATCH(TPMS_CAPABILITY_DATA),
+#define TPMS_CONTEXT_P_MARSHAL                  (TPMS_CAPABILITY_DATA_P_MARSHAL + 1)
+				    MARSHAL_DISPATCH(TPMS_CONTEXT),
+#define TPMS_TIME_INFO_P_MARSHAL                (TPMS_CONTEXT_P_MARSHAL + 1)
+				    MARSHAL_DISPATCH(TPMS_TIME_INFO),
+#define TPMT_HA_P_MARSHAL                       (TPMS_TIME_INFO_P_MARSHAL + 1)
+				    MARSHAL_DISPATCH(TPMT_HA),
+#define TPMT_SIGNATURE_P_MARSHAL                (TPMT_HA_P_MARSHAL + 1)
+				    MARSHAL_DISPATCH(TPMT_SIGNATURE),
+#define TPMT_TK_AUTH_P_MARSHAL                  (TPMT_SIGNATURE_P_MARSHAL + 1)
+				    MARSHAL_DISPATCH(TPMT_TK_AUTH),
+#define TPMT_TK_CREATION_P_MARSHAL              (TPMT_TK_AUTH_P_MARSHAL + 1)
+				    MARSHAL_DISPATCH(TPMT_TK_CREATION),
+#define TPMT_TK_HASHCHECK_P_MARSHAL             (TPMT_TK_CREATION_P_MARSHAL + 1)
+				    MARSHAL_DISPATCH(TPMT_TK_HASHCHECK),
+#define TPMT_TK_VERIFIED_P_MARSHAL              (TPMT_TK_HASHCHECK_P_MARSHAL + 1)
+				    MARSHAL_DISPATCH(TPMT_TK_VERIFIED),
+#define UINT32_P_MARSHAL                        (TPMT_TK_VERIFIED_P_MARSHAL + 1)
+				    MARSHAL_DISPATCH(UINT32),
+#define UINT16_P_MARSHAL                        (UINT32_P_MARSHAL + 1)
+				    MARSHAL_DISPATCH(UINT16)
+
+#ifdef TPM_NUVOTON
+,
+#define NTC2_CFG_STRUCT_P_MARSHAL		(UINT16_P_MARSHAL + 1)
+				    MARSHAL_DISPATCH(NTC2_CFG_STRUCT)
+
+#define RESPONSE_PARAMETER_LAST_TYPE    (NTC2_CFG_STRUCT_P_MARSHAL)
+
+#else     
+				    // RESPONSE_PARAMETER_LAST_TYPE is the end of the response parameter list.
+#define RESPONSE_PARAMETER_LAST_TYPE    (UINT16_P_MARSHAL)
+
+#endif	/* TPM_NUVOTON */
+				    // RESPONSE_PARAMETER_LAST_TYPE is the end of the response parameter list.
+};
+
+/* This list of aliases allows the types in the _COMMAND_DESCRIPTOR_T to match the types in the
+   command/response templates of part 3. */
+#define INT32_P_UNMARSHAL                   UINT32_P_UNMARSHAL
+#define TPM2B_AUTH_P_UNMARSHAL              TPM2B_DIGEST_P_UNMARSHAL
+#define TPM2B_NONCE_P_UNMARSHAL             TPM2B_DIGEST_P_UNMARSHAL
+#define TPM2B_OPERAND_P_UNMARSHAL           TPM2B_DIGEST_P_UNMARSHAL
+#define TPMA_LOCALITY_P_UNMARSHAL           UINT8_P_UNMARSHAL
+#define TPM_CC_P_UNMARSHAL                  UINT32_P_UNMARSHAL
+#define TPMI_DH_CONTEXT_H_MARSHAL           UINT32_H_MARSHAL
+#define TPMI_DH_OBJECT_H_MARSHAL            UINT32_H_MARSHAL
+#define TPMI_SH_AUTH_SESSION_H_MARSHAL      UINT32_H_MARSHAL
+#define TPM_HANDLE_H_MARSHAL                UINT32_H_MARSHAL
+#define TPM2B_NONCE_P_MARSHAL               TPM2B_DIGEST_P_MARSHAL
+#define TPMI_YES_NO_P_MARSHAL               UINT8_P_MARSHAL
+#define TPM_RC_P_MARSHAL                    UINT32_P_MARSHAL
+
+#if CC_Startup
+#include "Startup_fp.h"
+typedef TPM_RC  (Startup_Entry)(
+				Startup_In *in
+				);
+typedef const struct {
+    Startup_Entry    *entry;
+    UINT16           inSize;
+    UINT16           outSize;
+    UINT16           offsetOfTypes;
+    BYTE             types[3];
+} Startup_COMMAND_DESCRIPTOR_t;
+Startup_COMMAND_DESCRIPTOR_t _StartupData = {
+    /* entry  */          &TPM2_Startup,
+    /* inSize */          (UINT16)(sizeof(Startup_In)),
+    /* outSize */         0,
+    /* offsetOfTypes */   offsetof(Startup_COMMAND_DESCRIPTOR_t, types),
+    /* offsets */         // No parameter offsets
+    /* types */           {TPM_SU_P_UNMARSHAL,
+			   END_OF_LIST,
+			   END_OF_LIST}
+};
+#define _StartupDataAddress (&_StartupData)
+#else
+#define _StartupDataAddress 0
+#endif
+#if CC_Shutdown
+#include "Shutdown_fp.h"
+typedef TPM_RC  (Shutdown_Entry)(
+				 Shutdown_In *in
+				 );
+typedef const struct {
+    Shutdown_Entry    *entry;
+    UINT16            inSize;
+    UINT16            outSize;
+    UINT16            offsetOfTypes;
+    BYTE              types[3];
+} Shutdown_COMMAND_DESCRIPTOR_t;
+Shutdown_COMMAND_DESCRIPTOR_t _ShutdownData = {
+    /* entry  */          &TPM2_Shutdown,
+    /* inSize */          (UINT16)(sizeof(Shutdown_In)),
+    /* outSize */         0,
+    /* offsetOfTypes */   offsetof(Shutdown_COMMAND_DESCRIPTOR_t, types),
+    /* offsets */         // No parameter offsets
+    /* types */           {TPM_SU_P_UNMARSHAL,
+			   END_OF_LIST,
+			   END_OF_LIST}
+};
+#define _ShutdownDataAddress (&_ShutdownData)
+#else
+#define _ShutdownDataAddress 0
+#endif
+#if CC_SelfTest
+#include "SelfTest_fp.h"
+typedef TPM_RC  (SelfTest_Entry)(
+				 SelfTest_In *in
+				 );
+typedef const struct {
+    SelfTest_Entry    *entry;
+    UINT16            inSize;
+    UINT16            outSize;
+    UINT16            offsetOfTypes;
+    BYTE              types[3];
+} SelfTest_COMMAND_DESCRIPTOR_t;
+SelfTest_COMMAND_DESCRIPTOR_t _SelfTestData = {
+    /* entry  */          &TPM2_SelfTest,
+    /* inSize */          (UINT16)(sizeof(SelfTest_In)),
+    /* outSize */         0,
+    /* offsetOfTypes */   offsetof(SelfTest_COMMAND_DESCRIPTOR_t, types),
+    /* offsets */         // No parameter offsets
+    /* types */           {TPMI_YES_NO_P_UNMARSHAL,
+			   END_OF_LIST,
+			   END_OF_LIST}
+};
+#define _SelfTestDataAddress (&_SelfTestData)
+#else
+#define _SelfTestDataAddress 0
+#endif
+#if CC_IncrementalSelfTest
+#include "IncrementalSelfTest_fp.h"
+typedef TPM_RC  (IncrementalSelfTest_Entry)(
+					    IncrementalSelfTest_In *in,
+					    IncrementalSelfTest_Out *out
+					    );
+typedef const struct {
+    IncrementalSelfTest_Entry    *entry;
+    UINT16                       inSize;
+    UINT16                       outSize;
+    UINT16                       offsetOfTypes;
+    BYTE                         types[4];
+} IncrementalSelfTest_COMMAND_DESCRIPTOR_t;
+IncrementalSelfTest_COMMAND_DESCRIPTOR_t _IncrementalSelfTestData = {
+    /* entry  */          &TPM2_IncrementalSelfTest,
+    /* inSize */          (UINT16)(sizeof(IncrementalSelfTest_In)),
+    /* outSize */         (UINT16)(sizeof(IncrementalSelfTest_Out)),
+    /* offsetOfTypes */   offsetof(IncrementalSelfTest_COMMAND_DESCRIPTOR_t, types),
+    /* offsets */         // No parameter offsets
+    /* types */           {TPML_ALG_P_UNMARSHAL,
+			   END_OF_LIST,
+			   TPML_ALG_P_MARSHAL,
+			   END_OF_LIST}
+};
+#define _IncrementalSelfTestDataAddress (&_IncrementalSelfTestData)
+#else
+#define _IncrementalSelfTestDataAddress 0
+#endif
+#if CC_GetTestResult
+#include "GetTestResult_fp.h"
+typedef TPM_RC  (GetTestResult_Entry)(
+				      GetTestResult_Out *out
+				      );
+typedef const struct {
+    GetTestResult_Entry    *entry;
+    UINT16                 inSize;
+    UINT16                 outSize;
+    UINT16                 offsetOfTypes;
+    UINT16                 paramOffsets[1];
+    BYTE                   types[4];
+} GetTestResult_COMMAND_DESCRIPTOR_t;
+GetTestResult_COMMAND_DESCRIPTOR_t _GetTestResultData = {
+    /* entry  */          &TPM2_GetTestResult,
+    /* inSize */          0,
+    /* outSize */         (UINT16)(sizeof(GetTestResult_Out)),
+    /* offsetOfTypes */   offsetof(GetTestResult_COMMAND_DESCRIPTOR_t, types),
+    /* offsets */         {(UINT16)(offsetof(GetTestResult_Out, testResult))},
+    /* types */           {END_OF_LIST,
+			   TPM2B_MAX_BUFFER_P_MARSHAL,
+			   TPM_RC_P_MARSHAL,
+			   END_OF_LIST}
+};
+#define _GetTestResultDataAddress (&_GetTestResultData)
+#else
+#define _GetTestResultDataAddress 0
+#endif
+#if CC_StartAuthSession
+#include "StartAuthSession_fp.h"
+typedef TPM_RC  (StartAuthSession_Entry)(
+					 StartAuthSession_In *in,
+					 StartAuthSession_Out *out
+					 );
+typedef const struct {
+    StartAuthSession_Entry    *entry;
+    UINT16                    inSize;
+    UINT16                    outSize;
+    UINT16                    offsetOfTypes;
+    UINT16                    paramOffsets[7];
+    BYTE                      types[11];
+} StartAuthSession_COMMAND_DESCRIPTOR_t;
+StartAuthSession_COMMAND_DESCRIPTOR_t _StartAuthSessionData = {
+    /* entry  */          &TPM2_StartAuthSession,
+    /* inSize */          (UINT16)(sizeof(StartAuthSession_In)),
+    /* outSize */         (UINT16)(sizeof(StartAuthSession_Out)),
+    /* offsetOfTypes */   offsetof(StartAuthSession_COMMAND_DESCRIPTOR_t, types),
+    /* offsets */         {(UINT16)(offsetof(StartAuthSession_In, bind)),
+			   (UINT16)(offsetof(StartAuthSession_In, nonceCaller)),
+			   (UINT16)(offsetof(StartAuthSession_In, encryptedSalt)),
+			   (UINT16)(offsetof(StartAuthSession_In, sessionType)),
+			   (UINT16)(offsetof(StartAuthSession_In, symmetric)),
+			   (UINT16)(offsetof(StartAuthSession_In, authHash)),
+			   (UINT16)(offsetof(StartAuthSession_Out, nonceTPM))},
+    /* types */           {TPMI_DH_OBJECT_H_UNMARSHAL + ADD_FLAG,
+			   TPMI_DH_ENTITY_H_UNMARSHAL + ADD_FLAG,
+			   TPM2B_NONCE_P_UNMARSHAL,
+			   TPM2B_ENCRYPTED_SECRET_P_UNMARSHAL,
+			   TPM_SE_P_UNMARSHAL,
+			   TPMT_SYM_DEF_P_UNMARSHAL + ADD_FLAG,
+			   TPMI_ALG_HASH_P_UNMARSHAL,
+			   END_OF_LIST,
+			   TPMI_SH_AUTH_SESSION_H_MARSHAL,
+			   TPM2B_NONCE_P_MARSHAL,
+			   END_OF_LIST}
+};
+#define _StartAuthSessionDataAddress (&_StartAuthSessionData)
+#else
+#define _StartAuthSessionDataAddress 0
+#endif
+#if CC_PolicyRestart
+#include "PolicyRestart_fp.h"
+typedef TPM_RC  (PolicyRestart_Entry)(
+				      PolicyRestart_In *in
+				      );
+typedef const struct {
+    PolicyRestart_Entry    *entry;
+    UINT16                 inSize;
+    UINT16                 outSize;
+    UINT16                 offsetOfTypes;
+    BYTE                   types[3];
+} PolicyRestart_COMMAND_DESCRIPTOR_t;
+PolicyRestart_COMMAND_DESCRIPTOR_t _PolicyRestartData = {
+    /* entry  */          &TPM2_PolicyRestart,
+    /* inSize */          (UINT16)(sizeof(PolicyRestart_In)),
+    /* outSize */         0,
+    /* offsetOfTypes */   offsetof(PolicyRestart_COMMAND_DESCRIPTOR_t, types),
+    /* offsets */         // No parameter offsets
+    /* types */           {TPMI_SH_POLICY_H_UNMARSHAL,
+			   END_OF_LIST,
+			   END_OF_LIST}
+};
+#define _PolicyRestartDataAddress (&_PolicyRestartData)
+#else
+#define _PolicyRestartDataAddress 0
+#endif
+#if CC_Create
+#include "Create_fp.h"
+typedef TPM_RC  (Create_Entry)(
+			       Create_In *in,
+			       Create_Out *out
+			       );
+typedef const struct {
+    Create_Entry    *entry;
+    UINT16          inSize;
+    UINT16          outSize;
+    UINT16          offsetOfTypes;
+    UINT16          paramOffsets[8];
+    BYTE            types[12];
+} Create_COMMAND_DESCRIPTOR_t;
+Create_COMMAND_DESCRIPTOR_t _CreateData = {
+    /* entry  */          &TPM2_Create,
+    /* inSize */          (UINT16)(sizeof(Create_In)),
+    /* outSize */         (UINT16)(sizeof(Create_Out)),
+    /* offsetOfTypes */   offsetof(Create_COMMAND_DESCRIPTOR_t, types),
+    /* offsets */         {(UINT16)(offsetof(Create_In, inSensitive)),
+			   (UINT16)(offsetof(Create_In, inPublic)),
+			   (UINT16)(offsetof(Create_In, outsideInfo)),
+			   (UINT16)(offsetof(Create_In, creationPCR)),
+			   (UINT16)(offsetof(Create_Out, outPublic)),
+			   (UINT16)(offsetof(Create_Out, creationData)),
+			   (UINT16)(offsetof(Create_Out, creationHash)),
+			   (UINT16)(offsetof(Create_Out, creationTicket))},
+    /* types */           {TPMI_DH_OBJECT_H_UNMARSHAL,
+			   TPM2B_SENSITIVE_CREATE_P_UNMARSHAL,
+			   TPM2B_PUBLIC_P_UNMARSHAL,
+			   TPM2B_DATA_P_UNMARSHAL,
+			   TPML_PCR_SELECTION_P_UNMARSHAL,
+			   END_OF_LIST,
+			   TPM2B_PRIVATE_P_MARSHAL,
+			   TPM2B_PUBLIC_P_MARSHAL,
+			   TPM2B_CREATION_DATA_P_MARSHAL,
+			   TPM2B_DIGEST_P_MARSHAL,
+			   TPMT_TK_CREATION_P_MARSHAL,
+			   END_OF_LIST}
+};
+#define _CreateDataAddress (&_CreateData)
+#else
+#define _CreateDataAddress 0
+#endif
+#if CC_Load
+#include "Load_fp.h"
+typedef TPM_RC  (Load_Entry)(
+			     Load_In *in,
+			     Load_Out *out
+			     );
+typedef const struct {
+    Load_Entry    *entry;
+    UINT16        inSize;
+    UINT16        outSize;
+    UINT16        offsetOfTypes;
+    UINT16        paramOffsets[3];
+    BYTE          types[7];
+} Load_COMMAND_DESCRIPTOR_t;
+Load_COMMAND_DESCRIPTOR_t _LoadData = {
+    /* entry  */          &TPM2_Load,
+    /* inSize */          (UINT16)(sizeof(Load_In)),
+    /* outSize */         (UINT16)(sizeof(Load_Out)),
+    /* offsetOfTypes */   offsetof(Load_COMMAND_DESCRIPTOR_t, types),
+    /* offsets */         {(UINT16)(offsetof(Load_In, inPrivate)),
+			   (UINT16)(offsetof(Load_In, inPublic)),
+			   (UINT16)(offsetof(Load_Out, name))},
+    /* types */           {TPMI_DH_OBJECT_H_UNMARSHAL,
+			   TPM2B_PRIVATE_P_UNMARSHAL,
+			   TPM2B_PUBLIC_P_UNMARSHAL,
+			   END_OF_LIST,
+			   TPM_HANDLE_H_MARSHAL,
+			   TPM2B_NAME_P_MARSHAL,
+			   END_OF_LIST}
+};
+#define _LoadDataAddress (&_LoadData)
+#else
+#define _LoadDataAddress 0
+#endif
+#if CC_LoadExternal
+#include "LoadExternal_fp.h"
+typedef TPM_RC  (LoadExternal_Entry)(
+				     LoadExternal_In *in,
+				     LoadExternal_Out *out
+				     );
+typedef const struct {
+    LoadExternal_Entry    *entry;
+    UINT16                inSize;
+    UINT16                outSize;
+    UINT16                offsetOfTypes;
+    UINT16                paramOffsets[3];
+    BYTE                  types[7];
+} LoadExternal_COMMAND_DESCRIPTOR_t;
+LoadExternal_COMMAND_DESCRIPTOR_t _LoadExternalData = {
+    /* entry  */          &TPM2_LoadExternal,
+    /* inSize */          (UINT16)(sizeof(LoadExternal_In)),
+    /* outSize */         (UINT16)(sizeof(LoadExternal_Out)),
+    /* offsetOfTypes */   offsetof(LoadExternal_COMMAND_DESCRIPTOR_t, types),
+    /* offsets */         {(UINT16)(offsetof(LoadExternal_In, inPublic)),
+			   (UINT16)(offsetof(LoadExternal_In, hierarchy)),
+			   (UINT16)(offsetof(LoadExternal_Out, name))},
+    /* types */           {TPM2B_SENSITIVE_P_UNMARSHAL,
+			   TPM2B_PUBLIC_P_UNMARSHAL + ADD_FLAG,
+			   TPMI_RH_HIERARCHY_P_UNMARSHAL + ADD_FLAG,
+			   END_OF_LIST,
+			   TPM_HANDLE_H_MARSHAL,
+			   TPM2B_NAME_P_MARSHAL,
+			   END_OF_LIST}
+};
+#define _LoadExternalDataAddress (&_LoadExternalData)
+#else
+#define _LoadExternalDataAddress 0
+#endif
+#if CC_ReadPublic
+#include "ReadPublic_fp.h"
+typedef TPM_RC  (ReadPublic_Entry)(
+				   ReadPublic_In *in,
+				   ReadPublic_Out *out
+				   );
+typedef const struct {
+    ReadPublic_Entry    *entry;
+    UINT16              inSize;
+    UINT16              outSize;
+    UINT16              offsetOfTypes;
+    UINT16              paramOffsets[2];
+    BYTE                types[6];
+} ReadPublic_COMMAND_DESCRIPTOR_t;
+ReadPublic_COMMAND_DESCRIPTOR_t _ReadPublicData = {
+    /* entry  */          &TPM2_ReadPublic,
+    /* inSize */          (UINT16)(sizeof(ReadPublic_In)),
+    /* outSize */         (UINT16)(sizeof(ReadPublic_Out)),
+    /* offsetOfTypes */   offsetof(ReadPublic_COMMAND_DESCRIPTOR_t, types),
+    /* offsets */         {(UINT16)(offsetof(ReadPublic_Out, name)),
+			   (UINT16)(offsetof(ReadPublic_Out, qualifiedName))},
+    /* types */           {TPMI_DH_OBJECT_H_UNMARSHAL,
+			   END_OF_LIST,
+			   TPM2B_PUBLIC_P_MARSHAL,
+			   TPM2B_NAME_P_MARSHAL,
+			   TPM2B_NAME_P_MARSHAL,
+			   END_OF_LIST}
+};
+#define _ReadPublicDataAddress (&_ReadPublicData)
+#else
+#define _ReadPublicDataAddress 0
+#endif
+#if CC_ActivateCredential
+#include "ActivateCredential_fp.h"
+typedef TPM_RC  (ActivateCredential_Entry)(
+					   ActivateCredential_In *in,
+					   ActivateCredential_Out *out
+					   );
+typedef const struct {
+    ActivateCredential_Entry    *entry;
+    UINT16                      inSize;
+    UINT16                      outSize;
+    UINT16                      offsetOfTypes;
+    UINT16                      paramOffsets[3];
+    BYTE                        types[7];
+} ActivateCredential_COMMAND_DESCRIPTOR_t;
+ActivateCredential_COMMAND_DESCRIPTOR_t _ActivateCredentialData = {
+    /* entry  */          &TPM2_ActivateCredential,
+    /* inSize */          (UINT16)(sizeof(ActivateCredential_In)),
+    /* outSize */         (UINT16)(sizeof(ActivateCredential_Out)),
+    /* offsetOfTypes */   offsetof(ActivateCredential_COMMAND_DESCRIPTOR_t, types),
+    /* offsets */         {(UINT16)(offsetof(ActivateCredential_In, keyHandle)),
+			   (UINT16)(offsetof(ActivateCredential_In, credentialBlob)),
+			   (UINT16)(offsetof(ActivateCredential_In, secret))},
+    /* types */           {TPMI_DH_OBJECT_H_UNMARSHAL,
+			   TPMI_DH_OBJECT_H_UNMARSHAL,
+			   TPM2B_ID_OBJECT_P_UNMARSHAL,
+			   TPM2B_ENCRYPTED_SECRET_P_UNMARSHAL,
+			   END_OF_LIST,
+			   TPM2B_DIGEST_P_MARSHAL,
+			   END_OF_LIST}
+};
+#define _ActivateCredentialDataAddress (&_ActivateCredentialData)
+#else
+#define _ActivateCredentialDataAddress 0
+#endif
+#if CC_MakeCredential
+#include "MakeCredential_fp.h"
+typedef TPM_RC  (MakeCredential_Entry)(
+				       MakeCredential_In *in,
+				       MakeCredential_Out *out
+				       );
+typedef const struct {
+    MakeCredential_Entry    *entry;
+    UINT16                  inSize;
+    UINT16                  outSize;
+    UINT16                  offsetOfTypes;
+    UINT16                  paramOffsets[3];
+    BYTE                    types[7];
+} MakeCredential_COMMAND_DESCRIPTOR_t;
+MakeCredential_COMMAND_DESCRIPTOR_t _MakeCredentialData = {
+    /* entry  */          &TPM2_MakeCredential,
+    /* inSize */          (UINT16)(sizeof(MakeCredential_In)),
+    /* outSize */         (UINT16)(sizeof(MakeCredential_Out)),
+    /* offsetOfTypes */   offsetof(MakeCredential_COMMAND_DESCRIPTOR_t, types),
+    /* offsets */         {(UINT16)(offsetof(MakeCredential_In, credential)),
+			   (UINT16)(offsetof(MakeCredential_In, objectName)),
+			   (UINT16)(offsetof(MakeCredential_Out, secret))},
+    /* types */           {TPMI_DH_OBJECT_H_UNMARSHAL,
+			   TPM2B_DIGEST_P_UNMARSHAL,
+			   TPM2B_NAME_P_UNMARSHAL,
+			   END_OF_LIST,
+			   TPM2B_ID_OBJECT_P_MARSHAL,
+			   TPM2B_ENCRYPTED_SECRET_P_MARSHAL,
+			   END_OF_LIST}
+};
+#define _MakeCredentialDataAddress (&_MakeCredentialData)
+#else
+#define _MakeCredentialDataAddress 0
+#endif
+#if CC_Unseal
+#include "Unseal_fp.h"
+typedef TPM_RC  (Unseal_Entry)(
+			       Unseal_In *in,
+			       Unseal_Out *out
+			       );
+typedef const struct {
+    Unseal_Entry    *entry;
+    UINT16          inSize;
+    UINT16          outSize;
+    UINT16          offsetOfTypes;
+    BYTE            types[4];
+} Unseal_COMMAND_DESCRIPTOR_t;
+Unseal_COMMAND_DESCRIPTOR_t _UnsealData = {
+    /* entry  */          &TPM2_Unseal,
+    /* inSize */          (UINT16)(sizeof(Unseal_In)),
+    /* outSize */         (UINT16)(sizeof(Unseal_Out)),
+    /* offsetOfTypes */   offsetof(Unseal_COMMAND_DESCRIPTOR_t, types),
+    /* offsets */         // No parameter offsets
+    /* types */           {TPMI_DH_OBJECT_H_UNMARSHAL,
+			   END_OF_LIST,
+			   TPM2B_SENSITIVE_DATA_P_MARSHAL,
+			   END_OF_LIST}
+};
+#define _UnsealDataAddress (&_UnsealData)
+#else
+#define _UnsealDataAddress 0
+#endif
+#if CC_ObjectChangeAuth
+#include "ObjectChangeAuth_fp.h"
+typedef TPM_RC  (ObjectChangeAuth_Entry)(
+					 ObjectChangeAuth_In *in,
+					 ObjectChangeAuth_Out *out
+					 );
+typedef const struct {
+    ObjectChangeAuth_Entry    *entry;
+    UINT16                    inSize;
+    UINT16                    outSize;
+    UINT16                    offsetOfTypes;
+    UINT16                    paramOffsets[2];
+    BYTE                      types[6];
+} ObjectChangeAuth_COMMAND_DESCRIPTOR_t;
+ObjectChangeAuth_COMMAND_DESCRIPTOR_t _ObjectChangeAuthData = {
+    /* entry  */          &TPM2_ObjectChangeAuth,
+    /* inSize */          (UINT16)(sizeof(ObjectChangeAuth_In)),
+    /* outSize */         (UINT16)(sizeof(ObjectChangeAuth_Out)),
+    /* offsetOfTypes */   offsetof(ObjectChangeAuth_COMMAND_DESCRIPTOR_t, types),
+    /* offsets */         {(UINT16)(offsetof(ObjectChangeAuth_In, parentHandle)),
+			   (UINT16)(offsetof(ObjectChangeAuth_In, newAuth))},
+    /* types */           {TPMI_DH_OBJECT_H_UNMARSHAL,
+			   TPMI_DH_OBJECT_H_UNMARSHAL,
+			   TPM2B_AUTH_P_UNMARSHAL,
+			   END_OF_LIST,
+			   TPM2B_PRIVATE_P_MARSHAL,
+			   END_OF_LIST}
+};
+#define _ObjectChangeAuthDataAddress (&_ObjectChangeAuthData)
+#else
+#define _ObjectChangeAuthDataAddress 0
+#endif
+#if CC_CreateLoaded
+#include "CreateLoaded_fp.h"
+typedef TPM_RC  (CreateLoaded_Entry)(
+				     CreateLoaded_In *in,
+				     CreateLoaded_Out *out
+				     );
+typedef const struct {
+    CreateLoaded_Entry    *entry;
+    UINT16                inSize;
+    UINT16                outSize;
+    UINT16                offsetOfTypes;
+    UINT16                paramOffsets[5];
+    BYTE                  types[9];
+} CreateLoaded_COMMAND_DESCRIPTOR_t;
+CreateLoaded_COMMAND_DESCRIPTOR_t _CreateLoadedData = {
+    /* entry  */          &TPM2_CreateLoaded,
+    /* inSize */          (UINT16)(sizeof(CreateLoaded_In)),
+    /* outSize */         (UINT16)(sizeof(CreateLoaded_Out)),
+    /* offsetOfTypes */   offsetof(CreateLoaded_COMMAND_DESCRIPTOR_t, types),
+    /* offsets */         {(UINT16)(offsetof(CreateLoaded_In, inSensitive)),
+			   (UINT16)(offsetof(CreateLoaded_In, inPublic)),
+			   (UINT16)(offsetof(CreateLoaded_Out, outPrivate)),
+			   (UINT16)(offsetof(CreateLoaded_Out, outPublic)),
+			   (UINT16)(offsetof(CreateLoaded_Out, name))},
+    /* types */           {TPMI_DH_PARENT_H_UNMARSHAL + ADD_FLAG,
+			   TPM2B_SENSITIVE_CREATE_P_UNMARSHAL,
+			   TPM2B_TEMPLATE_P_UNMARSHAL,
+			   END_OF_LIST,
+			   TPM_HANDLE_H_MARSHAL,
+			   TPM2B_PRIVATE_P_MARSHAL,
+			   TPM2B_PUBLIC_P_MARSHAL,
+			   TPM2B_NAME_P_MARSHAL,
+			   END_OF_LIST}
+};
+#define _CreateLoadedDataAddress (&_CreateLoadedData)
+#else
+#define _CreateLoadedDataAddress 0
+#endif
+#if CC_Duplicate
+#include "Duplicate_fp.h"
+typedef TPM_RC  (Duplicate_Entry)(
+				  Duplicate_In *in,
+				  Duplicate_Out *out
+				  );
+typedef const struct {
+    Duplicate_Entry    *entry;
+    UINT16             inSize;
+    UINT16             outSize;
+    UINT16             offsetOfTypes;
+    UINT16             paramOffsets[5];
+    BYTE               types[9];
+} Duplicate_COMMAND_DESCRIPTOR_t;
+Duplicate_COMMAND_DESCRIPTOR_t _DuplicateData = {
+    /* entry  */          &TPM2_Duplicate,
+    /* inSize */          (UINT16)(sizeof(Duplicate_In)),
+    /* outSize */         (UINT16)(sizeof(Duplicate_Out)),
+    /* offsetOfTypes */   offsetof(Duplicate_COMMAND_DESCRIPTOR_t, types),
+    /* offsets */         {(UINT16)(offsetof(Duplicate_In, newParentHandle)),
+			   (UINT16)(offsetof(Duplicate_In, encryptionKeyIn)),
+			   (UINT16)(offsetof(Duplicate_In, symmetricAlg)),
+			   (UINT16)(offsetof(Duplicate_Out, duplicate)),
+			   (UINT16)(offsetof(Duplicate_Out, outSymSeed))},
+    /* types */           {TPMI_DH_OBJECT_H_UNMARSHAL,
+			   TPMI_DH_OBJECT_H_UNMARSHAL + ADD_FLAG,
+			   TPM2B_DATA_P_UNMARSHAL,
+			   TPMT_SYM_DEF_OBJECT_P_UNMARSHAL + ADD_FLAG,
+			   END_OF_LIST,
+			   TPM2B_DATA_P_MARSHAL,
+			   TPM2B_PRIVATE_P_MARSHAL,
+			   TPM2B_ENCRYPTED_SECRET_P_MARSHAL,
+			   END_OF_LIST}
+};
+#define _DuplicateDataAddress (&_DuplicateData)
+#else
+#define _DuplicateDataAddress 0
+#endif
+#if CC_Rewrap
+#include "Rewrap_fp.h"
+typedef TPM_RC  (Rewrap_Entry)(
+			       Rewrap_In *in,
+			       Rewrap_Out *out
+			       );
+typedef const struct {
+    Rewrap_Entry    *entry;
+    UINT16          inSize;
+    UINT16          outSize;
+    UINT16          offsetOfTypes;
+    UINT16          paramOffsets[5];
+    BYTE            types[9];
+} Rewrap_COMMAND_DESCRIPTOR_t;
+Rewrap_COMMAND_DESCRIPTOR_t _RewrapData = {
+    /* entry  */          &TPM2_Rewrap,
+    /* inSize */          (UINT16)(sizeof(Rewrap_In)),
+    /* outSize */         (UINT16)(sizeof(Rewrap_Out)),
+    /* offsetOfTypes */   offsetof(Rewrap_COMMAND_DESCRIPTOR_t, types),
+    /* offsets */         {(UINT16)(offsetof(Rewrap_In, newParent)),
+			   (UINT16)(offsetof(Rewrap_In, inDuplicate)),
+			   (UINT16)(offsetof(Rewrap_In, name)),
+			   (UINT16)(offsetof(Rewrap_In, inSymSeed)),
+			   (UINT16)(offsetof(Rewrap_Out, outSymSeed))},
+    /* types */           {TPMI_DH_OBJECT_H_UNMARSHAL + ADD_FLAG,
+			   TPMI_DH_OBJECT_H_UNMARSHAL + ADD_FLAG,
+			   TPM2B_PRIVATE_P_UNMARSHAL,
+			   TPM2B_NAME_P_UNMARSHAL,
+			   TPM2B_ENCRYPTED_SECRET_P_UNMARSHAL,
+			   END_OF_LIST,
+			   TPM2B_PRIVATE_P_MARSHAL,
+			   TPM2B_ENCRYPTED_SECRET_P_MARSHAL,
+			   END_OF_LIST}
+};
+#define _RewrapDataAddress (&_RewrapData)
+#else
+#define _RewrapDataAddress 0
+#endif
+#if CC_Import
+#include "Import_fp.h"
+typedef TPM_RC  (Import_Entry)(
+			       Import_In *in,
+			       Import_Out *out
+			       );
+typedef const struct {
+    Import_Entry    *entry;
+    UINT16          inSize;
+    UINT16          outSize;
+    UINT16          offsetOfTypes;
+    UINT16          paramOffsets[5];
+    BYTE            types[9];
+} Import_COMMAND_DESCRIPTOR_t;
+Import_COMMAND_DESCRIPTOR_t _ImportData = {
+    /* entry  */          &TPM2_Import,
+    /* inSize */          (UINT16)(sizeof(Import_In)),
+    /* outSize */         (UINT16)(sizeof(Import_Out)),
+    /* offsetOfTypes */   offsetof(Import_COMMAND_DESCRIPTOR_t, types),
+    /* offsets */         {(UINT16)(offsetof(Import_In, encryptionKey)),
+			   (UINT16)(offsetof(Import_In, objectPublic)),
+			   (UINT16)(offsetof(Import_In, duplicate)),
+			   (UINT16)(offsetof(Import_In, inSymSeed)),
+			   (UINT16)(offsetof(Import_In, symmetricAlg))},
+    /* types */           {TPMI_DH_OBJECT_H_UNMARSHAL,
+			   TPM2B_DATA_P_UNMARSHAL,
+			   TPM2B_PUBLIC_P_UNMARSHAL,
+			   TPM2B_PRIVATE_P_UNMARSHAL,
+			   TPM2B_ENCRYPTED_SECRET_P_UNMARSHAL,
+			   TPMT_SYM_DEF_OBJECT_P_UNMARSHAL + ADD_FLAG,
+			   END_OF_LIST,
+			   TPM2B_PRIVATE_P_MARSHAL,
+			   END_OF_LIST}
+};
+#define _ImportDataAddress (&_ImportData)
+#else
+#define _ImportDataAddress 0
+#endif
+#if CC_RSA_Encrypt
+#include "RSA_Encrypt_fp.h"
+typedef TPM_RC  (RSA_Encrypt_Entry)(
+				    RSA_Encrypt_In *in,
+				    RSA_Encrypt_Out *out
+				    );
+typedef const struct {
+    RSA_Encrypt_Entry    *entry;
+    UINT16               inSize;
+    UINT16               outSize;
+    UINT16               offsetOfTypes;
+    UINT16               paramOffsets[3];
+    BYTE                 types[7];
+} RSA_Encrypt_COMMAND_DESCRIPTOR_t;
+RSA_Encrypt_COMMAND_DESCRIPTOR_t _RSA_EncryptData = {
+    /* entry  */          &TPM2_RSA_Encrypt,
+    /* inSize */          (UINT16)(sizeof(RSA_Encrypt_In)),
+    /* outSize */         (UINT16)(sizeof(RSA_Encrypt_Out)),
+    /* offsetOfTypes */   offsetof(RSA_Encrypt_COMMAND_DESCRIPTOR_t, types),
+    /* offsets */         {(UINT16)(offsetof(RSA_Encrypt_In, message)),
+			   (UINT16)(offsetof(RSA_Encrypt_In, inScheme)),
+			   (UINT16)(offsetof(RSA_Encrypt_In, label))},
+    /* types */           {TPMI_DH_OBJECT_H_UNMARSHAL,
+			   TPM2B_PUBLIC_KEY_RSA_P_UNMARSHAL,
+			   TPMT_RSA_DECRYPT_P_UNMARSHAL + ADD_FLAG,
+			   TPM2B_DATA_P_UNMARSHAL,
+			   END_OF_LIST,
+			   TPM2B_PUBLIC_KEY_RSA_P_MARSHAL,
+			   END_OF_LIST}
+};
+#define _RSA_EncryptDataAddress (&_RSA_EncryptData)
+#else
+#define _RSA_EncryptDataAddress 0
+#endif
+#if CC_RSA_Decrypt
+#include "RSA_Decrypt_fp.h"
+typedef TPM_RC  (RSA_Decrypt_Entry)(
+				    RSA_Decrypt_In *in,
+				    RSA_Decrypt_Out *out
+				    );
+typedef const struct {
+    RSA_Decrypt_Entry    *entry;
+    UINT16               inSize;
+    UINT16               outSize;
+    UINT16               offsetOfTypes;
+    UINT16               paramOffsets[3];
+    BYTE                 types[7];
+} RSA_Decrypt_COMMAND_DESCRIPTOR_t;
+RSA_Decrypt_COMMAND_DESCRIPTOR_t _RSA_DecryptData = {
+    /* entry  */          &TPM2_RSA_Decrypt,
+    /* inSize */          (UINT16)(sizeof(RSA_Decrypt_In)),
+    /* outSize */         (UINT16)(sizeof(RSA_Decrypt_Out)),
+    /* offsetOfTypes */   offsetof(RSA_Decrypt_COMMAND_DESCRIPTOR_t, types),
+    /* offsets */         {(UINT16)(offsetof(RSA_Decrypt_In, cipherText)),
+			   (UINT16)(offsetof(RSA_Decrypt_In, inScheme)),
+			   (UINT16)(offsetof(RSA_Decrypt_In, label))},
+    /* types */           {TPMI_DH_OBJECT_H_UNMARSHAL,
+			   TPM2B_PUBLIC_KEY_RSA_P_UNMARSHAL,
+			   TPMT_RSA_DECRYPT_P_UNMARSHAL + ADD_FLAG,
+			   TPM2B_DATA_P_UNMARSHAL,
+			   END_OF_LIST,
+			   TPM2B_PUBLIC_KEY_RSA_P_MARSHAL,
+			   END_OF_LIST}
+};
+#define _RSA_DecryptDataAddress (&_RSA_DecryptData)
+#else
+#define _RSA_DecryptDataAddress 0
+#endif
+#if CC_ECDH_KeyGen
+#include "ECDH_KeyGen_fp.h"
+typedef TPM_RC  (ECDH_KeyGen_Entry)(
+				    ECDH_KeyGen_In *in,
+				    ECDH_KeyGen_Out *out
+				    );
+typedef const struct {
+    ECDH_KeyGen_Entry    *entry;
+    UINT16               inSize;
+    UINT16               outSize;
+    UINT16               offsetOfTypes;
+    UINT16               paramOffsets[1];
+    BYTE                 types[5];
+} ECDH_KeyGen_COMMAND_DESCRIPTOR_t;
+ECDH_KeyGen_COMMAND_DESCRIPTOR_t _ECDH_KeyGenData = {
+    /* entry  */          &TPM2_ECDH_KeyGen,
+    /* inSize */          (UINT16)(sizeof(ECDH_KeyGen_In)),
+    /* outSize */         (UINT16)(sizeof(ECDH_KeyGen_Out)),
+    /* offsetOfTypes */   offsetof(ECDH_KeyGen_COMMAND_DESCRIPTOR_t, types),
+    /* offsets */         {(UINT16)(offsetof(ECDH_KeyGen_Out, pubPoint))},
+    /* types */           {TPMI_DH_OBJECT_H_UNMARSHAL,
+			   END_OF_LIST,
+			   TPM2B_ECC_POINT_P_MARSHAL,
+			   TPM2B_ECC_POINT_P_MARSHAL,
+			   END_OF_LIST}
+};
+#define _ECDH_KeyGenDataAddress (&_ECDH_KeyGenData)
+#else
+#define _ECDH_KeyGenDataAddress 0
+#endif
+#if CC_ECDH_ZGen
+#include "ECDH_ZGen_fp.h"
+typedef TPM_RC  (ECDH_ZGen_Entry)(
+				  ECDH_ZGen_In *in,
+				  ECDH_ZGen_Out *out
+				  );
+typedef const struct {
+    ECDH_ZGen_Entry    *entry;
+    UINT16             inSize;
+    UINT16             outSize;
+    UINT16             offsetOfTypes;
+    UINT16             paramOffsets[1];
+    BYTE               types[5];
+} ECDH_ZGen_COMMAND_DESCRIPTOR_t;
+ECDH_ZGen_COMMAND_DESCRIPTOR_t _ECDH_ZGenData = {
+    /* entry  */          &TPM2_ECDH_ZGen,
+    /* inSize */          (UINT16)(sizeof(ECDH_ZGen_In)),
+    /* outSize */         (UINT16)(sizeof(ECDH_ZGen_Out)),
+    /* offsetOfTypes */   offsetof(ECDH_ZGen_COMMAND_DESCRIPTOR_t, types),
+    /* offsets */         {(UINT16)(offsetof(ECDH_ZGen_In, inPoint))},
+    /* types */           {TPMI_DH_OBJECT_H_UNMARSHAL,
+			   TPM2B_ECC_POINT_P_UNMARSHAL,
+			   END_OF_LIST,
+			   TPM2B_ECC_POINT_P_MARSHAL,
+			   END_OF_LIST}
+};
+#define _ECDH_ZGenDataAddress (&_ECDH_ZGenData)
+#else
+#define _ECDH_ZGenDataAddress 0
+#endif
+
+#if CC_ECC_Encrypt
+
+#include "ECC_Encrypt_fp.h"
+
+typedef TPM_RC  (ECC_Encrypt_Entry)(
+				    ECC_Encrypt_In              *in,
+				    ECC_Encrypt_Out             *out
+				    );
+
+typedef const struct {
+    ECC_Encrypt_Entry       *entry;
+    UINT16                  inSize;
+    UINT16                  outSize;
+    UINT16                  offsetOfTypes;
+    UINT16                  paramOffsets[4];
+    BYTE                    types[8];
+} ECC_Encrypt_COMMAND_DESCRIPTOR_t;
+
+ECC_Encrypt_COMMAND_DESCRIPTOR_t _ECC_EncryptData = {
+    /* entry         */     &TPM2_ECC_Encrypt,
+    /* inSize        */     (UINT16)(sizeof(ECC_Encrypt_In)),
+    /* outSize       */     (UINT16)(sizeof(ECC_Encrypt_Out)),
+    /* offsetOfTypes */     offsetof(ECC_Encrypt_COMMAND_DESCRIPTOR_t, types),
+    /* offsets       */     {(UINT16)(offsetof(ECC_Encrypt_In, plainText)),
+			     (UINT16)(offsetof(ECC_Encrypt_In, inScheme)),
+			     (UINT16)(offsetof(ECC_Encrypt_Out, C2)),
+			     (UINT16)(offsetof(ECC_Encrypt_Out, C3))},
+    /* types         */     {TPMI_DH_OBJECT_H_UNMARSHAL,
+			     TPM2B_MAX_BUFFER_P_UNMARSHAL,
+			     TPMT_KDF_SCHEME_P_UNMARSHAL + ADD_FLAG,
+			     END_OF_LIST,
+			     TPM2B_ECC_POINT_P_MARSHAL,
+			     TPM2B_MAX_BUFFER_P_MARSHAL,
+			     TPM2B_DIGEST_P_MARSHAL,
+			     END_OF_LIST}
+};
+
+#define _ECC_EncryptDataAddress (&_ECC_EncryptData)
+#else
+#define _ECC_EncryptDataAddress 0
+#endif // CC_ECC_Encrypt
+
+#if CC_ECC_Decrypt
+
+#include "ECC_Decrypt_fp.h"
+
+typedef TPM_RC  (ECC_Decrypt_Entry)(
+				    ECC_Decrypt_In              *in,
+				    ECC_Decrypt_Out             *out
+				    );
+
+typedef const struct {
+    ECC_Decrypt_Entry       *entry;
+    UINT16                  inSize;
+    UINT16                  outSize;
+    UINT16                  offsetOfTypes;
+    UINT16                  paramOffsets[4];
+    BYTE                    types[8];
+} ECC_Decrypt_COMMAND_DESCRIPTOR_t;
+
+ECC_Decrypt_COMMAND_DESCRIPTOR_t _ECC_DecryptData = {
+    /* entry         */     &TPM2_ECC_Decrypt,
+    /* inSize        */     (UINT16)(sizeof(ECC_Decrypt_In)),
+    /* outSize       */     (UINT16)(sizeof(ECC_Decrypt_Out)),
+    /* offsetOfTypes */     offsetof(ECC_Decrypt_COMMAND_DESCRIPTOR_t, types),
+    /* offsets       */     {(UINT16)(offsetof(ECC_Decrypt_In, C1)),
+			     (UINT16)(offsetof(ECC_Decrypt_In, C2)),
+			     (UINT16)(offsetof(ECC_Decrypt_In, C3)),
+			     (UINT16)(offsetof(ECC_Decrypt_In, inScheme))},
+    /* types         */     {TPMI_DH_OBJECT_H_UNMARSHAL,
+			     TPM2B_ECC_POINT_P_UNMARSHAL,
+			     TPM2B_MAX_BUFFER_P_UNMARSHAL,
+			     TPM2B_DIGEST_P_UNMARSHAL,
+			     TPMT_KDF_SCHEME_P_UNMARSHAL + ADD_FLAG,
+			     END_OF_LIST,
+			     TPM2B_MAX_BUFFER_P_MARSHAL,
+			     END_OF_LIST}
+};
+
+#define _ECC_DecryptDataAddress (&_ECC_DecryptData)
+#else
+#define _ECC_DecryptDataAddress 0
+#endif // CC_ECC_Decrypt
+
+#if CC_ECC_Parameters
+#include "ECC_Parameters_fp.h"
+typedef TPM_RC  (ECC_Parameters_Entry)(
+				       ECC_Parameters_In *in,
+				       ECC_Parameters_Out *out
+				       );
+typedef const struct {
+    ECC_Parameters_Entry    *entry;
+    UINT16                  inSize;
+    UINT16                  outSize;
+    UINT16                  offsetOfTypes;
+    BYTE                    types[4];
+} ECC_Parameters_COMMAND_DESCRIPTOR_t;
+ECC_Parameters_COMMAND_DESCRIPTOR_t _ECC_ParametersData = {
+    /* entry  */          &TPM2_ECC_Parameters,
+    /* inSize */          (UINT16)(sizeof(ECC_Parameters_In)),
+    /* outSize */         (UINT16)(sizeof(ECC_Parameters_Out)),
+    /* offsetOfTypes */   offsetof(ECC_Parameters_COMMAND_DESCRIPTOR_t, types),
+    /* offsets */         // No parameter offsets
+    /* types */           {TPMI_ECC_CURVE_P_UNMARSHAL,
+			   END_OF_LIST,
+			   TPMS_ALGORITHM_DETAIL_ECC_P_MARSHAL,
+			   END_OF_LIST}
+};
+#define _ECC_ParametersDataAddress (&_ECC_ParametersData)
+#else
+#define _ECC_ParametersDataAddress 0
+#endif
+#if CC_ZGen_2Phase
+#include "ZGen_2Phase_fp.h"
+typedef TPM_RC  (ZGen_2Phase_Entry)(
+				    ZGen_2Phase_In *in,
+				    ZGen_2Phase_Out *out
+				    );
+typedef const struct {
+    ZGen_2Phase_Entry    *entry;
+    UINT16               inSize;
+    UINT16               outSize;
+    UINT16               offsetOfTypes;
+    UINT16               paramOffsets[5];
+    BYTE                 types[9];
+} ZGen_2Phase_COMMAND_DESCRIPTOR_t;
+ZGen_2Phase_COMMAND_DESCRIPTOR_t _ZGen_2PhaseData = {
+    /* entry  */          &TPM2_ZGen_2Phase,
+    /* inSize */          (UINT16)(sizeof(ZGen_2Phase_In)),
+    /* outSize */         (UINT16)(sizeof(ZGen_2Phase_Out)),
+    /* offsetOfTypes */   offsetof(ZGen_2Phase_COMMAND_DESCRIPTOR_t, types),
+    /* offsets */         {(UINT16)(offsetof(ZGen_2Phase_In, inQsB)),
+			   (UINT16)(offsetof(ZGen_2Phase_In, inQeB)),
+			   (UINT16)(offsetof(ZGen_2Phase_In, inScheme)),
+			   (UINT16)(offsetof(ZGen_2Phase_In, counter)),
+			   (UINT16)(offsetof(ZGen_2Phase_Out, outZ2))},
+    /* types */           {TPMI_DH_OBJECT_H_UNMARSHAL,
+			   TPM2B_ECC_POINT_P_UNMARSHAL,
+			   TPM2B_ECC_POINT_P_UNMARSHAL,
+			   TPMI_ECC_KEY_EXCHANGE_P_UNMARSHAL,
+			   UINT16_P_UNMARSHAL,
+			   END_OF_LIST,
+			   TPM2B_ECC_POINT_P_MARSHAL,
+			   TPM2B_ECC_POINT_P_MARSHAL,
+			   END_OF_LIST}
+};
+#define _ZGen_2PhaseDataAddress (&_ZGen_2PhaseData)
+#else
+#define _ZGen_2PhaseDataAddress 0
+#endif
+#if CC_EncryptDecrypt
+#include "EncryptDecrypt_fp.h"
+typedef TPM_RC  (EncryptDecrypt_Entry)(
+				       EncryptDecrypt_In *in,
+				       EncryptDecrypt_Out *out
+				       );
+typedef const struct {
+    EncryptDecrypt_Entry    *entry;
+    UINT16                  inSize;
+    UINT16                  outSize;
+    UINT16                  offsetOfTypes;
+    UINT16                  paramOffsets[5];
+    BYTE                    types[9];
+} EncryptDecrypt_COMMAND_DESCRIPTOR_t;
+EncryptDecrypt_COMMAND_DESCRIPTOR_t _EncryptDecryptData = {
+    /* entry  */          &TPM2_EncryptDecrypt,
+    /* inSize */          (UINT16)(sizeof(EncryptDecrypt_In)),
+    /* outSize */         (UINT16)(sizeof(EncryptDecrypt_Out)),
+    /* offsetOfTypes */   offsetof(EncryptDecrypt_COMMAND_DESCRIPTOR_t, types),
+    /* offsets */         {(UINT16)(offsetof(EncryptDecrypt_In, decrypt)),
+			   (UINT16)(offsetof(EncryptDecrypt_In, mode)),
+			   (UINT16)(offsetof(EncryptDecrypt_In, ivIn)),
+			   (UINT16)(offsetof(EncryptDecrypt_In, inData)),
+			   (UINT16)(offsetof(EncryptDecrypt_Out, ivOut))},
+    /* types */           {TPMI_DH_OBJECT_H_UNMARSHAL,
+			   TPMI_YES_NO_P_UNMARSHAL,
+			   TPMI_ALG_CIPHER_MODE_P_UNMARSHAL + ADD_FLAG,
+			   TPM2B_IV_P_UNMARSHAL,
+			   TPM2B_MAX_BUFFER_P_UNMARSHAL,
+			   END_OF_LIST,
+			   TPM2B_MAX_BUFFER_P_MARSHAL,
+			   TPM2B_IV_P_MARSHAL,
+			   END_OF_LIST}
+};
+#define _EncryptDecryptDataAddress (&_EncryptDecryptData)
+#else
+#define _EncryptDecryptDataAddress 0
+#endif
+#if CC_EncryptDecrypt2
+#include "EncryptDecrypt2_fp.h"
+typedef TPM_RC  (EncryptDecrypt2_Entry)(
+					EncryptDecrypt2_In *in,
+					EncryptDecrypt2_Out *out
+					);
+typedef const struct {
+    EncryptDecrypt2_Entry    *entry;
+    UINT16                   inSize;
+    UINT16                   outSize;
+    UINT16                   offsetOfTypes;
+    UINT16                   paramOffsets[5];
+    BYTE                     types[9];
+} EncryptDecrypt2_COMMAND_DESCRIPTOR_t;
+EncryptDecrypt2_COMMAND_DESCRIPTOR_t _EncryptDecrypt2Data = {
+    /* entry  */          &TPM2_EncryptDecrypt2,
+    /* inSize */          (UINT16)(sizeof(EncryptDecrypt2_In)),
+    /* outSize */         (UINT16)(sizeof(EncryptDecrypt2_Out)),
+    /* offsetOfTypes */   offsetof(EncryptDecrypt2_COMMAND_DESCRIPTOR_t, types),
+    /* offsets */         {(UINT16)(offsetof(EncryptDecrypt2_In, inData)),
+			   (UINT16)(offsetof(EncryptDecrypt2_In, decrypt)),
+			   (UINT16)(offsetof(EncryptDecrypt2_In, mode)),
+			   (UINT16)(offsetof(EncryptDecrypt2_In, ivIn)),
+			   (UINT16)(offsetof(EncryptDecrypt2_Out, ivOut))},
+    /* types */           {TPMI_DH_OBJECT_H_UNMARSHAL,
+			   TPM2B_MAX_BUFFER_P_UNMARSHAL,
+			   TPMI_YES_NO_P_UNMARSHAL,
+			   TPMI_ALG_CIPHER_MODE_P_UNMARSHAL + ADD_FLAG,
+			   TPM2B_IV_P_UNMARSHAL,
+			   END_OF_LIST,
+			   TPM2B_MAX_BUFFER_P_MARSHAL,
+			   TPM2B_IV_P_MARSHAL,
+			   END_OF_LIST}
+};
+#define _EncryptDecrypt2DataAddress (&_EncryptDecrypt2Data)
+#else
+#define _EncryptDecrypt2DataAddress 0
+#endif
+#if CC_Hash
+#include "Hash_fp.h"
+typedef TPM_RC  (Hash_Entry)(
+			     Hash_In *in,
+			     Hash_Out *out
+			     );
+typedef const struct {
+    Hash_Entry    *entry;
+    UINT16        inSize;
+    UINT16        outSize;
+    UINT16        offsetOfTypes;
+    UINT16        paramOffsets[3];
+    BYTE          types[7];
+} Hash_COMMAND_DESCRIPTOR_t;
+Hash_COMMAND_DESCRIPTOR_t _HashData = {
+    /* entry  */          &TPM2_Hash,
+    /* inSize */          (UINT16)(sizeof(Hash_In)),
+    /* outSize */         (UINT16)(sizeof(Hash_Out)),
+    /* offsetOfTypes */   offsetof(Hash_COMMAND_DESCRIPTOR_t, types),
+    /* offsets */         {(UINT16)(offsetof(Hash_In, hashAlg)),
+			   (UINT16)(offsetof(Hash_In, hierarchy)),
+			   (UINT16)(offsetof(Hash_Out, validation))},
+    /* types */           {TPM2B_MAX_BUFFER_P_UNMARSHAL,
+			   TPMI_ALG_HASH_P_UNMARSHAL,
+			   TPMI_RH_HIERARCHY_P_UNMARSHAL + ADD_FLAG,
+			   END_OF_LIST,
+			   TPM2B_DIGEST_P_MARSHAL,
+			   TPMT_TK_HASHCHECK_P_MARSHAL,
+			   END_OF_LIST}
+};
+#define _HashDataAddress (&_HashData)
+#else
+#define _HashDataAddress 0
+#endif
+#if CC_HMAC
+#include "HMAC_fp.h"
+typedef TPM_RC  (HMAC_Entry)(
+			     HMAC_In *in,
+			     HMAC_Out *out
+			     );
+typedef const struct {
+    HMAC_Entry    *entry;
+    UINT16        inSize;
+    UINT16        outSize;
+    UINT16        offsetOfTypes;
+    UINT16        paramOffsets[2];
+    BYTE          types[6];
+} HMAC_COMMAND_DESCRIPTOR_t;
+HMAC_COMMAND_DESCRIPTOR_t _HMACData = {
+    /* entry  */          &TPM2_HMAC,
+    /* inSize */          (UINT16)(sizeof(HMAC_In)),
+    /* outSize */         (UINT16)(sizeof(HMAC_Out)),
+    /* offsetOfTypes */   offsetof(HMAC_COMMAND_DESCRIPTOR_t, types),
+    /* offsets */         {(UINT16)(offsetof(HMAC_In, buffer)),
+			   (UINT16)(offsetof(HMAC_In, hashAlg))},
+    /* types */           {TPMI_DH_OBJECT_H_UNMARSHAL,
+			   TPM2B_MAX_BUFFER_P_UNMARSHAL,
+			   TPMI_ALG_HASH_P_UNMARSHAL + ADD_FLAG,
+			   END_OF_LIST,
+			   TPM2B_DIGEST_P_MARSHAL,
+			   END_OF_LIST}
+};
+#define _HMACDataAddress (&_HMACData)
+#else
+#define _HMACDataAddress 0
+#endif
+#if CC_MAC
+#include "MAC_fp.h"
+typedef TPM_RC  (MAC_Entry)(
+			    MAC_In *in,
+			    MAC_Out *out
+			    );
+typedef const struct {
+    MAC_Entry    *entry;
+    UINT16       inSize;
+    UINT16       outSize;
+    UINT16       offsetOfTypes;
+    UINT16       paramOffsets[2];
+    BYTE         types[6];
+} MAC_COMMAND_DESCRIPTOR_t;
+MAC_COMMAND_DESCRIPTOR_t _MACData = {
+    /* entry  */          &TPM2_MAC,
+    /* inSize */          (UINT16)(sizeof(MAC_In)),
+    /* outSize */         (UINT16)(sizeof(MAC_Out)),
+    /* offsetOfTypes */   offsetof(MAC_COMMAND_DESCRIPTOR_t, types),
+    /* offsets */         {(UINT16)(offsetof(MAC_In, buffer)),
+			   (UINT16)(offsetof(MAC_In, inScheme))},
+    /* types */           {TPMI_DH_OBJECT_H_UNMARSHAL,
+			   TPM2B_MAX_BUFFER_P_UNMARSHAL,
+			   TPMI_ALG_MAC_SCHEME_P_UNMARSHAL + ADD_FLAG,
+			   END_OF_LIST,
+			   TPM2B_DIGEST_P_MARSHAL,
+			   END_OF_LIST}
+};
+#define _MACDataAddress (&_MACData)
+#else
+#define _MACDataAddress 0
+#endif
+#if CC_GetRandom
+#include "GetRandom_fp.h"
+typedef TPM_RC  (GetRandom_Entry)(
+				  GetRandom_In *in,
+				  GetRandom_Out *out
+				  );
+typedef const struct {
+    GetRandom_Entry    *entry;
+    UINT16             inSize;
+    UINT16             outSize;
+    UINT16             offsetOfTypes;
+    BYTE               types[4];
+} GetRandom_COMMAND_DESCRIPTOR_t;
+GetRandom_COMMAND_DESCRIPTOR_t _GetRandomData = {
+    /* entry  */          &TPM2_GetRandom,
+    /* inSize */          (UINT16)(sizeof(GetRandom_In)),
+    /* outSize */         (UINT16)(sizeof(GetRandom_Out)),
+    /* offsetOfTypes */   offsetof(GetRandom_COMMAND_DESCRIPTOR_t, types),
+    /* offsets */         // No parameter offsets
+    /* types */           {UINT16_P_UNMARSHAL,
+			   END_OF_LIST,
+			   TPM2B_DIGEST_P_MARSHAL,
+			   END_OF_LIST}
+};
+#define _GetRandomDataAddress (&_GetRandomData)
+#else
+#define _GetRandomDataAddress 0
+#endif
+#if CC_StirRandom
+#include "StirRandom_fp.h"
+typedef TPM_RC  (StirRandom_Entry)(
+				   StirRandom_In *in
+				   );
+typedef const struct {
+    StirRandom_Entry    *entry;
+    UINT16              inSize;
+    UINT16              outSize;
+    UINT16              offsetOfTypes;
+    BYTE                types[3];
+} StirRandom_COMMAND_DESCRIPTOR_t;
+StirRandom_COMMAND_DESCRIPTOR_t _StirRandomData = {
+    /* entry  */          &TPM2_StirRandom,
+    /* inSize */          (UINT16)(sizeof(StirRandom_In)),
+    /* outSize */         0,
+    /* offsetOfTypes */   offsetof(StirRandom_COMMAND_DESCRIPTOR_t, types),
+    /* offsets */         // No parameter offsets
+    /* types */           {TPM2B_SENSITIVE_DATA_P_UNMARSHAL,
+			   END_OF_LIST,
+			   END_OF_LIST}
+};
+#define _StirRandomDataAddress (&_StirRandomData)
+#else
+#define _StirRandomDataAddress 0
+#endif
+#if CC_HMAC_Start
+#include "HMAC_Start_fp.h"
+typedef TPM_RC  (HMAC_Start_Entry)(
+				   HMAC_Start_In *in,
+				   HMAC_Start_Out *out
+				   );
+typedef const struct {
+    HMAC_Start_Entry    *entry;
+    UINT16              inSize;
+    UINT16              outSize;
+    UINT16              offsetOfTypes;
+    UINT16              paramOffsets[2];
+    BYTE                types[6];
+} HMAC_Start_COMMAND_DESCRIPTOR_t;
+HMAC_Start_COMMAND_DESCRIPTOR_t _HMAC_StartData = {
+    /* entry  */          &TPM2_HMAC_Start,
+    /* inSize */          (UINT16)(sizeof(HMAC_Start_In)),
+    /* outSize */         (UINT16)(sizeof(HMAC_Start_Out)),
+    /* offsetOfTypes */   offsetof(HMAC_Start_COMMAND_DESCRIPTOR_t, types),
+    /* offsets */         {(UINT16)(offsetof(HMAC_Start_In, auth)),
+			   (UINT16)(offsetof(HMAC_Start_In, hashAlg))},
+    /* types */           {TPMI_DH_OBJECT_H_UNMARSHAL,
+			   TPM2B_AUTH_P_UNMARSHAL,
+			   TPMI_ALG_HASH_P_UNMARSHAL + ADD_FLAG,
+			   END_OF_LIST,
+			   TPMI_DH_OBJECT_H_MARSHAL,
+			   END_OF_LIST}
+};
+#define _HMAC_StartDataAddress (&_HMAC_StartData)
+#else
+#define _HMAC_StartDataAddress 0
+#endif
+#if CC_MAC_Start
+#include "MAC_Start_fp.h"
+typedef TPM_RC  (MAC_Start_Entry)(
+				  MAC_Start_In *in,
+				  MAC_Start_Out *out
+				  );
+typedef const struct {
+    MAC_Start_Entry    *entry;
+    UINT16             inSize;
+    UINT16             outSize;
+    UINT16             offsetOfTypes;
+    UINT16             paramOffsets[2];
+    BYTE               types[6];
+} MAC_Start_COMMAND_DESCRIPTOR_t;
+MAC_Start_COMMAND_DESCRIPTOR_t _MAC_StartData = {
+    /* entry  */          &TPM2_MAC_Start,
+    /* inSize */          (UINT16)(sizeof(MAC_Start_In)),
+    /* outSize */         (UINT16)(sizeof(MAC_Start_Out)),
+    /* offsetOfTypes */   offsetof(MAC_Start_COMMAND_DESCRIPTOR_t, types),
+    /* offsets */         {(UINT16)(offsetof(MAC_Start_In, auth)),
+			   (UINT16)(offsetof(MAC_Start_In, inScheme))},
+    /* types */           {TPMI_DH_OBJECT_H_UNMARSHAL,
+			   TPM2B_AUTH_P_UNMARSHAL,
+			   TPMI_ALG_MAC_SCHEME_P_UNMARSHAL + ADD_FLAG,
+			   END_OF_LIST,
+			   TPMI_DH_OBJECT_H_MARSHAL,
+			   END_OF_LIST}
+};
+#define _MAC_StartDataAddress (&_MAC_StartData)
+#else
+#define _MAC_StartDataAddress 0
+#endif
+#if CC_HashSequenceStart
+#include "HashSequenceStart_fp.h"
+typedef TPM_RC  (HashSequenceStart_Entry)(
+					  HashSequenceStart_In *in,
+					  HashSequenceStart_Out *out
+					  );
+typedef const struct {
+    HashSequenceStart_Entry    *entry;
+    UINT16                     inSize;
+    UINT16                     outSize;
+    UINT16                     offsetOfTypes;
+    UINT16                     paramOffsets[1];
+    BYTE                       types[5];
+} HashSequenceStart_COMMAND_DESCRIPTOR_t;
+HashSequenceStart_COMMAND_DESCRIPTOR_t _HashSequenceStartData = {
+    /* entry  */          &TPM2_HashSequenceStart,
+    /* inSize */          (UINT16)(sizeof(HashSequenceStart_In)),
+    /* outSize */         (UINT16)(sizeof(HashSequenceStart_Out)),
+    /* offsetOfTypes */   offsetof(HashSequenceStart_COMMAND_DESCRIPTOR_t, types),
+    /* offsets */         {(UINT16)(offsetof(HashSequenceStart_In, hashAlg))},
+    /* types */           {TPM2B_AUTH_P_UNMARSHAL,
+			   TPMI_ALG_HASH_P_UNMARSHAL + ADD_FLAG,
+			   END_OF_LIST,
+			   TPMI_DH_OBJECT_H_MARSHAL,
+			   END_OF_LIST}
+};
+#define _HashSequenceStartDataAddress (&_HashSequenceStartData)
+#else
+#define _HashSequenceStartDataAddress 0
+#endif
+#if CC_SequenceUpdate
+#include "SequenceUpdate_fp.h"
+typedef TPM_RC  (SequenceUpdate_Entry)(
+				       SequenceUpdate_In *in
+				       );
+typedef const struct {
+    SequenceUpdate_Entry    *entry;
+    UINT16                  inSize;
+    UINT16                  outSize;
+    UINT16                  offsetOfTypes;
+    UINT16                  paramOffsets[1];
+    BYTE                    types[4];
+} SequenceUpdate_COMMAND_DESCRIPTOR_t;
+SequenceUpdate_COMMAND_DESCRIPTOR_t _SequenceUpdateData = {
+    /* entry  */          &TPM2_SequenceUpdate,
+    /* inSize */          (UINT16)(sizeof(SequenceUpdate_In)),
+    /* outSize */         0,
+    /* offsetOfTypes */   offsetof(SequenceUpdate_COMMAND_DESCRIPTOR_t, types),
+    /* offsets */         {(UINT16)(offsetof(SequenceUpdate_In, buffer))},
+    /* types */           {TPMI_DH_OBJECT_H_UNMARSHAL,
+			   TPM2B_MAX_BUFFER_P_UNMARSHAL,
+			   END_OF_LIST,
+			   END_OF_LIST}
+};
+#define _SequenceUpdateDataAddress (&_SequenceUpdateData)
+#else
+#define _SequenceUpdateDataAddress 0
+#endif
+#if CC_SequenceComplete
+#include "SequenceComplete_fp.h"
+typedef TPM_RC  (SequenceComplete_Entry)(
+					 SequenceComplete_In *in,
+					 SequenceComplete_Out *out
+					 );
+typedef const struct {
+    SequenceComplete_Entry    *entry;
+    UINT16                    inSize;
+    UINT16                    outSize;
+    UINT16                    offsetOfTypes;
+    UINT16                    paramOffsets[3];
+    BYTE                      types[7];
+} SequenceComplete_COMMAND_DESCRIPTOR_t;
+SequenceComplete_COMMAND_DESCRIPTOR_t _SequenceCompleteData = {
+    /* entry  */          &TPM2_SequenceComplete,
+    /* inSize */          (UINT16)(sizeof(SequenceComplete_In)),
+    /* outSize */         (UINT16)(sizeof(SequenceComplete_Out)),
+    /* offsetOfTypes */   offsetof(SequenceComplete_COMMAND_DESCRIPTOR_t, types),
+    /* offsets */         {(UINT16)(offsetof(SequenceComplete_In, buffer)),
+			   (UINT16)(offsetof(SequenceComplete_In, hierarchy)),
+			   (UINT16)(offsetof(SequenceComplete_Out, validation))},
+    /* types */           {TPMI_DH_OBJECT_H_UNMARSHAL,
+			   TPM2B_MAX_BUFFER_P_UNMARSHAL,
+			   TPMI_RH_HIERARCHY_P_UNMARSHAL + ADD_FLAG,
+			   END_OF_LIST,
+			   TPM2B_DIGEST_P_MARSHAL,
+			   TPMT_TK_HASHCHECK_P_MARSHAL,
+			   END_OF_LIST}
+};
+#define _SequenceCompleteDataAddress (&_SequenceCompleteData)
+#else
+#define _SequenceCompleteDataAddress 0
+#endif
+#if CC_EventSequenceComplete
+#include "EventSequenceComplete_fp.h"
+typedef TPM_RC  (EventSequenceComplete_Entry)(
+					      EventSequenceComplete_In *in,
+					      EventSequenceComplete_Out *out
+					      );
+typedef const struct {
+    EventSequenceComplete_Entry    *entry;
+    UINT16                         inSize;
+    UINT16                         outSize;
+    UINT16                         offsetOfTypes;
+    UINT16                         paramOffsets[2];
+    BYTE                           types[6];
+} EventSequenceComplete_COMMAND_DESCRIPTOR_t;
+EventSequenceComplete_COMMAND_DESCRIPTOR_t _EventSequenceCompleteData = {
+    /* entry  */          &TPM2_EventSequenceComplete,
+    /* inSize */          (UINT16)(sizeof(EventSequenceComplete_In)),
+    /* outSize */         (UINT16)(sizeof(EventSequenceComplete_Out)),
+    /* offsetOfTypes */   offsetof(EventSequenceComplete_COMMAND_DESCRIPTOR_t, types),
+    /* offsets */         {(UINT16)(offsetof(EventSequenceComplete_In, sequenceHandle)),
+			   (UINT16)(offsetof(EventSequenceComplete_In, buffer))},
+    /* types */           {TPMI_DH_PCR_H_UNMARSHAL + ADD_FLAG,
+			   TPMI_DH_OBJECT_H_UNMARSHAL,
+			   TPM2B_MAX_BUFFER_P_UNMARSHAL,
+			   END_OF_LIST,
+			   TPML_DIGEST_VALUES_P_MARSHAL,
+			   END_OF_LIST}
+};
+#define _EventSequenceCompleteDataAddress (&_EventSequenceCompleteData)
+#else
+#define _EventSequenceCompleteDataAddress 0
+#endif
+#if CC_Certify
+#include "Certify_fp.h"
+typedef TPM_RC  (Certify_Entry)(
+				Certify_In *in,
+				Certify_Out *out
+				);
+typedef const struct {
+    Certify_Entry    *entry;
+    UINT16           inSize;
+    UINT16           outSize;
+    UINT16           offsetOfTypes;
+    UINT16           paramOffsets[4];
+    BYTE             types[8];
+} Certify_COMMAND_DESCRIPTOR_t;
+Certify_COMMAND_DESCRIPTOR_t _CertifyData = {
+    /* entry  */          &TPM2_Certify,
+    /* inSize */          (UINT16)(sizeof(Certify_In)),
+    /* outSize */         (UINT16)(sizeof(Certify_Out)),
+    /* offsetOfTypes */   offsetof(Certify_COMMAND_DESCRIPTOR_t, types),
+    /* offsets */         {(UINT16)(offsetof(Certify_In, signHandle)),
+			   (UINT16)(offsetof(Certify_In, qualifyingData)),
+			   (UINT16)(offsetof(Certify_In, inScheme)),
+			   (UINT16)(offsetof(Certify_Out, signature))},
+    /* types */           {TPMI_DH_OBJECT_H_UNMARSHAL,
+			   TPMI_DH_OBJECT_H_UNMARSHAL + ADD_FLAG,
+			   TPM2B_DATA_P_UNMARSHAL,
+			   TPMT_SIG_SCHEME_P_UNMARSHAL + ADD_FLAG,
+			   END_OF_LIST,
+			   TPM2B_ATTEST_P_MARSHAL,
+			   TPMT_SIGNATURE_P_MARSHAL,
+			   END_OF_LIST}
+};
+#define _CertifyDataAddress (&_CertifyData)
+#else
+#define _CertifyDataAddress 0
+#endif
+#if CC_CertifyCreation
+#include "CertifyCreation_fp.h"
+typedef TPM_RC  (CertifyCreation_Entry)(
+					CertifyCreation_In *in,
+					CertifyCreation_Out *out
+					);
+typedef const struct {
+    CertifyCreation_Entry    *entry;
+    UINT16                   inSize;
+    UINT16                   outSize;
+    UINT16                   offsetOfTypes;
+    UINT16                   paramOffsets[6];
+    BYTE                     types[10];
+} CertifyCreation_COMMAND_DESCRIPTOR_t;
+CertifyCreation_COMMAND_DESCRIPTOR_t _CertifyCreationData = {
+    /* entry  */          &TPM2_CertifyCreation,
+    /* inSize */          (UINT16)(sizeof(CertifyCreation_In)),
+    /* outSize */         (UINT16)(sizeof(CertifyCreation_Out)),
+    /* offsetOfTypes */   offsetof(CertifyCreation_COMMAND_DESCRIPTOR_t, types),
+    /* offsets */         {(UINT16)(offsetof(CertifyCreation_In, objectHandle)),
+			   (UINT16)(offsetof(CertifyCreation_In, qualifyingData)),
+			   (UINT16)(offsetof(CertifyCreation_In, creationHash)),
+			   (UINT16)(offsetof(CertifyCreation_In, inScheme)),
+			   (UINT16)(offsetof(CertifyCreation_In, creationTicket)),
+			   (UINT16)(offsetof(CertifyCreation_Out, signature))},
+    /* types */           {TPMI_DH_OBJECT_H_UNMARSHAL + ADD_FLAG,
+			   TPMI_DH_OBJECT_H_UNMARSHAL,
+			   TPM2B_DATA_P_UNMARSHAL,
+			   TPM2B_DIGEST_P_UNMARSHAL,
+			   TPMT_SIG_SCHEME_P_UNMARSHAL + ADD_FLAG,
+			   TPMT_TK_CREATION_P_UNMARSHAL,
+			   END_OF_LIST,
+			   TPM2B_ATTEST_P_MARSHAL,
+			   TPMT_SIGNATURE_P_MARSHAL,
+			   END_OF_LIST}
+};
+#define _CertifyCreationDataAddress (&_CertifyCreationData)
+#else
+#define _CertifyCreationDataAddress 0
+#endif
+#if CC_Quote
+#include "Quote_fp.h"
+typedef TPM_RC  (Quote_Entry)(
+			      Quote_In *in,
+			      Quote_Out *out
+			      );
+typedef const struct {
+    Quote_Entry    *entry;
+    UINT16         inSize;
+    UINT16         outSize;
+    UINT16         offsetOfTypes;
+    UINT16         paramOffsets[4];
+    BYTE           types[8];
+} Quote_COMMAND_DESCRIPTOR_t;
+Quote_COMMAND_DESCRIPTOR_t _QuoteData = {
+    /* entry  */          &TPM2_Quote,
+    /* inSize */          (UINT16)(sizeof(Quote_In)),
+    /* outSize */         (UINT16)(sizeof(Quote_Out)),
+    /* offsetOfTypes */   offsetof(Quote_COMMAND_DESCRIPTOR_t, types),
+    /* offsets */         {(UINT16)(offsetof(Quote_In, qualifyingData)),
+			   (UINT16)(offsetof(Quote_In, inScheme)),
+			   (UINT16)(offsetof(Quote_In, PCRselect)),
+			   (UINT16)(offsetof(Quote_Out, signature))},
+    /* types */           {TPMI_DH_OBJECT_H_UNMARSHAL + ADD_FLAG,
+			   TPM2B_DATA_P_UNMARSHAL,
+			   TPMT_SIG_SCHEME_P_UNMARSHAL + ADD_FLAG,
+			   TPML_PCR_SELECTION_P_UNMARSHAL,
+			   END_OF_LIST,
+			   TPM2B_ATTEST_P_MARSHAL,
+			   TPMT_SIGNATURE_P_MARSHAL,
+			   END_OF_LIST}
+};
+#define _QuoteDataAddress (&_QuoteData)
+#else
+#define _QuoteDataAddress 0
+#endif
+#if CC_GetSessionAuditDigest
+#include "GetSessionAuditDigest_fp.h"
+typedef TPM_RC  (GetSessionAuditDigest_Entry)(
+					      GetSessionAuditDigest_In *in,
+					      GetSessionAuditDigest_Out *out
+					      );
+typedef const struct {
+    GetSessionAuditDigest_Entry    *entry;
+    UINT16                         inSize;
+    UINT16                         outSize;
+    UINT16                         offsetOfTypes;
+    UINT16                         paramOffsets[5];
+    BYTE                           types[9];
+} GetSessionAuditDigest_COMMAND_DESCRIPTOR_t;
+GetSessionAuditDigest_COMMAND_DESCRIPTOR_t _GetSessionAuditDigestData = {
+    /* entry  */          &TPM2_GetSessionAuditDigest,
+    /* inSize */          (UINT16)(sizeof(GetSessionAuditDigest_In)),
+    /* outSize */         (UINT16)(sizeof(GetSessionAuditDigest_Out)),
+    /* offsetOfTypes */   offsetof(GetSessionAuditDigest_COMMAND_DESCRIPTOR_t, types),
+    /* offsets */         {(UINT16)(offsetof(GetSessionAuditDigest_In, signHandle)),
+			   (UINT16)(offsetof(GetSessionAuditDigest_In, sessionHandle)),
+			   (UINT16)(offsetof(GetSessionAuditDigest_In, qualifyingData)),
+			   (UINT16)(offsetof(GetSessionAuditDigest_In, inScheme)),
+			   (UINT16)(offsetof(GetSessionAuditDigest_Out, signature))},
+    /* types */           {TPMI_RH_ENDORSEMENT_H_UNMARSHAL,
+			   TPMI_DH_OBJECT_H_UNMARSHAL + ADD_FLAG,
+			   TPMI_SH_HMAC_H_UNMARSHAL,
+			   TPM2B_DATA_P_UNMARSHAL,
+			   TPMT_SIG_SCHEME_P_UNMARSHAL + ADD_FLAG,
+			   END_OF_LIST,
+			   TPM2B_ATTEST_P_MARSHAL,
+			   TPMT_SIGNATURE_P_MARSHAL,
+			   END_OF_LIST}
+};
+#define _GetSessionAuditDigestDataAddress (&_GetSessionAuditDigestData)
+#else
+#define _GetSessionAuditDigestDataAddress 0
+#endif
+#if CC_GetCommandAuditDigest
+#include "GetCommandAuditDigest_fp.h"
+typedef TPM_RC  (GetCommandAuditDigest_Entry)(
+					      GetCommandAuditDigest_In *in,
+					      GetCommandAuditDigest_Out *out
+					      );
+typedef const struct {
+    GetCommandAuditDigest_Entry    *entry;
+    UINT16                         inSize;
+    UINT16                         outSize;
+    UINT16                         offsetOfTypes;
+    UINT16                         paramOffsets[4];
+    BYTE                           types[8];
+} GetCommandAuditDigest_COMMAND_DESCRIPTOR_t;
+GetCommandAuditDigest_COMMAND_DESCRIPTOR_t _GetCommandAuditDigestData = {
+    /* entry  */          &TPM2_GetCommandAuditDigest,
+    /* inSize */          (UINT16)(sizeof(GetCommandAuditDigest_In)),
+    /* outSize */         (UINT16)(sizeof(GetCommandAuditDigest_Out)),
+    /* offsetOfTypes */   offsetof(GetCommandAuditDigest_COMMAND_DESCRIPTOR_t, types),
+    /* offsets */         {(UINT16)(offsetof(GetCommandAuditDigest_In, signHandle)),
+			   (UINT16)(offsetof(GetCommandAuditDigest_In, qualifyingData)),
+			   (UINT16)(offsetof(GetCommandAuditDigest_In, inScheme)),
+			   (UINT16)(offsetof(GetCommandAuditDigest_Out, signature))},
+    /* types */           {TPMI_RH_ENDORSEMENT_H_UNMARSHAL,
+			   TPMI_DH_OBJECT_H_UNMARSHAL + ADD_FLAG,
+			   TPM2B_DATA_P_UNMARSHAL,
+			   TPMT_SIG_SCHEME_P_UNMARSHAL + ADD_FLAG,
+			   END_OF_LIST,
+			   TPM2B_ATTEST_P_MARSHAL,
+			   TPMT_SIGNATURE_P_MARSHAL,
+			   END_OF_LIST}
+};
+#define _GetCommandAuditDigestDataAddress (&_GetCommandAuditDigestData)
+#else
+#define _GetCommandAuditDigestDataAddress 0
+#endif
+#if CC_GetTime
+#include "GetTime_fp.h"
+typedef TPM_RC  (GetTime_Entry)(
+				GetTime_In *in,
+				GetTime_Out *out
+				);
+typedef const struct {
+    GetTime_Entry    *entry;
+    UINT16           inSize;
+    UINT16           outSize;
+    UINT16           offsetOfTypes;
+    UINT16           paramOffsets[4];
+    BYTE             types[8];
+} GetTime_COMMAND_DESCRIPTOR_t;
+GetTime_COMMAND_DESCRIPTOR_t _GetTimeData = {
+    /* entry  */          &TPM2_GetTime,
+    /* inSize */          (UINT16)(sizeof(GetTime_In)),
+    /* outSize */         (UINT16)(sizeof(GetTime_Out)),
+    /* offsetOfTypes */   offsetof(GetTime_COMMAND_DESCRIPTOR_t, types),
+    /* offsets */         {(UINT16)(offsetof(GetTime_In, signHandle)),
+			   (UINT16)(offsetof(GetTime_In, qualifyingData)),
+			   (UINT16)(offsetof(GetTime_In, inScheme)),
+			   (UINT16)(offsetof(GetTime_Out, signature))},
+    /* types */           {TPMI_RH_ENDORSEMENT_H_UNMARSHAL,
+			   TPMI_DH_OBJECT_H_UNMARSHAL + ADD_FLAG,
+			   TPM2B_DATA_P_UNMARSHAL,
+			   TPMT_SIG_SCHEME_P_UNMARSHAL + ADD_FLAG,
+			   END_OF_LIST,
+			   TPM2B_ATTEST_P_MARSHAL,
+			   TPMT_SIGNATURE_P_MARSHAL,
+			   END_OF_LIST}
+};
+#define _GetTimeDataAddress (&_GetTimeData)
+#else
+#define _GetTimeDataAddress 0
+#endif
+#if CC_CertifyX509
+#include "CertifyX509_fp.h"
+typedef TPM_RC  (CertifyX509_Entry)(
+				    CertifyX509_In              *in,
+				    CertifyX509_Out             *out
+				    );
+typedef const struct {
+    CertifyX509_Entry       *entry;
+    UINT16                  inSize;
+    UINT16                  outSize;
+    UINT16                  offsetOfTypes;
+    UINT16                  paramOffsets[6];
+    BYTE                    types[10];
+} CertifyX509_COMMAND_DESCRIPTOR_t;
+CertifyX509_COMMAND_DESCRIPTOR_t _CertifyX509Data = {
+	/* entry         */     &TPM2_CertifyX509,
+	/* inSize        */     (UINT16)(sizeof(CertifyX509_In)),
+	/* outSize       */     (UINT16)(sizeof(CertifyX509_Out)),
+	/* offsetOfTypes */     offsetof(CertifyX509_COMMAND_DESCRIPTOR_t, types),
+	/* offsets       */     {(UINT16)(offsetof(CertifyX509_In, signHandle)),
+				 (UINT16)(offsetof(CertifyX509_In, reserved)),
+				 (UINT16)(offsetof(CertifyX509_In, inScheme)),
+				 (UINT16)(offsetof(CertifyX509_In, partialCertificate)),
+				 (UINT16)(offsetof(CertifyX509_Out, tbsDigest)),
+				 (UINT16)(offsetof(CertifyX509_Out, signature))},
+	/* types         */     {TPMI_DH_OBJECT_H_UNMARSHAL,
+				 TPMI_DH_OBJECT_H_UNMARSHAL + ADD_FLAG,
+				 TPM2B_DATA_P_UNMARSHAL,
+				 TPMT_SIG_SCHEME_P_UNMARSHAL + ADD_FLAG,
+				 TPM2B_MAX_BUFFER_P_UNMARSHAL,
+				 END_OF_LIST,
+				 TPM2B_MAX_BUFFER_P_MARSHAL,
+				 TPM2B_DIGEST_P_MARSHAL,
+				 TPMT_SIGNATURE_P_MARSHAL,
+				 END_OF_LIST}
+};
+#define _CertifyX509DataAddress (&_CertifyX509Data)
+#else
+#define _CertifyX509DataAddress 0
+#endif // CC_CertifyX509
+#if CC_Commit
+#include "Commit_fp.h"
+typedef TPM_RC  (Commit_Entry)(
+			       Commit_In *in,
+			       Commit_Out *out
+			       );
+typedef const struct {
+    Commit_Entry    *entry;
+    UINT16          inSize;
+    UINT16          outSize;
+    UINT16          offsetOfTypes;
+    UINT16          paramOffsets[6];
+    BYTE            types[10];
+} Commit_COMMAND_DESCRIPTOR_t;
+Commit_COMMAND_DESCRIPTOR_t _CommitData = {
+    /* entry  */          &TPM2_Commit,
+    /* inSize */          (UINT16)(sizeof(Commit_In)),
+    /* outSize */         (UINT16)(sizeof(Commit_Out)),
+    /* offsetOfTypes */   offsetof(Commit_COMMAND_DESCRIPTOR_t, types),
+    /* offsets */         {(UINT16)(offsetof(Commit_In, P1)),
+			   (UINT16)(offsetof(Commit_In, s2)),
+			   (UINT16)(offsetof(Commit_In, y2)),
+			   (UINT16)(offsetof(Commit_Out, L)),
+			   (UINT16)(offsetof(Commit_Out, E)),
+			   (UINT16)(offsetof(Commit_Out, counter))},
+    /* types */           {TPMI_DH_OBJECT_H_UNMARSHAL,
+			   TPM2B_ECC_POINT_P_UNMARSHAL,
+			   TPM2B_SENSITIVE_DATA_P_UNMARSHAL,
+			   TPM2B_ECC_PARAMETER_P_UNMARSHAL,
+			   END_OF_LIST,
+			   TPM2B_ECC_POINT_P_MARSHAL,
+			   TPM2B_ECC_POINT_P_MARSHAL,
+			   TPM2B_ECC_POINT_P_MARSHAL,
+			   UINT16_P_MARSHAL,
+			   END_OF_LIST}
+};
+#define _CommitDataAddress (&_CommitData)
+#else
+#define _CommitDataAddress 0
+#endif
+#if CC_EC_Ephemeral
+#include "EC_Ephemeral_fp.h"
+typedef TPM_RC  (EC_Ephemeral_Entry)(
+				     EC_Ephemeral_In *in,
+				     EC_Ephemeral_Out *out
+				     );
+typedef const struct {
+    EC_Ephemeral_Entry    *entry;
+    UINT16                inSize;
+    UINT16                outSize;
+    UINT16                offsetOfTypes;
+    UINT16                paramOffsets[1];
+    BYTE                  types[5];
+} EC_Ephemeral_COMMAND_DESCRIPTOR_t;
+EC_Ephemeral_COMMAND_DESCRIPTOR_t _EC_EphemeralData = {
+    /* entry  */          &TPM2_EC_Ephemeral,
+    /* inSize */          (UINT16)(sizeof(EC_Ephemeral_In)),
+    /* outSize */         (UINT16)(sizeof(EC_Ephemeral_Out)),
+    /* offsetOfTypes */   offsetof(EC_Ephemeral_COMMAND_DESCRIPTOR_t, types),
+    /* offsets */         {(UINT16)(offsetof(EC_Ephemeral_Out, counter))},
+    /* types */           {TPMI_ECC_CURVE_P_UNMARSHAL,
+			   END_OF_LIST,
+			   TPM2B_ECC_POINT_P_MARSHAL,
+			   UINT16_P_MARSHAL,
+			   END_OF_LIST}
+};
+#define _EC_EphemeralDataAddress (&_EC_EphemeralData)
+#else
+#define _EC_EphemeralDataAddress 0
+#endif
+#if CC_VerifySignature
+#include "VerifySignature_fp.h"
+typedef TPM_RC  (VerifySignature_Entry)(
+					VerifySignature_In *in,
+					VerifySignature_Out *out
+					);
+typedef const struct {
+    VerifySignature_Entry    *entry;
+    UINT16                   inSize;
+    UINT16                   outSize;
+    UINT16                   offsetOfTypes;
+    UINT16                   paramOffsets[2];
+    BYTE                     types[6];
+} VerifySignature_COMMAND_DESCRIPTOR_t;
+VerifySignature_COMMAND_DESCRIPTOR_t _VerifySignatureData = {
+    /* entry  */          &TPM2_VerifySignature,
+    /* inSize */          (UINT16)(sizeof(VerifySignature_In)),
+    /* outSize */         (UINT16)(sizeof(VerifySignature_Out)),
+    /* offsetOfTypes */   offsetof(VerifySignature_COMMAND_DESCRIPTOR_t, types),
+    /* offsets */         {(UINT16)(offsetof(VerifySignature_In, digest)),
+			   (UINT16)(offsetof(VerifySignature_In, signature))},
+    /* types */           {TPMI_DH_OBJECT_H_UNMARSHAL,
+			   TPM2B_DIGEST_P_UNMARSHAL,
+			   TPMT_SIGNATURE_P_UNMARSHAL,
+			   END_OF_LIST,
+			   TPMT_TK_VERIFIED_P_MARSHAL,
+			   END_OF_LIST}
+};
+#define _VerifySignatureDataAddress (&_VerifySignatureData)
+#else
+#define _VerifySignatureDataAddress 0
+#endif
+#if CC_Sign
+#include "Sign_fp.h"
+typedef TPM_RC  (Sign_Entry)(
+			     Sign_In *in,
+			     Sign_Out *out
+			     );
+typedef const struct {
+    Sign_Entry    *entry;
+    UINT16        inSize;
+    UINT16        outSize;
+    UINT16        offsetOfTypes;
+    UINT16        paramOffsets[3];
+    BYTE          types[7];
+} Sign_COMMAND_DESCRIPTOR_t;
+Sign_COMMAND_DESCRIPTOR_t _SignData = {
+    /* entry  */          &TPM2_Sign,
+    /* inSize */          (UINT16)(sizeof(Sign_In)),
+    /* outSize */         (UINT16)(sizeof(Sign_Out)),
+    /* offsetOfTypes */   offsetof(Sign_COMMAND_DESCRIPTOR_t, types),
+    /* offsets */         {(UINT16)(offsetof(Sign_In, digest)),
+			   (UINT16)(offsetof(Sign_In, inScheme)),
+			   (UINT16)(offsetof(Sign_In, validation))},
+    /* types */           {TPMI_DH_OBJECT_H_UNMARSHAL,
+			   TPM2B_DIGEST_P_UNMARSHAL,
+			   TPMT_SIG_SCHEME_P_UNMARSHAL + ADD_FLAG,
+			   TPMT_TK_HASHCHECK_P_UNMARSHAL,
+			   END_OF_LIST,
+			   TPMT_SIGNATURE_P_MARSHAL,
+			   END_OF_LIST}
+};
+#define _SignDataAddress (&_SignData)
+#else
+#define _SignDataAddress 0
+#endif
+#if CC_SetCommandCodeAuditStatus
+#include "SetCommandCodeAuditStatus_fp.h"
+typedef TPM_RC  (SetCommandCodeAuditStatus_Entry)(
+						  SetCommandCodeAuditStatus_In *in
+						  );
+typedef const struct {
+    SetCommandCodeAuditStatus_Entry    *entry;
+    UINT16                             inSize;
+    UINT16                             outSize;
+    UINT16                             offsetOfTypes;
+    UINT16                             paramOffsets[3];
+    BYTE                               types[6];
+} SetCommandCodeAuditStatus_COMMAND_DESCRIPTOR_t;
+SetCommandCodeAuditStatus_COMMAND_DESCRIPTOR_t _SetCommandCodeAuditStatusData = {
+    /* entry  */          &TPM2_SetCommandCodeAuditStatus,
+    /* inSize */          (UINT16)(sizeof(SetCommandCodeAuditStatus_In)),
+    /* outSize */         0,
+    /* offsetOfTypes */   offsetof(SetCommandCodeAuditStatus_COMMAND_DESCRIPTOR_t, types),
+    /* offsets */         {(UINT16)(offsetof(SetCommandCodeAuditStatus_In, auditAlg)),
+			   (UINT16)(offsetof(SetCommandCodeAuditStatus_In, setList)),
+			   (UINT16)(offsetof(SetCommandCodeAuditStatus_In, clearList))},
+    /* types */           {TPMI_RH_PROVISION_H_UNMARSHAL,
+			   TPMI_ALG_HASH_P_UNMARSHAL + ADD_FLAG,
+			   TPML_CC_P_UNMARSHAL,
+			   TPML_CC_P_UNMARSHAL,
+			   END_OF_LIST,
+			   END_OF_LIST}
+};
+#define _SetCommandCodeAuditStatusDataAddress (&_SetCommandCodeAuditStatusData)
+#else
+#define _SetCommandCodeAuditStatusDataAddress 0
+#endif
+#if CC_PCR_Extend
+#include "PCR_Extend_fp.h"
+typedef TPM_RC  (PCR_Extend_Entry)(
+				   PCR_Extend_In *in
+				   );
+typedef const struct {
+    PCR_Extend_Entry    *entry;
+    UINT16              inSize;
+    UINT16              outSize;
+    UINT16              offsetOfTypes;
+    UINT16              paramOffsets[1];
+    BYTE                types[4];
+} PCR_Extend_COMMAND_DESCRIPTOR_t;
+PCR_Extend_COMMAND_DESCRIPTOR_t _PCR_ExtendData = {
+    /* entry  */          &TPM2_PCR_Extend,
+    /* inSize */          (UINT16)(sizeof(PCR_Extend_In)),
+    /* outSize */         0,
+    /* offsetOfTypes */   offsetof(PCR_Extend_COMMAND_DESCRIPTOR_t, types),
+    /* offsets */         {(UINT16)(offsetof(PCR_Extend_In, digests))},
+    /* types */           {TPMI_DH_PCR_H_UNMARSHAL + ADD_FLAG,
+			   TPML_DIGEST_VALUES_P_UNMARSHAL,
+			   END_OF_LIST,
+			   END_OF_LIST}
+};
+#define _PCR_ExtendDataAddress (&_PCR_ExtendData)
+#else
+#define _PCR_ExtendDataAddress 0
+#endif
+#if CC_PCR_Event
+#include "PCR_Event_fp.h"
+typedef TPM_RC  (PCR_Event_Entry)(
+				  PCR_Event_In *in,
+				  PCR_Event_Out *out
+				  );
+typedef const struct {
+    PCR_Event_Entry    *entry;
+    UINT16             inSize;
+    UINT16             outSize;
+    UINT16             offsetOfTypes;
+    UINT16             paramOffsets[1];
+    BYTE               types[5];
+} PCR_Event_COMMAND_DESCRIPTOR_t;
+PCR_Event_COMMAND_DESCRIPTOR_t _PCR_EventData = {
+    /* entry  */          &TPM2_PCR_Event,
+    /* inSize */          (UINT16)(sizeof(PCR_Event_In)),
+    /* outSize */         (UINT16)(sizeof(PCR_Event_Out)),
+    /* offsetOfTypes */   offsetof(PCR_Event_COMMAND_DESCRIPTOR_t, types),
+    /* offsets */         {(UINT16)(offsetof(PCR_Event_In, eventData))},
+    /* types */           {TPMI_DH_PCR_H_UNMARSHAL + ADD_FLAG,
+			   TPM2B_EVENT_P_UNMARSHAL,
+			   END_OF_LIST,
+			   TPML_DIGEST_VALUES_P_MARSHAL,
+			   END_OF_LIST}
+};
+#define _PCR_EventDataAddress (&_PCR_EventData)
+#else
+#define _PCR_EventDataAddress 0
+#endif
+#if CC_PCR_Read
+#include "PCR_Read_fp.h"
+typedef TPM_RC  (PCR_Read_Entry)(
+				 PCR_Read_In *in,
+				 PCR_Read_Out *out
+				 );
+typedef const struct {
+    PCR_Read_Entry    *entry;
+    UINT16            inSize;
+    UINT16            outSize;
+    UINT16            offsetOfTypes;
+    UINT16            paramOffsets[2];
+    BYTE              types[6];
+} PCR_Read_COMMAND_DESCRIPTOR_t;
+PCR_Read_COMMAND_DESCRIPTOR_t _PCR_ReadData = {
+    /* entry  */          &TPM2_PCR_Read,
+    /* inSize */          (UINT16)(sizeof(PCR_Read_In)),
+    /* outSize */         (UINT16)(sizeof(PCR_Read_Out)),
+    /* offsetOfTypes */   offsetof(PCR_Read_COMMAND_DESCRIPTOR_t, types),
+    /* offsets */         {(UINT16)(offsetof(PCR_Read_Out, pcrSelectionOut)),
+			   (UINT16)(offsetof(PCR_Read_Out, pcrValues))},
+    /* types */           {TPML_PCR_SELECTION_P_UNMARSHAL,
+			   END_OF_LIST,
+			   UINT32_P_MARSHAL,
+			   TPML_PCR_SELECTION_P_MARSHAL,
+			   TPML_DIGEST_P_MARSHAL,
+			   END_OF_LIST}
+};
+#define _PCR_ReadDataAddress (&_PCR_ReadData)
+#else
+#define _PCR_ReadDataAddress 0
+#endif
+#if CC_PCR_Allocate
+#include "PCR_Allocate_fp.h"
+typedef TPM_RC  (PCR_Allocate_Entry)(
+				     PCR_Allocate_In *in,
+				     PCR_Allocate_Out *out
+				     );
+typedef const struct {
+    PCR_Allocate_Entry    *entry;
+    UINT16                inSize;
+    UINT16                outSize;
+    UINT16                offsetOfTypes;
+    UINT16                paramOffsets[4];
+    BYTE                  types[8];
+} PCR_Allocate_COMMAND_DESCRIPTOR_t;
+PCR_Allocate_COMMAND_DESCRIPTOR_t _PCR_AllocateData = {
+    /* entry  */          &TPM2_PCR_Allocate,
+    /* inSize */          (UINT16)(sizeof(PCR_Allocate_In)),
+    /* outSize */         (UINT16)(sizeof(PCR_Allocate_Out)),
+    /* offsetOfTypes */   offsetof(PCR_Allocate_COMMAND_DESCRIPTOR_t, types),
+    /* offsets */         {(UINT16)(offsetof(PCR_Allocate_In, pcrAllocation)),
+			   (UINT16)(offsetof(PCR_Allocate_Out, maxPCR)),
+			   (UINT16)(offsetof(PCR_Allocate_Out, sizeNeeded)),
+			   (UINT16)(offsetof(PCR_Allocate_Out, sizeAvailable))},
+    /* types */           {TPMI_RH_PLATFORM_H_UNMARSHAL,
+			   TPML_PCR_SELECTION_P_UNMARSHAL,
+			   END_OF_LIST,
+			   TPMI_YES_NO_P_MARSHAL,
+			   UINT32_P_MARSHAL,
+			   UINT32_P_MARSHAL,
+			   UINT32_P_MARSHAL,
+			   END_OF_LIST}
+};
+#define _PCR_AllocateDataAddress (&_PCR_AllocateData)
+#else
+#define _PCR_AllocateDataAddress 0
+#endif
+#if CC_PCR_SetAuthPolicy
+#include "PCR_SetAuthPolicy_fp.h"
+typedef TPM_RC  (PCR_SetAuthPolicy_Entry)(
+					  PCR_SetAuthPolicy_In *in
+					  );
+typedef const struct {
+    PCR_SetAuthPolicy_Entry    *entry;
+    UINT16                     inSize;
+    UINT16                     outSize;
+    UINT16                     offsetOfTypes;
+    UINT16                     paramOffsets[3];
+    BYTE                       types[6];
+} PCR_SetAuthPolicy_COMMAND_DESCRIPTOR_t;
+PCR_SetAuthPolicy_COMMAND_DESCRIPTOR_t _PCR_SetAuthPolicyData = {
+    /* entry  */          &TPM2_PCR_SetAuthPolicy,
+    /* inSize */          (UINT16)(sizeof(PCR_SetAuthPolicy_In)),
+    /* outSize */         0,
+    /* offsetOfTypes */   offsetof(PCR_SetAuthPolicy_COMMAND_DESCRIPTOR_t, types),
+    /* offsets */         {(UINT16)(offsetof(PCR_SetAuthPolicy_In, authPolicy)),
+			   (UINT16)(offsetof(PCR_SetAuthPolicy_In, hashAlg)),
+			   (UINT16)(offsetof(PCR_SetAuthPolicy_In, pcrNum))},
+    /* types */           {TPMI_RH_PLATFORM_H_UNMARSHAL,
+			   TPM2B_DIGEST_P_UNMARSHAL,
+			   TPMI_ALG_HASH_P_UNMARSHAL + ADD_FLAG,
+			   TPMI_DH_PCR_P_UNMARSHAL,
+			   END_OF_LIST,
+			   END_OF_LIST}
+};
+#define _PCR_SetAuthPolicyDataAddress (&_PCR_SetAuthPolicyData)
+#else
+#define _PCR_SetAuthPolicyDataAddress 0
+#endif
+#if CC_PCR_SetAuthValue
+#include "PCR_SetAuthValue_fp.h"
+typedef TPM_RC  (PCR_SetAuthValue_Entry)(
+					 PCR_SetAuthValue_In *in
+					 );
+typedef const struct {
+    PCR_SetAuthValue_Entry    *entry;
+    UINT16                    inSize;
+    UINT16                    outSize;
+    UINT16                    offsetOfTypes;
+    UINT16                    paramOffsets[1];
+    BYTE                      types[4];
+} PCR_SetAuthValue_COMMAND_DESCRIPTOR_t;
+PCR_SetAuthValue_COMMAND_DESCRIPTOR_t _PCR_SetAuthValueData = {
+    /* entry  */          &TPM2_PCR_SetAuthValue,
+    /* inSize */          (UINT16)(sizeof(PCR_SetAuthValue_In)),
+    /* outSize */         0,
+    /* offsetOfTypes */   offsetof(PCR_SetAuthValue_COMMAND_DESCRIPTOR_t, types),
+    /* offsets */         {(UINT16)(offsetof(PCR_SetAuthValue_In, auth))},
+    /* types */           {TPMI_DH_PCR_H_UNMARSHAL,
+			   TPM2B_DIGEST_P_UNMARSHAL,
+			   END_OF_LIST,
+			   END_OF_LIST}
+};
+#define _PCR_SetAuthValueDataAddress (&_PCR_SetAuthValueData)
+#else
+#define _PCR_SetAuthValueDataAddress 0
+#endif
+#if CC_PCR_Reset
+#include "PCR_Reset_fp.h"
+typedef TPM_RC  (PCR_Reset_Entry)(
+				  PCR_Reset_In *in
+				  );
+typedef const struct {
+    PCR_Reset_Entry    *entry;
+    UINT16             inSize;
+    UINT16             outSize;
+    UINT16             offsetOfTypes;
+    BYTE               types[3];
+} PCR_Reset_COMMAND_DESCRIPTOR_t;
+PCR_Reset_COMMAND_DESCRIPTOR_t _PCR_ResetData = {
+    /* entry  */          &TPM2_PCR_Reset,
+    /* inSize */          (UINT16)(sizeof(PCR_Reset_In)),
+    /* outSize */         0,
+    /* offsetOfTypes */   offsetof(PCR_Reset_COMMAND_DESCRIPTOR_t, types),
+    /* offsets */         // No parameter offsets
+    /* types */           {TPMI_DH_PCR_H_UNMARSHAL,
+			   END_OF_LIST,
+			   END_OF_LIST}
+};
+#define _PCR_ResetDataAddress (&_PCR_ResetData)
+#else
+#define _PCR_ResetDataAddress 0
+#endif
+#if CC_PolicySigned
+#include "PolicySigned_fp.h"
+typedef TPM_RC  (PolicySigned_Entry)(
+				     PolicySigned_In *in,
+				     PolicySigned_Out *out
+				     );
+typedef const struct {
+    PolicySigned_Entry    *entry;
+    UINT16                inSize;
+    UINT16                outSize;
+    UINT16                offsetOfTypes;
+    UINT16                paramOffsets[7];
+    BYTE                  types[11];
+} PolicySigned_COMMAND_DESCRIPTOR_t;
+PolicySigned_COMMAND_DESCRIPTOR_t _PolicySignedData = {
+    /* entry  */          &TPM2_PolicySigned,
+    /* inSize */          (UINT16)(sizeof(PolicySigned_In)),
+    /* outSize */         (UINT16)(sizeof(PolicySigned_Out)),
+    /* offsetOfTypes */   offsetof(PolicySigned_COMMAND_DESCRIPTOR_t, types),
+    /* offsets */         {(UINT16)(offsetof(PolicySigned_In, policySession)),
+			   (UINT16)(offsetof(PolicySigned_In, nonceTPM)),
+			   (UINT16)(offsetof(PolicySigned_In, cpHashA)),
+			   (UINT16)(offsetof(PolicySigned_In, policyRef)),
+			   (UINT16)(offsetof(PolicySigned_In, expiration)),
+			   (UINT16)(offsetof(PolicySigned_In, auth)),
+			   (UINT16)(offsetof(PolicySigned_Out, policyTicket))},
+    /* types */           {TPMI_DH_OBJECT_H_UNMARSHAL,
+			   TPMI_SH_POLICY_H_UNMARSHAL,
+			   TPM2B_NONCE_P_UNMARSHAL,
+			   TPM2B_DIGEST_P_UNMARSHAL,
+			   TPM2B_NONCE_P_UNMARSHAL,
+			   INT32_P_UNMARSHAL,
+			   TPMT_SIGNATURE_P_UNMARSHAL,
+			   END_OF_LIST,
+			   TPM2B_TIMEOUT_P_MARSHAL,
+			   TPMT_TK_AUTH_P_MARSHAL,
+			   END_OF_LIST}
+};
+#define _PolicySignedDataAddress (&_PolicySignedData)
+#else
+#define _PolicySignedDataAddress 0
+#endif
+#if CC_PolicySecret
+#include "PolicySecret_fp.h"
+typedef TPM_RC  (PolicySecret_Entry)(
+				     PolicySecret_In *in,
+				     PolicySecret_Out *out
+				     );
+typedef const struct {
+    PolicySecret_Entry    *entry;
+    UINT16                inSize;
+    UINT16                outSize;
+    UINT16                offsetOfTypes;
+    UINT16                paramOffsets[6];
+    BYTE                  types[10];
+} PolicySecret_COMMAND_DESCRIPTOR_t;
+PolicySecret_COMMAND_DESCRIPTOR_t _PolicySecretData = {
+    /* entry  */          &TPM2_PolicySecret,
+    /* inSize */          (UINT16)(sizeof(PolicySecret_In)),
+    /* outSize */         (UINT16)(sizeof(PolicySecret_Out)),
+    /* offsetOfTypes */   offsetof(PolicySecret_COMMAND_DESCRIPTOR_t, types),
+    /* offsets */         {(UINT16)(offsetof(PolicySecret_In, policySession)),
+			   (UINT16)(offsetof(PolicySecret_In, nonceTPM)),
+			   (UINT16)(offsetof(PolicySecret_In, cpHashA)),
+			   (UINT16)(offsetof(PolicySecret_In, policyRef)),
+			   (UINT16)(offsetof(PolicySecret_In, expiration)),
+			   (UINT16)(offsetof(PolicySecret_Out, policyTicket))},
+    /* types */           {TPMI_DH_ENTITY_H_UNMARSHAL,
+			   TPMI_SH_POLICY_H_UNMARSHAL,
+			   TPM2B_NONCE_P_UNMARSHAL,
+			   TPM2B_DIGEST_P_UNMARSHAL,
+			   TPM2B_NONCE_P_UNMARSHAL,
+			   INT32_P_UNMARSHAL,
+			   END_OF_LIST,
+			   TPM2B_TIMEOUT_P_MARSHAL,
+			   TPMT_TK_AUTH_P_MARSHAL,
+			   END_OF_LIST}
+};
+#define _PolicySecretDataAddress (&_PolicySecretData)
+#else
+#define _PolicySecretDataAddress 0
+#endif
+#if CC_PolicyTicket
+#include "PolicyTicket_fp.h"
+typedef TPM_RC  (PolicyTicket_Entry)(
+				     PolicyTicket_In *in
+				     );
+typedef const struct {
+    PolicyTicket_Entry    *entry;
+    UINT16                inSize;
+    UINT16                outSize;
+    UINT16                offsetOfTypes;
+    UINT16                paramOffsets[5];
+    BYTE                  types[8];
+} PolicyTicket_COMMAND_DESCRIPTOR_t;
+PolicyTicket_COMMAND_DESCRIPTOR_t _PolicyTicketData = {
+    /* entry  */          &TPM2_PolicyTicket,
+    /* inSize */          (UINT16)(sizeof(PolicyTicket_In)),
+    /* outSize */         0,
+    /* offsetOfTypes */   offsetof(PolicyTicket_COMMAND_DESCRIPTOR_t, types),
+    /* offsets */         {(UINT16)(offsetof(PolicyTicket_In, timeout)),
+			   (UINT16)(offsetof(PolicyTicket_In, cpHashA)),
+			   (UINT16)(offsetof(PolicyTicket_In, policyRef)),
+			   (UINT16)(offsetof(PolicyTicket_In, authName)),
+			   (UINT16)(offsetof(PolicyTicket_In, ticket))},
+    /* types */           {TPMI_SH_POLICY_H_UNMARSHAL,
+			   TPM2B_TIMEOUT_P_UNMARSHAL,
+			   TPM2B_DIGEST_P_UNMARSHAL,
+			   TPM2B_NONCE_P_UNMARSHAL,
+			   TPM2B_NAME_P_UNMARSHAL,
+			   TPMT_TK_AUTH_P_UNMARSHAL,
+			   END_OF_LIST,
+			   END_OF_LIST}
+};
+#define _PolicyTicketDataAddress (&_PolicyTicketData)
+#else
+#define _PolicyTicketDataAddress 0
+#endif
+#if CC_PolicyOR
+#include "PolicyOR_fp.h"
+typedef TPM_RC  (PolicyOR_Entry)(
+				 PolicyOR_In *in
+				 );
+typedef const struct {
+    PolicyOR_Entry    *entry;
+    UINT16            inSize;
+    UINT16            outSize;
+    UINT16            offsetOfTypes;
+    UINT16            paramOffsets[1];
+    BYTE              types[4];
+} PolicyOR_COMMAND_DESCRIPTOR_t;
+PolicyOR_COMMAND_DESCRIPTOR_t _PolicyORData = {
+    /* entry  */          &TPM2_PolicyOR,
+    /* inSize */          (UINT16)(sizeof(PolicyOR_In)),
+    /* outSize */         0,
+    /* offsetOfTypes */   offsetof(PolicyOR_COMMAND_DESCRIPTOR_t, types),
+    /* offsets */         {(UINT16)(offsetof(PolicyOR_In, pHashList))},
+    /* types */           {TPMI_SH_POLICY_H_UNMARSHAL,
+			   TPML_DIGEST_P_UNMARSHAL,
+			   END_OF_LIST,
+			   END_OF_LIST}
+};
+#define _PolicyORDataAddress (&_PolicyORData)
+#else
+#define _PolicyORDataAddress 0
+#endif
+#if CC_PolicyPCR
+#include "PolicyPCR_fp.h"
+typedef TPM_RC  (PolicyPCR_Entry)(
+				  PolicyPCR_In *in
+				  );
+typedef const struct {
+    PolicyPCR_Entry    *entry;
+    UINT16             inSize;
+    UINT16             outSize;
+    UINT16             offsetOfTypes;
+    UINT16             paramOffsets[2];
+    BYTE               types[5];
+} PolicyPCR_COMMAND_DESCRIPTOR_t;
+PolicyPCR_COMMAND_DESCRIPTOR_t _PolicyPCRData = {
+    /* entry  */          &TPM2_PolicyPCR,
+    /* inSize */          (UINT16)(sizeof(PolicyPCR_In)),
+    /* outSize */         0,
+    /* offsetOfTypes */   offsetof(PolicyPCR_COMMAND_DESCRIPTOR_t, types),
+    /* offsets */         {(UINT16)(offsetof(PolicyPCR_In, pcrDigest)),
+			   (UINT16)(offsetof(PolicyPCR_In, pcrs))},
+    /* types */           {TPMI_SH_POLICY_H_UNMARSHAL,
+			   TPM2B_DIGEST_P_UNMARSHAL,
+			   TPML_PCR_SELECTION_P_UNMARSHAL,
+			   END_OF_LIST,
+			   END_OF_LIST}
+};
+#define _PolicyPCRDataAddress (&_PolicyPCRData)
+#else
+#define _PolicyPCRDataAddress 0
+#endif
+#if CC_PolicyLocality
+#include "PolicyLocality_fp.h"
+typedef TPM_RC  (PolicyLocality_Entry)(
+				       PolicyLocality_In *in
+				       );
+typedef const struct {
+    PolicyLocality_Entry    *entry;
+    UINT16                  inSize;
+    UINT16                  outSize;
+    UINT16                  offsetOfTypes;
+    UINT16                  paramOffsets[1];
+    BYTE                    types[4];
+} PolicyLocality_COMMAND_DESCRIPTOR_t;
+PolicyLocality_COMMAND_DESCRIPTOR_t _PolicyLocalityData = {
+    /* entry  */          &TPM2_PolicyLocality,
+    /* inSize */          (UINT16)(sizeof(PolicyLocality_In)),
+    /* outSize */         0,
+    /* offsetOfTypes */   offsetof(PolicyLocality_COMMAND_DESCRIPTOR_t, types),
+    /* offsets */         {(UINT16)(offsetof(PolicyLocality_In, locality))},
+    /* types */           {TPMI_SH_POLICY_H_UNMARSHAL,
+			   TPMA_LOCALITY_P_UNMARSHAL,
+			   END_OF_LIST,
+			   END_OF_LIST}
+};
+#define _PolicyLocalityDataAddress (&_PolicyLocalityData)
+#else
+#define _PolicyLocalityDataAddress 0
+#endif
+#if CC_PolicyNV
+#include "PolicyNV_fp.h"
+typedef TPM_RC  (PolicyNV_Entry)(
+				 PolicyNV_In *in
+				 );
+typedef const struct {
+    PolicyNV_Entry    *entry;
+    UINT16            inSize;
+    UINT16            outSize;
+    UINT16            offsetOfTypes;
+    UINT16            paramOffsets[5];
+    BYTE              types[8];
+} PolicyNV_COMMAND_DESCRIPTOR_t;
+PolicyNV_COMMAND_DESCRIPTOR_t _PolicyNVData = {
+    /* entry  */          &TPM2_PolicyNV,
+    /* inSize */          (UINT16)(sizeof(PolicyNV_In)),
+    /* outSize */         0,
+    /* offsetOfTypes */   offsetof(PolicyNV_COMMAND_DESCRIPTOR_t, types),
+    /* offsets */         {(UINT16)(offsetof(PolicyNV_In, nvIndex)),
+			   (UINT16)(offsetof(PolicyNV_In, policySession)),
+			   (UINT16)(offsetof(PolicyNV_In, operandB)),
+			   (UINT16)(offsetof(PolicyNV_In, offset)),
+			   (UINT16)(offsetof(PolicyNV_In, operation))},
+    /* types */           {TPMI_RH_NV_AUTH_H_UNMARSHAL,
+			   TPMI_RH_NV_INDEX_H_UNMARSHAL,
+			   TPMI_SH_POLICY_H_UNMARSHAL,
+			   TPM2B_OPERAND_P_UNMARSHAL,
+			   UINT16_P_UNMARSHAL,
+			   TPM_EO_P_UNMARSHAL,
+			   END_OF_LIST,
+			   END_OF_LIST}
+};
+#define _PolicyNVDataAddress (&_PolicyNVData)
+#else
+#define _PolicyNVDataAddress 0
+#endif
+#if CC_PolicyCounterTimer
+#include "PolicyCounterTimer_fp.h"
+typedef TPM_RC  (PolicyCounterTimer_Entry)(
+					   PolicyCounterTimer_In *in
+					   );
+typedef const struct {
+    PolicyCounterTimer_Entry    *entry;
+    UINT16                      inSize;
+    UINT16                      outSize;
+    UINT16                      offsetOfTypes;
+    UINT16                      paramOffsets[3];
+    BYTE                        types[6];
+} PolicyCounterTimer_COMMAND_DESCRIPTOR_t;
+PolicyCounterTimer_COMMAND_DESCRIPTOR_t _PolicyCounterTimerData = {
+    /* entry  */          &TPM2_PolicyCounterTimer,
+    /* inSize */          (UINT16)(sizeof(PolicyCounterTimer_In)),
+    /* outSize */         0,
+    /* offsetOfTypes */   offsetof(PolicyCounterTimer_COMMAND_DESCRIPTOR_t, types),
+    /* offsets */         {(UINT16)(offsetof(PolicyCounterTimer_In, operandB)),
+			   (UINT16)(offsetof(PolicyCounterTimer_In, offset)),
+			   (UINT16)(offsetof(PolicyCounterTimer_In, operation))},
+    /* types */           {TPMI_SH_POLICY_H_UNMARSHAL,
+			   TPM2B_OPERAND_P_UNMARSHAL,
+			   UINT16_P_UNMARSHAL,
+			   TPM_EO_P_UNMARSHAL,
+			   END_OF_LIST,
+			   END_OF_LIST}
+};
+#define _PolicyCounterTimerDataAddress (&_PolicyCounterTimerData)
+#else
+#define _PolicyCounterTimerDataAddress 0
+#endif
+#if CC_PolicyCommandCode
+#include "PolicyCommandCode_fp.h"
+typedef TPM_RC  (PolicyCommandCode_Entry)(
+					  PolicyCommandCode_In *in
+					  );
+typedef const struct {
+    PolicyCommandCode_Entry    *entry;
+    UINT16                     inSize;
+    UINT16                     outSize;
+    UINT16                     offsetOfTypes;
+    UINT16                     paramOffsets[1];
+    BYTE                       types[4];
+} PolicyCommandCode_COMMAND_DESCRIPTOR_t;
+PolicyCommandCode_COMMAND_DESCRIPTOR_t _PolicyCommandCodeData = {
+    /* entry  */          &TPM2_PolicyCommandCode,
+    /* inSize */          (UINT16)(sizeof(PolicyCommandCode_In)),
+    /* outSize */         0,
+    /* offsetOfTypes */   offsetof(PolicyCommandCode_COMMAND_DESCRIPTOR_t, types),
+    /* offsets */         {(UINT16)(offsetof(PolicyCommandCode_In, code))},
+    /* types */           {TPMI_SH_POLICY_H_UNMARSHAL,
+			   TPM_CC_P_UNMARSHAL,
+			   END_OF_LIST,
+			   END_OF_LIST}
+};
+#define _PolicyCommandCodeDataAddress (&_PolicyCommandCodeData)
+#else
+#define _PolicyCommandCodeDataAddress 0
+#endif
+#if CC_PolicyPhysicalPresence
+#include "PolicyPhysicalPresence_fp.h"
+typedef TPM_RC  (PolicyPhysicalPresence_Entry)(
+					       PolicyPhysicalPresence_In *in
+					       );
+typedef const struct {
+    PolicyPhysicalPresence_Entry    *entry;
+    UINT16                          inSize;
+    UINT16                          outSize;
+    UINT16                          offsetOfTypes;
+    BYTE                            types[3];
+} PolicyPhysicalPresence_COMMAND_DESCRIPTOR_t;
+PolicyPhysicalPresence_COMMAND_DESCRIPTOR_t _PolicyPhysicalPresenceData = {
+    /* entry  */          &TPM2_PolicyPhysicalPresence,
+    /* inSize */          (UINT16)(sizeof(PolicyPhysicalPresence_In)),
+    /* outSize */         0,
+    /* offsetOfTypes */   offsetof(PolicyPhysicalPresence_COMMAND_DESCRIPTOR_t, types),
+    /* offsets */         // No parameter offsets
+    /* types */           {TPMI_SH_POLICY_H_UNMARSHAL,
+			   END_OF_LIST,
+			   END_OF_LIST}
+};
+#define _PolicyPhysicalPresenceDataAddress (&_PolicyPhysicalPresenceData)
+#else
+#define _PolicyPhysicalPresenceDataAddress 0
+#endif
+#if CC_PolicyCpHash
+#include "PolicyCpHash_fp.h"
+typedef TPM_RC  (PolicyCpHash_Entry)(
+				     PolicyCpHash_In *in
+				     );
+typedef const struct {
+    PolicyCpHash_Entry    *entry;
+    UINT16                inSize;
+    UINT16                outSize;
+    UINT16                offsetOfTypes;
+    UINT16                paramOffsets[1];
+    BYTE                  types[4];
+} PolicyCpHash_COMMAND_DESCRIPTOR_t;
+PolicyCpHash_COMMAND_DESCRIPTOR_t _PolicyCpHashData = {
+    /* entry  */          &TPM2_PolicyCpHash,
+    /* inSize */          (UINT16)(sizeof(PolicyCpHash_In)),
+    /* outSize */         0,
+    /* offsetOfTypes */   offsetof(PolicyCpHash_COMMAND_DESCRIPTOR_t, types),
+    /* offsets */         {(UINT16)(offsetof(PolicyCpHash_In, cpHashA))},
+    /* types */           {TPMI_SH_POLICY_H_UNMARSHAL,
+			   TPM2B_DIGEST_P_UNMARSHAL,
+			   END_OF_LIST,
+			   END_OF_LIST}
+};
+#define _PolicyCpHashDataAddress (&_PolicyCpHashData)
+#else
+#define _PolicyCpHashDataAddress 0
+#endif
+#if CC_PolicyNameHash
+#include "PolicyNameHash_fp.h"
+typedef TPM_RC  (PolicyNameHash_Entry)(
+				       PolicyNameHash_In *in
+				       );
+typedef const struct {
+    PolicyNameHash_Entry    *entry;
+    UINT16                  inSize;
+    UINT16                  outSize;
+    UINT16                  offsetOfTypes;
+    UINT16                  paramOffsets[1];
+    BYTE                    types[4];
+} PolicyNameHash_COMMAND_DESCRIPTOR_t;
+PolicyNameHash_COMMAND_DESCRIPTOR_t _PolicyNameHashData = {
+    /* entry  */          &TPM2_PolicyNameHash,
+    /* inSize */          (UINT16)(sizeof(PolicyNameHash_In)),
+    /* outSize */         0,
+    /* offsetOfTypes */   offsetof(PolicyNameHash_COMMAND_DESCRIPTOR_t, types),
+    /* offsets */         {(UINT16)(offsetof(PolicyNameHash_In, nameHash))},
+    /* types */           {TPMI_SH_POLICY_H_UNMARSHAL,
+			   TPM2B_DIGEST_P_UNMARSHAL,
+			   END_OF_LIST,
+			   END_OF_LIST}
+};
+#define _PolicyNameHashDataAddress (&_PolicyNameHashData)
+#else
+#define _PolicyNameHashDataAddress 0
+#endif
+#if CC_PolicyDuplicationSelect
+#include "PolicyDuplicationSelect_fp.h"
+typedef TPM_RC  (PolicyDuplicationSelect_Entry)(
+						PolicyDuplicationSelect_In *in
+						);
+typedef const struct {
+    PolicyDuplicationSelect_Entry    *entry;
+    UINT16                           inSize;
+    UINT16                           outSize;
+    UINT16                           offsetOfTypes;
+    UINT16                           paramOffsets[3];
+    BYTE                             types[6];
+} PolicyDuplicationSelect_COMMAND_DESCRIPTOR_t;
+PolicyDuplicationSelect_COMMAND_DESCRIPTOR_t _PolicyDuplicationSelectData = {
+    /* entry  */          &TPM2_PolicyDuplicationSelect,
+    /* inSize */          (UINT16)(sizeof(PolicyDuplicationSelect_In)),
+    /* outSize */         0,
+    /* offsetOfTypes */   offsetof(PolicyDuplicationSelect_COMMAND_DESCRIPTOR_t, types),
+    /* offsets */         {(UINT16)(offsetof(PolicyDuplicationSelect_In, objectName)),
+			   (UINT16)(offsetof(PolicyDuplicationSelect_In, newParentName)),
+			   (UINT16)(offsetof(PolicyDuplicationSelect_In, includeObject))},
+    /* types */           {TPMI_SH_POLICY_H_UNMARSHAL,
+			   TPM2B_NAME_P_UNMARSHAL,
+			   TPM2B_NAME_P_UNMARSHAL,
+			   TPMI_YES_NO_P_UNMARSHAL,
+			   END_OF_LIST,
+			   END_OF_LIST}
+};
+#define _PolicyDuplicationSelectDataAddress (&_PolicyDuplicationSelectData)
+#else
+#define _PolicyDuplicationSelectDataAddress 0
+#endif
+#if CC_PolicyAuthorize
+#include "PolicyAuthorize_fp.h"
+typedef TPM_RC  (PolicyAuthorize_Entry)(
+					PolicyAuthorize_In *in
+					);
+typedef const struct {
+    PolicyAuthorize_Entry    *entry;
+    UINT16                   inSize;
+    UINT16                   outSize;
+    UINT16                   offsetOfTypes;
+    UINT16                   paramOffsets[4];
+    BYTE                     types[7];
+} PolicyAuthorize_COMMAND_DESCRIPTOR_t;
+PolicyAuthorize_COMMAND_DESCRIPTOR_t _PolicyAuthorizeData = {
+    /* entry  */          &TPM2_PolicyAuthorize,
+    /* inSize */          (UINT16)(sizeof(PolicyAuthorize_In)),
+    /* outSize */         0,
+    /* offsetOfTypes */   offsetof(PolicyAuthorize_COMMAND_DESCRIPTOR_t, types),
+    /* offsets */         {(UINT16)(offsetof(PolicyAuthorize_In, approvedPolicy)),
+			   (UINT16)(offsetof(PolicyAuthorize_In, policyRef)),
+			   (UINT16)(offsetof(PolicyAuthorize_In, keySign)),
+			   (UINT16)(offsetof(PolicyAuthorize_In, checkTicket))},
+    /* types */           {TPMI_SH_POLICY_H_UNMARSHAL,
+			   TPM2B_DIGEST_P_UNMARSHAL,
+			   TPM2B_NONCE_P_UNMARSHAL,
+			   TPM2B_NAME_P_UNMARSHAL,
+			   TPMT_TK_VERIFIED_P_UNMARSHAL,
+			   END_OF_LIST,
+			   END_OF_LIST}
+};
+#define _PolicyAuthorizeDataAddress (&_PolicyAuthorizeData)
+#else
+#define _PolicyAuthorizeDataAddress 0
+#endif
+#if CC_PolicyAuthValue
+#include "PolicyAuthValue_fp.h"
+typedef TPM_RC  (PolicyAuthValue_Entry)(
+					PolicyAuthValue_In *in
+					);
+typedef const struct {
+    PolicyAuthValue_Entry    *entry;
+    UINT16                   inSize;
+    UINT16                   outSize;
+    UINT16                   offsetOfTypes;
+    BYTE                     types[3];
+} PolicyAuthValue_COMMAND_DESCRIPTOR_t;
+PolicyAuthValue_COMMAND_DESCRIPTOR_t _PolicyAuthValueData = {
+    /* entry  */          &TPM2_PolicyAuthValue,
+    /* inSize */          (UINT16)(sizeof(PolicyAuthValue_In)),
+    /* outSize */         0,
+    /* offsetOfTypes */   offsetof(PolicyAuthValue_COMMAND_DESCRIPTOR_t, types),
+    /* offsets */         // No parameter offsets
+    /* types */           {TPMI_SH_POLICY_H_UNMARSHAL,
+			   END_OF_LIST,
+			   END_OF_LIST}
+};
+#define _PolicyAuthValueDataAddress (&_PolicyAuthValueData)
+#else
+#define _PolicyAuthValueDataAddress 0
+#endif
+#if CC_PolicyPassword
+#include "PolicyPassword_fp.h"
+typedef TPM_RC  (PolicyPassword_Entry)(
+				       PolicyPassword_In *in
+				       );
+typedef const struct {
+    PolicyPassword_Entry    *entry;
+    UINT16                  inSize;
+    UINT16                  outSize;
+    UINT16                  offsetOfTypes;
+    BYTE                    types[3];
+} PolicyPassword_COMMAND_DESCRIPTOR_t;
+PolicyPassword_COMMAND_DESCRIPTOR_t _PolicyPasswordData = {
+    /* entry  */          &TPM2_PolicyPassword,
+    /* inSize */          (UINT16)(sizeof(PolicyPassword_In)),
+    /* outSize */         0,
+    /* offsetOfTypes */   offsetof(PolicyPassword_COMMAND_DESCRIPTOR_t, types),
+    /* offsets */         // No parameter offsets
+    /* types */           {TPMI_SH_POLICY_H_UNMARSHAL,
+			   END_OF_LIST,
+			   END_OF_LIST}
+};
+#define _PolicyPasswordDataAddress (&_PolicyPasswordData)
+#else
+#define _PolicyPasswordDataAddress 0
+#endif
+#if CC_PolicyGetDigest
+#include "PolicyGetDigest_fp.h"
+typedef TPM_RC  (PolicyGetDigest_Entry)(
+					PolicyGetDigest_In *in,
+					PolicyGetDigest_Out *out
+					);
+typedef const struct {
+    PolicyGetDigest_Entry    *entry;
+    UINT16                   inSize;
+    UINT16                   outSize;
+    UINT16                   offsetOfTypes;
+    BYTE                     types[4];
+} PolicyGetDigest_COMMAND_DESCRIPTOR_t;
+PolicyGetDigest_COMMAND_DESCRIPTOR_t _PolicyGetDigestData = {
+    /* entry  */          &TPM2_PolicyGetDigest,
+    /* inSize */          (UINT16)(sizeof(PolicyGetDigest_In)),
+    /* outSize */         (UINT16)(sizeof(PolicyGetDigest_Out)),
+    /* offsetOfTypes */   offsetof(PolicyGetDigest_COMMAND_DESCRIPTOR_t, types),
+    /* offsets */         // No parameter offsets
+    /* types */           {TPMI_SH_POLICY_H_UNMARSHAL,
+			   END_OF_LIST,
+			   TPM2B_DIGEST_P_MARSHAL,
+			   END_OF_LIST}
+};
+#define _PolicyGetDigestDataAddress (&_PolicyGetDigestData)
+#else
+#define _PolicyGetDigestDataAddress 0
+#endif
+#if CC_PolicyNvWritten
+#include "PolicyNvWritten_fp.h"
+typedef TPM_RC  (PolicyNvWritten_Entry)(
+					PolicyNvWritten_In *in
+					);
+typedef const struct {
+    PolicyNvWritten_Entry    *entry;
+    UINT16                   inSize;
+    UINT16                   outSize;
+    UINT16                   offsetOfTypes;
+    UINT16                   paramOffsets[1];
+    BYTE                     types[4];
+} PolicyNvWritten_COMMAND_DESCRIPTOR_t;
+PolicyNvWritten_COMMAND_DESCRIPTOR_t _PolicyNvWrittenData = {
+    /* entry  */          &TPM2_PolicyNvWritten,
+    /* inSize */          (UINT16)(sizeof(PolicyNvWritten_In)),
+    /* outSize */         0,
+    /* offsetOfTypes */   offsetof(PolicyNvWritten_COMMAND_DESCRIPTOR_t, types),
+    /* offsets */         {(UINT16)(offsetof(PolicyNvWritten_In, writtenSet))},
+    /* types */           {TPMI_SH_POLICY_H_UNMARSHAL,
+			   TPMI_YES_NO_P_UNMARSHAL,
+			   END_OF_LIST,
+			   END_OF_LIST}
+};
+#define _PolicyNvWrittenDataAddress (&_PolicyNvWrittenData)
+#else
+#define _PolicyNvWrittenDataAddress 0
+#endif
+#if CC_PolicyTemplate
+#include "PolicyTemplate_fp.h"
+typedef TPM_RC  (PolicyTemplate_Entry)(
+				       PolicyTemplate_In *in
+				       );
+typedef const struct {
+    PolicyTemplate_Entry    *entry;
+    UINT16                  inSize;
+    UINT16                  outSize;
+    UINT16                  offsetOfTypes;
+    UINT16                  paramOffsets[1];
+    BYTE                    types[4];
+} PolicyTemplate_COMMAND_DESCRIPTOR_t;
+PolicyTemplate_COMMAND_DESCRIPTOR_t _PolicyTemplateData = {
+    /* entry  */          &TPM2_PolicyTemplate,
+    /* inSize */          (UINT16)(sizeof(PolicyTemplate_In)),
+    /* outSize */         0,
+    /* offsetOfTypes */   offsetof(PolicyTemplate_COMMAND_DESCRIPTOR_t, types),
+    /* offsets */         {(UINT16)(offsetof(PolicyTemplate_In, templateHash))},
+    /* types */           {TPMI_SH_POLICY_H_UNMARSHAL,
+			   TPM2B_DIGEST_P_UNMARSHAL,
+			   END_OF_LIST,
+			   END_OF_LIST}
+};
+#define _PolicyTemplateDataAddress (&_PolicyTemplateData)
+#else
+#define _PolicyTemplateDataAddress 0
+#endif
+#if CC_PolicyAuthorizeNV
+#include "PolicyAuthorizeNV_fp.h"
+typedef TPM_RC  (PolicyAuthorizeNV_Entry)(
+					  PolicyAuthorizeNV_In *in
+					  );
+typedef const struct {
+    PolicyAuthorizeNV_Entry    *entry;
+    UINT16                     inSize;
+    UINT16                     outSize;
+    UINT16                     offsetOfTypes;
+    UINT16                     paramOffsets[2];
+    BYTE                       types[5];
+} PolicyAuthorizeNV_COMMAND_DESCRIPTOR_t;
+PolicyAuthorizeNV_COMMAND_DESCRIPTOR_t _PolicyAuthorizeNVData = {
+    /* entry  */          &TPM2_PolicyAuthorizeNV,
+    /* inSize */          (UINT16)(sizeof(PolicyAuthorizeNV_In)),
+    /* outSize */         0,
+    /* offsetOfTypes */   offsetof(PolicyAuthorizeNV_COMMAND_DESCRIPTOR_t, types),
+    /* offsets */         {(UINT16)(offsetof(PolicyAuthorizeNV_In, nvIndex)),
+			   (UINT16)(offsetof(PolicyAuthorizeNV_In, policySession))},
+    /* types */           {TPMI_RH_NV_AUTH_H_UNMARSHAL,
+			   TPMI_RH_NV_INDEX_H_UNMARSHAL,
+			   TPMI_SH_POLICY_H_UNMARSHAL,
+			   END_OF_LIST,
+			   END_OF_LIST}
+};
+#define _PolicyAuthorizeNVDataAddress (&_PolicyAuthorizeNVData)
+#else
+#define _PolicyAuthorizeNVDataAddress 0
+#endif
+#if CC_CreatePrimary
+#include "CreatePrimary_fp.h"
+typedef TPM_RC  (CreatePrimary_Entry)(
+				      CreatePrimary_In *in,
+				      CreatePrimary_Out *out
+				      );
+typedef const struct {
+    CreatePrimary_Entry    *entry;
+    UINT16                 inSize;
+    UINT16                 outSize;
+    UINT16                 offsetOfTypes;
+    UINT16                 paramOffsets[9];
+    BYTE                   types[13];
+} CreatePrimary_COMMAND_DESCRIPTOR_t;
+CreatePrimary_COMMAND_DESCRIPTOR_t _CreatePrimaryData = {
+    /* entry  */          &TPM2_CreatePrimary,
+    /* inSize */          (UINT16)(sizeof(CreatePrimary_In)),
+    /* outSize */         (UINT16)(sizeof(CreatePrimary_Out)),
+    /* offsetOfTypes */   offsetof(CreatePrimary_COMMAND_DESCRIPTOR_t, types),
+    /* offsets */         {(UINT16)(offsetof(CreatePrimary_In, inSensitive)),
+			   (UINT16)(offsetof(CreatePrimary_In, inPublic)),
+			   (UINT16)(offsetof(CreatePrimary_In, outsideInfo)),
+			   (UINT16)(offsetof(CreatePrimary_In, creationPCR)),
+			   (UINT16)(offsetof(CreatePrimary_Out, outPublic)),
+			   (UINT16)(offsetof(CreatePrimary_Out, creationData)),
+			   (UINT16)(offsetof(CreatePrimary_Out, creationHash)),
+			   (UINT16)(offsetof(CreatePrimary_Out, creationTicket)),
+			   (UINT16)(offsetof(CreatePrimary_Out, name))},
+    /* types */           {TPMI_RH_HIERARCHY_H_UNMARSHAL + ADD_FLAG,
+			   TPM2B_SENSITIVE_CREATE_P_UNMARSHAL,
+			   TPM2B_PUBLIC_P_UNMARSHAL,
+			   TPM2B_DATA_P_UNMARSHAL,
+			   TPML_PCR_SELECTION_P_UNMARSHAL,
+			   END_OF_LIST,
+			   TPM_HANDLE_H_MARSHAL,
+			   TPM2B_PUBLIC_P_MARSHAL,
+			   TPM2B_CREATION_DATA_P_MARSHAL,
+			   TPM2B_DIGEST_P_MARSHAL,
+			   TPMT_TK_CREATION_P_MARSHAL,
+			   TPM2B_NAME_P_MARSHAL,
+			   END_OF_LIST}
+};
+#define _CreatePrimaryDataAddress (&_CreatePrimaryData)
+#else
+#define _CreatePrimaryDataAddress 0
+#endif
+#if CC_HierarchyControl
+#include "HierarchyControl_fp.h"
+typedef TPM_RC  (HierarchyControl_Entry)(
+					 HierarchyControl_In *in
+					 );
+typedef const struct {
+    HierarchyControl_Entry    *entry;
+    UINT16                    inSize;
+    UINT16                    outSize;
+    UINT16                    offsetOfTypes;
+    UINT16                    paramOffsets[2];
+    BYTE                      types[5];
+} HierarchyControl_COMMAND_DESCRIPTOR_t;
+HierarchyControl_COMMAND_DESCRIPTOR_t _HierarchyControlData = {
+    /* entry  */          &TPM2_HierarchyControl,
+    /* inSize */          (UINT16)(sizeof(HierarchyControl_In)),
+    /* outSize */         0,
+    /* offsetOfTypes */   offsetof(HierarchyControl_COMMAND_DESCRIPTOR_t, types),
+    /* offsets */         {(UINT16)(offsetof(HierarchyControl_In, enable)),
+			   (UINT16)(offsetof(HierarchyControl_In, state))},
+    /* types */           {TPMI_RH_HIERARCHY_H_UNMARSHAL,
+			   TPMI_RH_ENABLES_P_UNMARSHAL,
+			   TPMI_YES_NO_P_UNMARSHAL,
+			   END_OF_LIST,
+			   END_OF_LIST}
+};
+#define _HierarchyControlDataAddress (&_HierarchyControlData)
+#else
+#define _HierarchyControlDataAddress 0
+#endif
+#if CC_SetPrimaryPolicy
+#include "SetPrimaryPolicy_fp.h"
+typedef TPM_RC  (SetPrimaryPolicy_Entry)(
+					 SetPrimaryPolicy_In *in
+					 );
+typedef const struct {
+    SetPrimaryPolicy_Entry    *entry;
+    UINT16                    inSize;
+    UINT16                    outSize;
+    UINT16                    offsetOfTypes;
+    UINT16                    paramOffsets[2];
+    BYTE                      types[5];
+} SetPrimaryPolicy_COMMAND_DESCRIPTOR_t;
+SetPrimaryPolicy_COMMAND_DESCRIPTOR_t _SetPrimaryPolicyData = {
+    /* entry  */          &TPM2_SetPrimaryPolicy,
+    /* inSize */          (UINT16)(sizeof(SetPrimaryPolicy_In)),
+    /* outSize */         0,
+    /* offsetOfTypes */   offsetof(SetPrimaryPolicy_COMMAND_DESCRIPTOR_t, types),
+    /* offsets */         {(UINT16)(offsetof(SetPrimaryPolicy_In, authPolicy)),
+			   (UINT16)(offsetof(SetPrimaryPolicy_In, hashAlg))},
+    /* types */           {TPMI_RH_HIERARCHY_POLICY_H_UNMARSHAL,
+			   TPM2B_DIGEST_P_UNMARSHAL,
+			   TPMI_ALG_HASH_P_UNMARSHAL + ADD_FLAG,
+			   END_OF_LIST,
+			   END_OF_LIST}
+};
+#define _SetPrimaryPolicyDataAddress (&_SetPrimaryPolicyData)
+#else
+#define _SetPrimaryPolicyDataAddress 0
+#endif
+#if CC_ChangePPS
+#include "ChangePPS_fp.h"
+typedef TPM_RC  (ChangePPS_Entry)(
+				  ChangePPS_In *in
+				  );
+typedef const struct {
+    ChangePPS_Entry    *entry;
+    UINT16             inSize;
+    UINT16             outSize;
+    UINT16             offsetOfTypes;
+    BYTE               types[3];
+} ChangePPS_COMMAND_DESCRIPTOR_t;
+ChangePPS_COMMAND_DESCRIPTOR_t _ChangePPSData = {
+    /* entry  */          &TPM2_ChangePPS,
+    /* inSize */          (UINT16)(sizeof(ChangePPS_In)),
+    /* outSize */         0,
+    /* offsetOfTypes */   offsetof(ChangePPS_COMMAND_DESCRIPTOR_t, types),
+    /* offsets */         // No parameter offsets
+    /* types */           {TPMI_RH_PLATFORM_H_UNMARSHAL,
+			   END_OF_LIST,
+			   END_OF_LIST}
+};
+#define _ChangePPSDataAddress (&_ChangePPSData)
+#else
+#define _ChangePPSDataAddress 0
+#endif
+#if CC_ChangeEPS
+#include "ChangeEPS_fp.h"
+typedef TPM_RC  (ChangeEPS_Entry)(
+				  ChangeEPS_In *in
+				  );
+typedef const struct {
+    ChangeEPS_Entry    *entry;
+    UINT16             inSize;
+    UINT16             outSize;
+    UINT16             offsetOfTypes;
+    BYTE               types[3];
+} ChangeEPS_COMMAND_DESCRIPTOR_t;
+ChangeEPS_COMMAND_DESCRIPTOR_t _ChangeEPSData = {
+    /* entry  */          &TPM2_ChangeEPS,
+    /* inSize */          (UINT16)(sizeof(ChangeEPS_In)),
+    /* outSize */         0,
+    /* offsetOfTypes */   offsetof(ChangeEPS_COMMAND_DESCRIPTOR_t, types),
+    /* offsets */         // No parameter offsets
+    /* types */           {TPMI_RH_PLATFORM_H_UNMARSHAL,
+			   END_OF_LIST,
+			   END_OF_LIST}
+};
+#define _ChangeEPSDataAddress (&_ChangeEPSData)
+#else
+#define _ChangeEPSDataAddress 0
+#endif
+#if CC_Clear
+#include "Clear_fp.h"
+typedef TPM_RC  (Clear_Entry)(
+			      Clear_In *in
+			      );
+typedef const struct {
+    Clear_Entry    *entry;
+    UINT16         inSize;
+    UINT16         outSize;
+    UINT16         offsetOfTypes;
+    BYTE           types[3];
+} Clear_COMMAND_DESCRIPTOR_t;
+Clear_COMMAND_DESCRIPTOR_t _ClearData = {
+    /* entry  */          &TPM2_Clear,
+    /* inSize */          (UINT16)(sizeof(Clear_In)),
+    /* outSize */         0,
+    /* offsetOfTypes */   offsetof(Clear_COMMAND_DESCRIPTOR_t, types),
+    /* offsets */         // No parameter offsets
+    /* types */           {TPMI_RH_CLEAR_H_UNMARSHAL,
+			   END_OF_LIST,
+			   END_OF_LIST}
+};
+#define _ClearDataAddress (&_ClearData)
+#else
+#define _ClearDataAddress 0
+#endif
+#if CC_ClearControl
+#include "ClearControl_fp.h"
+typedef TPM_RC  (ClearControl_Entry)(
+				     ClearControl_In *in
+				     );
+typedef const struct {
+    ClearControl_Entry    *entry;
+    UINT16                inSize;
+    UINT16                outSize;
+    UINT16                offsetOfTypes;
+    UINT16                paramOffsets[1];
+    BYTE                  types[4];
+} ClearControl_COMMAND_DESCRIPTOR_t;
+ClearControl_COMMAND_DESCRIPTOR_t _ClearControlData = {
+    /* entry  */          &TPM2_ClearControl,
+    /* inSize */          (UINT16)(sizeof(ClearControl_In)),
+    /* outSize */         0,
+    /* offsetOfTypes */   offsetof(ClearControl_COMMAND_DESCRIPTOR_t, types),
+    /* offsets */         {(UINT16)(offsetof(ClearControl_In, disable))},
+    /* types */           {TPMI_RH_CLEAR_H_UNMARSHAL,
+			   TPMI_YES_NO_P_UNMARSHAL,
+			   END_OF_LIST,
+			   END_OF_LIST}
+};
+#define _ClearControlDataAddress (&_ClearControlData)
+#else
+#define _ClearControlDataAddress 0
+#endif
+#if CC_HierarchyChangeAuth
+#include "HierarchyChangeAuth_fp.h"
+typedef TPM_RC  (HierarchyChangeAuth_Entry)(
+					    HierarchyChangeAuth_In *in
+					    );
+typedef const struct {
+    HierarchyChangeAuth_Entry    *entry;
+    UINT16                       inSize;
+    UINT16                       outSize;
+    UINT16                       offsetOfTypes;
+    UINT16                       paramOffsets[1];
+    BYTE                         types[4];
+} HierarchyChangeAuth_COMMAND_DESCRIPTOR_t;
+HierarchyChangeAuth_COMMAND_DESCRIPTOR_t _HierarchyChangeAuthData = {
+    /* entry  */          &TPM2_HierarchyChangeAuth,
+    /* inSize */          (UINT16)(sizeof(HierarchyChangeAuth_In)),
+    /* outSize */         0,
+    /* offsetOfTypes */   offsetof(HierarchyChangeAuth_COMMAND_DESCRIPTOR_t, types),
+    /* offsets */         {(UINT16)(offsetof(HierarchyChangeAuth_In, newAuth))},
+    /* types */           {TPMI_RH_HIERARCHY_AUTH_H_UNMARSHAL,
+			   TPM2B_AUTH_P_UNMARSHAL,
+			   END_OF_LIST,
+			   END_OF_LIST}
+};
+#define _HierarchyChangeAuthDataAddress (&_HierarchyChangeAuthData)
+#else
+#define _HierarchyChangeAuthDataAddress 0
+#endif
+#if CC_DictionaryAttackLockReset
+#include "DictionaryAttackLockReset_fp.h"
+typedef TPM_RC  (DictionaryAttackLockReset_Entry)(
+						  DictionaryAttackLockReset_In *in
+						  );
+typedef const struct {
+    DictionaryAttackLockReset_Entry    *entry;
+    UINT16                             inSize;
+    UINT16                             outSize;
+    UINT16                             offsetOfTypes;
+    BYTE                               types[3];
+} DictionaryAttackLockReset_COMMAND_DESCRIPTOR_t;
+DictionaryAttackLockReset_COMMAND_DESCRIPTOR_t _DictionaryAttackLockResetData = {
+    /* entry  */          &TPM2_DictionaryAttackLockReset,
+    /* inSize */          (UINT16)(sizeof(DictionaryAttackLockReset_In)),
+    /* outSize */         0,
+    /* offsetOfTypes */   offsetof(DictionaryAttackLockReset_COMMAND_DESCRIPTOR_t, types),
+    /* offsets */         // No parameter offsets
+    /* types */           {TPMI_RH_LOCKOUT_H_UNMARSHAL,
+			   END_OF_LIST,
+			   END_OF_LIST}
+};
+#define _DictionaryAttackLockResetDataAddress (&_DictionaryAttackLockResetData)
+#else
+#define _DictionaryAttackLockResetDataAddress 0
+#endif
+#if CC_DictionaryAttackParameters
+#include "DictionaryAttackParameters_fp.h"
+typedef TPM_RC  (DictionaryAttackParameters_Entry)(
+						   DictionaryAttackParameters_In *in
+						   );
+typedef const struct {
+    DictionaryAttackParameters_Entry    *entry;
+    UINT16                              inSize;
+    UINT16                              outSize;
+    UINT16                              offsetOfTypes;
+    UINT16                              paramOffsets[3];
+    BYTE                                types[6];
+} DictionaryAttackParameters_COMMAND_DESCRIPTOR_t;
+DictionaryAttackParameters_COMMAND_DESCRIPTOR_t _DictionaryAttackParametersData = {
+    /* entry  */          &TPM2_DictionaryAttackParameters,
+    /* inSize */          (UINT16)(sizeof(DictionaryAttackParameters_In)),
+    /* outSize */         0,
+    /* offsetOfTypes */   offsetof(DictionaryAttackParameters_COMMAND_DESCRIPTOR_t, types),
+    /* offsets */         {(UINT16)(offsetof(DictionaryAttackParameters_In, newMaxTries)),
+			   (UINT16)(offsetof(DictionaryAttackParameters_In, newRecoveryTime)),
+			   (UINT16)(offsetof(DictionaryAttackParameters_In, lockoutRecovery))},
+    /* types */           {TPMI_RH_LOCKOUT_H_UNMARSHAL,
+			   UINT32_P_UNMARSHAL,
+			   UINT32_P_UNMARSHAL,
+			   UINT32_P_UNMARSHAL,
+			   END_OF_LIST,
+			   END_OF_LIST}
+};
+#define _DictionaryAttackParametersDataAddress (&_DictionaryAttackParametersData)
+#else
+#define _DictionaryAttackParametersDataAddress 0
+#endif
+#if CC_PP_Commands
+#include "PP_Commands_fp.h"
+typedef TPM_RC  (PP_Commands_Entry)(
+				    PP_Commands_In *in
+				    );
+typedef const struct {
+    PP_Commands_Entry    *entry;
+    UINT16               inSize;
+    UINT16               outSize;
+    UINT16               offsetOfTypes;
+    UINT16               paramOffsets[2];
+    BYTE                 types[5];
+} PP_Commands_COMMAND_DESCRIPTOR_t;
+PP_Commands_COMMAND_DESCRIPTOR_t _PP_CommandsData = {
+    /* entry  */          &TPM2_PP_Commands,
+    /* inSize */          (UINT16)(sizeof(PP_Commands_In)),
+    /* outSize */         0,
+    /* offsetOfTypes */   offsetof(PP_Commands_COMMAND_DESCRIPTOR_t, types),
+    /* offsets */         {(UINT16)(offsetof(PP_Commands_In, setList)),
+			   (UINT16)(offsetof(PP_Commands_In, clearList))},
+    /* types */           {TPMI_RH_PLATFORM_H_UNMARSHAL,
+			   TPML_CC_P_UNMARSHAL,
+			   TPML_CC_P_UNMARSHAL,
+			   END_OF_LIST,
+			   END_OF_LIST}
+};
+#define _PP_CommandsDataAddress (&_PP_CommandsData)
+#else
+#define _PP_CommandsDataAddress 0
+#endif
+#if CC_SetAlgorithmSet
+#include "SetAlgorithmSet_fp.h"
+typedef TPM_RC  (SetAlgorithmSet_Entry)(
+					SetAlgorithmSet_In *in
+					);
+typedef const struct {
+    SetAlgorithmSet_Entry    *entry;
+    UINT16                   inSize;
+    UINT16                   outSize;
+    UINT16                   offsetOfTypes;
+    UINT16                   paramOffsets[1];
+    BYTE                     types[4];
+} SetAlgorithmSet_COMMAND_DESCRIPTOR_t;
+SetAlgorithmSet_COMMAND_DESCRIPTOR_t _SetAlgorithmSetData = {
+    /* entry  */          &TPM2_SetAlgorithmSet,
+    /* inSize */          (UINT16)(sizeof(SetAlgorithmSet_In)),
+    /* outSize */         0,
+    /* offsetOfTypes */   offsetof(SetAlgorithmSet_COMMAND_DESCRIPTOR_t, types),
+    /* offsets */         {(UINT16)(offsetof(SetAlgorithmSet_In, algorithmSet))},
+    /* types */           {TPMI_RH_PLATFORM_H_UNMARSHAL,
+			   UINT32_P_UNMARSHAL,
+			   END_OF_LIST,
+			   END_OF_LIST}
+};
+#define _SetAlgorithmSetDataAddress (&_SetAlgorithmSetData)
+#else
+#define _SetAlgorithmSetDataAddress 0
+#endif
+#if CC_FieldUpgradeStart
+#include "FieldUpgradeStart_fp.h"
+typedef TPM_RC  (FieldUpgradeStart_Entry)(
+					  FieldUpgradeStart_In *in
+					  );
+typedef const struct {
+    FieldUpgradeStart_Entry    *entry;
+    UINT16                     inSize;
+    UINT16                     outSize;
+    UINT16                     offsetOfTypes;
+    UINT16                     paramOffsets[3];
+    BYTE                       types[6];
+} FieldUpgradeStart_COMMAND_DESCRIPTOR_t;
+FieldUpgradeStart_COMMAND_DESCRIPTOR_t _FieldUpgradeStartData = {
+    /* entry  */          &TPM2_FieldUpgradeStart,
+    /* inSize */          (UINT16)(sizeof(FieldUpgradeStart_In)),
+    /* outSize */         0,
+    /* offsetOfTypes */   offsetof(FieldUpgradeStart_COMMAND_DESCRIPTOR_t, types),
+    /* offsets */         {(UINT16)(offsetof(FieldUpgradeStart_In, keyHandle)),
+			   (UINT16)(offsetof(FieldUpgradeStart_In, fuDigest)),
+			   (UINT16)(offsetof(FieldUpgradeStart_In, manifestSignature))},
+    /* types */           {TPMI_RH_PLATFORM_H_UNMARSHAL,
+			   TPMI_DH_OBJECT_H_UNMARSHAL,
+			   TPM2B_DIGEST_P_UNMARSHAL,
+			   TPMT_SIGNATURE_P_UNMARSHAL,
+			   END_OF_LIST,
+			   END_OF_LIST}
+};
+#define _FieldUpgradeStartDataAddress (&_FieldUpgradeStartData)
+#else
+#define _FieldUpgradeStartDataAddress 0
+#endif
+#if CC_FieldUpgradeData
+#include "FieldUpgradeData_fp.h"
+typedef TPM_RC  (FieldUpgradeData_Entry)(
+					 FieldUpgradeData_In *in,
+					 FieldUpgradeData_Out *out
+					 );
+typedef const struct {
+    FieldUpgradeData_Entry    *entry;
+    UINT16                    inSize;
+    UINT16                    outSize;
+    UINT16                    offsetOfTypes;
+    UINT16                    paramOffsets[1];
+    BYTE                      types[5];
+} FieldUpgradeData_COMMAND_DESCRIPTOR_t;
+FieldUpgradeData_COMMAND_DESCRIPTOR_t _FieldUpgradeDataData = {
+    /* entry  */          &TPM2_FieldUpgradeData,
+    /* inSize */          (UINT16)(sizeof(FieldUpgradeData_In)),
+    /* outSize */         (UINT16)(sizeof(FieldUpgradeData_Out)),
+    /* offsetOfTypes */   offsetof(FieldUpgradeData_COMMAND_DESCRIPTOR_t, types),
+    /* offsets */         {(UINT16)(offsetof(FieldUpgradeData_Out, firstDigest))},
+    /* types */           {TPM2B_MAX_BUFFER_P_UNMARSHAL,
+			   END_OF_LIST,
+			   TPMT_HA_P_MARSHAL,
+			   TPMT_HA_P_MARSHAL,
+			   END_OF_LIST}
+};
+#define _FieldUpgradeDataDataAddress (&_FieldUpgradeDataData)
+#else
+#define _FieldUpgradeDataDataAddress 0
+#endif
+#if CC_FirmwareRead
+#include "FirmwareRead_fp.h"
+typedef TPM_RC  (FirmwareRead_Entry)(
+				     FirmwareRead_In *in,
+				     FirmwareRead_Out *out
+				     );
+typedef const struct {
+    FirmwareRead_Entry    *entry;
+    UINT16                inSize;
+    UINT16                outSize;
+    UINT16                offsetOfTypes;
+    BYTE                  types[4];
+} FirmwareRead_COMMAND_DESCRIPTOR_t;
+FirmwareRead_COMMAND_DESCRIPTOR_t _FirmwareReadData = {
+    /* entry  */          &TPM2_FirmwareRead,
+    /* inSize */          (UINT16)(sizeof(FirmwareRead_In)),
+    /* outSize */         (UINT16)(sizeof(FirmwareRead_Out)),
+    /* offsetOfTypes */   offsetof(FirmwareRead_COMMAND_DESCRIPTOR_t, types),
+    /* offsets */         // No parameter offsets
+    /* types */           {UINT32_P_UNMARSHAL,
+			   END_OF_LIST,
+			   TPM2B_MAX_BUFFER_P_MARSHAL,
+			   END_OF_LIST}
+};
+#define _FirmwareReadDataAddress (&_FirmwareReadData)
+#else
+#define _FirmwareReadDataAddress 0
+#endif
+#if CC_ContextSave
+#include "ContextSave_fp.h"
+typedef TPM_RC  (ContextSave_Entry)(
+				    ContextSave_In *in,
+				    ContextSave_Out *out
+				    );
+typedef const struct {
+    ContextSave_Entry    *entry;
+    UINT16               inSize;
+    UINT16               outSize;
+    UINT16               offsetOfTypes;
+    BYTE                 types[4];
+} ContextSave_COMMAND_DESCRIPTOR_t;
+ContextSave_COMMAND_DESCRIPTOR_t _ContextSaveData = {
+    /* entry  */          &TPM2_ContextSave,
+    /* inSize */          (UINT16)(sizeof(ContextSave_In)),
+    /* outSize */         (UINT16)(sizeof(ContextSave_Out)),
+    /* offsetOfTypes */   offsetof(ContextSave_COMMAND_DESCRIPTOR_t, types),
+    /* offsets */         // No parameter offsets
+    /* types */           {TPMI_DH_CONTEXT_H_UNMARSHAL,
+			   END_OF_LIST,
+			   TPMS_CONTEXT_P_MARSHAL,
+			   END_OF_LIST}
+};
+#define _ContextSaveDataAddress (&_ContextSaveData)
+#else
+#define _ContextSaveDataAddress 0
+#endif
+#if CC_ContextLoad
+#include "ContextLoad_fp.h"
+typedef TPM_RC  (ContextLoad_Entry)(
+				    ContextLoad_In *in,
+				    ContextLoad_Out *out
+				    );
+typedef const struct {
+    ContextLoad_Entry    *entry;
+    UINT16               inSize;
+    UINT16               outSize;
+    UINT16               offsetOfTypes;
+    BYTE                 types[4];
+} ContextLoad_COMMAND_DESCRIPTOR_t;
+ContextLoad_COMMAND_DESCRIPTOR_t _ContextLoadData = {
+    /* entry  */          &TPM2_ContextLoad,
+    /* inSize */          (UINT16)(sizeof(ContextLoad_In)),
+    /* outSize */         (UINT16)(sizeof(ContextLoad_Out)),
+    /* offsetOfTypes */   offsetof(ContextLoad_COMMAND_DESCRIPTOR_t, types),
+    /* offsets */         // No parameter offsets
+    /* types */           {TPMS_CONTEXT_P_UNMARSHAL,
+			   END_OF_LIST,
+			   TPMI_DH_CONTEXT_H_MARSHAL,
+			   END_OF_LIST}
+};
+#define _ContextLoadDataAddress (&_ContextLoadData)
+#else
+#define _ContextLoadDataAddress 0
+#endif
+#if CC_FlushContext
+#include "FlushContext_fp.h"
+typedef TPM_RC  (FlushContext_Entry)(
+				     FlushContext_In *in
+				     );
+typedef const struct {
+    FlushContext_Entry    *entry;
+    UINT16                inSize;
+    UINT16                outSize;
+    UINT16                offsetOfTypes;
+    BYTE                  types[3];
+} FlushContext_COMMAND_DESCRIPTOR_t;
+FlushContext_COMMAND_DESCRIPTOR_t _FlushContextData = {
+    /* entry  */          &TPM2_FlushContext,
+    /* inSize */          (UINT16)(sizeof(FlushContext_In)),
+    /* outSize */         0,
+    /* offsetOfTypes */   offsetof(FlushContext_COMMAND_DESCRIPTOR_t, types),
+    /* offsets */         // No parameter offsets
+    /* types */           {TPMI_DH_CONTEXT_P_UNMARSHAL,
+			   END_OF_LIST,
+			   END_OF_LIST}
+};
+#define _FlushContextDataAddress (&_FlushContextData)
+#else
+#define _FlushContextDataAddress 0
+#endif
+#if CC_EvictControl
+#include "EvictControl_fp.h"
+typedef TPM_RC  (EvictControl_Entry)(
+				     EvictControl_In *in
+				     );
+typedef const struct {
+    EvictControl_Entry    *entry;
+    UINT16                inSize;
+    UINT16                outSize;
+    UINT16                offsetOfTypes;
+    UINT16                paramOffsets[2];
+    BYTE                  types[5];
+} EvictControl_COMMAND_DESCRIPTOR_t;
+EvictControl_COMMAND_DESCRIPTOR_t _EvictControlData = {
+    /* entry  */          &TPM2_EvictControl,
+    /* inSize */          (UINT16)(sizeof(EvictControl_In)),
+    /* outSize */         0,
+    /* offsetOfTypes */   offsetof(EvictControl_COMMAND_DESCRIPTOR_t, types),
+    /* offsets */         {(UINT16)(offsetof(EvictControl_In, objectHandle)),
+			   (UINT16)(offsetof(EvictControl_In, persistentHandle))},
+    /* types */           {TPMI_RH_PROVISION_H_UNMARSHAL,
+			   TPMI_DH_OBJECT_H_UNMARSHAL,
+			   TPMI_DH_PERSISTENT_P_UNMARSHAL,
+			   END_OF_LIST,
+			   END_OF_LIST}
+};
+#define _EvictControlDataAddress (&_EvictControlData)
+#else
+#define _EvictControlDataAddress 0
+#endif
+#if CC_ReadClock
+#include "ReadClock_fp.h"
+typedef TPM_RC  (ReadClock_Entry)(
+				  ReadClock_Out *out
+				  );
+typedef const struct {
+    ReadClock_Entry    *entry;
+    UINT16             inSize;
+    UINT16             outSize;
+    UINT16             offsetOfTypes;
+    BYTE               types[3];
+} ReadClock_COMMAND_DESCRIPTOR_t;
+ReadClock_COMMAND_DESCRIPTOR_t _ReadClockData = {
+    /* entry  */          &TPM2_ReadClock,
+    /* inSize */          0,
+    /* outSize */         (UINT16)(sizeof(ReadClock_Out)),
+    /* offsetOfTypes */   offsetof(ReadClock_COMMAND_DESCRIPTOR_t, types),
+    /* offsets */         // No parameter offsets
+    /* types */           {END_OF_LIST,
+			   TPMS_TIME_INFO_P_MARSHAL,
+			   END_OF_LIST}
+};
+#define _ReadClockDataAddress (&_ReadClockData)
+#else
+#define _ReadClockDataAddress 0
+#endif
+#if CC_ClockSet
+#include "ClockSet_fp.h"
+typedef TPM_RC  (ClockSet_Entry)(
+				 ClockSet_In *in
+				 );
+typedef const struct {
+    ClockSet_Entry    *entry;
+    UINT16            inSize;
+    UINT16            outSize;
+    UINT16            offsetOfTypes;
+    UINT16            paramOffsets[1];
+    BYTE              types[4];
+} ClockSet_COMMAND_DESCRIPTOR_t;
+ClockSet_COMMAND_DESCRIPTOR_t _ClockSetData = {
+    /* entry  */          &TPM2_ClockSet,
+    /* inSize */          (UINT16)(sizeof(ClockSet_In)),
+    /* outSize */         0,
+    /* offsetOfTypes */   offsetof(ClockSet_COMMAND_DESCRIPTOR_t, types),
+    /* offsets */         {(UINT16)(offsetof(ClockSet_In, newTime))},
+    /* types */           {TPMI_RH_PROVISION_H_UNMARSHAL,
+			   UINT64_P_UNMARSHAL,
+			   END_OF_LIST,
+			   END_OF_LIST}
+};
+#define _ClockSetDataAddress (&_ClockSetData)
+#else
+#define _ClockSetDataAddress 0
+#endif
+#if CC_ClockRateAdjust
+#include "ClockRateAdjust_fp.h"
+typedef TPM_RC  (ClockRateAdjust_Entry)(
+					ClockRateAdjust_In *in
+					);
+typedef const struct {
+    ClockRateAdjust_Entry    *entry;
+    UINT16                   inSize;
+    UINT16                   outSize;
+    UINT16                   offsetOfTypes;
+    UINT16                   paramOffsets[1];
+    BYTE                     types[4];
+} ClockRateAdjust_COMMAND_DESCRIPTOR_t;
+ClockRateAdjust_COMMAND_DESCRIPTOR_t _ClockRateAdjustData = {
+    /* entry  */          &TPM2_ClockRateAdjust,
+    /* inSize */          (UINT16)(sizeof(ClockRateAdjust_In)),
+    /* outSize */         0,
+    /* offsetOfTypes */   offsetof(ClockRateAdjust_COMMAND_DESCRIPTOR_t, types),
+    /* offsets */         {(UINT16)(offsetof(ClockRateAdjust_In, rateAdjust))},
+    /* types */           {TPMI_RH_PROVISION_H_UNMARSHAL,
+			   TPM_CLOCK_ADJUST_P_UNMARSHAL,
+			   END_OF_LIST,
+			   END_OF_LIST}
+};
+#define _ClockRateAdjustDataAddress (&_ClockRateAdjustData)
+#else
+#define _ClockRateAdjustDataAddress 0
+#endif
+#if CC_GetCapability
+#include "GetCapability_fp.h"
+typedef TPM_RC  (GetCapability_Entry)(
+				      GetCapability_In *in,
+				      GetCapability_Out *out
+				      );
+typedef const struct {
+    GetCapability_Entry    *entry;
+    UINT16                 inSize;
+    UINT16                 outSize;
+    UINT16                 offsetOfTypes;
+    UINT16                 paramOffsets[3];
+    BYTE                   types[7];
+} GetCapability_COMMAND_DESCRIPTOR_t;
+GetCapability_COMMAND_DESCRIPTOR_t _GetCapabilityData = {
+    /* entry  */          &TPM2_GetCapability,
+    /* inSize */          (UINT16)(sizeof(GetCapability_In)),
+    /* outSize */         (UINT16)(sizeof(GetCapability_Out)),
+    /* offsetOfTypes */   offsetof(GetCapability_COMMAND_DESCRIPTOR_t, types),
+    /* offsets */         {(UINT16)(offsetof(GetCapability_In, property)),
+			   (UINT16)(offsetof(GetCapability_In, propertyCount)),
+			   (UINT16)(offsetof(GetCapability_Out, capabilityData))},
+    /* types */           {TPM_CAP_P_UNMARSHAL,
+			   UINT32_P_UNMARSHAL,
+			   UINT32_P_UNMARSHAL,
+			   END_OF_LIST,
+			   TPMI_YES_NO_P_MARSHAL,
+			   TPMS_CAPABILITY_DATA_P_MARSHAL,
+			   END_OF_LIST}
+};
+#define _GetCapabilityDataAddress (&_GetCapabilityData)
+#else
+#define _GetCapabilityDataAddress 0
+#endif
+#if CC_TestParms
+#include "TestParms_fp.h"
+typedef TPM_RC  (TestParms_Entry)(
+				  TestParms_In *in
+				  );
+typedef const struct {
+    TestParms_Entry    *entry;
+    UINT16             inSize;
+    UINT16             outSize;
+    UINT16             offsetOfTypes;
+    BYTE               types[3];
+} TestParms_COMMAND_DESCRIPTOR_t;
+TestParms_COMMAND_DESCRIPTOR_t _TestParmsData = {
+    /* entry  */          &TPM2_TestParms,
+    /* inSize */          (UINT16)(sizeof(TestParms_In)),
+    /* outSize */         0,
+    /* offsetOfTypes */   offsetof(TestParms_COMMAND_DESCRIPTOR_t, types),
+    /* offsets */         // No parameter offsets
+    /* types */           {TPMT_PUBLIC_PARMS_P_UNMARSHAL,
+			   END_OF_LIST,
+			   END_OF_LIST}
+};
+#define _TestParmsDataAddress (&_TestParmsData)
+#else
+#define _TestParmsDataAddress 0
+#endif
+#if CC_NV_DefineSpace
+#include "NV_DefineSpace_fp.h"
+typedef TPM_RC  (NV_DefineSpace_Entry)(
+				       NV_DefineSpace_In *in
+				       );
+typedef const struct {
+    NV_DefineSpace_Entry    *entry;
+    UINT16                  inSize;
+    UINT16                  outSize;
+    UINT16                  offsetOfTypes;
+    UINT16                  paramOffsets[2];
+    BYTE                    types[5];
+} NV_DefineSpace_COMMAND_DESCRIPTOR_t;
+NV_DefineSpace_COMMAND_DESCRIPTOR_t _NV_DefineSpaceData = {
+    /* entry  */          &TPM2_NV_DefineSpace,
+    /* inSize */          (UINT16)(sizeof(NV_DefineSpace_In)),
+    /* outSize */         0,
+    /* offsetOfTypes */   offsetof(NV_DefineSpace_COMMAND_DESCRIPTOR_t, types),
+    /* offsets */         {(UINT16)(offsetof(NV_DefineSpace_In, auth)),
+			   (UINT16)(offsetof(NV_DefineSpace_In, publicInfo))},
+    /* types */           {TPMI_RH_PROVISION_H_UNMARSHAL,
+			   TPM2B_AUTH_P_UNMARSHAL,
+			   TPM2B_NV_PUBLIC_P_UNMARSHAL,
+			   END_OF_LIST,
+			   END_OF_LIST}
+};
+#define _NV_DefineSpaceDataAddress (&_NV_DefineSpaceData)
+#else
+#define _NV_DefineSpaceDataAddress 0
+#endif
+#if CC_NV_UndefineSpace
+#include "NV_UndefineSpace_fp.h"
+typedef TPM_RC  (NV_UndefineSpace_Entry)(
+					 NV_UndefineSpace_In *in
+					 );
+typedef const struct {
+    NV_UndefineSpace_Entry    *entry;
+    UINT16                    inSize;
+    UINT16                    outSize;
+    UINT16                    offsetOfTypes;
+    UINT16                    paramOffsets[1];
+    BYTE                      types[4];
+} NV_UndefineSpace_COMMAND_DESCRIPTOR_t;
+NV_UndefineSpace_COMMAND_DESCRIPTOR_t _NV_UndefineSpaceData = {
+    /* entry  */          &TPM2_NV_UndefineSpace,
+    /* inSize */          (UINT16)(sizeof(NV_UndefineSpace_In)),
+    /* outSize */         0,
+    /* offsetOfTypes */   offsetof(NV_UndefineSpace_COMMAND_DESCRIPTOR_t, types),
+    /* offsets */         {(UINT16)(offsetof(NV_UndefineSpace_In, nvIndex))},
+    /* types */           {TPMI_RH_PROVISION_H_UNMARSHAL,
+			   TPMI_RH_NV_INDEX_H_UNMARSHAL,
+			   END_OF_LIST,
+			   END_OF_LIST}
+};
+#define _NV_UndefineSpaceDataAddress (&_NV_UndefineSpaceData)
+#else
+#define _NV_UndefineSpaceDataAddress 0
+#endif
+#if CC_NV_UndefineSpaceSpecial
+#include "NV_UndefineSpaceSpecial_fp.h"
+typedef TPM_RC  (NV_UndefineSpaceSpecial_Entry)(
+						NV_UndefineSpaceSpecial_In *in
+						);
+typedef const struct {
+    NV_UndefineSpaceSpecial_Entry    *entry;
+    UINT16                           inSize;
+    UINT16                           outSize;
+    UINT16                           offsetOfTypes;
+    UINT16                           paramOffsets[1];
+    BYTE                             types[4];
+} NV_UndefineSpaceSpecial_COMMAND_DESCRIPTOR_t;
+NV_UndefineSpaceSpecial_COMMAND_DESCRIPTOR_t _NV_UndefineSpaceSpecialData = {
+    /* entry  */          &TPM2_NV_UndefineSpaceSpecial,
+    /* inSize */          (UINT16)(sizeof(NV_UndefineSpaceSpecial_In)),
+    /* outSize */         0,
+    /* offsetOfTypes */   offsetof(NV_UndefineSpaceSpecial_COMMAND_DESCRIPTOR_t, types),
+    /* offsets */         {(UINT16)(offsetof(NV_UndefineSpaceSpecial_In, platform))},
+    /* types */           {TPMI_RH_NV_INDEX_H_UNMARSHAL,
+			   TPMI_RH_PLATFORM_H_UNMARSHAL,
+			   END_OF_LIST,
+			   END_OF_LIST}
+};
+#define _NV_UndefineSpaceSpecialDataAddress (&_NV_UndefineSpaceSpecialData)
+#else
+#define _NV_UndefineSpaceSpecialDataAddress 0
+#endif
+#if CC_NV_ReadPublic
+#include "NV_ReadPublic_fp.h"
+typedef TPM_RC  (NV_ReadPublic_Entry)(
+				      NV_ReadPublic_In *in,
+				      NV_ReadPublic_Out *out
+				      );
+typedef const struct {
+    NV_ReadPublic_Entry    *entry;
+    UINT16                 inSize;
+    UINT16                 outSize;
+    UINT16                 offsetOfTypes;
+    UINT16                 paramOffsets[1];
+    BYTE                   types[5];
+} NV_ReadPublic_COMMAND_DESCRIPTOR_t;
+NV_ReadPublic_COMMAND_DESCRIPTOR_t _NV_ReadPublicData = {
+    /* entry  */          &TPM2_NV_ReadPublic,
+    /* inSize */          (UINT16)(sizeof(NV_ReadPublic_In)),
+    /* outSize */         (UINT16)(sizeof(NV_ReadPublic_Out)),
+    /* offsetOfTypes */   offsetof(NV_ReadPublic_COMMAND_DESCRIPTOR_t, types),
+    /* offsets */         {(UINT16)(offsetof(NV_ReadPublic_Out, nvName))},
+    /* types */           {TPMI_RH_NV_INDEX_H_UNMARSHAL,
+			   END_OF_LIST,
+			   TPM2B_NV_PUBLIC_P_MARSHAL,
+			   TPM2B_NAME_P_MARSHAL,
+			   END_OF_LIST}
+};
+#define _NV_ReadPublicDataAddress (&_NV_ReadPublicData)
+#else
+#define _NV_ReadPublicDataAddress 0
+#endif
+#if CC_NV_Write
+#include "NV_Write_fp.h"
+typedef TPM_RC  (NV_Write_Entry)(
+				 NV_Write_In *in
+				 );
+typedef const struct {
+    NV_Write_Entry    *entry;
+    UINT16            inSize;
+    UINT16            outSize;
+    UINT16            offsetOfTypes;
+    UINT16            paramOffsets[3];
+    BYTE              types[6];
+} NV_Write_COMMAND_DESCRIPTOR_t;
+NV_Write_COMMAND_DESCRIPTOR_t _NV_WriteData = {
+    /* entry  */          &TPM2_NV_Write,
+    /* inSize */          (UINT16)(sizeof(NV_Write_In)),
+    /* outSize */         0,
+    /* offsetOfTypes */   offsetof(NV_Write_COMMAND_DESCRIPTOR_t, types),
+    /* offsets */         {(UINT16)(offsetof(NV_Write_In, nvIndex)),
+			   (UINT16)(offsetof(NV_Write_In, data)),
+			   (UINT16)(offsetof(NV_Write_In, offset))},
+    /* types */           {TPMI_RH_NV_AUTH_H_UNMARSHAL,
+			   TPMI_RH_NV_INDEX_H_UNMARSHAL,
+			   TPM2B_MAX_NV_BUFFER_P_UNMARSHAL,
+			   UINT16_P_UNMARSHAL,
+			   END_OF_LIST,
+			   END_OF_LIST}
+};
+#define _NV_WriteDataAddress (&_NV_WriteData)
+#else
+#define _NV_WriteDataAddress 0
+#endif
+#if CC_NV_Increment
+#include "NV_Increment_fp.h"
+typedef TPM_RC  (NV_Increment_Entry)(
+				     NV_Increment_In *in
+				     );
+typedef const struct {
+    NV_Increment_Entry    *entry;
+    UINT16                inSize;
+    UINT16                outSize;
+    UINT16                offsetOfTypes;
+    UINT16                paramOffsets[1];
+    BYTE                  types[4];
+} NV_Increment_COMMAND_DESCRIPTOR_t;
+NV_Increment_COMMAND_DESCRIPTOR_t _NV_IncrementData = {
+    /* entry  */          &TPM2_NV_Increment,
+    /* inSize */          (UINT16)(sizeof(NV_Increment_In)),
+    /* outSize */         0,
+    /* offsetOfTypes */   offsetof(NV_Increment_COMMAND_DESCRIPTOR_t, types),
+    /* offsets */         {(UINT16)(offsetof(NV_Increment_In, nvIndex))},
+    /* types */           {TPMI_RH_NV_AUTH_H_UNMARSHAL,
+			   TPMI_RH_NV_INDEX_H_UNMARSHAL,
+			   END_OF_LIST,
+			   END_OF_LIST}
+};
+#define _NV_IncrementDataAddress (&_NV_IncrementData)
+#else
+#define _NV_IncrementDataAddress 0
+#endif
+#if CC_NV_Extend
+#include "NV_Extend_fp.h"
+typedef TPM_RC  (NV_Extend_Entry)(
+				  NV_Extend_In *in
+				  );
+typedef const struct {
+    NV_Extend_Entry    *entry;
+    UINT16             inSize;
+    UINT16             outSize;
+    UINT16             offsetOfTypes;
+    UINT16             paramOffsets[2];
+    BYTE               types[5];
+} NV_Extend_COMMAND_DESCRIPTOR_t;
+NV_Extend_COMMAND_DESCRIPTOR_t _NV_ExtendData = {
+    /* entry  */          &TPM2_NV_Extend,
+    /* inSize */          (UINT16)(sizeof(NV_Extend_In)),
+    /* outSize */         0,
+    /* offsetOfTypes */   offsetof(NV_Extend_COMMAND_DESCRIPTOR_t, types),
+    /* offsets */         {(UINT16)(offsetof(NV_Extend_In, nvIndex)),
+			   (UINT16)(offsetof(NV_Extend_In, data))},
+    /* types */           {TPMI_RH_NV_AUTH_H_UNMARSHAL,
+			   TPMI_RH_NV_INDEX_H_UNMARSHAL,
+			   TPM2B_MAX_NV_BUFFER_P_UNMARSHAL,
+			   END_OF_LIST,
+			   END_OF_LIST}
+};
+#define _NV_ExtendDataAddress (&_NV_ExtendData)
+#else
+#define _NV_ExtendDataAddress 0
+#endif
+#if CC_NV_SetBits
+#include "NV_SetBits_fp.h"
+typedef TPM_RC  (NV_SetBits_Entry)(
+				   NV_SetBits_In *in
+				   );
+typedef const struct {
+    NV_SetBits_Entry    *entry;
+    UINT16              inSize;
+    UINT16              outSize;
+    UINT16              offsetOfTypes;
+    UINT16              paramOffsets[2];
+    BYTE                types[5];
+} NV_SetBits_COMMAND_DESCRIPTOR_t;
+NV_SetBits_COMMAND_DESCRIPTOR_t _NV_SetBitsData = {
+    /* entry  */          &TPM2_NV_SetBits,
+    /* inSize */          (UINT16)(sizeof(NV_SetBits_In)),
+    /* outSize */         0,
+    /* offsetOfTypes */   offsetof(NV_SetBits_COMMAND_DESCRIPTOR_t, types),
+    /* offsets */         {(UINT16)(offsetof(NV_SetBits_In, nvIndex)),
+			   (UINT16)(offsetof(NV_SetBits_In, bits))},
+    /* types */           {TPMI_RH_NV_AUTH_H_UNMARSHAL,
+			   TPMI_RH_NV_INDEX_H_UNMARSHAL,
+			   UINT64_P_UNMARSHAL,
+			   END_OF_LIST,
+			   END_OF_LIST}
+};
+#define _NV_SetBitsDataAddress (&_NV_SetBitsData)
+#else
+#define _NV_SetBitsDataAddress 0
+#endif
+#if CC_NV_WriteLock
+#include "NV_WriteLock_fp.h"
+typedef TPM_RC  (NV_WriteLock_Entry)(
+				     NV_WriteLock_In *in
+				     );
+typedef const struct {
+    NV_WriteLock_Entry    *entry;
+    UINT16                inSize;
+    UINT16                outSize;
+    UINT16                offsetOfTypes;
+    UINT16                paramOffsets[1];
+    BYTE                  types[4];
+} NV_WriteLock_COMMAND_DESCRIPTOR_t;
+NV_WriteLock_COMMAND_DESCRIPTOR_t _NV_WriteLockData = {
+    /* entry  */          &TPM2_NV_WriteLock,
+    /* inSize */          (UINT16)(sizeof(NV_WriteLock_In)),
+    /* outSize */         0,
+    /* offsetOfTypes */   offsetof(NV_WriteLock_COMMAND_DESCRIPTOR_t, types),
+    /* offsets */         {(UINT16)(offsetof(NV_WriteLock_In, nvIndex))},
+    /* types */           {TPMI_RH_NV_AUTH_H_UNMARSHAL,
+			   TPMI_RH_NV_INDEX_H_UNMARSHAL,
+			   END_OF_LIST,
+			   END_OF_LIST}
+};
+#define _NV_WriteLockDataAddress (&_NV_WriteLockData)
+#else
+#define _NV_WriteLockDataAddress 0
+#endif
+#if CC_NV_GlobalWriteLock
+#include "NV_GlobalWriteLock_fp.h"
+typedef TPM_RC  (NV_GlobalWriteLock_Entry)(
+					   NV_GlobalWriteLock_In *in
+					   );
+typedef const struct {
+    NV_GlobalWriteLock_Entry    *entry;
+    UINT16                      inSize;
+    UINT16                      outSize;
+    UINT16                      offsetOfTypes;
+    BYTE                        types[3];
+} NV_GlobalWriteLock_COMMAND_DESCRIPTOR_t;
+NV_GlobalWriteLock_COMMAND_DESCRIPTOR_t _NV_GlobalWriteLockData = {
+    /* entry  */          &TPM2_NV_GlobalWriteLock,
+    /* inSize */          (UINT16)(sizeof(NV_GlobalWriteLock_In)),
+    /* outSize */         0,
+    /* offsetOfTypes */   offsetof(NV_GlobalWriteLock_COMMAND_DESCRIPTOR_t, types),
+    /* offsets */         // No parameter offsets
+    /* types */           {TPMI_RH_PROVISION_H_UNMARSHAL,
+			   END_OF_LIST,
+			   END_OF_LIST}
+};
+#define _NV_GlobalWriteLockDataAddress (&_NV_GlobalWriteLockData)
+#else
+#define _NV_GlobalWriteLockDataAddress 0
+#endif
+#if CC_NV_Read
+#include "NV_Read_fp.h"
+typedef TPM_RC  (NV_Read_Entry)(
+				NV_Read_In *in,
+				NV_Read_Out *out
+				);
+typedef const struct {
+    NV_Read_Entry    *entry;
+    UINT16           inSize;
+    UINT16           outSize;
+    UINT16           offsetOfTypes;
+    UINT16           paramOffsets[3];
+    BYTE             types[7];
+} NV_Read_COMMAND_DESCRIPTOR_t;
+NV_Read_COMMAND_DESCRIPTOR_t _NV_ReadData = {
+    /* entry  */          &TPM2_NV_Read,
+    /* inSize */          (UINT16)(sizeof(NV_Read_In)),
+    /* outSize */         (UINT16)(sizeof(NV_Read_Out)),
+    /* offsetOfTypes */   offsetof(NV_Read_COMMAND_DESCRIPTOR_t, types),
+    /* offsets */         {(UINT16)(offsetof(NV_Read_In, nvIndex)),
+			   (UINT16)(offsetof(NV_Read_In, size)),
+			   (UINT16)(offsetof(NV_Read_In, offset))},
+    /* types */           {TPMI_RH_NV_AUTH_H_UNMARSHAL,
+			   TPMI_RH_NV_INDEX_H_UNMARSHAL,
+			   UINT16_P_UNMARSHAL,
+			   UINT16_P_UNMARSHAL,
+			   END_OF_LIST,
+			   TPM2B_MAX_NV_BUFFER_P_MARSHAL,
+			   END_OF_LIST}
+};
+#define _NV_ReadDataAddress (&_NV_ReadData)
+#else
+#define _NV_ReadDataAddress 0
+#endif
+#if CC_NV_ReadLock
+#include "NV_ReadLock_fp.h"
+typedef TPM_RC  (NV_ReadLock_Entry)(
+				    NV_ReadLock_In *in
+				    );
+typedef const struct {
+    NV_ReadLock_Entry    *entry;
+    UINT16               inSize;
+    UINT16               outSize;
+    UINT16               offsetOfTypes;
+    UINT16               paramOffsets[1];
+    BYTE                 types[4];
+} NV_ReadLock_COMMAND_DESCRIPTOR_t;
+NV_ReadLock_COMMAND_DESCRIPTOR_t _NV_ReadLockData = {
+    /* entry  */          &TPM2_NV_ReadLock,
+    /* inSize */          (UINT16)(sizeof(NV_ReadLock_In)),
+    /* outSize */         0,
+    /* offsetOfTypes */   offsetof(NV_ReadLock_COMMAND_DESCRIPTOR_t, types),
+    /* offsets */         {(UINT16)(offsetof(NV_ReadLock_In, nvIndex))},
+    /* types */           {TPMI_RH_NV_AUTH_H_UNMARSHAL,
+			   TPMI_RH_NV_INDEX_H_UNMARSHAL,
+			   END_OF_LIST,
+			   END_OF_LIST}
+};
+#define _NV_ReadLockDataAddress (&_NV_ReadLockData)
+#else
+#define _NV_ReadLockDataAddress 0
+#endif
+#if CC_NV_ChangeAuth
+#include "NV_ChangeAuth_fp.h"
+typedef TPM_RC  (NV_ChangeAuth_Entry)(
+				      NV_ChangeAuth_In *in
+				      );
+typedef const struct {
+    NV_ChangeAuth_Entry    *entry;
+    UINT16                 inSize;
+    UINT16                 outSize;
+    UINT16                 offsetOfTypes;
+    UINT16                 paramOffsets[1];
+    BYTE                   types[4];
+} NV_ChangeAuth_COMMAND_DESCRIPTOR_t;
+NV_ChangeAuth_COMMAND_DESCRIPTOR_t _NV_ChangeAuthData = {
+    /* entry  */          &TPM2_NV_ChangeAuth,
+    /* inSize */          (UINT16)(sizeof(NV_ChangeAuth_In)),
+    /* outSize */         0,
+    /* offsetOfTypes */   offsetof(NV_ChangeAuth_COMMAND_DESCRIPTOR_t, types),
+    /* offsets */         {(UINT16)(offsetof(NV_ChangeAuth_In, newAuth))},
+    /* types */           {TPMI_RH_NV_INDEX_H_UNMARSHAL,
+			   TPM2B_AUTH_P_UNMARSHAL,
+			   END_OF_LIST,
+			   END_OF_LIST}
+};
+#define _NV_ChangeAuthDataAddress (&_NV_ChangeAuthData)
+#else
+#define _NV_ChangeAuthDataAddress 0
+#endif
+#if CC_NV_Certify
+#include "NV_Certify_fp.h"
+typedef TPM_RC  (NV_Certify_Entry)(
+				   NV_Certify_In *in,
+				   NV_Certify_Out *out
+				   );
+typedef const struct {
+    NV_Certify_Entry    *entry;
+    UINT16              inSize;
+    UINT16              outSize;
+    UINT16              offsetOfTypes;
+    UINT16              paramOffsets[7];
+    BYTE                types[11];
+} NV_Certify_COMMAND_DESCRIPTOR_t;
+NV_Certify_COMMAND_DESCRIPTOR_t _NV_CertifyData = {
+    /* entry  */          &TPM2_NV_Certify,
+    /* inSize */          (UINT16)(sizeof(NV_Certify_In)),
+    /* outSize */         (UINT16)(sizeof(NV_Certify_Out)),
+    /* offsetOfTypes */   offsetof(NV_Certify_COMMAND_DESCRIPTOR_t, types),
+    /* offsets */         {(UINT16)(offsetof(NV_Certify_In, authHandle)),
+			   (UINT16)(offsetof(NV_Certify_In, nvIndex)),
+			   (UINT16)(offsetof(NV_Certify_In, qualifyingData)),
+			   (UINT16)(offsetof(NV_Certify_In, inScheme)),
+			   (UINT16)(offsetof(NV_Certify_In, size)),
+			   (UINT16)(offsetof(NV_Certify_In, offset)),
+			   (UINT16)(offsetof(NV_Certify_Out, signature))},
+    /* types */           {TPMI_DH_OBJECT_H_UNMARSHAL + ADD_FLAG,
+			   TPMI_RH_NV_AUTH_H_UNMARSHAL,
+			   TPMI_RH_NV_INDEX_H_UNMARSHAL,
+			   TPM2B_DATA_P_UNMARSHAL,
+			   TPMT_SIG_SCHEME_P_UNMARSHAL + ADD_FLAG,
+			   UINT16_P_UNMARSHAL,
+			   UINT16_P_UNMARSHAL,
+			   END_OF_LIST,
+			   TPM2B_ATTEST_P_MARSHAL,
+			   TPMT_SIGNATURE_P_MARSHAL,
+			   END_OF_LIST}
+};
+#define _NV_CertifyDataAddress (&_NV_CertifyData)
+#else
+#define _NV_CertifyDataAddress 0
+#endif
+
+#if CC_AC_GetCapability
+#include "AC_GetCapability_fp.h"
+typedef TPM_RC  (AC_GetCapability_Entry)(
+					 AC_GetCapability_In *in,
+					 AC_GetCapability_Out *out
+					 );
+typedef const struct {
+    AC_GetCapability_Entry    *entry;
+    UINT16                    inSize;
+    UINT16                    outSize;
+    UINT16                    offsetOfTypes;
+    UINT16                    paramOffsets[3];
+    BYTE                      types[7];
+} AC_GetCapability_COMMAND_DESCRIPTOR_t;
+AC_GetCapability_COMMAND_DESCRIPTOR_t _AC_GetCapabilityData = {
+    /* entry  */          &TPM2_AC_GetCapability,
+    /* inSize */          (UINT16)(sizeof(AC_GetCapability_In)),
+    /* outSize */         (UINT16)(sizeof(AC_GetCapability_Out)),
+    /* offsetOfTypes */   offsetof(AC_GetCapability_COMMAND_DESCRIPTOR_t, types),
+    /* offsets */         {(UINT16)(offsetof(AC_GetCapability_In, capability)),
+			   (UINT16)(offsetof(AC_GetCapability_In, count)),
+			   (UINT16)(offsetof(AC_GetCapability_Out, capabilitiesData))},
+    /* types */           {TPMI_RH_AC_H_UNMARSHAL,
+			   TPM_AT_P_UNMARSHAL,
+			   UINT32_P_UNMARSHAL,
+			   END_OF_LIST,
+			   TPMI_YES_NO_P_MARSHAL,
+			   TPML_AC_CAPABILITIES_P_MARSHAL,
+			   END_OF_LIST}
+};
+#define _AC_GetCapabilityDataAddress (&_AC_GetCapabilityData)
+#else
+#define _AC_GetCapabilityDataAddress 0
+#endif
+
+#if CC_AC_Send
+#include "AC_Send_fp.h"
+typedef TPM_RC  (AC_Send_Entry)(
+				AC_Send_In *in,
+				AC_Send_Out *out
+				);
+typedef const struct {
+    AC_Send_Entry    *entry;
+    UINT16           inSize;
+    UINT16           outSize;
+    UINT16           offsetOfTypes;
+    UINT16           paramOffsets[3];
+    BYTE             types[7];
+} AC_Send_COMMAND_DESCRIPTOR_t;
+AC_Send_COMMAND_DESCRIPTOR_t _AC_SendData = {
+    /* entry  */          &TPM2_AC_Send,
+    /* inSize */          (UINT16)(sizeof(AC_Send_In)),
+    /* outSize */         (UINT16)(sizeof(AC_Send_Out)),
+    /* offsetOfTypes */   offsetof(AC_Send_COMMAND_DESCRIPTOR_t, types),
+    /* offsets */         {(UINT16)(offsetof(AC_Send_In, authHandle)),
+			   (UINT16)(offsetof(AC_Send_In, ac)),
+			   (UINT16)(offsetof(AC_Send_In, acDataIn))},
+    /* types */           {TPMI_DH_OBJECT_H_UNMARSHAL,
+			   TPMI_RH_NV_AUTH_H_UNMARSHAL,
+			   TPMI_RH_AC_H_UNMARSHAL,
+			   TPM2B_MAX_BUFFER_P_UNMARSHAL,
+			   END_OF_LIST,
+			   TPMS_AC_OUTPUT_P_MARSHAL,
+			   END_OF_LIST}
+};
+#define _AC_SendDataAddress (&_AC_SendData)
+#else
+#define _AC_SendDataAddress 0
+#endif
+
+#if CC_Policy_AC_SendSelect
+#include "Policy_AC_SendSelect_fp.h"
+typedef TPM_RC  (Policy_AC_SendSelect_Entry)(
+					     Policy_AC_SendSelect_In *in
+					     );
+typedef const struct {
+    Policy_AC_SendSelect_Entry    *entry;
+    UINT16                        inSize;
+    UINT16                        outSize;
+    UINT16                        offsetOfTypes;
+    UINT16                        paramOffsets[4];
+    BYTE                          types[7];
+} Policy_AC_SendSelect_COMMAND_DESCRIPTOR_t;
+Policy_AC_SendSelect_COMMAND_DESCRIPTOR_t _Policy_AC_SendSelectData = {
+    /* entry  */          &TPM2_Policy_AC_SendSelect,
+    /* inSize */          (UINT16)(sizeof(Policy_AC_SendSelect_In)),
+    /* outSize */         0,
+    /* offsetOfTypes */   offsetof(Policy_AC_SendSelect_COMMAND_DESCRIPTOR_t, types),
+    /* offsets */         {(UINT16)(offsetof(Policy_AC_SendSelect_In, objectName)),
+			   (UINT16)(offsetof(Policy_AC_SendSelect_In, authHandleName)),
+			   (UINT16)(offsetof(Policy_AC_SendSelect_In, acName)),
+			   (UINT16)(offsetof(Policy_AC_SendSelect_In, includeObject))},
+    /* types */           {TPMI_SH_POLICY_H_UNMARSHAL,
+			   TPM2B_NAME_P_UNMARSHAL,
+			   TPM2B_NAME_P_UNMARSHAL,
+			   TPM2B_NAME_P_UNMARSHAL,
+			   TPMI_YES_NO_P_UNMARSHAL,
+			   END_OF_LIST,
+			   END_OF_LIST}
+};
+#define _Policy_AC_SendSelectDataAddress (&_Policy_AC_SendSelectData)
+#else
+#define _Policy_AC_SendSelectDataAddress 0
+#endif
+
+#if CC_ACT_SetTimeout
+#include "ACT_SetTimeout_fp.h"
+typedef TPM_RC  (ACT_SetTimeout_Entry)(
+				       ACT_SetTimeout_In           *in
+				       );
+typedef const struct {
+    ACT_SetTimeout_Entry    *entry;
+    UINT16                  inSize;
+    UINT16                  outSize;
+    UINT16                  offsetOfTypes;
+    UINT16                  paramOffsets[1];
+    BYTE                    types[4];
+} ACT_SetTimeout_COMMAND_DESCRIPTOR_t;
+ACT_SetTimeout_COMMAND_DESCRIPTOR_t _ACT_SetTimeoutData = {
+	/* entry         */     &TPM2_ACT_SetTimeout,
+	/* inSize        */     (UINT16)(sizeof(ACT_SetTimeout_In)),
+	/* outSize       */     0,
+	/* offsetOfTypes */     offsetof(ACT_SetTimeout_COMMAND_DESCRIPTOR_t, types),
+	/* offsets	 */	{(UINT16)(offsetof(ACT_SetTimeout_In, startTimeout))},
+	/* types         */     {TPMI_RH_ACT_H_UNMARSHAL,
+				 UINT32_P_UNMARSHAL,
+				 END_OF_LIST,
+				 END_OF_LIST}
+};
+#define _ACT_SetTimeoutDataAddress (&_ACT_SetTimeoutData)
+#else
+#define _ACT_SetTimeoutDataAddress 0
+#endif // CC_ACT_SetTimeout
+
+#if CC_Vendor_TCG_Test
+#include "Vendor_TCG_Test_fp.h"
+typedef TPM_RC  (Vendor_TCG_Test_Entry)(
+					Vendor_TCG_Test_In *in,
+					Vendor_TCG_Test_Out *out
+					);
+typedef const struct {
+    Vendor_TCG_Test_Entry    *entry;
+    UINT16                   inSize;
+    UINT16                   outSize;
+    UINT16                   offsetOfTypes;
+    BYTE                     types[4];
+} Vendor_TCG_Test_COMMAND_DESCRIPTOR_t;
+Vendor_TCG_Test_COMMAND_DESCRIPTOR_t _Vendor_TCG_TestData = {
+    /* entry  */          &TPM2_Vendor_TCG_Test,
+    /* inSize */          (UINT16)(sizeof(Vendor_TCG_Test_In)),
+    /* outSize */         (UINT16)(sizeof(Vendor_TCG_Test_Out)),
+    /* offsetOfTypes */   offsetof(Vendor_TCG_Test_COMMAND_DESCRIPTOR_t, types),
+    /* offsets */         // No parameter offsets
+    /* types */           {TPM2B_DATA_P_UNMARSHAL,
+			   END_OF_LIST,
+			   TPM2B_DATA_P_MARSHAL,
+			   END_OF_LIST}
+};
+#define _Vendor_TCG_TestDataAddress (&_Vendor_TCG_TestData)
+#else
+#define _Vendor_TCG_TestDataAddress 0
+#endif
+
+#ifdef TPM_NUVOTON
+
+typedef TPM_RC (NTC2_PreConfig_Entry) (
+				       NTC2_PreConfig_In *in
+				       );
+
+typedef const struct {
+    NTC2_PreConfig_Entry    	*entry;
+    UINT16           		inSize;
+    UINT16           		outSize;
+    UINT16           		offsetOfTypes;
+    BYTE             		types[3];
+} NTC2_PreConfig_COMMAND_DESCRIPTOR_t;
+
+NTC2_PreConfig_COMMAND_DESCRIPTOR_t _NTC2_PreConfigData = {
+    /* entry  */          &NTC2_PreConfig,
+    /* inSize */          (UINT16)(sizeof(NTC2_PreConfig_In)),
+    /* outSize */         0,
+    /* offsetOfTypes */   offsetof(NTC2_PreConfig_COMMAND_DESCRIPTOR_t, types),
+    /* offsets */         // No parameter offsets
+    /* types */           {NTC2_CFG_STRUCT_P_UNMARSHAL,
+			   END_OF_LIST,
+			   END_OF_LIST}
+};
+
+#define _NTC2_PreConfigDataAddress (&_NTC2_PreConfigData)
+
+typedef TPM_RC (NTC2_LockPreConfig_Entry) ();
+				   
+typedef const struct {
+    NTC2_LockPreConfig_Entry    *entry;
+    UINT16           		inSize;
+    UINT16           		outSize;
+    UINT16             		offsetOfTypes;
+    BYTE                        types[2];
+} NTC2_LockPreConfig_COMMAND_DESCRIPTOR_t;
+
+NTC2_LockPreConfig_COMMAND_DESCRIPTOR_t _NTC2_LockPreConfigData = {
+    /* entry */		&NTC2_LockPreConfig,
+    /* inSize */        0,
+    /* outSize */       0,
+    /* offsetOfTypes */ offsetof(NTC2_LockPreConfig_COMMAND_DESCRIPTOR_t, types),
+    /* offsets */         // No parameter offsets
+    /* types */         {END_OF_LIST,
+			 END_OF_LIST}
+};
+
+#define _NTC2_LockPreConfigDataAddress (&_NTC2_LockPreConfigData)
+
+typedef TPM_RC (NTC2_GetConfig_Entry) (
+				       NTC2_GetConfig_Out *out
+				       );
+typedef const struct {
+    NTC2_GetConfig_Entry	*entry;
+    UINT16             		inSize;
+    UINT16             		outSize;
+    UINT16             		offsetOfTypes;
+    BYTE               		types[3];
+} NTC2_GetConfig_COMMAND_DESCRIPTOR_t;
+
+NTC2_GetConfig_COMMAND_DESCRIPTOR_t _NTC2_GetConfigData = {
+    /* entry */		&NTC2_GetConfig,
+    /* inSize */        0,
+    /* outSize */       (UINT16)(sizeof(NTC2_GetConfig_Out)),
+    /* offsetOfTypes */ offsetof(NTC2_GetConfig_COMMAND_DESCRIPTOR_t, types),
+    /* offsets */         // No parameter offsets
+    /* types */         {END_OF_LIST,
+			 NTC2_CFG_STRUCT_P_MARSHAL,
+			 END_OF_LIST}
+};
+
+#define _NTC2_GetConfigDataAddress (&_NTC2_GetConfigData)
+
+#else
+#define _NTC2_PreConfigDataAddress 0
+#define _NTC2_LockPreConfigDataAddress 0
+#define _NTC2_GetConfigDataAddress 0
+#endif		/* TPM_NUVOTON */
+
+COMMAND_DESCRIPTOR_t *s_CommandDataArray[] = {
+#if (PAD_LIST || CC_NV_UndefineSpaceSpecial)
+    (COMMAND_DESCRIPTOR_t *)_NV_UndefineSpaceSpecialDataAddress,
+#endif
+#if (PAD_LIST || CC_EvictControl)
+    (COMMAND_DESCRIPTOR_t *)_EvictControlDataAddress,
+#endif
+#if (PAD_LIST || CC_HierarchyControl)
+    (COMMAND_DESCRIPTOR_t *)_HierarchyControlDataAddress,
+#endif
+#if (PAD_LIST || CC_NV_UndefineSpace)
+    (COMMAND_DESCRIPTOR_t *)_NV_UndefineSpaceDataAddress,
+#endif
+#if (PAD_LIST)
+    (COMMAND_DESCRIPTOR_t *)0,
+#endif
+#if (PAD_LIST || CC_ChangeEPS)
+    (COMMAND_DESCRIPTOR_t *)_ChangeEPSDataAddress,
+#endif
+#if (PAD_LIST || CC_ChangePPS)
+    (COMMAND_DESCRIPTOR_t *)_ChangePPSDataAddress,
+#endif
+#if (PAD_LIST || CC_Clear)
+    (COMMAND_DESCRIPTOR_t *)_ClearDataAddress,
+#endif
+#if (PAD_LIST || CC_ClearControl)
+    (COMMAND_DESCRIPTOR_t *)_ClearControlDataAddress,
+#endif
+#if (PAD_LIST || CC_ClockSet)
+    (COMMAND_DESCRIPTOR_t *)_ClockSetDataAddress,
+#endif
+#if (PAD_LIST || CC_HierarchyChangeAuth)
+    (COMMAND_DESCRIPTOR_t *)_HierarchyChangeAuthDataAddress,
+#endif
+#if (PAD_LIST || CC_NV_DefineSpace)
+    (COMMAND_DESCRIPTOR_t *)_NV_DefineSpaceDataAddress,
+#endif
+#if (PAD_LIST || CC_PCR_Allocate)
+    (COMMAND_DESCRIPTOR_t *)_PCR_AllocateDataAddress,
+#endif
+#if (PAD_LIST || CC_PCR_SetAuthPolicy)
+    (COMMAND_DESCRIPTOR_t *)_PCR_SetAuthPolicyDataAddress,
+#endif
+#if (PAD_LIST || CC_PP_Commands)
+    (COMMAND_DESCRIPTOR_t *)_PP_CommandsDataAddress,
+#endif
+#if (PAD_LIST || CC_SetPrimaryPolicy)
+    (COMMAND_DESCRIPTOR_t *)_SetPrimaryPolicyDataAddress,
+#endif
+#if (PAD_LIST || CC_FieldUpgradeStart)
+    (COMMAND_DESCRIPTOR_t *)_FieldUpgradeStartDataAddress,
+#endif
+#if (PAD_LIST || CC_ClockRateAdjust)
+    (COMMAND_DESCRIPTOR_t *)_ClockRateAdjustDataAddress,
+#endif
+#if (PAD_LIST || CC_CreatePrimary)
+    (COMMAND_DESCRIPTOR_t *)_CreatePrimaryDataAddress,
+#endif
+#if (PAD_LIST || CC_NV_GlobalWriteLock)
+    (COMMAND_DESCRIPTOR_t *)_NV_GlobalWriteLockDataAddress,
+#endif
+#if (PAD_LIST || CC_GetCommandAuditDigest)
+    (COMMAND_DESCRIPTOR_t *)_GetCommandAuditDigestDataAddress,
+#endif
+#if (PAD_LIST || CC_NV_Increment)
+    (COMMAND_DESCRIPTOR_t *)_NV_IncrementDataAddress,
+#endif
+#if (PAD_LIST || CC_NV_SetBits)
+    (COMMAND_DESCRIPTOR_t *)_NV_SetBitsDataAddress,
+#endif
+#if (PAD_LIST || CC_NV_Extend)
+    (COMMAND_DESCRIPTOR_t *)_NV_ExtendDataAddress,
+#endif
+#if (PAD_LIST || CC_NV_Write)
+    (COMMAND_DESCRIPTOR_t *)_NV_WriteDataAddress,
+#endif
+#if (PAD_LIST || CC_NV_WriteLock)
+    (COMMAND_DESCRIPTOR_t *)_NV_WriteLockDataAddress,
+#endif
+#if (PAD_LIST || CC_DictionaryAttackLockReset)
+    (COMMAND_DESCRIPTOR_t *)_DictionaryAttackLockResetDataAddress,
+#endif
+#if (PAD_LIST || CC_DictionaryAttackParameters)
+    (COMMAND_DESCRIPTOR_t *)_DictionaryAttackParametersDataAddress,
+#endif
+#if (PAD_LIST || CC_NV_ChangeAuth)
+    (COMMAND_DESCRIPTOR_t *)_NV_ChangeAuthDataAddress,
+#endif
+#if (PAD_LIST || CC_PCR_Event)
+    (COMMAND_DESCRIPTOR_t *)_PCR_EventDataAddress,
+#endif
+#if (PAD_LIST || CC_PCR_Reset)
+    (COMMAND_DESCRIPTOR_t *)_PCR_ResetDataAddress,
+#endif
+#if (PAD_LIST || CC_SequenceComplete)
+    (COMMAND_DESCRIPTOR_t *)_SequenceCompleteDataAddress,
+#endif
+#if (PAD_LIST || CC_SetAlgorithmSet)
+    (COMMAND_DESCRIPTOR_t *)_SetAlgorithmSetDataAddress,
+#endif
+#if (PAD_LIST || CC_SetCommandCodeAuditStatus)
+    (COMMAND_DESCRIPTOR_t *)_SetCommandCodeAuditStatusDataAddress,
+#endif
+#if (PAD_LIST || CC_FieldUpgradeData)
+    (COMMAND_DESCRIPTOR_t *)_FieldUpgradeDataDataAddress,
+#endif
+#if (PAD_LIST || CC_IncrementalSelfTest)
+    (COMMAND_DESCRIPTOR_t *)_IncrementalSelfTestDataAddress,
+#endif
+#if (PAD_LIST || CC_SelfTest)
+    (COMMAND_DESCRIPTOR_t *)_SelfTestDataAddress,
+#endif
+#if (PAD_LIST || CC_Startup)
+    (COMMAND_DESCRIPTOR_t *)_StartupDataAddress,
+#endif
+#if (PAD_LIST || CC_Shutdown)
+    (COMMAND_DESCRIPTOR_t *)_ShutdownDataAddress,
+#endif
+#if (PAD_LIST || CC_StirRandom)
+    (COMMAND_DESCRIPTOR_t *)_StirRandomDataAddress,
+#endif
+#if (PAD_LIST || CC_ActivateCredential)
+    (COMMAND_DESCRIPTOR_t *)_ActivateCredentialDataAddress,
+#endif
+#if (PAD_LIST || CC_Certify)
+    (COMMAND_DESCRIPTOR_t *)_CertifyDataAddress,
+#endif
+#if (PAD_LIST || CC_PolicyNV)
+    (COMMAND_DESCRIPTOR_t *)_PolicyNVDataAddress,
+#endif
+#if (PAD_LIST || CC_CertifyCreation)
+    (COMMAND_DESCRIPTOR_t *)_CertifyCreationDataAddress,
+#endif
+#if (PAD_LIST || CC_Duplicate)
+    (COMMAND_DESCRIPTOR_t *)_DuplicateDataAddress,
+#endif
+#if (PAD_LIST || CC_GetTime)
+    (COMMAND_DESCRIPTOR_t *)_GetTimeDataAddress,
+#endif
+#if (PAD_LIST || CC_GetSessionAuditDigest)
+    (COMMAND_DESCRIPTOR_t *)_GetSessionAuditDigestDataAddress,
+#endif
+#if (PAD_LIST || CC_NV_Read)
+    (COMMAND_DESCRIPTOR_t *)_NV_ReadDataAddress,
+#endif
+#if (PAD_LIST || CC_NV_ReadLock)
+    (COMMAND_DESCRIPTOR_t *)_NV_ReadLockDataAddress,
+#endif
+#if (PAD_LIST || CC_ObjectChangeAuth)
+    (COMMAND_DESCRIPTOR_t *)_ObjectChangeAuthDataAddress,
+#endif
+#if (PAD_LIST || CC_PolicySecret)
+    (COMMAND_DESCRIPTOR_t *)_PolicySecretDataAddress,
+#endif
+#if (PAD_LIST || CC_Rewrap)
+    (COMMAND_DESCRIPTOR_t *)_RewrapDataAddress,
+#endif
+#if (PAD_LIST || CC_Create)
+    (COMMAND_DESCRIPTOR_t *)_CreateDataAddress,
+#endif
+#if (PAD_LIST || CC_ECDH_ZGen)
+    (COMMAND_DESCRIPTOR_t *)_ECDH_ZGenDataAddress,
+#endif
+#if (PAD_LIST || (CC_HMAC || CC_MAC))
+#    if CC_HMAC
+    (COMMAND_DESCRIPTOR_t *)_HMACDataAddress,
+#    endif
+#    if CC_MAC
+    (COMMAND_DESCRIPTOR_t *)_MACDataAddress,
+#    endif
+#    if (CC_HMAC || CC_MAC) > 1
+#        error "More than one aliased command defined"
+#    endif
+#endif // CC_HMAC CC_MAC
+#if (PAD_LIST || CC_Import)
+    (COMMAND_DESCRIPTOR_t *)_ImportDataAddress,
+#endif
+#if (PAD_LIST || CC_Load)
+    (COMMAND_DESCRIPTOR_t *)_LoadDataAddress,
+#endif
+#if (PAD_LIST || CC_Quote)
+    (COMMAND_DESCRIPTOR_t *)_QuoteDataAddress,
+#endif
+#if (PAD_LIST || CC_RSA_Decrypt)
+    (COMMAND_DESCRIPTOR_t *)_RSA_DecryptDataAddress,
+#endif
+#if (PAD_LIST)
+    (COMMAND_DESCRIPTOR_t *)0,
+#endif
+#if (PAD_LIST || (CC_HMAC_Start || CC_MAC_Start))
+#    if CC_HMAC_Start
+    (COMMAND_DESCRIPTOR_t *)_HMAC_StartDataAddress,
+#    endif
+#    if CC_MAC_Start
+    (COMMAND_DESCRIPTOR_t *)_MAC_StartDataAddress,
+#    endif
+#    if (CC_HMAC_Start || CC_MAC_Start) > 1
+#        error "More than one aliased command defined"
+#    endif
+#endif // CC_HMAC_Start CC_MAC_Start
+#if (PAD_LIST || CC_SequenceUpdate)
+    (COMMAND_DESCRIPTOR_t *)_SequenceUpdateDataAddress,
+#endif
+#if (PAD_LIST || CC_Sign)
+    (COMMAND_DESCRIPTOR_t *)_SignDataAddress,
+#endif
+#if (PAD_LIST || CC_Unseal)
+    (COMMAND_DESCRIPTOR_t *)_UnsealDataAddress,
+#endif
+#if (PAD_LIST)
+    (COMMAND_DESCRIPTOR_t *)0,
+#endif
+#if (PAD_LIST || CC_PolicySigned)
+    (COMMAND_DESCRIPTOR_t *)_PolicySignedDataAddress,
+#endif
+#if (PAD_LIST || CC_ContextLoad)
+    (COMMAND_DESCRIPTOR_t *)_ContextLoadDataAddress,
+#endif
+#if (PAD_LIST || CC_ContextSave)
+    (COMMAND_DESCRIPTOR_t *)_ContextSaveDataAddress,
+#endif
+#if (PAD_LIST || CC_ECDH_KeyGen)
+    (COMMAND_DESCRIPTOR_t *)_ECDH_KeyGenDataAddress,
+#endif
+#if (PAD_LIST || CC_EncryptDecrypt)
+    (COMMAND_DESCRIPTOR_t *)_EncryptDecryptDataAddress,
+#endif
+#if (PAD_LIST || CC_FlushContext)
+    (COMMAND_DESCRIPTOR_t *)_FlushContextDataAddress,
+#endif
+#if (PAD_LIST)
+    (COMMAND_DESCRIPTOR_t *)0,
+#endif
+#if (PAD_LIST || CC_LoadExternal)
+    (COMMAND_DESCRIPTOR_t *)_LoadExternalDataAddress,
+#endif
+#if (PAD_LIST || CC_MakeCredential)
+    (COMMAND_DESCRIPTOR_t *)_MakeCredentialDataAddress,
+#endif
+#if (PAD_LIST || CC_NV_ReadPublic)
+    (COMMAND_DESCRIPTOR_t *)_NV_ReadPublicDataAddress,
+#endif
+#if (PAD_LIST || CC_PolicyAuthorize)
+    (COMMAND_DESCRIPTOR_t *)_PolicyAuthorizeDataAddress,
+#endif
+#if (PAD_LIST || CC_PolicyAuthValue)
+    (COMMAND_DESCRIPTOR_t *)_PolicyAuthValueDataAddress,
+#endif
+#if (PAD_LIST || CC_PolicyCommandCode)
+    (COMMAND_DESCRIPTOR_t *)_PolicyCommandCodeDataAddress,
+#endif
+#if (PAD_LIST || CC_PolicyCounterTimer)
+    (COMMAND_DESCRIPTOR_t *)_PolicyCounterTimerDataAddress,
+#endif
+#if (PAD_LIST || CC_PolicyCpHash)
+    (COMMAND_DESCRIPTOR_t *)_PolicyCpHashDataAddress,
+#endif
+#if (PAD_LIST || CC_PolicyLocality)
+    (COMMAND_DESCRIPTOR_t *)_PolicyLocalityDataAddress,
+#endif
+#if (PAD_LIST || CC_PolicyNameHash)
+    (COMMAND_DESCRIPTOR_t *)_PolicyNameHashDataAddress,
+#endif
+#if (PAD_LIST || CC_PolicyOR)
+    (COMMAND_DESCRIPTOR_t *)_PolicyORDataAddress,
+#endif
+#if (PAD_LIST || CC_PolicyTicket)
+    (COMMAND_DESCRIPTOR_t *)_PolicyTicketDataAddress,
+#endif
+#if (PAD_LIST || CC_ReadPublic)
+    (COMMAND_DESCRIPTOR_t *)_ReadPublicDataAddress,
+#endif
+#if (PAD_LIST || CC_RSA_Encrypt)
+    (COMMAND_DESCRIPTOR_t *)_RSA_EncryptDataAddress,
+#endif
+#if (PAD_LIST)
+    (COMMAND_DESCRIPTOR_t *)0,
+#endif
+#if (PAD_LIST || CC_StartAuthSession)
+    (COMMAND_DESCRIPTOR_t *)_StartAuthSessionDataAddress,
+#endif
+#if (PAD_LIST || CC_VerifySignature)
+    (COMMAND_DESCRIPTOR_t *)_VerifySignatureDataAddress,
+#endif
+#if (PAD_LIST || CC_ECC_Parameters)
+    (COMMAND_DESCRIPTOR_t *)_ECC_ParametersDataAddress,
+#endif
+#if (PAD_LIST || CC_FirmwareRead)
+    (COMMAND_DESCRIPTOR_t *)_FirmwareReadDataAddress,
+#endif
+#if (PAD_LIST || CC_GetCapability)
+    (COMMAND_DESCRIPTOR_t *)_GetCapabilityDataAddress,
+#endif
+#if (PAD_LIST || CC_GetRandom)
+    (COMMAND_DESCRIPTOR_t *)_GetRandomDataAddress,
+#endif
+#if (PAD_LIST || CC_GetTestResult)
+    (COMMAND_DESCRIPTOR_t *)_GetTestResultDataAddress,
+#endif
+#if (PAD_LIST || CC_Hash)
+    (COMMAND_DESCRIPTOR_t *)_HashDataAddress,
+#endif
+#if (PAD_LIST || CC_PCR_Read)
+    (COMMAND_DESCRIPTOR_t *)_PCR_ReadDataAddress,
+#endif
+#if (PAD_LIST || CC_PolicyPCR)
+    (COMMAND_DESCRIPTOR_t *)_PolicyPCRDataAddress,
+#endif
+#if (PAD_LIST || CC_PolicyRestart)
+    (COMMAND_DESCRIPTOR_t *)_PolicyRestartDataAddress,
+#endif
+#if (PAD_LIST || CC_ReadClock)
+    (COMMAND_DESCRIPTOR_t *)_ReadClockDataAddress,
+#endif
+#if (PAD_LIST || CC_PCR_Extend)
+    (COMMAND_DESCRIPTOR_t *)_PCR_ExtendDataAddress,
+#endif
+#if (PAD_LIST || CC_PCR_SetAuthValue)
+    (COMMAND_DESCRIPTOR_t *)_PCR_SetAuthValueDataAddress,
+#endif
+#if (PAD_LIST || CC_NV_Certify)
+    (COMMAND_DESCRIPTOR_t *)_NV_CertifyDataAddress,
+#endif
+#if (PAD_LIST || CC_EventSequenceComplete)
+    (COMMAND_DESCRIPTOR_t *)_EventSequenceCompleteDataAddress,
+#endif
+#if (PAD_LIST || CC_HashSequenceStart)
+    (COMMAND_DESCRIPTOR_t *)_HashSequenceStartDataAddress,
+#endif
+#if (PAD_LIST || CC_PolicyPhysicalPresence)
+    (COMMAND_DESCRIPTOR_t *)_PolicyPhysicalPresenceDataAddress,
+#endif
+#if (PAD_LIST || CC_PolicyDuplicationSelect)
+    (COMMAND_DESCRIPTOR_t *)_PolicyDuplicationSelectDataAddress,
+#endif
+#if (PAD_LIST || CC_PolicyGetDigest)
+    (COMMAND_DESCRIPTOR_t *)_PolicyGetDigestDataAddress,
+#endif
+#if (PAD_LIST || CC_TestParms)
+    (COMMAND_DESCRIPTOR_t *)_TestParmsDataAddress,
+#endif
+#if (PAD_LIST || CC_Commit)
+    (COMMAND_DESCRIPTOR_t *)_CommitDataAddress,
+#endif
+#if (PAD_LIST || CC_PolicyPassword)
+    (COMMAND_DESCRIPTOR_t *)_PolicyPasswordDataAddress,
+#endif
+#if (PAD_LIST || CC_ZGen_2Phase)
+    (COMMAND_DESCRIPTOR_t *)_ZGen_2PhaseDataAddress,
+#endif
+#if (PAD_LIST || CC_EC_Ephemeral)
+    (COMMAND_DESCRIPTOR_t *)_EC_EphemeralDataAddress,
+#endif
+#if (PAD_LIST || CC_PolicyNvWritten)
+    (COMMAND_DESCRIPTOR_t *)_PolicyNvWrittenDataAddress,
+#endif
+#if (PAD_LIST || CC_PolicyTemplate)
+    (COMMAND_DESCRIPTOR_t *)_PolicyTemplateDataAddress,
+#endif
+#if (PAD_LIST || CC_CreateLoaded)
+    (COMMAND_DESCRIPTOR_t *)_CreateLoadedDataAddress,
+#endif
+#if (PAD_LIST || CC_PolicyAuthorizeNV)
+    (COMMAND_DESCRIPTOR_t *)_PolicyAuthorizeNVDataAddress,
+#endif
+#if (PAD_LIST || CC_EncryptDecrypt2)
+    (COMMAND_DESCRIPTOR_t *)_EncryptDecrypt2DataAddress,
+#endif
+#if (PAD_LIST || CC_AC_GetCapability)
+    (COMMAND_DESCRIPTOR_t *)_AC_GetCapabilityDataAddress,
+#endif // CC_AC_GetCapability
+#if (PAD_LIST || CC_AC_Send)
+    (COMMAND_DESCRIPTOR_t *)_AC_SendDataAddress,
+#endif // CC_AC_Send
+#if (PAD_LIST || CC_Policy_AC_SendSelect)
+    (COMMAND_DESCRIPTOR_t *)_Policy_AC_SendSelectDataAddress,
+#endif // CC_Policy_AC_SendSelect
+#if (PAD_LIST || CC_CertifyX509)
+    (COMMAND_DESCRIPTOR_t *)_CertifyX509DataAddress,
+#endif // CC_CertifyX509
+#if (PAD_LIST || CC_ACT_SetTimeout)
+    (COMMAND_DESCRIPTOR_t *)_ACT_SetTimeoutDataAddress,
+#endif // CC_ACT_SetTimeout
+#if (PAD_LIST || CC_ECC_Encrypt)
+    (COMMAND_DESCRIPTOR_t *)_ECC_EncryptDataAddress,
+#endif // CC_ECC_Encrypt
+#if (PAD_LIST || CC_ECC_Decrypt)
+    (COMMAND_DESCRIPTOR_t *)_ECC_DecryptDataAddress,
+#endif // CC_ECC_Decrypt
+#if (PAD_LIST || CC_Vendor_TCG_Test)
+    (COMMAND_DESCRIPTOR_t *)_Vendor_TCG_TestDataAddress,
+#endif
+#ifdef TPM_NUVOTON
+#if (PAD_LIST || TPM_NUVOTON)
+    (COMMAND_DESCRIPTOR_t *)_NTC2_PreConfigDataAddress,
+    (COMMAND_DESCRIPTOR_t *)_NTC2_LockPreConfigDataAddress,
+    (COMMAND_DESCRIPTOR_t *)_NTC2_GetConfigDataAddress,
+#endif
+#endif    
+    0
+};
+
+#endif  // _COMMAND_TABLE_DISPATCH_

+ 409 - 0
EVSE/GPL/ibmtpm1682/src/CommandDispatcher.c

@@ -0,0 +1,409 @@
+/********************************************************************************/
+/*										*/
+/*			   Command Dispatcher	  				*/
+/*			     Written by Ken Goldman				*/
+/*		       IBM Thomas J. Watson Research Center			*/
+/*            $Id: CommandDispatcher.c 1658 2021-01-22 23:14:01Z kgoldman $	*/
+/*										*/
+/*  Licenses and Notices							*/
+/*										*/
+/*  1. Copyright Licenses:							*/
+/*										*/
+/*  - Trusted Computing Group (TCG) grants to the user of the source code in	*/
+/*    this specification (the "Source Code") a worldwide, irrevocable, 		*/
+/*    nonexclusive, royalty free, copyright license to reproduce, create 	*/
+/*    derivative works, distribute, display and perform the Source Code and	*/
+/*    derivative works thereof, and to grant others the rights granted herein.	*/
+/*										*/
+/*  - The TCG grants to the user of the other parts of the specification 	*/
+/*    (other than the Source Code) the rights to reproduce, distribute, 	*/
+/*    display, and perform the specification solely for the purpose of 		*/
+/*    developing products based on such documents.				*/
+/*										*/
+/*  2. Source Code Distribution Conditions:					*/
+/*										*/
+/*  - Redistributions of Source Code must retain the above copyright licenses, 	*/
+/*    this list of conditions and the following disclaimers.			*/
+/*										*/
+/*  - Redistributions in binary form must reproduce the above copyright 	*/
+/*    licenses, this list of conditions	and the following disclaimers in the 	*/
+/*    documentation and/or other materials provided with the distribution.	*/
+/*										*/
+/*  3. Disclaimers:								*/
+/*										*/
+/*  - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF	*/
+/*  LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH	*/
+/*  RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES)	*/
+/*  THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE.		*/
+/*  Contact TCG Administration (admin@trustedcomputinggroup.org) for 		*/
+/*  information on specification licensing rights available through TCG 	*/
+/*  membership agreements.							*/
+/*										*/
+/*  - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED 	*/
+/*    WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR 	*/
+/*    FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR 		*/
+/*    NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY 		*/
+/*    OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE.		*/
+/*										*/
+/*  - Without limitation, TCG and its members and licensors disclaim all 	*/
+/*    liability, including liability for infringement of any proprietary 	*/
+/*    rights, relating to use of information in this specification and to the	*/
+/*    implementation of this specification, and TCG disclaims all liability for	*/
+/*    cost of procurement of substitute goods or services, lost profits, loss 	*/
+/*    of use, loss of data or any incidental, consequential, direct, indirect, 	*/
+/*    or special damages, whether under contract, tort, warranty or otherwise, 	*/
+/*    arising in any way out of use or reliance upon this specification or any 	*/
+/*    information herein.							*/
+/*										*/
+/*  (c) Copyright IBM Corp. and others, 2016 - 2021				*/
+/*										*/
+/********************************************************************************/
+
+/* 6.3 CommandDispatcher.c */
+/* CommandDispatcher() performs the following operations: */
+/* *	unmarshals command parameters from the input buffer; */
+/* NOTE Unlike other unmarshaling functions, parmBufferStart does not advance.  parmBufferSize Is
+   reduced.  */
+/* *	invokes the function that performs the command actions; */
+/* *	marshals the returned handles, if any; and */
+/* *	marshals the returned parameters, if any, into the output buffer putting in the
+   *	parameterSize field if authorization sessions are present. */
+/* NOTE 1 The output buffer is the return from the MemoryGetResponseBuffer() function.  It includes
+   the header, handles, response parameters, and authorization area. respParmSize is the response
+   parameter size, and does not include the header, handles, or authorization area. */
+/* NOTE 2 The reference implementation is permitted to do compare operations over a union as a byte
+   array.  Therefore, the command parameter in structure must be initialized (e.g., zeroed) before
+   unmarshaling so that the compare operation is valid in cases where some bytes are unused. */
+/* 6.3.1.1 Includes and Typedefs */
+#include "Tpm.h"
+// #include "Marshal.h" kgold
+
+#if TABLE_DRIVEN_DISPATCH
+typedef TPM_RC(NoFlagFunction)(void *target, BYTE **buffer, INT32 *size);
+typedef TPM_RC(FlagFunction)(void *target, BYTE **buffer, INT32 *size, BOOL flag);
+typedef FlagFunction *UNMARSHAL_t;
+typedef INT16(MarshalFunction)(void *source, BYTE **buffer, INT32 *size);
+typedef MarshalFunction *MARSHAL_t;
+typedef TPM_RC(COMMAND_NO_ARGS)(void);
+typedef TPM_RC(COMMAND_IN_ARG)(void *in);
+typedef TPM_RC(COMMAND_OUT_ARG)(void *out);
+typedef TPM_RC(COMMAND_INOUT_ARG)(void *in, void *out);
+typedef union
+{
+    COMMAND_NO_ARGS         *noArgs;
+    COMMAND_IN_ARG          *inArg;
+    COMMAND_OUT_ARG         *outArg;
+    COMMAND_INOUT_ARG       *inOutArg;
+} COMMAND_t;
+typedef struct
+{
+    COMMAND_t       command;        // Address of the command
+    UINT16          inSize;         // Maximum size of the input structure
+    UINT16          outSize;        // Maximum size of the output structure
+    UINT16          typesOffset;    // address of the types field
+    UINT16          offsets[1];
+} COMMAND_DESCRIPTOR_t;
+#if COMPRESSED_LISTS
+#   define PAD_LIST 0
+#else
+#   define PAD_LIST 1
+#endif
+#define _COMMAND_TABLE_DISPATCH_
+#include "CommandDispatchData.h"
+#define TEST_COMMAND    TPM_CC_Startup
+#define NEW_CC
+#else
+#include "Commands.h"
+#endif
+
+/* 6.3.1.2   Marshal/Unmarshal Functions */
+/* 6.3.1.2.1 ParseHandleBuffer() */
+/* This is the table-driven version of the handle buffer unmarshaling code */
+
+TPM_RC
+ParseHandleBuffer(
+		  COMMAND                 *command
+		  )
+{
+    TPM_RC                   result;
+#if TABLE_DRIVEN_DISPATCH
+    COMMAND_DESCRIPTOR_t    *desc;
+    BYTE                    *types;
+    BYTE                     type;
+    BYTE                     dType;
+    // Make sure that nothing strange has happened
+    pAssert(command->index
+	    < sizeof(s_CommandDataArray) / sizeof(COMMAND_DESCRIPTOR_t *));
+    // Get the address of the descriptor for this command
+    desc = s_CommandDataArray[command->index];
+    pAssert(desc != NULL);
+    // Get the associated list of unmarshaling data types.
+    types = &((BYTE *)desc)[desc->typesOffset];
+    //    if(s_ccAttr[commandIndex].commandIndex == TEST_COMMAND)
+    //        commandIndex = commandIndex;
+    // No handles yet
+    command->handleNum = 0;
+    // Get the first type value
+    for(type = *types++;
+	// check each byte to make sure that we have not hit the start
+	// of the parameters
+	(dType = (type & 0x7F)) < PARAMETER_FIRST_TYPE;
+	// get the next type
+	type = *types++)
+	{
+#if TABLE_DRIVEN_MARSHAL
+	marshalIndex_t      index;
+    index = unmarshalArray[dType] | ((type & 0x80) ? NULL_FLAG : 0);
+    result = Unmarshal(index, &(command->handles[command->handleNum]),
+		       &command->parameterBuffer, &command->parameterSize);
+    
+#else
+
+	    // See if unmarshaling of this handle type requires a flag
+	    if(dType < HANDLE_FIRST_FLAG_TYPE)
+		{
+		    // Look up the function to do the unmarshaling
+		    NoFlagFunction  *f = (NoFlagFunction *)unmarshalArray[dType];
+		    // call it
+		    result = f(&(command->handles[command->handleNum]),
+			       &command->parameterBuffer,
+			       &command->parameterSize);
+		}
+	    else
+		{
+		    //  Look up the function
+		    FlagFunction    *f = unmarshalArray[dType];
+		    // Call it setting the flag to the appropriate value
+		    result = f(&(command->handles[command->handleNum]),
+			       &command->parameterBuffer,
+			       &command->parameterSize, (type & 0x80) != 0);
+		}
+#endif
+	    // Got a handle
+	    // We do this first so that the match for the handle offset of the
+	    // response code works correctly.
+	    command->handleNum += 1;
+	    if(result != TPM_RC_SUCCESS)
+		// if the unmarshaling failed, return the response code with the
+		// handle indication set
+		return result + TPM_RC_H + (command->handleNum * TPM_RC_1);
+	}
+#else
+    BYTE            **handleBufferStart = &command->parameterBuffer;
+    INT32           *bufferRemainingSize = &command->parameterSize;
+    TPM_HANDLE      *handles = &command->handles[0];
+    UINT32          *handleCount = &command->handleNum;
+    *handleCount = 0;
+    switch(command->code)
+	{
+#include "HandleProcess.h"
+#undef handles
+	  default:
+	    FAIL(FATAL_ERROR_INTERNAL);
+	    break;
+	}
+#endif
+    return TPM_RC_SUCCESS;
+}
+
+/* 6.3.1.2.2	CommandDispatcher() */
+/* Function to unmarshal the command parameters, call the selected action code, and marshal the
+   response parameters. */
+
+TPM_RC
+CommandDispatcher(
+		  COMMAND                 *command
+		  )
+{
+#if !TABLE_DRIVEN_DISPATCH
+    TPM_RC       result;
+    BYTE        **paramBuffer = &command->parameterBuffer;
+    INT32       *paramBufferSize = &command->parameterSize;
+    BYTE        **responseBuffer = &command->responseBuffer;
+    INT32       *respParmSize = &command->parameterSize;
+    INT32        rSize;
+    TPM_HANDLE  *handles = &command->handles[0];
+
+    command->handleNum = 0;	/* The command-specific code knows how many handles there are. This
+				   is for cataloging the number of response handles */
+    MemoryIoBufferAllocationReset();        /* Initialize so that allocation will work properly */
+    switch(GetCommandCode(command->index))
+	{
+#include "CommandDispatcher.h"
+	  default:
+	    FAIL(FATAL_ERROR_INTERNAL);
+	    break;
+	}
+ Exit:
+    MemoryIoBufferZero();
+    return result;
+#else
+    COMMAND_DESCRIPTOR_t    *desc;
+    BYTE                    *types;
+    BYTE                     type;
+    UINT16                  *offsets;
+    UINT16                   offset = 0;
+    UINT32                   maxInSize;
+    BYTE                    *commandIn;
+    INT32                    maxOutSize;
+    BYTE                    *commandOut;
+    COMMAND_t                cmd;
+    TPM_HANDLE              *handles;
+    UINT32                   hasInParameters = 0;
+    BOOL                     hasOutParameters = FALSE;
+    UINT32                   pNum = 0;
+    BYTE                     dType;     // dispatch type
+    TPM_RC                   result;
+    //
+    // Get the address of the descriptor for this command
+    pAssert(command->index
+	    < sizeof(s_CommandDataArray) / sizeof(COMMAND_DESCRIPTOR_t *));
+    desc = s_CommandDataArray[command->index];
+    // Get the list of parameter types for this command
+    pAssert(desc != NULL);
+    types = &((BYTE *)desc)[desc->typesOffset];
+    // Get a pointer to the list of parameter offsets
+    offsets = &desc->offsets[0];
+    // pointer to handles
+    handles = command->handles;
+    // Get the size required to hold all the unmarshaled parameters for this command
+    maxInSize = desc->inSize;
+    // and the size of the output parameter structure returned by this command
+    maxOutSize = desc->outSize;
+    MemoryIoBufferAllocationReset();
+    // Get a buffer for the input parameters
+    commandIn = MemoryGetInBuffer(maxInSize);
+    // And the output parameters
+    commandOut = (BYTE *)MemoryGetOutBuffer((UINT32)maxOutSize);
+    // Get the address of the action code dispatch
+    cmd = desc->command;
+    // Copy any handles into the input buffer
+    for(type = *types++; (type & 0x7F) < PARAMETER_FIRST_TYPE; type = *types++)
+	{
+	    // 'offset' was initialized to zero so the first unmarshaling will always
+	    // be to the start of the data structure
+	    *(TPM_HANDLE *)&(commandIn[offset]) = *handles++;
+	    // This check is used so that we don't have to add an additional offset
+	    // value to the offsets list to correspond to the stop value in the
+	    // command parameter list.
+	    if(*types != 0xFF)
+		offset = *offsets++;
+	    //        maxInSize -= sizeof(TPM_HANDLE);
+	    hasInParameters++;
+	}
+    // Exit loop with type containing the last value read from types
+    // maxInSize has the amount of space remaining in the command action input
+    // buffer. Make sure that we don't have more data to unmarshal than is going to
+    // fit.
+    // type contains the last value read from types so it is not necessary to
+    // reload it, which is good because *types now points to the next value
+    for(; (dType = (type & 0x7F)) <= PARAMETER_LAST_TYPE; type = *types++)
+	{
+	    pNum++;
+#if TABLE_DRIVEN_MARSHAL
+	    {
+		marshalIndex_t      index = unmarshalArray[dType];
+		index |= (type & 0x80) ? NULL_FLAG : 0;
+		result = Unmarshal(index, &commandIn[offset], &command->parameterBuffer,
+				   &command->parameterSize);
+	    }
+#else
+	    if(dType < PARAMETER_FIRST_FLAG_TYPE)
+		{
+		    NoFlagFunction      *f = (NoFlagFunction *)unmarshalArray[dType];
+		    result = f(&commandIn[offset], &command->parameterBuffer,
+			       &command->parameterSize);
+		}
+	    else
+		{
+		    FlagFunction        *f = unmarshalArray[dType];
+		    result = f(&commandIn[offset], &command->parameterBuffer,
+			       &command->parameterSize,
+			       (type & 0x80) != 0);
+		}
+#endif
+	    if(result != TPM_RC_SUCCESS)
+		{
+		    result += TPM_RC_P + (TPM_RC_1 * pNum);
+		    goto Exit;
+		}
+	    // This check is used so that we don't have to add an additional offset
+	    // value to the offsets list to correspond to the stop value in the
+	    // command parameter list.
+	    if(*types != 0xFF)
+		offset = *offsets++;
+	    hasInParameters++;
+	}
+    // Should have used all the bytes in the input
+    if(command->parameterSize != 0)
+	{
+	    result = TPM_RC_SIZE;
+	    goto Exit;
+	}
+    // The command parameter unmarshaling stopped when it hit a value that was out
+    // of range for unmarshaling values and left *types pointing to the first
+    // marshaling type. If that type happens to be the STOP value, then there
+    // are no response parameters. So, set the flag to indicate if there are
+    // output parameters.
+    hasOutParameters = *types != 0xFF;
+    // There are four cases for calling, with and without input parameters and with
+    // and without output parameters.
+    if(hasInParameters > 0)
+	{
+	    if(hasOutParameters)
+		result = cmd.inOutArg(commandIn, commandOut);
+	    else
+		result = cmd.inArg(commandIn);
+	}
+    else
+	{
+	    if(hasOutParameters)
+		result = cmd.outArg(commandOut);
+	    else
+		result = cmd.noArgs();
+	}
+    if(result != TPM_RC_SUCCESS)
+	goto Exit;
+    // Offset in the marshaled output structure
+    offset = 0;
+    // Process the return handles, if any
+    command->handleNum = 0;
+    // Could make this a loop to process output handles but there is only ever
+    // one handle in the outputs (for now).
+    type = *types++;
+    if((dType = (type & 0x7F)) < RESPONSE_PARAMETER_FIRST_TYPE)
+	{
+	    // The out->handle value was referenced as TPM_HANDLE in the
+	    // action code so it has to be properly aligned.
+	    command->handles[command->handleNum++] =
+		*((TPM_HANDLE *)&(commandOut[offset]));
+	    maxOutSize -= sizeof(UINT32);
+	    type = *types++;
+	    offset = *offsets++;
+	}
+    // Use the size of the command action output buffer as the maximum for the
+    // number of bytes that can get marshaled. Since the marshaling code has
+    // no pointers to data, all of the data being returned has to be in the
+    // command action output buffer. If we try to marshal more bytes than
+    // could fit into the output buffer, we need to fail.
+    for(;(dType = (type & 0x7F)) <= RESPONSE_PARAMETER_LAST_TYPE
+	    && !g_inFailureMode; type = *types++)
+	{
+#if TABLE_DRIVEN_MARSHAL
+	    marshalIndex_t      index = marshalArray[dType];
+	    command->parameterSize += Marshal(index, &commandOut[offset],
+					      &command->responseBuffer,
+					      &maxOutSize);
+#else
+	    const MARSHAL_t     f = marshalArray[dType];
+	    command->parameterSize += f(&commandOut[offset], &command->responseBuffer,
+					&maxOutSize);
+#endif
+	    offset = *offsets++;
+	}
+    result = (maxOutSize < 0) ? TPM_RC_FAILURE : TPM_RC_SUCCESS;
+ Exit:
+    MemoryIoBufferZero();
+    return result;
+#endif
+}

+ 75 - 0
EVSE/GPL/ibmtpm1682/src/CommandDispatcher_fp.h

@@ -0,0 +1,75 @@
+/********************************************************************************/
+/*										*/
+/*			     				*/
+/*			     Written by Ken Goldman				*/
+/*		       IBM Thomas J. Watson Research Center			*/
+/*            $Id: CommandDispatcher_fp.h 1490 2019-07-26 21:13:22Z kgoldman $			*/
+/*										*/
+/*  Licenses and Notices							*/
+/*										*/
+/*  1. Copyright Licenses:							*/
+/*										*/
+/*  - Trusted Computing Group (TCG) grants to the user of the source code in	*/
+/*    this specification (the "Source Code") a worldwide, irrevocable, 		*/
+/*    nonexclusive, royalty free, copyright license to reproduce, create 	*/
+/*    derivative works, distribute, display and perform the Source Code and	*/
+/*    derivative works thereof, and to grant others the rights granted herein.	*/
+/*										*/
+/*  - The TCG grants to the user of the other parts of the specification 	*/
+/*    (other than the Source Code) the rights to reproduce, distribute, 	*/
+/*    display, and perform the specification solely for the purpose of 		*/
+/*    developing products based on such documents.				*/
+/*										*/
+/*  2. Source Code Distribution Conditions:					*/
+/*										*/
+/*  - Redistributions of Source Code must retain the above copyright licenses, 	*/
+/*    this list of conditions and the following disclaimers.			*/
+/*										*/
+/*  - Redistributions in binary form must reproduce the above copyright 	*/
+/*    licenses, this list of conditions	and the following disclaimers in the 	*/
+/*    documentation and/or other materials provided with the distribution.	*/
+/*										*/
+/*  3. Disclaimers:								*/
+/*										*/
+/*  - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF	*/
+/*  LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH	*/
+/*  RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES)	*/
+/*  THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE.		*/
+/*  Contact TCG Administration (admin@trustedcomputinggroup.org) for 		*/
+/*  information on specification licensing rights available through TCG 	*/
+/*  membership agreements.							*/
+/*										*/
+/*  - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED 	*/
+/*    WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR 	*/
+/*    FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR 		*/
+/*    NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY 		*/
+/*    OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE.		*/
+/*										*/
+/*  - Without limitation, TCG and its members and licensors disclaim all 	*/
+/*    liability, including liability for infringement of any proprietary 	*/
+/*    rights, relating to use of information in this specification and to the	*/
+/*    implementation of this specification, and TCG disclaims all liability for	*/
+/*    cost of procurement of substitute goods or services, lost profits, loss 	*/
+/*    of use, loss of data or any incidental, consequential, direct, indirect, 	*/
+/*    or special damages, whether under contract, tort, warranty or otherwise, 	*/
+/*    arising in any way out of use or reliance upon this specification or any 	*/
+/*    information herein.							*/
+/*										*/
+/*  (c) Copyright IBM Corp. and others, 2016					*/
+/*										*/
+/********************************************************************************/
+
+#ifndef COMMANDDISPATCHER_FP_H
+#define COMMANDDISPATCHER_FP_H
+
+TPM_RC
+CommandDispatcher(
+		  COMMAND                 *command
+		  );
+TPM_RC
+ParseHandleBuffer(
+		  COMMAND                 *command
+		  );
+
+
+#endif

+ 468 - 0
EVSE/GPL/ibmtpm1682/src/Commands.h

@@ -0,0 +1,468 @@
+/********************************************************************************/
+/*										*/
+/*			  Command Header Includes   				*/
+/*			     Written by Ken Goldman				*/
+/*		       IBM Thomas J. Watson Research Center			*/
+/*            $Id: Commands.h 1594 2020-03-26 22:15:48Z kgoldman $		*/
+/*										*/
+/*  Licenses and Notices							*/
+/*										*/
+/*  1. Copyright Licenses:							*/
+/*										*/
+/*  - Trusted Computing Group (TCG) grants to the user of the source code in	*/
+/*    this specification (the "Source Code") a worldwide, irrevocable, 		*/
+/*    nonexclusive, royalty free, copyright license to reproduce, create 	*/
+/*    derivative works, distribute, display and perform the Source Code and	*/
+/*    derivative works thereof, and to grant others the rights granted herein.	*/
+/*										*/
+/*  - The TCG grants to the user of the other parts of the specification 	*/
+/*    (other than the Source Code) the rights to reproduce, distribute, 	*/
+/*    display, and perform the specification solely for the purpose of 		*/
+/*    developing products based on such documents.				*/
+/*										*/
+/*  2. Source Code Distribution Conditions:					*/
+/*										*/
+/*  - Redistributions of Source Code must retain the above copyright licenses, 	*/
+/*    this list of conditions and the following disclaimers.			*/
+/*										*/
+/*  - Redistributions in binary form must reproduce the above copyright 	*/
+/*    licenses, this list of conditions	and the following disclaimers in the 	*/
+/*    documentation and/or other materials provided with the distribution.	*/
+/*										*/
+/*  3. Disclaimers:								*/
+/*										*/
+/*  - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF	*/
+/*  LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH	*/
+/*  RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES)	*/
+/*  THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE.		*/
+/*  Contact TCG Administration (admin@trustedcomputinggroup.org) for 		*/
+/*  information on specification licensing rights available through TCG 	*/
+/*  membership agreements.							*/
+/*										*/
+/*  - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED 	*/
+/*    WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR 	*/
+/*    FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR 		*/
+/*    NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY 		*/
+/*    OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE.		*/
+/*										*/
+/*  - Without limitation, TCG and its members and licensors disclaim all 	*/
+/*    liability, including liability for infringement of any proprietary 	*/
+/*    rights, relating to use of information in this specification and to the	*/
+/*    implementation of this specification, and TCG disclaims all liability for	*/
+/*    cost of procurement of substitute goods or services, lost profits, loss 	*/
+/*    of use, loss of data or any incidental, consequential, direct, indirect, 	*/
+/*    or special damages, whether under contract, tort, warranty or otherwise, 	*/
+/*    arising in any way out of use or reliance upon this specification or any 	*/
+/*    information herein.							*/
+/*										*/
+/*  (c) Copyright IBM Corp. and others, 2016 - 2020				*/
+/*										*/
+/********************************************************************************/
+
+#ifndef COMMANDS_H
+#define COMMANDS_H
+
+#if CC_Startup
+#include "Startup_fp.h"
+#endif
+#if CC_Shutdown
+#include "Shutdown_fp.h"
+#endif
+/* Testing */
+#if CC_SelfTest
+#include "SelfTest_fp.h"
+#endif
+#if CC_IncrementalSelfTest
+#include "IncrementalSelfTest_fp.h"
+#endif
+#if CC_GetTestResult
+#include "GetTestResult_fp.h"
+#endif
+/* Session Commands */
+#if CC_StartAuthSession
+#include "StartAuthSession_fp.h"
+#endif
+#if CC_PolicyRestart
+#include "PolicyRestart_fp.h"
+#endif
+/* Object Commands */
+#if CC_Create
+#include "Create_fp.h"
+#endif
+#if CC_Load
+#include "Load_fp.h"
+#endif
+#if CC_LoadExternal
+#include "LoadExternal_fp.h"
+#endif
+#if CC_ReadPublic
+#include "ReadPublic_fp.h"
+#endif
+#if CC_ActivateCredential
+#include "ActivateCredential_fp.h"
+#endif
+#if CC_MakeCredential
+#include "MakeCredential_fp.h"
+#endif
+#if CC_Unseal
+#include "Unseal_fp.h"
+#endif
+#if CC_ObjectChangeAuth
+#include "ObjectChangeAuth_fp.h"
+#endif
+#if CC_CreateLoaded
+#include "CreateLoaded_fp.h"
+#endif
+/* Duplication Commands */
+#if CC_Duplicate
+#include "Duplicate_fp.h"
+#endif
+#if CC_Rewrap
+#include "Rewrap_fp.h"
+#endif
+#if CC_Import
+#include "Import_fp.h"
+#endif
+/* Asymmetric Primitives */
+#if CC_RSA_Encrypt
+#include "RSA_Encrypt_fp.h"
+#endif
+#if CC_RSA_Decrypt
+#include "RSA_Decrypt_fp.h"
+#endif
+#if CC_ECDH_KeyGen
+#include "ECDH_KeyGen_fp.h"
+#endif
+#if CC_ECDH_ZGen
+#include "ECDH_ZGen_fp.h"
+#endif
+#if CC_ECC_Parameters
+#include "ECC_Parameters_fp.h"
+#endif
+#if CC_ZGen_2Phase
+#include "ZGen_2Phase_fp.h"
+#endif
+#if CC_ECC_Encrypt
+#include "ECC_Encrypt_fp.h"
+#endif
+#if CC_ECC_Decrypt
+#include "ECC_Decrypt_fp.h"
+#endif
+/* Symmetric Primitives */
+#if CC_EncryptDecrypt
+#include "EncryptDecrypt_fp.h"
+#endif
+#if CC_EncryptDecrypt2
+#include "EncryptDecrypt2_fp.h"
+#endif
+#if CC_Hash
+#include "Hash_fp.h"
+#endif
+#if CC_HMAC
+#include "HMAC_fp.h"
+#endif
+#if CC_MAC
+#include "MAC_fp.h"
+#endif
+/* Random Number Generator */
+#if CC_GetRandom
+#include "GetRandom_fp.h"
+#endif
+#if CC_StirRandom
+#include "StirRandom_fp.h"
+#endif
+/* Hash/HMAC/Event Sequences */
+#if CC_HMAC_Start
+#include "HMAC_Start_fp.h"
+#endif
+#if CC_MAC_Start
+#include "MAC_Start_fp.h"
+#endif
+#if CC_HashSequenceStart
+#include "HashSequenceStart_fp.h"
+#endif
+#if CC_SequenceUpdate
+#include "SequenceUpdate_fp.h"
+#endif
+#if CC_SequenceComplete
+#include "SequenceComplete_fp.h"
+#endif
+#if CC_EventSequenceComplete
+#include "EventSequenceComplete_fp.h"
+#endif
+/* Attestation Commands */
+#if CC_Certify
+#include "Certify_fp.h"
+#endif
+#if CC_CertifyCreation
+#include "CertifyCreation_fp.h"
+#endif
+#if CC_CertifyX509
+#include "CertifyX509_fp.h"
+#endif
+#if CC_Quote
+#include "Quote_fp.h"
+#endif
+#if CC_GetSessionAuditDigest
+#include "GetSessionAuditDigest_fp.h"
+#endif
+#if CC_GetCommandAuditDigest
+#include "GetCommandAuditDigest_fp.h"
+#endif
+#if CC_GetTime
+#include "GetTime_fp.h"
+#endif
+#ifdef TPM_CC_CertifyX509
+#include "CertifyX509_fp.h"
+#endif
+/* Ephemeral EC Keys */
+#if CC_Commit
+#include "Commit_fp.h"
+#endif
+#if CC_EC_Ephemeral
+#include "EC_Ephemeral_fp.h"
+#endif
+/* Signing and Signature Verification */
+#if CC_VerifySignature
+#include "VerifySignature_fp.h"
+#endif
+#if CC_Sign
+#include "Sign_fp.h"
+#endif
+/* Command Audit */
+#if CC_SetCommandCodeAuditStatus
+#include "SetCommandCodeAuditStatus_fp.h"
+#endif
+/* Integrity Collection (PCR) */
+#if CC_PCR_Extend
+#include "PCR_Extend_fp.h"
+#endif
+#if CC_PCR_Event
+#include "PCR_Event_fp.h"
+#endif
+#if CC_PCR_Read
+#include "PCR_Read_fp.h"
+#endif
+#if CC_PCR_Allocate
+#include "PCR_Allocate_fp.h"
+#endif
+#if CC_PCR_SetAuthPolicy
+#include "PCR_SetAuthPolicy_fp.h"
+#endif
+#if CC_PCR_SetAuthValue
+#include "PCR_SetAuthValue_fp.h"
+#endif
+#if CC_PCR_Reset
+#include "PCR_Reset_fp.h"
+#endif
+/* Enhanced Authorization (EA) Commands */
+#if CC_PolicySigned
+#include "PolicySigned_fp.h"
+#endif
+#if CC_PolicySecret
+#include "PolicySecret_fp.h"
+#endif
+#if CC_PolicyTicket
+#include "PolicyTicket_fp.h"
+#endif
+#if CC_PolicyOR
+#include "PolicyOR_fp.h"
+#endif
+#if CC_PolicyPCR
+#include "PolicyPCR_fp.h"
+#endif
+#if CC_PolicyLocality
+#include "PolicyLocality_fp.h"
+#endif
+#if CC_PolicyNV
+#include "PolicyNV_fp.h"
+#endif
+#if CC_PolicyCounterTimer
+#include "PolicyCounterTimer_fp.h"
+#endif
+#if CC_PolicyCommandCode
+#include "PolicyCommandCode_fp.h"
+#endif
+#if CC_PolicyPhysicalPresence
+#include "PolicyPhysicalPresence_fp.h"
+#endif
+#if CC_PolicyCpHash
+#include "PolicyCpHash_fp.h"
+#endif
+#if CC_PolicyNameHash
+#include "PolicyNameHash_fp.h"
+#endif
+#if CC_PolicyDuplicationSelect
+#include "PolicyDuplicationSelect_fp.h"
+#endif
+#if CC_PolicyAuthorize
+#include "PolicyAuthorize_fp.h"
+#endif
+#if CC_PolicyAuthValue
+#include "PolicyAuthValue_fp.h"
+#endif
+#if CC_PolicyPassword
+#include "PolicyPassword_fp.h"
+#endif
+#if CC_PolicyGetDigest
+#include "PolicyGetDigest_fp.h"
+#endif
+#if CC_PolicyNvWritten
+#include "PolicyNvWritten_fp.h"
+#endif
+#if CC_PolicyTemplate
+#include "PolicyTemplate_fp.h"
+#endif
+#if CC_PolicyAuthorizeNV
+#include "PolicyAuthorizeNV_fp.h"
+#endif
+/* Hierarchy Commands */
+#if CC_CreatePrimary
+#include "CreatePrimary_fp.h"
+#endif
+#if CC_HierarchyControl
+#include "HierarchyControl_fp.h"
+#endif
+#if CC_SetPrimaryPolicy
+#include "SetPrimaryPolicy_fp.h"
+#endif
+#if CC_ChangePPS
+#include "ChangePPS_fp.h"
+#endif
+#if CC_ChangeEPS
+#include "ChangeEPS_fp.h"
+#endif
+#if CC_Clear
+#include "Clear_fp.h"
+#endif
+#if CC_ClearControl
+#include "ClearControl_fp.h"
+#endif
+#if CC_HierarchyChangeAuth
+#include "HierarchyChangeAuth_fp.h"
+#endif
+/* Dictionary Attack Functions */
+#if CC_DictionaryAttackLockReset
+#include "DictionaryAttackLockReset_fp.h"
+#endif
+#if CC_DictionaryAttackParameters
+#include "DictionaryAttackParameters_fp.h"
+#endif
+/* Miscellaneous Management Functions */
+#if CC_PP_Commands
+#include "PP_Commands_fp.h"
+#endif
+#if CC_SetAlgorithmSet
+#include "SetAlgorithmSet_fp.h"
+#endif
+/* Field Upgrade */
+#if CC_FieldUpgradeStart
+#include "FieldUpgradeStart_fp.h"
+#endif
+#if CC_FieldUpgradeData
+#include "FieldUpgradeData_fp.h"
+#endif
+#if CC_FirmwareRead
+#include "FirmwareRead_fp.h"
+#endif
+/* Context Management */
+#if CC_ContextSave
+#include "ContextSave_fp.h"
+#endif
+#if CC_ContextLoad
+#include "ContextLoad_fp.h"
+#endif
+#if CC_FlushContext
+#include "FlushContext_fp.h"
+#endif
+#if CC_EvictControl
+#include "EvictControl_fp.h"
+#endif
+/* Clocks and Timers */
+#if CC_ReadClock
+#include "ReadClock_fp.h"
+#endif
+#if CC_ClockSet
+#include "ClockSet_fp.h"
+#endif
+#if CC_ClockRateAdjust
+#include "ClockRateAdjust_fp.h"
+#endif
+/* Capability Commands */
+#if CC_GetCapability
+#include "GetCapability_fp.h"
+#endif
+#if CC_TestParms
+#include "TestParms_fp.h"
+#endif
+#if CC_NV_DefineSpace
+#include "NV_DefineSpace_fp.h"
+#endif
+#if CC_NV_UndefineSpace
+#include "NV_UndefineSpace_fp.h"
+#endif
+#if CC_NV_UndefineSpaceSpecial
+#include "NV_UndefineSpaceSpecial_fp.h"
+#endif
+#if CC_NV_ReadPublic
+#include "NV_ReadPublic_fp.h"
+#endif
+#if CC_NV_Write
+#include "NV_Write_fp.h"
+#endif
+#if CC_NV_Increment
+#include "NV_Increment_fp.h"
+#endif
+#if CC_NV_Extend
+#include "NV_Extend_fp.h"
+#endif
+#if CC_NV_SetBits
+#include "NV_SetBits_fp.h"
+#endif
+#if CC_NV_WriteLock
+#include "NV_WriteLock_fp.h"
+#endif
+#if CC_NV_GlobalWriteLock
+#include "NV_GlobalWriteLock_fp.h"
+#endif
+#if CC_NV_Read
+#include "NV_Read_fp.h"
+#endif
+#if CC_NV_ReadLock
+#include "NV_ReadLock_fp.h"
+#endif
+#if CC_NV_ChangeAuth
+#include "NV_ChangeAuth_fp.h"
+#endif
+#if CC_NV_Certify
+#include "NV_Certify_fp.h"
+#endif
+
+/* Attached Components */
+
+#if CC_AC_GetCapability
+#include "AC_GetCapability_fp.h"
+#endif
+#if CC_AC_Send
+#include "AC_Send_fp.h"
+#endif
+#if CC_Policy_AC_SendSelect
+#include "Policy_AC_SendSelect_fp.h"
+#endif
+
+/* Authenticated Countdown Timer */
+#ifdef TPM_CC_ACT_SetTimeout
+#include "ACT_SetTimeout_fp.h"
+#endif
+
+/* Vendor Specific */
+#if CC_Vendor_TCG_Test
+#include "Vendor_TCG_Test_fp.h"
+#endif
+
+/* Nuvoton Commands */
+#ifdef TPM_NUVOTON
+#include "ntc2_fp.h"
+#endif
+
+#endif

+ 94 - 0
EVSE/GPL/ibmtpm1682/src/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

+ 165 - 0
EVSE/GPL/ibmtpm1682/src/CompilerDependencies.h

@@ -0,0 +1,165 @@
+/********************************************************************************/
+/*										*/
+/*			   Compiler Dependencies  				*/
+/*			     Written by Ken Goldman				*/
+/*		       IBM Thomas J. Watson Research Center			*/
+/*            $Id: CompilerDependencies.h 1453 2019-04-05 16:43:36Z kgoldman $	*/
+/*										*/
+/*  Licenses and Notices							*/
+/*										*/
+/*  1. Copyright Licenses:							*/
+/*										*/
+/*  - Trusted Computing Group (TCG) grants to the user of the source code in	*/
+/*    this specification (the "Source Code") a worldwide, irrevocable, 		*/
+/*    nonexclusive, royalty free, copyright license to reproduce, create 	*/
+/*    derivative works, distribute, display and perform the Source Code and	*/
+/*    derivative works thereof, and to grant others the rights granted herein.	*/
+/*										*/
+/*  - The TCG grants to the user of the other parts of the specification 	*/
+/*    (other than the Source Code) the rights to reproduce, distribute, 	*/
+/*    display, and perform the specification solely for the purpose of 		*/
+/*    developing products based on such documents.				*/
+/*										*/
+/*  2. Source Code Distribution Conditions:					*/
+/*										*/
+/*  - Redistributions of Source Code must retain the above copyright licenses, 	*/
+/*    this list of conditions and the following disclaimers.			*/
+/*										*/
+/*  - Redistributions in binary form must reproduce the above copyright 	*/
+/*    licenses, this list of conditions	and the following disclaimers in the 	*/
+/*    documentation and/or other materials provided with the distribution.	*/
+/*										*/
+/*  3. Disclaimers:								*/
+/*										*/
+/*  - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF	*/
+/*  LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH	*/
+/*  RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES)	*/
+/*  THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE.		*/
+/*  Contact TCG Administration (admin@trustedcomputinggroup.org) for 		*/
+/*  information on specification licensing rights available through TCG 	*/
+/*  membership agreements.							*/
+/*										*/
+/*  - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED 	*/
+/*    WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR 	*/
+/*    FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR 		*/
+/*    NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY 		*/
+/*    OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE.		*/
+/*										*/
+/*  - Without limitation, TCG and its members and licensors disclaim all 	*/
+/*    liability, including liability for infringement of any proprietary 	*/
+/*    rights, relating to use of information in this specification and to the	*/
+/*    implementation of this specification, and TCG disclaims all liability for	*/
+/*    cost of procurement of substitute goods or services, lost profits, loss 	*/
+/*    of use, loss of data or any incidental, consequential, direct, indirect, 	*/
+/*    or special damages, whether under contract, tort, warranty or otherwise, 	*/
+/*    arising in any way out of use or reliance upon this specification or any 	*/
+/*    information herein.							*/
+/*										*/
+/*  (c) Copyright IBM Corp. and others, 2016 - 2019				*/
+/*										*/
+/********************************************************************************/
+
+#ifndef COMPILERDEPEDENCIES_H
+#define COMPILERDEPEDENCIES_H
+
+/* kgold - Not in the original code.  A user reported that it was required for a non-Visual Studio
+   environment.
+*/
+
+#ifdef TPM_WINDOWS
+#include <windows.h>
+#include <winsock.h>
+#endif
+
+/* 5.10	CompilerDependencies.h */
+#ifdef GCC
+#   undef _MSC_VER
+#   undef WIN32
+#endif
+
+#ifdef _MSC_VER
+
+// These definitions are for the Microsoft compiler Endian conversion for aligned structures
+#   define REVERSE_ENDIAN_16(_Number) _byteswap_ushort(_Number)
+#   define REVERSE_ENDIAN_32(_Number) _byteswap_ulong(_Number)
+#   define REVERSE_ENDIAN_64(_Number) _byteswap_uint64(_Number)
+
+// Avoid compiler warning for in line of stdio (or not)
+
+// #define _NO_CRT_STDIO_INLINE
+
+// This macro is used to handle LIB_EXPORT of function and variable names in lieu of a .def
+// file. Visual Studio requires that functions be explicitly exported and imported.
+
+#   define LIB_EXPORT __declspec(dllexport) // VS compatible version
+#   define LIB_IMPORT __declspec(dllimport)
+
+// This is defined to indicate a function that does not return. Microsoft compilers do not
+// support the _Noretrun() function parameter.
+
+#   define NORETURN  __declspec(noreturn)
+#   if _MSC_VER >= 1400     // SAL processing when needed
+#       include <sal.h>
+#   endif
+#   ifdef _WIN64
+#       define _INTPTR 2
+#   else
+#       define _INTPTR 1
+#   endif
+#   define NOT_REFERENCED(x)   (x)
+
+// Lower the compiler error warning for system include files. They tend not to be that clean and
+// there is no reason to sort through all the spurious errors that they generate when the normal
+// error level is set to /Wall
+
+#   define _REDUCE_WARNING_LEVEL_(n)		\
+    __pragma(warning(push, n))
+
+// Restore the compiler warning level
+
+#   define _NORMAL_WARNING_LEVEL_		\
+    __pragma(warning(pop))
+#   include <stdint.h>
+#endif 	// _MSC_VER
+
+#ifndef _MSC_VER
+#ifndef WINAPI
+#   define WINAPI
+#endif
+#   define __pragma(x)
+#   define REVERSE_ENDIAN_16(_Number) __builtin_bswap16(_Number)
+#   define REVERSE_ENDIAN_32(_Number) __builtin_bswap32(_Number)
+#   define REVERSE_ENDIAN_64(_Number) __builtin_bswap64(_Number)
+#endif
+#if defined(__GNUC__)
+#      define NORETURN                     __attribute__((noreturn))
+#      include <stdint.h>
+#endif
+
+// Things that are not defined should be defined as NULL
+#ifndef NORETURN
+#   define NORETURN
+#endif
+#ifndef LIB_EXPORT
+#   define LIB_EXPORT
+#endif
+#ifndef LIB_IMPORT
+#   define LIB_IMPORT
+#endif
+#ifndef _REDUCE_WARNING_LEVEL_
+#   define _REDUCE_WARNING_LEVEL_(n)
+#endif
+#ifndef _NORMAL_WARNING_LEVEL_
+#   define _NORMAL_WARNING_LEVEL_
+#endif
+#ifndef NOT_REFERENCED
+#   define  NOT_REFERENCED(x) (x = x)
+#endif
+#ifdef _POSIX_
+typedef int SOCKET;
+#endif
+// #ifdef TPM_POSIX
+// typedef int SOCKET;
+// #endif
+#endif // _COMPILER_DEPENDENCIES_H_
+

+ 476 - 0
EVSE/GPL/ibmtpm1682/src/ContextCommands.c

@@ -0,0 +1,476 @@
+/********************************************************************************/
+/*										*/
+/*			   Context Management	  				*/
+/*			     Written by Ken Goldman				*/
+/*		       IBM Thomas J. Watson Research Center			*/
+/*            $Id: ContextCommands.c 1671 2021-06-03 18:30:41Z kgoldman $	*/
+/*										*/
+/*  Licenses and Notices							*/
+/*										*/
+/*  1. Copyright Licenses:							*/
+/*										*/
+/*  - Trusted Computing Group (TCG) grants to the user of the source code in	*/
+/*    this specification (the "Source Code") a worldwide, irrevocable, 		*/
+/*    nonexclusive, royalty free, copyright license to reproduce, create 	*/
+/*    derivative works, distribute, display and perform the Source Code and	*/
+/*    derivative works thereof, and to grant others the rights granted herein.	*/
+/*										*/
+/*  - The TCG grants to the user of the other parts of the specification 	*/
+/*    (other than the Source Code) the rights to reproduce, distribute, 	*/
+/*    display, and perform the specification solely for the purpose of 		*/
+/*    developing products based on such documents.				*/
+/*										*/
+/*  2. Source Code Distribution Conditions:					*/
+/*										*/
+/*  - Redistributions of Source Code must retain the above copyright licenses, 	*/
+/*    this list of conditions and the following disclaimers.			*/
+/*										*/
+/*  - Redistributions in binary form must reproduce the above copyright 	*/
+/*    licenses, this list of conditions	and the following disclaimers in the 	*/
+/*    documentation and/or other materials provided with the distribution.	*/
+/*										*/
+/*  3. Disclaimers:								*/
+/*										*/
+/*  - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF	*/
+/*  LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH	*/
+/*  RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES)	*/
+/*  THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE.		*/
+/*  Contact TCG Administration (admin@trustedcomputinggroup.org) for 		*/
+/*  information on specification licensing rights available through TCG 	*/
+/*  membership agreements.							*/
+/*										*/
+/*  - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED 	*/
+/*    WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR 	*/
+/*    FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR 		*/
+/*    NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY 		*/
+/*    OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE.		*/
+/*										*/
+/*  - Without limitation, TCG and its members and licensors disclaim all 	*/
+/*    liability, including liability for infringement of any proprietary 	*/
+/*    rights, relating to use of information in this specification and to the	*/
+/*    implementation of this specification, and TCG disclaims all liability for	*/
+/*    cost of procurement of substitute goods or services, lost profits, loss 	*/
+/*    of use, loss of data or any incidental, consequential, direct, indirect, 	*/
+/*    or special damages, whether under contract, tort, warranty or otherwise, 	*/
+/*    arising in any way out of use or reliance upon this specification or any 	*/
+/*    information herein.							*/
+/*										*/
+/*  (c) Copyright IBM Corp. and others, 2016 - 2021				*/
+/*										*/
+/********************************************************************************/
+
+#include "Tpm.h"
+#include "ContextSave_fp.h"
+#if CC_ContextSave  // Conditional expansion of this file
+#include "Context_spt_fp.h"
+
+extern int verbose;
+
+/* Error Returns Meaning */
+/* TPM_RC_CONTEXT_GAP a contextID could not be assigned for a session context save */
+/* TPM_RC_TOO_MANY_CONTEXTS no more contexts can be saved as the counter has maxed out */
+TPM_RC
+TPM2_ContextSave(
+		 ContextSave_In      *in,            // IN: input parameter list
+		 ContextSave_Out     *out            // OUT: output parameter list
+		 )
+{
+    TPM_RC          result = TPM_RC_SUCCESS;
+    UINT16          fingerprintSize;    // The size of fingerprint in context
+    // blob.
+    UINT64          contextID = 0;      // session context ID
+    TPM2B_SYM_KEY   symKey;
+    TPM2B_IV        iv;
+    TPM2B_DIGEST    integrity;
+    UINT16          integritySize;
+    BYTE            *buffer;
+    if (verbose) {
+	FILE *f = fopen("trace.txt", "a");
+	fprintf(f, "TPM2_ContextSave: %08x\n", in->saveHandle);
+	fclose(f);
+    }
+    // This command may cause the orderlyState to be cleared due to
+    // the update of state reset data. If the state is orderly and
+    // cannot be changed, exit early.
+    RETURN_IF_ORDERLY;
+
+    // Internal Data Update
+
+    // This implementation does not do things in quite the same way as described in
+    // Part 2 of the specification. In Part 2, it indicates that the
+    // TPMS_CONTEXT_DATA contains two TPM2B values. That is not how this is
+    // implemented. Rather, the size field of the TPM2B_CONTEXT_DATA is used to
+    // determine the amount of data in the encrypted data. That part is not
+    // independently sized. This makes the actual size 2 bytes smaller than
+    // calculated using Part 2. Since this is opaque to the caller, it is not
+    // necessary to fix. The actual size is returned by TPM2_GetCapabilties().
+
+    // Initialize output handle.  At the end of command action, the output
+    // handle of an object will be replaced, while the output handle
+    // for a session will be the same as input
+    out->context.savedHandle = in->saveHandle;
+    // Get the size of fingerprint in context blob.  The sequence value in
+    // TPMS_CONTEXT structure is used as the fingerprint
+    fingerprintSize = sizeof(out->context.sequence);
+    // Compute the integrity size at the beginning of context blob
+    integritySize = sizeof(integrity.t.size)
+		    + CryptHashGetDigestSize(CONTEXT_INTEGRITY_HASH_ALG);
+    // Perform object or session specific context save
+    switch(HandleGetType(in->saveHandle))
+	{
+	  case TPM_HT_TRANSIENT:
+	      {
+		  OBJECT              *object = HandleToObject(in->saveHandle);
+		  ANY_OBJECT_BUFFER   *outObject;
+		  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"
+#if CC_ContextLoad  // Conditional expansion of this file
+#include "Context_spt_fp.h"
+TPM_RC
+TPM2_ContextLoad(
+		 ContextLoad_In      *in,            // IN: input parameter list
+		 ContextLoad_Out     *out            // OUT: output parameter list
+		 )
+{
+    TPM_RC              result;
+    TPM2B_DIGEST        integrityToCompare;
+    TPM2B_DIGEST        integrity;
+    BYTE                *buffer;    // defined to save some typing
+    INT32               size;       // defined to save some typing
+    TPM_HT              handleType;
+    TPM2B_SYM_KEY       symKey;
+    TPM2B_IV            iv;
+    // Input Validation
+
+    // See discussion about the context format in TPM2_ContextSave Detailed Actions
+
+    // IF this is a session context, make sure that the sequence number is
+    // consistent with the version in the slot
+    // Check context blob size
+    handleType = HandleGetType(in->context.savedHandle);
+    // Get integrity from context blob
+    buffer = in->context.contextBlob.t.buffer;
+    size = (INT32)in->context.contextBlob.t.size;
+    result = TPM2B_DIGEST_Unmarshal(&integrity, &buffer, &size);
+    if(result != TPM_RC_SUCCESS)
+	return result;
+    // the size of the integrity value has to match the size of digest produced
+    // by the integrity hash
+    if(integrity.t.size != CryptHashGetDigestSize(CONTEXT_INTEGRITY_HASH_ALG))
+	return TPM_RCS_SIZE + RC_ContextLoad_context;
+    // Make sure that the context blob has enough space for the fingerprint. This
+    // is elastic pants to go with the belt and suspenders we already have to make
+    // sure that the context is complete and untampered.
+    if((unsigned)size < sizeof(in->context.sequence))
+	return TPM_RCS_SIZE + RC_ContextLoad_context;
+    // After unmarshaling the integrity value, 'buffer' is pointing at the first
+    // byte of the integrity protected and encrypted buffer and 'size' is the number
+    // of integrity protected and encrypted bytes.
+    // Compute context integrity
+    ComputeContextIntegrity(&in->context, &integrityToCompare);
+    // Compare integrity
+    if(!MemoryEqual2B(&integrity.b, &integrityToCompare.b))
+	return TPM_RCS_INTEGRITY + RC_ContextLoad_context;
+    // Compute context encryption key
+    ComputeContextProtectionKey(&in->context, &symKey, &iv);
+    // Decrypt context data in place
+    CryptSymmetricDecrypt(buffer, CONTEXT_ENCRYPT_ALG, CONTEXT_ENCRYPT_KEY_BITS,
+			  symKey.t.buffer, &iv, TPM_ALG_CFB, size, buffer);
+    // See if the fingerprint value matches. If not, it is symptomatic of either
+    // a broken TPM or that the TPM is under attack so go into failure mode.
+    if(!MemoryEqual(buffer, &in->context.sequence, sizeof(in->context.sequence)))
+	FAIL(FATAL_ERROR_INTERNAL);
+    // step over fingerprint
+    buffer += sizeof(in->context.sequence);
+    // set the remaining size of the context
+    size -= sizeof(in->context.sequence);
+    // Perform object or session specific input check
+    switch(handleType)
+	{
+	  case TPM_HT_TRANSIENT:
+	      {
+		  OBJECT      *outObject;
+		  if(size > (INT32)sizeof(OBJECT))
+		      FAIL(FATAL_ERROR_INTERNAL);
+		  // Discard any changes to the handle that the TRM might have made
+		  in->context.savedHandle = TRANSIENT_FIRST;
+		  // If hierarchy is disabled, no object context can be loaded in this
+		  // hierarchy
+		  if(!HierarchyIsEnabled(in->context.hierarchy))
+		      return TPM_RCS_HIERARCHY + RC_ContextLoad_context;
+		  // Restore object. If there is no empty space, indicate as much
+		  outObject = 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(!SequenceNumberForSavedContextIsValid(&in->context))
+		      return TPM_RCS_HANDLE + RC_ContextLoad_context;
+		  // Restore session.  A TPM_RC_SESSION_MEMORY, TPM_RC_CONTEXT_GAP error
+		  // may be returned at this point
+		  result = SessionContextLoad((SESSION_BUF *)buffer,
+					      &in->context.savedHandle);
+		  if(result != TPM_RC_SUCCESS)
+		      return result;
+		  out->loadedHandle = in->context.savedHandle;
+		  // orderly state should be cleared because of the update of state
+		  // reset and state clear data
+		  g_clearOrderly = TRUE;
+		  break;
+	      }
+	  default:
+	    // Context blob may only have an object handle or a session handle.
+	    // All the other handle type should be filtered out at unmarshal
+	    FAIL(FATAL_ERROR_INTERNAL);
+	    break;
+	}
+    if (verbose) {
+	FILE *f = fopen("trace.txt", "a");
+	fprintf(f, "TPM2_ContextLoad: %08x\n", out->loadedHandle);
+	fclose(f);
+    }
+    return TPM_RC_SUCCESS;
+}
+#endif // CC_ContextLoad
+#include "Tpm.h"
+#include "FlushContext_fp.h"
+#if CC_FlushContext  // Conditional expansion of this file
+TPM_RC
+TPM2_FlushContext(
+		  FlushContext_In     *in             // IN: input parameter list
+		  )
+{
+    if (verbose) {
+	FILE *f = fopen("trace.txt", "a");
+	fprintf(f, "TPM2_FlushContext: %08x\n", in->flushHandle);
+	fclose(f);
+    }
+    // Internal Data Update
+    // Call object or session specific routine to flush
+    switch(HandleGetType(in->flushHandle))
+	{
+	  case TPM_HT_TRANSIENT:
+	    if(!IsObjectPresent(in->flushHandle))
+		return TPM_RCS_HANDLE + RC_FlushContext_flushHandle;
+	    // Flush object
+	    FlushObject(in->flushHandle);
+	    break;
+	  case TPM_HT_HMAC_SESSION:
+	  case TPM_HT_POLICY_SESSION:
+	    if(!SessionIsLoaded(in->flushHandle)
+	       && !SessionIsSaved(in->flushHandle)
+	       )
+		return TPM_RCS_HANDLE + RC_FlushContext_flushHandle;
+	    // If the session to be flushed is the exclusive audit session, then
+	    // indicate that there is no exclusive audit session any longer.
+	    if(in->flushHandle == g_exclusiveAuditSession)
+		g_exclusiveAuditSession = TPM_RH_UNASSIGNED;
+	    // Flush session
+	    SessionFlush(in->flushHandle);
+	    break;
+	  default:
+	    // This command only takes object or session handle.  Other handles
+	    // should be filtered out at handle unmarshal
+	    FAIL(FATAL_ERROR_INTERNAL);
+	    break;
+	}
+    return TPM_RC_SUCCESS;
+}
+#endif // CC_FlushContext
+#include "Tpm.h"
+#include "EvictControl_fp.h"
+#if CC_EvictControl  // Conditional expansion of this file
+TPM_RC
+TPM2_EvictControl(
+		  EvictControl_In     *in             // IN: input parameter list
+		  )
+{
+    TPM_RC      result;
+    OBJECT      *evictObject;
+    if (verbose) {
+	FILE *f = fopen("trace.txt", "a");
+	fprintf(f, "EvictControl: persistentHandle %08x\n", in->persistentHandle);
+	fprintf(f, "EvictControl: objectHandle %08x\n", in->objectHandle);
+	fclose(f);
+    }
+    // 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

+ 84 - 0
EVSE/GPL/ibmtpm1682/src/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

+ 84 - 0
EVSE/GPL/ibmtpm1682/src/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

+ 202 - 0
EVSE/GPL/ibmtpm1682/src/Context_spt.c

@@ -0,0 +1,202 @@
+/********************************************************************************/
+/*										*/
+/*			Context Management Command Support   			*/
+/*			     Written by Ken Goldman				*/
+/*		       IBM Thomas J. Watson Research Center			*/
+/*            $Id: Context_spt.c 1603 2020-04-03 17:48:43Z kgoldman $		*/
+/*										*/
+/*  Licenses and Notices							*/
+/*										*/
+/*  1. Copyright Licenses:							*/
+/*										*/
+/*  - Trusted Computing Group (TCG) grants to the user of the source code in	*/
+/*    this specification (the "Source Code") a worldwide, irrevocable, 		*/
+/*    nonexclusive, royalty free, copyright license to reproduce, create 	*/
+/*    derivative works, distribute, display and perform the Source Code and	*/
+/*    derivative works thereof, and to grant others the rights granted herein.	*/
+/*										*/
+/*  - The TCG grants to the user of the other parts of the specification 	*/
+/*    (other than the Source Code) the rights to reproduce, distribute, 	*/
+/*    display, and perform the specification solely for the purpose of 		*/
+/*    developing products based on such documents.				*/
+/*										*/
+/*  2. Source Code Distribution Conditions:					*/
+/*										*/
+/*  - Redistributions of Source Code must retain the above copyright licenses, 	*/
+/*    this list of conditions and the following disclaimers.			*/
+/*										*/
+/*  - Redistributions in binary form must reproduce the above copyright 	*/
+/*    licenses, this list of conditions	and the following disclaimers in the 	*/
+/*    documentation and/or other materials provided with the distribution.	*/
+/*										*/
+/*  3. Disclaimers:								*/
+/*										*/
+/*  - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF	*/
+/*  LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH	*/
+/*  RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES)	*/
+/*  THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE.		*/
+/*  Contact TCG Administration (admin@trustedcomputinggroup.org) for 		*/
+/*  information on specification licensing rights available through TCG 	*/
+/*  membership agreements.							*/
+/*										*/
+/*  - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED 	*/
+/*    WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR 	*/
+/*    FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR 		*/
+/*    NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY 		*/
+/*    OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE.		*/
+/*										*/
+/*  - Without limitation, TCG and its members and licensors disclaim all 	*/
+/*    liability, including liability for infringement of any proprietary 	*/
+/*    rights, relating to use of information in this specification and to the	*/
+/*    implementation of this specification, and TCG disclaims all liability for	*/
+/*    cost of procurement of substitute goods or services, lost profits, loss 	*/
+/*    of use, loss of data or any incidental, consequential, direct, indirect, 	*/
+/*    or special damages, whether under contract, tort, warranty or otherwise, 	*/
+/*    arising in any way out of use or reliance upon this specification or any 	*/
+/*    information herein.							*/
+/*										*/
+/*  (c) Copyright IBM Corp. and others, 2016 - 2020				*/
+/*										*/
+/********************************************************************************/
+
+/* 7.3.1 Includes */
+#include "Tpm.h"
+#include "Context_spt_fp.h"
+/* 7.3.2 Functions */
+/* 7.3.2.1 ComputeContextProtectionKey() */
+/* This function retrieves the symmetric protection key for context encryption It is used by
+   TPM2_ContextSave() and TPM2_ContextLoad() to create the symmetric encryption key and iv */
+void
+ComputeContextProtectionKey(
+			    TPMS_CONTEXT    *contextBlob,   // IN: context blob
+			    TPM2B_SYM_KEY   *symKey,        // OUT: the symmetric key
+			    TPM2B_IV        *iv             // OUT: the IV.
+			    )
+{
+    UINT16           symKeyBits;    // number of bits in the parent's
+    //   symmetric key
+    TPM2B_PROOF      *proof = NULL;  // the proof value to use. Is null for
+    //   everything but a primary object in
+    //   the Endorsement Hierarchy
+    BYTE             kdfResult[sizeof(TPMU_HA) * 2];// Value produced by the KDF
+    TPM2B_DATA       sequence2B, handle2B;
+    // Get proof value
+    proof = HierarchyGetProof(contextBlob->hierarchy);
+
+    // Get sequence value in 2B format
+    sequence2B.t.size = sizeof(contextBlob->sequence);
+    cAssert(sequence2B.t.size <= sizeof(sequence2B.t.buffer));
+    MemoryCopy(sequence2B.t.buffer, &contextBlob->sequence, sequence2B.t.size);
+    
+    // Get handle value in 2B format
+    handle2B.t.size = sizeof(contextBlob->savedHandle);
+    cAssert(handle2B.t.size <= sizeof(handle2B.t.buffer));
+    MemoryCopy(handle2B.t.buffer, &contextBlob->savedHandle, handle2B.t.size);
+
+    // Get the symmetric encryption key size
+    symKey->t.size = CONTEXT_ENCRYPT_KEY_BYTES;
+    symKeyBits = CONTEXT_ENCRYPT_KEY_BITS;
+    // Get the size of the IV for the algorithm
+    iv->t.size = CryptGetSymmetricBlockSize(CONTEXT_ENCRYPT_ALG, symKeyBits);
+    // KDFa to generate symmetric key and IV value
+    CryptKDFa(CONTEXT_INTEGRITY_HASH_ALG, &proof->b, CONTEXT_KEY, &sequence2B.b,
+	      &handle2B.b, (symKey->t.size + iv->t.size) * 8, kdfResult, NULL,
+	      FALSE);
+    // Copy part of the returned value as the key
+    pAssert(symKey->t.size <= sizeof(symKey->t.buffer));
+    MemoryCopy(symKey->t.buffer, kdfResult, symKey->t.size);
+    // Copy the rest as the IV
+    pAssert(iv->t.size <= sizeof(iv->t.buffer));
+    MemoryCopy(iv->t.buffer, &kdfResult[symKey->t.size], iv->t.size);
+    return;
+}
+/* 7.3.2.2 ComputeContextIntegrity() */
+/* Generate the integrity hash for a context It is used by TPM2_ContextSave() to create an integrity
+   hash and by TPM2_ContextLoad() to compare an integrity hash */
+void
+ComputeContextIntegrity(
+			TPMS_CONTEXT    *contextBlob,   // IN: context blob
+			TPM2B_DIGEST    *integrity      // OUT: integrity
+			)
+{
+    HMAC_STATE          hmacState;
+    TPM2B_PROOF         *proof;
+    UINT16              integritySize;
+    // Get proof value
+    proof = HierarchyGetProof(contextBlob->hierarchy);
+    // Start HMAC
+    integrity->t.size = CryptHmacStart2B(&hmacState, CONTEXT_INTEGRITY_HASH_ALG,
+					 &proof->b);
+    // Compute integrity size at the beginning of context blob
+    integritySize = sizeof(integrity->t.size) + integrity->t.size;
+    // Adding total reset counter so that the context cannot be
+    // used after a TPM Reset
+    CryptDigestUpdateInt(&hmacState.hashState, sizeof(gp.totalResetCount),
+			 gp.totalResetCount);
+    // If this is a ST_CLEAR object, add the clear count
+    // so that this contest cannot be loaded after a TPM Restart
+    if(contextBlob->savedHandle == 0x80000002)
+	CryptDigestUpdateInt(&hmacState.hashState, sizeof(gr.clearCount),
+			     gr.clearCount);
+    // Adding sequence number to the HMAC to make sure that it doesn't
+    // get changed
+    CryptDigestUpdateInt(&hmacState.hashState, sizeof(contextBlob->sequence),
+			 contextBlob->sequence);
+    // Protect the handle
+    CryptDigestUpdateInt(&hmacState.hashState, sizeof(contextBlob->savedHandle),
+			 contextBlob->savedHandle);
+    // Adding sensitive contextData, skip the leading integrity area
+    CryptDigestUpdate(&hmacState.hashState,
+		      contextBlob->contextBlob.t.size - integritySize,
+		      contextBlob->contextBlob.t.buffer + integritySize);
+    // Complete HMAC
+    CryptHmacEnd2B(&hmacState, &integrity->b);
+    return;
+}
+/* 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);
+	}
+}

+ 88 - 0
EVSE/GPL/ibmtpm1682/src/Context_spt_fp.h

@@ -0,0 +1,88 @@
+/********************************************************************************/
+/*										*/
+/*			     				*/
+/*			     Written by Ken Goldman				*/
+/*		       IBM Thomas J. Watson Research Center			*/
+/*            $Id: Context_spt_fp.h 1490 2019-07-26 21:13:22Z kgoldman $			*/
+/*										*/
+/*  Licenses and Notices							*/
+/*										*/
+/*  1. Copyright Licenses:							*/
+/*										*/
+/*  - Trusted Computing Group (TCG) grants to the user of the source code in	*/
+/*    this specification (the "Source Code") a worldwide, irrevocable, 		*/
+/*    nonexclusive, royalty free, copyright license to reproduce, create 	*/
+/*    derivative works, distribute, display and perform the Source Code and	*/
+/*    derivative works thereof, and to grant others the rights granted herein.	*/
+/*										*/
+/*  - The TCG grants to the user of the other parts of the specification 	*/
+/*    (other than the Source Code) the rights to reproduce, distribute, 	*/
+/*    display, and perform the specification solely for the purpose of 		*/
+/*    developing products based on such documents.				*/
+/*										*/
+/*  2. Source Code Distribution Conditions:					*/
+/*										*/
+/*  - Redistributions of Source Code must retain the above copyright licenses, 	*/
+/*    this list of conditions and the following disclaimers.			*/
+/*										*/
+/*  - Redistributions in binary form must reproduce the above copyright 	*/
+/*    licenses, this list of conditions	and the following disclaimers in the 	*/
+/*    documentation and/or other materials provided with the distribution.	*/
+/*										*/
+/*  3. Disclaimers:								*/
+/*										*/
+/*  - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF	*/
+/*  LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH	*/
+/*  RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES)	*/
+/*  THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE.		*/
+/*  Contact TCG Administration (admin@trustedcomputinggroup.org) for 		*/
+/*  information on specification licensing rights available through TCG 	*/
+/*  membership agreements.							*/
+/*										*/
+/*  - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED 	*/
+/*    WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR 	*/
+/*    FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR 		*/
+/*    NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY 		*/
+/*    OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE.		*/
+/*										*/
+/*  - Without limitation, TCG and its members and licensors disclaim all 	*/
+/*    liability, including liability for infringement of any proprietary 	*/
+/*    rights, relating to use of information in this specification and to the	*/
+/*    implementation of this specification, and TCG disclaims all liability for	*/
+/*    cost of procurement of substitute goods or services, lost profits, loss 	*/
+/*    of use, loss of data or any incidental, consequential, direct, indirect, 	*/
+/*    or special damages, whether under contract, tort, warranty or otherwise, 	*/
+/*    arising in any way out of use or reliance upon this specification or any 	*/
+/*    information herein.							*/
+/*										*/
+/*  (c) Copyright IBM Corp. and others, 2016					*/
+/*										*/
+/********************************************************************************/
+
+#ifndef CONTEXT_SPT_H
+#define CONTEXT_SPT_H
+
+void
+ComputeContextProtectionKey(
+			    TPMS_CONTEXT    *contextBlob,   // IN: context blob
+			    TPM2B_SYM_KEY   *symKey,        // OUT: the symmetric key
+			    TPM2B_IV        *iv             // OUT: the IV.
+			    );
+void
+ComputeContextIntegrity(
+			TPMS_CONTEXT    *contextBlob,   // IN: context blob
+			TPM2B_DIGEST    *integrity      // OUT: integrity
+			);
+void
+SequenceDataExport(
+		   HASH_OBJECT         *object,        // IN: an internal hash object
+		   HASH_OBJECT_BUFFER  *exportObject   // OUT: a sequence context in a buffer
+		   );
+void
+SequenceDataImport(
+		   HASH_OBJECT         *object,        // IN/OUT: an internal hash object
+		   HASH_OBJECT_BUFFER  *exportObject   // IN/OUT: a sequence context in a buffer
+		   );
+
+
+#endif

+ 90 - 0
EVSE/GPL/ibmtpm1682/src/CreateLoaded_fp.h

@@ -0,0 +1,90 @@
+/********************************************************************************/
+/*										*/
+/*			     				*/
+/*			     Written by Ken Goldman				*/
+/*		       IBM Thomas J. Watson Research Center			*/
+/*            $Id: CreateLoaded_fp.h 1600 2020-03-30 22:08:01Z kgoldman $	*/
+/*										*/
+/*  Licenses and Notices							*/
+/*										*/
+/*  1. Copyright Licenses:							*/
+/*										*/
+/*  - Trusted Computing Group (TCG) grants to the user of the source code in	*/
+/*    this specification (the "Source Code") a worldwide, irrevocable, 		*/
+/*    nonexclusive, royalty free, copyright license to reproduce, create 	*/
+/*    derivative works, distribute, display and perform the Source Code and	*/
+/*    derivative works thereof, and to grant others the rights granted herein.	*/
+/*										*/
+/*  - The TCG grants to the user of the other parts of the specification 	*/
+/*    (other than the Source Code) the rights to reproduce, distribute, 	*/
+/*    display, and perform the specification solely for the purpose of 		*/
+/*    developing products based on such documents.				*/
+/*										*/
+/*  2. Source Code Distribution Conditions:					*/
+/*										*/
+/*  - Redistributions of Source Code must retain the above copyright licenses, 	*/
+/*    this list of conditions and the following disclaimers.			*/
+/*										*/
+/*  - Redistributions in binary form must reproduce the above copyright 	*/
+/*    licenses, this list of conditions	and the following disclaimers in the 	*/
+/*    documentation and/or other materials provided with the distribution.	*/
+/*										*/
+/*  3. Disclaimers:								*/
+/*										*/
+/*  - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF	*/
+/*  LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH	*/
+/*  RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES)	*/
+/*  THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE.		*/
+/*  Contact TCG Administration (admin@trustedcomputinggroup.org) for 		*/
+/*  information on specification licensing rights available through TCG 	*/
+/*  membership agreements.							*/
+/*										*/
+/*  - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED 	*/
+/*    WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR 	*/
+/*    FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR 		*/
+/*    NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY 		*/
+/*    OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE.		*/
+/*										*/
+/*  - Without limitation, TCG and its members and licensors disclaim all 	*/
+/*    liability, including liability for infringement of any proprietary 	*/
+/*    rights, relating to use of information in this specification and to the	*/
+/*    implementation of this specification, and TCG disclaims all liability for	*/
+/*    cost of procurement of substitute goods or services, lost profits, loss 	*/
+/*    of use, loss of data or any incidental, consequential, direct, indirect, 	*/
+/*    or special damages, whether under contract, tort, warranty or otherwise, 	*/
+/*    arising in any way out of use or reliance upon this specification or any 	*/
+/*    information herein.							*/
+/*										*/
+/*  (c) Copyright IBM Corp. and others, 2012-2015				*/
+/*										*/
+/********************************************************************************/
+
+#ifndef CREATELOADED_FP_H
+#define CREATELOADED_FP_H
+
+/* rev 136 */
+
+typedef struct {
+    TPMI_DH_PARENT		parentHandle;
+    TPM2B_SENSITIVE_CREATE	inSensitive;
+    TPM2B_TEMPLATE		inPublic;
+} CreateLoaded_In;
+
+#define RC_CreateLoaded_parentHandle 	(TPM_RC_H + TPM_RC_1)
+#define RC_CreateLoaded_inSensitive 	(TPM_RC_P + TPM_RC_1)
+#define RC_CreateLoaded_inPublic 	(TPM_RC_P + TPM_RC_2)
+
+typedef struct {
+    TPM_HANDLE		objectHandle;
+    TPM2B_PRIVATE	outPrivate;
+    TPM2B_PUBLIC	outPublic;
+    TPM2B_NAME		name;
+} CreateLoaded_Out;
+
+TPM_RC
+TPM2_CreateLoaded(
+		  CreateLoaded_In       *in,            // IN: input parameter list
+		  CreateLoaded_Out      *out            // OUT: output parameter list
+		  );
+
+#endif

+ 96 - 0
EVSE/GPL/ibmtpm1682/src/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

+ 96 - 0
EVSE/GPL/ibmtpm1682/src/Create_fp.h

@@ -0,0 +1,96 @@
+/********************************************************************************/
+/*										*/
+/*			     				*/
+/*			     Written by Ken Goldman				*/
+/*		       IBM Thomas J. Watson Research Center			*/
+/*            $Id: Create_fp.h 1521 2019-11-15 21:00:47Z kgoldman $		*/
+/*										*/
+/*  Licenses and Notices							*/
+/*										*/
+/*  1. Copyright Licenses:							*/
+/*										*/
+/*  - Trusted Computing Group (TCG) grants to the user of the source code in	*/
+/*    this specification (the "Source Code") a worldwide, irrevocable, 		*/
+/*    nonexclusive, royalty free, copyright license to reproduce, create 	*/
+/*    derivative works, distribute, display and perform the Source Code and	*/
+/*    derivative works thereof, and to grant others the rights granted herein.	*/
+/*										*/
+/*  - The TCG grants to the user of the other parts of the specification 	*/
+/*    (other than the Source Code) the rights to reproduce, distribute, 	*/
+/*    display, and perform the specification solely for the purpose of 		*/
+/*    developing products based on such documents.				*/
+/*										*/
+/*  2. Source Code Distribution Conditions:					*/
+/*										*/
+/*  - Redistributions of Source Code must retain the above copyright licenses, 	*/
+/*    this list of conditions and the following disclaimers.			*/
+/*										*/
+/*  - Redistributions in binary form must reproduce the above copyright 	*/
+/*    licenses, this list of conditions	and the following disclaimers in the 	*/
+/*    documentation and/or other materials provided with the distribution.	*/
+/*										*/
+/*  3. Disclaimers:								*/
+/*										*/
+/*  - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF	*/
+/*  LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH	*/
+/*  RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES)	*/
+/*  THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE.		*/
+/*  Contact TCG Administration (admin@trustedcomputinggroup.org) for 		*/
+/*  information on specification licensing rights available through TCG 	*/
+/*  membership agreements.							*/
+/*										*/
+/*  - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED 	*/
+/*    WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR 	*/
+/*    FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR 		*/
+/*    NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY 		*/
+/*    OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE.		*/
+/*										*/
+/*  - Without limitation, TCG and its members and licensors disclaim all 	*/
+/*    liability, including liability for infringement of any proprietary 	*/
+/*    rights, relating to use of information in this specification and to the	*/
+/*    implementation of this specification, and TCG disclaims all liability for	*/
+/*    cost of procurement of substitute goods or services, lost profits, loss 	*/
+/*    of use, loss of data or any incidental, consequential, direct, indirect, 	*/
+/*    or special damages, whether under contract, tort, warranty or otherwise, 	*/
+/*    arising in any way out of use or reliance upon this specification or any 	*/
+/*    information herein.							*/
+/*										*/
+/*  (c) Copyright IBM Corp. and others, 2012-2015				*/
+/*										*/
+/********************************************************************************/
+
+/* rev 137 */
+
+#ifndef CREATE_FP_H
+#define CREATE_FP_H
+
+typedef struct {
+    TPMI_DH_OBJECT		parentHandle;
+    TPM2B_SENSITIVE_CREATE	inSensitive;
+    TPM2B_PUBLIC		inPublic;
+    TPM2B_DATA			outsideInfo;
+    TPML_PCR_SELECTION		creationPCR;
+} Create_In;     
+
+#define RC_Create_parentHandle 	(TPM_RC_H + TPM_RC_1)
+#define RC_Create_inSensitive 	(TPM_RC_P + TPM_RC_1)
+#define RC_Create_inPublic 	(TPM_RC_P + TPM_RC_2)
+#define RC_Create_outsideInfo	(TPM_RC_P + TPM_RC_3)
+#define RC_Create_creationPCR	(TPM_RC_P + TPM_RC_4)
+
+typedef struct {
+    TPM2B_PRIVATE	outPrivate;
+    TPM2B_PUBLIC	outPublic;
+    TPM2B_CREATION_DATA	creationData;
+    TPM2B_DIGEST	creationHash;
+    TPMT_TK_CREATION	creationTicket;
+} Create_Out;
+
+TPM_RC
+TPM2_Create(
+	    Create_In       *in,            // IN: input parameter list
+	    Create_Out      *out            // OUT: output parameter list
+	    );
+
+
+#endif

+ 207 - 0
EVSE/GPL/ibmtpm1682/src/CryptCmac.c

@@ -0,0 +1,207 @@
+/********************************************************************************/
+/*										*/
+/*	Message Authentication Codes Based on a Symmetric Block Cipher		*/
+/*			     Written by Ken Goldman				*/
+/*		       IBM Thomas J. Watson Research Center			*/
+/*            $Id: CryptCmac.c 1658 2021-01-22 23:14:01Z kgoldman $		*/
+/*										*/
+/*  Licenses and Notices							*/
+/*										*/
+/*  1. Copyright Licenses:							*/
+/*										*/
+/*  - Trusted Computing Group (TCG) grants to the user of the source code in	*/
+/*    this specification (the "Source Code") a worldwide, irrevocable, 		*/
+/*    nonexclusive, royalty free, copyright license to reproduce, create 	*/
+/*    derivative works, distribute, display and perform the Source Code and	*/
+/*    derivative works thereof, and to grant others the rights granted herein.	*/
+/*										*/
+/*  - The TCG grants to the user of the other parts of the specification 	*/
+/*    (other than the Source Code) the rights to reproduce, distribute, 	*/
+/*    display, and perform the specification solely for the purpose of 		*/
+/*    developing products based on such documents.				*/
+/*										*/
+/*  2. Source Code Distribution Conditions:					*/
+/*										*/
+/*  - Redistributions of Source Code must retain the above copyright licenses, 	*/
+/*    this list of conditions and the following disclaimers.			*/
+/*										*/
+/*  - Redistributions in binary form must reproduce the above copyright 	*/
+/*    licenses, this list of conditions	and the following disclaimers in the 	*/
+/*    documentation and/or other materials provided with the distribution.	*/
+/*										*/
+/*  3. Disclaimers:								*/
+/*										*/
+/*  - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF	*/
+/*  LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH	*/
+/*  RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES)	*/
+/*  THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE.		*/
+/*  Contact TCG Administration (admin@trustedcomputinggroup.org) for 		*/
+/*  information on specification licensing rights available through TCG 	*/
+/*  membership agreements.							*/
+/*										*/
+/*  - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED 	*/
+/*    WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR 	*/
+/*    FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR 		*/
+/*    NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY 		*/
+/*    OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE.		*/
+/*										*/
+/*  - Without limitation, TCG and its members and licensors disclaim all 	*/
+/*    liability, including liability for infringement of any proprietary 	*/
+/*    rights, relating to use of information in this specification and to the	*/
+/*    implementation of this specification, and TCG disclaims all liability for	*/
+/*    cost of procurement of substitute goods or services, lost profits, loss 	*/
+/*    of use, loss of data or any incidental, consequential, direct, indirect, 	*/
+/*    or special damages, whether under contract, tort, warranty or otherwise, 	*/
+/*    arising in any way out of use or reliance upon this specification or any 	*/
+/*    information herein.							*/
+/*										*/
+/*  (c) Copyright IBM Corp. and others, 2018 - 2021				*/
+/*										*/
+/********************************************************************************/
+
+/* 10.2.6	CryptCmac.c */
+/* 10.2.6.1	Introduction */
+/* This file contains the implementation of the message authentication codes based on a symmetric
+   block cipher. These functions only use the single block encryption functions of the selected
+   symmetric cryptographic library. */
+/* 10.2.6.2	Includes, Defines, and Typedefs */
+#define _CRYPT_HASH_C_
+#include "Tpm.h"
+#include "CryptSym.h"
+#if ALG_CMAC
+    /* 10.2.6.3	Functions */
+    /* 10.2.6.3.1	CryptCmacStart() */
+    /* This is the function to start the CMAC sequence operation. It initializes the dispatch
+       functions for the data and end operations for CMAC and initializes the parameters that are
+       used for the processing of data, including the key, key size and block cipher algorithm. */
+UINT16
+CryptCmacStart(
+	       SMAC_STATE          *state,
+	       TPMU_PUBLIC_PARMS   *keyParms,
+	       TPM_ALG_ID           macAlg,
+	       TPM2B               *key
+	       )
+{
+    tpmCmacState_t      *cState = &state->state.cmac;
+    TPMT_SYM_DEF_OBJECT *def = &keyParms->symDetail.sym;
+    //
+    if(macAlg != TPM_ALG_CMAC)
+	return 0;
+    // set up the encryption algorithm and parameters
+    cState->symAlg = def->algorithm;
+    cState->keySizeBits = def->keyBits.sym;
+    cState->iv.t.size = CryptGetSymmetricBlockSize(def->algorithm,
+						   def->keyBits.sym);
+    MemoryCopy2B(&cState->symKey.b, key, sizeof(cState->symKey.t.buffer));
+    // Set up the dispatch methods for the CMAC
+    state->smacMethods.data = CryptCmacData;
+    state->smacMethods.end = CryptCmacEnd;
+    return cState->iv.t.size;
+}
+
+/* 10.2.5.3.2	CryptCmacData() */
+/* This function is used to add data to the CMAC sequence computation. The function will XOR new
+   data into the IV. If the buffer is full, and there is additional input data, the data is
+   encrypted into the IV buffer, the new data is then XOR into the IV. When the data runs out, the
+   function returns without encrypting even if the buffer is full. The last data block of a sequence
+   will not be encrypted until the call to CryptCmacEnd(). This is to allow the proper subkey to be
+   computed and applied before the last block is encrypted. */
+void
+CryptCmacData(
+	      SMAC_STATES         *state,
+	      UINT32               size,
+	      const BYTE          *buffer
+	      )
+{
+    tpmCmacState_t          *cmacState = &state->cmac;
+    TPM_ALG_ID               algorithm = cmacState->symAlg;
+    BYTE                    *key = cmacState->symKey.t.buffer;
+    UINT16                   keySizeInBits = cmacState->keySizeBits;
+    tpmCryptKeySchedule_t    keySchedule;
+    TpmCryptSetSymKeyCall_t  encrypt;
+    //
+    // Set up the encryption values based on the algorithm
+    switch (algorithm)
+	{
+	    FOR_EACH_SYM(ENCRYPT_CASE)
+	  default:
+	    FAIL(FATAL_ERROR_INTERNAL);
+	}
+    while(size > 0)
+	{
+	    if(cmacState->bcount == cmacState->iv.t.size)
+	        {
+	            ENCRYPT(&keySchedule, cmacState->iv.t.buffer, cmacState->iv.t.buffer);
+	            cmacState->bcount = 0;
+	        }
+	    for(;(size > 0) && (cmacState->bcount < cmacState->iv.t.size);
+		size--, cmacState->bcount++)
+	        {
+	            cmacState->iv.t.buffer[cmacState->bcount] ^= *buffer++;
+	        }
+	}
+}
+
+/* 10.2.6.3.3	CryptCmacEnd() */
+/* This is the completion function for the CMAC. It does padding, if needed, and selects the subkey
+   to be applied before the last block is encrypted. */
+UINT16
+CryptCmacEnd(
+	     SMAC_STATES             *state,
+	     UINT32                   outSize,
+	     BYTE                    *outBuffer
+	     )
+{
+    tpmCmacState_t          *cState = &state->cmac;
+    // Need to set algorithm, key, and keySizeInBits in the local context so that
+    // the SELECT and ENCRYPT macros will work here
+    TPM_ALG_ID               algorithm = cState->symAlg;
+    BYTE                    *key = cState->symKey.t.buffer;
+    UINT16                   keySizeInBits = cState->keySizeBits;
+    tpmCryptKeySchedule_t    keySchedule;
+    TpmCryptSetSymKeyCall_t  encrypt;
+    TPM2B_IV                 subkey = {{0, {0}}};
+    BOOL                     xorVal;
+    UINT16                   i;
+
+    subkey.t.size = cState->iv.t.size;
+    // Encrypt a block of zero
+    // Set up the encryption values based on the algorithm
+    switch (algorithm)
+	{
+	    FOR_EACH_SYM(ENCRYPT_CASE)
+	  default:
+	    return 0;
+	}
+    ENCRYPT(&keySchedule, subkey.t.buffer, subkey.t.buffer);
+
+    // shift left by 1 and XOR with 0x0...87 if the MSb was 0
+    xorVal = ((subkey.t.buffer[0] & 0x80) == 0) ? 0 : 0x87;
+    ShiftLeft(&subkey.b);
+    subkey.t.buffer[subkey.t.size - 1] ^= xorVal;
+    // this is a sanity check to make sure that the algorithm is working properly.
+    // remove this check when debug is done
+    pAssert(cState->bcount <= cState->iv.t.size);
+    // If the buffer is full then no need to compute subkey 2.
+    if(cState->bcount < cState->iv.t.size)
+	{
+	    //Pad the data
+	    cState->iv.t.buffer[cState->bcount++] ^= 0x80;
+	    // The rest of the data is a pad of zero which would simply be XORed
+	    // with the iv value so nothing to do...
+	    // Now compute K2
+	    xorVal = ((subkey.t.buffer[0] & 0x80) == 0) ? 0 : 0x87;
+	    ShiftLeft(&subkey.b);
+	    subkey.t.buffer[subkey.t.size - 1] ^= xorVal;
+	}
+    // XOR the subkey into the IV
+    for(i = 0; i < subkey.t.size; i++)
+	cState->iv.t.buffer[i] ^= subkey.t.buffer[i];
+    ENCRYPT(&keySchedule, cState->iv.t.buffer, cState->iv.t.buffer);
+    i = (UINT16)MIN(cState->iv.t.size, outSize);
+    MemoryCopy(outBuffer, cState->iv.t.buffer, i);
+
+    return i;
+}
+
+#endif

+ 86 - 0
EVSE/GPL/ibmtpm1682/src/CryptCmac_fp.h

@@ -0,0 +1,86 @@
+/********************************************************************************/
+/*	Message Authentication Codes Based on a Symmetric Block Cipher		*/
+/*		Implementation of cryptographic functions for hashing.		*/
+/*			     Written by Ken Goldman				*/
+/*		       IBM Thomas J. Watson Research Center			*/
+/*            $Id: CryptCmac_fp.h 1490 2019-07-26 21:13:22Z kgoldman $		*/
+/*										*/
+/*  Licenses and Notices							*/
+/*										*/
+/*  1. Copyright Licenses:							*/
+/*										*/
+/*  - Trusted Computing Group (TCG) grants to the user of the source code in	*/
+/*    this specification (the "Source Code") a worldwide, irrevocable, 		*/
+/*    nonexclusive, royalty free, copyright license to reproduce, create 	*/
+/*    derivative works, distribute, display and perform the Source Code and	*/
+/*    derivative works thereof, and to grant others the rights granted herein.	*/
+/*										*/
+/*  - The TCG grants to the user of the other parts of the specification 	*/
+/*    (other than the Source Code) the rights to reproduce, distribute, 	*/
+/*    display, and perform the specification solely for the purpose of 		*/
+/*    developing products based on such documents.				*/
+/*										*/
+/*  2. Source Code Distribution Conditions:					*/
+/*										*/
+/*  - Redistributions of Source Code must retain the above copyright licenses, 	*/
+/*    this list of conditions and the following disclaimers.			*/
+/*										*/
+/*  - Redistributions in binary form must reproduce the above copyright 	*/
+/*    licenses, this list of conditions	and the following disclaimers in the 	*/
+/*    documentation and/or other materials provided with the distribution.	*/
+/*										*/
+/*  3. Disclaimers:								*/
+/*										*/
+/*  - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF	*/
+/*  LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH	*/
+/*  RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES)	*/
+/*  THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE.		*/
+/*  Contact TCG Administration (admin@trustedcomputinggroup.org) for 		*/
+/*  information on specification licensing rights available through TCG 	*/
+/*  membership agreements.							*/
+/*										*/
+/*  - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED 	*/
+/*    WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR 	*/
+/*    FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR 		*/
+/*    NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY 		*/
+/*    OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE.		*/
+/*										*/
+/*  - Without limitation, TCG and its members and licensors disclaim all 	*/
+/*    liability, including liability for infringement of any proprietary 	*/
+/*    rights, relating to use of information in this specification and to the	*/
+/*    implementation of this specification, and TCG disclaims all liability for	*/
+/*    cost of procurement of substitute goods or services, lost profits, loss 	*/
+/*    of use, loss of data or any incidental, consequential, direct, indirect, 	*/
+/*    or special damages, whether under contract, tort, warranty or otherwise, 	*/
+/*    arising in any way out of use or reliance upon this specification or any 	*/
+/*    information herein.							*/
+/*										*/
+/*  (c) Copyright IBM Corp. and others, 2018					*/
+/*										*/
+/********************************************************************************/
+
+#ifndef CRYPTCMAC_FP_H
+#define CRYPTCMAC_FP_H
+#include "Tpm.h"
+
+UINT16
+CryptCmacStart(
+	       SMAC_STATE          *state,
+	       TPMU_PUBLIC_PARMS   *keyParms,
+	       TPM_ALG_ID           macAlg,
+	       TPM2B               *key
+	       );
+void
+CryptCmacData(
+	      SMAC_STATES         *state,
+	      UINT32               size,
+	      const BYTE          *buffer
+	      );
+UINT16
+CryptCmacEnd(
+	     SMAC_STATES             *state,
+	     UINT32                   outSize,
+	     BYTE                    *outBuffer
+	     );
+
+#endif

+ 184 - 0
EVSE/GPL/ibmtpm1682/src/CryptDes.c

@@ -0,0 +1,184 @@
+/********************************************************************************/
+/*										*/
+/*			   Functions Required for TDES  			*/
+/*			     Written by Ken Goldman				*/
+/*		       IBM Thomas J. Watson Research Center			*/
+/*            $Id: CryptDes.c 1398 2018-12-17 22:37:57Z kgoldman $		*/
+/*										*/
+/*  Licenses and Notices							*/
+/*										*/
+/*  1. Copyright Licenses:							*/
+/*										*/
+/*  - Trusted Computing Group (TCG) grants to the user of the source code in	*/
+/*    this specification (the "Source Code") a worldwide, irrevocable, 		*/
+/*    nonexclusive, royalty free, copyright license to reproduce, create 	*/
+/*    derivative works, distribute, display and perform the Source Code and	*/
+/*    derivative works thereof, and to grant others the rights granted herein.	*/
+/*										*/
+/*  - The TCG grants to the user of the other parts of the specification 	*/
+/*    (other than the Source Code) the rights to reproduce, distribute, 	*/
+/*    display, and perform the specification solely for the purpose of 		*/
+/*    developing products based on such documents.				*/
+/*										*/
+/*  2. Source Code Distribution Conditions:					*/
+/*										*/
+/*  - Redistributions of Source Code must retain the above copyright licenses, 	*/
+/*    this list of conditions and the following disclaimers.			*/
+/*										*/
+/*  - Redistributions in binary form must reproduce the above copyright 	*/
+/*    licenses, this list of conditions	and the following disclaimers in the 	*/
+/*    documentation and/or other materials provided with the distribution.	*/
+/*										*/
+/*  3. Disclaimers:								*/
+/*										*/
+/*  - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF	*/
+/*  LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH	*/
+/*  RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES)	*/
+/*  THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE.		*/
+/*  Contact TCG Administration (admin@trustedcomputinggroup.org) for 		*/
+/*  information on specification licensing rights available through TCG 	*/
+/*  membership agreements.							*/
+/*										*/
+/*  - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED 	*/
+/*    WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR 	*/
+/*    FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR 		*/
+/*    NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY 		*/
+/*    OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE.		*/
+/*										*/
+/*  - Without limitation, TCG and its members and licensors disclaim all 	*/
+/*    liability, including liability for infringement of any proprietary 	*/
+/*    rights, relating to use of information in this specification and to the	*/
+/*    implementation of this specification, and TCG disclaims all liability for	*/
+/*    cost of procurement of substitute goods or services, lost profits, loss 	*/
+/*    of use, loss of data or any incidental, consequential, direct, indirect, 	*/
+/*    or special damages, whether under contract, tort, warranty or otherwise, 	*/
+/*    arising in any way out of use or reliance upon this specification or any 	*/
+/*    information herein.							*/
+/*										*/
+/*  (c) Copyright IBM Corp. and others, 2016 - 2018				*/
+/*										*/
+/********************************************************************************/
+
+/* 10.2.9 CryptDes.c */
+/* 10.2.9.1 Introduction */
+/* This file contains the extra functions required for TDES. */
+/* 10.2.9.2 Includes, Defines, and Typedefs */
+#include "Tpm.h"
+#if ALG_TDES
+#define DES_NUM_WEAK 64
+const UINT64 DesWeakKeys[DES_NUM_WEAK] = {
+    0x0101010101010101ULL, 0xFEFEFEFEFEFEFEFEULL, 0xE0E0E0E0F1F1F1F1ULL, 0x1F1F1F1F0E0E0E0EULL,
+    0x011F011F010E010EULL, 0x1F011F010E010E01ULL, 0x01E001E001F101F1ULL, 0xE001E001F101F101ULL,
+    0x01FE01FE01FE01FEULL, 0xFE01FE01FE01FE01ULL, 0x1FE01FE00EF10EF1ULL, 0xE01FE01FF10EF10EULL,
+    0x1FFE1FFE0EFE0EFEULL, 0xFE1FFE1FFE0EFE0EULL, 0xE0FEE0FEF1FEF1FEULL, 0xFEE0FEE0FEF1FEF1ULL,
+    0x01011F1F01010E0EULL, 0x1F1F01010E0E0101ULL, 0xE0E01F1FF1F10E0EULL, 0x0101E0E00101F1F1ULL,
+    0x1F1FE0E00E0EF1F1ULL, 0xE0E0FEFEF1F1FEFEULL, 0x0101FEFE0101FEFEULL, 0x1F1FFEFE0E0EFEFEULL,
+    0xE0FE011FF1FE010EULL, 0x011F1F01010E0E01ULL, 0x1FE001FE0EF101FEULL, 0xE0FE1F01F1FE0E01ULL,
+    0x011FE0FE010EF1FEULL, 0x1FE0E01F0EF1F10EULL, 0xE0FEFEE0F1FEFEF1ULL, 0x011FFEE0010EFEF1ULL,
+    0x1FE0FE010EF1FE01ULL, 0xFE0101FEFE0101FEULL, 0x01E01FFE01F10EFEULL, 0x1FFE01E00EFE01F1ULL,
+    0xFE011FE0FE010EF1ULL, 0xFE01E01FFE01F10EULL, 0x1FFEE0010EFEF101ULL, 0xFE1F01E0FE0E01F1ULL,
+    0x01E0E00101F1F101ULL, 0x1FFEFE1F0EFEFE0EULL, 0xFE1FE001FE0EF101ULL, 0x01E0FE1F01F1FE0EULL,
+    0xE00101E0F10101F1ULL, 0xFE1F1FFEFE0E0EFEULL, 0x01FE1FE001FE0EF1ULL, 0xE0011FFEF1010EFEULL,
+    0xFEE0011FFEF1010EULL, 0x01FEE01F01FEF10EULL, 0xE001FE1FF101FE0EULL, 0xFEE01F01FEF10E01ULL,
+    0x01FEFE0101FEFE01ULL, 0xE01F01FEF10E01FEULL, 0xFEE0E0FEFEF1F1FEULL, 0x1F01011F0E01010EULL,
+    0xE01F1FE0F10E0EF1ULL, 0xFEFE0101FEFE0101ULL, 0x1F01E0FE0E01F1FEULL, 0xE01FFE01F10EFE01ULL,
+    0xFEFE1F1FFEFE0E0EULL, 0x1F01FEE00E01FEF1ULL, 0xE0E00101F1F10101ULL, 0xFEFEE0E0FEFEF1F1ULL};
+/* 10.2.9.2.1 CryptSetOddByteParity() */
+/* This function sets the per byte parity of a 64-bit value. The least-significant bit is of each
+   byte is replaced with the odd parity of the other 7 bits in the byte. With odd parity, no byte
+   will ever be 0x00. */
+UINT64
+CryptSetOddByteParity(
+		      UINT64          k
+		      )
+{
+#define PMASK 0x0101010101010101ULL
+    UINT64          out;
+    k |= PMASK;     // set the parity bit
+    out = k;
+    k ^= k >> 4;
+    k ^= k >> 2;
+    k ^= k >> 1;
+    k &= PMASK;     // odd parity extracted
+    out ^= k;       // out is now even parity because parity bit was already set
+    out ^= PMASK;   // out is now even parity
+    return out;
+}
+/* 10.2.9.2.2 CryptDesIsWeakKey() */
+/* Check to see if a DES key is on the list of weak, semi-weak, or possibly weak keys. */
+/* Return Value	Meaning */
+/* TRUE(1)	DES key is weak */
+/* FALSE(0)	DES key is not weak */
+static BOOL
+CryptDesIsWeakKey(
+		  UINT64            k
+		  )
+{
+    int              i;
+    //
+    for(i = 0; i < DES_NUM_WEAK; i++)
+	{
+	    if(k == DesWeakKeys[i])
+		return TRUE;
+	}
+    return FALSE;
+}
+/* 10.2.9.2.3 CryptDesValidateKey() */
+/* Function to check to see if the input key is a valid DES key where the definition of valid is
+   that none of the elements are on the list of weak, semi-weak, or possibly weak keys; and that for
+   two keys, K1!=K2, and for three keys that K1!=K2 and K2!=K3. */
+BOOL
+CryptDesValidateKey(
+		    TPM2B_SYM_KEY       *desKey     // IN: key to validate
+		    )
+{
+    UINT64               k[3];
+    int                  i;
+    int                  keys = (desKey->t.size + 7) / 8;
+    BYTE                *pk = desKey->t.buffer;
+    BOOL                 ok;
+    //
+    // Note: 'keys' is the number of keys, not the maximum index for 'k'
+    ok = ((keys == 2) || (keys == 3)) && ((desKey->t.size % 8) == 0);
+    for(i = 0; ok && i < keys; pk += 8, i++)
+	{
+	    k[i] = CryptSetOddByteParity(BYTE_ARRAY_TO_UINT64(pk));
+	    ok = !CryptDesIsWeakKey(k[i]);
+	}
+    ok = ok && k[0] != k[1];
+    if(keys == 3)
+	ok = ok && k[1] != k[2];
+    return ok;
+}
+/* 10.2.9.2.4 CryptGenerateKeyDes() */
+/* This function is used to create a DES key of the appropriate size. The key will have odd parity
+   in the bytes. */
+TPM_RC
+CryptGenerateKeyDes(
+		    TPMT_PUBLIC             *publicArea,        // IN/OUT: The public area template
+		    //     for the new key.
+		    TPMT_SENSITIVE          *sensitive,         // OUT: sensitive area
+		    RAND_STATE              *rand               // IN: the "entropy" source for
+		    )
+{
+    // Assume that the publicArea key size has been validated and is a supported
+    // number of bits.
+    sensitive->sensitive.sym.t.size =
+	BITS_TO_BYTES(publicArea->parameters.symDetail.sym.keyBits.sym);
+    do
+	{
+	    BYTE                    *pK = sensitive->sensitive.sym.t.buffer;
+	    int                      i = (sensitive->sensitive.sym.t.size + 7) / 8;
+	    // Use the random number generator to generate the required number of bits
+	    if(DRBG_Generate(rand, pK, sensitive->sensitive.sym.t.size) == 0)
+		return TPM_RC_NO_RESULT;
+	    for(; i > 0; pK += 8, i--)
+		{
+		    UINT64      k = BYTE_ARRAY_TO_UINT64(pK);
+		    k = CryptSetOddByteParity(k);
+		    UINT64_TO_BYTE_ARRAY(k, pK);
+		}
+	} while(!CryptDesValidateKey(&sensitive->sensitive.sym));
+    return TPM_RC_SUCCESS;
+}
+#endif

+ 82 - 0
EVSE/GPL/ibmtpm1682/src/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

+ 103 - 0
EVSE/GPL/ibmtpm1682/src/CryptEcc.h

@@ -0,0 +1,103 @@
+/********************************************************************************/
+/*										*/
+/*			   Structure definitions used for ECC 			*/
+/*			     Written by Ken Goldman				*/
+/*		       IBM Thomas J. Watson Research Center			*/
+/*            $Id: CryptEcc.h 1594 2020-03-26 22:15:48Z kgoldman $		*/
+/*										*/
+/*  Licenses and Notices							*/
+/*										*/
+/*  1. Copyright Licenses:							*/
+/*										*/
+/*  - Trusted Computing Group (TCG) grants to the user of the source code in	*/
+/*    this specification (the "Source Code") a worldwide, irrevocable, 		*/
+/*    nonexclusive, royalty free, copyright license to reproduce, create 	*/
+/*    derivative works, distribute, display and perform the Source Code and	*/
+/*    derivative works thereof, and to grant others the rights granted herein.	*/
+/*										*/
+/*  - The TCG grants to the user of the other parts of the specification 	*/
+/*    (other than the Source Code) the rights to reproduce, distribute, 	*/
+/*    display, and perform the specification solely for the purpose of 		*/
+/*    developing products based on such documents.				*/
+/*										*/
+/*  2. Source Code Distribution Conditions:					*/
+/*										*/
+/*  - Redistributions of Source Code must retain the above copyright licenses, 	*/
+/*    this list of conditions and the following disclaimers.			*/
+/*										*/
+/*  - Redistributions in binary form must reproduce the above copyright 	*/
+/*    licenses, this list of conditions	and the following disclaimers in the 	*/
+/*    documentation and/or other materials provided with the distribution.	*/
+/*										*/
+/*  3. Disclaimers:								*/
+/*										*/
+/*  - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF	*/
+/*  LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH	*/
+/*  RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES)	*/
+/*  THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE.		*/
+/*  Contact TCG Administration (admin@trustedcomputinggroup.org) for 		*/
+/*  information on specification licensing rights available through TCG 	*/
+/*  membership agreements.							*/
+/*										*/
+/*  - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED 	*/
+/*    WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR 	*/
+/*    FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR 		*/
+/*    NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY 		*/
+/*    OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE.		*/
+/*										*/
+/*  - Without limitation, TCG and its members and licensors disclaim all 	*/
+/*    liability, including liability for infringement of any proprietary 	*/
+/*    rights, relating to use of information in this specification and to the	*/
+/*    implementation of this specification, and TCG disclaims all liability for	*/
+/*    cost of procurement of substitute goods or services, lost profits, loss 	*/
+/*    of use, loss of data or any incidental, consequential, direct, indirect, 	*/
+/*    or special damages, whether under contract, tort, warranty or otherwise, 	*/
+/*    arising in any way out of use or reliance upon this specification or any 	*/
+/*    information herein.							*/
+/*										*/
+/*  (c) Copyright IBM Corp. and others, 2016 - 2020				*/
+/*										*/
+/********************************************************************************/
+
+/* 10.1.2 CryptEcc.h */
+/* 10.1.2.1 Introduction */
+/* This file contains structure definitions used for ECC. The structures in this file are only used
+   internally. The ECC-related structures that cross the TPM interface are defined in TpmTypes.h */
+#ifndef _CRYPT_ECC_H
+#define _CRYPT_ECC_H
+
+/* 10.1.2.2 Structures */
+typedef struct ECC_CURVE
+{
+    const TPM_ECC_CURVE          curveId;
+    const UINT16                 keySizeBits;
+    const TPMT_KDF_SCHEME        kdf;
+    const TPMT_ECC_SCHEME        sign;
+    const ECC_CURVE_DATA        *curveData; // the address of the curve data
+    const BYTE                  *OID;
+} ECC_CURVE;
+
+
+/* 10.1.2.2.1	Macros */
+/* This macro is used to instance an ECC_CURVE_DATA structure for the curve. This structure is
+   referenced by the ECC_CURVE structure */
+#define CURVE_DATA_DEF(CURVE)						\
+    const ECC_CURVE_DATA CURVE = {					\
+	(bigNum)&CURVE##_p_DATA, (bigNum)&CURVE##_n_DATA, (bigNum)&CURVE##_h_DATA, \
+	(bigNum)&CURVE##_a_DATA, (bigNum)&CURVE##_b_DATA,		\
+	{(bigNum)&CURVE##_gX_DATA, (bigNum)&CURVE##_gY_DATA, (bigNum)&BN_ONE} };
+
+extern const ECC_CURVE eccCurves[ECC_CURVE_COUNT];
+
+#define CURVE_DEF(CURVE)						\
+    {									\
+	TPM_ECC_##CURVE,						\
+	    CURVE##_KEY_SIZE,						\
+	    CURVE##_KDF,						\
+	    CURVE##_SIGN,						\
+	    &##CURVE,							\
+	    OID_ECC_##CURVE						\
+	    }
+#define CURVE_NAME(N)
+
+#endif

+ 233 - 0
EVSE/GPL/ibmtpm1682/src/CryptEccCrypt.c

@@ -0,0 +1,233 @@
+/********************************************************************************/
+/*										*/
+/*			  Asymmetric ECC Commands   				*/
+/*			     Written by Ken Goldman				*/
+/*		       IBM Thomas J. Watson Research Center			*/
+/*            $Id$	*/
+/*										*/
+/*  Licenses and Notices							*/
+/*										*/
+/*  1. Copyright Licenses:							*/
+/*										*/
+/*  - Trusted Computing Group (TCG) grants to the user of the source code in	*/
+/*    this specification (the "Source Code") a worldwide, irrevocable, 		*/
+/*    nonexclusive, royalty free, copyright license to reproduce, create 	*/
+/*    derivative works, distribute, display and perform the Source Code and	*/
+/*    derivative works thereof, and to grant others the rights granted herein.	*/
+/*										*/
+/*  - The TCG grants to the user of the other parts of the specification 	*/
+/*    (other than the Source Code) the rights to reproduce, distribute, 	*/
+/*    display, and perform the specification solely for the purpose of 		*/
+/*    developing products based on such documents.				*/
+/*										*/
+/*  2. Source Code Distribution Conditions:					*/
+/*										*/
+/*  - Redistributions of Source Code must retain the above copyright licenses, 	*/
+/*    this list of conditions and the following disclaimers.			*/
+/*										*/
+/*  - Redistributions in binary form must reproduce the above copyright 	*/
+/*    licenses, this list of conditions	and the following disclaimers in the 	*/
+/*    documentation and/or other materials provided with the distribution.	*/
+/*										*/
+/*  3. Disclaimers:								*/
+/*										*/
+/*  - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF	*/
+/*  LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH	*/
+/*  RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES)	*/
+/*  THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE.		*/
+/*  Contact TCG Administration (admin@trustedcomputinggroup.org) for 		*/
+/*  information on specification licensing rights available through TCG 	*/
+/*  membership agreements.							*/
+/*										*/
+/*  - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED 	*/
+/*    WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR 	*/
+/*    FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR 		*/
+/*    NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY 		*/
+/*    OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE.		*/
+/*										*/
+/*  - Without limitation, TCG and its members and licensors disclaim all 	*/
+/*    liability, including liability for infringement of any proprietary 	*/
+/*    rights, relating to use of information in this specification and to the	*/
+/*    implementation of this specification, and TCG disclaims all liability for	*/
+/*    cost of procurement of substitute goods or services, lost profits, loss 	*/
+/*    of use, loss of data or any incidental, consequential, direct, indirect, 	*/
+/*    or special damages, whether under contract, tort, warranty or otherwise, 	*/
+/*    arising in any way out of use or reliance upon this specification or any 	*/
+/*    information herein.							*/
+/*										*/
+/*  (c) Copyright IBM Corp. and others, 2022					*/
+/*										*/
+/********************************************************************************/
+
+
+/* 10.2.28.1	Includes and Defines */
+#include "Tpm.h"
+
+#if CC_ECC_Encrypt || CC_ECC_Encrypt
+/* 10.2.28.2	Functions */
+/* 10.2.28.2.1	CryptEccSelectScheme() */
+/* This function is used by TPM2_ECC_Decrypt and TPM2_ECC_Encrypt.  It sets scheme either the input
+   scheme or the key scheme. If they key scheme is not TPM_ALG_NULL then the input scheme must be
+   TPM_ALG_NULL or the same as the key scheme. If not, then the function returns FALSE. */
+/*     Return Value	Meaning */
+/*     TRUE	scheme is set */
+/*     FALSE	scheme is not valid (it may have been changed). */
+BOOL
+CryptEccSelectScheme(
+		     OBJECT              *key,           //IN: key containing default scheme
+		     TPMT_KDF_SCHEME     *scheme         // IN: a decrypt scheme
+		     )
+{
+    TPMT_KDF_SCHEME    *keyScheme = &key->publicArea.parameters.eccDetail.kdf;
+
+    // Get sign object pointer
+    if(scheme->scheme == TPM_ALG_NULL)
+	*scheme = *keyScheme;
+    if(keyScheme->scheme == TPM_ALG_NULL)
+	keyScheme = scheme;
+    return (scheme->scheme != TPM_ALG_NULL &&
+	    (keyScheme->scheme == scheme->scheme
+	     && keyScheme->details.anyKdf.hashAlg == scheme->details.anyKdf.hashAlg));
+}
+/* 10.2.28.2.2	CryptEccEncrypt() */
+/* This function performs ECC-based data obfuscation. The only scheme that is currently supported is
+   MGF1 based. See Part 1, Annex D for details. */
+/*     Error Return	Meaning */
+/*     TPM_RC_CURVE	unsupported curve */
+/*     TPM_RC_HASH	hash not allowed */
+/*     TPM_RC_SCHEME	scheme is not supported */
+/*     TPM_RC_NO_RESULT	internal error in big number processing */
+LIB_EXPORT TPM_RC
+CryptEccEncrypt(
+		OBJECT                  *key,           // IN: public key of recipient
+		TPMT_KDF_SCHEME         *scheme,        // IN: scheme to use.
+		TPM2B_MAX_BUFFER        *plainText,     // IN: the text to obfuscate
+		TPMS_ECC_POINT          *c1,            // OUT: public ephemeral key
+		TPM2B_MAX_BUFFER        *c2,            // OUT: obfuscated text
+		TPM2B_DIGEST            *c3             // OUT: digest of ephemeral key
+		//      and plainText
+		)
+{
+    CURVE_INITIALIZED(E, key->publicArea.parameters.eccDetail.curveID);
+    POINT_INITIALIZED(PB, &key->publicArea.unique.ecc);
+    POINT_VAR(Px, MAX_ECC_KEY_BITS);
+    TPMS_ECC_POINT          p2;
+    ECC_NUM(D);
+    TPM2B_TYPE(2ECC, MAX_ECC_KEY_BYTES * 2);
+    TPM2B_2ECC              z;
+    int                     i;
+    HASH_STATE              hashState;
+    TPM_RC                  retVal = TPM_RC_SUCCESS;
+    //
+#if defined DEBUG_ECC_ENCRYPT && DEBUG_ECC_ENCRYPT == YES
+    RND_DEBUG           dbg;
+    // This value is one less than the value from the reference so that it
+    // will become the correct value after having one added
+    TPM2B_ECC_PARAMETER k = {24, {
+	    0x38, 0x4F, 0x30, 0x35, 0x30, 0x73, 0xAE, 0xEC,
+	    0xE7, 0xA1, 0x65, 0x43, 0x30, 0xA9, 0x62, 0x04,
+	    0xD3, 0x79, 0x82, 0xA3, 0xE1, 0x5B, 0x2C, 0xB4}};
+    RND_DEBUG_Instantiate(&dbg, &k.b);
+#   define RANDOM      (RAND_STATE *)&dbg
+
+#else
+#   define RANDOM      NULL
+#endif
+    if (E == NULL)
+	ERROR_RETURN(TPM_RC_CURVE);
+    if (TPM_ALG_KDF2 != scheme->scheme)
+	ERROR_RETURN(TPM_RC_SCHEME);
+    // generate an ephemeral key from a random k
+    if (!BnEccGenerateKeyPair(D, Px, E, RANDOM)
+	// C1 is the public part of the ephemeral key
+	|| !BnPointTo2B(c1, Px, E)
+	// Compute P2
+	|| (BnPointMult(Px, PB, D, NULL, NULL, E) != TPM_RC_SUCCESS)
+	|| !BnPointTo2B(&p2, Px, E))
+	ERROR_RETURN(TPM_RC_NO_RESULT);
+
+    //Compute the C3 value hash(x2 || M || y2)
+    if (0 == CryptHashStart(&hashState, scheme->details.mgf1.hashAlg))
+	ERROR_RETURN(TPM_RC_HASH);
+    CryptDigestUpdate2B(&hashState, &p2.x.b);
+    CryptDigestUpdate2B(&hashState, &plainText->b);
+    CryptDigestUpdate2B(&hashState, &p2.y.b);
+    c3->t.size = CryptHashEnd(&hashState, sizeof(c3->t.buffer), c3->t.buffer);
+
+    MemoryCopy2B(&z.b, &p2.x.b, sizeof(z.t.buffer));
+    MemoryConcat2B(&z.b, &p2.y.b, sizeof(z.t.buffer));
+    // Generate the mask value from MGF1 and put it in the return buffer
+    c2->t.size = CryptMGF_KDF(plainText->t.size, c2->t.buffer,
+			      scheme->details.mgf1.hashAlg, z.t.size, z.t.buffer, 1);
+    // XOR the plainText into the generated mask to create the obfuscated data
+    for (i = 0; i < plainText->t.size; i++)
+	c2->t.buffer[i] ^= plainText->t.buffer[i];
+ Exit:
+    CURVE_FREE(E);
+    return retVal;
+}
+/* 10.2.28.2.3	CryptEccDecrypt() */
+/* This function performs ECC decryption and integrity check of the input data. */
+/* Error Return	Meaning */
+/* TPM_RC_CURVE	unsupported curve */
+/* TPM_RC_HASH	hash not allowed */
+/* TPM_RC_SCHEME	scheme is not supported */
+/* TPM_RC_NO_RESULT	internal error in big number processing */
+/* TPM_RC_VALUE	C3 did not match hash of recovered data */
+LIB_EXPORT TPM_RC
+CryptEccDecrypt(
+		OBJECT                  *key,           // IN: key used for data recovery
+		TPMT_KDF_SCHEME         *scheme,        // IN: scheme to use.
+		TPM2B_MAX_BUFFER        *plainText,     // OUT: the recovered text
+		TPMS_ECC_POINT          *c1,            // IN: public ephemeral key
+		TPM2B_MAX_BUFFER        *c2,            // IN: obfuscated text
+		TPM2B_DIGEST            *c3             // IN: digest of ephemeral key
+		//      and plainText
+		)
+{
+    CURVE_INITIALIZED(E, key->publicArea.parameters.eccDetail.curveID);
+    ECC_INITIALIZED(D, &key->sensitive.sensitive.ecc.b);
+    POINT_INITIALIZED(C1, c1);
+    TPMS_ECC_POINT          p2;
+    TPM2B_TYPE(2ECC, MAX_ECC_KEY_BYTES * 2);
+    TPM2B_DIGEST            check;
+    TPM2B_2ECC              z;
+    int                     i;
+    HASH_STATE              hashState;
+    TPM_RC                  retVal = TPM_RC_SUCCESS;
+    //
+    if (E == NULL)
+	ERROR_RETURN(TPM_RC_CURVE);
+    if (TPM_ALG_KDF2 != scheme->scheme)
+	ERROR_RETURN(TPM_RC_SCHEME);
+    // Generate the Z value
+    BnPointMult(C1, C1, D, NULL, NULL, E);
+    BnPointTo2B(&p2, C1, E);
+
+    // Start the hash to check the algorithm
+    if (0 == CryptHashStart(&hashState, scheme->details.mgf1.hashAlg))
+	ERROR_RETURN(TPM_RC_HASH);
+    CryptDigestUpdate2B(&hashState, &p2.x.b);
+
+    MemoryCopy2B(&z.b, &p2.x.b, sizeof(z.t.buffer));
+    MemoryConcat2B(&z.b, &p2.y.b, sizeof(z.t.buffer));
+
+    // Generate the mask
+    plainText->t.size = CryptMGF_KDF(c2->t.size, plainText->t.buffer,
+				     scheme->details.mgf1.hashAlg, z.t.size,
+				     z.t.buffer, 1);
+    // XOR the obfuscated data into the generated mask to create the plainText data
+    for (i = 0; i < plainText->t.size; i++)
+	plainText->t.buffer[i] ^= c2->t.buffer[i];
+
+    // Complete the hash and verify the data
+    CryptDigestUpdate2B(&hashState, &plainText->b);
+    CryptDigestUpdate2B(&hashState, &p2.y.b);
+    check.t.size = CryptHashEnd(&hashState, sizeof(check.t.buffer), check.t.buffer);
+    if (!MemoryEqual2B(&check.b, &c3->b))
+	ERROR_RETURN(TPM_RC_VALUE);
+ Exit:
+    CURVE_FREE(E);
+    return retVal;
+}
+#endif  // CC_ECC_Encrypt ||

+ 92 - 0
EVSE/GPL/ibmtpm1682/src/CryptEccCrypt_fp.h

@@ -0,0 +1,92 @@
+/********************************************************************************/
+/*										*/
+/*			Include Headers for Internal Routines			*/
+/*			     Written by Ken Goldman				*/
+/*		       IBM Thomas J. Watson Research Center			*/
+/*            $Id: CryptEccCrypt_fp.h 1681 2022-04-14 21:45:26Z kgold $	*/
+/*										*/
+/*  Licenses and Notices							*/
+/*										*/
+/*  1. Copyright Licenses:							*/
+/*										*/
+/*  - Trusted Computing Group (TCG) grants to the user of the source code in	*/
+/*    this specification (the "Source Code") a worldwide, irrevocable, 		*/
+/*    nonexclusive, royalty free, copyright license to reproduce, create 	*/
+/*    derivative works, distribute, display and perform the Source Code and	*/
+/*    derivative works thereof, and to grant others the rights granted herein.	*/
+/*										*/
+/*  - The TCG grants to the user of the other parts of the specification 	*/
+/*    (other than the Source Code) the rights to reproduce, distribute, 	*/
+/*    display, and perform the specification solely for the purpose of 		*/
+/*    developing products based on such documents.				*/
+/*										*/
+/*  2. Source Code Distribution Conditions:					*/
+/*										*/
+/*  - Redistributions of Source Code must retain the above copyright licenses, 	*/
+/*    this list of conditions and the following disclaimers.			*/
+/*										*/
+/*  - Redistributions in binary form must reproduce the above copyright 	*/
+/*    licenses, this list of conditions	and the following disclaimers in the 	*/
+/*    documentation and/or other materials provided with the distribution.	*/
+/*										*/
+/*  3. Disclaimers:								*/
+/*										*/
+/*  - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF	*/
+/*  LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH	*/
+/*  RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES)	*/
+/*  THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE.		*/
+/*  Contact TCG Administration (admin@trustedcomputinggroup.org) for 		*/
+/*  information on specification licensing rights available through TCG 	*/
+/*  membership agreements.							*/
+/*										*/
+/*  - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED 	*/
+/*    WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR 	*/
+/*    FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR 		*/
+/*    NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY 		*/
+/*    OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE.		*/
+/*										*/
+/*  - Without limitation, TCG and its members and licensors disclaim all 	*/
+/*    liability, including liability for infringement of any proprietary 	*/
+/*    rights, relating to use of information in this specification and to the	*/
+/*    implementation of this specification, and TCG disclaims all liability for	*/
+/*    cost of procurement of substitute goods or services, lost profits, loss 	*/
+/*    of use, loss of data or any incidental, consequential, direct, indirect, 	*/
+/*    or special damages, whether under contract, tort, warranty or otherwise, 	*/
+/*    arising in any way out of use or reliance upon this specification or any 	*/
+/*    information herein.							*/
+/*										*/
+/*  (c) Copyright IBM Corp. and others, 2020 - 2022				*/
+/*										*/
+/********************************************************************************/
+
+#ifndef CRYPTECCCRYPT_FP_H
+#define CRYPTECCCRYPT_FP_H
+
+BOOL
+CryptEccSelectScheme(
+		     OBJECT              *key,           //IN: key containing default scheme
+		     TPMT_KDF_SCHEME     *scheme         // IN: a decrypt scheme
+		     );
+
+LIB_EXPORT TPM_RC
+CryptEccEncrypt(
+		OBJECT                  *key,           // IN: public key of recipient
+		TPMT_KDF_SCHEME         *scheme,        // IN: scheme to use.
+		TPM2B_MAX_BUFFER        *plainText,     // IN: the text to obfuscate
+		TPMS_ECC_POINT          *c1,            // OUT: public ephemeral key
+		TPM2B_MAX_BUFFER        *c2,            // OUT: obfuscated text
+		TPM2B_DIGEST            *c3             // OUT: digest of ephemeral key
+		//      and plainText
+		);
+LIB_EXPORT TPM_RC
+CryptEccDecrypt(
+		OBJECT                  *key,           // IN: key used for data recovery
+		TPMT_KDF_SCHEME         *scheme,        // IN: scheme to use.
+		TPM2B_MAX_BUFFER        *plainText,     // OUT: the recovered text
+		TPMS_ECC_POINT          *c1,            // IN: public ephemeral key
+		TPM2B_MAX_BUFFER        *c2,            // IN: obfuscated text
+		TPM2B_DIGEST            *c3             // IN: digest of ephemeral key
+		//      and plainText
+		);
+
+#endif

+ 618 - 0
EVSE/GPL/ibmtpm1682/src/CryptEccData.c

@@ -0,0 +1,618 @@
+/********************************************************************************/
+/*										*/
+/*			ECC curve data 						*/
+/*			     Written by Ken Goldman				*/
+/*		       IBM Thomas J. Watson Research Center			*/
+/*            $Id: CryptEccData.c 1658 2021-01-22 23:14:01Z kgoldman $		*/
+/*										*/
+/*  Licenses and Notices							*/
+/*										*/
+/*  1. Copyright Licenses:							*/
+/*										*/
+/*  - Trusted Computing Group (TCG) grants to the user of the source code in	*/
+/*    this specification (the "Source Code") a worldwide, irrevocable, 		*/
+/*    nonexclusive, royalty free, copyright license to reproduce, create 	*/
+/*    derivative works, distribute, display and perform the Source Code and	*/
+/*    derivative works thereof, and to grant others the rights granted herein.	*/
+/*										*/
+/*  - The TCG grants to the user of the other parts of the specification 	*/
+/*    (other than the Source Code) the rights to reproduce, distribute, 	*/
+/*    display, and perform the specification solely for the purpose of 		*/
+/*    developing products based on such documents.				*/
+/*										*/
+/*  2. Source Code Distribution Conditions:					*/
+/*										*/
+/*  - Redistributions of Source Code must retain the above copyright licenses, 	*/
+/*    this list of conditions and the following disclaimers.			*/
+/*										*/
+/*  - Redistributions in binary form must reproduce the above copyright 	*/
+/*    licenses, this list of conditions	and the following disclaimers in the 	*/
+/*    documentation and/or other materials provided with the distribution.	*/
+/*										*/
+/*  3. Disclaimers:								*/
+/*										*/
+/*  - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF	*/
+/*  LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH	*/
+/*  RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES)	*/
+/*  THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE.		*/
+/*  Contact TCG Administration (admin@trustedcomputinggroup.org) for 		*/
+/*  information on specification licensing rights available through TCG 	*/
+/*  membership agreements.							*/
+/*										*/
+/*  - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED 	*/
+/*    WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR 	*/
+/*    FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR 		*/
+/*    NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY 		*/
+/*    OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE.		*/
+/*										*/
+/*  - Without limitation, TCG and its members and licensors disclaim all 	*/
+/*    liability, including liability for infringement of any proprietary 	*/
+/*    rights, relating to use of information in this specification and to the	*/
+/*    implementation of this specification, and TCG disclaims all liability for	*/
+/*    cost of procurement of substitute goods or services, lost profits, loss 	*/
+/*    of use, loss of data or any incidental, consequential, direct, indirect, 	*/
+/*    or special damages, whether under contract, tort, warranty or otherwise, 	*/
+/*    arising in any way out of use or reliance upon this specification or any 	*/
+/*    information herein.							*/
+/*										*/
+/*  (c) Copyright IBM Corp. and others, 2018 - 2021				*/
+/*										*/
+/********************************************************************************/
+
+/* 10.2.8	CryptEccData.c */
+#include "Tpm.h"
+#include "OIDs.h"
+/* This file contains the ECC curve data. The format of the data depends on the setting of
+   USE_BN_ECC_DATA. If it is defined, then the TPM's BigNum() format is used. Otherwise, it is kept
+   in TPM2B format. The purpose of having the data in BigNum() format is so that it does not have to
+   be reformatted before being used by the crypto library. */
+#if ALG_ECC
+#if USE_BN_ECC_DATA
+#       define TO_ECC_64                        TO_CRYPT_WORD_64
+#       define TO_ECC_56(a, b, c, d, e, f, g)   TO_ECC_64(0, a, b, c, d, e, f, g)
+#       define TO_ECC_48(a, b, c, d, e, f)      TO_ECC_64(0, 0, a, b, c, d, e, f)
+#       define TO_ECC_40(a, b, c, d, e)         TO_ECC_64(0, 0, 0, a, b, c, d, e)
+#   if RADIX_BITS > 32
+#       define TO_ECC_32(a, b, c, d)            TO_ECC_64(0, 0, 0, 0, a, b, c, d)
+#       define TO_ECC_24(a, b, c)               TO_ECC_64(0, 0, 0, 0, 0, a, b, c)
+#       define TO_ECC_16(a, b)                  TO_ECC_64(0, 0, 0, 0, 0, 0, a, b)
+#       define TO_ECC_8(a)                      TO_ECC_64(0, 0, 0, 0, 0, 0, 0, a)
+#   else // RADIX_BITS == 32
+#       define TO_ECC_32                        BIG_ENDIAN_BYTES_TO_UINT32
+#       define TO_ECC_24(a, b, c)               TO_ECC_32(0, a, b, c)
+#       define TO_ECC_16(a, b)                  TO_ECC_32(0, 0, a, b)
+#       define TO_ECC_8(a)                      TO_ECC_32(0, 0, 0, a)
+#   endif
+#else // TPM2B_
+#   define TO_ECC_64(a, b, c, d, e, f, g, h) a, b, c, d, e, f, g, h
+#   define TO_ECC_56(a, b, c, d, e, f, g)    a, b, c, d, e, f, g
+#   define TO_ECC_48(a, b, c, d, e, f)       a, b, c, d, e, f
+#   define TO_ECC_40(a, b, c, d, e)          a, b, c, d, e
+#   define TO_ECC_32(a, b, c, d)             a, b, c, d
+#   define TO_ECC_24(a, b, c)                a, b, c
+#   define TO_ECC_16(a, b)                   a, b
+#   define TO_ECC_8(a)                       a
+#endif
+#if USE_BN_ECC_DATA
+#define BN_MIN_ALLOC(bytes)						\
+    (BYTES_TO_CRYPT_WORDS(bytes) == 0) ? 1 : BYTES_TO_CRYPT_WORDS(bytes)
+# define ECC_CONST(NAME, bytes, initializer)				\
+    const struct {							\
+	crypt_uword_t   allocate, size, d[BN_MIN_ALLOC(bytes)];		\
+    } NAME = {BN_MIN_ALLOC(bytes), BYTES_TO_CRYPT_WORDS(bytes),{initializer}}
+	ECC_CONST(ECC_ZERO, 0, 0);
+#else
+# define ECC_CONST(NAME, bytes, initializer)				\
+    const TPM2B_##bytes##_BYTE_VALUE NAME = {bytes, {initializer}}
+/* Have to special case ECC_ZERO */
+TPM2B_BYTE_VALUE(1);
+TPM2B_1_BYTE_VALUE ECC_ZERO = {1, {0}};
+#endif
+ECC_CONST(ECC_ONE, 1, 1);
+#if !USE_BN_ECC_DATA
+TPM2B_BYTE_VALUE(24);
+#define TO_ECC_192(a, b, c)  a, b, c
+TPM2B_BYTE_VALUE(28);
+#define TO_ECC_224(a, b, c, d)   a, b, c, d
+TPM2B_BYTE_VALUE(32);
+#define TO_ECC_256(a, b, c, d)   a, b, c, d
+TPM2B_BYTE_VALUE(48);
+#define TO_ECC_384(a, b, c, d, e, f)     a, b, c, d, e, f
+TPM2B_BYTE_VALUE(66);
+#define TO_ECC_528(a, b, c, d, e, f, g, h, i)    a, b, c, d, e, f, g, h, i
+TPM2B_BYTE_VALUE(80);
+#define TO_ECC_640(a, b, c, d, e, f, g, h, i, j)     a, b, c, d, e, f, g, h, i, j
+#else
+#define TO_ECC_192(a, b, c)  c, b, a
+#define TO_ECC_224(a, b, c, d)   d, c, b, a
+#define TO_ECC_256(a, b, c, d)   d, c, b, a
+#define TO_ECC_384(a, b, c, d, e, f)     f, e, d, c, b, a
+#define TO_ECC_528(a, b, c, d, e, f, g, h, i)    i, h, g, f, e, d, c, b, a
+#define TO_ECC_640(a, b, c, d, e, f, g, h, i, j)     j, i, h, g, f, e, d, c, b, a
+#endif // !USE_BN_ECC_DATA
+#if ECC_NIST_P192
+ECC_CONST(NIST_P192_p, 24, TO_ECC_192(
+				      TO_ECC_64(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF),
+				      TO_ECC_64(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE),
+				      TO_ECC_64(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF)));
+ECC_CONST(NIST_P192_a, 24, TO_ECC_192(
+				      TO_ECC_64(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF),
+				      TO_ECC_64(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE),
+				      TO_ECC_64(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC)));
+ECC_CONST(NIST_P192_b, 24, TO_ECC_192(
+				      TO_ECC_64(0x64, 0x21, 0x05, 0x19, 0xE5, 0x9C, 0x80, 0xE7),
+				      TO_ECC_64(0x0F, 0xA7, 0xE9, 0xAB, 0x72, 0x24, 0x30, 0x49),
+				      TO_ECC_64(0xFE, 0xB8, 0xDE, 0xEC, 0xC1, 0x46, 0xB9, 0xB1)));
+ECC_CONST(NIST_P192_gX, 24, TO_ECC_192(
+				       TO_ECC_64(0x18, 0x8D, 0xA8, 0x0E, 0xB0, 0x30, 0x90, 0xF6),
+				       TO_ECC_64(0x7C, 0xBF, 0x20, 0xEB, 0x43, 0xA1, 0x88, 0x00),
+				       TO_ECC_64(0xF4, 0xFF, 0x0A, 0xFD, 0x82, 0xFF, 0x10, 0x12)));
+ECC_CONST(NIST_P192_gY, 24, TO_ECC_192(
+				       TO_ECC_64(0x07, 0x19, 0x2B, 0x95, 0xFF, 0xC8, 0xDA, 0x78),
+				       TO_ECC_64(0x63, 0x10, 0x11, 0xED, 0x6B, 0x24, 0xCD, 0xD5),
+				       TO_ECC_64(0x73, 0xF9, 0x77, 0xA1, 0x1E, 0x79, 0x48, 0x11)));
+ECC_CONST(NIST_P192_n, 24, TO_ECC_192(
+				      TO_ECC_64(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF),
+				      TO_ECC_64(0xFF, 0xFF, 0xFF, 0xFF, 0x99, 0xDE, 0xF8, 0x36),
+				      TO_ECC_64(0x14, 0x6B, 0xC9, 0xB1, 0xB4, 0xD2, 0x28, 0x31)));
+#define NIST_P192_h         ECC_ONE
+#define NIST_P192_gZ        ECC_ONE
+#if USE_BN_ECC_DATA
+const ECC_CURVE_DATA NIST_P192 = {
+				  (bigNum)&NIST_P192_p, (bigNum)&NIST_P192_n, (bigNum)&NIST_P192_h,
+				  (bigNum)&NIST_P192_a, (bigNum)&NIST_P192_b,
+				  {(bigNum)&NIST_P192_gX, (bigNum)&NIST_P192_gY, (bigNum)&NIST_P192_gZ}};
+#else
+const ECC_CURVE_DATA NIST_P192 = {
+				  &NIST_P192_p.b, &NIST_P192_n.b, &NIST_P192_h.b,
+				  &NIST_P192_a.b, &NIST_P192_b.b,
+				  {&NIST_P192_gX.b, &NIST_P192_gY.b, &NIST_P192_gZ.b}};
+#endif // USE_BN_ECC_DATA
+#endif // ECC_NIST_P192
+#if ECC_NIST_P224
+ECC_CONST(NIST_P224_p, 28, TO_ECC_224(
+				      TO_ECC_32(0xFF, 0xFF, 0xFF, 0xFF),
+				      TO_ECC_64(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF),
+				      TO_ECC_64(0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00),
+				      TO_ECC_64(0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01)));
+ECC_CONST(NIST_P224_a, 28, TO_ECC_224(
+				      TO_ECC_32(0xFF, 0xFF, 0xFF, 0xFF),
+				      TO_ECC_64(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF),
+				      TO_ECC_64(0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF),
+				      TO_ECC_64(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE)));
+ECC_CONST(NIST_P224_b, 28, TO_ECC_224(
+				      TO_ECC_32(0xB4, 0x05, 0x0A, 0x85),
+				      TO_ECC_64(0x0C, 0x04, 0xB3, 0xAB, 0xF5, 0x41, 0x32, 0x56),
+				      TO_ECC_64(0x50, 0x44, 0xB0, 0xB7, 0xD7, 0xBF, 0xD8, 0xBA),
+				      TO_ECC_64(0x27, 0x0B, 0x39, 0x43, 0x23, 0x55, 0xFF, 0xB4)));
+ECC_CONST(NIST_P224_gX, 28, TO_ECC_224(
+				       TO_ECC_32(0xB7, 0x0E, 0x0C, 0xBD),
+				       TO_ECC_64(0x6B, 0xB4, 0xBF, 0x7F, 0x32, 0x13, 0x90, 0xB9),
+				       TO_ECC_64(0x4A, 0x03, 0xC1, 0xD3, 0x56, 0xC2, 0x11, 0x22),
+				       TO_ECC_64(0x34, 0x32, 0x80, 0xD6, 0x11, 0x5C, 0x1D, 0x21)));
+ECC_CONST(NIST_P224_gY, 28, TO_ECC_224(
+				       TO_ECC_32(0xBD, 0x37, 0x63, 0x88),
+				       TO_ECC_64(0xB5, 0xF7, 0x23, 0xFB, 0x4C, 0x22, 0xDF, 0xE6),
+				       TO_ECC_64(0xCD, 0x43, 0x75, 0xA0, 0x5A, 0x07, 0x47, 0x64),
+				       TO_ECC_64(0x44, 0xD5, 0x81, 0x99, 0x85, 0x00, 0x7E, 0x34)));
+ECC_CONST(NIST_P224_n, 28, TO_ECC_224(
+				      TO_ECC_32(0xFF, 0xFF, 0xFF, 0xFF),
+				      TO_ECC_64(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF),
+				      TO_ECC_64(0xFF, 0xFF, 0x16, 0xA2, 0xE0, 0xB8, 0xF0, 0x3E),
+				      TO_ECC_64(0x13, 0xDD, 0x29, 0x45, 0x5C, 0x5C, 0x2A, 0x3D)));
+#define NIST_P224_h         ECC_ONE
+#define NIST_P224_gZ        ECC_ONE
+#if USE_BN_ECC_DATA
+const ECC_CURVE_DATA NIST_P224 = {
+				  (bigNum)&NIST_P224_p, (bigNum)&NIST_P224_n, (bigNum)&NIST_P224_h,
+				  (bigNum)&NIST_P224_a, (bigNum)&NIST_P224_b,
+				  {(bigNum)&NIST_P224_gX, (bigNum)&NIST_P224_gY, (bigNum)&NIST_P224_gZ}};
+#else
+const ECC_CURVE_DATA NIST_P224 = {
+				  &NIST_P224_p.b, &NIST_P224_n.b, &NIST_P224_h.b,
+				  &NIST_P224_a.b, &NIST_P224_b.b,
+				  {&NIST_P224_gX.b, &NIST_P224_gY.b, &NIST_P224_gZ.b}};
+#endif // USE_BN_ECC_DATA
+#endif // ECC_NIST_P224
+#if ECC_NIST_P256
+ECC_CONST(NIST_P256_p, 32, TO_ECC_256(
+				      TO_ECC_64(0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x01),
+				      TO_ECC_64(0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00),
+				      TO_ECC_64(0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF),
+				      TO_ECC_64(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF)));
+ECC_CONST(NIST_P256_a, 32, TO_ECC_256(
+				      TO_ECC_64(0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x01),
+				      TO_ECC_64(0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00),
+				      TO_ECC_64(0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF),
+				      TO_ECC_64(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC)));
+ECC_CONST(NIST_P256_b, 32, TO_ECC_256(
+				      TO_ECC_64(0x5A, 0xC6, 0x35, 0xD8, 0xAA, 0x3A, 0x93, 0xE7),
+				      TO_ECC_64(0xB3, 0xEB, 0xBD, 0x55, 0x76, 0x98, 0x86, 0xBC),
+				      TO_ECC_64(0x65, 0x1D, 0x06, 0xB0, 0xCC, 0x53, 0xB0, 0xF6),
+				      TO_ECC_64(0x3B, 0xCE, 0x3C, 0x3E, 0x27, 0xD2, 0x60, 0x4B)));
+ECC_CONST(NIST_P256_gX, 32, TO_ECC_256(
+				       TO_ECC_64(0x6B, 0x17, 0xD1, 0xF2, 0xE1, 0x2C, 0x42, 0x47),
+				       TO_ECC_64(0xF8, 0xBC, 0xE6, 0xE5, 0x63, 0xA4, 0x40, 0xF2),
+				       TO_ECC_64(0x77, 0x03, 0x7D, 0x81, 0x2D, 0xEB, 0x33, 0xA0),
+				       TO_ECC_64(0xF4, 0xA1, 0x39, 0x45, 0xD8, 0x98, 0xC2, 0x96)));
+ECC_CONST(NIST_P256_gY, 32, TO_ECC_256(
+				       TO_ECC_64(0x4F, 0xE3, 0x42, 0xE2, 0xFE, 0x1A, 0x7F, 0x9B),
+				       TO_ECC_64(0x8E, 0xE7, 0xEB, 0x4A, 0x7C, 0x0F, 0x9E, 0x16),
+				       TO_ECC_64(0x2B, 0xCE, 0x33, 0x57, 0x6B, 0x31, 0x5E, 0xCE),
+				       TO_ECC_64(0xCB, 0xB6, 0x40, 0x68, 0x37, 0xBF, 0x51, 0xF5)));
+ECC_CONST(NIST_P256_n, 32, TO_ECC_256(
+				      TO_ECC_64(0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00),
+				      TO_ECC_64(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF),
+				      TO_ECC_64(0xBC, 0xE6, 0xFA, 0xAD, 0xA7, 0x17, 0x9E, 0x84),
+				      TO_ECC_64(0xF3, 0xB9, 0xCA, 0xC2, 0xFC, 0x63, 0x25, 0x51)));
+#define NIST_P256_h         ECC_ONE
+#define NIST_P256_gZ        ECC_ONE
+#if USE_BN_ECC_DATA
+const ECC_CURVE_DATA NIST_P256 = {
+				  (bigNum)&NIST_P256_p, (bigNum)&NIST_P256_n, (bigNum)&NIST_P256_h,
+				  (bigNum)&NIST_P256_a, (bigNum)&NIST_P256_b,
+				  {(bigNum)&NIST_P256_gX, (bigNum)&NIST_P256_gY, (bigNum)&NIST_P256_gZ}};
+#else
+const ECC_CURVE_DATA NIST_P256 = {
+				  &NIST_P256_p.b, &NIST_P256_n.b, &NIST_P256_h.b,
+				  &NIST_P256_a.b, &NIST_P256_b.b,
+				  {&NIST_P256_gX.b, &NIST_P256_gY.b, &NIST_P256_gZ.b}};
+#endif // USE_BN_ECC_DATA
+#endif // ECC_NIST_P256
+#if ECC_NIST_P384
+ECC_CONST(NIST_P384_p, 48, TO_ECC_384(
+				      TO_ECC_64(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF),
+				      TO_ECC_64(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF),
+				      TO_ECC_64(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF),
+				      TO_ECC_64(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE),
+				      TO_ECC_64(0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00),
+				      TO_ECC_64(0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF)));
+ECC_CONST(NIST_P384_a, 48, TO_ECC_384(
+				      TO_ECC_64(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF),
+				      TO_ECC_64(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF),
+				      TO_ECC_64(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF),
+				      TO_ECC_64(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE),
+				      TO_ECC_64(0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00),
+				      TO_ECC_64(0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFC)));
+ECC_CONST(NIST_P384_b, 48, TO_ECC_384(
+				      TO_ECC_64(0xB3, 0x31, 0x2F, 0xA7, 0xE2, 0x3E, 0xE7, 0xE4),
+				      TO_ECC_64(0x98, 0x8E, 0x05, 0x6B, 0xE3, 0xF8, 0x2D, 0x19),
+				      TO_ECC_64(0x18, 0x1D, 0x9C, 0x6E, 0xFE, 0x81, 0x41, 0x12),
+				      TO_ECC_64(0x03, 0x14, 0x08, 0x8F, 0x50, 0x13, 0x87, 0x5A),
+				      TO_ECC_64(0xC6, 0x56, 0x39, 0x8D, 0x8A, 0x2E, 0xD1, 0x9D),
+				      TO_ECC_64(0x2A, 0x85, 0xC8, 0xED, 0xD3, 0xEC, 0x2A, 0xEF)));
+ECC_CONST(NIST_P384_gX, 48, TO_ECC_384(
+				       TO_ECC_64(0xAA, 0x87, 0xCA, 0x22, 0xBE, 0x8B, 0x05, 0x37),
+				       TO_ECC_64(0x8E, 0xB1, 0xC7, 0x1E, 0xF3, 0x20, 0xAD, 0x74),
+				       TO_ECC_64(0x6E, 0x1D, 0x3B, 0x62, 0x8B, 0xA7, 0x9B, 0x98),
+				       TO_ECC_64(0x59, 0xF7, 0x41, 0xE0, 0x82, 0x54, 0x2A, 0x38),
+				       TO_ECC_64(0x55, 0x02, 0xF2, 0x5D, 0xBF, 0x55, 0x29, 0x6C),
+				       TO_ECC_64(0x3A, 0x54, 0x5E, 0x38, 0x72, 0x76, 0x0A, 0xB7)));
+ECC_CONST(NIST_P384_gY, 48, TO_ECC_384(
+				       TO_ECC_64(0x36, 0x17, 0xDE, 0x4A, 0x96, 0x26, 0x2C, 0x6F),
+				       TO_ECC_64(0x5D, 0x9E, 0x98, 0xBF, 0x92, 0x92, 0xDC, 0x29),
+				       TO_ECC_64(0xF8, 0xF4, 0x1D, 0xBD, 0x28, 0x9A, 0x14, 0x7C),
+				       TO_ECC_64(0xE9, 0xDA, 0x31, 0x13, 0xB5, 0xF0, 0xB8, 0xC0),
+				       TO_ECC_64(0x0A, 0x60, 0xB1, 0xCE, 0x1D, 0x7E, 0x81, 0x9D),
+				       TO_ECC_64(0x7A, 0x43, 0x1D, 0x7C, 0x90, 0xEA, 0x0E, 0x5F)));
+ECC_CONST(NIST_P384_n, 48, TO_ECC_384(
+				      TO_ECC_64(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF),
+				      TO_ECC_64(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF),
+				      TO_ECC_64(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF),
+				      TO_ECC_64(0xC7, 0x63, 0x4D, 0x81, 0xF4, 0x37, 0x2D, 0xDF),
+				      TO_ECC_64(0x58, 0x1A, 0x0D, 0xB2, 0x48, 0xB0, 0xA7, 0x7A),
+				      TO_ECC_64(0xEC, 0xEC, 0x19, 0x6A, 0xCC, 0xC5, 0x29, 0x73)));
+#define NIST_P384_h         ECC_ONE
+#define NIST_P384_gZ        ECC_ONE
+#if USE_BN_ECC_DATA
+const ECC_CURVE_DATA NIST_P384 = {
+				  (bigNum)&NIST_P384_p, (bigNum)&NIST_P384_n, (bigNum)&NIST_P384_h,
+				  (bigNum)&NIST_P384_a, (bigNum)&NIST_P384_b,
+				  {(bigNum)&NIST_P384_gX, (bigNum)&NIST_P384_gY, (bigNum)&NIST_P384_gZ}};
+#else
+const ECC_CURVE_DATA NIST_P384 = {
+				  &NIST_P384_p.b, &NIST_P384_n.b, &NIST_P384_h.b,
+				  &NIST_P384_a.b, &NIST_P384_b.b,
+				  {&NIST_P384_gX.b, &NIST_P384_gY.b, &NIST_P384_gZ.b}};
+#endif // USE_BN_ECC_DATA
+#endif // ECC_NIST_P384
+#if ECC_NIST_P521
+ECC_CONST(NIST_P521_p, 66, TO_ECC_528(
+				      TO_ECC_16(0x01, 0xFF),
+				      TO_ECC_64(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF),
+				      TO_ECC_64(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF),
+				      TO_ECC_64(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF),
+				      TO_ECC_64(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF),
+				      TO_ECC_64(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF),
+				      TO_ECC_64(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF),
+				      TO_ECC_64(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF),
+				      TO_ECC_64(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF)));
+ECC_CONST(NIST_P521_a, 66, TO_ECC_528(
+				      TO_ECC_16(0x01, 0xFF),
+				      TO_ECC_64(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF),
+				      TO_ECC_64(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF),
+				      TO_ECC_64(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF),
+				      TO_ECC_64(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF),
+				      TO_ECC_64(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF),
+				      TO_ECC_64(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF),
+				      TO_ECC_64(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF),
+				      TO_ECC_64(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC)));
+ECC_CONST(NIST_P521_b, 66, TO_ECC_528(
+				      TO_ECC_16(0x00, 0x51),
+				      TO_ECC_64(0x95, 0x3E, 0xB9, 0x61, 0x8E, 0x1C, 0x9A, 0x1F),
+				      TO_ECC_64(0x92, 0x9A, 0x21, 0xA0, 0xB6, 0x85, 0x40, 0xEE),
+				      TO_ECC_64(0xA2, 0xDA, 0x72, 0x5B, 0x99, 0xB3, 0x15, 0xF3),
+				      TO_ECC_64(0xB8, 0xB4, 0x89, 0x91, 0x8E, 0xF1, 0x09, 0xE1),
+				      TO_ECC_64(0x56, 0x19, 0x39, 0x51, 0xEC, 0x7E, 0x93, 0x7B),
+				      TO_ECC_64(0x16, 0x52, 0xC0, 0xBD, 0x3B, 0xB1, 0xBF, 0x07),
+				      TO_ECC_64(0x35, 0x73, 0xDF, 0x88, 0x3D, 0x2C, 0x34, 0xF1),
+				      TO_ECC_64(0xEF, 0x45, 0x1F, 0xD4, 0x6B, 0x50, 0x3F, 0x00)));
+ECC_CONST(NIST_P521_gX, 66, TO_ECC_528(
+				       TO_ECC_16(0x00, 0xC6),
+				       TO_ECC_64(0x85, 0x8E, 0x06, 0xB7, 0x04, 0x04, 0xE9, 0xCD),
+				       TO_ECC_64(0x9E, 0x3E, 0xCB, 0x66, 0x23, 0x95, 0xB4, 0x42),
+				       TO_ECC_64(0x9C, 0x64, 0x81, 0x39, 0x05, 0x3F, 0xB5, 0x21),
+				       TO_ECC_64(0xF8, 0x28, 0xAF, 0x60, 0x6B, 0x4D, 0x3D, 0xBA),
+				       TO_ECC_64(0xA1, 0x4B, 0x5E, 0x77, 0xEF, 0xE7, 0x59, 0x28),
+				       TO_ECC_64(0xFE, 0x1D, 0xC1, 0x27, 0xA2, 0xFF, 0xA8, 0xDE),
+				       TO_ECC_64(0x33, 0x48, 0xB3, 0xC1, 0x85, 0x6A, 0x42, 0x9B),
+				       TO_ECC_64(0xF9, 0x7E, 0x7E, 0x31, 0xC2, 0xE5, 0xBD, 0x66)));
+ECC_CONST(NIST_P521_gY, 66, TO_ECC_528(
+				       TO_ECC_16(0x01, 0x18),
+				       TO_ECC_64(0x39, 0x29, 0x6A, 0x78, 0x9A, 0x3B, 0xC0, 0x04),
+				       TO_ECC_64(0x5C, 0x8A, 0x5F, 0xB4, 0x2C, 0x7D, 0x1B, 0xD9),
+				       TO_ECC_64(0x98, 0xF5, 0x44, 0x49, 0x57, 0x9B, 0x44, 0x68),
+				       TO_ECC_64(0x17, 0xAF, 0xBD, 0x17, 0x27, 0x3E, 0x66, 0x2C),
+				       TO_ECC_64(0x97, 0xEE, 0x72, 0x99, 0x5E, 0xF4, 0x26, 0x40),
+				       TO_ECC_64(0xC5, 0x50, 0xB9, 0x01, 0x3F, 0xAD, 0x07, 0x61),
+				       TO_ECC_64(0x35, 0x3C, 0x70, 0x86, 0xA2, 0x72, 0xC2, 0x40),
+				       TO_ECC_64(0x88, 0xBE, 0x94, 0x76, 0x9F, 0xD1, 0x66, 0x50)));
+ECC_CONST(NIST_P521_n, 66, TO_ECC_528(
+				      TO_ECC_16(0x01, 0xFF),
+				      TO_ECC_64(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF),
+				      TO_ECC_64(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF),
+				      TO_ECC_64(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF),
+				      TO_ECC_64(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFA),
+				      TO_ECC_64(0x51, 0x86, 0x87, 0x83, 0xBF, 0x2F, 0x96, 0x6B),
+				      TO_ECC_64(0x7F, 0xCC, 0x01, 0x48, 0xF7, 0x09, 0xA5, 0xD0),
+				      TO_ECC_64(0x3B, 0xB5, 0xC9, 0xB8, 0x89, 0x9C, 0x47, 0xAE),
+				      TO_ECC_64(0xBB, 0x6F, 0xB7, 0x1E, 0x91, 0x38, 0x64, 0x09)));
+#define NIST_P521_h         ECC_ONE
+#define NIST_P521_gZ        ECC_ONE
+#if USE_BN_ECC_DATA
+const ECC_CURVE_DATA NIST_P521 = {
+				  (bigNum)&NIST_P521_p, (bigNum)&NIST_P521_n, (bigNum)&NIST_P521_h,
+				  (bigNum)&NIST_P521_a, (bigNum)&NIST_P521_b,
+				  {(bigNum)&NIST_P521_gX, (bigNum)&NIST_P521_gY, (bigNum)&NIST_P521_gZ}};
+#else
+const ECC_CURVE_DATA NIST_P521 = {
+				  &NIST_P521_p.b, &NIST_P521_n.b, &NIST_P521_h.b,
+				  &NIST_P521_a.b, &NIST_P521_b.b,
+				  {&NIST_P521_gX.b, &NIST_P521_gY.b, &NIST_P521_gZ.b}};
+#endif // USE_BN_ECC_DATA
+#endif // ECC_NIST_P521
+#if ECC_BN_P256
+ECC_CONST(BN_P256_p, 32, TO_ECC_256(
+				    TO_ECC_64(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0xF0, 0xCD),
+				    TO_ECC_64(0x46, 0xE5, 0xF2, 0x5E, 0xEE, 0x71, 0xA4, 0x9F),
+				    TO_ECC_64(0x0C, 0xDC, 0x65, 0xFB, 0x12, 0x98, 0x0A, 0x82),
+				    TO_ECC_64(0xD3, 0x29, 0x2D, 0xDB, 0xAE, 0xD3, 0x30, 0x13)));
+#define BN_P256_a           ECC_ZERO
+ECC_CONST(BN_P256_b, 1, TO_ECC_8(3));
+#define BN_P256_gX          ECC_ONE
+ECC_CONST(BN_P256_gY, 1, TO_ECC_8(2));
+ECC_CONST(BN_P256_n, 32, TO_ECC_256(
+				    TO_ECC_64(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0xF0, 0xCD),
+				    TO_ECC_64(0x46, 0xE5, 0xF2, 0x5E, 0xEE, 0x71, 0xA4, 0x9E),
+				    TO_ECC_64(0x0C, 0xDC, 0x65, 0xFB, 0x12, 0x99, 0x92, 0x1A),
+				    TO_ECC_64(0xF6, 0x2D, 0x53, 0x6C, 0xD1, 0x0B, 0x50, 0x0D)));
+#define BN_P256_h           ECC_ONE
+#define BN_P256_gZ          ECC_ONE
+#if USE_BN_ECC_DATA
+const ECC_CURVE_DATA BN_P256 = {
+				(bigNum)&BN_P256_p, (bigNum)&BN_P256_n, (bigNum)&BN_P256_h,
+				(bigNum)&BN_P256_a, (bigNum)&BN_P256_b,
+				{(bigNum)&BN_P256_gX, (bigNum)&BN_P256_gY, (bigNum)&BN_P256_gZ}};
+#else
+const ECC_CURVE_DATA BN_P256 = {
+				&BN_P256_p.b, &BN_P256_n.b, &BN_P256_h.b,
+				&BN_P256_a.b, &BN_P256_b.b,
+				{&BN_P256_gX.b, &BN_P256_gY.b, &BN_P256_gZ.b}};
+#endif // USE_BN_ECC_DATA
+#endif // ECC_BN_P256
+#if ECC_BN_P638
+ECC_CONST(BN_P638_p, 80, TO_ECC_640(
+				    TO_ECC_64(0x23, 0xFF, 0xFF, 0xFD, 0xC0, 0x00, 0x00, 0x0D),
+				    TO_ECC_64(0x7F, 0xFF, 0xFF, 0xB8, 0x00, 0x00, 0x01, 0xD3),
+				    TO_ECC_64(0xFF, 0xFF, 0xF9, 0x42, 0xD0, 0x00, 0x16, 0x5E),
+				    TO_ECC_64(0x3F, 0xFF, 0x94, 0x87, 0x00, 0x00, 0xD5, 0x2F),
+				    TO_ECC_64(0xFF, 0xFD, 0xD0, 0xE0, 0x00, 0x08, 0xDE, 0x55),
+				    TO_ECC_64(0xC0, 0x00, 0x86, 0x52, 0x00, 0x21, 0xE5, 0x5B),
+				    TO_ECC_64(0xFF, 0xFF, 0xF5, 0x1F, 0xFF, 0xF4, 0xEB, 0x80),
+				    TO_ECC_64(0x00, 0x00, 0x00, 0x4C, 0x80, 0x01, 0x5A, 0xCD),
+				    TO_ECC_64(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xEC, 0xE0),
+				    TO_ECC_64(0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x67)));
+#define BN_P638_a           ECC_ZERO
+ECC_CONST(BN_P638_b, 2, TO_ECC_16(0x01,0x01));
+ECC_CONST(BN_P638_gX, 80, TO_ECC_640(
+				     TO_ECC_64(0x23, 0xFF, 0xFF, 0xFD, 0xC0, 0x00, 0x00, 0x0D),
+				     TO_ECC_64(0x7F, 0xFF, 0xFF, 0xB8, 0x00, 0x00, 0x01, 0xD3),
+				     TO_ECC_64(0xFF, 0xFF, 0xF9, 0x42, 0xD0, 0x00, 0x16, 0x5E),
+				     TO_ECC_64(0x3F, 0xFF, 0x94, 0x87, 0x00, 0x00, 0xD5, 0x2F),
+				     TO_ECC_64(0xFF, 0xFD, 0xD0, 0xE0, 0x00, 0x08, 0xDE, 0x55),
+				     TO_ECC_64(0xC0, 0x00, 0x86, 0x52, 0x00, 0x21, 0xE5, 0x5B),
+				     TO_ECC_64(0xFF, 0xFF, 0xF5, 0x1F, 0xFF, 0xF4, 0xEB, 0x80),
+				     TO_ECC_64(0x00, 0x00, 0x00, 0x4C, 0x80, 0x01, 0x5A, 0xCD),
+				     TO_ECC_64(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xEC, 0xE0),
+				     TO_ECC_64(0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x66)));
+ECC_CONST(BN_P638_gY, 1, TO_ECC_8(0x10));
+ECC_CONST(BN_P638_n, 80, TO_ECC_640(
+				    TO_ECC_64(0x23, 0xFF, 0xFF, 0xFD, 0xC0, 0x00, 0x00, 0x0D),
+				    TO_ECC_64(0x7F, 0xFF, 0xFF, 0xB8, 0x00, 0x00, 0x01, 0xD3),
+				    TO_ECC_64(0xFF, 0xFF, 0xF9, 0x42, 0xD0, 0x00, 0x16, 0x5E),
+				    TO_ECC_64(0x3F, 0xFF, 0x94, 0x87, 0x00, 0x00, 0xD5, 0x2F),
+				    TO_ECC_64(0xFF, 0xFD, 0xD0, 0xE0, 0x00, 0x08, 0xDE, 0x55),
+				    TO_ECC_64(0x60, 0x00, 0x86, 0x55, 0x00, 0x21, 0xE5, 0x55),
+				    TO_ECC_64(0xFF, 0xFF, 0xF5, 0x4F, 0xFF, 0xF4, 0xEA, 0xC0),
+				    TO_ECC_64(0x00, 0x00, 0x00, 0x49, 0x80, 0x01, 0x54, 0xD9),
+				    TO_ECC_64(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xED, 0xA0),
+				    TO_ECC_64(0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x61)));
+#define BN_P638_h           ECC_ONE
+#define BN_P638_gZ          ECC_ONE
+#if USE_BN_ECC_DATA
+const ECC_CURVE_DATA BN_P638 = {
+				(bigNum)&BN_P638_p, (bigNum)&BN_P638_n, (bigNum)&BN_P638_h,
+				(bigNum)&BN_P638_a, (bigNum)&BN_P638_b,
+				{(bigNum)&BN_P638_gX, (bigNum)&BN_P638_gY, (bigNum)&BN_P638_gZ}};
+#else
+const ECC_CURVE_DATA BN_P638 = {
+				&BN_P638_p.b, &BN_P638_n.b, &BN_P638_h.b,
+				&BN_P638_a.b, &BN_P638_b.b,
+				{&BN_P638_gX.b, &BN_P638_gY.b, &BN_P638_gZ.b}};
+#endif // USE_BN_ECC_DATA
+#endif // ECC_BN_P638
+#if ECC_SM2_P256
+ECC_CONST(SM2_P256_p, 32, TO_ECC_256(
+				     TO_ECC_64(0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF),
+				     TO_ECC_64(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF),
+				     TO_ECC_64(0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00),
+				     TO_ECC_64(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF)));
+ECC_CONST(SM2_P256_a, 32, TO_ECC_256(
+				     TO_ECC_64(0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF),
+				     TO_ECC_64(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF),
+				     TO_ECC_64(0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00),
+				     TO_ECC_64(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC)));
+ECC_CONST(SM2_P256_b, 32, TO_ECC_256(
+				     TO_ECC_64(0x28, 0xE9, 0xFA, 0x9E, 0x9D, 0x9F, 0x5E, 0x34),
+				     TO_ECC_64(0x4D, 0x5A, 0x9E, 0x4B, 0xCF, 0x65, 0x09, 0xA7),
+				     TO_ECC_64(0xF3, 0x97, 0x89, 0xF5, 0x15, 0xAB, 0x8F, 0x92),
+				     TO_ECC_64(0xDD, 0xBC, 0xBD, 0x41, 0x4D, 0x94, 0x0E, 0x93)));
+ECC_CONST(SM2_P256_gX, 32, TO_ECC_256(
+				      TO_ECC_64(0x32, 0xC4, 0xAE, 0x2C, 0x1F, 0x19, 0x81, 0x19),
+				      TO_ECC_64(0x5F, 0x99, 0x04, 0x46, 0x6A, 0x39, 0xC9, 0x94),
+				      TO_ECC_64(0x8F, 0xE3, 0x0B, 0xBF, 0xF2, 0x66, 0x0B, 0xE1),
+				      TO_ECC_64(0x71, 0x5A, 0x45, 0x89, 0x33, 0x4C, 0x74, 0xC7)));
+ECC_CONST(SM2_P256_gY, 32, TO_ECC_256(
+				      TO_ECC_64(0xBC, 0x37, 0x36, 0xA2, 0xF4, 0xF6, 0x77, 0x9C),
+				      TO_ECC_64(0x59, 0xBD, 0xCE, 0xE3, 0x6B, 0x69, 0x21, 0x53),
+				      TO_ECC_64(0xD0, 0xA9, 0x87, 0x7C, 0xC6, 0x2A, 0x47, 0x40),
+				      TO_ECC_64(0x02, 0xDF, 0x32, 0xE5, 0x21, 0x39, 0xF0, 0xA0)));
+ECC_CONST(SM2_P256_n, 32, TO_ECC_256(
+				     TO_ECC_64(0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF),
+				     TO_ECC_64(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF),
+				     TO_ECC_64(0x72, 0x03, 0xDF, 0x6B, 0x21, 0xC6, 0x05, 0x2B),
+				     TO_ECC_64(0x53, 0xBB, 0xF4, 0x09, 0x39, 0xD5, 0x41, 0x23)));
+#define SM2_P256_h          ECC_ONE
+#define SM2_P256_gZ         ECC_ONE
+#if USE_BN_ECC_DATA
+const ECC_CURVE_DATA SM2_P256 = {
+				 (bigNum)&SM2_P256_p, (bigNum)&SM2_P256_n, (bigNum)&SM2_P256_h,
+				 (bigNum)&SM2_P256_a, (bigNum)&SM2_P256_b,
+				 {(bigNum)&SM2_P256_gX, (bigNum)&SM2_P256_gY, (bigNum)&SM2_P256_gZ}};
+#else
+const ECC_CURVE_DATA SM2_P256 = {
+				 &SM2_P256_p.b, &SM2_P256_n.b, &SM2_P256_h.b,
+				 &SM2_P256_a.b, &SM2_P256_b.b,
+				 {&SM2_P256_gX.b, &SM2_P256_gY.b, &SM2_P256_gZ.b}};
+#endif // USE_BN_ECC_DATA
+#endif // ECC_SM2_P256
+#define comma
+const ECC_CURVE   eccCurves[] = {
+#if ECC_NIST_P192
+				 comma
+				 {TPM_ECC_NIST_P192,
+				  192,
+				  {TPM_ALG_KDF1_SP800_56A, {{TPM_ALG_SHA256}}},
+				  {TPM_ALG_NULL, {{TPM_ALG_NULL}}},
+				  &NIST_P192,
+				  OID_ECC_NIST_P192
+				  CURVE_NAME("NIST_P192")}
+#   undef comma
+#   define comma ,
+#endif // ECC_NIST_P192
+#if ECC_NIST_P224
+				 comma
+				 {TPM_ECC_NIST_P224,
+				  224,
+				  {TPM_ALG_KDF1_SP800_56A_, {{TPM_ALG_SHA256}}},
+				  {TPM_ALG_NULL, {{TPM_ALG_NULL}}},
+				  &NIST_P224,
+				  OID_ECC_NIST_P224
+				  CURVE_NAME("NIST_P224")}
+#   undef comma
+#   define comma ,
+#endif // ECC_NIST_P224
+#if ECC_NIST_P256
+				 comma
+				 {TPM_ECC_NIST_P256,
+				  256,
+				  {TPM_ALG_KDF1_SP800_56A, {{TPM_ALG_SHA256}}},
+				  {TPM_ALG_NULL, {{TPM_ALG_NULL}}},
+				  &NIST_P256,
+				  OID_ECC_NIST_P256
+				  CURVE_NAME("NIST_P256")}
+#   undef comma
+#   define comma ,
+#endif // ECC_NIST_P256
+#if ECC_NIST_P384
+				 comma
+				 {TPM_ECC_NIST_P384,
+				  384,
+				  {TPM_ALG_KDF1_SP800_56A, {{TPM_ALG_SHA384}}},
+				  {TPM_ALG_NULL, {{TPM_ALG_NULL}}},
+				  &NIST_P384,
+				  OID_ECC_NIST_P384
+				  CURVE_NAME("NIST_P384")}
+#   undef comma
+#   define comma ,
+#endif // ECC_NIST_P384
+#if ECC_NIST_P521
+				 comma
+				 {TPM_ECC_NIST_P521,
+				  521,
+				  {TPM_ALG_KDF1_SP800_56A, {{TPM_ALG_SHA512}}},
+				  {TPM_ALG_NULL, {{TPM_ALG_NULL}}},
+				  &NIST_P521,
+				  OID_ECC_NIST_P521
+				  CURVE_NAME("NIST_P521")}
+#   undef comma
+#   define comma ,
+#endif // ECC_NIST_P521
+#if ECC_BN_P256
+				 comma
+				 {TPM_ECC_BN_P256,
+				  256,
+				  {TPM_ALG_NULL, {{TPM_ALG_NULL}}},
+				  {TPM_ALG_NULL, {{TPM_ALG_NULL}}},
+				  &BN_P256,
+				  OID_ECC_BN_P256
+				  CURVE_NAME("BN_P256")}
+#   undef comma
+#   define comma ,
+#endif // ECC_BN_P256
+#if ECC_BN_P638
+				 comma
+				 {TPM_ECC_BN_P638,
+				  638,
+				  {TPM_ALG_NULL, {{TPM_ALG_NULL}}},
+				  {TPM_ALG_NULL, {{TPM_ALG_NULL}}},
+				  &BN_P638,
+				  OID_ECC_BN_P638
+				  CURVE_NAME("BN_P638")}
+#   undef comma
+#   define comma ,
+#endif // ECC_BN_P638
+#if ECC_SM2_P256
+				 comma
+				 {TPM_ECC_SM2_P256,
+				  256,
+				  {TPM_ALG_KDF1_SP800_56A, {{TPM_ALG_SM3_256}}},
+				  {TPM_ALG_NULL, {{TPM_ALG_NULL}}},
+				  &SM2_P256,
+				  OID_ECC_SM2_P256
+				  CURVE_NAME("SM2_P256")}
+#   undef comma
+#   define comma ,
+#endif // ECC_SM2_P256
+};
+#endif // TPM_ALG_ECC

+ 373 - 0
EVSE/GPL/ibmtpm1682/src/CryptEccKeyExchange.c

@@ -0,0 +1,373 @@
+/********************************************************************************/
+/*										*/
+/*	Functions that are used for the two-phase, ECC, key-exchange protocols	*/
+/*			     Written by Ken Goldman				*/
+/*		       IBM Thomas J. Watson Research Center			*/
+/*            $Id: CryptEccKeyExchange.c 1658 2021-01-22 23:14:01Z kgoldman $	*/
+/*										*/
+/*  Licenses and Notices							*/
+/*										*/
+/*  1. Copyright Licenses:							*/
+/*										*/
+/*  - Trusted Computing Group (TCG) grants to the user of the source code in	*/
+/*    this specification (the "Source Code") a worldwide, irrevocable, 		*/
+/*    nonexclusive, royalty free, copyright license to reproduce, create 	*/
+/*    derivative works, distribute, display and perform the Source Code and	*/
+/*    derivative works thereof, and to grant others the rights granted herein.	*/
+/*										*/
+/*  - The TCG grants to the user of the other parts of the specification 	*/
+/*    (other than the Source Code) the rights to reproduce, distribute, 	*/
+/*    display, and perform the specification solely for the purpose of 		*/
+/*    developing products based on such documents.				*/
+/*										*/
+/*  2. Source Code Distribution Conditions:					*/
+/*										*/
+/*  - Redistributions of Source Code must retain the above copyright licenses, 	*/
+/*    this list of conditions and the following disclaimers.			*/
+/*										*/
+/*  - Redistributions in binary form must reproduce the above copyright 	*/
+/*    licenses, this list of conditions	and the following disclaimers in the 	*/
+/*    documentation and/or other materials provided with the distribution.	*/
+/*										*/
+/*  3. Disclaimers:								*/
+/*										*/
+/*  - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF	*/
+/*  LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH	*/
+/*  RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES)	*/
+/*  THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE.		*/
+/*  Contact TCG Administration (admin@trustedcomputinggroup.org) for 		*/
+/*  information on specification licensing rights available through TCG 	*/
+/*  membership agreements.							*/
+/*										*/
+/*  - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED 	*/
+/*    WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR 	*/
+/*    FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR 		*/
+/*    NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY 		*/
+/*    OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE.		*/
+/*										*/
+/*  - Without limitation, TCG and its members and licensors disclaim all 	*/
+/*    liability, including liability for infringement of any proprietary 	*/
+/*    rights, relating to use of information in this specification and to the	*/
+/*    implementation of this specification, and TCG disclaims all liability for	*/
+/*    cost of procurement of substitute goods or services, lost profits, loss 	*/
+/*    of use, loss of data or any incidental, consequential, direct, indirect, 	*/
+/*    or special damages, whether under contract, tort, warranty or otherwise, 	*/
+/*    arising in any way out of use or reliance upon this specification or any 	*/
+/*    information herein.							*/
+/*										*/
+/*  (c) Copyright IBM Corp. and others, 2016 - 2021				*/
+/*										*/
+/********************************************************************************/
+
+/* 10.2.11 CryptEccKeyExchange.c */
+#include "Tpm.h"
+
+LIB_EXPORT TPM_RC
+SM2KeyExchange(
+	       TPMS_ECC_POINT        *outZ,         // OUT: the computed point
+	       TPM_ECC_CURVE          curveId,      // IN: the curve for the computations
+	       TPM2B_ECC_PARAMETER   *dsAIn,        // IN: static private TPM key
+	       TPM2B_ECC_PARAMETER   *deAIn,        // IN: ephemeral private TPM key
+	       TPMS_ECC_POINT        *QsBIn,        // IN: static public party B key
+	       TPMS_ECC_POINT        *QeBIn         // IN: ephemeral public party B key
+	       );
+
+#if CC_ZGen_2Phase == YES
+#if ALG_ECMQV
+/*     10.2.11.1.1 avf1() */
+/* This function does the associated value computation required by MQV key exchange. Process: */
+/* a) Convert xQ to an integer xqi using the convention specified in Appendix C.3. */
+/* b) Calculate xqm = xqi mod 2^ceil(f/2) (where f = ceil(log2(n)). */
+/* c) Calculate the associate value function avf(Q) = xqm + 2ceil(f / 2) */
+/*  Always returns TRUE(1). */
+static BOOL
+avf1(
+     bigNum               bnX,           // IN/OUT: the reduced value
+     bigNum               bnN            // IN: the order of the curve
+     )
+{
+    // compute f = 2^(ceil(ceil(log2(n)) / 2))
+    int                      f = (BnSizeInBits(bnN) + 1) / 2;
+    // x' = 2^f + (x mod 2^f)
+    BnMaskBits(bnX, f);   // This is mod 2*2^f but it doesn't matter because
+    // the next operation will SET the extra bit anyway
+    BnSetBit(bnX, f);
+    return TRUE;
+}
+/* 	  10.2.11.1.2 C_2_2_MQV() */
+/* This function performs the key exchange defined in SP800-56A 6.1.1.4 Full MQV, C(2, 2, ECC
+   MQV). */
+/* CAUTION: Implementation of this function may require use of essential claims in patents not owned
+   by TCG members. */
+/* Points QsB() and QeB() are required to be on the curve of inQsA. The function will fail, possibly
+   catastrophically, if this is not the case. */
+/* Error Returns Meaning */
+/* TPM_RC_NO_RESULT the value for dsA does not give a valid point on the curve */
+static TPM_RC
+C_2_2_MQV(
+	  TPMS_ECC_POINT        *outZ,         // OUT: the computed point
+	  TPM_ECC_CURVE          curveId,      // IN: the curve for the computations
+	  TPM2B_ECC_PARAMETER   *dsA,          // IN: static private TPM key
+	  TPM2B_ECC_PARAMETER   *deA,          // IN: ephemeral private TPM key
+	  TPMS_ECC_POINT        *QsB,          // IN: static public party B key
+	  TPMS_ECC_POINT        *QeB           // IN: ephemeral public party B key
+	  )
+{
+    CURVE_INITIALIZED(E, curveId);
+    const ECC_CURVE_DATA          *C;
+    POINT(pQeA);
+    POINT_INITIALIZED(pQeB, QeB);
+    POINT_INITIALIZED(pQsB, QsB);
+    ECC_NUM(bnTa);
+    ECC_INITIALIZED(bnDeA, deA);
+    ECC_INITIALIZED(bnDsA, dsA);
+    ECC_NUM(bnN);
+    ECC_NUM(bnXeB);
+    TPM_RC                 retVal;
+    //
+    // Parameter checks
+    if(E == NULL)
+	ERROR_RETURN(TPM_RC_VALUE);
+    pAssert(outZ != NULL && pQeB != NULL && pQsB != NULL && deA != NULL
+	    && dsA != NULL);
+    C = AccessCurveData(E);
+    // Process:
+    //  1. implicitsigA = (de,A + avf(Qe,A)ds,A ) mod n.
+    //  2. P = h(implicitsigA)(Qe,B + avf(Qe,B)Qs,B).
+    //  3. If P = O, output an error indicator.
+    //  4. Z=xP, where xP is the x-coordinate of P.
+    // Compute the public ephemeral key pQeA = [de,A]G
+    if((retVal = BnPointMult(pQeA, CurveGetG(C), bnDeA, NULL, NULL, E))
+       != TPM_RC_SUCCESS)
+	goto Exit;
+    //  1. implicitsigA = (de,A + avf(Qe,A)ds,A ) mod n.
+    //  tA := (ds,A + de,A  avf(Xe,A)) mod n    (3)
+    //  Compute 'tA' = ('deA' +  'dsA'  avf('XeA')) mod n
+    // Ta = avf(XeA);
+    BnCopy(bnTa, pQeA->x);
+    avf1(bnTa, bnN);
+    // do Ta = ds,A * Ta mod n = dsA * avf(XeA) mod n
+    BnModMult(bnTa, bnDsA, bnTa, bnN);
+    // now Ta = deA + Ta mod n =  deA + dsA * avf(XeA) mod n
+    BnAdd(bnTa, bnTa, bnDeA);
+    BnMod(bnTa, bnN);
+    //  2. P = h(implicitsigA)(Qe,B + avf(Qe,B)Qs,B).
+    // Put this in because almost every case of h is == 1 so skip the call when
+    // not necessary.
+    if(!BnEqualWord(CurveGetCofactor(C), 1))
+	// Cofactor is not 1 so compute Ta := Ta * h mod n
+	BnModMult(bnTa, bnTa, CurveGetCofactor(C), CurveGetOrder(C));
+    // Now that 'tA' is (h * 'tA' mod n)
+    // 'outZ' = (tA)(Qe,B + avf(Qe,B)Qs,B).
+    // first, compute XeB = avf(XeB)
+    avf1(bnXeB, bnN);
+    // QsB := [XeB]QsB
+    BnPointMult(pQsB, pQsB, bnXeB, NULL, NULL, E);
+    BnEccAdd(pQeB, pQeB, pQsB, E);
+    // QeB := [tA]QeB = [tA](QsB + [Xe,B]QeB) and check for at infinity
+    // If the result is not the point at infinity, return QeB
+    BnPointMult(pQeB, pQeB, bnTa, NULL, NULL, E);
+    if(BnEqualZero(pQeB->z))
+	ERROR_RETURN(TPM_RC_NO_RESULT);
+    // Convert BIGNUM E to TPM2B E
+    BnPointTo2B(outZ, pQeB, E);
+ Exit:
+    CURVE_FREE(E);
+    return retVal;
+}
+#endif // ALG_ECMQV
+/* 10.2.11.1.3 C_2_2_ECDH() */
+/* This function performs the two phase key exchange defined in SP800-56A, 6.1.1.2 Full Unified
+   Model, C(2, 2, ECC CDH). */
+static TPM_RC
+C_2_2_ECDH(
+	   TPMS_ECC_POINT          *outZs,         // OUT: Zs
+	   TPMS_ECC_POINT          *outZe,         // OUT: Ze
+	   TPM_ECC_CURVE            curveId,       // IN: the curve for the computations
+	   TPM2B_ECC_PARAMETER     *dsA,           // IN: static private TPM key
+	   TPM2B_ECC_PARAMETER     *deA,           // IN: ephemeral private TPM key
+	   TPMS_ECC_POINT          *QsB,           // IN: static public party B key
+	   TPMS_ECC_POINT          *QeB            // IN: ephemeral public party B key
+	   )
+{
+    CURVE_INITIALIZED(E, curveId);
+    ECC_INITIALIZED(bnAs, dsA);
+    ECC_INITIALIZED(bnAe, deA);
+    POINT_INITIALIZED(ecBs, QsB);
+    POINT_INITIALIZED(ecBe, QeB);
+    POINT(ecZ);
+    TPM_RC            retVal;
+    //
+    // Parameter checks
+    if(E == NULL)
+	ERROR_RETURN(TPM_RC_CURVE);
+    pAssert(outZs != NULL && dsA != NULL && deA != NULL && QsB != NULL
+	    && QeB != NULL);
+    // Do the point multiply for the Zs value ([dsA]QsB)
+    retVal = BnPointMult(ecZ, ecBs, bnAs, NULL, NULL, E);
+    if(retVal == TPM_RC_SUCCESS)
+	{
+	    // Convert the Zs value.
+	    BnPointTo2B(outZs, ecZ, E);
+	    // Do the point multiply for the Ze value ([deA]QeB)
+	    retVal = BnPointMult(ecZ, ecBe, bnAe, NULL, NULL, E);
+	    if(retVal == TPM_RC_SUCCESS)
+		BnPointTo2B(outZe, ecZ, E);
+	}
+ Exit:
+    CURVE_FREE(E);
+    return retVal;
+}
+/* 10.2.11.1.4 CryptEcc2PhaseKeyExchange() */
+/* This function is the dispatch routine for the EC key exchange functions that use two ephemeral
+   and two static keys. */
+/* Error Returns Meaning */
+/* TPM_RC_SCHEME scheme is not defined */
+LIB_EXPORT TPM_RC
+CryptEcc2PhaseKeyExchange(
+			  TPMS_ECC_POINT          *outZ1,         // OUT: a computed point
+			  TPMS_ECC_POINT          *outZ2,         // OUT: and optional second point
+			  TPM_ECC_CURVE            curveId,   // IN: the curve for the computations
+			  TPM_ALG_ID               scheme,        // IN: the key exchange scheme
+			  TPM2B_ECC_PARAMETER     *dsA,           // IN: static private TPM key
+			  TPM2B_ECC_PARAMETER     *deA,           // IN: ephemeral private TPM key
+			  TPMS_ECC_POINT          *QsB,           // IN: static public party B key
+			  TPMS_ECC_POINT          *QeB            // IN: ephemeral public party B key
+			  )
+{
+    pAssert(outZ1 != NULL
+	    && dsA != NULL && deA != NULL
+	    && QsB != NULL && QeB != NULL);
+    // Initialize the output points so that they are empty until one of the
+    // functions decides otherwise
+    outZ1->x.b.size = 0;
+    outZ1->y.b.size = 0;
+    if(outZ2 != NULL)
+	{
+	    outZ2->x.b.size = 0;
+	    outZ2->y.b.size = 0;
+	}
+    switch(scheme)
+	{
+	  case TPM_ALG_ECDH:
+	    return C_2_2_ECDH(outZ1, outZ2, curveId, dsA, deA, QsB, QeB);
+	    break;
+#if ALG_ECMQV
+	  case TPM_ALG_ECMQV:
+	    return C_2_2_MQV(outZ1, curveId, dsA, deA, QsB, QeB);
+	    break;
+#endif
+#if ALG_SM2
+	  case TPM_ALG_SM2:
+	    return SM2KeyExchange(outZ1, curveId, dsA, deA, QsB, QeB);
+	    break;
+#endif
+	  default:
+	    return TPM_RC_SCHEME;
+	}
+}
+#if ALG_SM2
+/* 10.2.11.1.5 ComputeWForSM2() */
+/* Compute the value for w used by SM2 */
+static UINT32
+ComputeWForSM2(
+	       bigCurve        E
+	       )
+{
+    //  w := ceil(ceil(log2(n)) / 2) - 1
+    return (BnMsb(CurveGetOrder(AccessCurveData(E))) / 2 - 1);
+}
+/* 10.2.11.1.6 avfSm2() */
+/* This function does the associated value computation required by SM2 key exchange. This is
+   different form the avf() in the international standards because it returns a value that is half
+   the size of the value returned by the standard avf. For example, if n is 15, Ws (w in the
+   standard) is 2 but the W here is 1. This means that an input value of 14 (1110b) would return a
+   value of 110b with the standard but 10b with the scheme in SM2. */
+static bigNum
+avfSm2(
+       bigNum              bn,           // IN/OUT: the reduced value
+       UINT32              w              // IN: the value of w
+       )
+{
+    // a)   set w := ceil(ceil(log2(n)) / 2) - 1
+    // b)   set x' := 2^w + ( x & (2^w - 1))
+    // This is just like the avf for MQV where x' = 2^w + (x mod 2^w)
+    BnMaskBits(bn, w);   // as with avf1, this is too big by a factor of 2 but
+    // it doesn't matter because we SET the extra bit
+    // anyway
+    BnSetBit(bn, w);
+    return bn;
+}
+/* SM2KeyExchange() This function performs the key exchange defined in SM2. The first step is to
+   compute tA = (dsA + deA avf(Xe,A)) mod n Then, compute the Z value from outZ = (h tA mod n) (QsA
+   + [avf(QeB().x)](QeB())). The function will compute the ephemeral public key from the ephemeral
+   private key. All points are required to be on the curve of inQsA. The function will fail
+   catastrophically if this is not the case */
+/* Error Returns Meaning */
+/* TPM_RC_NO_RESULT the value for dsA does not give a valid point on the curve */
+LIB_EXPORT TPM_RC
+SM2KeyExchange(
+	       TPMS_ECC_POINT        *outZ,         // OUT: the computed point
+	       TPM_ECC_CURVE          curveId,      // IN: the curve for the computations
+	       TPM2B_ECC_PARAMETER   *dsAIn,        // IN: static private TPM key
+	       TPM2B_ECC_PARAMETER   *deAIn,        // IN: ephemeral private TPM key
+	       TPMS_ECC_POINT        *QsBIn,        // IN: static public party B key
+	       TPMS_ECC_POINT        *QeBIn         // IN: ephemeral public party B key
+	       )
+{
+    CURVE_INITIALIZED(E, curveId);
+    const ECC_CURVE_DATA      *C;
+    ECC_INITIALIZED(dsA, dsAIn);
+    ECC_INITIALIZED(deA, deAIn);
+    POINT_INITIALIZED(QsB, QsBIn);
+    POINT_INITIALIZED(QeB, QeBIn);
+    BN_WORD_INITIALIZED(One, 1);
+    POINT(QeA);
+    ECC_NUM(XeB);
+    POINT(Z);
+    ECC_NUM(Ta);
+    UINT32                   w;
+    TPM_RC                 retVal = TPM_RC_NO_RESULT;
+    //
+    // Parameter checks
+    if(E == NULL)
+	ERROR_RETURN(TPM_RC_CURVE);
+    C = AccessCurveData(E);
+    pAssert(outZ != NULL && dsA != NULL && deA != NULL &&  QsB != NULL
+	    && QeB != NULL);
+    // Compute the value for w
+    w = ComputeWForSM2(E);
+    // Compute the public ephemeral key pQeA = [de,A]G
+    if(!BnEccModMult(QeA, CurveGetG(C), deA, E))
+	goto Exit;
+    //  tA := (ds,A + de,A  avf(Xe,A)) mod n    (3)
+    //  Compute 'tA' = ('dsA' +  'deA'  avf('XeA')) mod n
+    // Ta = avf(XeA);
+    // do Ta = de,A * Ta = deA * avf(XeA)
+    BnMult(Ta, deA, avfSm2(QeA->x, w));
+    // now Ta = dsA + Ta =  dsA + deA * avf(XeA)
+    BnAdd(Ta, dsA, Ta);
+    BnMod(Ta, CurveGetOrder(C));
+    //  outZ = [h  tA mod n] (Qs,B + [avf(Xe,B)](Qe,B)) (4)
+    // Put this in because almost every case of h is == 1 so skip the call when
+    // not necessary.
+    if(!BnEqualWord(CurveGetCofactor(C), 1))
+	// Cofactor is not 1 so compute Ta := Ta * h mod n
+	BnModMult(Ta, Ta, CurveGetCofactor(C), CurveGetOrder(C));
+    // Now that 'tA' is (h * 'tA' mod n)
+    // 'outZ' = ['tA'](QsB + [avf(QeB.x)](QeB)).
+    BnCopy(XeB, QeB->x);
+    if(!BnEccModMult2(Z, QsB, One, QeB, avfSm2(XeB, w), E))
+	goto Exit;
+    // QeB := [tA]QeB = [tA](QsB + [Xe,B]QeB) and check for at infinity
+    if(!BnEccModMult(Z, Z, Ta, E))
+	goto Exit;
+    // Convert BIGNUM E to TPM2B E
+    BnPointTo2B(outZ, Z, E);
+    retVal = TPM_RC_SUCCESS;
+ Exit:
+    CURVE_FREE(E);
+    return retVal;
+}
+#endif
+#endif // CC_ZGen_2Phase

+ 78 - 0
EVSE/GPL/ibmtpm1682/src/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

+ 759 - 0
EVSE/GPL/ibmtpm1682/src/CryptEccMain.c

@@ -0,0 +1,759 @@
+/********************************************************************************/
+/*										*/
+/*			     	ECC Main					*/
+/*			     Written by Ken Goldman				*/
+/*		       IBM Thomas J. Watson Research Center			*/
+/*            $Id: CryptEccMain.c 1519 2019-11-15 20:43:51Z kgoldman $		*/
+/*										*/
+/*  Licenses and Notices							*/
+/*										*/
+/*  1. Copyright Licenses:							*/
+/*										*/
+/*  - Trusted Computing Group (TCG) grants to the user of the source code in	*/
+/*    this specification (the "Source Code") a worldwide, irrevocable, 		*/
+/*    nonexclusive, royalty free, copyright license to reproduce, create 	*/
+/*    derivative works, distribute, display and perform the Source Code and	*/
+/*    derivative works thereof, and to grant others the rights granted herein.	*/
+/*										*/
+/*  - The TCG grants to the user of the other parts of the specification 	*/
+/*    (other than the Source Code) the rights to reproduce, distribute, 	*/
+/*    display, and perform the specification solely for the purpose of 		*/
+/*    developing products based on such documents.				*/
+/*										*/
+/*  2. Source Code Distribution Conditions:					*/
+/*										*/
+/*  - Redistributions of Source Code must retain the above copyright licenses, 	*/
+/*    this list of conditions and the following disclaimers.			*/
+/*										*/
+/*  - Redistributions in binary form must reproduce the above copyright 	*/
+/*    licenses, this list of conditions	and the following disclaimers in the 	*/
+/*    documentation and/or other materials provided with the distribution.	*/
+/*										*/
+/*  3. Disclaimers:								*/
+/*										*/
+/*  - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF	*/
+/*  LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH	*/
+/*  RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES)	*/
+/*  THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE.		*/
+/*  Contact TCG Administration (admin@trustedcomputinggroup.org) for 		*/
+/*  information on specification licensing rights available through TCG 	*/
+/*  membership agreements.							*/
+/*										*/
+/*  - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED 	*/
+/*    WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR 	*/
+/*    FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR 		*/
+/*    NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY 		*/
+/*    OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE.		*/
+/*										*/
+/*  - Without limitation, TCG and its members and licensors disclaim all 	*/
+/*    liability, including liability for infringement of any proprietary 	*/
+/*    rights, relating to use of information in this specification and to the	*/
+/*    implementation of this specification, and TCG disclaims all liability for	*/
+/*    cost of procurement of substitute goods or services, lost profits, loss 	*/
+/*    of use, loss of data or any incidental, consequential, direct, indirect, 	*/
+/*    or special damages, whether under contract, tort, warranty or otherwise, 	*/
+/*    arising in any way out of use or reliance upon this specification or any 	*/
+/*    information herein.							*/
+/*										*/
+/*  (c) Copyright IBM Corp. and others, 2016 - 2019				*/
+/*										*/
+/********************************************************************************/
+
+/* 10.2.11 CryptEccMain.c */
+/* 10.2.11.1 Includes and Defines */
+#include "Tpm.h"
+#if ALG_ECC
+/* This version requires that the new format for ECC data be used */
+#if !USE_BN_ECC_DATA
+#error "Need to SET USE_BN_ECC_DATA to YES in TpmBuildSwitches.h"
+#endif
+/* 10.2.11.2 Functions */
+#if SIMULATION
+void
+EccSimulationEnd(
+		 void
+		 )
+{
+#if SIMULATION
+    // put things to be printed at the end of the simulation here
+#endif
+}
+#endif // SIMULATION
+/* 10.2.11.2.1 CryptEccInit() */
+/* This function is called at _TPM_Init() */
+BOOL
+CryptEccInit(
+	     void
+	     )
+{
+    return TRUE;
+}
+/* 10.2.11.2.2 CryptEccStartup() */
+/* This function is called at TPM2_Startup(). */
+BOOL
+CryptEccStartup(
+		void
+		)
+{
+    return TRUE;
+}
+/* 10.2.11.2.3 ClearPoint2B(generic */
+/* Initialize the size values of a TPMS_ECC_POINT structure. */
+void
+ClearPoint2B(
+	     TPMS_ECC_POINT      *p          // IN: the point
+	     )
+{
+    if(p != NULL)
+	{
+	    p->x.t.size = 0;
+	    p->y.t.size = 0;
+	}
+}
+/* 10.2.11.2.4 CryptEccGetParametersByCurveId() */
+/* This function returns a pointer to the curve data that is associated with the indicated
+   curveId. If there is no curve with the indicated ID, the function returns NULL. This function is
+   in this module so that it can be called by GetCurve() data. */
+/* Return Values Meaning */
+/* NULL curve with the indicated TPM_ECC_CURVE is not implemented */
+/* non-NULL pointer to the curve data */
+LIB_EXPORT const ECC_CURVE *
+CryptEccGetParametersByCurveId(
+			       TPM_ECC_CURVE       curveId     // IN: the curveID
+			       )
+{
+    int          i;
+    for(i = 0; i < ECC_CURVE_COUNT; i++)
+	{
+	    if(eccCurves[i].curveId == curveId)
+		return &eccCurves[i];
+	}
+    return NULL;
+}
+/*  10.2.11.2.5 CryptEccGetKeySizeForCurve() */
+/* This function returns the key size in bits of the indicated curve */
+LIB_EXPORT UINT16
+CryptEccGetKeySizeForCurve(
+			   TPM_ECC_CURVE            curveId    // IN: the curve
+			   )
+{
+    const ECC_CURVE *curve = CryptEccGetParametersByCurveId(curveId);
+    UINT16           keySizeInBits;
+    //
+    keySizeInBits = (curve != NULL) ? curve->keySizeBits : 0;
+    return keySizeInBits;
+}
+/* 10.2.11.2.6 GetCurveData() */
+/* This function returns the a pointer for the parameter data associated with a curve. */
+const ECC_CURVE_DATA *
+GetCurveData(
+	     TPM_ECC_CURVE        curveId     // IN: the curveID
+	     )
+{
+    const ECC_CURVE      *curve = CryptEccGetParametersByCurveId(curveId);
+    return (curve != NULL) ? curve->curveData : NULL;
+}
+/* 10.2.11.2.7	CryptEccGetOID() */
+const BYTE *
+CryptEccGetOID(
+	       TPM_ECC_CURVE       curveId
+	       )
+{
+    const ECC_CURVE         *curve = CryptEccGetParametersByCurveId(curveId);
+    return (curve != NULL) ? curve->OID : NULL;
+}
+/* 10.2.11.2.7 CryptEccGetCurveByIndex() */
+/* This function returns the number of the i-th implemented curve. The normal use would be to call
+   this function with i starting at 0. When the i is greater than or equal to the number of
+   implemented curves, TPM_ECC_NONE is returned. */
+LIB_EXPORT TPM_ECC_CURVE
+CryptEccGetCurveByIndex(
+			UINT16               i
+			)
+{
+    if(i >= ECC_CURVE_COUNT)
+	return TPM_ECC_NONE;
+    return eccCurves[i].curveId;
+}
+/* 10.2.11.2.8 CryptEccGetParameter() */
+/* This function returns an ECC curve parameter. The parameter is selected by a single character
+   designator from the set of {PNABXYH}. */
+/* Return Values Meaning */
+/* TRUE curve exists and parameter returned */
+/* FALSE curve does not exist or parameter selector */
+LIB_EXPORT BOOL
+CryptEccGetParameter(
+		     TPM2B_ECC_PARAMETER     *out,       // OUT: place to put parameter
+		     char                     p,         // IN: the parameter selector
+		     TPM_ECC_CURVE            curveId    // IN: the curve id
+		     )
+{
+    const ECC_CURVE_DATA    *curve = GetCurveData(curveId);
+    bigConst                 parameter = NULL;
+    if(curve != NULL)
+	{
+	    switch(p)
+		{
+		  case 'p':
+		    parameter = CurveGetPrime(curve);
+		    break;
+		  case 'n':
+		    parameter = CurveGetOrder(curve);
+		    break;
+		  case 'a':
+		    parameter = CurveGet_a(curve);
+		    break;
+		  case 'b':
+		    parameter = CurveGet_b(curve);
+		    break;
+		  case 'x':
+		    parameter = CurveGetGx(curve);
+		    break;
+		  case 'y':
+		    parameter = CurveGetGy(curve);
+		    break;
+		  case 'h':
+		    parameter = CurveGetCofactor(curve);
+		    break;
+		  default:
+		    FAIL(FATAL_ERROR_INTERNAL);
+		    break;
+		}
+	}
+    // If not debugging and we get here with parameter still NULL, had better
+    // not try to convert so just return FALSE instead.
+    return (parameter != NULL) ? BnTo2B(parameter, &out->b, 0) : 0;
+}
+/* 10.2.11.2.9 CryptCapGetECCCurve() */
+/* This function returns the list of implemented ECC curves. */
+/* Return Values Meaning */
+/* YES if no more ECC curve is available */
+/* NO if there are more ECC curves not reported */
+TPMI_YES_NO
+CryptCapGetECCCurve(
+		    TPM_ECC_CURVE    curveID,       // IN: the starting ECC curve
+		    UINT32           maxCount,      // IN: count of returned curves
+		    TPML_ECC_CURVE  *curveList      // OUT: ECC curve list
+		    )
+{
+    TPMI_YES_NO       more = NO;
+    UINT16            i;
+    UINT32            count = ECC_CURVE_COUNT;
+    TPM_ECC_CURVE     curve;
+    // Initialize output property list
+    curveList->count = 0;
+    // The maximum count of curves we may return is MAX_ECC_CURVES
+    if(maxCount > MAX_ECC_CURVES) maxCount = MAX_ECC_CURVES;
+    // Scan the eccCurveValues array
+    for(i = 0; i < count; i++)
+	{
+	    curve = CryptEccGetCurveByIndex(i);
+	    // If curveID is less than the starting curveID, skip it
+	    if(curve < curveID)
+		continue;
+	    if(curveList->count < maxCount)
+		{
+		    // If we have not filled up the return list, add more curves to
+		    // it
+		    curveList->eccCurves[curveList->count] = curve;
+		    curveList->count++;
+		}
+	    else
+		{
+		    // If the return list is full but we still have curves
+		    // available, report this and stop iterating
+		    more = YES;
+		    break;
+		}
+	}
+    return more;
+}
+/* 10.2.11.2.10 CryptGetCurveSignScheme() */
+/* This function will return a pointer to the scheme of the curve. */
+const TPMT_ECC_SCHEME *
+CryptGetCurveSignScheme(
+			TPM_ECC_CURVE    curveId        // IN: The curve selector
+			)
+{
+    const ECC_CURVE         *curve = CryptEccGetParametersByCurveId(curveId);
+    if(curve != NULL)
+	return &(curve->sign);
+    else
+	return NULL;
+}
+/* 10.2.11.2.11 CryptGenerateR() */
+/* This function computes the commit random value for a split signing scheme. */
+/* If c is NULL, it indicates that r is being generated for TPM2_Commit(). If c is not NULL, the TPM
+   will validate that the gr.commitArray bit associated with the input value of c is SET. If not,
+   the TPM returns FALSE and no r value is generated. */
+/* Return Values Meaning */
+/* TRUE r value computed */
+/* FALSE no r value computed */
+BOOL
+CryptGenerateR(
+	       TPM2B_ECC_PARAMETER     *r,             // OUT: the generated random value
+	       UINT16                  *c,             // IN/OUT: count value.
+	       TPMI_ECC_CURVE           curveID,       // IN: the curve for the value
+	       TPM2B_NAME              *name           // IN: optional name of a key to
+	       //     associate with 'r'
+	       )
+{
+    // This holds the marshaled g_commitCounter.
+    TPM2B_TYPE(8B, 8);
+    TPM2B_8B                 cntr = {{8,{0}}};
+    UINT32                   iterations;
+    TPM2B_ECC_PARAMETER      n;
+    UINT64                   currentCount = gr.commitCounter;
+    UINT16                   t1;
+    //
+    if(!CryptEccGetParameter(&n, 'n', curveID))
+	return FALSE;
+    // If this is the commit phase, use the current value of the commit counter
+    if(c != NULL)
+	{
+	    // if the array bit is not set, can't use the value.
+	    if(!TEST_BIT((*c & COMMIT_INDEX_MASK), gr.commitArray))
+		return FALSE;
+	    // If it is the sign phase, figure out what the counter value was
+	    // when the commitment was made.
+	    //
+	    // When gr.commitArray has less than 64K bits, the extra
+	    // bits of 'c' are used as a check to make sure that the
+	    // signing operation is not using an out of range count value
+	    t1 = (UINT16)currentCount;
+	    // If the lower bits of c are greater or equal to the lower bits of t1
+	    // then the upper bits of t1 must be one more than the upper bits
+	    // of c
+	    if((*c & COMMIT_INDEX_MASK) >= (t1 & COMMIT_INDEX_MASK))
+		// Since the counter is behind, reduce the current count
+		currentCount = currentCount - (COMMIT_INDEX_MASK + 1);
+	    t1 = (UINT16)currentCount;
+	    if((t1 & ~COMMIT_INDEX_MASK) != (*c & ~COMMIT_INDEX_MASK))
+		return FALSE;
+	    // set the counter to the value that was
+	    // present when the commitment was made
+	    currentCount = (currentCount & 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;
+    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.11.2.12 CryptCommit() */
+/* This function is called when the count value is committed. The gr.commitArray value associated
+   with the current count value is SET and g_commitCounter is incremented. The low-order 16 bits of
+   old value of the counter is returned. */
+UINT16
+CryptCommit(
+	    void
+	    )
+{
+    UINT16      oldCount = (UINT16)gr.commitCounter;
+    gr.commitCounter++;
+    SET_BIT(oldCount & COMMIT_INDEX_MASK, gr.commitArray);
+    return oldCount;
+}
+/* 10.2.11.2.13 CryptEndCommit() */
+/* This function is called when the signing operation using the committed value is completed. It
+   clears the gr.commitArray bit associated with the count value so that it can't be used again. */
+void
+CryptEndCommit(
+	       UINT16           c              // IN: the counter value of the commitment
+	       )
+{
+    ClearBit((c & COMMIT_INDEX_MASK), gr.commitArray, sizeof(gr.commitArray));
+}
+/* 10.2.11.2.14 CryptEccGetParameters() */
+/* This function returns the ECC parameter details of the given curve */
+/* Return Values Meaning */
+/* TRUE success */
+/* FALSE unsupported ECC curve ID */
+BOOL
+CryptEccGetParameters(
+		      TPM_ECC_CURVE                curveId,       // IN: ECC curve ID
+		      TPMS_ALGORITHM_DETAIL_ECC   *parameters     // OUT: ECC parameters
+		      )
+{
+    const ECC_CURVE             *curve = CryptEccGetParametersByCurveId(curveId);
+    const ECC_CURVE_DATA        *data;
+    BOOL                         found = curve != NULL;
+    if(found)
+	{
+	    data = curve->curveData;
+	    parameters->curveID = curve->curveId;
+	    parameters->keySize = curve->keySizeBits;
+	    parameters->kdf = curve->kdf;
+	    parameters->sign = curve->sign;
+	    /* BnTo2B(data->prime, &parameters->p.b, 0); */
+	    BnTo2B(data->prime, &parameters->p.b, parameters->p.t.size);
+	    BnTo2B(data->a, &parameters->a.b, 0);
+	    BnTo2B(data->b, &parameters->b.b, 0);
+	    BnTo2B(data->base.x, &parameters->gX.b, parameters->p.t.size);
+	    BnTo2B(data->base.y, &parameters->gY.b, parameters->p.t.size);
+	    BnTo2B(data->order, &parameters->n.b, 0);
+	    BnTo2B(data->h, &parameters->h.b, 0);
+	}
+    return found;
+}
+/* 10.2.11.2.15 BnGetCurvePrime() */
+/* This function is used to get just the prime modulus associated with a curve */
+const bignum_t *
+BnGetCurvePrime(
+		TPM_ECC_CURVE            curveId
+		)
+{
+    const ECC_CURVE_DATA    *C = GetCurveData(curveId);
+    return (C != NULL) ? CurveGetPrime(C) : NULL;
+}
+/* 10.2.11.2.16 BnGetCurveOrder() */
+/* This function is used to get just the curve order */
+const bignum_t *
+BnGetCurveOrder(
+		TPM_ECC_CURVE            curveId
+		)
+{
+    const ECC_CURVE_DATA    *C = GetCurveData(curveId);
+    return (C != NULL) ? CurveGetOrder(C) : NULL;
+}
+/* 10.2.11.2.17 BnIsOnCurve() */
+/* This function checks if a point is on the curve. */
+BOOL
+BnIsOnCurve(
+	    pointConst                   Q,
+	    const ECC_CURVE_DATA        *C
+	    )
+{
+    BN_VAR(right, (MAX_ECC_KEY_BITS * 3));
+    BN_VAR(left, (MAX_ECC_KEY_BITS * 2));
+    bigConst                   prime = CurveGetPrime(C);
+    //
+    // Show that point is on the curve y^2 = x^3 + ax + b;
+    // Or y^2 = x(x^2 + a) + b
+    // y^2
+    BnMult(left, Q->y, Q->y);
+    BnMod(left, prime);
+    // x^2
+    BnMult(right, Q->x, Q->x);
+    // x^2 + a
+    BnAdd(right, right, CurveGet_a(C));
+    //    BnMod(right, CurveGetPrime(C));
+    // x(x^2 + a)
+    BnMult(right, right, Q->x);
+    // x(x^2 + a) + b
+    BnAdd(right, right, CurveGet_b(C));
+    BnMod(right, prime);
+    if(BnUnsignedCmp(left, right) == 0)
+	return TRUE;
+    else
+	return FALSE;
+}
+/* 10.2.11.2.18 BnIsValidPrivateEcc() */
+/* Checks that 0 < x < q */
+BOOL
+BnIsValidPrivateEcc(
+		    bigConst                 x,         // IN: private key to check
+		    bigCurve                 E          // IN: the curve to check
+		    )
+{
+    BOOL        retVal;
+    retVal = (!BnEqualZero(x)
+	      && (BnUnsignedCmp(x, CurveGetOrder(AccessCurveData(E))) < 0));
+    return retVal;
+}
+LIB_EXPORT BOOL
+CryptEccIsValidPrivateKey(
+			  TPM2B_ECC_PARAMETER     *d,
+			  TPM_ECC_CURVE            curveId
+			  )
+{
+    BN_INITIALIZED(bnD, MAX_ECC_PARAMETER_BYTES * 8, d);
+    return !BnEqualZero(bnD) && (BnUnsignedCmp(bnD, BnGetCurveOrder(curveId)) < 0);
+}
+/* 10.2.11.2.19 BnPointMul() */
+/* This function does a point multiply of the form R = [d]S + [u]Q where the parameters are bigNum
+   values. If S is NULL and d is not NULL, then it computes R = [d]G + [u]Q or just R = [d]G if u
+   and Q are NULL. If skipChecks is TRUE, then the function will not verify that the inputs are
+   correct for the domain. This would be the case when the values were created by the CryptoEngine()
+   code. It will return TPM_RC_NO_RESULT if the resulting point is the point at infinity. */
+/* Error Returns Meaning */
+/* TPM_RC_NO_RESULT result of multiplication is a point at infinity */
+/* TPM_RC_ECC_POINT S or Q is not on the curve */
+/* TPM_RC_VALUE d or u is not < n */
+TPM_RC
+BnPointMult(
+	    bigPoint             R,         // OUT: computed point
+	    pointConst           S,         // IN: optional point to multiply by 'd'
+	    bigConst             d,         // IN: scalar for [d]S or [d]G
+	    pointConst           Q,         // IN: optional second point
+	    bigConst             u,         // IN: optional second scalar
+	    bigCurve             E          // IN: curve parameters
+	    )
+{
+    BOOL                 OK;
+    //
+    TEST(TPM_ALG_ECDH);
+    // Need one scalar
+    OK = (d != NULL || u != NULL);
+    // If S is present, then d has to be present. If S is not
+    // present, then d may or may not be present
+    OK = OK && (((S == NULL) == (d == NULL)) || (d != NULL));
+    // either both u and Q have to be provided or neither can be provided (don't
+    // know what to do if only one is provided.
+    OK = OK && ((u == NULL) == (Q == NULL));
+    OK = OK && (E != NULL);
+    if(!OK)
+	return TPM_RC_VALUE;
+    OK = (S == NULL) || BnIsOnCurve(S, AccessCurveData(E));
+    OK = OK && ((Q == NULL) || BnIsOnCurve(Q, AccessCurveData(E)));
+    if(!OK)
+	return TPM_RC_ECC_POINT;
+    if((d != NULL) && (S == NULL))
+	S = CurveGetG(AccessCurveData(E));
+    // If only one scalar, don't need Shamir's trick
+    if((d == NULL) || (u == NULL))
+	{
+	    if(d == NULL)
+		OK = BnEccModMult(R, Q, u, E);
+	    else
+		OK = BnEccModMult(R, S, d, E);
+	}
+    else
+	{
+	    OK = BnEccModMult2(R, S, d, Q, u, E);
+	}
+    return  (OK ? TPM_RC_SUCCESS : TPM_RC_NO_RESULT);
+}
+/* 10.2.11.2.20	BnEccGetPrivate() */
+/* This function gets random values that are the size of the key plus 64 bits. The value is reduced
+   (mod (q - 1)) and incremented by 1 (q is the order of the curve. This produces a value (d) such
+   that 1 <= d < q. This is the method of FIPS 186-4 Section B.4.1 'Key Pair Generation Using Extra
+   Random Value Meaning */
+/* TRUE		success */
+/* FALSE	failure generating private key */
+BOOL
+BnEccGetPrivate(
+		bigNum                   dOut,      // OUT: the qualified random value
+		const ECC_CURVE_DATA    *C,         // IN: curve for which the private key
+		//     needs to be appropriate
+		RAND_STATE              *rand       // IN: state for DRBG
+		)
+{
+    bigConst                 order = CurveGetOrder(C);
+    BOOL                     OK;
+    UINT32                   orderBits = BnSizeInBits(order);
+    UINT32                   orderBytes = BITS_TO_BYTES(orderBits);
+    BN_VAR(bnExtraBits, MAX_ECC_KEY_BITS + 64);
+    BN_VAR(nMinus1, MAX_ECC_KEY_BITS);
+    //
+    OK = BnGetRandomBits(bnExtraBits, (orderBytes * 8) + 64, rand);
+    OK = OK && BnSubWord(nMinus1, order, 1);
+    OK = OK && BnMod(bnExtraBits, nMinus1);
+    OK = OK && BnAddWord(dOut, bnExtraBits, 1);
+    return OK && !g_inFailureMode;
+}
+
+/* 10.2.11.2.21 BnEccGenerateKeyPair() */
+/* This function gets a private scalar from the source of random bits and does the point multiply to
+   get the public key. */
+BOOL
+BnEccGenerateKeyPair(
+		     bigNum               bnD,            // OUT: private scalar
+		     bn_point_t          *ecQ,            // OUT: public point
+		     bigCurve             E,              // IN: curve for the point
+		     RAND_STATE          *rand            // IN: DRBG state to use
+		     )
+{
+    BOOL                 OK = FALSE;
+    // Get a private scalar
+    OK = BnEccGetPrivate(bnD, AccessCurveData(E), rand);
+    // Do a point multiply
+    OK = OK && BnEccModMult(ecQ, NULL, bnD, E);
+    if(!OK)
+	BnSetWord(ecQ->z, 0);
+    else
+	BnSetWord(ecQ->z, 1);
+    return OK;
+}
+/* 10.2.11.2.21 CryptEccNewKeyPair */
+/* This function creates an ephemeral ECC. It is ephemeral in that is expected that the private part
+   of the key will be discarded */
+LIB_EXPORT TPM_RC
+CryptEccNewKeyPair(
+		   TPMS_ECC_POINT          *Qout,      // OUT: the public point
+		   TPM2B_ECC_PARAMETER     *dOut,      // OUT: the private scalar
+		   TPM_ECC_CURVE            curveId    // IN: the curve for the key
+		   )
+{
+    CURVE_INITIALIZED(E, curveId);
+    POINT(ecQ);
+    ECC_NUM(bnD);
+    BOOL                    OK;
+    if(E == NULL)
+	return TPM_RC_CURVE;
+    TEST(TPM_ALG_ECDH);
+    OK = BnEccGenerateKeyPair(bnD, ecQ, E, NULL);
+    if(OK)
+	{
+	    BnPointTo2B(Qout, ecQ, E);
+	    BnTo2B(bnD, &dOut->b, Qout->x.t.size);
+	}
+    else
+	{
+	    Qout->x.t.size = Qout->y.t.size = dOut->t.size = 0;
+	}
+    CURVE_FREE(E);
+    return OK ? TPM_RC_SUCCESS : TPM_RC_NO_RESULT;
+}
+/* 10.2.11.2.22 CryptEccPointMultiply() */
+/* This function computes 'R := [dIn]G + [uIn]QIn. Where dIn and uIn are scalars, G and QIn are
+   points on the specified curve and G is the default generator of the curve. */
+/* The xOut and yOut parameters are optional and may be set to NULL if not used. */
+/* It is not necessary to provide uIn if QIn is specified but one of uIn and dIn must be
+   provided. If dIn and QIn are specified but uIn is not provided, then R = [dIn]QIn. */
+/* If the multiply produces the point at infinity, the TPM_RC_NO_RESULT is returned. */
+/* The sizes of xOut and yOut' will be set to be the size of the degree of the curve */
+/* It is a fatal error if dIn and uIn are both unspecified (NULL) or if Qin or Rout is
+   unspecified. */
+/* Error Returns Meaning */
+/* TPM_RC_ECC_POINT the point Pin or Qin is not on the curve */
+/* TPM_RC_NO_RESULT the product point is at infinity */
+/* TPM_RC_CURVE bad curve */
+/* TPM_RC_VALUE dIn or uIn out of range */
+LIB_EXPORT TPM_RC
+CryptEccPointMultiply(
+		      TPMS_ECC_POINT      *Rout,              // OUT: the product point R
+		      TPM_ECC_CURVE        curveId,           // IN: the curve to use
+		      TPMS_ECC_POINT      *Pin,               // IN: first point (can be null)
+		      TPM2B_ECC_PARAMETER *dIn,               // IN: scalar value for [dIn]Qin
+		      //     the Pin
+		      TPMS_ECC_POINT      *Qin,               // IN: point Q
+		      TPM2B_ECC_PARAMETER *uIn                // IN: scalar value for the multiplier
+		      //     of Q
+		      )
+{
+    CURVE_INITIALIZED(E, curveId);
+    POINT_INITIALIZED(ecP, Pin);
+    ECC_INITIALIZED(bnD, dIn);      // If dIn is null, then bnD is null
+    ECC_INITIALIZED(bnU, uIn);
+    POINT_INITIALIZED(ecQ, Qin);
+    POINT(ecR);
+    TPM_RC             retVal;
+    //
+    retVal = BnPointMult(ecR, ecP, bnD, ecQ, bnU, E);
+    if(retVal == TPM_RC_SUCCESS)
+	BnPointTo2B(Rout, ecR, E);
+    else
+	ClearPoint2B(Rout);
+    CURVE_FREE(E);
+    return retVal;
+}
+/* 10.2.11.2.23 CryptEccIsPointOnCurve() */
+/* This function is used to test if a point is on a defined curve. It does this by checking that y^2
+   mod p = x^3 + a*x + b mod p */
+/* It is a fatal error if Q is not specified (is NULL). */
+/* Return Values Meaning */
+/* TRUE point is on curve */
+/* FALSE point is not on curve or curve is not supported */
+LIB_EXPORT BOOL
+CryptEccIsPointOnCurve(
+		       TPM_ECC_CURVE            curveId,       // IN: the curve selector
+		       TPMS_ECC_POINT          *Qin            // IN: the point.
+		       )
+{
+    const ECC_CURVE_DATA    *C = GetCurveData(curveId);
+    POINT_INITIALIZED(ecQ, Qin);
+    BOOL            OK;
+    //
+    pAssert(Qin != NULL);
+    OK = (C != NULL && (BnIsOnCurve(ecQ, C)));
+    return OK;
+}
+/* 10.2.11.2.24 CryptEccGenerateKey() */
+/* This function generates an ECC key pair based on the input parameters. This routine uses KDFa()
+   to produce candidate numbers. The method is according to FIPS 186-3, section B.1.2 "Key Pair
+   Generation by Testing Candidates." According to the method in FIPS 186-3, the resulting private
+   value d should be 1 <= d < n where n is the order of the base point. */
+/* It is a fatal error if Qout, dOut, is not provided (is NULL). */
+/* If the curve is not supported If seed is not provided, then a random number will be used for the
+   key */
+/* Error Returns Meaning */
+/* TPM_RC_CURVE curve is not supported */
+/* TPM_RC_NO_RESULT could not verify key with signature (FIPS only) */
+LIB_EXPORT TPM_RC
+CryptEccGenerateKey(
+		    TPMT_PUBLIC         *publicArea,        // IN/OUT: The public area template for
+		    //      the new key. The public key
+		    //      area will be replaced computed
+		    //      ECC public key
+		    TPMT_SENSITIVE      *sensitive,         // OUT: the sensitive area will be
+		    //      updated to contain the private
+		    //      ECC key and the symmetric
+		    //      encryption key
+		    RAND_STATE          *rand               // IN: if not NULL, the deterministic
+		    //     RNG state
+		    )
+{
+    CURVE_INITIALIZED(E, publicArea->parameters.eccDetail.curveID);
+    ECC_NUM(bnD);
+    POINT(ecQ);
+    BOOL                     OK;
+    TPM_RC                   retVal;
+    TEST(TPM_ALG_ECDSA); // ECDSA is used to verify each key
+    // Validate parameters
+    if(E == NULL)
+	ERROR_RETURN(TPM_RC_CURVE);
+    publicArea->unique.ecc.x.t.size = 0;
+    publicArea->unique.ecc.y.t.size = 0;
+    sensitive->sensitive.ecc.t.size = 0;
+    OK = BnEccGenerateKeyPair(bnD, ecQ, E, rand);
+    if(OK)
+	{
+	    BnPointTo2B(&publicArea->unique.ecc, ecQ, E);
+	    BnTo2B(bnD, &sensitive->sensitive.ecc.b, publicArea->unique.ecc.x.t.size);
+	}
+#if FIPS_COMPLIANT
+    // See if PWCT is required
+    if(OK && (IS_ATTRIBUTE(publicArea->objectAttributes, TPMA_OBJECT, sign)))
+	{
+	    ECC_NUM(bnT);
+	    ECC_NUM(bnS);
+	    TPM2B_DIGEST    digest;
+	    TEST(TPM_ALG_ECDSA);
+	    digest.t.size = MIN(sensitive->sensitive.ecc.t.size, sizeof(digest.t.buffer));
+	    // Get a random value to sign using the built in DRBG state
+	    DRBG_Generate(NULL, digest.t.buffer, digest.t.size);
+	    if(g_inFailureMode)
+		return TPM_RC_FAILURE;
+	    BnSignEcdsa(bnT, bnS, E, bnD, &digest, NULL);
+	    // and make sure that we can validate the signature
+	    OK = BnValidateSignatureEcdsa(bnT, bnS, E, ecQ, &digest) == TPM_RC_SUCCESS;
+	}
+#endif
+    retVal = (OK) ? TPM_RC_SUCCESS : TPM_RC_NO_RESULT;
+ Exit:
+    CURVE_FREE(E);
+    return retVal;
+}
+#endif  // TPM_ALG_ECC

+ 221 - 0
EVSE/GPL/ibmtpm1682/src/CryptEccMain_fp.h

@@ -0,0 +1,221 @@
+/********************************************************************************/
+/*										*/
+/*			     	ECC Main					*/
+/*			     Written by Ken Goldman				*/
+/*		       IBM Thomas J. Watson Research Center			*/
+/*            $Id: CryptEccMain_fp.h 1476 2019-06-10 19:32:03Z kgoldman $	*/
+/*										*/
+/*  Licenses and Notices							*/
+/*										*/
+/*  1. Copyright Licenses:							*/
+/*										*/
+/*  - Trusted Computing Group (TCG) grants to the user of the source code in	*/
+/*    this specification (the "Source Code") a worldwide, irrevocable, 		*/
+/*    nonexclusive, royalty free, copyright license to reproduce, create 	*/
+/*    derivative works, distribute, display and perform the Source Code and	*/
+/*    derivative works thereof, and to grant others the rights granted herein.	*/
+/*										*/
+/*  - The TCG grants to the user of the other parts of the specification 	*/
+/*    (other than the Source Code) the rights to reproduce, distribute, 	*/
+/*    display, and perform the specification solely for the purpose of 		*/
+/*    developing products based on such documents.				*/
+/*										*/
+/*  2. Source Code Distribution Conditions:					*/
+/*										*/
+/*  - Redistributions of Source Code must retain the above copyright licenses, 	*/
+/*    this list of conditions and the following disclaimers.			*/
+/*										*/
+/*  - Redistributions in binary form must reproduce the above copyright 	*/
+/*    licenses, this list of conditions	and the following disclaimers in the 	*/
+/*    documentation and/or other materials provided with the distribution.	*/
+/*										*/
+/*  3. Disclaimers:								*/
+/*										*/
+/*  - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF	*/
+/*  LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH	*/
+/*  RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES)	*/
+/*  THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE.		*/
+/*  Contact TCG Administration (admin@trustedcomputinggroup.org) for 		*/
+/*  information on specification licensing rights available through TCG 	*/
+/*  membership agreements.							*/
+/*										*/
+/*  - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED 	*/
+/*    WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR 	*/
+/*    FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR 		*/
+/*    NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY 		*/
+/*    OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE.		*/
+/*										*/
+/*  - Without limitation, TCG and its members and licensors disclaim all 	*/
+/*    liability, including liability for infringement of any proprietary 	*/
+/*    rights, relating to use of information in this specification and to the	*/
+/*    implementation of this specification, and TCG disclaims all liability for	*/
+/*    cost of procurement of substitute goods or services, lost profits, loss 	*/
+/*    of use, loss of data or any incidental, consequential, direct, indirect, 	*/
+/*    or special damages, whether under contract, tort, warranty or otherwise, 	*/
+/*    arising in any way out of use or reliance upon this specification or any 	*/
+/*    information herein.							*/
+/*										*/
+/*  (c) Copyright IBM Corp. and others, 2016 - 2019				*/
+/*										*/
+/********************************************************************************/
+
+#ifndef CRYPTECCMAIN_FP_H
+#define CRYPTECCMAIN_FP_H
+
+void
+EccSimulationEnd(
+		 void
+		 );
+BOOL
+CryptEccInit(
+	     void
+	     );
+BOOL
+CryptEccStartup(
+		void
+		);
+void
+ClearPoint2B(
+	     TPMS_ECC_POINT      *p          // IN: the point
+	     );
+LIB_EXPORT const ECC_CURVE *
+CryptEccGetParametersByCurveId(
+			       TPM_ECC_CURVE       curveId     // IN: the curveID
+			       );
+LIB_EXPORT UINT16
+CryptEccGetKeySizeForCurve(
+			   TPM_ECC_CURVE            curveId    // IN: the curve
+			   );
+const ECC_CURVE_DATA *
+GetCurveData(
+	     TPM_ECC_CURVE        curveId     // IN: the curveID
+	     );
+const BYTE *
+CryptEccGetOID(
+	       TPM_ECC_CURVE       curveId
+	       );
+LIB_EXPORT TPM_ECC_CURVE
+CryptEccGetCurveByIndex(
+			UINT16               i
+			);
+LIB_EXPORT BOOL
+CryptEccGetParameter(
+		     TPM2B_ECC_PARAMETER     *out,       // OUT: place to put parameter
+		     char                     p,         // IN: the parameter selector
+		     TPM_ECC_CURVE            curveId    // IN: the curve id
+		     );
+TPMI_YES_NO
+CryptCapGetECCCurve(
+		    TPM_ECC_CURVE    curveID,       // IN: the starting ECC curve
+		    UINT32           maxCount,      // IN: count of returned curves
+		    TPML_ECC_CURVE  *curveList      // OUT: ECC curve list
+		    );
+const TPMT_ECC_SCHEME *
+CryptGetCurveSignScheme(
+			TPM_ECC_CURVE    curveId        // IN: The curve selector
+			);
+BOOL
+CryptGenerateR(
+	       TPM2B_ECC_PARAMETER     *r,             // OUT: the generated random value
+	       UINT16                  *c,             // IN/OUT: count value.
+	       TPMI_ECC_CURVE           curveID,       // IN: the curve for the value
+	       TPM2B_NAME              *name           // IN: optional name of a key to
+	       //     associate with 'r'
+	       );
+UINT16
+CryptCommit(
+	    void
+	    );
+void
+CryptEndCommit(
+	       UINT16           c              // IN: the counter value of the commitment
+	       );
+BOOL
+CryptEccGetParameters(
+		      TPM_ECC_CURVE                curveId,       // IN: ECC curve ID
+		      TPMS_ALGORITHM_DETAIL_ECC   *parameters     // OUT: ECC parameters
+		      );
+const bignum_t *
+BnGetCurvePrime(
+		TPM_ECC_CURVE            curveId
+		);
+const bignum_t *
+BnGetCurveOrder(
+		TPM_ECC_CURVE            curveId
+		);
+BOOL
+BnIsOnCurve(
+	    pointConst                   Q,
+	    const ECC_CURVE_DATA        *C
+	    );
+BOOL
+BnIsValidPrivateEcc(
+		    bigConst                 x,         // IN: private key to check
+		    bigCurve                 E          // IN: the curve to check
+		    );
+LIB_EXPORT BOOL
+CryptEccIsValidPrivateKey(
+			  TPM2B_ECC_PARAMETER     *d,
+			  TPM_ECC_CURVE            curveId
+			  );
+TPM_RC
+BnPointMult(
+	    bigPoint             R,         // OUT: computed point
+	    pointConst           S,         // IN: optional point to multiply by 'd'
+	    bigConst             d,         // IN: scalar for [d]S or [d]G
+	    pointConst           Q,         // IN: optional second point
+	    bigConst             u,         // IN: optional second scalar
+	    bigCurve             E          // IN: curve parameters
+	    );
+BOOL
+BnEccGetPrivate(
+		bigNum                   dOut,      // OUT: the qualified random value
+		const ECC_CURVE_DATA    *C,         // IN: curve for which the private key
+		//     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

+ 892 - 0
EVSE/GPL/ibmtpm1682/src/CryptEccSignature.c

@@ -0,0 +1,892 @@
+/********************************************************************************/
+/*										*/
+/*			     ECC Signatures					*/
+/*			     Written by Ken Goldman				*/
+/*		       IBM Thomas J. Watson Research Center			*/
+/*            $Id: CryptEccSignature.c 1658 2021-01-22 23:14:01Z kgoldman $	*/
+/*										*/
+/*  Licenses and Notices							*/
+/*										*/
+/*  1. Copyright Licenses:							*/
+/*										*/
+/*  - Trusted Computing Group (TCG) grants to the user of the source code in	*/
+/*    this specification (the "Source Code") a worldwide, irrevocable, 		*/
+/*    nonexclusive, royalty free, copyright license to reproduce, create 	*/
+/*    derivative works, distribute, display and perform the Source Code and	*/
+/*    derivative works thereof, and to grant others the rights granted herein.	*/
+/*										*/
+/*  - The TCG grants to the user of the other parts of the specification 	*/
+/*    (other than the Source Code) the rights to reproduce, distribute, 	*/
+/*    display, and perform the specification solely for the purpose of 		*/
+/*    developing products based on such documents.				*/
+/*										*/
+/*  2. Source Code Distribution Conditions:					*/
+/*										*/
+/*  - Redistributions of Source Code must retain the above copyright licenses, 	*/
+/*    this list of conditions and the following disclaimers.			*/
+/*										*/
+/*  - Redistributions in binary form must reproduce the above copyright 	*/
+/*    licenses, this list of conditions	and the following disclaimers in the 	*/
+/*    documentation and/or other materials provided with the distribution.	*/
+/*										*/
+/*  3. Disclaimers:								*/
+/*										*/
+/*  - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF	*/
+/*  LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH	*/
+/*  RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES)	*/
+/*  THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE.		*/
+/*  Contact TCG Administration (admin@trustedcomputinggroup.org) for 		*/
+/*  information on specification licensing rights available through TCG 	*/
+/*  membership agreements.							*/
+/*										*/
+/*  - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED 	*/
+/*    WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR 	*/
+/*    FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR 		*/
+/*    NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY 		*/
+/*    OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE.		*/
+/*										*/
+/*  - Without limitation, TCG and its members and licensors disclaim all 	*/
+/*    liability, including liability for infringement of any proprietary 	*/
+/*    rights, relating to use of information in this specification and to the	*/
+/*    implementation of this specification, and TCG disclaims all liability for	*/
+/*    cost of procurement of substitute goods or services, lost profits, loss 	*/
+/*    of use, loss of data or any incidental, consequential, direct, indirect, 	*/
+/*    or special damages, whether under contract, tort, warranty or otherwise, 	*/
+/*    arising in any way out of use or reliance upon this specification or any 	*/
+/*    information herein.							*/
+/*										*/
+/*  (c) Copyright IBM Corp. and others, 2016 - 2021				*/
+/*										*/
+/********************************************************************************/
+
+/* 10.2.12 CryptEccSignature.c */
+/* 10.2.12.1 Includes and Defines */
+#include "Tpm.h"
+#include "CryptEccSignature_fp.h"
+#if ALG_ECC
+/* 10.2.12.2 Utility Functions */
+/* 10.2.12.2.1 EcdsaDigest() */
+/* Function to adjust the digest so that it is no larger than the order of the curve. This is used
+   for ECDSA sign and verification. */
+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.12.2.2 BnSchnorrSign() */
+/* This contains the Schnorr signature computation. It is used by both ECDSA and Schnorr
+   signing. The result is computed as: [s = k + r * d (mod n)] where */
+/* a) s is the signature */
+/* b) k is a random value */
+/* c) r is the value to sign */
+/* d) d is the private EC key */
+/* e) n is the order of the curve */
+/* Error Returns Meaning */
+/* TPM_RC_NO_RESULT the result of the operation was zero or r (mod n) is zero */
+static TPM_RC
+BnSchnorrSign(
+	      bigNum                   bnS,           // OUT: s component of the signature
+	      bigConst                 bnK,           // IN: a random value
+	      bigNum                   bnR,           // IN: the signature 'r' value
+	      bigConst                 bnD,           // IN: the private key
+	      bigConst                 bnN            // IN: the order of the curve
+	      )
+{
+    // Need a local temp value to store the intermediate computation because product
+    // size can be larger than will fit in bnS.
+    BN_VAR(bnT1, MAX_ECC_PARAMETER_BYTES * 2 * 8);
+    //
+    // Reduce bnR without changing the input value
+    BnDiv(NULL, bnT1, bnR, bnN);
+    if(BnEqualZero(bnT1))
+	return TPM_RC_NO_RESULT;
+    // compute s = (k + r * d)(mod n)
+    // r * d
+    BnMult(bnT1, bnT1, bnD);
+    // k * r * d
+    BnAdd(bnT1, bnT1, bnK);
+    // k + r * d (mod n)
+    BnDiv(NULL, bnS, bnT1, bnN);
+    return (BnEqualZero(bnS)) ? TPM_RC_NO_RESULT : TPM_RC_SUCCESS;
+}
+/* 10.2.12.3 Signing Functions */
+/* 10.2.12.3.1 BnSignEcdsa() */
+/* This function implements the ECDSA signing algorithm. The method is described in the comments
+   below. This version works with internal numbers. */
+TPM_RC
+BnSignEcdsa(
+	    bigNum                   bnR,           // OUT: r component of the signature
+	    bigNum                   bnS,           // OUT: s component of the signature
+	    bigCurve                 E,             // IN: the curve used in the signature
+	    //     process
+	    bigNum                   bnD,           // IN: private signing key
+	    const TPM2B_DIGEST      *digest,        // IN: the digest to sign
+	    RAND_STATE              *rand           // IN: used in debug of signing
+	    )
+{
+    ECC_NUM(bnK);
+    ECC_NUM(bnIk);
+    BN_VAR(bnE, MAX(MAX_ECC_KEY_BYTES, MAX_DIGEST_SIZE) * 8);
+    POINT(ecR);
+    bigConst                order = CurveGetOrder(AccessCurveData(E));
+    TPM_RC                  retVal = TPM_RC_SUCCESS;
+    INT32                   tries = 10;
+    BOOL                    OK = FALSE;
+    //
+    pAssert(digest != NULL);
+    // The algorithm as described in "Suite B Implementer's Guide to FIPS
+    // 186-3(ECDSA)"
+    // 1. Use one of the routines in Appendix A.2 to generate (k, k^-1), a
+    //    per-message secret number and its inverse modulo n. Since n is prime,
+    //    the output will be invalid only if there is a failure in the RBG.
+    // 2. Compute the elliptic curve point R = [k]G = (xR, yR) using EC scalar
+    //    multiplication (see [Routines]), where G is the base point included in
+    //    the set of domain parameters.
+    // 3. Compute r = xR mod n. If r = 0, then return to Step 1. 1.
+    // 4. Use the selected hash function to compute H = Hash(M).
+    // 5. Convert the bit string H to an integer e as described in Appendix B.2.
+    // 6. Compute s = (k^-1 *  (e + d *  r)) mod q. If s = 0, return to Step 1.2.
+    // 7. Return (r, s).
+    // In the code below, q is n (that it, the order of the curve is p)
+    do // This implements the loop at step 6. If s is zero, start over.
+	{
+	    for(; tries > 0; tries--)
+		{
+		    // Step 1 and 2 -- generate an ephemeral key and the modular inverse
+		    // of the private key.
+		    if(!BnEccGenerateKeyPair(bnK, ecR, E, rand))
+			continue;
+		    // x coordinate is mod p.  Make it mod q
+		    BnMod(ecR->x, order);
+		    // Make sure that it is not zero;
+		    if(BnEqualZero(ecR->x))
+			continue;
+		    // write the modular reduced version of r as part of the signature
+		    BnCopy(bnR, ecR->x);
+		    // Make sure that a modular inverse exists and try again if not
+		    OK = (BnModInverse(bnIk, bnK, order));
+		    if(OK)
+			break;
+		}
+	    if(!OK)
+		goto Exit;
+	    EcdsaDigest(bnE, digest, order);
+	    // now have inverse of K (bnIk), e (bnE), r (bnR),  d (bnD) and
+	    // CurveGetOrder(E)
+	    // Compute s = k^-1 (e + r*d)(mod q)
+	    //  first do s = r*d mod q
+	    BnModMult(bnS, bnR, bnD, order);
+	    // s = e + s = e + r * d
+	    BnAdd(bnS, bnE, bnS);
+	    // s = k^(-1)s (mod n) = k^(-1)(e + r * d)(mod n)
+	    BnModMult(bnS, bnIk, bnS, order);
+	    // If S is zero, try again
+	} while(BnEqualZero(bnS));
+ Exit:
+    return retVal;
+}
+#if ALG_ECDAA
+/* 10.2.12.3.2 BnSignEcdaa() */
+/* This function performs s = r + T * d mod q where */
+/* a) 'r is a random, or pseudo-random value created in the commit phase */
+/* b) nonceK is a TPM-generated, random value 0 < nonceK < n */
+/* c) T is mod q of Hash(nonceK || digest), and */
+/* d) d is a private key. */
+/* The signature is the tuple (nonceK, s) */
+/* Regrettably, the parameters in this function kind of collide with the parameter names used in
+   ECSCHNORR making for a lot of confusion. In particular, the k value in this function is value in
+   this function u */
+/* Error Returns Meaning */
+/* TPM_RC_SCHEME unsupported hash algorithm */
+/* TPM_RC_NO_RESULT cannot get values from random number generator */
+static TPM_RC
+BnSignEcdaa(
+	    TPM2B_ECC_PARAMETER     *nonceK,        // OUT: nonce component of the signature
+	    bigNum                   bnS,           // OUT: s component of the signature
+	    bigCurve                 E,             // IN: the curve used in signing
+	    bigNum                   bnD,           // IN: the private key
+	    const TPM2B_DIGEST      *digest,        // IN: the value to sign (mod q)
+	    TPMT_ECC_SCHEME         *scheme,        // IN: signing scheme (contains the
+	    //      commit count value).
+	    OBJECT                  *eccKey,        // IN: The signing key
+	    RAND_STATE              *rand           // IN: a random number state
+	    )
+{
+    TPM_RC                   retVal;
+    TPM2B_ECC_PARAMETER      r;
+    HASH_STATE               state;
+    TPM2B_DIGEST             T;
+    BN_MAX(bnT);
+    //
+    NOT_REFERENCED(rand);
+    if(!CryptGenerateR(&r, &scheme->details.ecdaa.count,
+		       eccKey->publicArea.parameters.eccDetail.curveID,
+		       &eccKey->name))
+	retVal = TPM_RC_VALUE;
+    else
+	{
+	    // This allocation is here because 'r' doesn't have a value until
+	    // CrypGenerateR() is done.
+	    ECC_INITIALIZED(bnR, &r);
+	    do
+		{
+		    // generate nonceK such that 0 < nonceK < n
+		    // use bnT as a temp.
+		    if(!BnEccGetPrivate(bnT, AccessCurveData(E), rand))
+			{
+			    retVal = TPM_RC_NO_RESULT;
+			    break;
+			}
+		    BnTo2B(bnT, &nonceK->b, 0);
+		    T.t.size = CryptHashStart(&state, scheme->details.ecdaa.hashAlg);
+		    if(T.t.size == 0)
+			{
+			    retVal = TPM_RC_SCHEME;
+			}
+		    else
+			{
+			    CryptDigestUpdate2B(&state, &nonceK->b);
+			    CryptDigestUpdate2B(&state, &digest->b);
+			    CryptHashEnd2B(&state, &T.b);
+			    BnFrom2B(bnT, &T.b);
+			    // Watch out for the name collisions in this call!!
+			    retVal = BnSchnorrSign(bnS, bnR, bnT, bnD,
+						   AccessCurveData(E)->order);
+			}
+		} while(retVal == TPM_RC_NO_RESULT);
+	    // Because the rule is that internal state is not modified if the command
+	    // fails, only end the commit if the command succeeds.
+	    // NOTE that if the result of the Schnorr computation was zero
+	    // it will probably not be worthwhile to run the same command again because
+	    // the result will still be zero. This means that the Commit command will
+	    // need to be run again to get a new commit value for the signature.
+	    if(retVal == TPM_RC_SUCCESS)
+		CryptEndCommit(scheme->details.ecdaa.count);
+	}
+    return retVal;
+}
+#endif // ALG_ECDAA
+#if ALG_ECSCHNORR
+/* 10.2.12.3.3 SchnorrReduce() */
+/* Function to reduce a hash result if it's magnitude is to large. The size of number is set so that
+   it has no more bytes of significance than the reference value. If the resulting number can have
+   more bits of significance than the reference. */
+static void
+SchnorrReduce(
+	      TPM2B       *number,        // IN/OUT: Value to reduce
+	      bigConst     reference      // IN: the reference value
+	      )
+{
+    UINT16      maxBytes = (UINT16)BITS_TO_BYTES(BnSizeInBits(reference));
+    if(number->size > maxBytes)
+	number->size = maxBytes;
+}
+/* 10.2.12.3.4 SchnorrEcc() */
+/* This function is used to perform a modified Schnorr signature. */
+/* This function will generate a random value k and compute */
+/* a) (xR, yR) = [k]G */
+/* b) r = hash(xR || P)(mod q) */
+/* c) rT = truncated r */
+/* d) s= k + rT * ds (mod q) */
+/* e) return the tuple rT, s */
+/* Error Returns Meaning */
+/* TPM_RC_NO_RESULT failure in the Schnorr sign process */
+/* TPM_RC_SCHEME hashAlg can't produce zero-length digest */
+static TPM_RC
+BnSignEcSchnorr(
+		bigNum                   bnR,           // OUT: r component of the signature
+		bigNum                   bnS,           // OUT: s component of the signature
+		bigCurve                 E,             // IN: the curve used in signing
+		bigNum                   bnD,           // IN: the signing key
+		const TPM2B_DIGEST      *digest,        // IN: the digest to sign
+		TPM_ALG_ID               hashAlg,       // IN: signing scheme (contains a hash)
+		RAND_STATE              *rand           // IN: non-NULL when testing
+		)
+{
+    HASH_STATE               hashState;
+    UINT16                   digestSize
+	= CryptHashGetDigestSize(hashAlg);
+    TPM2B_TYPE(T, MAX(MAX_DIGEST_SIZE, MAX_ECC_KEY_BYTES));
+    TPM2B_T                  T2b;
+    TPM2B                   *e = &T2b.b;
+    TPM_RC                   retVal = TPM_RC_NO_RESULT;
+    const ECC_CURVE_DATA    *C;
+    bigConst                 order;
+    bigConst                 prime;
+    ECC_NUM(bnK);
+    POINT(ecR);
+    //
+    // Parameter checks
+    if(E == NULL)
+	ERROR_RETURN(TPM_RC_VALUE);
+    C = AccessCurveData(E);
+    order = CurveGetOrder(C);
+    prime = CurveGetOrder(C);
+    // If the digest does not produce a hash, then null the signature and return
+    // a failure.
+    if(digestSize == 0)
+	{
+	    BnSetWord(bnR, 0);
+	    BnSetWord(bnS, 0);
+	    ERROR_RETURN(TPM_RC_SCHEME);
+	}
+    do
+	{
+	    // Generate a random key pair
+	    if(!BnEccGenerateKeyPair(bnK, ecR, E, rand))
+		break;
+	    // Convert R.x to a string
+	    BnTo2B(ecR->x, e, (NUMBYTES)BITS_TO_BYTES(BnSizeInBits(prime)));
+	    // f) compute r = Hash(e || P) (mod n)
+	    CryptHashStart(&hashState, hashAlg);
+	    CryptDigestUpdate2B(&hashState, e);
+	    CryptDigestUpdate2B(&hashState, &digest->b);
+	    e->size = CryptHashEnd(&hashState, digestSize, e->buffer);
+	    // Reduce the hash size if it is larger than the curve order
+	    SchnorrReduce(e, order);
+	    // Convert hash to number
+	    BnFrom2B(bnR, e);
+	    // Do the Schnorr computation
+	    retVal = BnSchnorrSign(bnS, bnK, bnR, bnD, CurveGetOrder(C));
+	} while(retVal == TPM_RC_NO_RESULT);
+ Exit:
+    return retVal;
+}
+#endif // ALG_ECSCHNORR
+#if ALG_SM2
+#ifdef _SM2_SIGN_DEBUG
+/* 10.2.12.3.5	BnHexEqual() */
+/* This function compares a bignum value to a hex string. */
+/* Return Value	Meaning */
+/* TRUE(1)	values equal */
+/* FALSE(0)	values not equal */
+static BOOL
+BnHexEqual(
+	   bigNum           bn,        //IN: big number value
+	   const char      *c          //IN: character string number
+	   )
+{
+    ECC_NUM(bnC);
+    BnFromHex(bnC, c);
+    return (BnUnsignedCmp(bn, bnC) == 0);
+}
+#endif // _SM2_SIGN_DEBUG
+/* 10.2.12.3.5 BnSignEcSm2() */
+/* This function signs a digest using the method defined in SM2 Part 2. The method in the standard
+   will add a header to the message to be signed that is a hash of the values that define the
+   key. This then hashed with the message to produce a digest (e) that is signed. This function
+   signs e. */
+/* Error Returns Meaning */
+/* TPM_RC_VALUE bad curve */
+static TPM_RC
+BnSignEcSm2(
+	    bigNum                   bnR,       // OUT: r component of the signature
+	    bigNum                   bnS,       // OUT: s component of the signature
+	    bigCurve                 E,         // IN: the curve used in signing
+	    bigNum                   bnD,       // IN: the private key
+	    const TPM2B_DIGEST      *digest,    // IN: the digest to sign
+	    RAND_STATE              *rand       // IN: random number generator (mostly for
+	    //     debug)
+	    )
+{
+    BN_MAX_INITIALIZED(bnE, digest);    // Don't know how big digest might be
+    ECC_NUM(bnN);
+    ECC_NUM(bnK);
+    ECC_NUM(bnT);                       // temp
+    POINT(Q1);
+    bigConst                  order = (E != NULL)
+				      ? CurveGetOrder(AccessCurveData(E)) : NULL;
+    //
+#ifdef _SM2_SIGN_DEBUG
+    BnFromHex(bnE, "B524F552CD82B8B028476E005C377FB1"
+	      "9A87E6FC682D48BB5D42E3D9B9EFFE76");
+    BnFromHex(bnD, "128B2FA8BD433C6C068C8D803DFF7979"
+	      "2A519A55171B1B650C23661D15897263");
+#endif
+    // A3: Use random number generator to generate random number 1 <= k <= n-1;
+    // NOTE: Ax: numbers are from the SM2 standard
+ loop:
+    {
+	// Get a random number 0 < k < n
+	BnGenerateRandomInRange(bnK, order, rand);
+#ifdef _SM2_SIGN_DEBUG
+	BnFromHex(bnK, "6CB28D99385C175C94F94E934817663F"
+		  "C176D925DD72B727260DBAAE1FB2F96F");
+#endif
+	// A4: Figure out the point of elliptic curve (x1, y1)=[k]G, and according
+	// to details specified in 4.2.7 in Part 1 of this document, transform the
+	// data type of x1 into an integer;
+	if(!BnEccModMult(Q1, NULL, bnK, E))
+	    goto loop;
+	// A5: Figure out r = (e + x1) mod n,
+	BnAdd(bnR, bnE, Q1->x);
+	BnMod(bnR, order);
+#ifdef _SM2_SIGN_DEBUG
+	pAssert(BnHexEqual(bnR, "40F1EC59F793D9F49E09DCEF49130D41"
+			   "94F79FB1EED2CAA55BACDB49C4E755D1"));
+#endif
+	// if r=0 or r+k=n, return to A3;
+	if(BnEqualZero(bnR))
+	    goto loop;
+	BnAdd(bnT, bnK, bnR);
+	if(BnUnsignedCmp(bnT, bnN) == 0)
+	    goto loop;
+	// A6: Figure out s = ((1 + dA)^-1  (k - r  dA)) mod n,
+	// if s=0, return to A3;
+	// compute t = (1+dA)^-1
+	BnAddWord(bnT, bnD, 1);
+	BnModInverse(bnT, bnT, order);
+#ifdef _SM2_SIGN_DEBUG
+	pAssert(BnHexEqual(bnT, "79BFCF3052C80DA7B939E0C6914A18CB"
+			   "B2D96D8555256E83122743A7D4F5F956"));
+#endif
+	// compute s = t * (k - r * dA) mod n
+	BnModMult(bnS, bnR, bnD, order);
+	// k - r * dA mod n = k + n - ((r * dA) mod n)
+	BnSub(bnS, order, bnS);
+	BnAdd(bnS, bnK, bnS);
+	BnModMult(bnS, bnS, bnT, order);
+#ifdef _SM2_SIGN_DEBUG
+	pAssert(BnHexEqual(bnS, "6FC6DAC32C5D5CF10C77DFB20F7C2EB6"
+			   "67A457872FB09EC56327A67EC7DEEBE7"));
+#endif
+	if(BnEqualZero(bnS))
+	    goto loop;
+    }
+    // A7: According to details specified in 4.2.1 in Part 1 of this document,
+    // transform the data type of r, s into bit strings, signature of message M
+    // is (r, s).
+    // This is handled by the common return code
+#ifdef _SM2_SIGN_DEBUG
+    pAssert(BnHexEqual(bnR, "40F1EC59F793D9F49E09DCEF49130D41"
+		       "94F79FB1EED2CAA55BACDB49C4E755D1"));
+    pAssert(BnHexEqual(bnS, "6FC6DAC32C5D5CF10C77DFB20F7C2EB6"
+		       "67A457872FB09EC56327A67EC7DEEBE7"));
+#endif
+    return TPM_RC_SUCCESS;
+}
+#endif // ALG_SM2
+/* 10.2.12.3.6 CryptEccSign() */
+/* This function is the dispatch function for the various ECC-based signing schemes. There is a bit
+   of ugliness to the parameter passing. In order to test this, we sometime would like to use a
+   deterministic RNG so that we can get the same signatures during testing. The easiest way to do
+   this for most schemes is to pass in a deterministic RNG and let it return canned values during
+   testing. There is a competing need for a canned parameter to use in ECDAA. To accommodate both
+   needs with minimal fuss, a special type of RAND_STATE is defined to carry the address of the
+   commit value. The setup and handling of this is not very different for the caller than what was
+   in previous versions of the code. */
+/* Error Returns Meaning */
+/* TPM_RC_SCHEME scheme is not supported */
+LIB_EXPORT TPM_RC
+CryptEccSign(
+	     TPMT_SIGNATURE          *signature,     // OUT: signature
+	     OBJECT                  *signKey,       // IN: ECC key to sign the hash
+	     const TPM2B_DIGEST      *digest,        // IN: digest to sign
+	     TPMT_ECC_SCHEME         *scheme,        // IN: signing scheme
+	     RAND_STATE              *rand
+	     )
+{
+    CURVE_INITIALIZED(E, signKey->publicArea.parameters.eccDetail.curveID);
+    ECC_INITIALIZED(bnD, &signKey->sensitive.sensitive.ecc.b);
+    ECC_NUM(bnR);
+    ECC_NUM(bnS);
+    const ECC_CURVE_DATA   *C;
+    TPM_RC                  retVal = TPM_RC_SCHEME;
+    //
+    NOT_REFERENCED(scheme);
+    if(E == NULL)
+	ERROR_RETURN(TPM_RC_VALUE);
+    C = AccessCurveData(E);
+    signature->signature.ecdaa.signatureR.t.size
+	= sizeof(signature->signature.ecdaa.signatureR.t.buffer);
+    signature->signature.ecdaa.signatureS.t.size
+	= sizeof(signature->signature.ecdaa.signatureS.t.buffer);
+    TEST(signature->sigAlg);
+    switch(signature->sigAlg)
+	{
+	  case TPM_ALG_ECDSA:
+	    retVal = BnSignEcdsa(bnR, bnS, E, bnD, digest, rand);
+	    break;
+#if ALG_ECDAA
+	  case TPM_ALG_ECDAA:
+	    retVal = BnSignEcdaa(&signature->signature.ecdaa.signatureR, bnS, E,
+				 bnD, digest, scheme, signKey, rand);
+	    bnR = NULL;
+	    break;
+#endif
+#if ALG_ECSCHNORR
+	  case TPM_ALG_ECSCHNORR:
+	    retVal = BnSignEcSchnorr(bnR, bnS, E, bnD, digest,
+				     signature->signature.ecschnorr.hash,
+				     rand);
+	    break;
+#endif
+#if ALG_SM2
+	  case TPM_ALG_SM2:
+	    retVal = BnSignEcSm2(bnR, bnS, E, bnD, digest, rand);
+	    break;
+#endif
+	  default:
+	    break;
+	}
+    // If signature generation worked, convert the results.
+    if(retVal == TPM_RC_SUCCESS)
+	{
+	    NUMBYTES     orderBytes =
+		(NUMBYTES)BITS_TO_BYTES(BnSizeInBits(CurveGetOrder(C)));
+	    if(bnR != NULL)
+		BnTo2B(bnR, &signature->signature.ecdaa.signatureR.b, orderBytes);
+	    if(bnS != NULL)
+		BnTo2B(bnS, &signature->signature.ecdaa.signatureS.b, orderBytes);
+	}
+ Exit:
+    CURVE_FREE(E);
+    return retVal;
+}
+#if ALG_ECDSA
+/* 10.2.12.3.7 BnValidateSignatureEcdsa() */
+/* This function validates an ECDSA signature. rIn and sIn should have been checked to make sure
+   that they are in the range 0 < v < n */
+/* Error Returns Meaning */
+/* TPM_RC_SIGNATURE signature not valid */
+TPM_RC
+BnValidateSignatureEcdsa(
+			 bigNum                   bnR,           // IN: r component of the signature
+			 bigNum                   bnS,           // IN: s component of the signature
+			 bigCurve                 E,             // IN: the curve used in the signature
+			 //     process
+			 bn_point_t              *ecQ,           // IN: the public point of the key
+			 const TPM2B_DIGEST      *digest         // IN: the digest that was signed
+			 )
+{
+    // Make sure that the allocation for the digest is big enough for a maximum
+    // digest
+    BN_VAR(bnE, MAX(MAX_ECC_KEY_BYTES, MAX_DIGEST_SIZE) * 8);
+    POINT(ecR);
+    ECC_NUM(bnU1);
+    ECC_NUM(bnU2);
+    ECC_NUM(bnW);
+    bigConst                 order = CurveGetOrder(AccessCurveData(E));
+    TPM_RC                   retVal = TPM_RC_SIGNATURE;
+    // Get adjusted digest
+    EcdsaDigest(bnE, digest, order);
+    // 1. If r and s are not both integers in the interval [1, n - 1], output
+    //    INVALID.
+    //  bnR  and bnS were validated by the caller
+    // 2. Use the selected hash function to compute H0 = Hash(M0).
+    // This is an input parameter
+    // 3. Convert the bit string H0 to an integer e as described in Appendix B.2.
+    // Done at entry
+    // 4. Compute w = (s')^-1 mod n, using the routine in Appendix B.1.
+    if(!BnModInverse(bnW, bnS, order))
+	goto Exit;
+    // 5. Compute u1 = (e' *   w) mod n, and compute u2 = (r' *  w) mod n.
+    BnModMult(bnU1, bnE, bnW, order);
+    BnModMult(bnU2, bnR, bnW, order);
+    // 6. Compute the elliptic curve point R = (xR, yR) = u1G+u2Q, using EC
+    //    scalar multiplication and EC addition (see [Routines]). If R is equal to
+    //    the point at infinity O, output INVALID.
+    if(BnPointMult(ecR, CurveGetG(AccessCurveData(E)), bnU1, ecQ, bnU2, E)
+       != TPM_RC_SUCCESS)
+	goto Exit;
+    // 7. Compute v = Rx mod n.
+    BnMod(ecR->x, order);
+    // 8. Compare v and r0. If v = r0, output VALID; otherwise, output INVALID
+    if(BnUnsignedCmp(ecR->x, bnR) != 0)
+	goto Exit;
+    retVal = TPM_RC_SUCCESS;
+ Exit:
+    return retVal;
+}
+#endif      // ALG_ECDSA
+#if ALG_SM2
+/* 10.2.12.3.8 BnValidateSignatureEcSm2() */
+/* This function is used to validate an SM2 signature. */
+/* Error Returns Meaning */
+/* TPM_RC_SIGNATURE signature not valid */
+static TPM_RC
+BnValidateSignatureEcSm2(
+			 bigNum                   bnR,       // IN: r component of the signature
+			 bigNum                   bnS,       // IN: s component of the signature
+			 bigCurve                 E,         // IN: the curve used in the signature
+			 //     process
+			 bigPoint                 ecQ,       // IN: the public point of the key
+			 const TPM2B_DIGEST      *digest     // IN: the digest that was signed
+			 )
+{
+    POINT(P);
+    ECC_NUM(bnRp);
+    ECC_NUM(bnT);
+    BN_MAX_INITIALIZED(bnE, digest);
+    BOOL                     OK;
+    bigConst                 order = CurveGetOrder(AccessCurveData(E));
+#ifdef _SM2_SIGN_DEBUG
+    // Make sure that the input signature is the test signature
+    pAssert(BnHexEqual(bnR,
+		       "40F1EC59F793D9F49E09DCEF49130D41"
+		       "94F79FB1EED2CAA55BACDB49C4E755D1"));
+    pAssert(BnHexEqual(bnS,
+		       "6FC6DAC32C5D5CF10C77DFB20F7C2EB6"
+		       "67A457872FB09EC56327A67EC7DEEBE7"));
+#endif
+    // b)   compute t  := (r + s) mod n
+    BnAdd(bnT, bnR, bnS);
+    BnMod(bnT, order);
+#ifdef _SM2_SIGN_DEBUG
+    pAssert(BnHexEqual(bnT,
+		       "2B75F07ED7ECE7CCC1C8986B991F441A"
+		       "D324D6D619FE06DD63ED32E0C997C801"));
+#endif
+    // c)   verify that t > 0
+    OK = !BnEqualZero(bnT);
+    if(!OK)
+	// set T to a value that should allow rest of the computations to run
+	// without trouble
+	BnCopy(bnT, bnS);
+    // d)   compute (x, y) := [s]G + [t]Q
+    OK = BnEccModMult2(P, NULL, bnS, ecQ, bnT, E);
+#ifdef  _SM2_SIGN_DEBUG
+    pAssert(OK && BnHexEqual(P->x,
+			     "110FCDA57615705D5E7B9324AC4B856D"
+			     "23E6D9188B2AE47759514657CE25D112"));
+#endif
+    // e)   compute r' := (e + x) mod n (the x coordinate is in bnT)
+    OK = OK && BnAdd(bnRp, bnE, P->x);
+    OK = OK && BnMod(bnRp, order);
+    // f)   verify that r' = r
+    OK = OK && (BnUnsignedCmp(bnR, bnRp) == 0);
+    
+    if(!OK)    
+	return TPM_RC_SIGNATURE;
+    else
+	return TPM_RC_SUCCESS;
+}
+#endif  // ALG_SM2
+#if ALG_ECSCHNORR
+/* 10.2.12.3.9 BnValidateSignatureEcSchnorr() */
+/* This function is used to validate an EC Schnorr signature. */
+/* Error Returns Meaning */
+/* TPM_RC_SIGNATURE signature not valid */
+static TPM_RC
+BnValidateSignatureEcSchnorr(
+			     bigNum               bnR,       // IN: r component of the signature
+			     bigNum               bnS,       // IN: s component of the signature
+			     TPM_ALG_ID           hashAlg,   // IN: hash algorithm of the signature
+			     bigCurve             E,         // IN: the curve used in the signature
+			     //     process
+			     bigPoint             ecQ,       // IN: the public point of the key
+			     const TPM2B_DIGEST  *digest     // IN: the digest that was signed
+			     )
+{
+    BN_MAX(bnRn);
+    POINT(ecE);
+    BN_MAX(bnEx);
+    const ECC_CURVE_DATA    *C = AccessCurveData(E);
+    bigConst                 order = CurveGetOrder(C);
+    UINT16                   digestSize = CryptHashGetDigestSize(hashAlg);
+    HASH_STATE               hashState;
+    TPM2B_TYPE(BUFFER, MAX(MAX_ECC_PARAMETER_BYTES, MAX_DIGEST_SIZE));
+    TPM2B_BUFFER             Ex2 = {{sizeof(Ex2.t.buffer),{ 0 }}};
+    BOOL                     OK;
+    //
+    // E = [s]G - [r]Q
+    BnMod(bnR, order);
+    // Make -r = n - r
+    BnSub(bnRn, order, bnR);
+    // E = [s]G + [-r]Q
+    OK = BnPointMult(ecE, CurveGetG(C), bnS, ecQ, bnRn, E) == TPM_RC_SUCCESS;
+    //   // reduce the x portion of E mod q
+    //    OK = OK && BnMod(ecE->x, order);
+    // Convert to byte string
+    OK = OK && BnTo2B(ecE->x, &Ex2.b,
+		      (NUMBYTES)(BITS_TO_BYTES(BnSizeInBits(order))));
+    if(OK)
+	{
+	    // Ex = h(pE.x || digest)
+	    CryptHashStart(&hashState, hashAlg);
+	    CryptDigestUpdate(&hashState, Ex2.t.size, Ex2.t.buffer);
+	    CryptDigestUpdate(&hashState, digest->t.size, digest->t.buffer);
+	    Ex2.t.size = CryptHashEnd(&hashState, digestSize, Ex2.t.buffer);
+	    SchnorrReduce(&Ex2.b, order);
+	    BnFrom2B(bnEx, &Ex2.b);
+	    // see if Ex matches R
+	    OK = BnUnsignedCmp(bnEx, bnR) == 0;
+	}
+    return (OK) ? TPM_RC_SUCCESS : TPM_RC_SIGNATURE;
+}
+#endif  // ALG_ECSCHNORR
+/* 10.2.12.3.10 CryptEccValidateSignature() */
+/* This function validates an EcDsa() or EcSchnorr() signature. The point Qin needs to have been
+   validated to be on the curve of curveId. */
+/* Error Returns Meaning */
+/* TPM_RC_SIGNATURE not a valid signature */
+LIB_EXPORT TPM_RC
+CryptEccValidateSignature(
+			  TPMT_SIGNATURE          *signature,     // IN: signature to be verified
+			  OBJECT                  *signKey,       // IN: ECC key signed the hash
+			  const TPM2B_DIGEST      *digest         // IN: digest that was signed
+			  )
+{
+    CURVE_INITIALIZED(E, signKey->publicArea.parameters.eccDetail.curveID);
+    ECC_NUM(bnR);
+    ECC_NUM(bnS);
+    POINT_INITIALIZED(ecQ, &signKey->publicArea.unique.ecc);
+    bigConst                 order;
+    TPM_RC                   retVal;
+    if(E == NULL)
+	ERROR_RETURN(TPM_RC_VALUE);
+    order = CurveGetOrder(AccessCurveData(E));
+    //    // Make sure that the scheme is valid
+    switch(signature->sigAlg)
+	{
+	  case TPM_ALG_ECDSA:
+#if ALG_ECSCHNORR
+	  case TPM_ALG_ECSCHNORR:
+#endif
+#if ALG_SM2
+	  case TPM_ALG_SM2:
+#endif
+	    break;
+	  default:
+	    ERROR_RETURN(TPM_RC_SCHEME);
+	    break;
+	}
+    // Can convert r and s after determining that the scheme is an ECC scheme. If
+    // this conversion doesn't work, it means that the unmarshaling code for
+    // an ECC signature is broken.
+    BnFrom2B(bnR, &signature->signature.ecdsa.signatureR.b);
+    BnFrom2B(bnS, &signature->signature.ecdsa.signatureS.b);
+    // r and s have to be greater than 0 but less than the curve order
+    if(BnEqualZero(bnR) || BnEqualZero(bnS))
+	ERROR_RETURN(TPM_RC_SIGNATURE);
+    if((BnUnsignedCmp(bnS, order) >= 0)
+       || (BnUnsignedCmp(bnR, order) >= 0))
+	ERROR_RETURN(TPM_RC_SIGNATURE);
+    switch(signature->sigAlg)
+	{
+	  case TPM_ALG_ECDSA:
+	    retVal = BnValidateSignatureEcdsa(bnR, bnS, E, ecQ, digest);
+	    break;
+#if ALG_ECSCHNORR
+	  case TPM_ALG_ECSCHNORR:
+	    retVal = BnValidateSignatureEcSchnorr(bnR, bnS,
+						  signature->signature.any.hashAlg,
+						  E, ecQ, digest);
+	    break;
+#endif
+#if ALG_SM2
+	  case TPM_ALG_SM2:
+	    retVal = BnValidateSignatureEcSm2(bnR, bnS, E, ecQ, digest);
+	    break;
+#endif
+	  default:
+	    FAIL(FATAL_ERROR_INTERNAL);
+	}
+ Exit:
+    CURVE_FREE(E);
+    return retVal;
+}
+/* 10.2.12.3.11 CryptEccCommitCompute() */
+/* This function performs the point multiply operations required by TPM2_Commit(). */
+/* If B or M is provided, they must be on the curve defined by curveId. This routine does not check
+   that they are on the curve and results are unpredictable if they are not. */
+/* It is a fatal error if r is NULL. If B is not NULL, then it is a fatal error if d is NULL or if K
+   and L are both NULL. If M is not NULL, then it is a fatal error if E is NULL. */
+/* Error Returns Meaning */
+/* TPM_RC_NO_RESULT if K, L or E was computed to be the point at infinity */
+/* TPM_RC_CANCELED a cancel indication was asserted during this function */
+LIB_EXPORT TPM_RC
+CryptEccCommitCompute(
+		      TPMS_ECC_POINT          *K,             // OUT: [d]B or [r]Q
+		      TPMS_ECC_POINT          *L,             // OUT: [r]B
+		      TPMS_ECC_POINT          *E,             // OUT: [r]M
+		      TPM_ECC_CURVE            curveId,       // IN: the curve for the computations
+		      TPMS_ECC_POINT          *M,             // IN: M (optional)
+		      TPMS_ECC_POINT          *B,             // IN: B (optional)
+		      TPM2B_ECC_PARAMETER     *d,             // IN: d (optional)
+		      TPM2B_ECC_PARAMETER     *r              // IN: the computed r value (required)
+		      )
+{
+    CURVE_INITIALIZED(curve, curveId);  	// Normally initialize E as the curve, but E means
+						// something else in this function
+    ECC_INITIALIZED(bnR, r);
+    TPM_RC               retVal = TPM_RC_SUCCESS;
+    //
+    // Validate that the required parameters are provided.
+    // Note: E has to be provided if computing E := [r]Q or E := [r]M. Will do
+    // E := [r]Q if both M and B are NULL.
+    pAssert(r != NULL && E != NULL);
+    // Initialize the output points in case they are not computed
+    ClearPoint2B(K);
+    ClearPoint2B(L);
+    ClearPoint2B(E);
+    // Sizes of the r parameter may not be zero
+    pAssert(r->t.size > 0);
+    // If B is provided, compute K=[d]B and L=[r]B
+    if(B != NULL)
+	{
+	    ECC_INITIALIZED(bnD, d);
+	    POINT_INITIALIZED(pB, B);
+	    POINT(pK);
+	    POINT(pL);
+	    //
+	    pAssert(d != NULL && K != NULL && L != NULL);
+	    if(!BnIsOnCurve(pB, AccessCurveData(curve)))
+		ERROR_RETURN(TPM_RC_VALUE);
+	    // do the math for K = [d]B
+	    if((retVal = BnPointMult(pK, pB, bnD, NULL, NULL, curve)) != TPM_RC_SUCCESS)
+		goto Exit;
+	    // Convert BN K to TPM2B K
+	    BnPointTo2B(K, pK, curve);
+	    //  compute L= [r]B after checking for cancel
+	    if(_plat__IsCanceled())
+		ERROR_RETURN(TPM_RC_CANCELED);
+	    // compute L = [r]B
+	    if(!BnIsValidPrivateEcc(bnR, curve))
+		ERROR_RETURN(TPM_RC_VALUE);
+	    if((retVal = BnPointMult(pL, pB, bnR, NULL, NULL, curve)) != TPM_RC_SUCCESS)
+		goto Exit;
+	    // Convert BN L to TPM2B L
+	    BnPointTo2B(L, pL, curve);
+	}
+    if((M != NULL) || (B == NULL))
+	{
+	    POINT_INITIALIZED(pM, M);
+	    POINT(pE);
+	    //
+	    // Make sure that a place was provided for the result
+	    pAssert(E != NULL);
+	    // if this is the third point multiply, check for cancel first
+	    if((B != NULL) && _plat__IsCanceled())
+		ERROR_RETURN(TPM_RC_CANCELED);
+	    // If M provided, then pM will not be NULL and will compute E = [r]M.
+	    // However, if M was not provided, then pM will be NULL and E = [r]G
+	    // will be computed
+	    if((retVal = BnPointMult(pE, pM, bnR, NULL, NULL, curve)) != TPM_RC_SUCCESS)
+		goto Exit;
+	    // Convert E to 2B format
+	    BnPointTo2B(E, pE, curve);
+	}
+ Exit:
+    CURVE_FREE(curve);
+    return retVal;
+}
+#endif  // TPM_ALG_ECC

+ 111 - 0
EVSE/GPL/ibmtpm1682/src/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

+ 863 - 0
EVSE/GPL/ibmtpm1682/src/CryptHash.c

@@ -0,0 +1,863 @@
+/********************************************************************************/
+/*										*/
+/*		Implementation of cryptographic functions for hashing.		*/
+/*			     Written by Ken Goldman				*/
+/*		       IBM Thomas J. Watson Research Center			*/
+/*            $Id: CryptHash.c 1658 2021-01-22 23:14:01Z kgoldman $		*/
+/*										*/
+/*  Licenses and Notices							*/
+/*										*/
+/*  1. Copyright Licenses:							*/
+/*										*/
+/*  - Trusted Computing Group (TCG) grants to the user of the source code in	*/
+/*    this specification (the "Source Code") a worldwide, irrevocable, 		*/
+/*    nonexclusive, royalty free, copyright license to reproduce, create 	*/
+/*    derivative works, distribute, display and perform the Source Code and	*/
+/*    derivative works thereof, and to grant others the rights granted herein.	*/
+/*										*/
+/*  - The TCG grants to the user of the other parts of the specification 	*/
+/*    (other than the Source Code) the rights to reproduce, distribute, 	*/
+/*    display, and perform the specification solely for the purpose of 		*/
+/*    developing products based on such documents.				*/
+/*										*/
+/*  2. Source Code Distribution Conditions:					*/
+/*										*/
+/*  - Redistributions of Source Code must retain the above copyright licenses, 	*/
+/*    this list of conditions and the following disclaimers.			*/
+/*										*/
+/*  - Redistributions in binary form must reproduce the above copyright 	*/
+/*    licenses, this list of conditions	and the following disclaimers in the 	*/
+/*    documentation and/or other materials provided with the distribution.	*/
+/*										*/
+/*  3. Disclaimers:								*/
+/*										*/
+/*  - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF	*/
+/*  LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH	*/
+/*  RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES)	*/
+/*  THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE.		*/
+/*  Contact TCG Administration (admin@trustedcomputinggroup.org) for 		*/
+/*  information on specification licensing rights available through TCG 	*/
+/*  membership agreements.							*/
+/*										*/
+/*  - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED 	*/
+/*    WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR 	*/
+/*    FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR 		*/
+/*    NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY 		*/
+/*    OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE.		*/
+/*										*/
+/*  - Without limitation, TCG and its members and licensors disclaim all 	*/
+/*    liability, including liability for infringement of any proprietary 	*/
+/*    rights, relating to use of information in this specification and to the	*/
+/*    implementation of this specification, and TCG disclaims all liability for	*/
+/*    cost of procurement of substitute goods or services, lost profits, loss 	*/
+/*    of use, loss of data or any incidental, consequential, direct, indirect, 	*/
+/*    or special damages, whether under contract, tort, warranty or otherwise, 	*/
+/*    arising in any way out of use or reliance upon this specification or any 	*/
+/*    information herein.							*/
+/*										*/
+/*  (c) Copyright IBM Corp. and others, 2016 - 2021				*/
+/*										*/
+/********************************************************************************/
+
+/* 10.2.13	CryptHash.c */
+/* 10.2.13.1	Description */
+/* This file contains implementation of cryptographic functions for hashing. */
+/* 10.2.13.2	Includes, Defines, and Types */
+#define _CRYPT_HASH_C_
+#include "Tpm.h"
+#include "CryptHash_fp.h"
+#include "CryptHash.h"
+#include "OIDs.h"
+
+/* Instance each of the hash descriptors based on the implemented algorithms */
+
+FOR_EACH_HASH(HASH_DEF_TEMPLATE)
+
+/* Instance a null def. */
+
+    HASH_DEF NULL_Def = {{0}};
+
+/* Create a table of pointers to the defined hash definitions */
+
+#define HASH_DEF_ENTRY(HASH, Hash)     &Hash##_Def,
+PHASH_DEF       HashDefArray[] = {
+				  // for each implemented HASH, expands to: &HASH_Def,
+				  FOR_EACH_HASH(HASH_DEF_ENTRY)
+				  &NULL_Def
+};
+
+/* 10.2.13.3	Obligatory Initialization Functions */
+/* 10.2.13.3.1	CryptHashInit() */
+/* This function is called by _TPM_Init() do perform the initialization operations for the
+   library. */
+BOOL
+CryptHashInit(
+	      void
+	      )
+{
+    LibHashInit();
+    return TRUE;
+}
+/* 10.2.13.3.2	CryptHashStartup() */
+/* This function is called by TPM2_Startup().  It checks that the size of the HashDefArray() is
+   consistent with the HASH_COUNT. */
+BOOL
+CryptHashStartup(
+		 void
+		 )
+{
+    int         i = sizeof(HashDefArray) / sizeof(PHASH_DEF) - 1;
+    return (i == HASH_COUNT);
+}
+/* 10.2.13.4	Hash Information Access Functions */
+/* 10.2.13.4.1	Introduction */
+/* These functions provide access to the hash algorithm description information. */
+/* 10.2.13.4.2	CryptGetHashDef() */
+/* This function accesses the hash descriptor associated with a hash a algorithm. The function
+   returns a pointer to a null descriptor if hashAlg is TPM_ALG_NULL or not a defined algorithm. */
+
+PHASH_DEF
+CryptGetHashDef(
+		TPM_ALG_ID       hashAlg
+		)
+{
+#define GET_DEF(HASH, Hash) case ALG_##HASH##_VALUE: return &Hash##_Def;
+    switch(hashAlg)
+	{
+	    FOR_EACH_HASH(GET_DEF)
+	  default:
+	    return &NULL_Def;
+	}
+#undef GET_DEF
+}
+/* 10.2.13.4.3	CryptHashIsValidAlg() */
+/* This function tests to see if an algorithm ID is a valid hash algorithm. If flag is true, then
+   TPM_ALG_NULL is a valid hash. */
+/*     Return Value	Meaning */
+/*     TRUE(1)	hashAlg is a valid, implemented hash on this TPM */
+/*     FALSE(0)	hashAlg is not valid for this TPM */
+BOOL
+CryptHashIsValidAlg(
+		    TPM_ALG_ID       hashAlg,           // IN: the algorithm to check
+		    BOOL             flag               // IN: TRUE if TPM_ALG_NULL is to be treated
+		    //     as a valid hash
+		    )
+{
+    if(hashAlg == TPM_ALG_NULL)
+	return flag;
+    return CryptGetHashDef(hashAlg) != &NULL_Def;
+}
+/* 10.2.13.4.4 CryptHashGetAlgByIndex() */
+/* This function is used to iterate through the hashes. TPM_ALG_NULL is returned for all indexes
+   that are not valid hashes. If the TPM implements 3 hashes, then an index value of 0 will return
+   the first implemented hash and an index of 2 will return the last. All other index values will
+   return TPM_ALG_NULL. */
+/*     Return Value	Meaning */
+/*     TPM_ALG_xxx	a hash algorithm */
+/*     TPM_ALG_NULL	this can be used as a stop value */
+LIB_EXPORT TPM_ALG_ID
+CryptHashGetAlgByIndex(
+		       UINT32           index          // IN: the index
+		       )
+{
+    TPM_ALG_ID       hashAlg;
+    if(index >= HASH_COUNT)
+	hashAlg = TPM_ALG_NULL;
+    else
+	hashAlg = HashDefArray[index]->hashAlg;
+    return hashAlg;
+}
+/* 10.2.13.4.5	CryptHashGetDigestSize() */
+/* Returns the size of the digest produced by the hash. If hashAlg is not a hash algorithm, the TPM
+   will FAIL. */
+/*     Return Value	Meaning */
+/*     0	TPM_ALG_NULL */
+/*     > 0	the digest size */
+LIB_EXPORT UINT16
+CryptHashGetDigestSize(
+		       TPM_ALG_ID       hashAlg        // IN: hash algorithm to look up
+		       )
+{
+    return CryptGetHashDef(hashAlg)->digestSize;
+}
+/* 10.2.13.4.6	CryptHashGetBlockSize() */
+/* Returns the size of the block used by the hash. If hashAlg is not a hash algorithm, the TPM will
+   FAIL. */
+/*     Return Value	Meaning */
+/*     0	TPM_ALG_NULL */
+/*     > 0	the digest size */
+LIB_EXPORT UINT16
+CryptHashGetBlockSize(
+		      TPM_ALG_ID       hashAlg        // IN: hash algorithm to look up
+		      )
+{
+    return CryptGetHashDef(hashAlg)->blockSize;
+}
+/* 10.2.13.4.7	CryptHashGetOid() */
+/* This function returns a pointer to DER=encoded OID for a hash algorithm. All OIDs are full OID
+   values including the Tag (0x06) and length byte. */
+LIB_EXPORT const BYTE *
+CryptHashGetOid(
+		TPM_ALG_ID      hashAlg
+		)
+{
+    return CryptGetHashDef(hashAlg)->OID;
+}
+/* 10.2.13.4.8	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.13.5	State Import and Export */
+/* 10.2.13.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)
+	{
+	    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;
+}
+/* 10.2.13.5.2	CryptHashExportState() */
+/* This function is used to export a hash or HMAC hash state. This function would be called when
+   preparing to context save a sequence object. */
+void
+CryptHashExportState(
+		     PCHASH_STATE         internalFmt,   // IN: the hash state formatted for use by
+		     //     library
+		     PEXPORT_HASH_STATE   externalFmt    // OUT: the exported hash state
+		     )
+{
+    BYTE                    *outBuf = (BYTE *)externalFmt;
+    //
+    cAssert(sizeof(HASH_STATE) <= sizeof(EXPORT_HASH_STATE));
+    // the following #define is used to move data from an aligned internal data
+    // structure to a byte buffer (external format data.
+#define CopyToOffset(value)						\
+    memcpy(&outBuf[offsetof(HASH_STATE,value)], &internalFmt->value,	\
+	   sizeof(internalFmt->value))
+    // Copy the hashAlg
+    CopyToOffset(hashAlg);
+    CopyToOffset(type);
+#ifdef HASH_STATE_SMAC
+    if(internalFmt->type == HASH_STATE_SMAC)
+	{
+	    memcpy(outBuf, internalFmt, sizeof(HASH_STATE));
+	    return;
+	    
+	}
+#endif
+    if(internalFmt->type == HASH_STATE_HMAC)
+	{
+	    HMAC_STATE              *from = (HMAC_STATE *)internalFmt;
+	    memcpy(&outBuf[offsetof(HMAC_STATE, hmacKey)], &from->hmacKey,
+		   sizeof(from->hmacKey));
+	}
+    if(internalFmt->hashAlg != TPM_ALG_NULL)
+	HASH_STATE_EXPORT(externalFmt, internalFmt);
+}
+/* 10.2.13.5.3	CryptHashImportState() */
+/* This function is used to import the hash state. This function would be called to import a hash
+   state when the context of a sequence object was being loaded. */
+void
+CryptHashImportState(
+		     PHASH_STATE          internalFmt,   // OUT: the hash state formatted for use by
+		     //     the library
+		     PCEXPORT_HASH_STATE  externalFmt    // IN: the exported hash state
+		     )
+{
+    BYTE                    *inBuf = (BYTE *)externalFmt;
+    //
+#define CopyFromOffset(value)						\
+    memcpy(&internalFmt->value, &inBuf[offsetof(HASH_STATE,value)],	\
+	   sizeof(internalFmt->value))
+    
+    // Copy the hashAlg of the byte-aligned input structure to the structure-aligned
+    // internal structure.
+    CopyFromOffset(hashAlg);
+    CopyFromOffset(type);
+    if(internalFmt->hashAlg != TPM_ALG_NULL)
+	{
+#ifdef HASH_STATE_SMAC
+	    if(internalFmt->type == HASH_STATE_SMAC)
+		{
+		    memcpy(internalFmt, inBuf, sizeof(HASH_STATE));
+		    return;
+		}
+#endif
+	    internalFmt->def = CryptGetHashDef(internalFmt->hashAlg);
+	    HASH_STATE_IMPORT(internalFmt, inBuf);
+	    if(internalFmt->type == HASH_STATE_HMAC)
+		{
+		    HMAC_STATE              *to = (HMAC_STATE *)internalFmt;
+		    memcpy(&to->hmacKey, &inBuf[offsetof(HMAC_STATE, hmacKey)],
+			   sizeof(to->hmacKey));
+		}
+	}
+}
+/* 10.2.13.6	State Modification Functions */
+/* 10.2.13.6.1	HashEnd() */
+/* Local function to complete a hash that uses the hashDef instead of an algorithm ID. This function
+   is used to complete the hash and only return a partial digest. The return value is the size of
+   the data copied. */
+static UINT16
+HashEnd(
+	PHASH_STATE      hashState,     // IN: the hash state
+	UINT32           dOutSize,      // IN: the size of receive buffer
+	PBYTE            dOut           // OUT: the receive buffer
+	)
+{
+    BYTE                temp[MAX_DIGEST_SIZE];
+    if((hashState->hashAlg == TPM_ALG_NULL)
+       || (hashState->type != HASH_STATE_HASH))
+	dOutSize = 0;
+    if(dOutSize > 0)
+	{
+	    hashState->def = CryptGetHashDef(hashState->hashAlg);
+	    // Set the final size
+	    dOutSize = MIN(dOutSize, hashState->def->digestSize);
+	    // Complete into the temp buffer and then copy
+	    HASH_END(hashState, temp);
+	    // Don't want any other functions calling the HASH_END method
+	    // directly.
+#undef HASH_END
+	    memcpy(dOut, &temp, dOutSize);
+	}
+    hashState->type = HASH_STATE_EMPTY;
+    return (UINT16)dOutSize;
+}
+/* 10.2.13.6.2	CryptHashStart() */
+/* Functions starts a hash stack Start a hash stack and returns the digest size. As a side effect,
+   the value of stateSize in hashState is updated to indicate the number of bytes of state that were
+   saved. This function calls GetHashServer() and that function will put the TPM into failure mode
+   if the hash algorithm is not supported. */
+/* This function does not use the sequence parameter. If it is necessary to import or export
+   context, this will start the sequence in a local state and export the state to the input
+   buffer. Will need to add a flag to the state structure to indicate that it needs to be imported
+   before it can be used. (BLEH). */
+/*     Return Value	Meaning */
+/*     0	hash is TPM_ALG_NULL */
+/*     >0	digest size */
+LIB_EXPORT UINT16
+CryptHashStart(
+	       PHASH_STATE      hashState,     // OUT: the running hash state
+	       TPM_ALG_ID       hashAlg        // IN: hash algorithm
+	       )
+{
+    UINT16               retVal;
+	
+    TEST(hashAlg);
+	
+    hashState->hashAlg = hashAlg;
+    if(hashAlg == TPM_ALG_NULL)
+	{
+	    retVal = 0;
+	}
+    else
+	{
+	    hashState->def = CryptGetHashDef(hashAlg);
+	    HASH_START(hashState);
+	    retVal = hashState->def->digestSize;
+	}
+#undef HASH_START
+    hashState->type = HASH_STATE_HASH;
+    return retVal;
+}
+/* 10.2.13.6.3	CryptDigestUpdate() */
+/* Add data to a hash or HMAC, SMAC stack. */
+void
+CryptDigestUpdate(
+		  PHASH_STATE      hashState,     // IN: the hash context information
+		  UINT32           dataSize,      // IN: the size of data to be added
+		  const BYTE      *data           // IN: data to be hashed
+		  )
+{
+    if(hashState->hashAlg != TPM_ALG_NULL)
+	{
+	    if((hashState->type == HASH_STATE_HASH)
+	       || (hashState->type == HASH_STATE_HMAC))
+		HASH_DATA(hashState, dataSize, (BYTE *)data);
+#if SMAC_IMPLEMENTED
+	    else if(hashState->type == HASH_STATE_SMAC)
+		(hashState->state.smac.smacMethods.data)(&hashState->state.smac.state,
+							 dataSize, data);
+#endif // SMAC_IMPLEMENTED
+	    else
+		FAIL(FATAL_ERROR_INTERNAL);
+	}
+    return;
+}
+/* 10.2.13.6.4 CryptHashEnd() */
+/* Complete a hash or HMAC computation. This function will place the smaller of digestSize or the
+   size of the digest in dOut. The number of bytes in the placed in the buffer is returned. If there
+   is a failure, the returned value is <= 0. */
+/*     Return Value	Meaning */
+/*     0	no data returned */
+/*     > 0	the number of bytes in the digest or dOutSize, whichever is smaller */
+LIB_EXPORT UINT16
+CryptHashEnd(
+	     PHASH_STATE      hashState,     // IN: the state of hash stack
+	     UINT32           dOutSize,      // IN: size of digest buffer
+	     BYTE            *dOut           // OUT: hash digest
+	     )
+{
+    pAssert(hashState->type == HASH_STATE_HASH);
+    return HashEnd(hashState, dOutSize, dOut);
+}
+/* 10.2.13.6.5	CryptHashBlock() */
+/* Start a hash, hash a single block, update digest and return the size of the results. */
+/*     The digestSize parameter can be smaller than the digest. If so, only the more significant
+       bytes are returned. */
+/*     Return Value	Meaning */
+/*     >= 0	number of bytes placed in dOut */
+LIB_EXPORT UINT16
+CryptHashBlock(
+	       TPM_ALG_ID       hashAlg,       // IN: The hash algorithm
+	       UINT32           dataSize,      // IN: size of buffer to hash
+	       const BYTE      *data,          // IN: the buffer to hash
+	       UINT32           dOutSize,      // IN: size of the digest buffer
+	       BYTE            *dOut           // OUT: digest buffer
+	       )
+{
+    HASH_STATE          state;
+    CryptHashStart(&state, hashAlg);
+    CryptDigestUpdate(&state, dataSize, data);
+    return HashEnd(&state, dOutSize, dOut);
+}
+/* 10.2.13.6.6	CryptDigestUpdate2B() */
+/* This function updates a digest (hash or HMAC) with a TPM2B. */
+/* This function can be used for both HMAC and hash functions so the digestState is void so that
+   either state type can be passed. */
+LIB_EXPORT void
+CryptDigestUpdate2B(
+		    PHASH_STATE      state,         // IN: the digest state
+		    const TPM2B     *bIn            // IN: 2B containing the data
+		    )
+{
+    // Only compute the digest if a pointer to the 2B is provided.
+    // In CryptDigestUpdate(), if size is zero or buffer is NULL, then no change
+    // to the digest occurs. This function should not provide a buffer if bIn is
+    // not provided.
+    pAssert(bIn != NULL);
+    CryptDigestUpdate(state, bIn->size, bIn->buffer);
+    return;
+}
+/* 10.2.13.6.7	CryptHashEnd2B() */
+/* This function is the same as CryptCompleteHash() but the digest is placed in a TPM2B. This is the
+   most common use and this is provided for specification clarity. digest.size should be set to
+   indicate the number of bytes to place in the buffer */
+/* Return Value	Meaning */
+/* >=0	the number of bytes placed in digest.buffer */
+LIB_EXPORT UINT16
+CryptHashEnd2B(
+	       PHASH_STATE      state,         // IN: the hash state
+	       P2B              digest         // IN: the size of the buffer Out: requested
+	       //     number of bytes
+	       )
+{
+    return CryptHashEnd(state, digest->size, digest->buffer);
+}
+/* 10.2.13.6.8	CryptDigestUpdateInt() */
+/* This function is used to include an integer value to a hash stack. The function marshals the
+   integer into its canonical form before calling CryptDigestUpdate(). */
+LIB_EXPORT void
+CryptDigestUpdateInt(
+		     void            *state,         // IN: the state of hash stack
+		     UINT32           intSize,       // IN: the size of 'intValue' in bytes
+		     UINT64           intValue       // IN: integer value to be hashed
+		     )
+{
+#if LITTLE_ENDIAN_TPM
+    intValue = REVERSE_ENDIAN_64(intValue);
+#endif
+    CryptDigestUpdate(state, intSize, &((BYTE *)&intValue)[8 - intSize]);
+}
+/* 10.2.13.7	HMAC Functions */
+/* 10.2.13.7.1	CryptHmacStart() */
+/* This function is used to start an HMAC using a temp hash context. The function does the
+   initialization of the hash with the HMAC key XOR iPad and updates the HMAC key XOR oPad. */
+/* The function returns the number of bytes in a digest produced by hashAlg. */
+/* Return Value	Meaning */
+/* >= 0	number of bytes in digest produced by hashAlg (may be zero) */
+LIB_EXPORT UINT16
+CryptHmacStart(
+	       PHMAC_STATE      state,         // IN/OUT: the state buffer
+	       TPM_ALG_ID       hashAlg,       // IN: the algorithm to use
+	       UINT16           keySize,       // IN: the size of the HMAC key
+	       const BYTE      *key            // IN: the HMAC key
+	       )
+{
+    PHASH_DEF                hashDef;
+    BYTE *                   pb;
+    UINT32                   i;
+    //
+    hashDef = CryptGetHashDef(hashAlg);
+    if(hashDef->digestSize != 0)
+	{
+	    // If the HMAC key is larger than the hash block size, it has to be reduced
+	    // to fit. The reduction is a digest of the hashKey.
+	    if(keySize > hashDef->blockSize)
+		{
+		    // if the key is too big, reduce it to a digest of itself
+		    state->hmacKey.t.size = CryptHashBlock(hashAlg, keySize, key,
+							   hashDef->digestSize,
+							   state->hmacKey.t.buffer);
+		}
+	    else
+		{
+		    memcpy(state->hmacKey.t.buffer, key, keySize);
+		    state->hmacKey.t.size = keySize;
+		}
+	    // XOR the key with iPad (0x36)
+	    pb = state->hmacKey.t.buffer;
+	    for(i = state->hmacKey.t.size; i > 0; i--)
+		*pb++ ^= 0x36;
+	    
+	    // if the keySize is smaller than a block, fill the rest with 0x36
+	    for(i = hashDef->blockSize - state->hmacKey.t.size; i > 0; i--)
+		*pb++ = 0x36;
+	    
+	    // Increase the oPadSize to a full block
+	    state->hmacKey.t.size = hashDef->blockSize;
+	    
+	    // Start a new hash with the HMAC key
+	    // This will go in the caller's state structure and may be a sequence or not
+	    CryptHashStart((PHASH_STATE)state, hashAlg);
+	    CryptDigestUpdate((PHASH_STATE)state, state->hmacKey.t.size,
+			      state->hmacKey.t.buffer);
+	    // XOR the key block with 0x5c ^ 0x36
+	    for(pb = state->hmacKey.t.buffer, i = hashDef->blockSize; i > 0; i--)
+		*pb++ ^= (0x5c ^ 0x36);
+	}
+    // Set the hash algorithm
+    state->hashState.hashAlg = hashAlg;
+    // Set the hash state type
+    state->hashState.type = HASH_STATE_HMAC;
+    
+    return hashDef->digestSize;
+}
+/* 10.2.13.7.2	CryptHmacEnd() */
+/* This function is called to complete an HMAC. It will finish the current digest, and start a new digest. It will then add the oPadKey and the completed digest and return the results in dOut. It will not return more than dOutSize bytes. */
+/*     Return Value	Meaning */
+/*     >= 0	number of bytes in dOut (may be zero) */
+LIB_EXPORT UINT16
+CryptHmacEnd(
+	     PHMAC_STATE      state,         // IN: the hash state buffer
+	     UINT32           dOutSize,      // IN: size of digest buffer
+	     BYTE            *dOut           // OUT: hash digest
+	     )
+{
+    BYTE                 temp[MAX_DIGEST_SIZE];
+    PHASH_STATE          hState = (PHASH_STATE)&state->hashState;
+    
+#if SMAC_IMPLEMENTED
+    if(hState->type == HASH_STATE_SMAC)
+	return (state->hashState.state.smac.smacMethods.end)
+	    (&state->hashState.state.smac.state,
+	     dOutSize,
+	     dOut);
+#endif
+    pAssert(hState->type == HASH_STATE_HMAC);
+    hState->def = CryptGetHashDef(hState->hashAlg);
+    // Change the state type for completion processing
+    hState->type = HASH_STATE_HASH;
+    if(hState->hashAlg == TPM_ALG_NULL)
+	dOutSize = 0;
+    else
+	{
+	    
+	    // Complete the current hash
+	    HashEnd(hState, hState->def->digestSize, temp);
+	    // Do another hash starting with the oPad
+	    CryptHashStart(hState, hState->hashAlg);
+	    CryptDigestUpdate(hState, state->hmacKey.t.size, state->hmacKey.t.buffer);
+	    CryptDigestUpdate(hState, hState->def->digestSize, temp);
+	}
+    return HashEnd(hState, dOutSize, dOut);
+}
+/* 10.2.13.7.3	CryptHmacStart2B() */
+/* This function starts an HMAC and returns the size of the digest that will be produced. */
+/* This function is provided to support the most common use of starting an HMAC with a TPM2B key. */
+/* The caller must provide a block of memory in which the hash sequence state is kept. The caller
+   should not alter the contents of this buffer until the hash sequence is completed or
+   abandoned. */
+/* Return Value	Meaning */
+/* > 0	the digest size of the algorithm */
+/* = 0	the hashAlg was TPM_ALG_NULL */
+LIB_EXPORT UINT16
+CryptHmacStart2B(
+		 PHMAC_STATE      hmacState,     // OUT: the state of HMAC stack. It will be used
+		 //     in HMAC update and completion
+		 TPMI_ALG_HASH    hashAlg,       // IN: hash algorithm
+		 P2B              key            // IN: HMAC key
+		 )
+{
+    return CryptHmacStart(hmacState, hashAlg, key->size, key->buffer);
+}
+    /* 10.2.13.7.4	CryptHmacEnd2B() */
+    /* This function is the same as CryptHmacEnd() but the HMAC result is returned in a TPM2B which is the most common use. */
+    /* Return Value	Meaning */
+    /* >=0	the number of bytes placed in digest */
+LIB_EXPORT UINT16
+CryptHmacEnd2B(
+	       PHMAC_STATE      hmacState,     // IN: the state of HMAC stack
+	       P2B              digest         // OUT: HMAC
+	       )
+{
+    return CryptHmacEnd(hmacState, digest->size, digest->buffer);
+}
+/* 10.2.13.8	Mask and Key Generation Functions */
+/* 10.2.13.8.1	CryptMGF_KDF() */
+/* This function performs MGF1/KDF1 or KDF2 using the selected hash. KDF1 and KDF2 are T(n) = T(n-1)
+   || H(seed || counter) with the difference being that, with KDF1, counter starts at 0 but with
+   KDF2, counter starts at 1. The caller determines which version by setting the initial value of
+   counter to either 0 or 1. */
+/* 	Return Value	Meaning */
+/* 	0	hash algorithm was TPM_ALG_NULL */
+/* 	> 0	should be the same as mSize */
+LIB_EXPORT UINT16
+CryptMGF_KDF(
+	  UINT32           mSize,         // IN: length of the mask to be produced
+	  BYTE            *mask,          // OUT: buffer to receive the mask
+	  TPM_ALG_ID       hashAlg,       // IN: hash to use
+	  UINT32           seedSize,      // IN: size of the seed
+	  BYTE            *seed,          // IN: seed size
+	  UINT32           counter        // IN: counter initial value
+	  )
+{
+    HASH_STATE           hashState;
+    PHASH_DEF            hDef = CryptGetHashDef(hashAlg);
+    UINT32               hLen;
+    UINT32               bytes;
+    //
+    // If there is no digest to compute return
+    if((hDef->digestSize == 0) || (mSize == 0))
+	return 0;
+    if(counter != 0)
+	counter = 1;
+    hLen = hDef->digestSize;
+    for(bytes = 0; bytes < mSize; bytes += hLen)
+	{
+	    // Start the hash and include the seed and counter
+	    CryptHashStart(&hashState, hashAlg);
+	    CryptDigestUpdate(&hashState, seedSize, seed);
+	    CryptDigestUpdateInt(&hashState, 4, counter);
+	    // Get as much as will fit.
+	    CryptHashEnd(&hashState, MIN((mSize - bytes), hLen),
+			 &mask[bytes]);
+	    counter++;
+	}
+    return (UINT16)mSize;
+}
+/* 10.2.13.8.2	CryptKDFa() */
+/* This function performs the key generation according to Part 1 of the TPM specification. */
+/* This function returns the number of bytes generated which may be zero. */
+/* The key and keyStream pointers are not allowed to be NULL. The other pointer values may be
+   NULL. The value of sizeInBits must be no larger than (2^18)-1 = 256K bits (32385 bytes). */
+/*     The once parameter is set to allow incremental generation of a large value. If this flag is
+       TRUE, sizeInBits will be used in the HMAC computation but only one iteration of the KDF is
+       performed. This would be used for XOR obfuscation so that the mask value can be generated in
+       digest-sized chunks rather than having to be generated all at once in an arbitrarily large
+       buffer and then XORed into the result. If once is TRUE, then sizeInBits must be a multiple of
+       8. */
+/*     Any error in the processing of this command is considered fatal. */
+/*     Return Value	Meaning */
+/*     0	hash algorithm is not supported or is TPM_ALG_NULL */
+/*     > 0	the number of bytes in the keyStream buffer */
+LIB_EXPORT UINT16
+CryptKDFa(
+	  TPM_ALG_ID       hashAlg,       // IN: hash algorithm used in HMAC
+	  const TPM2B     *key,           // IN: HMAC key
+	  const TPM2B     *label,         // IN: a label for the KDF
+	  const TPM2B     *contextU,      // IN: context U
+	  const TPM2B     *contextV,      // IN: context V
+	  UINT32           sizeInBits,    // IN: size of generated key in bits
+	  BYTE            *keyStream,     // OUT: key buffer
+	  UINT32          *counterInOut,  // IN/OUT: caller may provide the iteration
+	  //     counter for incremental operations to
+	  //     avoid large intermediate buffers.
+	  UINT16           blocks         // IN: If non-zero, this is the maximum number
+	  //     of blocks to be returned, regardless
+	  //     of sizeInBits
+	  )
+{
+    UINT32                   counter = 0;       // counter value
+    INT16                    bytes;             // number of bytes to produce
+    UINT16                   generated;         // number of bytes generated
+    BYTE                    *stream = keyStream;
+    HMAC_STATE               hState;
+    UINT16                   digestSize = CryptHashGetDigestSize(hashAlg);
+    
+    pAssert(key != NULL && keyStream != NULL);
+    
+    TEST(TPM_ALG_KDF1_SP800_108);
+    
+    if(digestSize == 0)
+	return 0;
+    
+    if(counterInOut != NULL)
+	counter = *counterInOut;
+    
+    // If the size of the request is larger than the numbers will handle,
+    // it is a fatal error.
+    pAssert(((sizeInBits + 7) / 8) <= INT16_MAX);
+    
+    // The number of bytes to be generated is the smaller of the sizeInBits bytes or
+    // the number of requested blocks. The number of blocks is the smaller of the
+    // number requested or the number allowed by sizeInBits. A partial block is
+    // a full block.
+    bytes = (blocks > 0) ? blocks * digestSize : (UINT16)BITS_TO_BYTES(sizeInBits);
+    generated = bytes;
+    
+    // Generate required bytes
+    for(; bytes > 0; bytes -= digestSize)
+	{
+	    counter++;
+	    // Start HMAC
+	    if(CryptHmacStart(&hState, hashAlg, key->size, key->buffer) == 0)
+		return 0;
+	    // Adding counter
+	    CryptDigestUpdateInt(&hState.hashState, 4, counter);
+	    
+	    // Adding label
+	    if(label != NULL)
+		HASH_DATA(&hState.hashState, label->size, (BYTE *)label->buffer);
+	    // Add a null. SP108 is not very clear about when the 0 is needed but to
+	    // make this like the previous version that did not add an 0x00 after
+	    // a null-terminated string, this version will only add a null byte
+	    // if the label parameter did not end in a null byte, or if no label
+	    // is present.
+	    if((label == NULL)
+	       || (label->size == 0)
+	       || (label->buffer[label->size - 1] != 0))
+		CryptDigestUpdateInt(&hState.hashState, 1, 0);
+	    // Adding contextU
+	    if(contextU != NULL)
+		HASH_DATA(&hState.hashState, contextU->size, contextU->buffer);
+	    // Adding contextV
+	    if(contextV != NULL)
+		HASH_DATA(&hState.hashState, contextV->size, contextV->buffer);
+	    // Adding size in bits
+	    CryptDigestUpdateInt(&hState.hashState, 4, sizeInBits);
+	    
+	    // Complete and put the data in the buffer
+	    CryptHmacEnd(&hState, bytes, stream);
+	    stream = &stream[digestSize];
+	}
+    // Masking in the KDF is disabled. If the calling function wants something
+    // less than even number of bytes, then the caller should do the masking
+    // because there is no universal way to do it here
+    if(counterInOut != NULL)
+	*counterInOut = counter;
+    return generated;
+}
+/* 10.2.13.8.3	CryptKDFe() */
+/* This function implements KDFe() as defined in TPM specification part 1. */
+/* This function returns the number of bytes generated which may be zero. */
+/* The Z and keyStream pointers are not allowed to be NULL. The other pointer values may be
+   NULL. The value of sizeInBits must be no larger than (2^18)-1 = 256K bits (32385 bytes). Any
+   error in the processing of this command is considered fatal. */
+/*     Return Value	Meaning */
+/*     0	hash algorithm is not supported or is TPM_ALG_NULL */
+/*     > 0	the number of bytes in the keyStream buffer */
+LIB_EXPORT UINT16
+CryptKDFe(
+	  TPM_ALG_ID       hashAlg,       // IN: hash algorithm used in HMAC
+	  TPM2B           *Z,             // IN: Z
+	  const TPM2B     *label,         // IN: a label value for the KDF
+	  TPM2B           *partyUInfo,    // IN: PartyUInfo
+	  TPM2B           *partyVInfo,    // IN: PartyVInfo
+	  UINT32           sizeInBits,    // IN: size of generated key in bits
+	  BYTE            *keyStream      // OUT: key buffer
+	  )
+{
+    HASH_STATE       hashState;
+    PHASH_DEF        hashDef = CryptGetHashDef(hashAlg);
+    
+    UINT32           counter = 0;       // counter value
+    UINT16           hLen;
+    BYTE            *stream = keyStream;
+    INT16            bytes;             // number of bytes to generate
+    
+    pAssert(keyStream != NULL && Z != NULL && ((sizeInBits + 7) / 8) < INT16_MAX);
+    //
+    hLen = hashDef->digestSize;
+    bytes = (INT16)((sizeInBits + 7) / 8);
+    if(hashAlg == TPM_ALG_NULL || bytes == 0)
+	return 0;
+    
+    // Generate required bytes
+    //The inner loop of that KDF uses:
+    //  Hash[i] := H(counter | Z | OtherInfo) (5)
+    // Where:
+    //  Hash[i]         the hash generated on the i-th iteration of the loop.
+    //  H()             an approved hash function
+    //  counter         a 32-bit counter that is initialized to 1 and incremented
+    //                  on each iteration
+    //  Z               the X coordinate of the product of a public ECC key and a
+    //                  different private ECC key.
+    //  OtherInfo       a collection of qualifying data for the KDF defined below.
+    //  In this specification, OtherInfo will be constructed by:
+    //      OtherInfo := Use | PartyUInfo  | PartyVInfo
+    for(; bytes > 0; stream = &stream[hLen], bytes = bytes - hLen)
+	{
+	    if(bytes < hLen)
+		hLen = bytes;
+	    counter++;
+	    // Do the hash
+	    CryptHashStart(&hashState, hashAlg);
+	    // Add counter
+	    CryptDigestUpdateInt(&hashState, 4, counter);
+	    
+	    // Add Z
+	    if(Z != NULL)
+		CryptDigestUpdate2B(&hashState, Z);
+	    // Add label
+	    if(label != NULL)
+		CryptDigestUpdate2B(&hashState, label);
+	    // Add a null. SP108 is not very clear about when the 0 is needed but to
+	    // make this like the previous version that did not add an 0x00 after
+	    // a null-terminated string, this version will only add a null byte
+	    // if the label parameter did not end in a null byte, or if no label
+	    // is present.
+	    if((label == NULL)
+	       || (label->size == 0)
+	       || (label->buffer[label->size - 1] != 0))
+		CryptDigestUpdateInt(&hashState, 1, 0);
+	    // Add PartyUInfo
+	    if(partyUInfo != NULL)
+		CryptDigestUpdate2B(&hashState, partyUInfo);
+	    
+	    // Add PartyVInfo
+	    if(partyVInfo != NULL)
+		CryptDigestUpdate2B(&hashState, partyVInfo);
+	    
+	    // Compute Hash. hLen was changed to be the smaller of bytes or hLen
+	    // at the start of each iteration.
+	    CryptHashEnd(&hashState, hLen, stream);
+	}
+    
+    // Mask off bits if the required bits is not a multiple of byte size
+    if((sizeInBits % 8) != 0)
+	keyStream[0] &= ((1 << (sizeInBits % 8)) - 1);
+    
+    return (UINT16)((sizeInBits + 7) / 8);
+}

+ 343 - 0
EVSE/GPL/ibmtpm1682/src/CryptHash.h

@@ -0,0 +1,343 @@
+/********************************************************************************/
+/*										*/
+/*			    Hash structure definitions  			*/
+/*			     Written by Ken Goldman				*/
+/*		       IBM Thomas J. Watson Research Center			*/
+/*            $Id: CryptHash.h 1658 2021-01-22 23:14:01Z kgoldman $		*/
+/*										*/
+/*  Licenses and Notices							*/
+/*										*/
+/*  1. Copyright Licenses:							*/
+/*										*/
+/*  - Trusted Computing Group (TCG) grants to the user of the source code in	*/
+/*    this specification (the "Source Code") a worldwide, irrevocable, 		*/
+/*    nonexclusive, royalty free, copyright license to reproduce, create 	*/
+/*    derivative works, distribute, display and perform the Source Code and	*/
+/*    derivative works thereof, and to grant others the rights granted herein.	*/
+/*										*/
+/*  - The TCG grants to the user of the other parts of the specification 	*/
+/*    (other than the Source Code) the rights to reproduce, distribute, 	*/
+/*    display, and perform the specification solely for the purpose of 		*/
+/*    developing products based on such documents.				*/
+/*										*/
+/*  2. Source Code Distribution Conditions:					*/
+/*										*/
+/*  - Redistributions of Source Code must retain the above copyright licenses, 	*/
+/*    this list of conditions and the following disclaimers.			*/
+/*										*/
+/*  - Redistributions in binary form must reproduce the above copyright 	*/
+/*    licenses, this list of conditions	and the following disclaimers in the 	*/
+/*    documentation and/or other materials provided with the distribution.	*/
+/*										*/
+/*  3. Disclaimers:								*/
+/*										*/
+/*  - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF	*/
+/*  LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH	*/
+/*  RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES)	*/
+/*  THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE.		*/
+/*  Contact TCG Administration (admin@trustedcomputinggroup.org) for 		*/
+/*  information on specification licensing rights available through TCG 	*/
+/*  membership agreements.							*/
+/*										*/
+/*  - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED 	*/
+/*    WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR 	*/
+/*    FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR 		*/
+/*    NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY 		*/
+/*    OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE.		*/
+/*										*/
+/*  - Without limitation, TCG and its members and licensors disclaim all 	*/
+/*    liability, including liability for infringement of any proprietary 	*/
+/*    rights, relating to use of information in this specification and to the	*/
+/*    implementation of this specification, and TCG disclaims all liability for	*/
+/*    cost of procurement of substitute goods or services, lost profits, loss 	*/
+/*    of use, loss of data or any incidental, consequential, direct, indirect, 	*/
+/*    or special damages, whether under contract, tort, warranty or otherwise, 	*/
+/*    arising in any way out of use or reliance upon this specification or any 	*/
+/*    information herein.							*/
+/*										*/
+/*  (c) Copyright IBM Corp. and others, 2016 - 2021				*/
+/*										*/
+/********************************************************************************/
+
+#ifndef CRYPTHASH_H
+#define CRYPTHASH_H
+
+/* 10.1.3.1	Introduction */
+
+/* This header contains the hash structure definitions used in the TPM code to define the amount of
+   space to be reserved for the hash state. This allows the TPM code to not have to import all of
+   the symbols used by the hash computations. This lets the build environment of the TPM code not to
+   have include the header files associated with the CryptoEngine() code. */
+
+/* 10.1.3.2	Hash-related Structures */
+
+union SMAC_STATES;
+
+/* These definitions add the high-level methods for processing state that may be an SMAC */
+typedef void(* SMAC_DATA_METHOD)(
+				 union SMAC_STATES       *state,
+				 UINT32                   size,
+				 const BYTE              *buffer
+				 );
+typedef UINT16(* SMAC_END_METHOD)(
+				  union SMAC_STATES       *state,
+				  UINT32                   size,
+				  BYTE                    *buffer
+				  );
+typedef struct sequenceMethods {
+    SMAC_DATA_METHOD          data;
+    SMAC_END_METHOD           end;
+} SMAC_METHODS;
+#define SMAC_IMPLEMENTED (CC_MAC || CC_MAC_Start)
+
+/* These definitions are here because the SMAC state is in the union of hash states. */
+
+typedef struct tpmCmacState {
+    TPM_ALG_ID              symAlg;
+    UINT16                  keySizeBits;
+    INT16                   bcount; // current count of bytes accumulated in IV
+    TPM2B_IV                iv;     // IV buffer
+    TPM2B_SYM_KEY           symKey;
+} tpmCmacState_t;
+
+typedef union SMAC_STATES {
+#if ALG_CMAC
+    tpmCmacState_t          cmac;
+#endif
+    UINT64                  pad;
+} SMAC_STATES;
+
+typedef struct SMAC_STATE {
+    SMAC_METHODS            smacMethods;
+    SMAC_STATES             state;
+} SMAC_STATE;
+
+#if ALG_SHA1
+#   define  IF_IMPLEMENTED_SHA1(op)     op(SHA1, Sha1)
+#else
+#   define  IF_IMPLEMENTED_SHA1(op)
+#endif
+#if ALG_SHA256
+#   define  IF_IMPLEMENTED_SHA256(op)     op(SHA256, Sha256)
+#else
+#   define  IF_IMPLEMENTED_SHA256(op)
+#endif
+#if ALG_SHA384
+#   define  IF_IMPLEMENTED_SHA384(op)     op(SHA384, Sha384)
+#else
+#   define  IF_IMPLEMENTED_SHA384(op)
+#endif
+#if ALG_SHA512
+#   define  IF_IMPLEMENTED_SHA512(op)     op(SHA512, Sha512)
+#else
+#   define  IF_IMPLEMENTED_SHA512(op)
+#endif
+#if ALG_SM3_256
+#   define  IF_IMPLEMENTED_SM3_256(op)     op(SM3_256, Sm3_256)
+#else
+#   define  IF_IMPLEMENTED_SM3_256(op)
+#endif
+#if ALG_SHA3_256
+#   define  IF_IMPLEMENTED_SHA3_256(op)     op(SHA3_256, Sha3_256)
+#else
+#   define  IF_IMPLEMENTED_SHA3_256(op)
+#endif
+#if ALG_SHA3_384
+#   define  IF_IMPLEMENTED_SHA3_384(op)     op(SHA3_384, Sha3_384)
+#else
+#   define  IF_IMPLEMENTED_SHA3_384(op)
+#endif
+#if ALG_SHA3_512
+#   define  IF_IMPLEMENTED_SHA3_512(op)     op(SHA3_512, Sha3_512)
+#else
+#   define  IF_IMPLEMENTED_SHA3_512(op)
+#endif
+
+/* SHA512 added kgold */
+#define FOR_EACH_HASH(op)		    \
+    IF_IMPLEMENTED_SHA1(op)		    \
+    IF_IMPLEMENTED_SHA256(op)		    \
+    IF_IMPLEMENTED_SHA384(op)		    \
+    IF_IMPLEMENTED_SHA512(op)		    \
+    IF_IMPLEMENTED_SM3_256(op)		    \
+    IF_IMPLEMENTED_SHA3_256(op)		    \
+    IF_IMPLEMENTED_SHA3_384(op)		    \
+    IF_IMPLEMENTED_SHA3_512(op)
+
+#define HASH_TYPE(HASH, Hash)   tpmHashState##HASH##_t  Hash;
+
+typedef union
+{
+    FOR_EACH_HASH(HASH_TYPE)
+    // Additions for symmetric block cipher MAC
+#if SMAC_IMPLEMENTED
+    SMAC_STATE                 smac;
+#endif
+    // to force structure alignment to be no worse than HASH_ALIGNMENT
+#if HASH_ALIGNMENT == 8
+    uint64_t             align;
+#else
+    uint32_t             align;
+#endif
+} ANY_HASH_STATE;
+
+typedef ANY_HASH_STATE *PANY_HASH_STATE;
+typedef const ANY_HASH_STATE    *PCANY_HASH_STATE;
+#define ALIGNED_SIZE(x, b) ((((x) + (b) - 1) / (b)) * (b))
+/* MAX_HASH_STATE_SIZE will change with each implementation. It is assumed that a hash state will
+   not be larger than twice the block size plus some overhead (in this case, 16 bytes). The overall
+   size needs to be as large as any of the hash contexts. The structure needs to start on an
+   alignment boundary and be an even multiple of the alignment */
+#define MAX_HASH_STATE_SIZE ((2 * MAX_HASH_BLOCK_SIZE) + 16)
+#define MAX_HASH_STATE_SIZE_ALIGNED					\
+    ALIGNED_SIZE(MAX_HASH_STATE_SIZE, HASH_ALIGNMENT)
+/* This is an aligned byte array that will hold any of the hash contexts. */
+typedef  ANY_HASH_STATE ALIGNED_HASH_STATE;
+/* The header associated with the hash library is expected to define the methods which include the
+   calling sequence. When not compiling CryptHash.c, the methods are not defined so we need
+   placeholder functions for the structures */
+#ifndef HASH_START_METHOD_DEF
+#   define HASH_START_METHOD_DEF    void (HASH_START_METHOD)(void)
+#endif
+#ifndef HASH_DATA_METHOD_DEF
+#   define HASH_DATA_METHOD_DEF     void (HASH_DATA_METHOD)(void)
+#endif
+#ifndef HASH_END_METHOD_DEF
+#   define HASH_END_METHOD_DEF      void (HASH_END_METHOD)(void)
+#endif
+#ifndef HASH_STATE_COPY_METHOD_DEF
+#   define HASH_STATE_COPY_METHOD_DEF     void (HASH_STATE_COPY_METHOD)(void)
+#endif
+#ifndef  HASH_STATE_EXPORT_METHOD_DEF
+#   define  HASH_STATE_EXPORT_METHOD_DEF   void (HASH_STATE_EXPORT_METHOD)(void)
+#endif
+#ifndef  HASH_STATE_IMPORT_METHOD_DEF
+#   define  HASH_STATE_IMPORT_METHOD_DEF   void (HASH_STATE_IMPORT_METHOD)(void)
+#endif
+/* Define the prototypical function call for each of the methods. This defines the order in which
+   the parameters are passed to the underlying function. */
+typedef HASH_START_METHOD_DEF;
+typedef HASH_DATA_METHOD_DEF;
+typedef HASH_END_METHOD_DEF;
+typedef HASH_STATE_COPY_METHOD_DEF;
+typedef HASH_STATE_EXPORT_METHOD_DEF;
+typedef HASH_STATE_IMPORT_METHOD_DEF;
+typedef struct _HASH_METHODS
+{
+    HASH_START_METHOD           *start;
+    HASH_DATA_METHOD            *data;
+    HASH_END_METHOD             *end;
+    HASH_STATE_COPY_METHOD      *copy;      // Copy a hash block
+    HASH_STATE_EXPORT_METHOD    *copyOut;   // Copy a hash block from a hash
+    // context
+    HASH_STATE_IMPORT_METHOD    *copyIn;    // Copy a hash block to a proper hash
+    // context
+} HASH_METHODS, *PHASH_METHODS;
+
+#define HASH_TPM2B(HASH, Hash)  TPM2B_TYPE(HASH##_DIGEST, HASH##_DIGEST_SIZE);
+
+FOR_EACH_HASH(HASH_TPM2B)
+
+/* When the TPM implements RSA, the hash-dependent OID pointers are part of the HASH_DEF. These
+   macros conditionally add the OID reference to the HASH_DEF and the HASH_DEF_TEMPLATE. */
+#if ALG_RSA
+#define PKCS1_HASH_REF   const BYTE  *PKCS1;
+#define PKCS1_OID(NAME)  , OID_PKCS1_##NAME
+#else
+#define PKCS1_HASH_REF
+#define PKCS1_OID(NAME)
+#endif
+
+/* When the TPM implements ECC, the hash-dependent OID pointers are part of the HASH_DEF. These
+   macros conditionally add the OID reference to the HASH_DEF and the HASH_DEF_TEMPLATE. */
+#if ALG_ECDSA
+#define ECDSA_HASH_REF    const BYTE  *ECDSA;
+#define ECDSA_OID(NAME)  , OID_ECDSA_##NAME
+#else
+#define ECDSA_HASH_REF
+#define ECDSA_OID(NAME)
+#endif
+
+typedef const struct
+{
+    HASH_METHODS         method;
+    uint16_t             blockSize;
+    uint16_t             digestSize;
+    uint16_t             contextSize;
+    uint16_t             hashAlg;
+    const BYTE          *OID;
+    PKCS1_HASH_REF      // PKCS1 OID
+    ECDSA_HASH_REF      // ECDSA OID
+} HASH_DEF, *PHASH_DEF;
+
+/* Macro to fill in the HASH_DEF for an algorithm. For SHA1, the instance would be:
+   HASH_DEF_TEMPLATE(Sha1, SHA1) This handles the difference in capitalization for the various
+   pieces. */
+
+#define HASH_DEF_TEMPLATE(HASH, Hash)					\
+    HASH_DEF    Hash##_Def= {						\
+			     {(HASH_START_METHOD *)&tpmHashStart_##HASH, \
+			      (HASH_DATA_METHOD *)&tpmHashData_##HASH,	\
+			      (HASH_END_METHOD *)&tpmHashEnd_##HASH,	\
+			      (HASH_STATE_COPY_METHOD *)&tpmHashStateCopy_##HASH, \
+			      (HASH_STATE_EXPORT_METHOD *)&tpmHashStateExport_##HASH, \
+			      (HASH_STATE_IMPORT_METHOD *)&tpmHashStateImport_##HASH, \
+			     },						\
+			     HASH##_BLOCK_SIZE,     /*block size */	\
+			     HASH##_DIGEST_SIZE,    /*data size */	\
+			     sizeof(tpmHashState##HASH##_t),		\
+			     TPM_ALG_##HASH, OID_##HASH			\
+			     PKCS1_OID(HASH) ECDSA_OID(HASH)};
+
+/* These definitions are for the types that can be in a hash state structure. These types are used
+   in the cryptographic utilities. This is a define rather than an enum so that the size of this
+   field can be explicit. */
+typedef BYTE    HASH_STATE_TYPE;
+#define HASH_STATE_EMPTY        ((HASH_STATE_TYPE) 0)
+#define HASH_STATE_HASH         ((HASH_STATE_TYPE) 1)
+#define HASH_STATE_HMAC         ((HASH_STATE_TYPE) 2)
+#if CC_MAC || CC_MAC_Start
+#define HASH_STATE_SMAC         ((HASH_STATE_TYPE) 3)
+#endif
+/* This is the structure that is used for passing a context into the hashing functions. It should be
+   the same size as the function context used within the hashing functions. This is checked when the
+   hash function is initialized. This version uses a new layout for the contexts and a different
+   definition. The state buffer is an array of HASH_UNIT values so that a decent compiler will put
+   the structure on a HASH_UNIT boundary. If the structure is not properly aligned, the code that
+   manipulates the structure will copy to a properly aligned structure before it is used and copy
+   the result back. This just makes things slower. */
+/*     NOTE: This version of the state had the pointer to the update method in the state. This is to
+       allow the SMAC functions to use the same structure without having to replicate the entire
+       HASH_DEF structure. */
+typedef struct _HASH_STATE
+{
+    HASH_STATE_TYPE          type;               // type of the context
+    TPM_ALG_ID               hashAlg;
+    PHASH_DEF                def;
+    ANY_HASH_STATE           state;
+} HASH_STATE, *PHASH_STATE;
+typedef const HASH_STATE *PCHASH_STATE;
+
+/* 10.1.3.3 HMAC State Structures */
+/* This header contains the hash structure definitions used in the TPM code to define the amount of
+   space to be reserved for the hash state. This allows the TPM code to not have to import all of
+   the symbols used by the hash computations. This lets the build environment of the TPM code not to
+   have include the header files associated with the CryptoEngine() code. */
+
+/* An HMAC_STATE structure contains an opaque HMAC stack state. A caller would use this structure
+   when performing incremental HMAC operations. This structure contains a hash state and an HMAC key
+   and allows slightly better stack optimization than adding an HMAC key to each hash state. */
+typedef struct hmacState
+{
+    HASH_STATE           hashState;          // the hash state
+    TPM2B_HASH_BLOCK     hmacKey;            // the HMAC key
+} HMAC_STATE, *PHMAC_STATE;
+/* This is for the external hash state. This implementation assumes that the size of the exported
+   hash state is no larger than the internal hash state. */
+typedef struct
+{
+    BYTE                     buffer[sizeof(HASH_STATE)];
+} EXPORT_HASH_STATE, *PEXPORT_HASH_STATE;
+typedef const EXPORT_HASH_STATE *PCEXPORT_HASH_STATE;
+
+#endif	//  _CRYPT_HASH_H

+ 219 - 0
EVSE/GPL/ibmtpm1682/src/CryptHash_fp.h

@@ -0,0 +1,219 @@
+/********************************************************************************/
+/*										*/
+/*		Implementation of cryptographic functions for hashing.		*/
+/*			     Written by Ken Goldman				*/
+/*		       IBM Thomas J. Watson Research Center			*/
+/*            $Id: CryptHash_fp.h 1594 2020-03-26 22:15:48Z kgoldman $		*/
+/*										*/
+/*  Licenses and Notices							*/
+/*										*/
+/*  1. Copyright Licenses:							*/
+/*										*/
+/*  - Trusted Computing Group (TCG) grants to the user of the source code in	*/
+/*    this specification (the "Source Code") a worldwide, irrevocable, 		*/
+/*    nonexclusive, royalty free, copyright license to reproduce, create 	*/
+/*    derivative works, distribute, display and perform the Source Code and	*/
+/*    derivative works thereof, and to grant others the rights granted herein.	*/
+/*										*/
+/*  - The TCG grants to the user of the other parts of the specification 	*/
+/*    (other than the Source Code) the rights to reproduce, distribute, 	*/
+/*    display, and perform the specification solely for the purpose of 		*/
+/*    developing products based on such documents.				*/
+/*										*/
+/*  2. Source Code Distribution Conditions:					*/
+/*										*/
+/*  - Redistributions of Source Code must retain the above copyright licenses, 	*/
+/*    this list of conditions and the following disclaimers.			*/
+/*										*/
+/*  - Redistributions in binary form must reproduce the above copyright 	*/
+/*    licenses, this list of conditions	and the following disclaimers in the 	*/
+/*    documentation and/or other materials provided with the distribution.	*/
+/*										*/
+/*  3. Disclaimers:								*/
+/*										*/
+/*  - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF	*/
+/*  LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH	*/
+/*  RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES)	*/
+/*  THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE.		*/
+/*  Contact TCG Administration (admin@trustedcomputinggroup.org) for 		*/
+/*  information on specification licensing rights available through TCG 	*/
+/*  membership agreements.							*/
+/*										*/
+/*  - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED 	*/
+/*    WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR 	*/
+/*    FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR 		*/
+/*    NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY 		*/
+/*    OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE.		*/
+/*										*/
+/*  - Without limitation, TCG and its members and licensors disclaim all 	*/
+/*    liability, including liability for infringement of any proprietary 	*/
+/*    rights, relating to use of information in this specification and to the	*/
+/*    implementation of this specification, and TCG disclaims all liability for	*/
+/*    cost of procurement of substitute goods or services, lost profits, loss 	*/
+/*    of use, loss of data or any incidental, consequential, direct, indirect, 	*/
+/*    or special damages, whether under contract, tort, warranty or otherwise, 	*/
+/*    arising in any way out of use or reliance upon this specification or any 	*/
+/*    information herein.							*/
+/*										*/
+/*  (c) Copyright IBM Corp. and others, 2016 - 2020				*/
+/*										*/
+/********************************************************************************/
+
+#ifndef CRYPTHASH_FP_H
+#define CRYPTHASH_FP_H
+
+BOOL
+CryptHashInit(
+	      void
+	      );
+BOOL
+CryptHashStartup(
+		 void
+		 );
+PHASH_DEF
+CryptGetHashDef(
+		TPM_ALG_ID       hashAlg
+		);
+BOOL
+CryptHashIsValidAlg(
+		    TPM_ALG_ID       hashAlg,
+		    BOOL             flag
+		    );
+LIB_EXPORT TPM_ALG_ID
+CryptHashGetAlgByIndex(
+		       UINT32           index          // IN: the index
+		       );
+LIB_EXPORT UINT16
+CryptHashGetDigestSize(
+		       TPM_ALG_ID       hashAlg        // IN: hash algorithm to look up
+		       );
+LIB_EXPORT UINT16
+CryptHashGetBlockSize(
+		      TPM_ALG_ID       hashAlg        // IN: hash algorithm to look up
+		      );
+LIB_EXPORT const BYTE *
+CryptHashGetOid(
+		TPM_ALG_ID      hashAlg
+		);
+TPM_ALG_ID
+CryptHashGetContextAlg(
+		       PHASH_STATE      state          // IN: the context to check
+		       );
+LIB_EXPORT void
+CryptHashCopyState(
+		   HASH_STATE          *out,           // OUT: destination of the state
+		   const HASH_STATE    *in             // IN: source of the state
+		   );
+void
+CryptHashExportState(
+		     PCHASH_STATE         internalFmt,   // IN: the hash state formatted for use by
+		     //     library
+		     PEXPORT_HASH_STATE   externalFmt    // OUT: the exported hash state
+		     );
+void
+CryptHashImportState(
+		     PHASH_STATE          internalFmt,   // OUT: the hash state formatted for use by
+		     //     the library
+		     PCEXPORT_HASH_STATE  externalFmt    // IN: the exported hash state
+		     );
+LIB_EXPORT UINT16
+CryptHashStart(
+	       PHASH_STATE      hashState,     // OUT: the running hash state
+	       TPM_ALG_ID       hashAlg        // IN: hash algorithm
+	       );
+LIB_EXPORT void
+CryptDigestUpdate(
+		  PHASH_STATE      hashState,     // IN: the hash context information
+		  UINT32           dataSize,      // IN: the size of data to be added
+		  const BYTE      *data           // IN: data to be hashed
+		  );
+LIB_EXPORT UINT16
+CryptHashEnd(
+	     PHASH_STATE      hashState,     // IN: the state of hash stack
+	     UINT32           dOutSize,      // IN: size of digest buffer
+	     BYTE            *dOut           // OUT: hash digest
+	     );
+LIB_EXPORT UINT16
+CryptHashBlock(
+	       TPM_ALG_ID       hashAlg,       // IN: The hash algorithm
+	       UINT32           dataSize,      // IN: size of buffer to hash
+	       const BYTE      *data,          // IN: the buffer to hash
+	       UINT32           dOutSize,      // IN: size of the digest buffer
+	       BYTE            *dOut           // OUT: digest buffer
+	       );
+LIB_EXPORT void
+CryptDigestUpdate2B(
+		    PHASH_STATE      state,         // IN: the digest state
+		    const TPM2B     *bIn            // IN: 2B containing the data
+		    );
+LIB_EXPORT UINT16
+CryptHashEnd2B(
+	       PHASH_STATE      state,         // IN: the hash state
+	       P2B              digest         // IN: the size of the buffer Out: requested
+	       //     number of bytes
+	       );
+LIB_EXPORT void
+CryptDigestUpdateInt(
+		     void            *state,         // IN: the state of hash stack
+		     UINT32           intSize,       // IN: the size of 'intValue' in bytes
+		     UINT64           intValue       // IN: integer value to be hashed
+		     );
+LIB_EXPORT UINT16
+CryptHmacStart(
+	       PHMAC_STATE      state,         // IN/OUT: the state buffer
+	       TPM_ALG_ID       hashAlg,       // IN: the algorithm to use
+	       UINT16           keySize,       // IN: the size of the HMAC key
+	       const BYTE      *key            // IN: the HMAC key
+	       );
+LIB_EXPORT UINT16
+CryptHmacEnd(
+	     PHMAC_STATE      state,         // IN: the hash state buffer
+	     UINT32           dOutSize,      // IN: size of digest buffer
+	     BYTE            *dOut           // OUT: hash digest
+	     );
+LIB_EXPORT UINT16
+CryptHmacStart2B(
+		 PHMAC_STATE      hmacState,     // OUT: the state of HMAC stack. It will be used
+		 //     in HMAC update and completion
+		 TPMI_ALG_HASH    hashAlg,       // IN: hash algorithm
+		 P2B              key            // IN: HMAC key
+		 );
+LIB_EXPORT UINT16
+CryptHmacEnd2B(
+	       PHMAC_STATE      hmacState,     // IN: the state of HMAC stack
+	       P2B              digest         // OUT: HMAC
+	       );
+LIB_EXPORT UINT16
+CryptMGF_KDF(
+	  UINT32           mSize,         // IN: length of the mask to be produced
+	  BYTE            *mask,          // OUT: buffer to receive the mask
+	  TPM_ALG_ID       hashAlg,       // IN: hash to use
+	  UINT32           seedSize,      // IN: size of the seed
+	  BYTE            *seed,          // IN: seed size
+	  UINT32           counter        // IN: counter initial value
+	  );
+LIB_EXPORT UINT16
+CryptKDFa(
+	  TPM_ALG_ID       hashAlg,       // IN: hash algorithm used in HMAC
+	  const TPM2B     *key,           // IN: HMAC key
+	  const TPM2B     *label,         // IN: a label for the KDF
+	  const TPM2B     *contextU,      // IN: context U
+	  const TPM2B     *contextV,      // IN: context V
+	  UINT32           sizeInBits,    // IN: size of generated key in bits
+	  BYTE            *keyStream,     // OUT: key buffer
+	  UINT32          *counterInOut,  // IN/OUT: caller may provide the iteration
+	  UINT16           blocks         // IN: If non-zero, this is the maximum number
+	  );
+LIB_EXPORT UINT16
+CryptKDFe(
+	  TPM_ALG_ID       hashAlg,       // IN: hash algorithm used in HMAC
+	  TPM2B           *Z,             // IN: Z
+	  const TPM2B     *label,         // IN: a label value for the KDF
+	  TPM2B           *partyUInfo,    // IN: PartyUInfo
+	  TPM2B           *partyVInfo,    // IN: PartyVInfo
+	  UINT32           sizeInBits,    // IN: size of generated key in bits
+	  BYTE            *keyStream      // OUT: key buffer
+	  );
+
+
+#endif

+ 386 - 0
EVSE/GPL/ibmtpm1682/src/CryptPrime.c

@@ -0,0 +1,386 @@
+/********************************************************************************/
+/*										*/
+/*			    Code for prime validation. 				*/
+/*			     Written by Ken Goldman				*/
+/*		       IBM Thomas J. Watson Research Center			*/
+/*            $Id: CryptPrime.c 1529 2019-11-21 23:29:01Z kgoldman $		*/
+/*										*/
+/*  Licenses and Notices							*/
+/*										*/
+/*  1. Copyright Licenses:							*/
+/*										*/
+/*  - Trusted Computing Group (TCG) grants to the user of the source code in	*/
+/*    this specification (the "Source Code") a worldwide, irrevocable, 		*/
+/*    nonexclusive, royalty free, copyright license to reproduce, create 	*/
+/*    derivative works, distribute, display and perform the Source Code and	*/
+/*    derivative works thereof, and to grant others the rights granted herein.	*/
+/*										*/
+/*  - The TCG grants to the user of the other parts of the specification 	*/
+/*    (other than the Source Code) the rights to reproduce, distribute, 	*/
+/*    display, and perform the specification solely for the purpose of 		*/
+/*    developing products based on such documents.				*/
+/*										*/
+/*  2. Source Code Distribution Conditions:					*/
+/*										*/
+/*  - Redistributions of Source Code must retain the above copyright licenses, 	*/
+/*    this list of conditions and the following disclaimers.			*/
+/*										*/
+/*  - Redistributions in binary form must reproduce the above copyright 	*/
+/*    licenses, this list of conditions	and the following disclaimers in the 	*/
+/*    documentation and/or other materials provided with the distribution.	*/
+/*										*/
+/*  3. Disclaimers:								*/
+/*										*/
+/*  - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF	*/
+/*  LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH	*/
+/*  RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES)	*/
+/*  THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE.		*/
+/*  Contact TCG Administration (admin@trustedcomputinggroup.org) for 		*/
+/*  information on specification licensing rights available through TCG 	*/
+/*  membership agreements.							*/
+/*										*/
+/*  - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED 	*/
+/*    WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR 	*/
+/*    FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR 		*/
+/*    NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY 		*/
+/*    OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE.		*/
+/*										*/
+/*  - Without limitation, TCG and its members and licensors disclaim all 	*/
+/*    liability, including liability for infringement of any proprietary 	*/
+/*    rights, relating to use of information in this specification and to the	*/
+/*    implementation of this specification, and TCG disclaims all liability for	*/
+/*    cost of procurement of substitute goods or services, lost profits, loss 	*/
+/*    of use, loss of data or any incidental, consequential, direct, indirect, 	*/
+/*    or special damages, whether under contract, tort, warranty or otherwise, 	*/
+/*    arising in any way out of use or reliance upon this specification or any 	*/
+/*    information herein.							*/
+/*										*/
+/*  (c) Copyright IBM Corp. and others, 2016 - 2019				*/
+/*										*/
+/********************************************************************************/
+
+/* 10.2.14 CryptPrime.c */
+/* 10.2.14.1	Introduction */
+/* This file contains the code for prime validation. */
+
+#include "Tpm.h"
+#include "CryptPrime_fp.h"
+//#define CPRI_PRIME
+//#include "PrimeTable.h"
+#include "CryptPrimeSieve_fp.h"
+extern const uint32_t      s_LastPrimeInTable;
+extern const uint32_t      s_PrimeTableSize;
+extern const uint32_t      s_PrimesInTable;
+extern const unsigned char s_PrimeTable[];
+extern bigConst            s_CompositeOfSmallPrimes;
+
+/* 10.2.14.1.1 Root2() */
+/* This finds ceil(sqrt(n)) to use as a stopping point for searching the prime table. */
+static uint32_t
+Root2(
+      uint32_t             n
+      )
+{
+    int32_t              last = (int32_t)(n >> 2);
+    int32_t              next = (int32_t)(n >> 1);
+    int32_t              diff;
+    int32_t              stop = 10;
+    //
+    // get a starting point
+    for(; next != 0; last >>= 1, next >>= 2);
+    last++;
+    do
+	{
+	    next = (last + (n / last)) >> 1;
+	    diff = next - last;
+	    last = next;
+	    if(stop-- == 0)
+		FAIL(FATAL_ERROR_INTERNAL);
+	} while(diff < -1 || diff > 1);
+    if((n / next) > (unsigned)next)
+	next++;
+    pAssert(next != 0);
+    pAssert(((n / next) <= (unsigned)next) && (n / (next + 1) < (unsigned)next));
+    return next;
+}
+/* 10.2.14.1.2 IsPrimeInt() */
+/* This will do a test of a word of up to 32-bits in size. */
+BOOL
+IsPrimeInt(
+	   uint32_t            n
+	   )
+{
+    uint32_t            i;
+    uint32_t            stop;
+    if(n < 3 || ((n & 1) == 0))
+	return (n == 2);
+    if(n <= s_LastPrimeInTable)
+	{
+	    n >>= 1;
+	    return ((s_PrimeTable[n >> 3] >> (n & 7)) & 1);
+	}
+    // Need to search
+    stop = Root2(n) >> 1;
+    // starting at 1 is equivalent to staring at  (1 << 1) + 1 = 3
+    for(i = 1; i < stop; i++)
+	{
+	    if((s_PrimeTable[i >> 3] >> (i & 7)) & 1)
+		// see if this prime evenly divides the number
+		if((n % ((i << 1) + 1)) == 0)
+		    return FALSE;
+	}
+    return TRUE;
+}
+/* 10.2.14.1.3 BnIsProbablyPrime() */
+/* This function is used when the key sieve is not implemented. This function Will try to eliminate
+   some of the obvious things before going on to perform MillerRabin() as a final verification of
+   primeness. */
+BOOL
+BnIsProbablyPrime(
+		  bigNum          prime,           // IN:
+		  RAND_STATE      *rand            // IN: the random state just
+		  //     in case Miller-Rabin is required
+		  )
+{
+#if RADIX_BITS > 32
+    if(BnUnsignedCmpWord(prime, UINT32_MAX) <= 0)
+#else
+	if(BnGetSize(prime) == 1)
+#endif
+	    return IsPrimeInt((uint32_t)prime->d[0]);
+    if(BnIsEven(prime))
+	return FALSE;
+    if(BnUnsignedCmpWord(prime, s_LastPrimeInTable) <= 0)
+	{
+	    crypt_uword_t       temp = prime->d[0] >> 1;
+	    return ((s_PrimeTable[temp >> 3] >> (temp & 7)) & 1);
+	}
+    {
+	BN_VAR(n, LARGEST_NUMBER_BITS);
+	BnGcd(n, prime, s_CompositeOfSmallPrimes);
+	if(!BnEqualWord(n, 1))
+	    return FALSE;
+    }
+    return MillerRabin(prime, rand);
+}
+/* 10.2.14.1.4 MillerRabinRounds() */
+/* Function returns the number of Miller-Rabin rounds necessary to give an error probability equal
+   to the security strength of the prime. These values are from FIPS 186-3. */
+UINT32
+MillerRabinRounds(
+		  UINT32           bits           // IN: Number of bits in the RSA prime
+		  )
+{
+    if(bits < 511) return 8;    // don't really expect this
+    if(bits < 1536) return 5;   // for 512 and 1K primes
+    return 4;                   // for 3K public modulus and greater
+}
+/* 10.2.14.1.5 MillerRabin() */
+/* This function performs a Miller-Rabin test from FIPS 186-3. It does iterations trials on the
+   number. In all likelihood, if the number is not prime, the first test fails. */
+/* Return Values Meaning */
+/* TRUE probably prime */
+/* FALSE composite */
+BOOL
+MillerRabin(
+	    bigNum           bnW,
+	    RAND_STATE      *rand
+	    )
+{
+    BN_MAX(bnWm1);
+    BN_PRIME(bnM);
+    BN_PRIME(bnB);
+    BN_PRIME(bnZ);
+    BOOL             ret = FALSE;   // Assumed composite for easy exit
+    unsigned int     a;
+    unsigned int     j;
+    int              wLen;
+    int              i;
+    int              iterations = MillerRabinRounds(BnSizeInBits(bnW));
+    //
+    INSTRUMENT_INC(MillerRabinTrials[PrimeIndex]);
+    
+    pAssert(bnW->size > 1);
+    // Let a be the largest integer such that 2^a divides w1.
+    BnSubWord(bnWm1, bnW, 1);
+    pAssert(bnWm1->size != 0);
+    
+    // Since w is odd (w-1) is even so start at bit number 1 rather than 0
+    // Get the number of bits in bnWm1 so that it doesn't have to be recomputed
+    // on each iteration.
+    i = (int)(bnWm1->size * RADIX_BITS);
+    // Now find the largest power of 2 that divides w1
+    for(a = 1;
+	(a < (bnWm1->size * RADIX_BITS)) &&
+	    (BnTestBit(bnWm1, a) == 0);
+	a++);
+    // 2. m = (w1) / 2^a
+    BnShiftRight(bnM, bnWm1, a);
+    // 3. wlen = len (w).
+    wLen = BnSizeInBits(bnW);
+    // 4. For i = 1 to iterations do
+    for(i = 0; i < iterations; i++)
+	{
+	    // 4.1 Obtain a string b of wlen bits from an RBG.
+	    // Ensure that 1 < b < w1.
+	    // 4.2 If ((b <= 1) or (b >= w1)), then go to step 4.1.
+	    while(BnGetRandomBits(bnB, wLen, rand) && ((BnUnsignedCmpWord(bnB, 1) <= 0)
+						       || (BnUnsignedCmp(bnB, bnWm1) >= 0)));
+	    if(g_inFailureMode)
+		return FALSE;
+	    
+	    // 4.3 z = b^m mod w.
+	    // if ModExp fails, then say this is not
+	    // prime and bail out.
+	    BnModExp(bnZ, bnB, bnM, bnW);
+	    
+	    // 4.4 If ((z == 1) or (z = w == 1)), then go to step 4.7.
+	    if((BnUnsignedCmpWord(bnZ, 1) == 0)
+	       || (BnUnsignedCmp(bnZ, bnWm1) == 0))
+		goto step4point7;
+	    // 4.5 For j = 1 to a  1 do.
+	    for(j = 1; j < a; j++)
+		{
+		    // 4.5.1 z = z^2 mod w.
+		    BnModMult(bnZ, bnZ, bnZ, bnW);
+		    // 4.5.2 If (z = w1), then go to step 4.7.
+		    if(BnUnsignedCmp(bnZ, bnWm1) == 0)
+			goto step4point7;
+		    // 4.5.3 If (z = 1), then go to step 4.6.
+		    if(BnEqualWord(bnZ, 1))
+			goto step4point6;
+		}
+	    // 4.6 Return COMPOSITE.
+	step4point6:
+	    INSTRUMENT_INC(failedAtIteration[i]);
+	    goto end;
+	    // 4.7 Continue. Comment: Increment i for the do-loop in step 4.
+	step4point7:
+	    continue;
+	}
+    // 5. Return PROBABLY PRIME
+    ret = TRUE;
+ end:
+    return ret;
+}
+#if ALG_RSA
+/* 10.2.14.1.6 RsaCheckPrime() */
+/* This will check to see if a number is prime and appropriate for an RSA prime. */
+/* This has different functionality based on whether we are using key sieving or not. If not, the
+   number checked to see if it is divisible by the public exponent, then the number is adjusted
+   either up or down in order to make it a better candidate. It is then checked for being probably
+   prime. */
+/* If sieving is used, the number is used to root a sieving process. */
+TPM_RC
+RsaCheckPrime(
+	      bigNum           prime,
+	      UINT32           exponent,
+	      RAND_STATE      *rand
+	      )
+{
+#if !RSA_KEY_SIEVE
+    TPM_RC          retVal = TPM_RC_SUCCESS;
+    UINT32          modE = BnModWord(prime, exponent);
+    NOT_REFERENCED(rand);
+    if(modE == 0)
+	// evenly divisible so add two keeping the number odd
+	BnAddWord(prime, prime, 2);
+    // want 0 != (p - 1) mod e
+    // which is 1 != p mod e
+    else if(modE == 1)
+	// subtract 2 keeping number odd and insuring that
+	// 0 != (p - 1) mod e
+	BnSubWord(prime, prime, 2);
+    if(BnIsProbablyPrime(prime, rand) == 0)
+	ERROR_RETURN(g_inFailureMode ? TPM_RC_FAILURE : TPM_RC_VALUE);
+ Exit:
+    return retVal;
+#else
+    return PrimeSelectWithSieve(prime, exponent, rand);
+#endif
+}
+/* 10.2.14.1.7 RsaAdjustPrimeCandidate() */
+
+/* For this math, we assume that the RSA numbers are fixed-point numbers with the decimal point to
+   the left of the most significant bit. This approach helps make it clear what is happening with
+   the MSb of the values. The two RSA primes have to be large enough so that their product will be a
+   number with the necessary number of significant bits. For example, we want to be able to multiply
+   two 1024-bit numbers to produce a number with 2048 significant bits. If we accept any 1024-bit
+   prime that has its MSb set, then it is possible to produce a product that does not have the MSb
+   SET. For example, if we use tiny keys of 16 bits and have two 8-bit primes of 0x80, then the
+   public key would be 0x4000 which is only 15-bits. So, what we need to do is made sure that each
+   of the primes is large enough so that the product of the primes is twice as large as each
+   prime. A little arithmetic will show that the only way to do this is to make sure that each of
+   the primes is no less than root(2)/2. That's what this functions does. This function adjusts the
+   candidate prime so that it is odd and >= root(2)/2. This allows the product of these two numbers
+   to be .5, which, in fixed point notation means that the most significant bit is 1. For this
+   routine, the root(2)/2 (0.7071067811865475) approximated with 0xB505 which is, in fixed point,
+   0.7071075439453125 or an error of 0.000108%. Just setting the upper two bits would give a value >
+   0.75 which is an error of > 6%. Given the amount of time all the other computations take,
+   reducing the error is not much of a cost, but it isn't totally required either. */
+/* This function can be replaced with a function that just sets the two most significant bits of
+   each prime candidate without introducing any computational issues. */
+
+LIB_EXPORT void
+RsaAdjustPrimeCandidate(
+			bigNum          prime
+			)
+{
+    UINT32          msw;
+    UINT32          adjusted;
+    
+    // If the radix is 32, the compiler should turn this into a simple assignment
+    msw = prime->d[prime->size - 1] >> ((RADIX_BITS == 64) ? 32 : 0);
+    // Multiplying 0xff...f by 0x4AFB gives 0xff..f - 0xB5050...0
+    adjusted = (msw >> 16) * 0x4AFB;
+    adjusted += ((msw & 0xFFFF) * 0x4AFB) >> 16;
+    adjusted += 0xB5050000UL;
+#if RADIX_BITS == 64
+    // Save the low-order 32 bits
+    prime->d[prime->size - 1] &= 0xFFFFFFFFUL;
+    // replace the upper 32-bits
+    prime->d[prime->size -1] |= ((crypt_uword_t)adjusted << 32);
+#else
+    prime->d[prime->size - 1] = (crypt_uword_t)adjusted;
+#endif
+    // make sure the number is odd
+    prime->d[0] |= 1;
+}
+
+
+/* 10.2.14.1.8 BnGeneratePrimeForRSA() */
+/* Function to generate a prime of the desired size with the proper attributes for an RSA prime. */
+
+TPM_RC
+BnGeneratePrimeForRSA(
+		      bigNum          prime,          // IN/OUT: points to the BN that will get the
+		      //  random value
+		      UINT32          bits,           // IN: number of bits to get
+		      UINT32          exponent,       // IN: the exponent
+		      RAND_STATE      *rand           // IN: the random state
+		      )
+{
+    BOOL            found = FALSE;
+    //
+    // Make sure that the prime is large enough
+    pAssert(prime->allocated >= BITS_TO_CRYPT_WORDS(bits));
+    // Only try to handle specific sizes of keys in order to save overhead
+    pAssert((bits % 32) == 0);
+    
+    prime->size = BITS_TO_CRYPT_WORDS(bits);
+    
+    while(!found)
+	{
+	    // The change below is to make sure that all keys that are generated from the same
+	    // seed value will be the same regardless of the endianess or word size of the CPU.
+	    //       DRBG_Generate(rand, (BYTE *)prime->d, (UINT16)BITS_TO_BYTES(bits));// old
+	    //       if(g_inFailureMode)                                                // old
+	    if(!BnGetRandomBits(prime, bits, rand))                              // new
+		return TPM_RC_FAILURE;
+	    RsaAdjustPrimeCandidate(prime);
+	    found = RsaCheckPrime(prime, exponent, rand) == TPM_RC_SUCCESS;
+	}
+    return TPM_RC_SUCCESS;
+}
+
+#endif // TPM_ALG_RSA

+ 552 - 0
EVSE/GPL/ibmtpm1682/src/CryptPrimeSieve.c

@@ -0,0 +1,552 @@
+/********************************************************************************/
+/*										*/
+/*			     CryptPrimeSieve					*/
+/*			     Written by Ken Goldman				*/
+/*		       IBM Thomas J. Watson Research Center			*/
+/*            $Id: CryptPrimeSieve.c 1519 2019-11-15 20:43:51Z kgoldman $	*/
+/*										*/
+/*  Licenses and Notices							*/
+/*										*/
+/*  1. Copyright Licenses:							*/
+/*										*/
+/*  - Trusted Computing Group (TCG) grants to the user of the source code in	*/
+/*    this specification (the "Source Code") a worldwide, irrevocable, 		*/
+/*    nonexclusive, royalty free, copyright license to reproduce, create 	*/
+/*    derivative works, distribute, display and perform the Source Code and	*/
+/*    derivative works thereof, and to grant others the rights granted herein.	*/
+/*										*/
+/*  - The TCG grants to the user of the other parts of the specification 	*/
+/*    (other than the Source Code) the rights to reproduce, distribute, 	*/
+/*    display, and perform the specification solely for the purpose of 		*/
+/*    developing products based on such documents.				*/
+/*										*/
+/*  2. Source Code Distribution Conditions:					*/
+/*										*/
+/*  - Redistributions of Source Code must retain the above copyright licenses, 	*/
+/*    this list of conditions and the following disclaimers.			*/
+/*										*/
+/*  - Redistributions in binary form must reproduce the above copyright 	*/
+/*    licenses, this list of conditions	and the following disclaimers in the 	*/
+/*    documentation and/or other materials provided with the distribution.	*/
+/*										*/
+/*  3. Disclaimers:								*/
+/*										*/
+/*  - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF	*/
+/*  LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH	*/
+/*  RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES)	*/
+/*  THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE.		*/
+/*  Contact TCG Administration (admin@trustedcomputinggroup.org) for 		*/
+/*  information on specification licensing rights available through TCG 	*/
+/*  membership agreements.							*/
+/*										*/
+/*  - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED 	*/
+/*    WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR 	*/
+/*    FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR 		*/
+/*    NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY 		*/
+/*    OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE.		*/
+/*										*/
+/*  - Without limitation, TCG and its members and licensors disclaim all 	*/
+/*    liability, including liability for infringement of any proprietary 	*/
+/*    rights, relating to use of information in this specification and to the	*/
+/*    implementation of this specification, and TCG disclaims all liability for	*/
+/*    cost of procurement of substitute goods or services, lost profits, loss 	*/
+/*    of use, loss of data or any incidental, consequential, direct, indirect, 	*/
+/*    or special damages, whether under contract, tort, warranty or otherwise, 	*/
+/*    arising in any way out of use or reliance upon this specification or any 	*/
+/*    information herein.							*/
+/*										*/
+/*  (c) Copyright IBM Corp. and others, 2016 - 2019				*/
+/*										*/
+/********************************************************************************/
+
+/* 10.2.17 CryptPrimeSieve.c */
+/* 10.2.17.1 Includes and defines */
+#include "Tpm.h"
+#if RSA_KEY_SIEVE
+#include "CryptPrimeSieve_fp.h"
+/* This determines the number of bits in the largest sieve field. */
+#define MAX_FIELD_SIZE  2048
+extern const uint32_t      s_LastPrimeInTable;
+extern const uint32_t      s_PrimeTableSize;
+extern const uint32_t      s_PrimesInTable;
+extern const unsigned char s_PrimeTable[];
+/* This table is set of prime markers. Each entry is the prime value for the ((n + 1) * 1024)
+   prime. That is, the entry in s_PrimeMarkers[1] is the value for the 2,048th prime. This is used
+   in the PrimeSieve() to adjust the limit for the prime search. When processing smaller prime
+   candidates, fewer primes are checked directly before going to Miller-Rabin. As the prime grows,
+   it is worth spending more time eliminating primes as, a) the density is lower, and b) the cost of
+   Miller-Rabin is higher. */
+const uint32_t      s_PrimeMarkersCount = 6;
+const uint32_t      s_PrimeMarkers[] = {
+    8167, 17881, 28183, 38891, 49871, 60961 };
+uint32_t   primeLimit;
+
+/* 10.2.17.1.1 RsaAdjustPrimeLimit() */
+/* This used during the sieve process. The iterator for getting the next prime (RsaNextPrime()) will
+   return primes until it hits the limit (primeLimit) set up by this function. This causes the sieve
+   process to stop when an appropriate number of primes have been sieved. */
+
+void
+RsaAdjustPrimeLimit(
+		    uint32_t        requestedPrimes
+		    )
+{
+    if(requestedPrimes == 0 || requestedPrimes > s_PrimesInTable)
+	requestedPrimes = s_PrimesInTable;
+    requestedPrimes = (requestedPrimes - 1) / 1024;
+    if(requestedPrimes < s_PrimeMarkersCount)
+	primeLimit = s_PrimeMarkers[requestedPrimes];
+    else
+	primeLimit = s_LastPrimeInTable;
+    primeLimit >>= 1;
+}
+
+/* 10.2.17.1.2 RsaNextPrime() */
+/* This the iterator used during the sieve process. The input is the last prime returned (or any
+   starting point) and the output is the next higher prime. The function returns 0 when the
+   primeLimit is reached. */
+uint32_t
+RsaNextPrime(
+	     uint32_t    lastPrime
+	     )
+{
+    if(lastPrime == 0)
+	return 0;
+    lastPrime >>= 1;
+    for(lastPrime += 1; lastPrime <= primeLimit; lastPrime++)
+	{
+	    if(((s_PrimeTable[lastPrime >> 3] >> (lastPrime & 0x7)) & 1) == 1)
+		return ((lastPrime << 1) + 1);
+	}
+    return 0;
+}
+/* This table contains a previously sieved table. It has the bits for 3, 5, and 7 removed. Because
+   of the factors, it needs to be aligned to 105 and has a repeat of 105. */
+const BYTE   seedValues[] = {
+    0x16, 0x29, 0xcb, 0xa4, 0x65, 0xda, 0x30, 0x6c,
+    0x99, 0x96, 0x4c, 0x53, 0xa2, 0x2d, 0x52, 0x96,
+    0x49, 0xcb, 0xb4, 0x61, 0xd8, 0x32, 0x2d, 0x99,
+    0xa6, 0x44, 0x5b, 0xa4, 0x2c, 0x93, 0x96, 0x69,
+    0xc3, 0xb0, 0x65, 0x5a, 0x32, 0x4d, 0x89, 0xb6,
+    0x48, 0x59, 0x26, 0x2d, 0xd3, 0x86, 0x61, 0xcb,
+    0xb4, 0x64, 0x9a, 0x12, 0x6d, 0x91, 0xb2, 0x4c,
+    0x5a, 0xa6, 0x0d, 0xc3, 0x96, 0x69, 0xc9, 0x34,
+    0x25, 0xda, 0x22, 0x65, 0x99, 0xb4, 0x4c, 0x1b,
+    0x86, 0x2d, 0xd3, 0x92, 0x69, 0x4a, 0xb4, 0x45,
+    0xca, 0x32, 0x69, 0x99, 0x36, 0x0c, 0x5b, 0xa6,
+    0x25, 0xd3, 0x94, 0x68, 0x8b, 0x94, 0x65, 0xd2,
+    0x32, 0x6d, 0x18, 0xb6, 0x4c, 0x4b, 0xa6, 0x29,
+    0xd1};
+#define USE_NIBBLE
+#ifndef USE_NIBBLE
+static const BYTE bitsInByte[256] = {
+    0x00, 0x01, 0x01, 0x02, 0x01, 0x02, 0x02, 0x03,
+    0x01, 0x02, 0x02, 0x03, 0x02, 0x03, 0x03, 0x04,
+    0x01, 0x02, 0x02, 0x03, 0x02, 0x03, 0x03, 0x04,
+    0x02, 0x03, 0x03, 0x04, 0x03, 0x04, 0x04, 0x05,
+    0x01, 0x02, 0x02, 0x03, 0x02, 0x03, 0x03, 0x04,
+    0x02, 0x03, 0x03, 0x04, 0x03, 0x04, 0x04, 0x05,
+    0x02, 0x03, 0x03, 0x04, 0x03, 0x04, 0x04, 0x05,
+    0x03, 0x04, 0x04, 0x05, 0x04, 0x05, 0x05, 0x06,
+    0x01, 0x02, 0x02, 0x03, 0x02, 0x03, 0x03, 0x04,
+    0x02, 0x03, 0x03, 0x04, 0x03, 0x04, 0x04, 0x05,
+    0x02, 0x03, 0x03, 0x04, 0x03, 0x04, 0x04, 0x05,
+    0x03, 0x04, 0x04, 0x05, 0x04, 0x05, 0x05, 0x06,
+    0x02, 0x03, 0x03, 0x04, 0x03, 0x04, 0x04, 0x05,
+    0x03, 0x04, 0x04, 0x05, 0x04, 0x05, 0x05, 0x06,
+    0x03, 0x04, 0x04, 0x05, 0x04, 0x05, 0x05, 0x06,
+    0x04, 0x05, 0x05, 0x06, 0x05, 0x06, 0x06, 0x07,
+    0x01, 0x02, 0x02, 0x03, 0x02, 0x03, 0x03, 0x04,
+    0x02, 0x03, 0x03, 0x04, 0x03, 0x04, 0x04, 0x05,
+    0x02, 0x03, 0x03, 0x04, 0x03, 0x04, 0x04, 0x05,
+    0x03, 0x04, 0x04, 0x05, 0x04, 0x05, 0x05, 0x06,
+    0x02, 0x03, 0x03, 0x04, 0x03, 0x04, 0x04, 0x05,
+    0x03, 0x04, 0x04, 0x05, 0x04, 0x05, 0x05, 0x06,
+    0x03, 0x04, 0x04, 0x05, 0x04, 0x05, 0x05, 0x06,
+    0x04, 0x05, 0x05, 0x06, 0x05, 0x06, 0x06, 0x07,
+    0x02, 0x03, 0x03, 0x04, 0x03, 0x04, 0x04, 0x05,
+    0x03, 0x04, 0x04, 0x05, 0x04, 0x05, 0x05, 0x06,
+    0x03, 0x04, 0x04, 0x05, 0x04, 0x05, 0x05, 0x06,
+    0x04, 0x05, 0x05, 0x06, 0x05, 0x06, 0x06, 0x07,
+    0x03, 0x04, 0x04, 0x05, 0x04, 0x05, 0x05, 0x06,
+    0x04, 0x05, 0x05, 0x06, 0x05, 0x06, 0x06, 0x07,
+    0x04, 0x05, 0x05, 0x06, 0x05, 0x06, 0x06, 0x07,
+    0x05, 0x06, 0x06, 0x07, 0x06, 0x07, 0x07, 0x08
+};
+#define BitsInByte(x)   bitsInByte[(unsigned char)x]
+#else
+const BYTE bitsInNibble[16] = {
+    0x00, 0x01, 0x01, 0x02, 0x01, 0x02, 0x02, 0x03,
+    0x01, 0x02, 0x02, 0x03, 0x02, 0x03, 0x03, 0x04};
+#define BitsInByte(x)						    \
+    (bitsInNibble[(unsigned char)(x) & 0xf]				\
+     +   bitsInNibble[((unsigned char)(x) >> 4) & 0xf])
+#endif
+
+/* 10.2.17.1.3 BitsInArry() */
+/* This function counts the number of bits set in an array of bytes. */
+static int
+BitsInArray(
+	    const unsigned char     *a,             // IN: A pointer to an array of bytes
+	    unsigned int             aSize          // IN: the number of bytes to sum
+	    )
+{
+    int     j = 0;
+    for(; aSize; a++, aSize--)
+	j += BitsInByte(*a);
+    return j;
+}
+
+/* 10.2.17.1.4 FindNthSetBit() */
+/* This function finds the nth SET bit in a bit array. The n parameter is between 1 and the number
+   of bits in the array (always a multiple of 8). If called when the array does not have n bits set,
+   it will return -1 */
+/* Return Values Meaning */
+/* <0 no bit is set or no bit with the requested number is set */
+/* >=0 the number of the bit in the array that is the nth set */
+int
+FindNthSetBit(
+	      const UINT16     aSize,         // IN: the size of the array to check
+	      const BYTE      *a,             // IN: the array to check
+	      const UINT32     n              // IN, the number of the SET bit
+	      )
+{
+    UINT16       i;
+    int          retValue;
+    UINT32       sum = 0;
+    BYTE         sel;
+    //find the bit
+    for(i = 0; (i < (int)aSize) && (sum < n); i++)
+	sum += BitsInByte(a[i]);
+    i--;
+    // The chosen bit is in the byte that was just accessed
+    // Compute the offset to the start of that byte
+    retValue = i * 8 - 1;
+    sel = a[i];
+    // Subtract the bits in the last byte added.
+    sum -= BitsInByte(sel);
+    // Now process the byte, one bit at a time.
+    for(; (sel != 0) && (sum != n); retValue++, sel = sel >> 1)
+	sum += (sel & 1) != 0;
+    return (sum == n) ? retValue : -1;
+}
+typedef struct
+{
+    UINT16      prime;
+    UINT16      count;
+} SIEVE_MARKS;
+const SIEVE_MARKS sieveMarks[5] = {
+    {31, 7}, {73, 5}, {241, 4}, {1621, 3}, {UINT16_MAX, 2}};
+
+/* 10.2.17.1.5 PrimeSieve() */
+/* This function does a prime sieve over the input field which has as its starting address the value
+   in bnN. Since this initializes the Sieve using a precomputed field with the bits associated with
+   3, 5 and 7 already turned off, the value of pnN may need to be adjusted by a few counts to allow
+   the precomputed field to be used without modification. */
+/* To get better performance, one could address the issue of developing the composite numbers. When
+   the size of the prime gets large, the time for doing the divisions goes up, noticeably. It could
+   be better to develop larger composite numbers even if they need to be bigNum's themselves. The
+   object would be to reduce the number of times that the large prime is divided into a few large
+   divides and then use smaller divides to get to the final 16 bit (or smaller) remainders. */
+UINT32
+PrimeSieve(
+	   bigNum           bnN,       // IN/OUT: number to sieve
+	   UINT32           fieldSize, // IN: size of the field area in bytes
+	   BYTE            *field      // IN: field
+	   )
+{
+    UINT32            i;
+    UINT32            j;
+    UINT32           fieldBits = fieldSize * 8;
+    UINT32           r;
+    BYTE            *pField;
+    INT32            iter;
+    UINT32           adjust;
+    UINT32           mark = 0;
+    UINT32           count = sieveMarks[0].count;
+    UINT32           stop = sieveMarks[0].prime;
+    UINT32           composite;
+    UINT32           pList[8];
+    UINT32           next;
+    pAssert(field != NULL && bnN != NULL);
+    // If the remainder is odd, then subtracting the value will give an even number,
+    // but we want an odd number, so subtract the 105+rem. Otherwise, just subtract
+    // the even remainder.
+    adjust = (UINT32)BnModWord(bnN, 105);
+    if(adjust & 1)
+	adjust += 105;
+    // Adjust the input number so that it points to the first number in a
+    // aligned field.
+    BnSubWord(bnN, bnN, adjust);
+    //    pAssert(BnModWord(bnN, 105) == 0);
+    pField = field;
+    for(i = fieldSize; i >= sizeof(seedValues);
+	pField += sizeof(seedValues), i -= sizeof(seedValues))
+	{
+	    memcpy(pField, seedValues, sizeof(seedValues));
+	}
+    if(i != 0)
+	memcpy(pField, seedValues, i);
+    // Cycle through the primes, clearing bits
+    // Have already done 3, 5, and 7
+    iter = 7;
+#define NEXT_PRIME(iter)    (iter = RsaNextPrime(iter))
+    // Get the next N primes where N is determined by the mark in the sieveMarks
+    while((composite = NEXT_PRIME(iter)) != 0)
+	{
+	    next = 0;
+	    i = count;
+	    pList[i--] = composite;
+	    for(; i > 0; i--)
+		{
+		    next = NEXT_PRIME(iter);
+		    pList[i] = next;
+		    if(next != 0)
+			composite *= next;
+		}
+	    // Get the remainder when dividing the base field address
+	    // by the composite
+	    composite = (UINT32)BnModWord(bnN, composite);
+	    // 'composite' is divisible by the composite components. for each of the
+	    // composite components, divide 'composite'. That remainder (r) is used to
+	    // pick a starting point for clearing the array. The stride is equal to the
+	    // composite component. Note, the field only contains odd numbers. If the
+	    // field were expanded to contain all numbers, then half of the bits would
+	    // have already been cleared. We can save the trouble of clearing them a
+	    // second time by having a stride of 2*next. Or we can take all of the even
+	    // numbers out of the field and use a stride of 'next'
+	    for(i = count; i > 0; i--)
+		{
+		    next = pList[i];
+		    if(next == 0)
+			goto done;
+		    r = composite % next;
+		    // these computations deal with the fact that we have picked a field-sized
+		    // range that is aligned to a 105 count boundary. The problem is, this field
+		    // only contains odd numbers. If we take our prime guess and walk through all
+		    // the numbers using that prime as the 'stride', then every other 'stride' is
+		    // going to be an even number. So, we are actually counting by 2 * the stride
+		    // We want the count to start on an odd number at the start of our field. That
+		    // is, we want to assume that we have counted up to the edge of the field by
+		    // the 'stride' and now we are going to start flipping bits in the field as we
+		    // continue to count up by 'stride'. If we take the base of our field and
+		    // divide by the stride, we find out how much we find out how short the last
+		    // count was from reaching the edge of the bit field. Say we get a quotient of
+		    // 3 and remainder of 1. This means that after 3 strides, we are 1 short of
+		    // the start of the field and the next stride will either land within the
+		    // field or step completely over it. The confounding factor is that our field
+		    // only contains odd numbers and our stride is actually 2 * stride. If the
+		    // quoitent is even, then that means that when we add 2 * stride, we are going
+		    // to hit another even number. So, we have to know if we need to back off
+		    // by 1 stride before we start couting by 2 * stride.
+		    // We can tell from the remainder whether we are on an even or odd
+		    // stride when we hit the beginning of the table. If we are on an odd stride
+		    // (r & 1), we would start half a stride in (next - r)/2. If we are on an
+		    // even stride, we need 0.5 strides (next - r/2) because the table only has
+		    // odd numbers. If the remainder happens to be zero, then the start of the
+		    // table is on stride so no adjustment is necessary.
+
+		    if(r & 1)           j = (next - r) / 2;
+		    else if(r == 0)     j = 0;
+		    else                 j = next - (r / 2);
+		    for(; j < fieldBits; j += next)
+			ClearBit(j, field, fieldSize);
+		}
+	    if(next >= stop)
+		{
+		    mark++;
+		    count = sieveMarks[mark].count;
+		    stop = sieveMarks[mark].prime;
+		}
+	}
+ done:
+    INSTRUMENT_INC(totalFieldsSieved[PrimeIndex]);
+    i = BitsInArray(field, fieldSize);
+    INSTRUMENT_ADD(bitsInFieldAfterSieve[PrimeIndex], i);
+    INSTRUMENT_ADD(emptyFieldsSieved[PrimeIndex], (i == 0));
+    return i;
+}
+#ifdef SIEVE_DEBUG
+static uint32_t fieldSize = 210;
+
+/* 10.2.17.1.6 SetFieldSize() */
+/* Function to set the field size used for prime generation. Used for tuning. */
+uint32_t
+SetFieldSize(
+	     uint32_t         newFieldSize
+	     )
+{
+    if(newFieldSize == 0 || newFieldSize > MAX_FIELD_SIZE)
+	fieldSize = MAX_FIELD_SIZE;
+    else
+	fieldSize = newFieldSize;
+    return fieldSize;
+}
+#endif // SIEVE_DEBUG
+
+/* 10.2.17.1.7 PrimeSelectWithSieve() */
+/* This function will sieve the field around the input prime candidate. If the sieve field is not
+   empty, one of the one bits in the field is chosen for testing with Miller-Rabin. If the value is
+   prime, pnP is updated with this value and the function returns success. If this value is not
+   prime, another pseudo-random candidate is chosen and tested. This process repeats until all
+   values in the field have been checked. If all bits in the field have been checked and none is
+   prime, the function returns FALSE and a new random value needs to be chosen. */
+/* Error Returns Meaning */
+/* TPM_RC_FAILURE TPM in failure mode, probably due to entropy source */
+/* TPM_RC_SUCCESS candidate is probably prime */
+/* TPM_RC_NO_RESULT candidate is not prime and couldn't find and alternative in the field */
+LIB_EXPORT TPM_RC
+PrimeSelectWithSieve(
+		     bigNum           candidate,         // IN/OUT: The candidate to filter
+		     UINT32           e,                 // IN: the exponent
+		     RAND_STATE      *rand               // IN: the random number generator state
+		     )
+{
+    BYTE             field[MAX_FIELD_SIZE];
+    UINT32           first;
+    UINT32           ones;
+    INT32            chosen;
+    BN_PRIME(test);
+    UINT32           modE;
+#ifndef SIEVE_DEBUG
+    UINT32           fieldSize = MAX_FIELD_SIZE;
+#endif
+    UINT32           primeSize;
+    //
+    // Adjust the field size and prime table list to fit the size of the prime
+    // being tested. This is done to try to optimize the trade-off between the
+    // dividing done for sieving and the time for Miller-Rabin. When the size
+    // of the prime is large, the cost of Miller-Rabin is fairly high, as is the
+    // cost of the sieving. However, the time for Miller-Rabin goes up considerably
+    // faster than the cost of dividing by a number of primes.
+    primeSize = BnSizeInBits(candidate);
+    
+    if(primeSize <= 512)
+	{
+	    RsaAdjustPrimeLimit(1024); // Use just the first 1024 primes
+	}
+    else if(primeSize <= 1024)
+	{
+	    RsaAdjustPrimeLimit(4096); // Use just the first 4K primes
+	}
+    else
+	{
+	    RsaAdjustPrimeLimit(0);     // Use all available
+	}
+    
+    // Save the low-order word to use as a search generator and make sure that
+    // it has some interesting range to it
+    first = (UINT32)(candidate->d[0] | 0x80000000);
+    
+    // Sieve the field
+    ones = PrimeSieve(candidate, fieldSize, field);
+    pAssert(ones > 0 && ones < (fieldSize * 8));
+    for(; ones > 0; ones--)
+	{
+	    // Decide which bit to look at and find its offset
+	    chosen = FindNthSetBit((UINT16)fieldSize, field, ((first % ones) + 1));
+	    
+	    if((chosen < 0) || (chosen >= (INT32)(fieldSize * 8)))
+		FAIL(FATAL_ERROR_INTERNAL);
+	    
+	    // Set this as the trial prime
+	    BnAddWord(test, candidate, (crypt_uword_t)(chosen * 2));
+	    
+	    // The exponent might not have been one of the tested primes so
+	    // make sure that it isn't divisible and make sure that 0 != (p-1) mod e
+	    // Note: This is the same as 1 != p mod e
+	    modE = (UINT32)BnModWord(test, e);
+	    if((modE != 0) && (modE != 1) && MillerRabin(test, rand))
+		{
+		    BnCopy(candidate, test);
+		    return TPM_RC_SUCCESS;
+		}
+	    // Clear the bit just tested
+	    ClearBit(chosen, field, fieldSize);
+	}
+    // Ran out of bits and couldn't find a prime in this field
+    INSTRUMENT_INC(noPrimeFields[PrimeIndex]);
+    return (g_inFailureMode ? TPM_RC_FAILURE : TPM_RC_NO_RESULT);
+}
+
+#if RSA_INSTRUMENT
+static char            a[256];
+char *
+PrintTuple(
+	   UINT32      *i
+	   )
+{
+    sprintf(a, "{%d, %d, %d}", i[0], i[1], i[2]);
+    return a;
+}
+#define CLEAR_VALUE(x)    memset(x, 0, sizeof(x))
+ 
+void
+RsaSimulationEnd(
+		 void
+		 )
+{
+    int         i;
+    UINT32      averages[3];
+    UINT32      nonFirst = 0;
+    if((PrimeCounts[0] + PrimeCounts[1] + PrimeCounts[2]) != 0)
+	{
+	    printf("Primes generated = %s\n", PrintTuple(PrimeCounts));
+	    printf("Fields sieved = %s\n", PrintTuple(totalFieldsSieved));
+	    printf("Fields with no primes = %s\n", PrintTuple(noPrimeFields));
+	    printf("Primes checked with Miller-Rabin = %s\n",
+		   PrintTuple(MillerRabinTrials));
+	    for(i = 0; i < 3; i++)
+		averages[i] = (totalFieldsSieved[i]
+			       != 0 ? bitsInFieldAfterSieve[i] / totalFieldsSieved[i]
+			       : 0);
+	    printf("Average candidates in field %s\n", PrintTuple(averages));
+	    for(i = 1; i < (sizeof(failedAtIteration) / sizeof(failedAtIteration[0]));
+		i++)
+		nonFirst += failedAtIteration[i];
+	    printf("Miller-Rabin failures not in first round = %d\n", nonFirst);
+	}
+    CLEAR_VALUE(PrimeCounts);
+    CLEAR_VALUE(totalFieldsSieved);
+    CLEAR_VALUE(noPrimeFields);
+    CLEAR_VALUE(MillerRabinTrials);
+    CLEAR_VALUE(bitsInFieldAfterSieve);
+}
+void
+GetSieveStats(
+	      uint32_t        *trials,
+	      uint32_t        *emptyFields,
+	      uint32_t        *averageBits
+	      )
+{
+    uint32_t        totalBits;
+    uint32_t        fields;
+    *trials = MillerRabinTrials[0] + MillerRabinTrials[1] + MillerRabinTrials[2];
+    *emptyFields = noPrimeFields[0] + noPrimeFields[1] + noPrimeFields[2];
+    fields = totalFieldsSieved[0] + totalFieldsSieved[1]
+	     + totalFieldsSieved[2];
+    totalBits = bitsInFieldAfterSieve[0] + bitsInFieldAfterSieve[1]
+		+ bitsInFieldAfterSieve[2];
+    if(fields != 0)
+	*averageBits = totalBits / fields;
+    else
+	*averageBits = 0;
+    CLEAR_VALUE(PrimeCounts);
+    CLEAR_VALUE(totalFieldsSieved);
+    CLEAR_VALUE(noPrimeFields);
+    CLEAR_VALUE(MillerRabinTrials);
+    CLEAR_VALUE(bitsInFieldAfterSieve);
+}
+#endif
+#endif // RSA_KEY_SIEVE
+#if !RSA_INSTRUMENT
+//*** RsaSimulationEnd()
+// Stub for call when not doing instrumentation.
+void
+RsaSimulationEnd(
+		 void
+		 )
+{
+    return;
+}
+#endif

+ 101 - 0
EVSE/GPL/ibmtpm1682/src/CryptPrimeSieve_fp.h

@@ -0,0 +1,101 @@
+/********************************************************************************/
+/*										*/
+/*			     				*/
+/*			     Written by Ken Goldman				*/
+/*		       IBM Thomas J. Watson Research Center			*/
+/*            $Id: CryptPrimeSieve_fp.h 1671 2021-06-03 18:30:41Z kgoldman $	*/
+/*										*/
+/*  Licenses and Notices							*/
+/*										*/
+/*  1. Copyright Licenses:							*/
+/*										*/
+/*  - Trusted Computing Group (TCG) grants to the user of the source code in	*/
+/*    this specification (the "Source Code") a worldwide, irrevocable, 		*/
+/*    nonexclusive, royalty free, copyright license to reproduce, create 	*/
+/*    derivative works, distribute, display and perform the Source Code and	*/
+/*    derivative works thereof, and to grant others the rights granted herein.	*/
+/*										*/
+/*  - The TCG grants to the user of the other parts of the specification 	*/
+/*    (other than the Source Code) the rights to reproduce, distribute, 	*/
+/*    display, and perform the specification solely for the purpose of 		*/
+/*    developing products based on such documents.				*/
+/*										*/
+/*  2. Source Code Distribution Conditions:					*/
+/*										*/
+/*  - Redistributions of Source Code must retain the above copyright licenses, 	*/
+/*    this list of conditions and the following disclaimers.			*/
+/*										*/
+/*  - Redistributions in binary form must reproduce the above copyright 	*/
+/*    licenses, this list of conditions	and the following disclaimers in the 	*/
+/*    documentation and/or other materials provided with the distribution.	*/
+/*										*/
+/*  3. Disclaimers:								*/
+/*										*/
+/*  - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF	*/
+/*  LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH	*/
+/*  RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES)	*/
+/*  THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE.		*/
+/*  Contact TCG Administration (admin@trustedcomputinggroup.org) for 		*/
+/*  information on specification licensing rights available through TCG 	*/
+/*  membership agreements.							*/
+/*										*/
+/*  - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED 	*/
+/*    WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR 	*/
+/*    FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR 		*/
+/*    NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY 		*/
+/*    OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE.		*/
+/*										*/
+/*  - Without limitation, TCG and its members and licensors disclaim all 	*/
+/*    liability, including liability for infringement of any proprietary 	*/
+/*    rights, relating to use of information in this specification and to the	*/
+/*    implementation of this specification, and TCG disclaims all liability for	*/
+/*    cost of procurement of substitute goods or services, lost profits, loss 	*/
+/*    of use, loss of data or any incidental, consequential, direct, indirect, 	*/
+/*    or special damages, whether under contract, tort, warranty or otherwise, 	*/
+/*    arising in any way out of use or reliance upon this specification or any 	*/
+/*    information herein.							*/
+/*										*/
+/*  (c) Copyright IBM Corp. and others, 2016 - 2021				*/
+/*										*/
+/********************************************************************************/
+
+#ifndef 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

+ 103 - 0
EVSE/GPL/ibmtpm1682/src/CryptPrime_fp.h

@@ -0,0 +1,103 @@
+/********************************************************************************/
+/*										*/
+/*			      Code for prime validation				*/
+/*			     Written by Ken Goldman				*/
+/*		       IBM Thomas J. Watson Research Center			*/
+/*            $Id: CryptPrime_fp.h 1476 2019-06-10 19:32:03Z kgoldman $		*/
+/*										*/
+/*  Licenses and Notices							*/
+/*										*/
+/*  1. Copyright Licenses:							*/
+/*										*/
+/*  - Trusted Computing Group (TCG) grants to the user of the source code in	*/
+/*    this specification (the "Source Code") a worldwide, irrevocable, 		*/
+/*    nonexclusive, royalty free, copyright license to reproduce, create 	*/
+/*    derivative works, distribute, display and perform the Source Code and	*/
+/*    derivative works thereof, and to grant others the rights granted herein.	*/
+/*										*/
+/*  - The TCG grants to the user of the other parts of the specification 	*/
+/*    (other than the Source Code) the rights to reproduce, distribute, 	*/
+/*    display, and perform the specification solely for the purpose of 		*/
+/*    developing products based on such documents.				*/
+/*										*/
+/*  2. Source Code Distribution Conditions:					*/
+/*										*/
+/*  - Redistributions of Source Code must retain the above copyright licenses, 	*/
+/*    this list of conditions and the following disclaimers.			*/
+/*										*/
+/*  - Redistributions in binary form must reproduce the above copyright 	*/
+/*    licenses, this list of conditions	and the following disclaimers in the 	*/
+/*    documentation and/or other materials provided with the distribution.	*/
+/*										*/
+/*  3. Disclaimers:								*/
+/*										*/
+/*  - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF	*/
+/*  LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH	*/
+/*  RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES)	*/
+/*  THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE.		*/
+/*  Contact TCG Administration (admin@trustedcomputinggroup.org) for 		*/
+/*  information on specification licensing rights available through TCG 	*/
+/*  membership agreements.							*/
+/*										*/
+/*  - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED 	*/
+/*    WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR 	*/
+/*    FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR 		*/
+/*    NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY 		*/
+/*    OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE.		*/
+/*										*/
+/*  - Without limitation, TCG and its members and licensors disclaim all 	*/
+/*    liability, including liability for infringement of any proprietary 	*/
+/*    rights, relating to use of information in this specification and to the	*/
+/*    implementation of this specification, and TCG disclaims all liability for	*/
+/*    cost of procurement of substitute goods or services, lost profits, loss 	*/
+/*    of use, loss of data or any incidental, consequential, direct, indirect, 	*/
+/*    or special damages, whether under contract, tort, warranty or otherwise, 	*/
+/*    arising in any way out of use or reliance upon this specification or any 	*/
+/*    information herein.							*/
+/*										*/
+/*  (c) Copyright IBM Corp. and others, 2016 - 2019				*/
+/*										*/
+/********************************************************************************/
+
+#ifndef CRYPTPRIME_FP_H
+#define CRYPTPRIME_FP_H
+
+BOOL
+IsPrimeInt(
+	   uint32_t            n
+	   );
+BOOL
+BnIsProbablyPrime(
+		  bigNum          prime,           // IN:
+		  RAND_STATE      *rand            // IN: the random state just
+		  //     in case Miller-Rabin is required
+		  );
+UINT32
+MillerRabinRounds(
+		  UINT32           bits           // IN: Number of bits in the RSA prime
+		  );
+BOOL
+MillerRabin(
+	    bigNum           bnW,
+	    RAND_STATE      *rand
+	    );
+TPM_RC
+RsaCheckPrime(
+	      bigNum           prime,
+	      UINT32           exponent,
+	      RAND_STATE      *rand
+	      );
+LIB_EXPORT void
+RsaAdjustPrimeCandidate(
+			bigNum          prime
+			);
+TPM_RC
+BnGeneratePrimeForRSA(
+		      bigNum          prime,
+		      UINT32          bits,
+		      UINT32          exponent,
+		      RAND_STATE      *rand
+		      );
+
+
+#endif

+ 855 - 0
EVSE/GPL/ibmtpm1682/src/CryptRand.c

@@ -0,0 +1,855 @@
+/********************************************************************************/
+/*										*/
+/*		DRBG with a behavior according to SP800-90A			*/
+/*			     Written by Ken Goldman				*/
+/*		       IBM Thomas J. Watson Research Center			*/
+/*            $Id: CryptRand.c 1658 2021-01-22 23:14:01Z kgoldman $		*/
+/*										*/
+/*  Licenses and Notices							*/
+/*										*/
+/*  1. Copyright Licenses:							*/
+/*										*/
+/*  - Trusted Computing Group (TCG) grants to the user of the source code in	*/
+/*    this specification (the "Source Code") a worldwide, irrevocable, 		*/
+/*    nonexclusive, royalty free, copyright license to reproduce, create 	*/
+/*    derivative works, distribute, display and perform the Source Code and	*/
+/*    derivative works thereof, and to grant others the rights granted herein.	*/
+/*										*/
+/*  - The TCG grants to the user of the other parts of the specification 	*/
+/*    (other than the Source Code) the rights to reproduce, distribute, 	*/
+/*    display, and perform the specification solely for the purpose of 		*/
+/*    developing products based on such documents.				*/
+/*										*/
+/*  2. Source Code Distribution Conditions:					*/
+/*										*/
+/*  - Redistributions of Source Code must retain the above copyright licenses, 	*/
+/*    this list of conditions and the following disclaimers.			*/
+/*										*/
+/*  - Redistributions in binary form must reproduce the above copyright 	*/
+/*    licenses, this list of conditions	and the following disclaimers in the 	*/
+/*    documentation and/or other materials provided with the distribution.	*/
+/*										*/
+/*  3. Disclaimers:								*/
+/*										*/
+/*  - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF	*/
+/*  LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH	*/
+/*  RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES)	*/
+/*  THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE.		*/
+/*  Contact TCG Administration (admin@trustedcomputinggroup.org) for 		*/
+/*  information on specification licensing rights available through TCG 	*/
+/*  membership agreements.							*/
+/*										*/
+/*  - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED 	*/
+/*    WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR 	*/
+/*    FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR 		*/
+/*    NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY 		*/
+/*    OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE.		*/
+/*										*/
+/*  - Without limitation, TCG and its members and licensors disclaim all 	*/
+/*    liability, including liability for infringement of any proprietary 	*/
+/*    rights, relating to use of information in this specification and to the	*/
+/*    implementation of this specification, and TCG disclaims all liability for	*/
+/*    cost of procurement of substitute goods or services, lost profits, loss 	*/
+/*    of use, loss of data or any incidental, consequential, direct, indirect, 	*/
+/*    or special damages, whether under contract, tort, warranty or otherwise, 	*/
+/*    arising in any way out of use or reliance upon this specification or any 	*/
+/*    information herein.							*/
+/*										*/
+/*  (c) Copyright IBM Corp. and others, 2016 - 2021				*/
+/*										*/
+/********************************************************************************/
+
+#include "Tpm.h"
+#include    "PRNG_TestVectors.h"
+const BYTE DRBG_NistTestVector_Entropy[] = {DRBG_TEST_INITIATE_ENTROPY};
+const BYTE DRBG_NistTestVector_GeneratedInterm[] =
+    {DRBG_TEST_GENERATED_INTERM};
+const BYTE DRBG_NistTestVector_EntropyReseed[] =
+    {DRBG_TEST_RESEED_ENTROPY};
+const BYTE DRBG_NistTestVector_Generated[] = {DRBG_TEST_GENERATED};
+
+/* 10.2.16.2.2 Derivation Function Defines and Structures */
+#define     DF_COUNT (DRBG_KEY_SIZE_WORDS / DRBG_IV_SIZE_WORDS + 1)
+#if DRBG_KEY_SIZE_BITS != 128 && DRBG_KEY_SIZE_BITS != 256
+#   error "CryptRand.c only written for AES with 128- or 256-bit keys."
+#endif
+
+typedef struct
+{
+    DRBG_KEY_SCHEDULE   keySchedule;
+    DRBG_IV             iv[DF_COUNT];
+    DRBG_IV             out1;
+    DRBG_IV             buf;
+    int                 contents;
+} DF_STATE, *PDF_STATE;
+/* 10.2.16.2.3 DfCompute() */
+/* This function does the incremental update of the derivation function state. It encrypts the iv
+   value and XOR's the results into each of the blocks of the output. This is equivalent to
+   processing all of input data for each output block. */
+static void
+DfCompute(
+	  PDF_STATE        dfState
+	  )
+{
+    int              i;
+    int              iv;
+    crypt_uword_t   *pIv;
+    crypt_uword_t    temp[DRBG_IV_SIZE_WORDS] = {0};
+    //
+    for(iv = 0; iv < DF_COUNT; iv++)
+	{
+	    pIv = (crypt_uword_t *)&dfState->iv[iv].words[0];
+	    for(i = 0; i < DRBG_IV_SIZE_WORDS; i++)
+		{
+		    temp[i] ^= pIv[i] ^ dfState->buf.words[i];
+		}
+	    DRBG_ENCRYPT(&dfState->keySchedule, &temp, pIv);
+	}
+    for(i = 0; i < DRBG_IV_SIZE_WORDS; i++)
+	dfState->buf.words[i] = 0;
+    dfState->contents = 0;
+}
+/* 10.2.16.2.4 DfStart() */
+/* This initializes the output blocks with an encrypted counter value and initializes the key
+   schedule. */
+static void
+DfStart(
+	PDF_STATE        dfState,
+	uint32_t         inputLength
+	)
+{
+    BYTE            init[8];
+    int             i;
+    UINT32          drbgSeedSize = sizeof(DRBG_SEED);
+    const BYTE dfKey[DRBG_KEY_SIZE_BYTES] = {
+	0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+	0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f
+#if DRBG_KEY_SIZE_BYTES > 16
+	,0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
+	0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f
+#endif
+    };
+    memset(dfState, 0, sizeof(DF_STATE));
+    DRBG_ENCRYPT_SETUP(&dfKey[0], DRBG_KEY_SIZE_BITS, &dfState->keySchedule);
+    // Create the first chaining values
+    for(i = 0; i < DF_COUNT; i++)
+	((BYTE *)&dfState->iv[i])[3] = (BYTE)i;
+    DfCompute(dfState);
+    // initialize the first 64 bits of the IV in a way that doesn't depend
+    // on the size of the words used.
+    UINT32_TO_BYTE_ARRAY(inputLength, init);
+    UINT32_TO_BYTE_ARRAY(drbgSeedSize, &init[4]);
+    memcpy(&dfState->iv[0], init, 8);
+    dfState->contents = 4;
+}
+/* 10.2.16.2.5 DfUpdate() */
+/* This updates the state with the input data. A byte at a time is moved into the state buffer until
+   it is full and then that block is encrypted by DfCompute(). */
+static void
+DfUpdate(
+	 PDF_STATE        dfState,
+	 int              size,
+	 const BYTE      *data
+	 )
+{
+    while(size > 0)
+	{
+	    int         toFill = DRBG_IV_SIZE_BYTES - dfState->contents;
+	    if(size < toFill)
+		toFill = size;
+	    // Copy as many bytes as there are or until the state buffer is full
+	    memcpy(&dfState->buf.bytes[dfState->contents], data, toFill);
+	    // Reduce the size left by the amount copied
+	    size -= toFill;
+	    // Advance the data pointer by the amount copied
+	    data += toFill;
+	    // increase the buffer contents count by the amount copied
+	    dfState->contents += toFill;
+	    pAssert(dfState->contents <= DRBG_IV_SIZE_BYTES);
+	    // If we have a full buffer, do a computation pass.
+	    if(dfState->contents == DRBG_IV_SIZE_BYTES)
+		DfCompute(dfState);
+	}
+}
+/* 10.2.16.2.6 DfEnd() */
+/* This function is called to get the result of the derivation function computation. If the buffer
+   is not full, it is padded with zeros. The output buffer is structured to be the same as a
+   DRBG_SEED value so that the function can return a pointer to the DRBG_SEED value in the DF_STATE
+   structure. */
+static DRBG_SEED *
+DfEnd(
+      PDF_STATE        dfState
+      )
+{
+    // Since DfCompute is always called when a buffer is full, there is always
+    // space in the buffer for the terminator
+    dfState->buf.bytes[dfState->contents++] = 0x80;
+    // If the buffer is not full, pad with zeros
+    while(dfState->contents < DRBG_IV_SIZE_BYTES)
+	dfState->buf.bytes[dfState->contents++] = 0;
+    // Do a final state update
+    DfCompute(dfState);
+    return (DRBG_SEED *)&dfState->iv;
+}
+/* 10.2.16.2.7 DfBuffer() */
+/* Function to take an input buffer and do the derivation function to produce a DRBG_SEED value that
+   can be used in DRBG_Reseed(); */
+static DRBG_SEED *
+DfBuffer(
+	 DRBG_SEED       *output,        // OUT: receives the result
+	 int              size,          // IN: size of the buffer to add
+	 BYTE            *buf            // IN: address of the buffer
+	 )
+{
+    DF_STATE        dfState;
+    if(size == 0 || buf == NULL)
+	return NULL;
+    // Initialize the derivation function
+    DfStart(&dfState, size);
+    DfUpdate(&dfState, size, buf);
+    DfEnd(&dfState);
+    memcpy(output, &dfState.iv[0], sizeof(DRBG_SEED));
+    return output;
+}
+/* 10.2.16.2.8 DRBG_GetEntropy() */
+/* Even though this implementation never fails, it may get blocked indefinitely long in the call to
+   get entropy from the platform (DRBG_GetEntropy32()). This function is only used during
+   instantiation of the DRBG for manufacturing and on each start-up after an non-orderly
+   shutdown. */
+/* Return Values Meaning */
+/* TRUE Requested entropy returned */
+/* FALSE Entropy Failure */
+BOOL
+DRBG_GetEntropy(
+		UINT32           requiredEntropy,   // IN: requested number of bytes of full
+		//     entropy
+		BYTE            *entropy            // OUT: buffer to return collected entropy
+		)
+{
+#if !USE_DEBUG_RNG
+    UINT32       obtainedEntropy;
+    INT32        returnedEntropy;
+    // If in debug mode, always use the self-test values for initialization
+    if(IsSelfTest())
+	{
+#endif
+	    // If doing simulated DRBG, then check to see if the
+	    // entropyFailure condition is being tested
+	    if(!IsEntropyBad())/* This function increments the IV value by 1. It is used by EncryptDRBG(). */
+		{
+		    // In self-test, the caller should be asking for exactly the seed
+		    // size of entropy.
+		    pAssert(requiredEntropy == sizeof(DRBG_NistTestVector_Entropy));
+		    memcpy(entropy, DRBG_NistTestVector_Entropy,
+			   sizeof(DRBG_NistTestVector_Entropy));
+		}
+#if !USE_DEBUG_RNG
+	}
+    else if(!IsEntropyBad())
+	{
+	    // Collect entropy
+	    // Note: In debug mode, the only "entropy" value ever returned
+	    // is the value of the self-test vector.
+	    for(returnedEntropy = 1, obtainedEntropy = 0;
+		obtainedEntropy < requiredEntropy && !IsEntropyBad();
+		obtainedEntropy += returnedEntropy)
+		{
+		    returnedEntropy = _plat__GetEntropy(&entropy[obtainedEntropy],
+							requiredEntropy - obtainedEntropy);
+		    if(returnedEntropy <= 0)
+			SetEntropyBad();
+		}
+	}
+#endif
+    return !IsEntropyBad();
+}
+
+void
+IncrementIv(
+	    DRBG_IV         *iv
+	    )
+{
+    BYTE      *ivP = ((BYTE *)iv) + DRBG_IV_SIZE_BYTES;
+    while((--ivP >= (BYTE *)iv) && ((*ivP = ((*ivP + 1) & 0xFF)) == 0));
+}
+/* 10.2.16.2.10 EncryptDRBG() */
+/* This does the encryption operation for the DRBG. It will encrypt the input state counter (IV)
+   using the state key. Into the output buffer for as many times as it takes to generate the
+   required number of bytes. */
+static BOOL
+EncryptDRBG(
+	    BYTE                *dOut,
+	    UINT32               dOutBytes,
+	    DRBG_KEY_SCHEDULE   *keySchedule,
+	    DRBG_IV             *iv,
+	    UINT32              *lastValue      // Points to the last output value
+	    )
+{
+#if FIPS_COMPLIANT
+    // For FIPS compliance, the DRBG has to do a continuous self-test to make sure that
+    // no two consecutive values are the same. This overhead is not incurred if the TPM
+    // is not required to be FIPS compliant
+    //
+    UINT32           temp[DRBG_IV_SIZE_BYTES / sizeof(UINT32)];
+    int              i;
+    BYTE            *p;
+    for(; dOutBytes > 0;)
+	{
+	    // Increment the IV before each encryption (this is what makes this
+	    // different from normal counter-mode encryption
+	    IncrementIv(iv);
+	    DRBG_ENCRYPT(keySchedule, iv, temp);
+	    // Expect a 16 byte block
+#if DRBG_IV_SIZE_BITS != 128
+#error  "Unsuppored IV size in DRBG"
+#endif
+	    if((lastValue[0] == temp[0])
+	       && (lastValue[1] == temp[1])
+	       && (lastValue[2] == temp[2])
+	       && (lastValue[3] == temp[3])
+	       )
+		{
+		    LOG_FAILURE(FATAL_ERROR_ENTROPY);
+		    return FALSE;
+		}
+	    lastValue[0] = temp[0];
+	    lastValue[1] = temp[1];
+	    lastValue[2] = temp[2];
+	    lastValue[3] = temp[3];
+	    i = MIN(dOutBytes, DRBG_IV_SIZE_BYTES);
+	    dOutBytes -= i;
+	    for(p = (BYTE *)temp; i > 0; i--)
+		*dOut++ = *p++;
+	}
+#else // version without continuous self-test
+    NOT_REFERENCED(lastValue);
+    for(; dOutBytes >= DRBG_IV_SIZE_BYTES;
+	dOut = &dOut[DRBG_IV_SIZE_BYTES], dOutBytes -= DRBG_IV_SIZE_BYTES)
+	{
+	    // Increment the IV
+	    IncrementIv(iv);
+	    DRBG_ENCRYPT(keySchedule, iv, dOut);
+	}
+    // If there is a partial, generate into a block-sized
+    // temp buffer and copy to the output.
+    if(dOutBytes != 0)
+	{
+	    BYTE        temp[DRBG_IV_SIZE_BYTES];
+	    // Increment the IV
+	    IncrementIv(iv);
+	    DRBG_ENCRYPT(keySchedule, iv, temp);
+	    memcpy(dOut, temp, dOutBytes);
+	}
+#endif
+    return TRUE;
+}
+/* 10.2.16.2.11 DRBG_Update() */
+/* This function performs the state update function. According to SP800-90A, a temp value is created
+   by doing CTR mode encryption of providedData and replacing the key and IV with these values. The
+   one difference is that, with counter mode, the IV is incremented after each block is encrypted
+   and in this operation, the counter is incremented before each block is encrypted. This function
+   implements an optimized version of the algorithm in that it does the update of the
+   drbgState->seed in place and then providedData is XORed into drbgState->seed to complete the
+   encryption of providedData. This works because the IV is the last thing that gets encrypted. */
+static BOOL
+DRBG_Update(
+	    DRBG_STATE          *drbgState,     // IN:OUT state to update
+	    DRBG_KEY_SCHEDULE   *keySchedule,   // IN: the key schedule (optional)
+	    DRBG_SEED           *providedData   // IN: additional data
+	    )
+{
+    UINT32               i;
+    BYTE                *temp = (BYTE *)&drbgState->seed;
+    DRBG_KEY            *key = pDRBG_KEY(&drbgState->seed);
+    DRBG_IV             *iv = pDRBG_IV(&drbgState->seed);
+    DRBG_KEY_SCHEDULE    localKeySchedule;
+    //
+    pAssert(drbgState->magic == DRBG_MAGIC);
+    // If an key schedule was not provided, make one
+    if(keySchedule == NULL)
+	{
+	    if(DRBG_ENCRYPT_SETUP((BYTE *)key,
+				  DRBG_KEY_SIZE_BITS, &localKeySchedule) != 0)
+		{
+		    LOG_FAILURE(FATAL_ERROR_INTERNAL);
+		    return FALSE;
+		}
+	    keySchedule = &localKeySchedule;
+	}
+    // Encrypt the temp value
+    EncryptDRBG(temp, sizeof(DRBG_SEED), keySchedule, iv,
+		drbgState->lastValue);
+    if(providedData != NULL)
+	{
+	    BYTE        *pP = (BYTE *)providedData;
+	    for(i = DRBG_SEED_SIZE_BYTES; i != 0; i--)
+		*temp++ ^= *pP++;
+	}
+    // Since temp points to the input key and IV, we are done and
+    // don't need to copy the resulting 'temp' to drbgState->seed
+    return TRUE;
+}
+/* 10.2.16.2.12 DRBG_Reseed() */
+/* This function is used when reseeding of the DRBG is required. If entropy is provided, it is used
+   in lieu of using hardware entropy. */
+/* NOTE: the provided entropy must be the required size. */
+/* Return Values Meaning */
+/* TRUE reseed succeeded */
+/* FALSE reseed failed, probably due to the entropy generation */
+BOOL
+DRBG_Reseed(
+	    DRBG_STATE          *drbgState,         // IN: the state to update
+	    DRBG_SEED           *providedEntropy,   // IN: entropy
+	    DRBG_SEED           *additionalData     // IN:
+	    )
+{
+    DRBG_SEED            seed;
+    pAssert((drbgState != NULL) && (drbgState->magic == DRBG_MAGIC));
+    if(providedEntropy == NULL)
+	{
+	    providedEntropy = &seed;
+	    if(!DRBG_GetEntropy(sizeof(DRBG_SEED), (BYTE *)providedEntropy))
+		return FALSE;
+	}
+    if(additionalData != NULL)
+	{
+	    unsigned int          i;
+	    // XOR the provided data into the provided entropy
+	    for(i = 0; i < sizeof(DRBG_SEED); i++)
+		((BYTE *)providedEntropy)[i] ^= ((BYTE *)additionalData)[i];
+	}
+    DRBG_Update(drbgState, NULL, providedEntropy);
+    drbgState->reseedCounter = 1;
+    return TRUE;
+}
+/* 10.2.16.2.13 DRBG_SelfTest() */
+/* This is run when the DRBG is instantiated and at startup */
+/* Return Values Meaning */
+/* FALSE test failed */
+/* TRUE test OK */
+BOOL
+DRBG_SelfTest(
+	      void
+	      )
+{
+    BYTE             buf[sizeof(DRBG_NistTestVector_Generated)];
+    DRBG_SEED        seed;
+    UINT32           i;
+    BYTE            *p;
+    DRBG_STATE       testState;
+    //
+    pAssert(!IsSelfTest());
+    SetSelfTest();
+    SetDrbgTested();
+    // Do an instantiate
+    if(!DRBG_Instantiate(&testState, 0, NULL))
+	return FALSE;
+#if DRBG_DEBUG_PRINT
+    dbgDumpMemBlock(pDRBG_KEY(&testState), DRBG_KEY_SIZE_BYTES,
+		    "Key after Instantiate");
+    dbgDumpMemBlock(pDRBG_IV(&testState), DRBG_IV_SIZE_BYTES,
+		    "Value after Instantiate");
+#endif
+    if(DRBG_Generate((RAND_STATE *)&testState, buf, sizeof(buf)) == 0)
+	return FALSE;
+#if DRBG_DEBUG_PRINT
+    dbgDumpMemBlock(pDRBG_KEY(&testState.seed), DRBG_KEY_SIZE_BYTES,
+		    "Key after 1st Generate");
+    dbgDumpMemBlock(pDRBG_IV(&testState.seed), DRBG_IV_SIZE_BYTES,
+		    "Value after 1st Generate");
+#endif
+    if(memcmp(buf, DRBG_NistTestVector_GeneratedInterm, sizeof(buf)) != 0)
+	return FALSE;
+    memcpy(seed.bytes, DRBG_NistTestVector_EntropyReseed, sizeof(seed));
+    DRBG_Reseed(&testState, &seed, NULL);
+#if DRBG_DEBUG_PRINT
+    dbgDumpMemBlock((BYTE *)pDRBG_KEY(&testState.seed), DRBG_KEY_SIZE_BYTES,
+		    "Key after 2nd Generate");
+    dbgDumpMemBlock((BYTE *)pDRBG_IV(&testState.seed), DRBG_IV_SIZE_BYTES,
+		    "Value after 2nd Generate");
+    dbgDumpMemBlock(buf, sizeof(buf), "2nd Generated");
+#endif
+    if(DRBG_Generate((RAND_STATE *)&testState, buf, sizeof(buf)) == 0)
+	return FALSE;
+    if(memcmp(buf, DRBG_NistTestVector_Generated, sizeof(buf)) != 0)
+	return FALSE;
+    ClearSelfTest();
+    DRBG_Uninstantiate(&testState);
+    for(p = (BYTE *)&testState, i = 0; i < sizeof(DRBG_STATE); i++)
+	{
+	    if(*p++)
+		return FALSE;
+	}
+    // Simulate hardware failure to make sure that we get an error when
+    // trying to instantiate
+    SetEntropyBad();
+    if(DRBG_Instantiate(&testState, 0, NULL))
+	return FALSE;
+    ClearEntropyBad();
+    return TRUE;
+}
+/* 10.2.16.3 Public Interface */
+
+/* 10.2.16.3.1 Description */
+/* The functions in this section are the interface to the RNG. These are the functions that are used
+   by TPM.lib. */
+
+/* 10.2.16.3.2 CryptRandomStir() */
+/* This function is used to cause a reseed. A DRBG_SEED amount of entropy is collected from the
+   hardware and then additional data is added. */
+/* Error Returns Meaning */
+/* TPM_RC_NO_RESULT failure of the entropy generator */
+LIB_EXPORT TPM_RC
+CryptRandomStir(
+		UINT16           additionalDataSize,
+		BYTE            *additionalData
+		)
+{
+#if !USE_DEBUG_RNG
+    DRBG_SEED        tmpBuf;
+    DRBG_SEED        dfResult;
+    //
+    // All reseed with outside data starts with a buffer full of entropy
+    if(!DRBG_GetEntropy(sizeof(tmpBuf), (BYTE *)&tmpBuf))
+	return TPM_RC_NO_RESULT;
+    DRBG_Reseed(&drbgDefault, &tmpBuf,
+		DfBuffer(&dfResult, additionalDataSize, additionalData));
+    drbgDefault.reseedCounter = 1;
+    return TPM_RC_SUCCESS;
+#else
+    // If doing debug, use the input data as the initial setting for the RNG state
+    // so that the test can be reset at any time.
+    // Note: If this is called with a data size of 0 or less, nothing happens. The
+    // presumption is that, in a debug environment, the caller will have specific
+    // values for initialization, so this check is just a simple way to prevent
+    // inadvertent programming errors from screwing things up. This doesn't use an
+    // pAssert() because the non-debug version of this function will accept these
+    // parameters as meaning that there is no additionalData and only hardware
+    // entropy is used.
+    if((additionalDataSize > 0) && (additionalData != NULL))
+	{
+	    memset(drbgDefault.seed.bytes, 0, sizeof(drbgDefault.seed.bytes));
+	    memcpy(drbgDefault.seed.bytes, additionalData,
+		   MIN(additionalDataSize, sizeof(drbgDefault.seed.bytes)));
+	}
+    drbgDefault.reseedCounter = 1;
+    return TPM_RC_SUCCESS;
+#endif
+}
+/* 10.2.16.3.3 CryptRandomGenerate() */
+/* Generate a randomSize number or random bytes. */
+LIB_EXPORT UINT16
+CryptRandomGenerate(
+		    UINT16           randomSize,
+		    BYTE            *buffer
+		    )
+{
+    return DRBG_Generate((RAND_STATE *)&drbgDefault, buffer, randomSize);
+}
+/* 10.2.16.3.4 DRBG_InstantiateSeededKdf() */
+/* Function used to instantiate a KDF-based RNG. This is used for derivations. This function always
+   returns TRUE. */
+LIB_EXPORT BOOL
+DRBG_InstantiateSeededKdf(
+			  KDF_STATE       *state,         // OUT: buffer to hold the state
+			  TPM_ALG_ID       hashAlg,       // IN: hash algorithm
+			  TPM_ALG_ID       kdf,           // IN: the KDF to use
+			  TPM2B           *seed,          // IN: the seed to use
+			  const TPM2B     *label,         // IN: a label for the generation process.
+			  TPM2B           *context,       // IN: the context value
+			  UINT32           limit          // IN: Maximum number of bits from the KDF
+			  )
+{
+    state->magic = KDF_MAGIC;
+    state->limit = limit;
+    state->seed = seed;
+    state->hash = hashAlg;
+    state->kdf = kdf;
+    state->label = label;
+    state->context = context;
+    state->digestSize = CryptHashGetDigestSize(hashAlg);
+    state->counter = 0;
+    state->residual.t.size = 0;
+    return TRUE;
+}
+/* 10.2.16.3.5 DRBG_AdditionalData() */
+/* Function to reseed the DRBG with additional entropy. This is normally called before computing the
+   protection value of a primary key in the Endorsement hierarchy. */
+LIB_EXPORT void
+DRBG_AdditionalData(
+		    DRBG_STATE      *drbgState,     // IN:OUT state to update
+		    TPM2B           *additionalData // IN: value to incorporate
+		    )
+{
+    DRBG_SEED        dfResult;
+    if(drbgState->magic == DRBG_MAGIC)
+	{
+	    DfBuffer(&dfResult, additionalData->size, additionalData->buffer);
+	    DRBG_Reseed(drbgState, &dfResult, NULL);
+	}
+}
+/* 10.2.16.3.6 DRBG_InstantiateSeeded() */
+/* This function is used to instantiate a random number generator from seed values. The nominal use
+   of this generator is to create sequences of pseudo-random numbers from a seed value. */
+/* Returns
+   TPM_RC_FAILURE	DRBG self-test failure
+*/
+LIB_EXPORT TPM_RC
+DRBG_InstantiateSeeded(
+		       DRBG_STATE      *drbgState,     // IN/OUT: buffer to hold the state
+		       const TPM2B     *seed,          // IN: the seed to use
+		       const TPM2B     *purpose,       // IN: a label for the generation process.
+		       const TPM2B     *name,          // IN: name of the object
+		       const TPM2B     *additional     // IN: additional data
+		       )
+{
+    DF_STATE         dfState;
+    int              totalInputSize;
+    // DRBG should have been tested, but...
+    if(!IsDrbgTested() && !DRBG_SelfTest())
+	{
+	    LOG_FAILURE(FATAL_ERROR_SELF_TEST);
+	    return TPM_RC_FAILURE;
+	}
+    // Initialize the DRBG state
+    memset(drbgState, 0, sizeof(DRBG_STATE));
+    drbgState->magic = DRBG_MAGIC;
+    // Size all of the values
+    totalInputSize = (seed != NULL) ? seed->size : 0;
+    totalInputSize += (purpose != NULL) ? purpose->size : 0;
+    totalInputSize += (name != NULL) ? name->size : 0;
+    totalInputSize += (additional != NULL) ? additional->size : 0;
+    // Initialize the derivation
+    DfStart(&dfState, totalInputSize);
+    // Run all the input strings through the derivation function
+    if(seed != NULL)
+	DfUpdate(&dfState, seed->size, seed->buffer);
+    if(purpose != NULL)
+	DfUpdate(&dfState, purpose->size, purpose->buffer);
+    if(name != NULL)
+	DfUpdate(&dfState, name->size, name->buffer);
+    if(additional != NULL)
+	DfUpdate(&dfState, additional->size, additional->buffer);
+    // Used the derivation function output as the "entropy" input. This is not
+    // how it is described in SP800-90A but this is the equivalent function
+    DRBG_Reseed(((DRBG_STATE *)drbgState), DfEnd(&dfState), NULL);
+    return TPM_RC_SUCCESS;
+}
+/* 10.2.16.3.7 CryptRandStartup() */
+/* This function is called when TPM_Startup() is executed. */
+/* TRUE instantiation succeeded */	/* kgold */
+/* FALSE instantiation failed */
+LIB_EXPORT BOOL
+CryptRandStartup(
+		 void
+		 )
+{
+#if ! _DRBG_STATE_SAVE
+    // If not saved in NV, re-instantiate on each startup
+    return DRBG_Instantiate(&drbgDefault, 0, NULL);
+#else
+    // If the running state is saved in NV, NV has to be loaded before it can
+    // be updated
+    if(go.drbgState.magic == DRBG_MAGIC)
+	return DRBG_Reseed(&go.drbgState, NULL, NULL);
+    else
+	return DRBG_Instantiate(&go.drbgState, 0, NULL);
+#endif
+}
+/* 10.2.16.3.8 CryptRandInit() */
+/* This function is called when _TPM_Init() is being processed */
+LIB_EXPORT BOOL
+CryptRandInit(
+	      void
+	      )
+{
+#if !USE_DEBUG_RNG
+    _plat__GetEntropy(NULL, 0);
+#endif
+    return DRBG_SelfTest();
+}
+/* 10.2.16.5 DRBG_Generate() */
+/* This function generates a random sequence according SP800-90A. If random is not NULL, then
+   randomSize bytes of random values are generated. If random is NULL or randomSize is zero, then
+   the function returns TRUE without generating any bits or updating the reseed counter. This
+   function returns 0 if a reseed is required. Otherwise, it returns the number of bytes produced
+   which could be less than the number requested if the request is too large.("too large" is
+   implementation dependent.) */
+LIB_EXPORT UINT16
+DRBG_Generate(
+	      RAND_STATE      *state,
+	      BYTE            *random,        // OUT: buffer to receive the random values
+	      UINT16           randomSize     // IN: the number of bytes to generate
+	      )
+{
+    if(state == NULL)
+	state = (RAND_STATE *)&drbgDefault;
+    if(random == NULL)
+	return 0;
+
+    // If the caller used a KDF state, generate a sequence from the KDF not to
+    // exceed the limit.
+    if(state->kdf.magic == KDF_MAGIC)
+	{
+	    KDF_STATE       *kdf = (KDF_STATE *)state;
+	    UINT32           counter = (UINT32)kdf->counter;
+	    INT32            bytesLeft = randomSize;
+
+	    // If the number of bytes to be returned would put the generator
+	    // over the limit, then return 0
+	    if((((kdf->counter * kdf->digestSize) + randomSize) * 8) > kdf->limit)
+		return 0;
+	    // Process partial and full blocks until all requested bytes provided
+	    while(bytesLeft > 0)
+		{
+		    // If there is any residual data in the buffer, copy it to the output
+		    // buffer
+		    if(kdf->residual.t.size > 0)
+			{
+			    INT32      size;
+			    //
+			    // Don't use more of the residual than will fit or more than are
+			    // available
+			    size = MIN(kdf->residual.t.size, bytesLeft);
+			    // Copy some or all of the residual to the output. The residual is
+			    // at the end of the buffer. The residual might be a full buffer.
+			    MemoryCopy(random,
+				       &kdf->residual.t.buffer
+				       [kdf->digestSize - kdf->residual.t.size], size);
+			    // Advance the buffer pointer
+			    random += size;
+			    // Reduce the number of bytes left to get
+			    bytesLeft -= size;
+			    // And reduce the residual size appropriately
+			    kdf->residual.t.size -= (UINT16)size;
+			}
+		    else
+			{
+			    UINT16           blocks = (UINT16)(bytesLeft / kdf->digestSize);
+			    //
+			    // Get the number of required full blocks
+			    if(blocks > 0)
+				{
+				    UINT16      size = blocks * kdf->digestSize;
+				    // Get some number of full blocks and put them in the return buffer
+				    CryptKDFa(kdf->hash, kdf->seed, kdf->label, kdf->context, NULL,
+					      kdf->limit, random, &counter, blocks);
+				    // reduce the size remaining to be moved and advance the pointer
+				    bytesLeft -= size;
+				    random += size;
+				}
+			    else
+				{
+				    // Fill the residual buffer with a full block and then loop to
+				    // top to get part of it copied to the output.
+				    kdf->residual.t.size = CryptKDFa(kdf->hash, kdf->seed,
+								     kdf->label, kdf->context, NULL,
+								     kdf->limit,
+								     kdf->residual.t.buffer,
+								     &counter, 1);
+				}
+			}
+		}
+	    kdf->counter = counter;
+	    return randomSize;
+	}
+    else if(state->drbg.magic == DRBG_MAGIC)
+	{
+	    DRBG_STATE          *drbgState = (DRBG_STATE *)state;
+	    DRBG_KEY_SCHEDULE    keySchedule;
+	    DRBG_SEED           *seed = &drbgState->seed;
+	    if(drbgState->reseedCounter >= CTR_DRBG_MAX_REQUESTS_PER_RESEED)
+		{
+		    if(drbgState == &drbgDefault)
+			{
+			    DRBG_Reseed(drbgState, NULL, NULL);
+			    if(IsEntropyBad() && !IsSelfTest())
+				return 0;
+			}
+		    else
+			{
+			    // If this is a PRNG then the only way to get
+			    // here is if the SW has run away.
+			    LOG_FAILURE(FATAL_ERROR_INTERNAL);
+			    return 0;
+			}
+		}
+	    // if the allowed number of bytes in a request is larger than the
+	    // less than the number of bytes that can be requested, then check
+#if UINT16_MAX >=  CTR_DRBG_MAX_BYTES_PER_REQUEST
+	    if(randomSize > CTR_DRBG_MAX_BYTES_PER_REQUEST)
+		randomSize = CTR_DRBG_MAX_BYTES_PER_REQUEST;
+#endif
+	    // Create  encryption schedule
+	    if(DRBG_ENCRYPT_SETUP((BYTE *)pDRBG_KEY(seed),
+				  DRBG_KEY_SIZE_BITS, &keySchedule) != 0)
+		{
+		    LOG_FAILURE(FATAL_ERROR_INTERNAL);
+		    return 0;
+		}
+	    // Generate the random data
+	    EncryptDRBG(random, randomSize, &keySchedule, pDRBG_IV(seed),
+			drbgState->lastValue);
+	    // Do a key update
+	    DRBG_Update(drbgState, &keySchedule, NULL);
+	    // Increment the reseed counter
+	    drbgState->reseedCounter += 1;
+	}
+    else
+	{
+	    LOG_FAILURE(FATAL_ERROR_INTERNAL);
+	    return FALSE;
+	}
+    return randomSize;
+}
+/* 10.2.16.6 DRBG_Instantiate() */
+/* This is CTR_DRBG_Instantiate_algorithm() from [SP 800-90A 10.2.1.3.1]. This is called when a the
+   TPM DRBG is to be instantiated. This is called to instantiate a DRBG used by the TPM for normal
+   operations. */
+/* Return Values Meaning */
+/* TRUE instantiation succeeded */
+/* FALSE instantiation failed */
+LIB_EXPORT BOOL
+DRBG_Instantiate(
+		 DRBG_STATE      *drbgState,         // OUT: the instantiated value
+		 UINT16           pSize,             // IN: Size of personalization string
+		 BYTE            *personalization    // IN: The personalization string
+		 )
+{
+    DRBG_SEED        seed;
+    DRBG_SEED        dfResult;
+    //
+    pAssert((pSize == 0) || (pSize <= sizeof(seed)) || (personalization != NULL));
+    // If the DRBG has not been tested, test when doing an instantiation. Since
+    // Instantiation is called during self test, make sure we don't get stuck in a
+    // loop.
+    if(!IsDrbgTested() && !IsSelfTest() && !DRBG_SelfTest())
+	return FALSE;
+    // If doing a self test, DRBG_GetEntropy will return the NIST
+    // test vector value.
+    if(!DRBG_GetEntropy(sizeof(seed), (BYTE *)&seed))
+	return FALSE;
+    // set everything to zero
+    memset(drbgState, 0, sizeof(DRBG_STATE));
+    drbgState->magic = DRBG_MAGIC;
+    // Steps 1, 2, 3, 6, 7 of SP 800-90A 10.2.1.3.1 are exactly what
+    // reseeding does. So, do a reduction on the personalization value (if any)
+    // and do a reseed.
+    DRBG_Reseed(drbgState, &seed, DfBuffer(&dfResult, pSize, personalization));
+    return TRUE;
+}
+/* 10.2.16.7 DRBG_Uninstantiate() */
+/* This is Uninstantiate_function() from [SP 800-90A 9.4]. */
+/* Error Returns	Meaning */
+/* TPM_RC_VALUE	not a valid state */
+LIB_EXPORT TPM_RC
+DRBG_Uninstantiate(
+		   DRBG_STATE      *drbgState      // IN/OUT: working state to erase
+		   )
+{
+    if((drbgState == NULL) || (drbgState->magic != DRBG_MAGIC))
+	return TPM_RC_VALUE;
+    memset(drbgState, 0, sizeof(DRBG_STATE));
+    return TPM_RC_SUCCESS;
+}
+

+ 192 - 0
EVSE/GPL/ibmtpm1682/src/CryptRand.h

@@ -0,0 +1,192 @@
+/********************************************************************************/
+/*										*/
+/*		DRBG with a behavior according to SP800-90A			*/
+/*			     Written by Ken Goldman				*/
+/*		       IBM Thomas J. Watson Research Center			*/
+/*            $Id: CryptRand.h 1594 2020-03-26 22:15:48Z kgoldman $		*/
+/*										*/
+/*  Licenses and Notices							*/
+/*										*/
+/*  1. Copyright Licenses:							*/
+/*										*/
+/*  - Trusted Computing Group (TCG) grants to the user of the source code in	*/
+/*    this specification (the "Source Code") a worldwide, irrevocable, 		*/
+/*    nonexclusive, royalty free, copyright license to reproduce, create 	*/
+/*    derivative works, distribute, display and perform the Source Code and	*/
+/*    derivative works thereof, and to grant others the rights granted herein.	*/
+/*										*/
+/*  - The TCG grants to the user of the other parts of the specification 	*/
+/*    (other than the Source Code) the rights to reproduce, distribute, 	*/
+/*    display, and perform the specification solely for the purpose of 		*/
+/*    developing products based on such documents.				*/
+/*										*/
+/*  2. Source Code Distribution Conditions:					*/
+/*										*/
+/*  - Redistributions of Source Code must retain the above copyright licenses, 	*/
+/*    this list of conditions and the following disclaimers.			*/
+/*										*/
+/*  - Redistributions in binary form must reproduce the above copyright 	*/
+/*    licenses, this list of conditions	and the following disclaimers in the 	*/
+/*    documentation and/or other materials provided with the distribution.	*/
+/*										*/
+/*  3. Disclaimers:								*/
+/*										*/
+/*  - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF	*/
+/*  LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH	*/
+/*  RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES)	*/
+/*  THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE.		*/
+/*  Contact TCG Administration (admin@trustedcomputinggroup.org) for 		*/
+/*  information on specification licensing rights available through TCG 	*/
+/*  membership agreements.							*/
+/*										*/
+/*  - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED 	*/
+/*    WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR 	*/
+/*    FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR 		*/
+/*    NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY 		*/
+/*    OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE.		*/
+/*										*/
+/*  - Without limitation, TCG and its members and licensors disclaim all 	*/
+/*    liability, including liability for infringement of any proprietary 	*/
+/*    rights, relating to use of information in this specification and to the	*/
+/*    implementation of this specification, and TCG disclaims all liability for	*/
+/*    cost of procurement of substitute goods or services, lost profits, loss 	*/
+/*    of use, loss of data or any incidental, consequential, direct, indirect, 	*/
+/*    or special damages, whether under contract, tort, warranty or otherwise, 	*/
+/*    arising in any way out of use or reliance upon this specification or any 	*/
+/*    information herein.							*/
+/*										*/
+/*  (c) Copyright IBM Corp. and others, 2016 - 2020				*/
+/*										*/
+/********************************************************************************/
+
+/* 10.1.4 CryptRand.h */
+/* 10.1.4.1 Introduction */
+/* This file contains constant definition shared by CryptUtil() and the parts of the Crypto
+   Engine. */
+#ifndef _CRYPT_RAND_H
+#define _CRYPT_RAND_H
+/* DRBG Structures and Defines Values and structures for the random number generator. These values
+   are defined in this header file so that the size of the RNG state can be known to TPM.lib. This
+   allows the allocation of some space in NV memory for the state to be stored on an orderly
+   shutdown. The DRBG based on a symmetric block cipher is defined by three values, */
+/* a) the key size */
+/* b) the block size (the IV size) */
+/* c) the symmetric algorithm */
+#define DRBG_KEY_SIZE_BITS      AES_MAX_KEY_SIZE_BITS
+#define DRBG_IV_SIZE_BITS       (AES_MAX_BLOCK_SIZE * 8)
+#define DRBG_ALGORITHM          TPM_ALG_AES
+typedef tpmKeyScheduleAES DRBG_KEY_SCHEDULE;
+#define DRBG_ENCRYPT_SETUP(key, keySizeInBits, schedule)		\
+    TpmCryptSetEncryptKeyAES(key, keySizeInBits, schedule)
+#define DRBG_ENCRYPT(keySchedule, in, out)				\
+    TpmCryptEncryptAES(SWIZZLE(keySchedule, in, out))
+#if     ((DRBG_KEY_SIZE_BITS % RADIX_BITS) != 0)	\
+    || ((DRBG_IV_SIZE_BITS % RADIX_BITS) != 0)
+#error "Key size and IV for DRBG must be even multiples of the radix"
+#endif
+#if (DRBG_KEY_SIZE_BITS % DRBG_IV_SIZE_BITS) != 0
+#error "Key size for DRBG must be even multiple of the cypher block size"
+#endif
+/*     Derived values */
+#define DRBG_MAX_REQUESTS_PER_RESEED (1 << 48)
+#define DRBG_MAX_REQEST_SIZE (1 << 32)
+#define pDRBG_KEY(seed)    ((DRBG_KEY *)&(((BYTE *)(seed))[0]))
+#define pDRBG_IV(seed)     ((DRBG_IV *)&(((BYTE *)(seed))[DRBG_KEY_SIZE_BYTES]))
+#define DRBG_KEY_SIZE_WORDS     (BITS_TO_CRYPT_WORDS(DRBG_KEY_SIZE_BITS))
+#define DRBG_KEY_SIZE_BYTES     (DRBG_KEY_SIZE_WORDS * RADIX_BYTES)
+#define DRBG_IV_SIZE_WORDS      (BITS_TO_CRYPT_WORDS(DRBG_IV_SIZE_BITS))
+#define DRBG_IV_SIZE_BYTES      (DRBG_IV_SIZE_WORDS * RADIX_BYTES)
+#define DRBG_SEED_SIZE_WORDS    (DRBG_KEY_SIZE_WORDS + DRBG_IV_SIZE_WORDS)
+#define DRBG_SEED_SIZE_BYTES    (DRBG_KEY_SIZE_BYTES + DRBG_IV_SIZE_BYTES)
+typedef union
+{
+    BYTE            bytes[DRBG_KEY_SIZE_BYTES];
+    crypt_uword_t   words[DRBG_KEY_SIZE_WORDS];
+} DRBG_KEY;
+typedef union
+{
+    BYTE            bytes[DRBG_IV_SIZE_BYTES];
+    crypt_uword_t   words[DRBG_IV_SIZE_WORDS];
+} DRBG_IV;
+typedef union
+{
+    BYTE            bytes[DRBG_SEED_SIZE_BYTES];
+    crypt_uword_t   words[DRBG_SEED_SIZE_WORDS];
+} DRBG_SEED;
+#define CTR_DRBG_MAX_REQUESTS_PER_RESEED        ((UINT64)1 << 20)
+#define CTR_DRBG_MAX_BYTES_PER_REQUEST          (1 << 16)
+#   define CTR_DRBG_MIN_ENTROPY_INPUT_LENGTH    DRBG_SEED_SIZE_BYTES
+#   define CTR_DRBG_MAX_ENTROPY_INPUT_LENGTH    DRBG_SEED_SIZE_BYTES
+#   define CTR_DRBG_MAX_ADDITIONAL_INPUT_LENGTH DRBG_SEED_SIZE_BYTES
+#define     TESTING         (1 << 0)
+#define     ENTROPY         (1 << 1)
+#define     TESTED          (1 << 2)
+#define     IsTestStateSet(BIT)    ((g_cryptoSelfTestState.rng & BIT) != 0)
+#define     SetTestStateBit(BIT)   (g_cryptoSelfTestState.rng |= BIT)
+#define     ClearTestStateBit(BIT) (g_cryptoSelfTestState.rng &= ~BIT)
+#define     IsSelfTest()    IsTestStateSet(TESTING)
+#define     SetSelfTest()   SetTestStateBit(TESTING)
+#define     ClearSelfTest() ClearTestStateBit(TESTING)
+#define     IsEntropyBad()      IsTestStateSet(ENTROPY)
+#define     SetEntropyBad()     SetTestStateBit(ENTROPY)
+#define     ClearEntropyBad()   ClearTestStateBit(ENTROPY)
+#define     IsDrbgTested()      IsTestStateSet(TESTED)
+#define     SetDrbgTested()     SetTestStateBit(TESTED)
+#define     ClearDrbgTested()   ClearTestStateBit(TESTED)
+    typedef struct
+    {
+	UINT64      reseedCounter;
+	UINT32      magic;
+	DRBG_SEED   seed; // contains the key and IV for the counter mode DRBG
+	UINT32      lastValue[4];   // used when the TPM does continuous self-test
+	// for FIPS compliance of DRBG
+    } DRBG_STATE, *pDRBG_STATE;
+#define DRBG_MAGIC   ((UINT32) 0x47425244) // "DRBG" backwards so that it displays
+typedef struct KDF_STATE 
+{
+    UINT64               counter;
+    UINT32               magic;
+    UINT32               limit;
+    TPM2B               *seed;
+    const TPM2B         *label;
+    TPM2B               *context;
+    TPM_ALG_ID           hash;
+    TPM_ALG_ID           kdf;
+    UINT16               digestSize;
+    TPM2B_DIGEST         residual;
+} KDF_STATE, *pKDR_STATE;
+#define KDF_MAGIC    ((UINT32) 0x4048444a) // "KDF " backwards
+/* Make sure that any other structures added to this union start with a 64-bit counter and a 32-bit
+   magic number */
+typedef union
+{
+    DRBG_STATE      drbg;
+    KDF_STATE       kdf;
+} RAND_STATE;
+/* This is the state used when the library uses a random number generator. A special function is
+   installed for the library to call. That function picks up the state from this location and uses
+   it for the generation of the random number. */
+extern RAND_STATE           *s_random;
+/* When instrumenting RSA key sieve */
+#if  RSA_INSTRUMENT
+#define PRIME_INDEX(x)  ((x) == 512 ? 0 : (x) == 1024 ? 1 : 2)
+#   define INSTRUMENT_SET(a, b) ((a) = (b))
+#   define INSTRUMENT_ADD(a, b) (a) = (a) + (b)
+#   define INSTRUMENT_INC(a)    (a) = (a) + 1
+extern UINT32  PrimeIndex;
+extern UINT32  failedAtIteration[10];
+extern UINT32  PrimeCounts[3];
+extern UINT32  MillerRabinTrials[3];
+extern UINT32  totalFieldsSieved[3];
+extern UINT32  bitsInFieldAfterSieve[3];
+extern UINT32  emptyFieldsSieved[3];
+extern UINT32  noPrimeFields[3];
+extern UINT32  primesChecked[3];
+extern UINT16  lastSievePrime;
+#else
+#   define INSTRUMENT_SET(a, b)
+#   define INSTRUMENT_ADD(a, b)
+#   define INSTRUMENT_INC(a)
+#endif
+#endif // _CRYPT_RAND_H
+

+ 151 - 0
EVSE/GPL/ibmtpm1682/src/CryptRand_fp.h

@@ -0,0 +1,151 @@
+/********************************************************************************/
+/*										*/
+/*		DRBG with a behavior according to SP800-90A			*/
+/*			     Written by Ken Goldman				*/
+/*		       IBM Thomas J. Watson Research Center			*/
+/*            $Id: CryptRand_fp.h 1476 2019-06-10 19:32:03Z kgoldman $		*/
+/*										*/
+/*  Licenses and Notices							*/
+/*										*/
+/*  1. Copyright Licenses:							*/
+/*										*/
+/*  - Trusted Computing Group (TCG) grants to the user of the source code in	*/
+/*    this specification (the "Source Code") a worldwide, irrevocable, 		*/
+/*    nonexclusive, royalty free, copyright license to reproduce, create 	*/
+/*    derivative works, distribute, display and perform the Source Code and	*/
+/*    derivative works thereof, and to grant others the rights granted herein.	*/
+/*										*/
+/*  - The TCG grants to the user of the other parts of the specification 	*/
+/*    (other than the Source Code) the rights to reproduce, distribute, 	*/
+/*    display, and perform the specification solely for the purpose of 		*/
+/*    developing products based on such documents.				*/
+/*										*/
+/*  2. Source Code Distribution Conditions:					*/
+/*										*/
+/*  - Redistributions of Source Code must retain the above copyright licenses, 	*/
+/*    this list of conditions and the following disclaimers.			*/
+/*										*/
+/*  - Redistributions in binary form must reproduce the above copyright 	*/
+/*    licenses, this list of conditions	and the following disclaimers in the 	*/
+/*    documentation and/or other materials provided with the distribution.	*/
+/*										*/
+/*  3. Disclaimers:								*/
+/*										*/
+/*  - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF	*/
+/*  LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH	*/
+/*  RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES)	*/
+/*  THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE.		*/
+/*  Contact TCG Administration (admin@trustedcomputinggroup.org) for 		*/
+/*  information on specification licensing rights available through TCG 	*/
+/*  membership agreements.							*/
+/*										*/
+/*  - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED 	*/
+/*    WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR 	*/
+/*    FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR 		*/
+/*    NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY 		*/
+/*    OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE.		*/
+/*										*/
+/*  - Without limitation, TCG and its members and licensors disclaim all 	*/
+/*    liability, including liability for infringement of any proprietary 	*/
+/*    rights, relating to use of information in this specification and to the	*/
+/*    implementation of this specification, and TCG disclaims all liability for	*/
+/*    cost of procurement of substitute goods or services, lost profits, loss 	*/
+/*    of use, loss of data or any incidental, consequential, direct, indirect, 	*/
+/*    or special damages, whether under contract, tort, warranty or otherwise, 	*/
+/*    arising in any way out of use or reliance upon this specification or any 	*/
+/*    information herein.							*/
+/*										*/
+/*  (c) Copyright IBM Corp. and others, 2016 - 2019				*/
+/*										*/
+/********************************************************************************/
+
+#ifndef CRYPTRAND_FP_H
+#define CRYPTRAND_FP_H
+
+BOOL
+DRBG_GetEntropy(
+		UINT32           requiredEntropy,   // IN: requested number of bytes of full
+		//     entropy
+		BYTE            *entropy            // OUT: buffer to return collected entropy
+		);
+void
+IncrementIv(
+	    DRBG_IV         *iv
+	    );
+BOOL
+DRBG_Reseed(
+	    DRBG_STATE          *drbgState,         // IN: the state to update
+	    DRBG_SEED           *providedEntropy,   // IN: entropy
+	    DRBG_SEED           *additionalData     // IN:
+	    );
+BOOL
+DRBG_SelfTest(
+	      void
+	      );
+LIB_EXPORT TPM_RC
+CryptRandomStir(
+		UINT16           additionalDataSize,
+		BYTE            *additionalData
+		);
+LIB_EXPORT UINT16
+CryptRandomGenerate(
+		    UINT16           randomSize,
+		    BYTE            *buffer
+		    );
+LIB_EXPORT BOOL
+DRBG_InstantiateSeededKdf(
+			  KDF_STATE       *state,         // IN: buffer to hold the state
+			  TPM_ALG_ID       hashAlg,       // IN: hash algorithm
+			  TPM_ALG_ID       kdf,           // IN: the KDF to use
+			  TPM2B           *seed,          // IN: the seed to use
+			  const TPM2B     *label,         // IN: a label for the generation process.
+			  TPM2B           *context,       // IN: the context value
+			  UINT32           limit          // IN: Maximum number of bits from the KDF
+			  );
+LIB_EXPORT void
+DRBG_AdditionalData(
+		    DRBG_STATE      *drbgState,     // IN:OUT state to update
+		    TPM2B           *additionalData // IN: value to incorporate
+		    );
+LIB_EXPORT TPM_RC
+DRBG_InstantiateSeeded(
+		       DRBG_STATE      *drbgState,     // IN: buffer to hold the state
+		       const TPM2B     *seed,          // IN: the seed to use
+		       const TPM2B     *purpose,       // IN: a label for the generation process.
+		       const TPM2B     *name,          // IN: name of the object
+		       const TPM2B     *additional     // IN: additional data
+		       );
+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

+ 1255 - 0
EVSE/GPL/ibmtpm1682/src/CryptRsa.c

@@ -0,0 +1,1255 @@
+/********************************************************************************/
+/*										*/
+/*		Implementation of cryptographic primitives for RSA		*/
+/*			     Written by Ken Goldman				*/
+/*		       IBM Thomas J. Watson Research Center			*/
+/*            $Id: CryptRsa.c 1658 2021-01-22 23:14:01Z kgoldman $		*/
+/*										*/
+/*  Licenses and Notices							*/
+/*										*/
+/*  1. Copyright Licenses:							*/
+/*										*/
+/*  - Trusted Computing Group (TCG) grants to the user of the source code in	*/
+/*    this specification (the "Source Code") a worldwide, irrevocable, 		*/
+/*    nonexclusive, royalty free, copyright license to reproduce, create 	*/
+/*    derivative works, distribute, display and perform the Source Code and	*/
+/*    derivative works thereof, and to grant others the rights granted herein.	*/
+/*										*/
+/*  - The TCG grants to the user of the other parts of the specification 	*/
+/*    (other than the Source Code) the rights to reproduce, distribute, 	*/
+/*    display, and perform the specification solely for the purpose of 		*/
+/*    developing products based on such documents.				*/
+/*										*/
+/*  2. Source Code Distribution Conditions:					*/
+/*										*/
+/*  - Redistributions of Source Code must retain the above copyright licenses, 	*/
+/*    this list of conditions and the following disclaimers.			*/
+/*										*/
+/*  - Redistributions in binary form must reproduce the above copyright 	*/
+/*    licenses, this list of conditions	and the following disclaimers in the 	*/
+/*    documentation and/or other materials provided with the distribution.	*/
+/*										*/
+/*  3. Disclaimers:								*/
+/*										*/
+/*  - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF	*/
+/*  LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH	*/
+/*  RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES)	*/
+/*  THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE.		*/
+/*  Contact TCG Administration (admin@trustedcomputinggroup.org) for 		*/
+/*  information on specification licensing rights available through TCG 	*/
+/*  membership agreements.							*/
+/*										*/
+/*  - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED 	*/
+/*    WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR 	*/
+/*    FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR 		*/
+/*    NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY 		*/
+/*    OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE.		*/
+/*										*/
+/*  - Without limitation, TCG and its members and licensors disclaim all 	*/
+/*    liability, including liability for infringement of any proprietary 	*/
+/*    rights, relating to use of information in this specification and to the	*/
+/*    implementation of this specification, and TCG disclaims all liability for	*/
+/*    cost of procurement of substitute goods or services, lost profits, loss 	*/
+/*    of use, loss of data or any incidental, consequential, direct, indirect, 	*/
+/*    or special damages, whether under contract, tort, warranty or otherwise, 	*/
+/*    arising in any way out of use or reliance upon this specification or any 	*/
+/*    information herein.							*/
+/*										*/
+/*  (c) Copyright IBM Corp. and others, 2016 - 2021				*/
+/*										*/
+/********************************************************************************/
+
+/* 10.2.17 CryptRsa.c */
+/* 10.2.17.1 Introduction */
+/* This file contains implementation of cryptographic primitives for RSA. Vendors may replace the
+   implementation in this file with their own library functions. */
+/* 10.2.17.2 Includes */
+/* Need this define to get the private defines for this function */
+#define CRYPT_RSA_C
+#include "Tpm.h"
+#if ALG_RSA
+/* 10.2.17.3 Obligatory Initialization Functions */
+/* 10.2.17.3.1 CryptRsaInit() */
+/* Function called at _TPM_Init(). */
+BOOL
+CryptRsaInit(
+	     void
+	     )
+{
+    return TRUE;
+}
+/* 10.2.17.3.2 CryptRsaStartup() */
+/* Function called at TPM2_Startup() */
+BOOL
+CryptRsaStartup(
+		void
+		)
+{
+    return TRUE;
+}
+/* 10.2.17.4 Internal Functions */
+void
+RsaInitializeExponent(
+		      privateExponent_t      *pExp
+		      )
+{
+#if CRT_FORMAT_RSA == NO
+    BN_INIT(pExp->D);
+#else
+    BN_INIT(pExp->Q);
+    BN_INIT(pExp->dP);
+    BN_INIT(pExp->dQ);
+    BN_INIT(pExp->qInv);
+#endif
+}
+/* 10.2.17.4.1 ComputePrivateExponent() */
+/* This function computes the private exponent from the primes. */
+/* Return Value	Meaning */
+/* TRUE(1)	success */
+/* FALSE(0)	failure */
+static BOOL
+ComputePrivateExponent(
+		       bigNum               P,             // IN: first prime (size is 1/2 of bnN)
+		       bigNum               Q,             // IN: second prime (size is 1/2 of bnN)
+		       bigNum               E,             // IN: the public exponent
+		       bigNum               N,             // IN: the public modulus
+		       privateExponent_t   *pExp           // OUT:
+		       )
+{
+    BOOL                pOK;
+    BOOL                qOK;
+#if CRT_FORMAT_RSA == NO
+    BN_RSA(bnPhi);
+    //
+    RsaInitializeExponent(pExp);
+    // Get compute Phi = (p - 1)(q - 1) = pq - p - q + 1 = n - p - q + 1
+    pOK = BnCopy(bnPhi, N);
+    pOK = pOK && BnSub(bnPhi, bnPhi, P);
+    pOK = pOK && BnSub(bnPhi, bnPhi, Q);
+    pOK = pOK && BnAddWord(bnPhi, bnPhi, 1);
+    // Compute the multiplicative inverse d = 1/e mod Phi
+    pOK = pOK && BnModInverse((bigNum)&pExp->D, E, bnPhi);
+    qOK = pOK;
+#else
+    BN_PRIME(temp);
+    bigNum              pT;
+    //
+    NOT_REFERENCED(N);
+    RsaInitializeExponent(pExp);
+    BnCopy((bigNum)&pExp->Q, Q);
+    // make p the larger value so that m2 is always less than p
+    if(BnUnsignedCmp(P, Q) < 0)
+	{
+	    pT = P;
+	    P = Q;
+	    Q = pT;
+	}
+    //dP = (1/e) mod (p-1) = d mod (p-1)
+    pOK = BnSubWord(temp, P, 1);
+    pOK = pOK && BnModInverse((bigNum)&pExp->dP, E, temp);
+    //dQ = (1/e) mod (q-1) = d mod (q-1)
+    qOK = BnSubWord(temp, Q, 1);
+    qOK = qOK && BnModInverse((bigNum)&pExp->dQ, E, temp);
+    // qInv = (1/q) mod p
+    if(pOK && qOK)
+	pOK = qOK = BnModInverse((bigNum)&pExp->qInv, Q, P);
+#endif
+    if(!pOK)
+	BnSetWord(P, 0);
+    if(!qOK)
+	BnSetWord(Q, 0);
+    return pOK && qOK;
+}
+/* 10.2.17.4.2 RsaPrivateKeyOp() */
+/* This function is called to do the exponentiation with the private key. Compile options allow use
+   of the simple (but slow) private exponent, or the more complex but faster CRT method. */
+/* Return Value	Meaning */
+/* TRUE(1)	success */
+/* FALSE(0)	failure */
+static BOOL
+RsaPrivateKeyOp(
+		bigNum               inOut, // IN/OUT: number to be exponentiated
+		bigNum               N,     // IN: public modulus (can be NULL if CRT)
+		bigNum               P,     // IN: one of the primes (can be NULL if not CRT)
+		privateExponent_t   *pExp
+		)
+{
+    BOOL                 OK;
+#if CRT_FORMAT_RSA == NO
+    (P);
+    OK = BnModExp(inOut, inOut, (bigNum)&pExp->D, N);
+#else
+    BN_RSA(M1);
+    BN_RSA(M2);
+    BN_RSA(M);
+    BN_RSA(H);
+    bigNum              Q = (bigNum)&pExp->Q;
+    NOT_REFERENCED(N);
+    // Make P the larger prime.
+    // NOTE that when the CRT form of the private key is created, dP will always
+    // be computed using the larger of p and q so the only thing needed here is that
+    // the primes be selected so that they agree with dP.
+    if(BnUnsignedCmp(P, Q) < 0)
+	{
+	    bigNum      T = P;
+	    P = Q;
+	    Q = T;
+	}
+    // m1 = cdP mod p
+    OK = BnModExp(M1, inOut, (bigNum)&pExp->dP, P);
+    // m2 = cdQ mod q
+    OK = OK && BnModExp(M2, inOut, (bigNum)&pExp->dQ, Q);
+    // h = qInv * (m1 - m2) mod p = qInv * (m1 + P - m2) mod P because Q < P
+    // so m2 < P
+    OK = OK && BnSub(H, P, M2);
+    OK = OK && BnAdd(H, H, M1);
+    OK = OK && BnModMult(H, H, (bigNum)&pExp->qInv, P);
+    // m = m2 + h * q
+    OK = OK && BnMult(M, H, Q);
+    OK = OK && BnAdd(inOut, M2, M);
+#endif
+    return OK;
+}
+/* 10.2.17.4.3 RSAEP() */
+/* This function performs the RSAEP operation defined in PKCS#1v2.1. It is an exponentiation of a
+   value (m) with the public exponent (e), modulo the public (n). */
+/* Error Returns Meaning */
+/* TPM_RC_VALUE number to exponentiate is larger than the modulus */
+static TPM_RC
+RSAEP(
+      TPM2B       *dInOut,        // IN: size of the encrypted block and the size of
+      //     the encrypted value. It must be the size of
+      //     the modulus.
+      // OUT: the encrypted data. Will receive the
+      //      decrypted value
+      OBJECT      *key            // IN: the key to use
+      )
+{
+    TPM2B_TYPE(4BYTES, 4);
+    TPM2B_4BYTES(e) = {{4, {(BYTE)((RSA_DEFAULT_PUBLIC_EXPONENT >> 24) & 0xff),
+			    (BYTE)((RSA_DEFAULT_PUBLIC_EXPONENT >> 16) & 0xff),
+			    (BYTE)((RSA_DEFAULT_PUBLIC_EXPONENT >> 8) & 0xff),
+			    (BYTE)((RSA_DEFAULT_PUBLIC_EXPONENT)& 0xff)}}};
+    //
+    if(key->publicArea.parameters.rsaDetail.exponent != 0)
+	UINT32_TO_BYTE_ARRAY(key->publicArea.parameters.rsaDetail.exponent,
+			     e.t.buffer);
+    return ModExpB(dInOut->size, dInOut->buffer, dInOut->size, dInOut->buffer,
+		   e.t.size, e.t.buffer, key->publicArea.unique.rsa.t.size,
+		   key->publicArea.unique.rsa.t.buffer);
+}
+/* 10.2.17.4.4 RSADP() */
+/* This function performs the RSADP operation defined in PKCS#1v2.1. It is an exponentiation of a
+   value (c) with the private exponent (d), modulo the public modulus (n). The decryption is in
+   place. */
+/* This function also checks the size of the private key. If the size indicates that only a prime
+   value is present, the key is converted to being a private exponent. */
+/* Error Returns Meaning */
+/* TPM_RC_SIZE the value to decrypt is larger than the modulus */
+static TPM_RC
+RSADP(
+      TPM2B           *inOut,        // IN/OUT: the value to encrypt
+      OBJECT          *key           // IN: the key
+      )
+{
+    BN_RSA_INITIALIZED(bnM, inOut);
+    BN_RSA_INITIALIZED(bnN, &key->publicArea.unique.rsa);
+    BN_RSA_INITIALIZED(bnP, &key->sensitive.sensitive.rsa);
+    if(BnUnsignedCmp(bnM, bnN) >= 0)
+	return TPM_RC_SIZE;
+    // private key operation requires that private exponent be loaded
+    // During self-test, this might not be the case so load it up if it hasn't
+    // already done
+    // been done
+    if(!key->attributes.privateExp)
+	CryptRsaLoadPrivateExponent(key);
+    if(!RsaPrivateKeyOp(bnM, bnN, bnP, &key->privateExponent))
+	FAIL(FATAL_ERROR_INTERNAL);
+    BnTo2B(bnM, inOut, inOut->size);
+    return TPM_RC_SUCCESS;
+}
+/* 10.2.17.4.5 OaepEncode() */
+/* This function performs OAEP padding. The size of the buffer to receive the OAEP padded data must
+   equal the size of the modulus */
+/* Error Returns Meaning */
+/* TPM_RC_VALUE hashAlg is not valid or message size is too large */
+static TPM_RC
+OaepEncode(
+	   TPM2B       *padded,        // OUT: the pad data
+	   TPM_ALG_ID   hashAlg,       // IN: algorithm to use for padding
+	   const TPM2B *label,         // IN: null-terminated string (may be NULL)
+	   TPM2B       *message,       // IN: the message being padded
+	   RAND_STATE  *rand           // IN: the random number generator to use
+	   )
+{
+    INT32        padLen;
+    INT32        dbSize;
+    INT32        i;
+    BYTE         mySeed[MAX_DIGEST_SIZE];
+    BYTE        *seed = mySeed;
+    UINT16       hLen = CryptHashGetDigestSize(hashAlg);
+    BYTE         mask[MAX_RSA_KEY_BYTES];
+    BYTE        *pp;
+    BYTE        *pm;
+    TPM_RC       retVal = TPM_RC_SUCCESS;
+    pAssert(padded != NULL && message != NULL);
+    // A value of zero is not allowed because the KDF can't produce a result
+    // if the digest size is zero.
+    if(hLen == 0)
+	return TPM_RC_VALUE;
+    // Basic size checks
+    //  make sure digest isn't too big for key size
+    if(padded->size < (2 * hLen) + 2)
+	ERROR_RETURN(TPM_RC_HASH);
+    // and that message will fit messageSize <= k - 2hLen - 2
+    if(message->size > (padded->size - (2 * hLen) - 2))
+	ERROR_RETURN(TPM_RC_VALUE);
+    // Hash L even if it is null
+    // Offset into padded leaving room for masked seed and byte of zero
+    pp = &padded->buffer[hLen + 1];
+    if(CryptHashBlock(hashAlg, label->size, (BYTE *)label->buffer,
+		      hLen, pp) != hLen)
+	ERROR_RETURN(TPM_RC_FAILURE);
+    // concatenate PS of k  mLen  2hLen  2
+    padLen = padded->size - message->size - (2 * hLen) - 2;
+    MemorySet(&pp[hLen], 0, padLen);
+    pp[hLen + padLen] = 0x01;
+    padLen += 1;
+    memcpy(&pp[hLen + padLen], message->buffer, message->size);
+    // The total size of db = hLen + pad + mSize;
+    dbSize = hLen + padLen + message->size;
+    // If testing, then use the provided seed. Otherwise, use values
+    // from the RNG
+    CryptRandomGenerate(hLen, mySeed);
+    DRBG_Generate(rand, mySeed, (UINT16)hLen);
+    // mask = MGF1 (seed, nSize  hLen  1)
+    CryptMGF_KDF(dbSize, mask, hashAlg, hLen, seed, 0);
+    // Create the masked db
+    pm = mask;
+    for(i = dbSize; i > 0; i--)
+	*pp++ ^= *pm++;
+    pp = &padded->buffer[hLen + 1];
+    // Run the masked data through MGF1
+    if(CryptMGF_KDF(hLen, &padded->buffer[1], hashAlg, dbSize, pp, 0) != (unsigned)hLen)
+	ERROR_RETURN(TPM_RC_VALUE);
+    // Now XOR the seed to create masked seed
+    pp = &padded->buffer[1];
+    pm = seed;
+    for(i = hLen; i > 0; i--)
+	*pp++ ^= *pm++;
+    // Set the first byte to zero
+    padded->buffer[0] = 0x00;
+ Exit:
+    return retVal;
+}
+/* 10.2.17.4.6 OaepDecode() */
+/* This function performs OAEP padding checking. The size of the buffer to receive the recovered
+   data. If the padding is not valid, the dSize size is set to zero and the function returns
+   TPM_RC_VALUE. */
+/* The dSize parameter is used as an input to indicate the size available in the buffer. If
+   insufficient space is available, the size is not changed and the return code is TPM_RC_VALUE. */
+/* Error Returns Meaning */
+/* TPM_RC_VALUE the value to decode was larger than the modulus, or the padding is wrong or the
+   buffer to receive the results is too small */
+static TPM_RC
+OaepDecode(
+	   TPM2B           *dataOut,       // OUT: the recovered data
+	   TPM_ALG_ID       hashAlg,       // IN: algorithm to use for padding
+	   const TPM2B     *label,         // IN: null-terminated string (may be NULL)
+	   TPM2B           *padded         // IN: the padded data
+	   )
+{
+    UINT32       i;
+    BYTE         seedMask[MAX_DIGEST_SIZE];
+    UINT32       hLen = CryptHashGetDigestSize(hashAlg);
+    BYTE         mask[MAX_RSA_KEY_BYTES];
+    BYTE        *pp;
+    BYTE        *pm;
+    TPM_RC       retVal = TPM_RC_SUCCESS;
+    // Strange size (anything smaller can't be an OAEP padded block)
+    // Also check for no leading 0
+    if((padded->size < (unsigned)((2 * hLen) + 2)) || (padded->buffer[0] != 0))
+	ERROR_RETURN(TPM_RC_VALUE);
+    // Use the hash size to determine what to put through MGF1 in order
+    // to recover the seedMask
+    CryptMGF_KDF(hLen, seedMask, hashAlg, padded->size - hLen - 1,
+		 &padded->buffer[hLen + 1], 0);
+    // Recover the seed into seedMask
+    pAssert(hLen <= sizeof(seedMask));
+    pp = &padded->buffer[1];
+    pm = seedMask;
+    for(i = hLen; i > 0; i--)
+	*pm++ ^= *pp++;
+    // Use the seed to generate the data mask
+    CryptMGF_KDF(padded->size - hLen - 1, mask, hashAlg, hLen, seedMask, 0);
+    // Use the mask generated from seed to recover the padded data
+    pp = &padded->buffer[hLen + 1];
+    pm = mask;
+    for(i = (padded->size - hLen - 1); i > 0; i--)
+	*pm++ ^= *pp++;
+    // Make sure that the recovered data has the hash of the label
+    // Put trial value in the seed mask
+    if((CryptHashBlock(hashAlg, label->size, (BYTE *)label->buffer,
+		       hLen, seedMask)) != hLen)
+	FAIL(FATAL_ERROR_INTERNAL);
+    if(memcmp(seedMask, mask, hLen) != 0)
+	ERROR_RETURN(TPM_RC_VALUE);
+    // find the start of the data
+    pm = &mask[hLen];
+    for(i = (UINT32)padded->size - (2 * hLen) - 1; i > 0; i--)
+	{
+	    if(*pm++ != 0)
+		break;
+	}
+    // If we ran out of data or didn't end with 0x01, then return an error
+    if(i == 0 || pm[-1] != 0x01)
+	ERROR_RETURN(TPM_RC_VALUE);
+    // pm should be pointing at the first part of the data
+    // and i is one greater than the number of bytes to move
+    i--;
+    if(i > dataOut->size)
+	// Special exit to preserve the size of the output buffer
+	return TPM_RC_VALUE;
+    memcpy(dataOut->buffer, pm, i);
+    dataOut->size = (UINT16)i;
+ Exit:
+    if(retVal != TPM_RC_SUCCESS)
+	dataOut->size = 0;
+    return retVal;
+}
+/* 10.2.17.4.7 PKCS1v1_5Encode() */
+/* This function performs the encoding for RSAES-PKCS1-V1_5-ENCRYPT as defined in PKCS#1V2.1 */
+/* Error Returns Meaning */
+/* TPM_RC_VALUE message size is too large */
+static TPM_RC
+RSAES_PKCS1v1_5Encode(
+		      TPM2B       *padded,        // OUT: the pad data
+		      TPM2B       *message,       // IN: the message being padded
+		      RAND_STATE  *rand
+		      )
+{
+    UINT32      ps = padded->size - message->size - 3;
+    //
+    if(message->size > padded->size - 11)
+	return TPM_RC_VALUE;
+    // move the message to the end of the buffer
+    memcpy(&padded->buffer[padded->size - message->size], message->buffer,
+	   message->size);
+    // Set the first byte to 0x00 and the second to 0x02
+    padded->buffer[0] = 0;
+    padded->buffer[1] = 2;
+    // Fill with random bytes
+    DRBG_Generate(rand, &padded->buffer[2], (UINT16)ps);
+    // Set the delimiter for the random field to 0
+    padded->buffer[2 + ps] = 0;
+    // Now, the only messy part. Make sure that all the 'ps' bytes are non-zero
+    // In this implementation, use the value of the current index
+    for(ps++; ps > 1; ps--)
+	{
+	    if(padded->buffer[ps] == 0)
+		padded->buffer[ps] = 0x55;  // In the < 0.5% of the cases that the
+	    // random value is 0, just pick a value to
+	    // put into the spot.
+	}
+    return TPM_RC_SUCCESS;
+}
+/* 10.2.17.4.8 RSAES_Decode() */
+/* This function performs the decoding for RSAES-PKCS1-V1_5-ENCRYPT as defined in PKCS#1V2.1 */
+/* Error Returns Meaning */
+/* TPM_RC_FAIL decoding error or results would no fit into provided buffer */
+static TPM_RC
+RSAES_Decode(
+	     TPM2B       *message,       // OUT: the recovered message
+	     TPM2B       *coded          // IN: the encoded message
+	     )
+{
+    BOOL        fail = FALSE;
+    UINT16      pSize;
+    fail = (coded->size < 11);
+    fail = (coded->buffer[0] != 0x00) | fail;
+    fail = (coded->buffer[1] != 0x02) | fail;
+    for(pSize = 2; pSize < coded->size; pSize++)
+	{
+	    if(coded->buffer[pSize] == 0)
+		break;
+	}
+    pSize++;
+    // Make sure that pSize has not gone over the end and that there are at least 8
+    // bytes of pad data.
+    fail = (pSize > coded->size) | fail;
+    fail = ((pSize - 2) <= 8) | fail;
+    if((message->size < (UINT16)(coded->size - pSize)) || fail)
+	return TPM_RC_VALUE;
+    message->size = coded->size - pSize;
+    memcpy(message->buffer, &coded->buffer[pSize], coded->size - pSize);
+    return TPM_RC_SUCCESS;
+}
+/* 10.2.17.4.13	CryptRsaPssSaltSize() */
+/* This function computes the salt size used in PSS. It is broken out so that the X509 code can get
+   the same value that is used by the encoding function in this module. */
+INT16
+CryptRsaPssSaltSize(
+    INT16              hashSize,
+    INT16               outSize
+)
+{
+    INT16               saltSize;
+    //
+    // (Mask Length) = (outSize - hashSize - 1);
+    // Max saltSize is (Mask Length) - 1
+    saltSize = (outSize - hashSize - 1) - 1;
+    // Use the maximum salt size allowed by FIPS 186-4
+    if (saltSize > hashSize)
+	saltSize = hashSize;
+    else if (saltSize < 0)
+	saltSize = 0;
+    return saltSize;
+}
+
+/* 10.2.17.4.9 PssEncode() */
+/* This function creates an encoded block of data that is the size of modulus. The function uses the
+   maximum salt size that will fit in the encoded block. */
+/* Returns TPM_RC_SUCCESS or goes into failure mode. */
+static TPM_RC
+PssEncode(
+	  TPM2B           *out,       // OUT: the encoded buffer
+	  TPM_ALG_ID       hashAlg,   // IN: hash algorithm for the encoding
+	  TPM2B           *digest,    // IN: the digest
+	  RAND_STATE      *rand       // IN: random number source
+	  )
+{
+    UINT32               hLen = CryptHashGetDigestSize(hashAlg);
+    BYTE                 salt[MAX_RSA_KEY_BYTES - 1];
+    UINT16               saltSize;
+    BYTE                *ps = salt;
+    BYTE                *pOut;
+    UINT16               mLen;
+    HASH_STATE           hashState;
+    // These are fatal errors indicating bad TPM firmware
+    pAssert(out != NULL && hLen > 0 && digest != NULL);
+    // Get the size of the mask
+    mLen = (UINT16)(out->size - hLen - 1);
+    // Maximum possible salt size is mask length - 1
+    saltSize = mLen - 1;
+    // Use the maximum salt size allowed by FIPS 186-4
+    if(saltSize > hLen)
+	saltSize = (UINT16)hLen;
+    //using eOut for scratch space
+    // Set the first 8 bytes to zero
+    pOut = out->buffer;
+    memset(pOut, 0, 8);
+    // Get set the salt
+    DRBG_Generate(rand, salt, saltSize);
+    // Create the hash of the pad || input hash || salt
+    CryptHashStart(&hashState, hashAlg);
+    CryptDigestUpdate(&hashState, 8, pOut);
+    CryptDigestUpdate2B(&hashState, digest);
+    CryptDigestUpdate(&hashState, saltSize, salt);
+    CryptHashEnd(&hashState, hLen, &pOut[out->size - hLen - 1]);
+    // Create a mask
+    if(CryptMGF_KDF(mLen, pOut, hashAlg, hLen, &pOut[mLen], 0) != mLen)
+	FAIL(FATAL_ERROR_INTERNAL);
+    // Since this implementation uses key sizes that are all even multiples of
+    // 8, just need to make sure that the most significant bit is CLEAR
+    *pOut &= 0x7f;
+    // Before we mess up the pOut value, set the last byte to 0xbc
+    pOut[out->size - 1] = 0xbc;
+    // XOR a byte of 0x01 at the position just before where the salt will be XOR'ed
+    pOut = &pOut[mLen - saltSize - 1];
+    *pOut++ ^= 0x01;
+    // XOR the salt data into the buffer
+    for(; saltSize > 0; saltSize--)
+	*pOut++ ^= *ps++;
+    // and we are done
+    return TPM_RC_SUCCESS;
+}
+/* 10.2.17.4.10 PssDecode() */
+/* This function checks that the PSS encoded block was built from the provided digest. If the check
+   is successful, TPM_RC_SUCCESS is returned. Any other value indicates an error. */
+/* This implementation of PSS decoding is intended for the reference TPM implementation and is not
+   at all generalized.  It is used to check signatures over hashes and assumptions are made about
+   the sizes of values. Those assumptions are enforce by this implementation. This implementation
+   does allow for a variable size salt value to have been used by the creator of the signature. */
+/* Error Returns Meaning */
+/* TPM_RC_SCHEME hashAlg is not a supported hash algorithm */
+/* TPM_RC_VALUE decode operation failed */
+static TPM_RC
+PssDecode(
+	  TPM_ALG_ID   hashAlg,        // IN: hash algorithm to use for the encoding
+	  TPM2B       *dIn,            // In: the digest to compare
+	  TPM2B       *eIn             // IN: the encoded data
+	  )
+{
+    UINT32           hLen = CryptHashGetDigestSize(hashAlg);
+    BYTE             mask[MAX_RSA_KEY_BYTES];
+    BYTE            *pm = mask;
+    BYTE            *pe;
+    BYTE             pad[8] = {0};
+    UINT32           i;
+    UINT32           mLen;
+    BYTE             fail;
+    TPM_RC           retVal = TPM_RC_SUCCESS;
+    HASH_STATE       hashState;
+    // These errors are indicative of failures due to programmer error
+    pAssert(dIn != NULL && eIn != NULL);
+    pe = eIn->buffer;
+    // check the hash scheme
+    if(hLen == 0)
+	ERROR_RETURN(TPM_RC_SCHEME);
+    // most significant bit must be zero
+    fail = pe[0] & 0x80;
+    // last byte must be 0xbc
+    fail |= pe[eIn->size - 1] ^ 0xbc;
+    // Use the hLen bytes at the end of the buffer to generate a mask
+    // Doesn't start at the end which is a flag byte
+    mLen = eIn->size - hLen - 1;
+    CryptMGF_KDF(mLen, mask, hashAlg, hLen, &pe[mLen], 0);
+    // Clear the MSO of the mask to make it consistent with the encoding.
+    mask[0] &= 0x7F;
+    pAssert(mLen <= sizeof(mask));
+    // XOR the data into the mask to recover the salt. This sequence
+    // advances eIn so that it will end up pointing to the seed data
+    // which is the hash of the signature data
+    for(i = mLen; i > 0; i--)
+	*pm++ ^= *pe++;
+    // Find the first byte of 0x01 after a string of all 0x00
+    for(pm = mask, i = mLen; i > 0; i--)
+	{
+	    if(*pm == 0x01)
+		break;
+	    else
+		fail |= *pm++;
+	}
+    // i should not be zero
+    fail |= (i == 0);
+    // if we have failed, will continue using the entire mask as the salt value so
+    // that the timing attacks will not disclose anything (I don't think that this
+    // is a problem for TPM applications but, usually, we don't fail so this
+    // doesn't cost anything).
+    if(fail)
+	{
+	    i = mLen;
+	    pm = mask;
+	}
+    else
+	{
+	    pm++;
+	    i--;
+	}
+    // i contains the salt size and pm points to the salt. Going to use the input
+    // hash and the seed to recreate the hash in the lower portion of eIn.
+    CryptHashStart(&hashState, hashAlg);
+    // add the pad of 8 zeros
+    CryptDigestUpdate(&hashState, 8, pad);
+    // add the provided digest value
+    CryptDigestUpdate(&hashState, dIn->size, dIn->buffer);
+    // and the salt
+    CryptDigestUpdate(&hashState, i, pm);
+    // get the result
+    fail |= (CryptHashEnd(&hashState, hLen, mask) != hLen);
+    // Compare all bytes
+    for(pm = mask; hLen > 0; hLen--)
+	// don't use fail = because that could skip the increment and compare
+	// operations after the first failure and that gives away timing
+	// information.
+	fail |= *pm++ ^ *pe++;
+    retVal = (fail != 0) ? TPM_RC_VALUE : TPM_RC_SUCCESS;
+ Exit:
+    return retVal;
+}
+/* 10.2.17.4.16	MakeDerTag() */
+/* Construct the DER value that is used in RSASSA */
+/* Return Value	Meaning */
+/* > 0	size of value */
+/* <= 0	no hash exists */
+INT16
+MakeDerTag(
+	   TPM_ALG_ID   hashAlg,
+	   INT16        sizeOfBuffer,
+	   BYTE        *buffer
+	   )
+{
+    //    0x30, 0x31,       // SEQUENCE (2 elements) 1st
+    //        0x30, 0x0D,   // SEQUENCE (2 elements)
+    //            0x06, 0x09,   // HASH OID
+    //                0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01,
+    //             0x05, 0x00,  // NULL
+    //        0x04, 0x20  //  OCTET STRING
+    HASH_DEF   *info = CryptGetHashDef(hashAlg);
+    INT16       oidSize;
+    // If no OID, can't do encode
+    VERIFY(info != NULL);
+    oidSize = 2 + (info->OID)[1];
+    // make sure this fits in the buffer
+    VERIFY(sizeOfBuffer >= (oidSize + 8));
+    *buffer++ = 0x30;  // 1st SEQUENCE
+    // Size of the 1st SEQUENCE is 6 bytes + size of the hash OID + size of the
+    // digest size
+    *buffer++ = (BYTE)(6 + oidSize + info->digestSize);   //
+    *buffer++ = 0x30; // 2nd SEQUENCE
+    // size is 4 bytes of overhead plus the side of the OID
+    *buffer++ = (BYTE)(2 + oidSize);
+    MemoryCopy(buffer, info->OID, oidSize);
+    buffer += oidSize;
+    *buffer++ = 0x05;   // Add a NULL
+    *buffer++ = 0x00;
+    
+    *buffer++ = 0x04;
+    *buffer++ = (BYTE)(info->digestSize);
+    return oidSize + 8;
+ Error:
+    return 0;
+    
+}
+
+/* 10.2.17.4.17	RSASSA_Encode() */
+/* Encode a message using PKCS1v1.5 method. */
+/* Error Returns	Meaning */
+/* TPM_RC_SCHEME	hashAlg is not a supported hash algorithm */
+/* TPM_RC_SIZE	eOutSize is not large enough */
+/* TPM_RC_VALUE	hInSize does not match the digest size of hashAlg */
+static TPM_RC
+RSASSA_Encode(
+	      TPM2B               *pOut,      // IN:OUT on in, the size of the public key
+	      //        on out, the encoded area
+	      TPM_ALG_ID           hashAlg,   // IN: hash algorithm for PKCS1v1_5
+	      TPM2B               *hIn        // IN: digest value to encode
+	      )
+{
+    BYTE             DER[20];
+    BYTE            *der = DER;
+    INT32            derSize = MakeDerTag(hashAlg, sizeof(DER), DER);
+    BYTE            *eOut;
+    INT32            fillSize;
+    TPM_RC           retVal = TPM_RC_SUCCESS;
+    
+    // Can't use this scheme if the algorithm doesn't have a DER string defined.
+    if(derSize == 0)
+	ERROR_RETURN(TPM_RC_SCHEME);
+    
+    // If the digest size of 'hashAl' doesn't match the input digest size, then
+    // the DER will misidentify the digest so return an error
+    if(CryptHashGetDigestSize(hashAlg) != hIn->size)
+	ERROR_RETURN(TPM_RC_VALUE);
+    fillSize = pOut->size - derSize - hIn->size - 3;
+    eOut = pOut->buffer;
+    
+    // Make sure that this combination will fit in the provided space
+    if(fillSize < 8)
+	ERROR_RETURN(TPM_RC_SIZE);
+    
+    // Start filling
+    *eOut++ = 0; // initial byte of zero
+    *eOut++ = 1; // byte of 0x01
+    for(; fillSize > 0; fillSize--)
+	*eOut++ = 0xff; // bunch of 0xff
+    *eOut++ = 0; // another 0
+    for(; derSize > 0; derSize--)
+	*eOut++ = *der++;   // copy the DER
+    der = hIn->buffer;
+    for(fillSize = hIn->size; fillSize > 0; fillSize--)
+	*eOut++ = *der++;   // copy the hash
+ Exit:
+    return retVal;
+}
+
+/* 10.2.17.4.18	RSASSA_Decode() */
+/* This function performs the RSASSA decoding of a signature. */
+/* Error Returns	Meaning */
+/* TPM_RC_VALUE	decode unsuccessful */
+/* TPM_RC_SCHEME	haslAlg is not supported */
+static TPM_RC
+RSASSA_Decode(
+	      TPM_ALG_ID       hashAlg,        // IN: hash algorithm to use for the encoding
+	      TPM2B           *hIn,            // In: the digest to compare
+	      TPM2B           *eIn             // IN: the encoded data
+	      )
+{
+    BYTE             fail;
+    BYTE             DER[20];
+    BYTE            *der = DER;
+    INT32            derSize = MakeDerTag(hashAlg, sizeof(DER), DER);
+    BYTE            *pe;
+    INT32            hashSize = CryptHashGetDigestSize(hashAlg);
+    INT32            fillSize;
+    TPM_RC           retVal;
+    BYTE            *digest;
+    UINT16           digestSize;
+    
+    pAssert(hIn != NULL && eIn != NULL);
+    pe = eIn->buffer;
+    
+    // Can't use this scheme if the algorithm doesn't have a DER string
+    // defined or if the provided hash isn't the right size
+    if(derSize == 0 || (unsigned)hashSize != hIn->size)
+	ERROR_RETURN(TPM_RC_SCHEME);
+    
+    // Make sure that this combination will fit in the provided space
+    // Since no data movement takes place, can just walk though this
+    // and accept nearly random values. This can only be called from
+    // CryptValidateSignature() so eInSize is known to be in range.
+    fillSize = eIn->size - derSize - hashSize - 3;
+    
+    // Start checking (fail will become non-zero if any of the bytes do not have
+    // the expected value.
+    fail = *pe++;                   // initial byte of zero
+    fail |= *pe++ ^ 1;              // byte of 0x01
+    for(; fillSize > 0; fillSize--)
+	fail |= *pe++ ^ 0xff;       // bunch of 0xff
+    fail |= *pe++;                  // another 0
+    for(; derSize > 0; derSize--)
+	fail |= *pe++ ^ *der++;    // match the DER
+    digestSize = hIn->size;
+    digest = hIn->buffer;
+    for(; digestSize > 0; digestSize--)
+	fail |= *pe++ ^ *digest++; // match the hash
+    retVal = (fail != 0) ? TPM_RC_VALUE : TPM_RC_SUCCESS;
+ Exit:
+    return retVal;
+}
+
+/* 10.2.17.4.13 CryptRsaSelectScheme() */
+/* This function is used by TPM2_RSA_Decrypt() and TPM2_RSA_Encrypt().  It sets up the rules to
+   select a scheme between input and object default. This function assume the RSA object is
+   loaded. If a default scheme is defined in object, the default scheme should be chosen, otherwise,
+   the input scheme should be chosen. In the case that both the object and scheme are not
+   TPM_ALG_NULL, then if the schemes are the same, the input scheme will be chosen. if the scheme
+   are not compatible, a NULL pointer will be returned. */
+/* The return pointer may point to a TPM_ALG_NULL scheme. */
+TPMT_RSA_DECRYPT*
+CryptRsaSelectScheme(
+		     TPMI_DH_OBJECT       rsaHandle,     // IN: handle of an RSA key
+		     TPMT_RSA_DECRYPT    *scheme         // IN: a sign or decrypt scheme
+		     )
+{
+    OBJECT              *rsaObject;
+    TPMT_ASYM_SCHEME    *keyScheme;
+    TPMT_RSA_DECRYPT    *retVal = NULL;
+    // Get sign object pointer
+    rsaObject = HandleToObject(rsaHandle);
+    keyScheme = &rsaObject->publicArea.parameters.asymDetail.scheme;
+    // if the default scheme of the object is TPM_ALG_NULL, then select the
+    // input scheme
+    if(keyScheme->scheme == TPM_ALG_NULL)
+	{
+	    retVal = scheme;
+	}
+    // if the object scheme is not TPM_ALG_NULL and the input scheme is
+    // TPM_ALG_NULL, then select the default scheme of the object.
+    else if(scheme->scheme == TPM_ALG_NULL)
+	{
+	    // if input scheme is NULL
+	    retVal = (TPMT_RSA_DECRYPT *)keyScheme;
+	}
+    // get here if both the object scheme and the input scheme are
+    // not TPM_ALG_NULL. Need to insure that they are the same.
+    // IMPLEMENTATION NOTE: This could cause problems if future versions have
+    // schemes that have more values than just a hash algorithm. A new function
+    // (IsSchemeSame()) might be needed then.
+    else if(keyScheme->scheme == scheme->scheme
+	    && keyScheme->details.anySig.hashAlg == scheme->details.anySig.hashAlg)
+	{
+	    retVal = scheme;
+	}
+    // two different, incompatible schemes specified will return NULL
+    return retVal;
+}
+/* 10.2.17.4.14 CryptRsaLoadPrivateExponent() */
+/* Error Returns Meaning */
+/* TPM_RC_BINDING public and private parts of rsaKey are not matched */
+TPM_RC
+CryptRsaLoadPrivateExponent(
+			    OBJECT          *rsaKey        // IN: the RSA key object
+			    )
+{
+    BN_RSA_INITIALIZED(bnN, &rsaKey->publicArea.unique.rsa);
+    BN_PRIME_INITIALIZED(bnP, &rsaKey->sensitive.sensitive.rsa);
+    BN_RSA(bnQ);
+    BN_PRIME(bnQr);
+    BN_WORD_INITIALIZED(bnE, (rsaKey->publicArea.parameters.rsaDetail.exponent == 0)
+			? RSA_DEFAULT_PUBLIC_EXPONENT
+			: rsaKey->publicArea.parameters.rsaDetail.exponent);
+    TPM_RC          retVal = TPM_RC_SUCCESS;
+    if(!rsaKey->attributes.privateExp)
+	{
+	    TEST(TPM_ALG_NULL);
+	    // Make sure that the bigNum used for the exponent is properly initialized
+	    RsaInitializeExponent(&rsaKey->privateExponent);
+	    // Find the second prime by division
+	    BnDiv(bnQ, bnQr, bnN, bnP);
+	    if(!BnEqualZero(bnQr))
+		ERROR_RETURN(TPM_RC_BINDING);
+	    // Compute the private exponent and return it if found
+	    if(!ComputePrivateExponent(bnP, bnQ, bnE, bnN,
+				       &rsaKey->privateExponent))
+		ERROR_RETURN(TPM_RC_BINDING);
+	}
+ Exit:
+    rsaKey->attributes.privateExp = (retVal == TPM_RC_SUCCESS);
+    return retVal;
+}
+/* 10.2.17.4.15 CryptRsaEncrypt() */
+/* This is the entry point for encryption using RSA. Encryption is use of the public exponent. The
+   padding parameter determines what padding will be used. */
+/* The cOutSize parameter must be at least as large as the size of the key. */
+/* If the padding is RSA_PAD_NONE, dIn is treated as a number. It must be lower in value than the
+   key modulus. */
+/* NOTE: If dIn has fewer bytes than cOut, then we don't add low-order zeros to dIn to make it the
+   size of the RSA key for the call to RSAEP. This is because the high order bytes of dIn might have
+   a numeric value that is greater than the value of the key modulus. If this had low-order zeros
+   added, it would have a numeric value larger than the modulus even though it started out with a
+   lower numeric value. */
+/* Error Returns Meaning */
+/* TPM_RC_VALUE cOutSize is too small (must be the size of the modulus) */
+/* TPM_RC_SCHEME padType is not a supported scheme */
+LIB_EXPORT TPM_RC
+CryptRsaEncrypt(
+		TPM2B_PUBLIC_KEY_RSA        *cOut,          // OUT: the encrypted data
+		TPM2B                       *dIn,           // IN: the data to encrypt
+		OBJECT                      *key,           // IN: the key used for encryption
+		TPMT_RSA_DECRYPT            *scheme,        // IN: the type of padding and hash
+		//     if needed
+		const TPM2B                 *label,         // IN: in case it is needed
+		RAND_STATE                  *rand           // IN: random number generator
+		//     state (mostly for testing)
+		)
+{
+    TPM_RC                       retVal = TPM_RC_SUCCESS;
+    TPM2B_PUBLIC_KEY_RSA         dataIn;
+    //
+    // if the input and output buffers are the same, copy the input to a scratch
+    // buffer so that things don't get messed up.
+    if(dIn == &cOut->b)
+	{
+	    MemoryCopy2B(&dataIn.b, dIn, sizeof(dataIn.t.buffer));
+	    dIn = &dataIn.b;
+	}
+    // All encryption schemes return the same size of data
+    cOut->t.size = key->publicArea.unique.rsa.t.size;
+    TEST(scheme->scheme);
+    switch(scheme->scheme)
+	{
+	  case TPM_ALG_NULL:  // 'raw' encryption
+	      {
+		  INT32            i;
+		  INT32            dSize = dIn->size;
+		  // dIn can have more bytes than cOut as long as the extra bytes
+		  // are zero. Note: the more significant bytes of a number in a byte
+		  // buffer are the bytes at the start of the array.
+		  for(i = 0; (i < dSize) && (dIn->buffer[i] == 0); i++);
+		  dSize -= i;
+		  if(dSize > cOut->t.size)
+		      ERROR_RETURN(TPM_RC_VALUE);
+		  // Pad cOut with zeros if dIn is smaller
+		  memset(cOut->t.buffer, 0, cOut->t.size - dSize);
+		  // And copy the rest of the value
+		  memcpy(&cOut->t.buffer[cOut->t.size - dSize], &dIn->buffer[i], dSize);
+		  // If the size of dIn is the same as cOut dIn could be larger than
+		  // the modulus. If it is, then RSAEP() will catch it.
+	      }
+	      break;
+	  case TPM_ALG_RSAES:
+	    retVal = RSAES_PKCS1v1_5Encode(&cOut->b, dIn, rand);
+	    break;
+	  case TPM_ALG_OAEP:
+	    retVal = OaepEncode(&cOut->b, scheme->details.oaep.hashAlg, label, dIn,
+				rand);
+	    break;
+	  default:
+	    ERROR_RETURN(TPM_RC_SCHEME);
+	    break;
+	}
+    // All the schemes that do padding will come here for the encryption step
+    // Check that the Encoding worked
+    if(retVal == TPM_RC_SUCCESS)
+	// Padding OK so do the encryption
+	retVal = RSAEP(&cOut->b, key);
+ Exit:
+    return retVal;
+}
+/* 10.2.17.4.16 CryptRsaDecrypt() */
+/* This is the entry point for decryption using RSA. Decryption is use of the private exponent. The
+   padType parameter determines what padding was used. */
+/* Error Returns Meaning */
+/* TPM_RC_SIZE cInSize is not the same as the size of the public modulus of key; or numeric value of
+   the encrypted data is greater than the modulus */
+/* TPM_RC_VALUE dOutSize is not large enough for the result */
+/* TPM_RC_SCHEME padType is not supported */
+LIB_EXPORT TPM_RC
+CryptRsaDecrypt(
+		TPM2B               *dOut,          // OUT: the decrypted data
+		TPM2B               *cIn,           // IN: the data to decrypt
+		OBJECT              *key,           // IN: the key to use for decryption
+		TPMT_RSA_DECRYPT    *scheme,        // IN: the padding scheme
+		const TPM2B         *label          // IN: in case it is needed for the scheme
+		)
+{
+    TPM_RC                 retVal;
+    // Make sure that the necessary parameters are provided
+    pAssert(cIn != NULL && dOut != NULL && key != NULL);
+    // Size is checked to make sure that the encrypted value is the right size
+    if(cIn->size != key->publicArea.unique.rsa.t.size)
+	ERROR_RETURN(TPM_RC_SIZE);
+    TEST(scheme->scheme);
+    // For others that do padding, do the decryption in place and then
+    // go handle the decoding.
+    retVal = RSADP(cIn, key);
+    if(retVal == TPM_RC_SUCCESS)
+	{
+	    // Remove padding
+	    switch(scheme->scheme)
+		{
+		  case TPM_ALG_NULL:
+		    if(dOut->size < cIn->size)
+			return TPM_RC_VALUE;
+		    MemoryCopy2B(dOut, cIn, dOut->size);
+		    break;
+		  case TPM_ALG_RSAES:
+		    retVal = RSAES_Decode(dOut, cIn);
+		    break;
+		  case TPM_ALG_OAEP:
+		    retVal = OaepDecode(dOut, scheme->details.oaep.hashAlg, label, cIn);
+		    break;
+		  default:
+		    retVal = TPM_RC_SCHEME;
+		    break;
+		}
+	}
+ Exit:
+    return retVal;
+}
+/* 10.2.17.4.17 CryptRsaSign() */
+/* This function is used to generate an RSA signature of the type indicated in scheme. */
+/* Error Returns Meaning */
+/* TPM_RC_SCHEME scheme or hashAlg are not supported */
+/* TPM_RC_VALUE hInSize does not match hashAlg (for RSASSA) */
+LIB_EXPORT TPM_RC
+CryptRsaSign(
+	     TPMT_SIGNATURE      *sigOut,
+	     OBJECT              *key,           // IN: key to use
+	     TPM2B_DIGEST        *hIn,           // IN: the digest to sign
+	     RAND_STATE          *rand           // IN: the random number generator
+	     //      to use (mostly for testing)
+	     )
+{
+    TPM_RC                retVal = TPM_RC_SUCCESS;
+    UINT16                modSize;
+    // parameter checks
+    pAssert(sigOut != NULL && key != NULL && hIn != NULL);
+    modSize = key->publicArea.unique.rsa.t.size;
+    // for all non-null signatures, the size is the size of the key modulus
+    sigOut->signature.rsapss.sig.t.size = modSize;
+    TEST(sigOut->sigAlg);
+    switch(sigOut->sigAlg)
+	{
+	  case TPM_ALG_NULL:
+	    sigOut->signature.rsapss.sig.t.size = 0;
+	    return TPM_RC_SUCCESS;
+	  case TPM_ALG_RSAPSS:
+	    retVal = PssEncode(&sigOut->signature.rsapss.sig.b,
+			       sigOut->signature.rsapss.hash, &hIn->b, rand);
+	    break;
+	  case TPM_ALG_RSASSA:
+	    retVal = RSASSA_Encode(&sigOut->signature.rsassa.sig.b,
+				   sigOut->signature.rsassa.hash, &hIn->b);
+	    break;
+	  default:
+	    retVal = TPM_RC_SCHEME;
+	}
+    if(retVal == TPM_RC_SUCCESS)
+	{
+	    // Do the encryption using the private key
+	    retVal = RSADP(&sigOut->signature.rsapss.sig.b, key);
+	}
+    return retVal;
+}
+/* 10.2.17.4.18 CryptRsaValidateSignature() */
+/* This function is used to validate an RSA signature. If the signature is valid TPM_RC_SUCCESS is
+   returned. If the signature is not valid, TPM_RC_SIGNATURE is returned. Other return codes
+   indicate either parameter problems or fatal errors. */
+/* Error Returns Meaning */
+/* TPM_RC_SIGNATURE the signature does not check */
+/* TPM_RC_SCHEME unsupported scheme or hash algorithm */
+LIB_EXPORT TPM_RC
+CryptRsaValidateSignature(
+			  TPMT_SIGNATURE  *sig,           // IN: signature
+			  OBJECT          *key,           // IN: public modulus
+			  TPM2B_DIGEST    *digest         // IN: The digest being validated
+			  )
+{
+    TPM_RC          retVal;
+    //
+    // Fatal programming errors
+    pAssert(key != NULL && sig != NULL && digest != NULL);
+    switch(sig->sigAlg)
+	{
+	  case TPM_ALG_RSAPSS:
+	  case TPM_ALG_RSASSA:
+	    break;
+	  default:
+	    return TPM_RC_SCHEME;
+	}
+    // Errors that might be caused by calling parameters
+    if(sig->signature.rsassa.sig.t.size != key->publicArea.unique.rsa.t.size)
+	ERROR_RETURN(TPM_RC_SIGNATURE);
+    TEST(sig->sigAlg);
+    // Decrypt the block
+    retVal = RSAEP(&sig->signature.rsassa.sig.b, key);
+    if(retVal == TPM_RC_SUCCESS)
+	{
+	    switch(sig->sigAlg)
+		{
+		  case TPM_ALG_RSAPSS:
+		    retVal = PssDecode(sig->signature.any.hashAlg, &digest->b,
+				       &sig->signature.rsassa.sig.b);
+		    break;
+		  case TPM_ALG_RSASSA:
+		    retVal = RSASSA_Decode(sig->signature.any.hashAlg, &digest->b,
+					   &sig->signature.rsassa.sig.b);
+		    break;
+		  default:
+		    return TPM_RC_SCHEME;
+		}
+	}
+ Exit:
+    return (retVal != TPM_RC_SUCCESS) ? TPM_RC_SIGNATURE : TPM_RC_SUCCESS;
+}
+#if SIMULATION && USE_RSA_KEY_CACHE
+extern int s_rsaKeyCacheEnabled;
+int GetCachedRsaKey(OBJECT *key, RAND_STATE *rand);
+#define GET_CACHED_KEY(key, rand)					\
+    (s_rsaKeyCacheEnabled && GetCachedRsaKey(key, rand))
+#else
+#define GET_CACHED_KEY(key, rand)
+#endif
+/* 10.2.17.4.19 CryptRsaGenerateKey() */
+/* Generate an RSA key from a provided seed */
+/* Error Returns Meaning */
+/* TPM_RC_CANCELED operation was canceled */
+/* TPM_RC_RANGE public exponent is not supported */
+/* TPM_RC_VALUE could not find a prime using the provided parameters */
+LIB_EXPORT TPM_RC
+CryptRsaGenerateKey(
+		    OBJECT              *rsaKey,            // IN/OUT: The object structure in which
+		    //          the key is created.
+		    RAND_STATE          *rand               // IN: if not NULL, the deterministic
+		    //     RNG state
+		    )
+{
+    UINT32               i;
+    BN_PRIME(bnP); // These four declarations initialize the number to 0
+    BN_PRIME(bnQ);
+    BN_RSA(bnD);
+    BN_RSA(bnN);
+    BN_WORD(bnE);
+    UINT32               e;
+    int                  keySizeInBits;
+    TPMT_PUBLIC         *publicArea = &rsaKey->publicArea;
+    TPMT_SENSITIVE      *sensitive = &rsaKey->sensitive;
+    TPM_RC               retVal = TPM_RC_NO_RESULT;
+    //
+    // Need to make sure that the caller did not specify an exponent that is
+    // not supported
+    e = publicArea->parameters.rsaDetail.exponent;
+    if(e == 0)
+	e = RSA_DEFAULT_PUBLIC_EXPONENT;
+    if(e < 65537)
+	ERROR_RETURN(TPM_RC_RANGE);
+    if(e != RSA_DEFAULT_PUBLIC_EXPONENT && !IsPrimeInt(e))
+	ERROR_RETURN(TPM_RC_RANGE);
+    BnSetWord(bnE, e);
+    // Check that e is prime
+    // check for supported key size.
+    keySizeInBits = publicArea->parameters.rsaDetail.keyBits;
+    if(((keySizeInBits % 1024) != 0)
+       || (keySizeInBits > MAX_RSA_KEY_BITS)  // this might be redundant, but...
+       || (keySizeInBits == 0))
+	ERROR_RETURN(TPM_RC_VALUE);
+    // Set the prime size for instrumentation purposes
+    INSTRUMENT_SET(PrimeIndex, PRIME_INDEX(keySizeInBits / 2));
+#if SIMULATION && USE_RSA_KEY_CACHE
+    if(GET_CACHED_KEY(rsaKey, rand))
+	return TPM_RC_SUCCESS;
+#endif
+    // Make sure that key generation has been tested
+    TEST(TPM_ALG_NULL);
+    // Need to initialize the privateExponent structure
+    RsaInitializeExponent(&rsaKey->privateExponent);
+    // The prime is computed in P. When a new prime is found, Q is checked to
+    // see if it is zero.  If so, P is copied to Q and a new P is found.
+    // When both P and Q are non-zero, the modulus and
+    // private exponent are computed and a trial encryption/decryption is
+    // performed.  If the encrypt/decrypt fails, assume that at least one of the
+    // primes is composite. Since we don't know which one, set Q to zero and start
+    // over and find a new pair of primes.
+    for(i = 1; (retVal != TPM_RC_SUCCESS) && (i != 100); i++)
+	{
+	    if(_plat__IsCanceled())
+		ERROR_RETURN(TPM_RC_CANCELED);
+	    BnGeneratePrimeForRSA(bnP, keySizeInBits / 2, e, rand);
+	    INSTRUMENT_INC(PrimeCounts[PrimeIndex]);
+	    // If this is the second prime, make sure that it differs from the
+	    // first prime by at least 2^100
+	    if(BnEqualZero(bnQ))
+		{
+		    // copy p to q and compute another prime in p
+		    BnCopy(bnQ, bnP);
+		    continue;
+		}
+	    // Make sure that the difference is at least 100 bits. Need to do it this
+	    // way because the big numbers are only positive values
+	    if(BnUnsignedCmp(bnP, bnQ) < 0)
+		BnSub(bnD, bnQ, bnP);
+	    else
+		BnSub(bnD, bnP, bnQ);
+	    if(BnMsb(bnD) < 100)
+		continue;
+	    //Form the public modulus and set the unique value
+	    BnMult(bnN, bnP, bnQ);
+	    BnTo2B(bnN, &publicArea->unique.rsa.b,
+		   (NUMBYTES)BITS_TO_BYTES(keySizeInBits));
+	    // And the  prime to the sensitive area
+	    BnTo2B(bnP, &sensitive->sensitive.rsa.b,
+		   (NUMBYTES)BITS_TO_BYTES(keySizeInBits) / 2);
+	    // Make sure everything came out right. The MSb of the values must be
+	    // one
+	    if(((publicArea->unique.rsa.t.buffer[0] & 0x80) == 0)
+	       || ((sensitive->sensitive.rsa.t.buffer[0] & 0x80) == 0))
+		FAIL(FATAL_ERROR_INTERNAL);
+	    // Make sure that we can form the private exponent values
+	    if(ComputePrivateExponent(bnP, bnQ, bnE, bnN, &rsaKey->privateExponent)
+	       != TRUE)
+		{
+		    // If ComputePrivateExponent could not find an inverse for
+		    // Q, then copy P and recompute P. This might
+		    // cause both to be recomputed if P is also zero
+		    if(BnEqualZero(bnQ))
+			BnCopy(bnQ, bnP);
+		    continue;
+		}
+	    retVal = TPM_RC_SUCCESS;
+	    // Do a trial encryption decryption if this is a signing key
+	    if(IS_ATTRIBUTE(publicArea->objectAttributes, TPMA_OBJECT, sign))
+		{
+		    BN_RSA(temp1);
+		    BN_RSA(temp2);
+		    BnGenerateRandomInRange(temp1, bnN, rand);
+		    // Encrypt with public exponent...
+		    BnModExp(temp2, temp1, bnE, bnN);
+		    // ...  then decrypt with private exponent
+		    RsaPrivateKeyOp(temp2, bnN, bnP, &rsaKey->privateExponent);
+		    // If the starting and ending values are not the same,
+		    // start over )-;
+		    if(BnUnsignedCmp(temp2, temp1) != 0)
+			{
+			    BnSetWord(bnQ, 0);
+			    retVal = TPM_RC_NO_RESULT;
+			}
+		}
+	}
+ Exit:
+    if(retVal == TPM_RC_SUCCESS)
+	rsaKey->attributes.privateExp = SET;
+    return retVal;
+}
+#endif // TPM_ALG_RSA

+ 99 - 0
EVSE/GPL/ibmtpm1682/src/CryptRsa.h

@@ -0,0 +1,99 @@
+/********************************************************************************/
+/*										*/
+/*			     RSA-related structures and defines			*/
+/*			     Written by Ken Goldman				*/
+/*		       IBM Thomas J. Watson Research Center			*/
+/*            $Id: CryptRsa.h 1476 2019-06-10 19:32:03Z kgoldman $		*/
+/*										*/
+/*  Licenses and Notices							*/
+/*										*/
+/*  1. Copyright Licenses:							*/
+/*										*/
+/*  - Trusted Computing Group (TCG) grants to the user of the source code in	*/
+/*    this specification (the "Source Code") a worldwide, irrevocable, 		*/
+/*    nonexclusive, royalty free, copyright license to reproduce, create 	*/
+/*    derivative works, distribute, display and perform the Source Code and	*/
+/*    derivative works thereof, and to grant others the rights granted herein.	*/
+/*										*/
+/*  - The TCG grants to the user of the other parts of the specification 	*/
+/*    (other than the Source Code) the rights to reproduce, distribute, 	*/
+/*    display, and perform the specification solely for the purpose of 		*/
+/*    developing products based on such documents.				*/
+/*										*/
+/*  2. Source Code Distribution Conditions:					*/
+/*										*/
+/*  - Redistributions of Source Code must retain the above copyright licenses, 	*/
+/*    this list of conditions and the following disclaimers.			*/
+/*										*/
+/*  - Redistributions in binary form must reproduce the above copyright 	*/
+/*    licenses, this list of conditions	and the following disclaimers in the 	*/
+/*    documentation and/or other materials provided with the distribution.	*/
+/*										*/
+/*  3. Disclaimers:								*/
+/*										*/
+/*  - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF	*/
+/*  LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH	*/
+/*  RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES)	*/
+/*  THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE.		*/
+/*  Contact TCG Administration (admin@trustedcomputinggroup.org) for 		*/
+/*  information on specification licensing rights available through TCG 	*/
+/*  membership agreements.							*/
+/*										*/
+/*  - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED 	*/
+/*    WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR 	*/
+/*    FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR 		*/
+/*    NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY 		*/
+/*    OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE.		*/
+/*										*/
+/*  - Without limitation, TCG and its members and licensors disclaim all 	*/
+/*    liability, including liability for infringement of any proprietary 	*/
+/*    rights, relating to use of information in this specification and to the	*/
+/*    implementation of this specification, and TCG disclaims all liability for	*/
+/*    cost of procurement of substitute goods or services, lost profits, loss 	*/
+/*    of use, loss of data or any incidental, consequential, direct, indirect, 	*/
+/*    or special damages, whether under contract, tort, warranty or otherwise, 	*/
+/*    arising in any way out of use or reliance upon this specification or any 	*/
+/*    information herein.							*/
+/*										*/
+/*  (c) Copyright IBM Corp. and others, 2016 - 2019				*/
+/*										*/
+/********************************************************************************/
+
+// 10.1.5	CryptRsa.h
+// This file contains the RSA-related structures and defines.
+#ifndef _CRYPT_RSA_H
+#define _CRYPT_RSA_H
+
+/* This structure is a succinct representation of the cryptographic components of an RSA key. It is
+   used in testing */
+typedef struct
+{
+    UINT32        exponent;      // The public exponent pointer
+    TPM2B        *publicKey;     // Pointer to the public modulus
+    TPM2B        *privateKey;    // The private prime
+} RSA_KEY;
+/* These values are used in the bigNum representation of various RSA values. */
+#define RSA_BITS            (MAX_RSA_KEY_BYTES * 8)
+BN_TYPE(rsa, RSA_BITS);
+#define BN_RSA(name)       BN_VAR(name, RSA_BITS)
+#define BN_RSA_INITIALIZED(name, initializer)		\
+    BN_INITIALIZED(name, RSA_BITS, initializer)
+#define BN_PRIME(name)     BN_VAR(name, (RSA_BITS / 2))
+BN_TYPE(prime, (RSA_BITS / 2));
+#define BN_PRIME_INITIALIZED(name, initializer)			\
+    BN_INITIALIZED(name, RSA_BITS / 2, initializer)
+typedef struct privateExponent
+{
+#if CRT_FORMAT_RSA == NO
+    bn_rsa_t            D;
+#else
+    bn_prime_t          Q;
+    bn_prime_t          dP;
+    bn_prime_t          dQ;
+    bn_prime_t          qInv;
+#endif // CRT_FORMAT_RSA
+} privateExponent_t;
+#endif      // _CRYPT_RSA_H
+
+
+

+ 139 - 0
EVSE/GPL/ibmtpm1682/src/CryptRsa_fp.h

@@ -0,0 +1,139 @@
+/********************************************************************************/
+/*										*/
+/*		Implementation of cryptographic primitives for RSA		*/
+/*			     Written by Ken Goldman				*/
+/*		       IBM Thomas J. Watson Research Center			*/
+/*            $Id: CryptRsa_fp.h 1476 2019-06-10 19:32:03Z kgoldman $		*/
+/*										*/
+/*  Licenses and Notices							*/
+/*										*/
+/*  1. Copyright Licenses:							*/
+/*										*/
+/*  - Trusted Computing Group (TCG) grants to the user of the source code in	*/
+/*    this specification (the "Source Code") a worldwide, irrevocable, 		*/
+/*    nonexclusive, royalty free, copyright license to reproduce, create 	*/
+/*    derivative works, distribute, display and perform the Source Code and	*/
+/*    derivative works thereof, and to grant others the rights granted herein.	*/
+/*										*/
+/*  - The TCG grants to the user of the other parts of the specification 	*/
+/*    (other than the Source Code) the rights to reproduce, distribute, 	*/
+/*    display, and perform the specification solely for the purpose of 		*/
+/*    developing products based on such documents.				*/
+/*										*/
+/*  2. Source Code Distribution Conditions:					*/
+/*										*/
+/*  - Redistributions of Source Code must retain the above copyright licenses, 	*/
+/*    this list of conditions and the following disclaimers.			*/
+/*										*/
+/*  - Redistributions in binary form must reproduce the above copyright 	*/
+/*    licenses, this list of conditions	and the following disclaimers in the 	*/
+/*    documentation and/or other materials provided with the distribution.	*/
+/*										*/
+/*  3. Disclaimers:								*/
+/*										*/
+/*  - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF	*/
+/*  LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH	*/
+/*  RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES)	*/
+/*  THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE.		*/
+/*  Contact TCG Administration (admin@trustedcomputinggroup.org) for 		*/
+/*  information on specification licensing rights available through TCG 	*/
+/*  membership agreements.							*/
+/*										*/
+/*  - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED 	*/
+/*    WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR 	*/
+/*    FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR 		*/
+/*    NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY 		*/
+/*    OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE.		*/
+/*										*/
+/*  - Without limitation, TCG and its members and licensors disclaim all 	*/
+/*    liability, including liability for infringement of any proprietary 	*/
+/*    rights, relating to use of information in this specification and to the	*/
+/*    implementation of this specification, and TCG disclaims all liability for	*/
+/*    cost of procurement of substitute goods or services, lost profits, loss 	*/
+/*    of use, loss of data or any incidental, consequential, direct, indirect, 	*/
+/*    or special damages, whether under contract, tort, warranty or otherwise, 	*/
+/*    arising in any way out of use or reliance upon this specification or any 	*/
+/*    information herein.							*/
+/*										*/
+/*  (c) Copyright IBM Corp. and others, 2016 - 2019				*/
+/*										*/
+/********************************************************************************/
+
+#ifndef CRYPTRSA_FP_H
+#define CRYPTRSA_FP_H
+
+BOOL
+CryptRsaInit(
+	     void
+	     );
+BOOL
+CryptRsaStartup(
+		void
+		);
+void
+RsaInitializeExponent(
+		      privateExponent_t      *pExp
+		      );
+INT16
+CryptRsaPssSaltSize(
+		    INT16              hashSize,
+		    INT16               outSize
+		    );
+TPMT_RSA_DECRYPT*
+CryptRsaSelectScheme(
+		     TPMI_DH_OBJECT       rsaHandle,     // IN: handle of an RSA key
+		     TPMT_RSA_DECRYPT    *scheme         // IN: a sign or decrypt scheme
+		     );
+TPM_RC
+CryptRsaLoadPrivateExponent(
+			    OBJECT          *rsaKey        // IN: the RSA key object
+			    );
+LIB_EXPORT TPM_RC
+CryptRsaEncrypt(
+		TPM2B_PUBLIC_KEY_RSA        *cOut,          // OUT: the encrypted data
+		TPM2B                       *dIn,           // IN: the data to encrypt
+		OBJECT                      *key,           // IN: the key used for encryption
+		TPMT_RSA_DECRYPT            *scheme,        // IN: the type of padding and hash
+		//     if needed
+		const TPM2B                 *label,         // IN: in case it is needed
+		RAND_STATE                  *rand           // IN: random number generator
+		//     state (mostly for testing)
+		);
+LIB_EXPORT TPM_RC
+CryptRsaDecrypt(
+		TPM2B               *dOut,          // OUT: the decrypted data
+		TPM2B               *cIn,           // IN: the data to decrypt
+		OBJECT              *key,           // IN: the key to use for decryption
+		TPMT_RSA_DECRYPT    *scheme,        // IN: the padding scheme
+		const TPM2B         *label          // IN: in case it is needed for the scheme
+		);
+LIB_EXPORT TPM_RC
+CryptRsaSign(
+	     TPMT_SIGNATURE      *sigOut,
+	     OBJECT              *key,           // IN: key to use
+	     TPM2B_DIGEST        *hIn,           // IN: the digest to sign
+	     RAND_STATE          *rand           // IN: the random number generator
+	     //      to use (mostly for testing)
+	     );
+LIB_EXPORT TPM_RC
+CryptRsaValidateSignature(
+			  TPMT_SIGNATURE  *sig,           // IN: signature
+			  OBJECT          *key,           // IN: public modulus
+			  TPM2B_DIGEST    *digest         // IN: The digest being validated
+			  );
+LIB_EXPORT TPM_RC
+CryptRsaGenerateKey(
+		    OBJECT              *rsaKey,            // IN/OUT: The object structure in which
+		    //          the key is created.
+		    RAND_STATE          *rand               // IN: if not NULL, the deterministic
+		    //     RNG state
+		    );
+INT16
+MakeDerTag(
+	   TPM_ALG_ID   hashAlg,
+	   INT16        sizeOfBuffer,
+	   BYTE        *buffer
+	   );
+
+
+#endif

+ 225 - 0
EVSE/GPL/ibmtpm1682/src/CryptSelfTest.c

@@ -0,0 +1,225 @@
+/********************************************************************************/
+/*										*/
+/*			Self-Test of Cryptographic Functions 			*/
+/*			     Written by Ken Goldman				*/
+/*		       IBM Thomas J. Watson Research Center			*/
+/*            $Id: CryptSelfTest.c 1594 2020-03-26 22:15:48Z kgoldman $		*/
+/*										*/
+/*  Licenses and Notices							*/
+/*										*/
+/*  1. Copyright Licenses:							*/
+/*										*/
+/*  - Trusted Computing Group (TCG) grants to the user of the source code in	*/
+/*    this specification (the "Source Code") a worldwide, irrevocable, 		*/
+/*    nonexclusive, royalty free, copyright license to reproduce, create 	*/
+/*    derivative works, distribute, display and perform the Source Code and	*/
+/*    derivative works thereof, and to grant others the rights granted herein.	*/
+/*										*/
+/*  - The TCG grants to the user of the other parts of the specification 	*/
+/*    (other than the Source Code) the rights to reproduce, distribute, 	*/
+/*    display, and perform the specification solely for the purpose of 		*/
+/*    developing products based on such documents.				*/
+/*										*/
+/*  2. Source Code Distribution Conditions:					*/
+/*										*/
+/*  - Redistributions of Source Code must retain the above copyright licenses, 	*/
+/*    this list of conditions and the following disclaimers.			*/
+/*										*/
+/*  - Redistributions in binary form must reproduce the above copyright 	*/
+/*    licenses, this list of conditions	and the following disclaimers in the 	*/
+/*    documentation and/or other materials provided with the distribution.	*/
+/*										*/
+/*  3. Disclaimers:								*/
+/*										*/
+/*  - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF	*/
+/*  LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH	*/
+/*  RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES)	*/
+/*  THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE.		*/
+/*  Contact TCG Administration (admin@trustedcomputinggroup.org) for 		*/
+/*  information on specification licensing rights available through TCG 	*/
+/*  membership agreements.							*/
+/*										*/
+/*  - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED 	*/
+/*    WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR 	*/
+/*    FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR 		*/
+/*    NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY 		*/
+/*    OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE.		*/
+/*										*/
+/*  - Without limitation, TCG and its members and licensors disclaim all 	*/
+/*    liability, including liability for infringement of any proprietary 	*/
+/*    rights, relating to use of information in this specification and to the	*/
+/*    implementation of this specification, and TCG disclaims all liability for	*/
+/*    cost of procurement of substitute goods or services, lost profits, loss 	*/
+/*    of use, loss of data or any incidental, consequential, direct, indirect, 	*/
+/*    or special damages, whether under contract, tort, warranty or otherwise, 	*/
+/*    arising in any way out of use or reliance upon this specification or any 	*/
+/*    information herein.							*/
+/*										*/
+/*  (c) Copyright IBM Corp. and others, 2016 - 2020				*/
+/*										*/
+/********************************************************************************/
+
+/* 10.2.7 CryptSelfTest.c */
+/* 10.2.7.1 Introduction */
+/* The functions in this file are designed to support self-test of cryptographic functions in the
+   TPM. The TPM allows the user to decide whether to run self-test on a demand basis or to run all
+   the self-tests before proceeding. */
+/* The self-tests are controlled by a set of bit vectors. The g_untestedDecryptionAlgorithms vector
+   has a bit for each decryption algorithm that needs to be tested and
+   g_untestedEncryptionAlgorithms has a bit for each encryption algorithm that needs to be
+   tested. Before an algorithm is used, the appropriate vector is checked (indexed using the
+   algorithm ID). If the bit is 1, then the test function should be called. */
+/* For more information, see TpmSelfTests().txt */
+#include "Tpm.h"
+/*     10.2.7.2 Functions */
+/* 10.2.7.2.1 RunSelfTest() */
+/* Local function to run self-test */
+static TPM_RC
+CryptRunSelfTests(
+		  ALGORITHM_VECTOR    *toTest         // IN: the vector of the algorithms to test
+		  )
+{
+    TPM_ALG_ID           alg;
+    // For each of the algorithms that are in the toTestVecor, need to run a
+    // test
+    for(alg = TPM_ALG_FIRST; alg <= TPM_ALG_LAST; alg++)
+	{
+	    if(TEST_BIT(alg, *toTest))
+		{
+		    TPM_RC          result = CryptTestAlgorithm(alg, toTest);
+		    if(result != TPM_RC_SUCCESS)
+			return result;
+		}
+	}
+    return TPM_RC_SUCCESS;
+}
+/* 10.2.7.2.2 CryptSelfTest() */
+/* This function is called to start/complete a full self-test. If fullTest is NO, then only the
+   untested algorithms will be run. If fullTest is YES, then g_untestedDecryptionAlgorithms is
+   reinitialized and then all tests are run. This implementation of the reference design does not
+   support processing outside the framework of a TPM command. As a consequence, this command does
+   not complete until all tests are done. Since this can take a long time, the TPM will check after
+   each test to see if the command is canceled. If so, then the TPM will returned
+   TPM_RC_CANCELLED. To continue with the self-tests, call TPM2_SelfTest(fullTest == No) and the TPM
+   will complete the testing. */
+/* Error Returns Meaning */
+/* TPM_RC_CANCELED if the command is canceled */
+LIB_EXPORT
+TPM_RC
+CryptSelfTest(
+	      TPMI_YES_NO      fullTest       // IN: if full test is required
+	      )
+{
+#if SIMULATION
+    if(g_forceFailureMode)
+	FAIL(FATAL_ERROR_FORCED);
+#endif
+    // If the caller requested a full test, then reset the to test vector so that
+    // all the tests will be run
+    if(fullTest == YES)
+	{
+	    MemoryCopy(g_toTest,
+		       g_implementedAlgorithms,
+		       sizeof(g_toTest));
+	}
+    return CryptRunSelfTests(&g_toTest);
+}
+/* 10.2.7.2.3 CryptIncrementalSelfTest() */
+/* This function is used to perform an incremental self-test. This implementation will perform the
+   toTest values before returning. That is, it assumes that the TPM cannot perform background tasks
+   between commands. */
+/* This command may be canceled. If it is, then there is no return result. However, this command can
+   be run again and the incremental progress will not be lost. */
+/* Error Returns Meaning */
+/* TPM_RC_CANCELED processing of this command was canceled */
+/* TPM_RC_TESTING if toTest list is not empty */
+/* TPM_RC_VALUE an algorithm in the toTest list is not implemented */
+TPM_RC
+CryptIncrementalSelfTest(
+			 TPML_ALG            *toTest,        // IN: list of algorithms to be tested
+			 TPML_ALG            *toDoList       // OUT: list of algorithms needing test
+			 )
+{
+    ALGORITHM_VECTOR     toTestVector = {0};
+    TPM_ALG_ID           alg;
+    UINT32               i;
+    pAssert(toTest != NULL && toDoList != NULL);
+    if(toTest->count > 0)
+	{
+	    // Transcribe the toTest list into the toTestVector
+	    for(i = 0; i < toTest->count; i++)
+		{
+		    alg = toTest->algorithms[i];
+		    // make sure that the algorithm value is not out of range
+		    if((alg > TPM_ALG_LAST) || !TEST_BIT(alg, g_implementedAlgorithms))
+			return TPM_RC_VALUE;
+		    SET_BIT(alg, toTestVector);
+		}
+	    // Run the test
+	    if(CryptRunSelfTests(&toTestVector) == TPM_RC_CANCELED)
+		return TPM_RC_CANCELED;
+	}
+    // Fill in the toDoList with the algorithms that are still untested
+    toDoList->count = 0;
+    for(alg = TPM_ALG_FIRST;
+	toDoList->count < MAX_ALG_LIST_SIZE && alg <= TPM_ALG_LAST;
+	alg++)
+	{
+	    if(TEST_BIT(alg, g_toTest))
+		toDoList->algorithms[toDoList->count++] = alg;
+	}
+    return TPM_RC_SUCCESS;
+}
+/* 10.2.7.2.4 CryptInitializeToTest() */
+/* This function will initialize the data structures for testing all the algorithms. This should not
+   be called unless CryptAlgsSetImplemented() has been called */
+void
+CryptInitializeToTest(
+		      void
+		      )
+{
+    // Indicate that nothing has been tested
+    memset(&g_cryptoSelfTestState, 0, sizeof(g_cryptoSelfTestState));
+    // Copy the implemented algorithm vector
+    MemoryCopy(g_toTest, g_implementedAlgorithms, sizeof(g_toTest));
+    // Setting the algorithm to null causes the test function to just clear
+    // out any algorithms for which there is no test.
+    CryptTestAlgorithm(TPM_ALG_ERROR, &g_toTest);
+    return;
+}
+/* 10.2.7.2.5 CryptTestAlgorithm() */
+/* Only point of contact with the actual self tests. If a self-test fails, there is no return and
+   the TPM goes into failure mode. The call to TestAlgorithm() uses an algorithm selector and a bit
+   vector. When the test is run, the corresponding bit in toTest and in g_toTest is CLEAR. If toTest
+   is NULL, then only the bit in g_toTest is CLEAR. There is a special case for the call to
+   TestAlgorithm(). When alg is TPM_ALG_ERROR, TestAlgorithm() will CLEAR any bit in toTest for
+   which it has no test. This allows the knowledge about which algorithms have test to be accessed
+   through the interface that provides the test. */
+/* Error Returns Meaning */
+/* TPM_RC_CANCELED test was canceled */
+LIB_EXPORT
+TPM_RC
+CryptTestAlgorithm(
+		   TPM_ALG_ID           alg,
+		   ALGORITHM_VECTOR    *toTest
+		   )
+{
+    TPM_RC                   result;
+#if SELF_TEST
+    result = TestAlgorithm(alg, toTest);
+#else
+    // If this is an attempt to determine the algorithms for which there is a
+    // self test, pretend that all of them do. We do that by not clearing any
+    // of the algorithm bits. When/if this function is called to run tests, it
+    // will over report. This can be changed so that any call to check on which
+    // algorithms have tests, 'toTest' can be cleared.
+    if(alg != TPM_ALG_ERROR)
+	{
+	    CLEAR_BIT(alg, g_toTest);
+	    if(toTest != NULL)
+		CLEAR_BIT(alg, *toTest);
+	}
+    result = TPM_RC_SUCCESS;
+#endif
+    return result;
+}

+ 87 - 0
EVSE/GPL/ibmtpm1682/src/CryptSelfTest_fp.h

@@ -0,0 +1,87 @@
+/********************************************************************************/
+/*										*/
+/*			     				*/
+/*			     Written by Ken Goldman				*/
+/*		       IBM Thomas J. Watson Research Center			*/
+/*            $Id: CryptSelfTest_fp.h 1490 2019-07-26 21:13:22Z kgoldman $			*/
+/*										*/
+/*  Licenses and Notices							*/
+/*										*/
+/*  1. Copyright Licenses:							*/
+/*										*/
+/*  - Trusted Computing Group (TCG) grants to the user of the source code in	*/
+/*    this specification (the "Source Code") a worldwide, irrevocable, 		*/
+/*    nonexclusive, royalty free, copyright license to reproduce, create 	*/
+/*    derivative works, distribute, display and perform the Source Code and	*/
+/*    derivative works thereof, and to grant others the rights granted herein.	*/
+/*										*/
+/*  - The TCG grants to the user of the other parts of the specification 	*/
+/*    (other than the Source Code) the rights to reproduce, distribute, 	*/
+/*    display, and perform the specification solely for the purpose of 		*/
+/*    developing products based on such documents.				*/
+/*										*/
+/*  2. Source Code Distribution Conditions:					*/
+/*										*/
+/*  - Redistributions of Source Code must retain the above copyright licenses, 	*/
+/*    this list of conditions and the following disclaimers.			*/
+/*										*/
+/*  - Redistributions in binary form must reproduce the above copyright 	*/
+/*    licenses, this list of conditions	and the following disclaimers in the 	*/
+/*    documentation and/or other materials provided with the distribution.	*/
+/*										*/
+/*  3. Disclaimers:								*/
+/*										*/
+/*  - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF	*/
+/*  LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH	*/
+/*  RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES)	*/
+/*  THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE.		*/
+/*  Contact TCG Administration (admin@trustedcomputinggroup.org) for 		*/
+/*  information on specification licensing rights available through TCG 	*/
+/*  membership agreements.							*/
+/*										*/
+/*  - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED 	*/
+/*    WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR 	*/
+/*    FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR 		*/
+/*    NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY 		*/
+/*    OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE.		*/
+/*										*/
+/*  - Without limitation, TCG and its members and licensors disclaim all 	*/
+/*    liability, including liability for infringement of any proprietary 	*/
+/*    rights, relating to use of information in this specification and to the	*/
+/*    implementation of this specification, and TCG disclaims all liability for	*/
+/*    cost of procurement of substitute goods or services, lost profits, loss 	*/
+/*    of use, loss of data or any incidental, consequential, direct, indirect, 	*/
+/*    or special damages, whether under contract, tort, warranty or otherwise, 	*/
+/*    arising in any way out of use or reliance upon this specification or any 	*/
+/*    information herein.							*/
+/*										*/
+/*  (c) Copyright IBM Corp. and others, 2016					*/
+/*										*/
+/********************************************************************************/
+
+#ifndef CRYPTSELFTEST_FP_H
+#define CRYPTSELFTEST_FP_H
+
+LIB_EXPORT
+TPM_RC
+CryptSelfTest(
+	      TPMI_YES_NO      fullTest       // IN: if full test is required
+	      );
+TPM_RC
+CryptIncrementalSelfTest(
+			 TPML_ALG            *toTest,        // IN: list of algorithms to be tested
+			 TPML_ALG            *toDoList       // OUT: list of algorithms needing test
+			 );
+void
+CryptInitializeToTest(
+		      void
+		      );
+LIB_EXPORT
+TPM_RC
+CryptTestAlgorithm(
+		   TPM_ALG_ID           alg,
+		   ALGORITHM_VECTOR    *toTest
+		   );
+
+
+#endif

+ 154 - 0
EVSE/GPL/ibmtpm1682/src/CryptSmac.c

@@ -0,0 +1,154 @@
+/********************************************************************************/
+/*										*/
+/*		Message Authentication Codes Based on a Symmetric Block Cipher	*/
+/*			     Written by Ken Goldman				*/
+/*		       IBM Thomas J. Watson Research Center			*/
+/*            $Id: CryptSmac.c 1658 2021-01-22 23:14:01Z kgoldman $		*/
+/*										*/
+/*  Licenses and Notices							*/
+/*										*/
+/*  1. Copyright Licenses:							*/
+/*										*/
+/*  - Trusted Computing Group (TCG) grants to the user of the source code in	*/
+/*    this specification (the "Source Code") a worldwide, irrevocable, 		*/
+/*    nonexclusive, royalty free, copyright license to reproduce, create 	*/
+/*    derivative works, distribute, display and perform the Source Code and	*/
+/*    derivative works thereof, and to grant others the rights granted herein.	*/
+/*										*/
+/*  - The TCG grants to the user of the other parts of the specification 	*/
+/*    (other than the Source Code) the rights to reproduce, distribute, 	*/
+/*    display, and perform the specification solely for the purpose of 		*/
+/*    developing products based on such documents.				*/
+/*										*/
+/*  2. Source Code Distribution Conditions:					*/
+/*										*/
+/*  - Redistributions of Source Code must retain the above copyright licenses, 	*/
+/*    this list of conditions and the following disclaimers.			*/
+/*										*/
+/*  - Redistributions in binary form must reproduce the above copyright 	*/
+/*    licenses, this list of conditions	and the following disclaimers in the 	*/
+/*    documentation and/or other materials provided with the distribution.	*/
+/*										*/
+/*  3. Disclaimers:								*/
+/*										*/
+/*  - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF	*/
+/*  LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH	*/
+/*  RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES)	*/
+/*  THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE.		*/
+/*  Contact TCG Administration (admin@trustedcomputinggroup.org) for 		*/
+/*  information on specification licensing rights available through TCG 	*/
+/*  membership agreements.							*/
+/*										*/
+/*  - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED 	*/
+/*    WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR 	*/
+/*    FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR 		*/
+/*    NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY 		*/
+/*    OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE.		*/
+/*										*/
+/*  - Without limitation, TCG and its members and licensors disclaim all 	*/
+/*    liability, including liability for infringement of any proprietary 	*/
+/*    rights, relating to use of information in this specification and to the	*/
+/*    implementation of this specification, and TCG disclaims all liability for	*/
+/*    cost of procurement of substitute goods or services, lost profits, loss 	*/
+/*    of use, loss of data or any incidental, consequential, direct, indirect, 	*/
+/*    or special damages, whether under contract, tort, warranty or otherwise, 	*/
+/*    arising in any way out of use or reliance upon this specification or any 	*/
+/*    information herein.							*/
+/*										*/
+/*  (c) Copyright IBM Corp. and others, 2018 - 2021				*/
+/*										*/
+/********************************************************************************/
+
+/* 10.2.20	CryptSmac.c */
+/* 10.2.20.1	Introduction */
+/* This file contains the implementation of the message authentication codes based on a symmetric
+   block cipher. These functions only use the single block encryption functions of the selected
+   symmetric cryptographic library. */
+/* 10.2.20.2	Includes, Defines, and Typedefs */
+#define _CRYPT_HASH_C_
+#include "Tpm.h"
+#if SMAC_IMPLEMENTED
+    /* 10.2.20.2.1	CryptSmacStart() */
+    /* Function to start an SMAC. */
+UINT16
+CryptSmacStart(
+	       HASH_STATE              *state,
+	       TPMU_PUBLIC_PARMS       *keyParameters,
+	       TPM_ALG_ID               macAlg,          // IN: the type of MAC
+	       TPM2B                   *key
+	       )
+{
+    UINT16                  retVal = 0;
+    //
+    // Make sure that the key size is correct. This should have been checked
+    // at key load, but...
+    if(BITS_TO_BYTES(keyParameters->symDetail.sym.keyBits.sym) == key->size)
+	{
+	    switch(macAlg)
+		{
+#if ALG_CMAC
+		  case TPM_ALG_CMAC:
+		    retVal = CryptCmacStart(&state->state.smac, keyParameters,
+					    macAlg, key);
+		    break;
+#endif
+		  default:
+		    break;
+		}
+	}
+    state->type = (retVal != 0) ? HASH_STATE_SMAC : HASH_STATE_EMPTY;
+    return retVal;
+}
+/* 10.2.20.2.2	CryptMacStart() */
+/* Function to start either an HMAC or an SMAC. Cannot reuse the CryptHmacStart() function because
+   of the difference in number of parameters. */
+UINT16
+CryptMacStart(
+	      HMAC_STATE              *state,
+	      TPMU_PUBLIC_PARMS       *keyParameters,
+	      TPM_ALG_ID               macAlg,          // IN: the type of MAC
+	      TPM2B                   *key
+	      )
+{
+    MemorySet(state, 0, sizeof(HMAC_STATE));
+    if(CryptHashIsValidAlg(macAlg, FALSE))
+	{
+	    return CryptHmacStart(state, macAlg, key->size, key->buffer);
+	}
+    else if(CryptSmacIsValidAlg(macAlg, FALSE))
+	{
+	    return CryptSmacStart(&state->hashState, keyParameters, macAlg, key);
+	}
+    else
+	return 0;
+}
+/* 10.2.20.2.3	CryptMacEnd() */
+/* Dispatch to the MAC end function using a size and buffer pointer. */
+UINT16
+CryptMacEnd(
+	    HMAC_STATE          *state,
+	    UINT32               size,
+	    BYTE                *buffer
+	    )
+{
+    UINT16              retVal = 0;
+    if(state->hashState.type == HASH_STATE_SMAC)
+	retVal = (state->hashState.state.smac.smacMethods.end)(
+							       &state->hashState.state.smac.state, size, buffer);
+    else if(state->hashState.type == HASH_STATE_HMAC)
+	retVal = CryptHmacEnd(state, size, buffer);
+    state->hashState.type = HASH_STATE_EMPTY;
+    return retVal;
+}
+/* 10.2.20.2.4	CryptMacEnd2B() */
+/* Dispatch to the MAC end function using a 2B. */
+UINT16
+CryptMacEnd2B (
+	       HMAC_STATE          *state,
+	       TPM2B               *data
+	       )
+{
+    return CryptMacEnd(state, data->size, data->buffer);
+}
+#endif // SMAC_IMPLEMENTED
+

+ 98 - 0
EVSE/GPL/ibmtpm1682/src/CryptSmac_fp.h

@@ -0,0 +1,98 @@
+/********************************************************************************/
+/*		Message Authentication Codes Based on a Symmetric Block Cipher	*/
+/*		Implementation of cryptographic functions for hashing.		*/
+/*			     Written by Ken Goldman				*/
+/*		       IBM Thomas J. Watson Research Center			*/
+/*            $Id: CryptSmac_fp.h 1490 2019-07-26 21:13:22Z kgoldman $		*/
+/*										*/
+/*  Licenses and Notices							*/
+/*										*/
+/*  1. Copyright Licenses:							*/
+/*										*/
+/*  - Trusted Computing Group (TCG) grants to the user of the source code in	*/
+/*    this specification (the "Source Code") a worldwide, irrevocable, 		*/
+/*    nonexclusive, royalty free, copyright license to reproduce, create 	*/
+/*    derivative works, distribute, display and perform the Source Code and	*/
+/*    derivative works thereof, and to grant others the rights granted herein.	*/
+/*										*/
+/*  - The TCG grants to the user of the other parts of the specification 	*/
+/*    (other than the Source Code) the rights to reproduce, distribute, 	*/
+/*    display, and perform the specification solely for the purpose of 		*/
+/*    developing products based on such documents.				*/
+/*										*/
+/*  2. Source Code Distribution Conditions:					*/
+/*										*/
+/*  - Redistributions of Source Code must retain the above copyright licenses, 	*/
+/*    this list of conditions and the following disclaimers.			*/
+/*										*/
+/*  - Redistributions in binary form must reproduce the above copyright 	*/
+/*    licenses, this list of conditions	and the following disclaimers in the 	*/
+/*    documentation and/or other materials provided with the distribution.	*/
+/*										*/
+/*  3. Disclaimers:								*/
+/*										*/
+/*  - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF	*/
+/*  LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH	*/
+/*  RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES)	*/
+/*  THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE.		*/
+/*  Contact TCG Administration (admin@trustedcomputinggroup.org) for 		*/
+/*  information on specification licensing rights available through TCG 	*/
+/*  membership agreements.							*/
+/*										*/
+/*  - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED 	*/
+/*    WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR 	*/
+/*    FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR 		*/
+/*    NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY 		*/
+/*    OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE.		*/
+/*										*/
+/*  - Without limitation, TCG and its members and licensors disclaim all 	*/
+/*    liability, including liability for infringement of any proprietary 	*/
+/*    rights, relating to use of information in this specification and to the	*/
+/*    implementation of this specification, and TCG disclaims all liability for	*/
+/*    cost of procurement of substitute goods or services, lost profits, loss 	*/
+/*    of use, loss of data or any incidental, consequential, direct, indirect, 	*/
+/*    or special damages, whether under contract, tort, warranty or otherwise, 	*/
+/*    arising in any way out of use or reliance upon this specification or any 	*/
+/*    information herein.							*/
+/*										*/
+/*  (c) Copyright IBM Corp. and others, 2018					*/
+/*										*/
+/********************************************************************************/
+
+#ifndef CRYPTSMAC_FP_H
+#define CRYPTSMAC_FP_H
+#include "Tpm.h"
+
+UINT16
+CryptSmacStart(
+	       HASH_STATE              *state,
+	       TPMU_PUBLIC_PARMS       *keyParameters,
+	       TPM_ALG_ID               macAlg, 
+	       TPM2B                   *key
+	       );
+UINT16
+CryptMacStart(
+	      HMAC_STATE              *state,
+	      TPMU_PUBLIC_PARMS       *keyParameters,
+	      TPM_ALG_ID               macAlg, 
+	      TPM2B                   *key
+	      );
+UINT16
+CryptMacEnd(
+	    HMAC_STATE          *state,
+	    UINT32               size,
+	    BYTE                *buffer
+	    );
+UINT16
+CryptMacEnd(
+	    HMAC_STATE          *state,
+	    UINT32               size,
+	    BYTE                *buffer
+	    );
+UINT16
+CryptMacEnd2B (
+	       HMAC_STATE          *state,
+	       TPM2B               *data
+	       );
+
+#endif

+ 489 - 0
EVSE/GPL/ibmtpm1682/src/CryptSym.c

@@ -0,0 +1,489 @@
+/********************************************************************************/
+/*										*/
+/*			     Symmetric block cipher modes			*/
+/*			     Written by Ken Goldman				*/
+/*		       IBM Thomas J. Watson Research Center			*/
+/*            $Id: CryptSym.c 1661 2021-03-18 19:00:58Z kgoldman $		*/
+/*										*/
+/*  Licenses and Notices							*/
+/*										*/
+/*  1. Copyright Licenses:							*/
+/*										*/
+/*  - Trusted Computing Group (TCG) grants to the user of the source code in	*/
+/*    this specification (the "Source Code") a worldwide, irrevocable, 		*/
+/*    nonexclusive, royalty free, copyright license to reproduce, create 	*/
+/*    derivative works, distribute, display and perform the Source Code and	*/
+/*    derivative works thereof, and to grant others the rights granted herein.	*/
+/*										*/
+/*  - The TCG grants to the user of the other parts of the specification 	*/
+/*    (other than the Source Code) the rights to reproduce, distribute, 	*/
+/*    display, and perform the specification solely for the purpose of 		*/
+/*    developing products based on such documents.				*/
+/*										*/
+/*  2. Source Code Distribution Conditions:					*/
+/*										*/
+/*  - Redistributions of Source Code must retain the above copyright licenses, 	*/
+/*    this list of conditions and the following disclaimers.			*/
+/*										*/
+/*  - Redistributions in binary form must reproduce the above copyright 	*/
+/*    licenses, this list of conditions	and the following disclaimers in the 	*/
+/*    documentation and/or other materials provided with the distribution.	*/
+/*										*/
+/*  3. Disclaimers:								*/
+/*										*/
+/*  - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF	*/
+/*  LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH	*/
+/*  RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES)	*/
+/*  THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE.		*/
+/*  Contact TCG Administration (admin@trustedcomputinggroup.org) for 		*/
+/*  information on specification licensing rights available through TCG 	*/
+/*  membership agreements.							*/
+/*										*/
+/*  - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED 	*/
+/*    WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR 	*/
+/*    FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR 		*/
+/*    NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY 		*/
+/*    OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE.		*/
+/*										*/
+/*  - Without limitation, TCG and its members and licensors disclaim all 	*/
+/*    liability, including liability for infringement of any proprietary 	*/
+/*    rights, relating to use of information in this specification and to the	*/
+/*    implementation of this specification, and TCG disclaims all liability for	*/
+/*    cost of procurement of substitute goods or services, lost profits, loss 	*/
+/*    of use, loss of data or any incidental, consequential, direct, indirect, 	*/
+/*    or special damages, whether under contract, tort, warranty or otherwise, 	*/
+/*    arising in any way out of use or reliance upon this specification or any 	*/
+/*    information herein.							*/
+/*										*/
+/*  (c) Copyright IBM Corp. and others, 2016 - 2021				*/
+/*										*/
+/********************************************************************************/
+
+/* 10.2.19 CryptSym.c */
+/* 10.2.19.1 Introduction */
+/* This file contains the implementation of the symmetric block cipher modes allowed for a
+   TPM. These functions only use the single block encryption functions of the selected symmetric
+   crypto library. */
+
+/* 10.2.19.2	Includes, Defines, and Typedefs */
+#include "Tpm.h"
+#include "CryptSym.h"
+
+
+#define     KEY_BLOCK_SIZES(ALG, alg)					\
+    static const INT16       alg##KeyBlockSizes[] = {			\
+						     ALG##_KEY_SIZES_BITS, -1, ALG##_BLOCK_SIZES };
+
+FOR_EACH_SYM(KEY_BLOCK_SIZES)
+
+/* 10.2.19.3	Initialization and Data Access Functions */
+/* 10.2.19.3.1	CryptSymInit() */
+/* This function is called to do _TPM_Init() processing */
+BOOL
+CryptSymInit(
+	     void
+	     )
+{
+    return TRUE;
+}
+/* 10.2.19.3.2	CryptSymStartup() */
+/* This function is called to do TPM2_Startup() processing */
+BOOL
+CryptSymStartup(
+		void
+		)
+{
+    return TRUE;
+}
+/* 10.2.20.4 Data Access Functions */
+/* 10.2.20.4.1 CryptGetSymmetricBlockSize() */
+/* This function returns the block size of the algorithm. The table of bit sizes has an entry for
+   each allowed key size. The entry for a key size is 0 if the TPM does not implement that key
+   size. The key size table is delimited with a negative number (-1). After the delimiter is a list
+   of block sizes with each entry corresponding to the key bit size. For most symmetric algorithms,
+   the block size is the same regardless of the key size but this arrangement allows them to be
+   different. */
+/* Return Values Meaning */
+/* <= 0 cipher not supported */
+/* > 0 the cipher block size in bytes */
+
+LIB_EXPORT INT16
+CryptGetSymmetricBlockSize(
+			   TPM_ALG_ID      symmetricAlg,   // IN: the symmetric algorithm
+			   UINT16          keySizeInBits   // IN: the key size
+			   )
+{
+    const INT16    *sizes;
+    INT16            i;
+#define ALG_CASE(SYM, sym)  case TPM_ALG_##SYM: sizes = sym##KeyBlockSizes; break
+    switch(symmetricAlg)
+	{
+#define GET_KEY_BLOCK_POINTER(SYM, sym)					\
+	    case TPM_ALG_##SYM:						\
+	      sizes =  sym##KeyBlockSizes;				\
+	      break;
+	    // Get the pointer to the block size array
+	    FOR_EACH_SYM(GET_KEY_BLOCK_POINTER);
+
+	  default:
+	    return 0;
+	}
+    // Find the index of the indicated keySizeInBits
+    for(i = 0; *sizes >= 0; i++, sizes++)
+	{
+	    if(*sizes == keySizeInBits)
+		break;
+	}
+    // If sizes is pointing at the end of the list of key sizes, then the desired
+    // key size was not found so set the block size to zero.
+    if(*sizes++ < 0)
+	return 0;
+    // Advance until the end of the list is found
+    while(*sizes++ >= 0);
+    // sizes is pointing to the first entry in the list of block sizes. Use the
+    // ith index to find the block size for the corresponding key size.
+    return sizes[i];
+}
+
+/* 10.2.20.5 Symmetric Encryption */
+/* This function performs symmetric encryption based on the mode. */
+/* Error Returns Meaning */
+/* TPM_RC_SIZE dSize is not a multiple of the block size for an algorithm that requires it */
+/* TPM_RC_FAILURE Fatal error */
+LIB_EXPORT TPM_RC
+CryptSymmetricEncrypt(
+		      BYTE                *dOut,          // OUT:
+		      TPM_ALG_ID           algorithm,     // IN: the symmetric algorithm
+		      UINT16               keySizeInBits, // IN: key size in bits
+		      const BYTE          *key,           // IN: key buffer. The size of this buffer
+		      //     in bytes is (keySizeInBits + 7) / 8
+		      TPM2B_IV            *ivInOut,       // IN/OUT: IV for decryption.
+		      TPM_ALG_ID           mode,          // IN: Mode to use
+		      INT32                dSize,         // IN: data size (may need to be a
+		      //     multiple of the blockSize)
+		      const BYTE          *dIn            // IN: data buffer
+		      )
+{
+    BYTE                *pIv;
+    int                  i;
+    BYTE                 tmp[MAX_SYM_BLOCK_SIZE];
+    BYTE                *pT;
+    tpmCryptKeySchedule_t        keySchedule;
+    INT16                blockSize;
+    TpmCryptSetSymKeyCall_t        encrypt;
+    BYTE                *iv;
+    BYTE                 defaultIv[MAX_SYM_BLOCK_SIZE] = {0};
+    //
+    pAssert(dOut != NULL && key != NULL && dIn != NULL);
+    memset((void *)&keySchedule, 0, sizeof(keySchedule));	/* silence false positive */
+    memset(tmp, 0, sizeof(tmp));
+    if(dSize == 0)
+	return TPM_RC_SUCCESS;
+    TEST(algorithm);
+    blockSize = CryptGetSymmetricBlockSize(algorithm, keySizeInBits);
+    if(blockSize == 0)
+	return TPM_RC_FAILURE;
+    // If the iv is provided, then it is expected to be block sized. In some cases,
+    // the caller is providing an array of 0's that is equal to [MAX_SYM_BLOCK_SIZE]
+    // with no knowledge of the actual block size. This function will set it.
+    if((ivInOut != NULL) && (mode != TPM_ALG_ECB))
+	{
+	    ivInOut->t.size = blockSize;
+	    iv = ivInOut->t.buffer;
+	}
+    else
+	iv = defaultIv;
+    pIv = iv;
+    // Create encrypt key schedule and set the encryption function pointer.
+    switch (algorithm)
+	{
+	    FOR_EACH_SYM(ENCRYPT_CASE)
+
+	  default:
+	    return TPM_RC_SYMMETRIC;
+	}
+    switch(mode)
+	{
+#if ALG_CTR
+	  case TPM_ALG_CTR:
+	    for(; dSize > 0; dSize -= blockSize)
+		{
+		    // Encrypt the current value of the IV(counter)
+		    ENCRYPT(&keySchedule, iv, tmp);
+		    //increment the counter (counter is big-endian so start at end)
+		    for(i = blockSize - 1; i >= 0; i--)
+			if((iv[i] += 1) != 0)
+			    break;
+		    // XOR the encrypted counter value with input and put into output
+		    pT = tmp;
+		    for(i = (dSize < blockSize) ? dSize : blockSize; i > 0; i--)
+			*dOut++ = *dIn++ ^ *pT++;
+		}
+	    break;
+#endif
+#if ALG_OFB
+	  case TPM_ALG_OFB:
+	    // This is written so that dIn and dOut may be the same
+	    for(; dSize > 0; dSize -= blockSize)
+		{
+		    // Encrypt the current value of the "IV"
+		    ENCRYPT(&keySchedule, iv, iv);
+		    // XOR the encrypted IV into dIn to create the cipher text (dOut)
+		    pIv = iv;
+		    for(i = (dSize < blockSize) ? dSize : blockSize; i > 0; i--)
+			*dOut++ = (*pIv++ ^ *dIn++);
+		}
+	    break;
+#endif
+#if ALG_CBC
+	  case TPM_ALG_CBC:
+	    // For CBC the data size must be an even multiple of the
+	    // cipher block size
+	    if((dSize % blockSize) != 0)
+		return TPM_RC_SIZE;
+	    // XOR the data block into the IV, encrypt the IV into the IV
+	    // and then copy the IV to the output
+	    for(; dSize > 0; dSize -= blockSize)
+		{
+		    pIv = iv;
+		    for(i = blockSize; i > 0; i--)
+			*pIv++ ^= *dIn++;
+		    ENCRYPT(&keySchedule, iv, iv);
+		    pIv = iv;
+		    for(i = blockSize; i > 0; i--)
+			*dOut++ = *pIv++;
+		}
+	    break;
+#endif
+	    // CFB is not optional
+	  case TPM_ALG_CFB:
+	    // Encrypt the IV into the IV, XOR in the data, and copy to output
+	    for(; dSize > 0; dSize -= blockSize)
+		{
+		    // Encrypt the current value of the IV
+		    ENCRYPT(&keySchedule, iv, iv);
+		    pIv = iv;
+		    for(i = (int)(dSize < blockSize) ? dSize : blockSize; i > 0; i--)
+			// XOR the data into the IV to create the cipher text
+			// and put into the output
+			*dOut++ = *pIv++ ^= *dIn++;
+		}
+	    // If the inner loop (i loop) was smaller than blockSize, then dSize
+	    // would have been smaller than blockSize and it is now negative. If
+	    // it is negative, then it indicates how many bytes are needed to pad
+	    // out the IV for the next round.
+	    for(; dSize < 0; dSize++)
+		*pIv++ = 0;
+	    break;
+#if ALG_ECB
+	  case TPM_ALG_ECB:
+	    // For ECB the data size must be an even multiple of the
+	    // cipher block size
+	    if((dSize % blockSize) != 0)
+		return TPM_RC_SIZE;
+	    // Encrypt the input block to the output block
+	    for(; dSize > 0; dSize -= blockSize)
+		{
+		    ENCRYPT(&keySchedule, dIn, dOut);
+		    dIn = &dIn[blockSize];
+		    dOut = &dOut[blockSize];
+		}
+	    break;
+#endif
+	  default:
+	    return TPM_RC_FAILURE;
+	}
+    return TPM_RC_SUCCESS;
+}
+/* 10.2.20.5.1 CryptSymmetricDecrypt() */
+/* This function performs symmetric decryption based on the mode. */
+/* Error Returns Meaning */
+/* TPM_RC_FAILURE A fatal error */
+/* TPM_RCS_SIZE dSize is not a multiple of the block size for an algorithm that requires it */
+LIB_EXPORT TPM_RC
+CryptSymmetricDecrypt(
+		      BYTE                *dOut,          // OUT: decrypted data
+		      TPM_ALG_ID           algorithm,     // IN: the symmetric algorithm
+		      UINT16               keySizeInBits, // IN: key size in bits
+		      const BYTE          *key,           // IN: key buffer. The size of this buffer
+		      //     in bytes is (keySizeInBits + 7) / 8
+		      TPM2B_IV            *ivInOut,       // IN/OUT: IV for decryption.
+		      TPM_ALG_ID           mode,          // IN: Mode to use
+		      INT32                dSize,         // IN: data size (may need to be a
+		      //     multiple of the blockSize)
+		      const BYTE          *dIn            // IN: data buffer
+		      )
+{
+    BYTE                *pIv;
+    int                  i;
+    BYTE                 tmp[MAX_SYM_BLOCK_SIZE];
+    BYTE                *pT;
+    tpmCryptKeySchedule_t        keySchedule;
+    INT16                blockSize;
+    BYTE                *iv;
+    TpmCryptSetSymKeyCall_t        encrypt;
+    TpmCryptSetSymKeyCall_t        decrypt;
+    BYTE                 defaultIv[MAX_SYM_BLOCK_SIZE] = {0};
+
+    memset((void *)&keySchedule, 0, sizeof(keySchedule));	/* silence false positive */
+    memset(tmp, 0, sizeof(tmp));
+    // These are used but the compiler can't tell because they are initialized
+    // in case statements and it can't tell if they are always initialized
+    // when needed, so... Comment these out if the compiler can tell or doesn't
+    // care that these are initialized before use.
+    encrypt = NULL;
+    decrypt = NULL;
+    pAssert(dOut != NULL && key != NULL && dIn != NULL);
+    if(dSize == 0)
+	return TPM_RC_SUCCESS;
+    TEST(algorithm);
+    blockSize = CryptGetSymmetricBlockSize(algorithm, keySizeInBits);
+    if(blockSize == 0)
+	return TPM_RC_FAILURE;
+    // If the iv is provided, then it is expected to be block sized. In some cases,
+    // the caller is providing an array of 0's that is equal to [MAX_SYM_BLOCK_SIZE]
+    // with no knowledge of the actual block size. This function will set it.
+    if((ivInOut != NULL) && (mode != TPM_ALG_ECB))
+	{
+	    ivInOut->t.size = blockSize;
+	    iv = ivInOut->t.buffer;
+	}
+    else
+	iv = defaultIv;
+    pIv = iv;
+    // Use the mode to select the key schedule to create. Encrypt always uses the
+    // encryption schedule. Depending on the mode, decryption might use either
+    // the decryption or encryption schedule.
+    switch(mode)
+	{
+#if ALG_CBC || ALG_ECB
+	  case TPM_ALG_CBC: // decrypt = decrypt
+	  case TPM_ALG_ECB:
+	    // For ECB and CBC, the data size must be an even multiple of the
+	    // cipher block size
+	    if((dSize % blockSize) != 0)
+		return TPM_RC_SIZE;
+	    switch (algorithm)
+		{
+		    FOR_EACH_SYM(DECRYPT_CASE)
+		  default:
+		    return TPM_RC_SYMMETRIC;
+		}
+	    break;
+#endif
+	  default:
+	    // For the remaining stream ciphers, use encryption to decrypt
+	    switch (algorithm)
+		{
+		    FOR_EACH_SYM(ENCRYPT_CASE)
+		  default:
+		    return TPM_RC_SYMMETRIC;
+		}
+	}
+    // Now do the mode-dependent decryption
+    switch(mode)
+	{
+#if ALG_CBC
+	  case TPM_ALG_CBC:
+	    // Copy the input data to a temp buffer, decrypt the buffer into the
+	    // output, XOR in the IV, and copy the temp buffer to the IV and repeat.
+	    for(; dSize > 0; dSize -= blockSize)
+		{
+		    pT = tmp;
+		    for(i = blockSize; i > 0; i--)
+			*pT++ = *dIn++;
+		    DECRYPT(&keySchedule, tmp, dOut);
+		    pIv = iv;
+		    pT = tmp;
+		    for(i = blockSize; i > 0; i--)
+			{
+			    *dOut++ ^= *pIv;
+			    *pIv++ = *pT++;
+			}
+		}
+	    break;
+#endif
+	  case TPM_ALG_CFB:
+	    for(; dSize > 0; dSize -= blockSize)
+		{
+		    // Encrypt the IV into the temp buffer
+		    ENCRYPT(&keySchedule, iv, tmp);
+		    pT = tmp;
+		    pIv = iv;
+		    for(i = (dSize < blockSize) ? dSize : blockSize; i > 0; i--)
+			// Copy the current cipher text to IV, XOR
+			// with the temp buffer and put into the output
+			*dOut++ = *pT++ ^ (*pIv++ = *dIn++);
+		}
+	    // If the inner loop (i loop) was smaller than blockSize, then dSize
+	    // would have been smaller than blockSize and it is now negative
+	    // If it is negative, then it indicates how may fill bytes
+	    // are needed to pad out the IV for the next round.
+	    for(; dSize < 0; dSize++)
+		*pIv++ = 0;
+	    break;
+#if ALG_CTR
+	  case TPM_ALG_CTR:
+	    for(; dSize > 0; dSize -= blockSize)
+		{
+		    // Encrypt the current value of the IV(counter)
+		    ENCRYPT(&keySchedule, iv, tmp);
+		    //increment the counter (counter is big-endian so start at end)
+		    for(i = blockSize - 1; i >= 0; i--)
+			if((iv[i] += 1) != 0)
+			    break;
+		    // XOR the encrypted counter value with input and put into output
+		    pT = tmp;
+		    for(i = (dSize < blockSize) ? dSize : blockSize; i > 0; i--)
+			*dOut++ = *dIn++ ^ *pT++;
+		}
+	    break;
+#endif
+#if ALG_ECB
+	  case TPM_ALG_ECB:
+	    for(; dSize > 0; dSize -= blockSize)
+		{
+		    DECRYPT(&keySchedule, dIn, dOut);
+		    dIn = &dIn[blockSize];
+		    dOut = &dOut[blockSize];
+		}
+	    break;
+#endif
+#if ALG_OFB
+	  case TPM_ALG_OFB:
+	    // This is written so that dIn and dOut may be the same
+	    for(; dSize > 0; dSize -= blockSize)
+		{
+		    // Encrypt the current value of the "IV"
+		    ENCRYPT(&keySchedule, iv, iv);
+		    // XOR the encrypted IV into dIn to create the cipher text (dOut)
+		    pIv = iv;
+		    for(i = (dSize < blockSize) ? dSize : blockSize; i > 0; i--)
+			*dOut++ = (*pIv++ ^ *dIn++);
+		}
+	    break;
+#endif
+	  default:
+	    return TPM_RC_FAILURE;
+	}
+    return TPM_RC_SUCCESS;
+}
+/* 10.2.20.5.2 CryptSymKeyValidate() */
+/* Validate that a provided symmetric key meets the requirements of the TPM */
+/* Error Returns Meaning */
+/* TPM_RC_KEY_SIZE Key size specifiers do not match */
+/* TPM_RC_KEY Key is not allowed */
+TPM_RC
+CryptSymKeyValidate(
+		    TPMT_SYM_DEF_OBJECT *symDef,
+		    TPM2B_SYM_KEY       *key
+		    )
+{
+    if(key->t.size != BITS_TO_BYTES(symDef->keyBits.sym))
+	return TPM_RCS_KEY_SIZE;
+#if ALG_TDES
+    if(symDef->algorithm == TPM_ALG_TDES && !CryptDesValidateKey(key))
+	return TPM_RCS_KEY;
+#endif // TPM_ALG_TDES
+    return TPM_RC_SUCCESS;
+}

+ 135 - 0
EVSE/GPL/ibmtpm1682/src/CryptSym.h

@@ -0,0 +1,135 @@
+/********************************************************************************/
+/*										*/
+/*		Implementation of the symmetric block cipher modes 		*/
+/*			     Written by Ken Goldman				*/
+/*		       IBM Thomas J. Watson Research Center			*/
+/*            $Id: CryptSym.h 1658 2021-01-22 23:14:01Z kgoldman $		*/
+/*										*/
+/*  Licenses and Notices							*/
+/*										*/
+/*  1. Copyright Licenses:							*/
+/*										*/
+/*  - Trusted Computing Group (TCG) grants to the user of the source code in	*/
+/*    this specification (the "Source Code") a worldwide, irrevocable, 		*/
+/*    nonexclusive, royalty free, copyright license to reproduce, create 	*/
+/*    derivative works, distribute, display and perform the Source Code and	*/
+/*    derivative works thereof, and to grant others the rights granted herein.	*/
+/*										*/
+/*  - The TCG grants to the user of the other parts of the specification 	*/
+/*    (other than the Source Code) the rights to reproduce, distribute, 	*/
+/*    display, and perform the specification solely for the purpose of 		*/
+/*    developing products based on such documents.				*/
+/*										*/
+/*  2. Source Code Distribution Conditions:					*/
+/*										*/
+/*  - Redistributions of Source Code must retain the above copyright licenses, 	*/
+/*    this list of conditions and the following disclaimers.			*/
+/*										*/
+/*  - Redistributions in binary form must reproduce the above copyright 	*/
+/*    licenses, this list of conditions	and the following disclaimers in the 	*/
+/*    documentation and/or other materials provided with the distribution.	*/
+/*										*/
+/*  3. Disclaimers:								*/
+/*										*/
+/*  - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF	*/
+/*  LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH	*/
+/*  RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES)	*/
+/*  THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE.		*/
+/*  Contact TCG Administration (admin@trustedcomputinggroup.org) for 		*/
+/*  information on specification licensing rights available through TCG 	*/
+/*  membership agreements.							*/
+/*										*/
+/*  - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED 	*/
+/*    WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR 	*/
+/*    FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR 		*/
+/*    NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY 		*/
+/*    OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE.		*/
+/*										*/
+/*  - Without limitation, TCG and its members and licensors disclaim all 	*/
+/*    liability, including liability for infringement of any proprietary 	*/
+/*    rights, relating to use of information in this specification and to the	*/
+/*    implementation of this specification, and TCG disclaims all liability for	*/
+/*    cost of procurement of substitute goods or services, lost profits, loss 	*/
+/*    of use, loss of data or any incidental, consequential, direct, indirect, 	*/
+/*    or special damages, whether under contract, tort, warranty or otherwise, 	*/
+/*    arising in any way out of use or reliance upon this specification or any 	*/
+/*    information herein.							*/
+/*										*/
+/*  (c) Copyright IBM Corp. and others, 2017 - 2021 				*/
+/*										*/
+/********************************************************************************/
+
+
+#ifndef CRYPTSYM_H
+#define CRYPTSYM_H
+
+#if ALG_AES
+#   define IF_IMPLEMENTED_AES(op)    op(AES, aes)
+#else
+#   define IF_IMPLEMENTED_AES(op)
+#endif
+#if ALG_SM4
+#   define IF_IMPLEMENTED_SM4(op)    op(SM4, sm4)
+#else
+#   define IF_IMPLEMENTED_SM4(op)
+#endif
+#if ALG_CAMELLIA
+#   define IF_IMPLEMENTED_CAMELLIA(op)    op(CAMELLIA, camellia)
+#else
+#   define IF_IMPLEMENTED_CAMELLIA(op)
+#endif
+#if ALG_TDES
+#   define IF_IMPLEMENTED_TDES(op)    op(TDES, tdes)
+#else
+#   define IF_IMPLEMENTED_TDES(op)
+#endif
+
+#define FOR_EACH_SYM(op)		\
+    IF_IMPLEMENTED_AES(op)		\
+    IF_IMPLEMENTED_SM4(op)		\
+    IF_IMPLEMENTED_CAMELLIA(op)		\
+    IF_IMPLEMENTED_TDES(op)
+
+/* Macros for creating the key schedule union */
+
+#define     KEY_SCHEDULE(SYM, sym)      tpmKeySchedule##SYM sym;
+#define     TDES    DES[3]
+typedef union tpmCryptKeySchedule_t {
+    FOR_EACH_SYM(KEY_SCHEDULE)
+
+#if SYMMETRIC_ALIGNMENT == 8
+    uint64_t            alignment;
+#else
+    uint32_t            alignment;
+#endif
+} tpmCryptKeySchedule_t;
+
+/* Each block cipher within a library is expected to conform to the same calling conventions with
+   three parameters (keySchedule, in, and out) in the same order. That means that all algorithms
+   would use the same order of the same parameters. The code is written assuming the (keySchedule,
+   in, and out) order. However, if the library uses a different order, the order can be changed with
+   a SWIZZLE macro that puts the parameters in the correct order. Note that all algorithms have to
+   use the same order and number of parameters because the code to build the calling list is common
+   for each call to encrypt or decrypt with the algorithm chosen by setting a function pointer to
+   select the algorithm that is used. */
+#   define ENCRYPT(keySchedule, in, out)	\
+    encrypt(SWIZZLE(keySchedule, in, out))
+#   define DECRYPT(keySchedule, in, out)	\
+    decrypt(SWIZZLE(keySchedule, in, out))
+
+/* Note that the macros rely on encrypt as local values in the functions that use these
+   macros. Those parameters are set by the macro that set the key schedule to be used for the
+   call. */
+
+#define ENCRYPT_CASE(ALG, alg)						\
+    case TPM_ALG_##ALG:							\
+    TpmCryptSetEncryptKey##ALG(key, keySizeInBits, &keySchedule.alg);	\
+    encrypt = (TpmCryptSetSymKeyCall_t)TpmCryptEncrypt##ALG;		\
+    break;
+#define DECRYPT_CASE(ALG, alg)						\
+    case TPM_ALG_##ALG:							\
+    TpmCryptSetDecryptKey##ALG(key, keySizeInBits, &keySchedule.alg);	\
+    decrypt = (TpmCryptSetSymKeyCall_t)TpmCryptDecrypt##ALG;		\
+    break;
+
+#endif

+ 111 - 0
EVSE/GPL/ibmtpm1682/src/CryptSym_fp.h

@@ -0,0 +1,111 @@
+/********************************************************************************/
+/*										*/
+/*			     				*/
+/*			     Written by Ken Goldman				*/
+/*		       IBM Thomas J. Watson Research Center			*/
+/*            $Id: CryptSym_fp.h 1047 2017-07-20 18:27:34Z kgoldman $		*/
+/*										*/
+/*  Licenses and Notices							*/
+/*										*/
+/*  1. Copyright Licenses:							*/
+/*										*/
+/*  - Trusted Computing Group (TCG) grants to the user of the source code in	*/
+/*    this specification (the "Source Code") a worldwide, irrevocable, 		*/
+/*    nonexclusive, royalty free, copyright license to reproduce, create 	*/
+/*    derivative works, distribute, display and perform the Source Code and	*/
+/*    derivative works thereof, and to grant others the rights granted herein.	*/
+/*										*/
+/*  - The TCG grants to the user of the other parts of the specification 	*/
+/*    (other than the Source Code) the rights to reproduce, distribute, 	*/
+/*    display, and perform the specification solely for the purpose of 		*/
+/*    developing products based on such documents.				*/
+/*										*/
+/*  2. Source Code Distribution Conditions:					*/
+/*										*/
+/*  - Redistributions of Source Code must retain the above copyright licenses, 	*/
+/*    this list of conditions and the following disclaimers.			*/
+/*										*/
+/*  - Redistributions in binary form must reproduce the above copyright 	*/
+/*    licenses, this list of conditions	and the following disclaimers in the 	*/
+/*    documentation and/or other materials provided with the distribution.	*/
+/*										*/
+/*  3. Disclaimers:								*/
+/*										*/
+/*  - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF	*/
+/*  LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH	*/
+/*  RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES)	*/
+/*  THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE.		*/
+/*  Contact TCG Administration (admin@trustedcomputinggroup.org) for 		*/
+/*  information on specification licensing rights available through TCG 	*/
+/*  membership agreements.							*/
+/*										*/
+/*  - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED 	*/
+/*    WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR 	*/
+/*    FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR 		*/
+/*    NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY 		*/
+/*    OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE.		*/
+/*										*/
+/*  - Without limitation, TCG and its members and licensors disclaim all 	*/
+/*    liability, including liability for infringement of any proprietary 	*/
+/*    rights, relating to use of information in this specification and to the	*/
+/*    implementation of this specification, and TCG disclaims all liability for	*/
+/*    cost of procurement of substitute goods or services, lost profits, loss 	*/
+/*    of use, loss of data or any incidental, consequential, direct, indirect, 	*/
+/*    or special damages, whether under contract, tort, warranty or otherwise, 	*/
+/*    arising in any way out of use or reliance upon this specification or any 	*/
+/*    information herein.							*/
+/*										*/
+/*  (c) Copyright IBM Corp. and others, 2016					*/
+/*										*/
+/********************************************************************************/
+
+#ifndef CRYPTSYM_FP_H
+#define CRYPTSYM_FP_H
+
+BOOL
+CryptSymInit(
+	     void
+	     );
+BOOL
+CryptSymStartup(
+		void
+		);
+LIB_EXPORT INT16
+CryptGetSymmetricBlockSize(
+			   TPM_ALG_ID      symmetricAlg,   // IN: the symmetric algorithm
+			   UINT16          keySizeInBits   // IN: the key size
+			   );
+LIB_EXPORT TPM_RC
+CryptSymmetricEncrypt(
+		      BYTE                *dOut,          // OUT:
+		      TPM_ALG_ID           algorithm,     // IN: the symmetric algorithm
+		      UINT16               keySizeInBits, // IN: key size in bits
+		      const BYTE          *key,           // IN: key buffer. The size of this buffer
+		      //     in bytes is (keySizeInBits + 7) / 8
+		      TPM2B_IV            *ivInOut,       // IN/OUT: IV for decryption.
+		      TPM_ALG_ID           mode,          // IN: Mode to use
+		      INT32                dSize,         // IN: data size (may need to be a
+		      //     multiple of the blockSize)
+		      const BYTE          *dIn            // IN: data buffer
+		      );
+LIB_EXPORT TPM_RC
+CryptSymmetricDecrypt(
+		      BYTE                *dOut,          // OUT: decrypted data
+		      TPM_ALG_ID           algorithm,     // IN: the symmetric algorithm
+		      UINT16               keySizeInBits, // IN: key size in bits
+		      const BYTE          *key,           // IN: key buffer. The size of this buffer
+		      //     in bytes is (keySizeInBits + 7) / 8
+		      TPM2B_IV            *ivInOut,       // IN/OUT: IV for decryption.
+		      TPM_ALG_ID           mode,          // IN: Mode to use
+		      INT32                dSize,         // IN: data size (may need to be a
+		      //     multiple of the blockSize)
+		      const BYTE          *dIn            // IN: data buffer
+		      );
+TPM_RC
+CryptSymKeyValidate(
+		    TPMT_SYM_DEF_OBJECT *symDef,
+		    TPM2B_SYM_KEY       *key
+		    );
+
+
+#endif

+ 93 - 0
EVSE/GPL/ibmtpm1682/src/CryptTest.h

@@ -0,0 +1,93 @@
+/********************************************************************************/
+/*										*/
+/*			  constant definitions used for self-test.   		*/
+/*			     Written by Ken Goldman				*/
+/*		       IBM Thomas J. Watson Research Center			*/
+/*            $Id: CryptTest.h 1594 2020-03-26 22:15:48Z kgoldman $		*/
+/*										*/
+/*  Licenses and Notices							*/
+/*										*/
+/*  1. Copyright Licenses:							*/
+/*										*/
+/*  - Trusted Computing Group (TCG) grants to the user of the source code in	*/
+/*    this specification (the "Source Code") a worldwide, irrevocable, 		*/
+/*    nonexclusive, royalty free, copyright license to reproduce, create 	*/
+/*    derivative works, distribute, display and perform the Source Code and	*/
+/*    derivative works thereof, and to grant others the rights granted herein.	*/
+/*										*/
+/*  - The TCG grants to the user of the other parts of the specification 	*/
+/*    (other than the Source Code) the rights to reproduce, distribute, 	*/
+/*    display, and perform the specification solely for the purpose of 		*/
+/*    developing products based on such documents.				*/
+/*										*/
+/*  2. Source Code Distribution Conditions:					*/
+/*										*/
+/*  - Redistributions of Source Code must retain the above copyright licenses, 	*/
+/*    this list of conditions and the following disclaimers.			*/
+/*										*/
+/*  - Redistributions in binary form must reproduce the above copyright 	*/
+/*    licenses, this list of conditions	and the following disclaimers in the 	*/
+/*    documentation and/or other materials provided with the distribution.	*/
+/*										*/
+/*  3. Disclaimers:								*/
+/*										*/
+/*  - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF	*/
+/*  LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH	*/
+/*  RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES)	*/
+/*  THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE.		*/
+/*  Contact TCG Administration (admin@trustedcomputinggroup.org) for 		*/
+/*  information on specification licensing rights available through TCG 	*/
+/*  membership agreements.							*/
+/*										*/
+/*  - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED 	*/
+/*    WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR 	*/
+/*    FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR 		*/
+/*    NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY 		*/
+/*    OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE.		*/
+/*										*/
+/*  - Without limitation, TCG and its members and licensors disclaim all 	*/
+/*    liability, including liability for infringement of any proprietary 	*/
+/*    rights, relating to use of information in this specification and to the	*/
+/*    implementation of this specification, and TCG disclaims all liability for	*/
+/*    cost of procurement of substitute goods or services, lost profits, loss 	*/
+/*    of use, loss of data or any incidental, consequential, direct, indirect, 	*/
+/*    or special damages, whether under contract, tort, warranty or otherwise, 	*/
+/*    arising in any way out of use or reliance upon this specification or any 	*/
+/*    information herein.							*/
+/*										*/
+/*  (c) Copyright IBM Corp. and others, 2016 - 2020				*/
+/*										*/
+/********************************************************************************/
+
+#ifndef CRYPTTEST_H
+#define CRYPTTEST_H
+
+/* 10.1.7 CryptTest.h */
+/* This file contains constant definitions used for self test */
+/* This is the definition of a bit array with one bit per algorithm */
+/* NOTE: Since bit numbering starts at zero, when TPM_ALG_LAST is a multiple of 8,
+   ALGORITHM_VECTOR will need to have byte for the single bit in the last byte. So, for example,
+   when TPM_ALG_LAST is 8, ALGORITHM_VECTOR will need 2 bytes. */
+#define ALGORITHM_VECTOR_BYTES  ((TPM_ALG_LAST + 8) / 8)
+typedef BYTE    ALGORITHM_VECTOR[ALGORITHM_VECTOR_BYTES];
+#ifdef  TEST_SELF_TEST
+LIB_EXPORT    extern  ALGORITHM_VECTOR    LibToTest;
+#endif
+/* This structure is used to contain self-test tracking information for the cryptographic
+   modules. Each of the major modules is given a 32-bit value in which it may maintain its own self
+   test information. The convention for this state is that when all of the bits in this structure
+   are 0, all functions need to be tested. */
+typedef struct
+{
+    UINT32      rng;
+    UINT32      hash;
+    UINT32      sym;
+#if ALG_RSA
+    UINT32      rsa;
+#endif
+#if ALG_ECC
+    UINT32      ecc;
+#endif
+} CRYPTO_SELF_TEST_STATE;
+#endif // _CRYPT_TEST_H
+

+ 1739 - 0
EVSE/GPL/ibmtpm1682/src/CryptUtil.c

@@ -0,0 +1,1739 @@
+/********************************************************************************/
+/*										*/
+/*			Interfaces to the Crypto Engine				*/
+/*			     Written by Ken Goldman				*/
+/*		       IBM Thomas J. Watson Research Center			*/
+/*            $Id: CryptUtil.c 1682 2022-07-06 15:06:36Z kgold $		*/
+/*										*/
+/*  Licenses and Notices							*/
+/*										*/
+/*  1. Copyright Licenses:							*/
+/*										*/
+/*  - Trusted Computing Group (TCG) grants to the user of the source code in	*/
+/*    this specification (the "Source Code") a worldwide, irrevocable, 		*/
+/*    nonexclusive, royalty free, copyright license to reproduce, create 	*/
+/*    derivative works, distribute, display and perform the Source Code and	*/
+/*    derivative works thereof, and to grant others the rights granted herein.	*/
+/*										*/
+/*  - The TCG grants to the user of the other parts of the specification 	*/
+/*    (other than the Source Code) the rights to reproduce, distribute, 	*/
+/*    display, and perform the specification solely for the purpose of 		*/
+/*    developing products based on such documents.				*/
+/*										*/
+/*  2. Source Code Distribution Conditions:					*/
+/*										*/
+/*  - Redistributions of Source Code must retain the above copyright licenses, 	*/
+/*    this list of conditions and the following disclaimers.			*/
+/*										*/
+/*  - Redistributions in binary form must reproduce the above copyright 	*/
+/*    licenses, this list of conditions	and the following disclaimers in the 	*/
+/*    documentation and/or other materials provided with the distribution.	*/
+/*										*/
+/*  3. Disclaimers:								*/
+/*										*/
+/*  - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF	*/
+/*  LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH	*/
+/*  RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES)	*/
+/*  THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE.		*/
+/*  Contact TCG Administration (admin@trustedcomputinggroup.org) for 		*/
+/*  information on specification licensing rights available through TCG 	*/
+/*  membership agreements.							*/
+/*										*/
+/*  - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED 	*/
+/*    WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR 	*/
+/*    FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR 		*/
+/*    NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY 		*/
+/*    OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE.		*/
+/*										*/
+/*  - Without limitation, TCG and its members and licensors disclaim all 	*/
+/*    liability, including liability for infringement of any proprietary 	*/
+/*    rights, relating to use of information in this specification and to the	*/
+/*    implementation of this specification, and TCG disclaims all liability for	*/
+/*    cost of procurement of substitute goods or services, lost profits, loss 	*/
+/*    of use, loss of data or any incidental, consequential, direct, indirect, 	*/
+/*    or special damages, whether under contract, tort, warranty or otherwise, 	*/
+/*    arising in any way out of use or reliance upon this specification or any 	*/
+/*    information herein.							*/
+/*										*/
+/*  (c) Copyright IBM Corp. and others, 2016 - 2021				*/
+/*										*/
+/********************************************************************************/
+
+/* 10.2.6 CryptUtil.c */
+/* 10.2.6.1 Introduction */
+/* This module contains the interfaces to the CryptoEngine() and provides miscellaneous
+   cryptographic functions in support of the TPM. */
+/* 10.2.6.2 Includes */
+#include "Tpm.h"
+/* 10.2.6.3 Hash/HMAC Functions */
+/* 10.2.6.3.1 CryptHmacSign() */
+/* Sign a digest using an HMAC key. This an HMAC of a digest, not an HMAC of a message. */
+/* Error Returns Meaning */
+/* TPM_RC_HASH not a valid hash */
+static TPM_RC
+CryptHmacSign(
+	      TPMT_SIGNATURE      *signature,     // OUT: signature
+	      OBJECT              *signKey,       // IN: HMAC key sign the hash
+	      TPM2B_DIGEST        *hashData       // IN: hash to be signed
+	      )
+{
+    HMAC_STATE       hmacState;
+    UINT32           digestSize;
+    digestSize = CryptHmacStart2B(&hmacState, signature->signature.any.hashAlg,
+				  &signKey->sensitive.sensitive.bits.b);
+    CryptDigestUpdate2B(&hmacState.hashState, &hashData->b);
+    CryptHmacEnd(&hmacState, digestSize,
+		 (BYTE *)&signature->signature.hmac.digest);
+    return TPM_RC_SUCCESS;
+}
+/* 10.2.6.3.2 CryptHMACVerifySignature() */
+/* This function will verify a signature signed by a HMAC key. Note that a caller needs to prepare
+   signature with the signature algorithm (TPM_ALG_HMAC) and the hash algorithm to use. This
+   function then builds a signature of that type. */
+/* Error Returns Meaning */
+/* TPM_RC_SCHEME not the proper scheme for this key type */
+/* TPM_RC_SIGNATURE if invalid input or signature is not genuine */
+static TPM_RC
+CryptHMACVerifySignature(
+			 OBJECT              *signKey,       // IN: HMAC key signed the hash
+			 TPM2B_DIGEST        *hashData,      // IN: digest being verified
+			 TPMT_SIGNATURE      *signature      // IN: signature to be verified
+			 )
+{
+    TPMT_SIGNATURE           test;
+    TPMT_KEYEDHASH_SCHEME   *keyScheme =
+	&signKey->publicArea.parameters.keyedHashDetail.scheme;
+    //
+    if((signature->sigAlg != TPM_ALG_HMAC)
+       || (signature->signature.hmac.hashAlg == TPM_ALG_NULL))
+	return TPM_RC_SCHEME;
+    // This check is not really needed for verification purposes. However, it does
+    // prevent someone from trying to validate a signature using a weaker hash
+    // algorithm than otherwise allowed by the key. That is, a key with a scheme
+    // other than TMP_ALG_NULL can only be used to validate signatures that have
+    // a matching scheme.
+    if((keyScheme->scheme != TPM_ALG_NULL)
+       && ((keyScheme->scheme != signature->sigAlg)
+	   || (keyScheme->details.hmac.hashAlg != signature->signature.any.hashAlg)))
+	return TPM_RC_SIGNATURE;
+    test.sigAlg = signature->sigAlg;
+    test.signature.hmac.hashAlg = signature->signature.hmac.hashAlg;
+    CryptHmacSign(&test, signKey, hashData);
+    // Compare digest
+    if(!MemoryEqual(&test.signature.hmac.digest,
+		    &signature->signature.hmac.digest,
+		    CryptHashGetDigestSize(signature->signature.any.hashAlg)))
+	return TPM_RC_SIGNATURE;
+    return TPM_RC_SUCCESS;
+}
+/* 10.2.6.3.3 CryptGenerateKeyedHash() */
+/* This function creates a keyedHash object. */
+/* Error Returns Meaning */
+/* TPM_RC_NO_RESULT cannot get values from random number generator */
+/* TPM_RC_SIZE sensitive data size is larger than allowed for the scheme */
+static TPM_RC
+CryptGenerateKeyedHash(
+		       TPMT_PUBLIC             *publicArea,        // IN/OUT: the public area template
+		       //     for the new key.
+		       TPMT_SENSITIVE          *sensitive,         // OUT: sensitive area
+		       TPMS_SENSITIVE_CREATE   *sensitiveCreate,   // IN: sensitive creation data
+		       RAND_STATE              *rand               // IN: "entropy" source
+		       )
+{
+    TPMT_KEYEDHASH_SCHEME   *scheme;
+    TPM_ALG_ID               hashAlg;
+    UINT16                   digestSize;
+    
+    scheme = &publicArea->parameters.keyedHashDetail.scheme;
+    
+    if(publicArea->type != TPM_ALG_KEYEDHASH)
+	return TPM_RC_FAILURE;
+    // Pick the limiting hash algorithm
+    if(scheme->scheme == TPM_ALG_NULL)
+	hashAlg = publicArea->nameAlg;
+    else if(scheme->scheme == TPM_ALG_XOR)
+	hashAlg = scheme->details.xorr.hashAlg;
+    else
+	hashAlg = scheme->details.hmac.hashAlg;
+    /* hashBlockSize = CryptHashGetBlockSize(hashAlg); */
+    digestSize = CryptHashGetDigestSize(hashAlg);
+    
+    // if this is a signing or a decryption key, then the limit
+    // for the data size is the block size of the hash. This limit
+    // is set because larger values have lower entropy because of the
+    // HMAC function. The lower limit is 1/2 the size of the digest
+    //
+    //If the user provided the key, check that it is a proper size
+    if(sensitiveCreate->data.t.size != 0)
+	{
+	    if(IS_ATTRIBUTE(publicArea->objectAttributes, TPMA_OBJECT, decrypt)
+	       || IS_ATTRIBUTE(publicArea->objectAttributes, TPMA_OBJECT, sign))
+		{
+		    if(sensitiveCreate->data.t.size > CryptHashGetBlockSize(hashAlg))
+			return TPM_RC_SIZE;
+#if 0   // May make this a FIPS-mode requirement
+		    if(sensitiveCreate->data.t.size < (digestSize / 2))
+			return TPM_RC_SIZE;
+#endif
+		}
+	    // If this is a data blob, then anything that will get past the unmarshaling
+	    // is OK
+	    MemoryCopy2B(&sensitive->sensitive.bits.b, &sensitiveCreate->data.b,
+			 sizeof(sensitive->sensitive.bits.t.buffer));
+	}
+    else
+	{
+	    // The TPM is going to generate the data so set the size to be the
+	    // size of the digest of the algorithm
+	    sensitive->sensitive.bits.t.size =
+		DRBG_Generate(rand, sensitive->sensitive.bits.t.buffer, digestSize);
+	    if(sensitive->sensitive.bits.t.size == 0)
+		return (g_inFailureMode) ? TPM_RC_FAILURE : TPM_RC_NO_RESULT;
+	}
+    return TPM_RC_SUCCESS;
+}
+/* 10.2.6.3.4 CryptIsSchemeAnonymous() */
+/* This function is used to test a scheme to see if it is an anonymous scheme The only anonymous
+   scheme is ECDAA. ECDAA can be used to do things like U-Prove. */
+BOOL
+CryptIsSchemeAnonymous(
+		       TPM_ALG_ID       scheme         // IN: the scheme algorithm to test
+		       )
+{
+    return scheme == TPM_ALG_ECDAA;
+}
+/* 10.2.6.4 Symmetric Functions */
+/* 10.2.6.4.1 ParmDecryptSym() */
+/* This function performs parameter decryption using symmetric block cipher. */
+void
+ParmDecryptSym(
+	       TPM_ALG_ID       symAlg,        // IN: the symmetric algorithm
+	       TPM_ALG_ID       hash,          // IN: hash algorithm for KDFa
+	       UINT16           keySizeInBits, // IN: the key size in bits
+	       TPM2B           *key,           // IN: KDF HMAC key
+	       TPM2B           *nonceCaller,   // IN: nonce caller
+	       TPM2B           *nonceTpm,      // IN: nonce TPM
+	       UINT32           dataSize,      // IN: size of parameter buffer
+	       BYTE            *data           // OUT: buffer to be decrypted
+	       )
+{
+    // KDF output buffer
+    // It contains parameters for the CFB encryption
+    // From MSB to LSB, they are the key and iv
+    BYTE             symParmString[MAX_SYM_KEY_BYTES + MAX_SYM_BLOCK_SIZE];
+    // Symmetric key size in byte
+    UINT16           keySize = (keySizeInBits + 7) / 8;
+    TPM2B_IV         iv;
+    iv.t.size = CryptGetSymmetricBlockSize(symAlg, keySizeInBits);
+    // If there is decryption to do...
+    if(iv.t.size > 0)
+	{
+	    // Generate key and iv
+	    CryptKDFa(hash, key, CFB_KEY, nonceCaller, nonceTpm,
+		      keySizeInBits + (iv.t.size * 8), symParmString, NULL, FALSE);
+	    MemoryCopy(iv.t.buffer, &symParmString[keySize], iv.t.size);
+	    CryptSymmetricDecrypt(data, symAlg, keySizeInBits, symParmString,
+				  &iv, TPM_ALG_CFB, dataSize, data);
+	}
+    return;
+}
+/* 10.2.6.4.2 ParmEncryptSym() */
+/* This function performs parameter encryption using symmetric block cipher. */
+void
+ParmEncryptSym(
+	       TPM_ALG_ID       symAlg,        // IN: symmetric algorithm
+	       TPM_ALG_ID       hash,          // IN: hash algorithm for KDFa
+	       UINT16           keySizeInBits, // IN: AES symmetric key size in bits
+	       TPM2B           *key,           // IN: KDF HMAC key
+	       TPM2B           *nonceCaller,   // IN: nonce caller
+	       TPM2B           *nonceTpm,      // IN: nonce TPM
+	       UINT32           dataSize,      // IN: size of parameter buffer
+	       BYTE            *data           // OUT: buffer to be encrypted
+	       )
+{
+    // KDF output buffer
+    // It contains parameters for the CFB encryption
+    BYTE             symParmString[MAX_SYM_KEY_BYTES + MAX_SYM_BLOCK_SIZE];
+    // Symmetric key size in bytes
+    UINT16           keySize = (keySizeInBits + 7) / 8;
+    TPM2B_IV         iv;
+    iv.t.size = CryptGetSymmetricBlockSize(symAlg, keySizeInBits);
+    // See if there is any encryption to do
+    if(iv.t.size > 0)
+	{
+	    // Generate key and iv
+	    CryptKDFa(hash, key, CFB_KEY, nonceTpm, nonceCaller,
+		      keySizeInBits + (iv.t.size * 8), symParmString, NULL, FALSE);
+	    MemoryCopy(iv.t.buffer, &symParmString[keySize], iv.t.size);
+	    CryptSymmetricEncrypt(data, symAlg, keySizeInBits, symParmString, &iv,
+				  TPM_ALG_CFB, dataSize, data);
+	}
+    return;
+}
+/* 10.2.6.4.3 CryptGenerateKeySymmetric() */
+/* This function generates a symmetric cipher key. The derivation process is determined by the type
+   of the provided rand */
+/* Error Returns Meaning */
+/* TPM_RC_NO_RESULT cannot get a random value */
+/* TPM_RC_KEY_SIZE key size in the public area does not match the size in the sensitive creation
+   area */
+/* TPM_RC_KEY provided key value is not allowed */
+static TPM_RC
+CryptGenerateKeySymmetric(
+			  TPMT_PUBLIC             *publicArea,        // IN/OUT: The public area template
+			  //     for the new key.
+			  TPMT_SENSITIVE          *sensitive,         // OUT: sensitive area
+			  TPMS_SENSITIVE_CREATE   *sensitiveCreate,   // IN: sensitive creation data
+			  RAND_STATE              *rand               // IN: the "entropy" source for
+			  )
+{
+    UINT16           keyBits = publicArea->parameters.symDetail.sym.keyBits.sym;
+    TPM_RC           result;
+    //
+    // only do multiples of RADIX_BITS
+    if((keyBits % RADIX_BITS) != 0)
+	return TPM_RC_KEY_SIZE;
+    // If this is not a new key, then the provided key data must be the right size
+    if(sensitiveCreate->data.t.size != 0)
+	{
+	    result = CryptSymKeyValidate(&publicArea->parameters.symDetail.sym,
+					 (TPM2B_SYM_KEY *)&sensitiveCreate->data);
+	    if(result == TPM_RC_SUCCESS)
+		MemoryCopy2B(&sensitive->sensitive.sym.b, &sensitiveCreate->data.b,
+			     sizeof(sensitive->sensitive.sym.t.buffer));
+	}
+#if ALG_TDES
+    else if(publicArea->parameters.symDetail.sym.algorithm == TPM_ALG_TDES)
+	{
+	    sensitive->sensitive.sym.t.size = keyBits / 8;
+	    result = CryptGenerateKeyDes(publicArea, sensitive, rand);
+	}
+#endif
+    else
+    {
+	sensitive->sensitive.sym.t.size =
+	    DRBG_Generate(rand, sensitive->sensitive.sym.t.buffer,
+			  BITS_TO_BYTES(keyBits));
+	if(g_inFailureMode)
+	    result = TPM_RC_FAILURE;
+	else if(sensitive->sensitive.sym.t.size == 0)
+	    result = TPM_RC_NO_RESULT;
+	else
+	    result = TPM_RC_SUCCESS;
+    }
+    return result;
+}
+/* 10.2.6.4.4 CryptXORObfuscation() */
+/* This function implements XOR obfuscation. It should not be called if the hash algorithm is not
+   implemented. The only return value from this function is TPM_RC_SUCCESS. */
+void
+CryptXORObfuscation(
+		    TPM_ALG_ID       hash,          // IN: hash algorithm for KDF
+		    TPM2B           *key,           // IN: KDF key
+		    TPM2B           *contextU,      // IN: contextU
+		    TPM2B           *contextV,      // IN: contextV
+		    UINT32           dataSize,      // IN: size of data buffer
+		    BYTE            *data           // IN/OUT: data to be XORed in place
+		    )
+{
+    BYTE             mask[MAX_DIGEST_SIZE]; // Allocate a digest sized buffer
+    BYTE            *pm;
+    UINT32           i;
+    UINT32           counter = 0;
+    UINT16           hLen = CryptHashGetDigestSize(hash);
+    UINT32           requestSize = dataSize * 8;
+    INT32            remainBytes = (INT32)dataSize;
+    pAssert((key != NULL) && (data != NULL) && (hLen != 0));
+    // Call KDFa to generate XOR mask
+    for(; remainBytes > 0; remainBytes -= hLen)
+	{
+	    // Make a call to KDFa to get next iteration
+	    CryptKDFa(hash, key, XOR_KEY, contextU, contextV,
+		      requestSize, mask, &counter, TRUE);
+	    // XOR next piece of the data
+	    pm = mask;
+	    for(i = hLen < remainBytes ? hLen : remainBytes; i > 0; i--)
+		*data++ ^= *pm++;
+	}
+    return;
+}
+/* 10.2.6.5 Initialization and shut down */
+/* 10.2.6.5.1 CryptInit() */
+/* This function is called when the TPM receives a _TPM_Init() indication. */
+/* NOTE: The hash algorithms do not have to be tested, they just need to be available. They have to
+   be tested before the TPM can accept HMAC authorization or return any result that relies on a hash
+   algorithm. */
+/* Return Values Meaning */
+/* TRUE initializations succeeded */
+/* FALSE initialization failed and caller should place the TPM into Failure Mode */
+BOOL
+CryptInit(
+	  void
+	  )
+{
+    BOOL         ok;
+    // Initialize the vector of implemented algorithms
+    AlgorithmGetImplementedVector(&g_implementedAlgorithms);
+    // Indicate that all test are necessary
+    CryptInitializeToTest();
+    // Do any library initializations that are necessary. If any fails,
+    // the caller should go into failure mode;
+    ok = SupportLibInit();
+    ok = ok && CryptSymInit();
+    ok = ok && CryptRandInit();
+    ok = ok && CryptHashInit();
+#if ALG_RSA
+    ok = ok && CryptRsaInit();
+#endif // TPM_ALG_RSA
+#if ALG_ECC
+    ok = ok && CryptEccInit();
+#endif // TPM_ALG_ECC
+    return ok;
+}
+/* 10.2.6.5.2 CryptStartup() */
+/* This function is called by TPM2_Startup() to initialize the functions in this cryptographic
+   library and in the provided CryptoLibrary(). This function and CryptUtilInit() are both provided
+   so that the implementation may move the initialization around to get the best interaction. */
+/* Return Values Meaning */
+/* TRUE startup succeeded */
+/* FALSE startup failed and caller should place the TPM into Failure Mode */
+BOOL
+CryptStartup(
+	     STARTUP_TYPE     type           // IN: the startup type
+	     )
+{
+    BOOL            OK;
+    NOT_REFERENCED(type);
+    OK = CryptSymStartup();
+    OK = OK && CryptRandStartup();
+    OK = OK && CryptHashStartup();
+#if ALG_RSA
+    OK = OK && CryptRsaStartup();
+#endif // TPM_ALG_RSA
+#if ALG_ECC
+    OK = OK && CryptEccStartup();
+#endif // TPM_ALG_ECC
+	 ;
+#if ALG_ECC
+    // Don't directly check for SU_RESET because that is the default
+    if(OK && (type != SU_RESTART) && (type != SU_RESUME))
+	{
+	    // If the shutdown was orderly, then the values recovered from NV will
+	    // be OK to use.
+	    // Get a new  random commit nonce
+	    gr.commitNonce.t.size = sizeof(gr.commitNonce.t.buffer);
+	    CryptRandomGenerate(gr.commitNonce.t.size, gr.commitNonce.t.buffer);
+	    // Reset the counter and commit array
+	    gr.commitCounter = 0;
+	    MemorySet(gr.commitArray, 0, sizeof(gr.commitArray));
+	}
+#endif // TPM_ALG_ECC
+    return OK;
+}
+/* 10.2.6.6 Algorithm-Independent Functions */
+/* 10.2.6.6.1 Introduction */
+/* These functions are used generically when a function of a general type (e.g., symmetric
+   encryption) is required.  The functions will modify the parameters as required to interface to
+   the indicated algorithms. */
+/* 10.2.6.6.2 CryptIsAsymAlgorithm() */
+/* This function indicates if an algorithm is an asymmetric algorithm. */
+/* Return Values Meaning */
+/* TRUE if it is an asymmetric algorithm */
+/* FALSE if it is not an asymmetric algorithm */
+BOOL
+CryptIsAsymAlgorithm(
+		     TPM_ALG_ID       algID          // IN: algorithm ID
+		     )
+{
+    switch(algID)
+	{
+#if ALG_RSA
+	  case TPM_ALG_RSA:
+#endif
+#if ALG_ECC
+	  case TPM_ALG_ECC:
+#endif
+	    return TRUE;
+	    break;
+	  default:
+	    break;
+	}
+    return FALSE;
+}
+/* 10.2.6.6.3 CryptSecretEncrypt() */
+/* This function creates a secret value and its associated secret structure using an asymmetric
+   algorithm. */
+/* This function is used by TPM2_Rewrap() TPM2_MakeCredential(), and TPM2_Duplicate(). */
+/* Error Returns Meaning */
+/* TPM_RC_ATTRIBUTES keyHandle does not reference a valid decryption key */
+/* TPM_RC_KEY invalid ECC key (public point is not on the curve) */
+/* TPM_RC_SCHEME RSA key with an unsupported padding scheme */
+/* TPM_RC_VALUE numeric value of the data to be decrypted is greater than the RSA key modulus */
+TPM_RC
+CryptSecretEncrypt(
+		   OBJECT                  *encryptKey,    // IN: encryption key object
+		   const TPM2B             *label,         // IN: a null-terminated string as L
+		   TPM2B_DATA              *data,          // OUT: secret value
+		   TPM2B_ENCRYPTED_SECRET  *secret         // OUT: secret structure
+		   )
+{
+    TPMT_RSA_DECRYPT         scheme;
+    TPM_RC                   result = TPM_RC_SUCCESS;
+    //
+    if(data == NULL || secret == NULL)
+	return TPM_RC_FAILURE;
+    // The output secret value has the size of the digest produced by the nameAlg.
+    data->t.size = CryptHashGetDigestSize(encryptKey->publicArea.nameAlg);
+    // The encryption scheme is OAEP using the nameAlg of the encrypt key.
+    scheme.scheme = TPM_ALG_OAEP;
+    scheme.details.anySig.hashAlg = encryptKey->publicArea.nameAlg;
+    if(!IS_ATTRIBUTE(encryptKey->publicArea.objectAttributes, TPMA_OBJECT, decrypt))
+	return TPM_RC_ATTRIBUTES;
+    switch(encryptKey->publicArea.type)
+	{
+#if ALG_RSA
+	  case TPM_ALG_RSA:
+	      {
+		  // Create secret data from RNG
+		  CryptRandomGenerate(data->t.size, data->t.buffer);
+		  // Encrypt the data by RSA OAEP into encrypted secret
+		  result = CryptRsaEncrypt((TPM2B_PUBLIC_KEY_RSA *)secret, &data->b,
+					   encryptKey, &scheme, label, NULL);
+	      }
+	      break;
+#endif //TPM_ALG_RSA
+#if ALG_ECC
+	  case TPM_ALG_ECC:
+	      {
+		  TPMS_ECC_POINT      eccPublic;
+		  TPM2B_ECC_PARAMETER eccPrivate;
+		  TPMS_ECC_POINT      eccSecret;
+		  BYTE                *buffer = secret->t.secret;
+		  // Need to make sure that the public point of the key is on the
+		  // curve defined by the key.
+		  if(!CryptEccIsPointOnCurve(
+					     encryptKey->publicArea.parameters.eccDetail.curveID,
+					     &encryptKey->publicArea.unique.ecc))
+		      result = TPM_RC_KEY;
+		  else
+		      {
+			  // Call crypto engine to create an auxiliary ECC key
+			  // We assume crypt engine initialization should always success.
+			  // Otherwise, TPM should go to failure mode.
+			  CryptEccNewKeyPair(&eccPublic, &eccPrivate,
+					     encryptKey->publicArea.parameters.eccDetail.curveID);
+			  // Marshal ECC public to secret structure. This will be used by the
+			  // recipient to decrypt the secret with their private key.
+			  secret->t.size = TPMS_ECC_POINT_Marshal(&eccPublic, &buffer, NULL);
+			  // Compute ECDH shared secret which is R = [d]Q where d is the
+			  // private part of the ephemeral key and Q is the public part of a
+			  // TPM key. TPM_RC_KEY error return from CryptComputeECDHSecret
+			  // because the auxiliary ECC key is just created according to the
+			  // parameters of input ECC encrypt key.
+			  if(CryptEccPointMultiply(&eccSecret,
+						   encryptKey->publicArea.parameters.eccDetail.curveID,
+						   &encryptKey->publicArea.unique.ecc, &eccPrivate,
+						   NULL, NULL) != TPM_RC_SUCCESS)
+			      result = TPM_RC_KEY;
+			  else
+			      {
+				  // The secret value is computed from Z using KDFe as:
+				  // secret := KDFe(HashID, Z, Use, PartyUInfo, PartyVInfo, bits)
+				  // Where:
+				  //  HashID  the nameAlg of the decrypt key
+				  //  Z   the x coordinate (Px) of the product (P) of the point
+				  //      (Q) of the secret and the private x coordinate (de,V)
+				  //      of the decryption key
+				  //  Use a null-terminated string containing "SECRET"
+				  //  PartyUInfo  the x coordinate of the point in the secret
+				  //              (Qe,U )
+				  //  PartyVInfo  the x coordinate of the public key (Qs,V )
+				  //  bits    the number of bits in the digest of HashID
+				  // Retrieve seed from KDFe
+				  CryptKDFe(encryptKey->publicArea.nameAlg, &eccSecret.x.b,
+					    label, &eccPublic.x.b,
+					    &encryptKey->publicArea.unique.ecc.x.b,
+					    data->t.size * 8, data->t.buffer);
+			      }
+		      }
+	      }
+	      break;
+#endif //TPM_ALG_ECC
+	  default:
+	    FAIL(FATAL_ERROR_INTERNAL);
+	    break;
+	}
+    return result;
+}
+/* 10.2.6.6.4 CryptSecretDecrypt() */
+/* Decrypt a secret value by asymmetric (or symmetric) algorithm This function is used for
+   ActivateCredential() and Import for asymmetric decryption, and StartAuthSession() for both
+   asymmetric and symmetric decryption process */
+/* Error Returns Meaning */
+/* TPM_RC_ATTRIBUTES RSA key is not a decryption key */
+/* TPM_RC_BINDING Invalid RSA key (public and private parts are not cryptographically bound. */
+/* TPM_RC_ECC_POINT ECC point in the secret is not on the curve */
+/* TPM_RC_INSUFFICIENT failed to retrieve ECC point from the secret */
+/* TPM_RC_NO_RESULT multiplication resulted in ECC point at infinity */
+/* TPM_RC_SIZE data to decrypt is not of the same size as RSA key */
+/* TPM_RC_VALUE For RSA key, numeric value of the encrypted data is greater than the modulus, or the
+   recovered data is larger than the output buffer. For keyedHash or symmetric key, the secret is
+   larger than the size of the digest produced by the name algorithm. */
+/* TPM_RC_FAILURE internal error */
+TPM_RC
+CryptSecretDecrypt(
+		   OBJECT                 *decryptKey,    // IN: decrypt key
+		   TPM2B_NONCE             *nonceCaller,   // IN: nonceCaller.  It is needed for
+		   //     symmetric decryption.  For
+		   //     asymmetric decryption, this
+		   //     parameter is NULL
+		   const TPM2B             *label,         // IN: a value for L
+		   TPM2B_ENCRYPTED_SECRET  *secret,        // IN: input secret
+		   TPM2B_DATA              *data           // OUT: decrypted secret value
+		   )
+{
+    TPM_RC      result = TPM_RC_SUCCESS;
+    // Decryption for secret
+    switch(decryptKey->publicArea.type)
+	{
+#if ALG_RSA
+	  case TPM_ALG_RSA:
+	      {
+		  TPMT_RSA_DECRYPT        scheme;
+		  TPMT_RSA_SCHEME         *keyScheme
+		      = &decryptKey->publicArea.parameters.rsaDetail.scheme;
+		  UINT16                   digestSize;
+		  scheme = *(TPMT_RSA_DECRYPT *)keyScheme;
+		  // If the key scheme is TPM_ALG_NULL, set the scheme to OAEP and
+		  // set the algorithm to the name algorithm.
+		  if(scheme.scheme == TPM_ALG_NULL)
+		      {
+			  // Use OAEP scheme
+			  scheme.scheme = TPM_ALG_OAEP;
+			  scheme.details.oaep.hashAlg = decryptKey->publicArea.nameAlg;
+		      }
+		  // use the digestSize as an indicator of whether or not the scheme
+		  // is using a supported hash algorithm.
+		  // Note: depending on the scheme used for encryption, a hashAlg might
+		  // not be needed. However, the return value has to have some upper
+		  // limit on the size. In this case, it is the size of the digest of the
+		  // hash algorithm. It is checked after the decryption is done but, there
+		  // is no point in doing the decryption if the size is going to be
+		  // 'wrong' anyway.
+		  digestSize = CryptHashGetDigestSize(scheme.details.oaep.hashAlg);
+		  if(scheme.scheme != TPM_ALG_OAEP || digestSize == 0)
+		      return TPM_RC_SCHEME;
+		  // Set the output buffer capacity
+		  data->t.size = sizeof(data->t.buffer);
+		  // Decrypt seed by RSA OAEP
+		  result = CryptRsaDecrypt(&data->b, &secret->b,
+					   decryptKey, &scheme, label);
+		  if((result == TPM_RC_SUCCESS) && (data->t.size > digestSize))
+		      result = TPM_RC_VALUE;
+	      }
+	      break;
+#endif //TPM_ALG_RSA
+#if ALG_ECC
+	  case TPM_ALG_ECC:
+	      {
+		  TPMS_ECC_POINT       eccPublic;
+		  TPMS_ECC_POINT       eccSecret;
+		  BYTE                *buffer = secret->t.secret;
+		  INT32                size = secret->t.size;
+		  // Retrieve ECC point from secret buffer
+		  result = TPMS_ECC_POINT_Unmarshal(&eccPublic, &buffer, &size);
+		  if(result == TPM_RC_SUCCESS)
+		      {
+			  result = CryptEccPointMultiply(&eccSecret,
+							 decryptKey->publicArea.parameters.eccDetail.curveID,
+							 &eccPublic, &decryptKey->sensitive.sensitive.ecc,
+							 NULL, NULL);
+			  if(result == TPM_RC_SUCCESS)
+			      {
+				  // Set the size of the "recovered" secret value to be the size
+				  // of the digest produced by the nameAlg.
+				  data->t.size =
+				      CryptHashGetDigestSize(decryptKey->publicArea.nameAlg);
+				  // The secret value is computed from Z using KDFe as:
+				  // secret := KDFe(HashID, Z, Use, PartyUInfo, PartyVInfo, bits)
+				  // Where:
+				  //  HashID -- the nameAlg of the decrypt key
+				  //  Z --  the x coordinate (Px) of the product (P) of the point
+				  //        (Q) of the secret and the private x coordinate (de,V)
+				  //        of the decryption key
+				  //  Use -- a null-terminated string containing "SECRET"
+				  //  PartyUInfo -- the x coordinate of the point in the secret
+				  //              (Qe,U )
+				  //  PartyVInfo -- the x coordinate of the public key (Qs,V )
+				  //  bits -- the number of bits in the digest of HashID
+				  // Retrieve seed from KDFe
+				  CryptKDFe(decryptKey->publicArea.nameAlg, &eccSecret.x.b, label,
+					    &eccPublic.x.b,
+					    &decryptKey->publicArea.unique.ecc.x.b,
+					    data->t.size * 8, data->t.buffer);
+			      }
+		      }
+	      }
+	      break;
+#endif //TPM_ALG_ECC
+#if !ALG_KEYEDHASH
+#   error   "KEYEDHASH support is required"
+#endif
+	  case TPM_ALG_KEYEDHASH:
+	    // The seed size can not be bigger than the digest size of nameAlg
+	    if(secret->t.size >
+	       CryptHashGetDigestSize(decryptKey->publicArea.nameAlg))
+		result = TPM_RC_VALUE;
+	    else
+		{
+		    // Retrieve seed by XOR Obfuscation:
+		    //    seed = XOR(secret, hash, key, nonceCaller, nullNonce)
+		    //    where:
+		    //    secret  the secret parameter from the TPM2_StartAuthHMAC
+		    //            command that contains the seed value
+		    //    hash    nameAlg  of tpmKey
+		    //    key     the key or data value in the object referenced by
+		    //            entityHandle in the TPM2_StartAuthHMAC command
+		    //    nonceCaller the parameter from the TPM2_StartAuthHMAC command
+		    //    nullNonce   a zero-length nonce
+		    // XOR Obfuscation in place
+		    CryptXORObfuscation(decryptKey->publicArea.nameAlg,
+					&decryptKey->sensitive.sensitive.bits.b,
+					&nonceCaller->b, NULL,
+					secret->t.size, secret->t.secret);
+		    // Copy decrypted seed
+		    MemoryCopy2B(&data->b, &secret->b, sizeof(data->t.buffer));
+		}
+	    break;
+	  case TPM_ALG_SYMCIPHER:
+	      {
+		  TPM2B_IV                iv = {{0}};
+		  TPMT_SYM_DEF_OBJECT     *symDef;
+		  // The seed size can not be bigger than the digest size of nameAlg
+		  if(secret->t.size >
+		     CryptHashGetDigestSize(decryptKey->publicArea.nameAlg))
+		      result = TPM_RC_VALUE;
+		  else
+		      {
+			  symDef = &decryptKey->publicArea.parameters.symDetail.sym;
+			  iv.t.size = CryptGetSymmetricBlockSize(symDef->algorithm,
+								 symDef->keyBits.sym);
+			  if(iv.t.size == 0)
+			      return TPM_RC_FAILURE;
+			  if(nonceCaller->t.size >= iv.t.size)
+			      {
+				  MemoryCopy(iv.t.buffer, nonceCaller->t.buffer, iv.t.size);
+			      }
+			  else
+			      {
+				  if(nonceCaller->t.size > sizeof(iv.t.buffer))
+				      return TPM_RC_FAILURE;
+				  MemoryCopy(iv.b.buffer, nonceCaller->t.buffer,
+					     nonceCaller->t.size);
+			      }
+			  // make sure secret will fit
+			  if(secret->t.size > sizeof(data->t.buffer))
+			      return TPM_RC_FAILURE;
+			  data->t.size = secret->t.size;
+			  // CFB decrypt, using nonceCaller as iv
+			  CryptSymmetricDecrypt(data->t.buffer, symDef->algorithm,
+						symDef->keyBits.sym,
+						decryptKey->sensitive.sensitive.sym.t.buffer,
+						&iv, TPM_ALG_CFB, secret->t.size,
+						secret->t.secret);
+		      }
+	      }
+	      break;
+	  default:
+	    FAIL(FATAL_ERROR_INTERNAL);
+	    break;
+	}
+    return result;
+}
+/* 10.2.6.6.5 CryptParameterEncryption() */
+/* This function does in-place encryption of a response parameter. */
+void
+CryptParameterEncryption(
+			 TPM_HANDLE       handle,            // IN: encrypt session handle
+			 TPM2B           *nonceCaller,       // IN: nonce caller
+			 UINT16           leadingSizeInByte, // IN: the size of the leading size field in
+			 //     bytes
+			 TPM2B_AUTH      *extraKey,          // IN: additional key material other than
+			 //     sessionAuth
+			 BYTE            *buffer             // IN/OUT: parameter buffer to be encrypted
+			 )
+{
+    SESSION     *session = SessionGet(handle);  // encrypt session
+    TPM2B_TYPE(TEMP_KEY, (sizeof(extraKey->t.buffer)
+			  + sizeof(session->sessionKey.t.buffer)));
+    TPM2B_TEMP_KEY        key;               // encryption key
+    UINT32               cipherSize = 0;    // size of cipher text
+    // Retrieve encrypted data size.
+    if(leadingSizeInByte == 2)
+	{
+	    // Extract the first two bytes as the size field as the data size
+	    // encrypt
+	    cipherSize = (UINT32)BYTE_ARRAY_TO_UINT16(buffer);
+	    // advance the buffer
+	    buffer = &buffer[2];
+	}
+#ifdef      TPM4B
+    else if(leadingSizeInByte == 4)
+	{
+	    // use the first four bytes to indicate the number of bytes to encrypt
+	    cipherSize = BYTE_ARRAY_TO_UINT32(buffer);
+	    //advance pointer
+	    buffer = &buffer[4];
+	}
+#endif
+    else
+	{
+	    FAIL(FATAL_ERROR_INTERNAL);
+	}
+    // Compute encryption key by concatenating sessionKey with extra key
+    MemoryCopy2B(&key.b, &session->sessionKey.b, sizeof(key.t.buffer));
+    MemoryConcat2B(&key.b, &extraKey->b, sizeof(key.t.buffer));
+    if(session->symmetric.algorithm == TPM_ALG_XOR)
+	// XOR parameter encryption formulation:
+	//    XOR(parameter, hash, sessionAuth, nonceNewer, nonceOlder)
+	CryptXORObfuscation(session->authHashAlg, &(key.b),
+			    &(session->nonceTPM.b),
+			    nonceCaller, cipherSize, buffer);
+    else
+	ParmEncryptSym(session->symmetric.algorithm, session->authHashAlg,
+		       session->symmetric.keyBits.aes, &(key.b),
+		       nonceCaller, &(session->nonceTPM.b),
+		       cipherSize, buffer);
+    return;
+}
+/* 10.2.6.6.6 CryptParameterDecryption() */
+/* This function does in-place decryption of a command parameter. */
+/* Error Returns Meaning */
+/* TPM_RC_SIZE The number of bytes in the input buffer is less than the number of bytes to be
+   decrypted. */
+TPM_RC
+CryptParameterDecryption(
+			 TPM_HANDLE       handle,            // IN: encrypted session handle
+			 TPM2B           *nonceCaller,       // IN: nonce caller
+			 UINT32           bufferSize,        // IN: size of parameter buffer
+			 UINT16           leadingSizeInByte, // IN: the size of the leading size field in
+			 //     byte
+			 TPM2B_AUTH      *extraKey,          // IN: the authValue
+			 BYTE            *buffer             // IN/OUT: parameter buffer to be decrypted
+			 )
+{
+    SESSION         *session = SessionGet(handle);  // encrypt session
+    // The HMAC key is going to be the concatenation of the session key and any
+    // additional key material (like the authValue). The size of both of these
+    // is the size of the buffer which can contain a TPMT_HA.
+    TPM2B_TYPE(HMAC_KEY, (sizeof(extraKey->t.buffer)
+			  + sizeof(session->sessionKey.t.buffer)));
+    TPM2B_HMAC_KEY          key;            // decryption key
+    UINT32                  cipherSize = 0; // size of cipher text
+    // Retrieve encrypted data size.
+    if(leadingSizeInByte == 2)
+	{
+	    // The first two bytes of the buffer are the size of the
+	    // data to be decrypted
+	    cipherSize = (UINT32)BYTE_ARRAY_TO_UINT16(buffer);
+	    buffer = &buffer[2];   // advance the buffer
+	}
+#ifdef  TPM4B
+    else if(leadingSizeInByte == 4)
+	{
+	    // the leading size is four bytes so get the four byte size field
+	    cipherSize = BYTE_ARRAY_TO_UINT32(buffer);
+	    buffer = &buffer[4];   //advance pointer
+	}
+#endif
+    else
+	{
+	    FAIL(FATAL_ERROR_INTERNAL);
+	}
+    if(cipherSize > bufferSize)
+	return TPM_RC_SIZE;
+    // Compute decryption key by concatenating sessionAuth with extra input key
+    MemoryCopy2B(&key.b, &session->sessionKey.b, sizeof(key.t.buffer));
+    MemoryConcat2B(&key.b, &extraKey->b, sizeof(key.t.buffer));
+    if(session->symmetric.algorithm == TPM_ALG_XOR)
+	// XOR parameter decryption formulation:
+	//    XOR(parameter, hash, sessionAuth, nonceNewer, nonceOlder)
+	// Call XOR obfuscation function
+	CryptXORObfuscation(session->authHashAlg, &key.b, nonceCaller,
+			    &(session->nonceTPM.b), cipherSize, buffer);
+    else
+	// Assume that it is one of the symmetric block ciphers.
+	ParmDecryptSym(session->symmetric.algorithm, session->authHashAlg,
+		       session->symmetric.keyBits.sym,
+		       &key.b, nonceCaller, &session->nonceTPM.b,
+		       cipherSize, buffer);
+    return TPM_RC_SUCCESS;
+}
+/* 10.2.6.6.7 CryptComputeSymmetricUnique() */
+/* This function computes the unique field in public area for symmetric objects. */
+void
+CryptComputeSymmetricUnique(
+			    TPMT_PUBLIC     *publicArea,    // IN: the object's public area
+			    TPMT_SENSITIVE  *sensitive,     // IN: the associated sensitive area
+			    TPM2B_DIGEST    *unique         // OUT: unique buffer
+			    )
+{
+    // For parents (symmetric and derivation), use an HMAC to compute
+    // the 'unique' field
+    if(IS_ATTRIBUTE(publicArea->objectAttributes, TPMA_OBJECT, restricted)
+       && IS_ATTRIBUTE(publicArea->objectAttributes, TPMA_OBJECT, decrypt))
+	{
+	    // Unique field is HMAC(sensitive->seedValue, sensitive->sensitive)
+	    HMAC_STATE      hmacState;
+	    unique->b.size = CryptHmacStart2B(&hmacState, publicArea->nameAlg,
+					      &sensitive->seedValue.b);
+	    CryptDigestUpdate2B(&hmacState.hashState,
+				&sensitive->sensitive.any.b);
+	    CryptHmacEnd2B(&hmacState, &unique->b);
+	}
+    else
+	{
+	    HASH_STATE  hashState;
+	    // Unique := Hash(sensitive->seedValue || sensitive->sensitive)
+	    unique->t.size = CryptHashStart(&hashState, publicArea->nameAlg);
+	    CryptDigestUpdate2B(&hashState, &sensitive->seedValue.b);
+	    CryptDigestUpdate2B(&hashState, &sensitive->sensitive.any.b);
+	    CryptHashEnd2B(&hashState, &unique->b);
+	}
+    return;
+}
+/* 10.2.6.6.8 CryptCreateObject() */
+/* This function creates an object. For an asymmetric key, it will create a key pair and, for a
+   parent key, a seed value for child protections. */
+/* For an symmetric object, (TPM_ALG_SYMCIPHER or TPM_ALG_KEYEDHASH), it will create a secret key if
+   the caller did not provide one. It will create a random secret seed value that is hashed with the
+   secret value to create the public unique value. */
+/* publicArea, sensitive, and sensitiveCreate are the only required parameters and are the only ones
+   that are used by TPM2_Create(). The other parameters are optional and are used when the generated
+   Object needs to be deterministic. This is the case for both Primary Objects and Derived
+   Objects. */
+/* When a seed value is provided, a RAND_STATE will be populated and used for all operations in the
+   object generation that require a random number. In the simplest case, TPM2_CreatePrimary() will
+   use seed, label and context with context being the hash of the template. If the Primary Object is
+   in the Endorsement hierarchy, it will also populate proof with ehProof. */
+/* For derived keys, seed will be the secret value from the parent, label and context will be set
+   according to the parameters of TPM2_CreateLoaded() and hashAlg will be set which causes the RAND_STATE
+   to be a KDF generator. */
+/* Error Returns Meaning */
+/* TPM_RC_KEY a provided key is not an allowed value */
+/* TPM_RC_KEY_SIZE key size in the public area does not match the size in the sensitive creation
+   area for a symmetric key */
+/* TPM_RC_NO_RESULT unable to get random values (only in derivation) */
+/* TPM_RC_RANGE for an RSA key, the exponent is not supported */
+/* TPM_RC_SIZE sensitive data size is larger than allowed for the scheme for a keyed hash object */
+/* TPM_RC_VALUE exponent is not prime or could not find a prime using the provided parameters for an
+   RSA key; unsupported name algorithm for an ECC key */
+TPM_RC
+CryptCreateObject(
+		  OBJECT                  *object,            // IN: new object structure pointer
+		  TPMS_SENSITIVE_CREATE   *sensitiveCreate,   // IN: sensitive creation
+		  RAND_STATE              *rand               // IN: the random number generator
+		  //      to use
+		  )
+{
+    TPMT_PUBLIC             *publicArea = &object->publicArea;
+    TPMT_SENSITIVE          *sensitive = &object->sensitive;
+    TPM_RC                   result = TPM_RC_SUCCESS;
+    //
+    // Set the sensitive type for the object
+    sensitive->sensitiveType = publicArea->type;
+    // For all objects, copy the initial authorization data
+    sensitive->authValue = sensitiveCreate->userAuth;
+    // If the TPM is the source of the data, set the size of the provided data to
+    // zero so that there's no confusion about what to do.
+    if(IS_ATTRIBUTE(publicArea->objectAttributes,
+		    TPMA_OBJECT, sensitiveDataOrigin))
+	sensitiveCreate->data.t.size = 0;
+    // Generate the key and unique fields for the asymmetric keys and just the
+    // sensitive value for symmetric object
+    switch(publicArea->type)
+	{
+#if ALG_RSA
+	    // Create RSA key
+	  case TPM_ALG_RSA:
+	    // RSA uses full object so that it has a place to put the private
+	    // exponent
+	    result = CryptRsaGenerateKey(object, rand);
+	    break;
+#endif // TPM_ALG_RSA
+#if ALG_ECC
+	    // Create ECC key
+	  case TPM_ALG_ECC:
+	    result = CryptEccGenerateKey(publicArea, sensitive, rand);
+	    break;
+#endif // TPM_ALG_ECC
+	  case TPM_ALG_SYMCIPHER:
+	    result = CryptGenerateKeySymmetric(publicArea, sensitive,
+					       sensitiveCreate, rand);
+	    break;
+	  case TPM_ALG_KEYEDHASH:
+	    result = CryptGenerateKeyedHash(publicArea, sensitive,
+					    sensitiveCreate, rand);
+	    break;
+	  default:
+	    FAIL(FATAL_ERROR_INTERNAL);
+	    break;
+	}
+    if(result != TPM_RC_SUCCESS)
+	return result;
+    // Create the sensitive seed value
+    // If this is a primary key in the endorsement hierarchy, stir the DRBG state
+    // This implementation uses both shProof and ehProof to make sure that there
+    // is no leakage of either.
+    if(object->attributes.primary && object->attributes.epsHierarchy)
+	{
+	    DRBG_AdditionalData((DRBG_STATE *)rand, &gp.shProof.b);
+	    DRBG_AdditionalData((DRBG_STATE *)rand, &gp.ehProof.b);
+	}
+    // Generate a seedValue that is the size of the digest produced by nameAlg
+    sensitive->seedValue.t.size =
+	DRBG_Generate(rand, object->sensitive.seedValue.t.buffer,
+		      CryptHashGetDigestSize(publicArea->nameAlg));
+    if(g_inFailureMode)
+	return TPM_RC_FAILURE;
+    else if(sensitive->seedValue.t.size == 0)
+	return TPM_RC_NO_RESULT;
+    // For symmetric objects, need to compute the unique value for the public area
+    if(publicArea->type == TPM_ALG_SYMCIPHER
+       || publicArea->type == TPM_ALG_KEYEDHASH)
+	{
+	    CryptComputeSymmetricUnique(publicArea, sensitive,
+					&publicArea->unique.sym);
+	}
+    else
+	{
+	    // if this is an asymmetric key and it isn't a parent, then
+	    // get rid of the seed.
+	    if(IS_ATTRIBUTE(publicArea->objectAttributes, TPMA_OBJECT, sign)
+	       || !IS_ATTRIBUTE(publicArea->objectAttributes, TPMA_OBJECT, restricted))
+		memset(&sensitive->seedValue, 0,
+		       sizeof(sensitive->seedValue));
+	}
+    // Compute the name
+    PublicMarshalAndComputeName(publicArea, &object->name);
+    return result;
+}
+/* 10.2.6.6.9 CryptGetSignHashAlg() */
+/* Get the hash algorithm of signature from a TPMT_SIGNATURE structure. It assumes the signature is
+   not NULL This is a function for easy access */
+TPMI_ALG_HASH
+CryptGetSignHashAlg(
+		    TPMT_SIGNATURE  *auth           // IN: signature
+		    )
+{
+    if(auth->sigAlg == TPM_ALG_NULL)
+	FAIL(FATAL_ERROR_INTERNAL);
+    // Get authHash algorithm based on signing scheme
+    switch(auth->sigAlg)
+	{
+#if ALG_RSA
+	    // If RSA is supported, both RSASSA and RSAPSS are required
+#   if !defined TPM_ALG_RSASSA || !defined TPM_ALG_RSAPSS
+#       error "RSASSA and RSAPSS are required for RSA"
+#   endif
+	  case TPM_ALG_RSASSA:
+	    return auth->signature.rsassa.hash;
+	  case TPM_ALG_RSAPSS:
+	    return auth->signature.rsapss.hash;
+#endif //TPM_ALG_RSA
+#if ALG_ECC
+	    // If ECC is defined, ECDSA is mandatory
+#   ifndef  TPM_ALG_ECDSA
+#       error "ECDSA is requried for ECC"
+#   endif
+	  case TPM_ALG_ECDSA:
+	    // SM2 and ECSCHNORR are optional
+#   if ALG_SM2
+	  case TPM_ALG_SM2:
+#   endif
+#   if ALG_ECSCHNORR
+	  case TPM_ALG_ECSCHNORR:
+#   endif
+	    //all ECC signatures look the same
+	    return auth->signature.ecdsa.hash;
+#   if ALG_ECDAA
+	    // Don't know how to verify an ECDAA signature
+	  case TPM_ALG_ECDAA:
+	    break;
+#   endif
+#endif //TPM_ALG_ECC
+	  case TPM_ALG_HMAC:
+	    return auth->signature.hmac.hashAlg;
+	  default:
+	    break;
+	}
+    return TPM_ALG_NULL;
+}
+/* 10.2.6.6.10 CryptIsSplitSign() */
+/* This function us used to determine if the signing operation is a split signing operation that
+   required a TPM2_Commit(). */
+BOOL
+CryptIsSplitSign(
+		 TPM_ALG_ID       scheme         // IN: the algorithm selector
+		 )
+{
+    switch(scheme)
+	{
+#   if ALG_ECDAA
+	  case TPM_ALG_ECDAA:
+	    return TRUE;
+	    break;
+#   endif   // TPM_ALG_ECDAA
+	  default:
+	    return FALSE;
+	    break;
+	}
+}
+/* 10.2.6.6.11 CryptIsAsymSignScheme() */
+/* This function indicates if a scheme algorithm is a sign algorithm. */
+BOOL
+CryptIsAsymSignScheme(
+		      TPMI_ALG_PUBLIC          publicType,        // IN: Type of the object
+		      TPMI_ALG_ASYM_SCHEME     scheme             // IN: the scheme
+		      )
+{
+    BOOL            isSignScheme = TRUE;
+    switch(publicType)
+	{
+#if ALG_RSA
+	  case TPM_ALG_RSA:
+	    switch(scheme)
+		{
+#   if !defined TPM_ALG_RSASSA  || !defined TPM_ALG_RSAPSS
+#       error "RSASSA and PSAPSS required if RSA used."
+#   endif
+		  case TPM_ALG_RSASSA:
+		  case TPM_ALG_RSAPSS:
+		    break;
+		  default:
+		    isSignScheme = FALSE;
+		    break;
+		}
+	    break;
+#endif //TPM_ALG_RSA
+#if ALG_ECC
+	    // If ECC is implemented ECDSA is required
+	  case TPM_ALG_ECC:
+	    switch(scheme)
+		{
+		    // Support for ECDSA is required for ECC
+		  case TPM_ALG_ECDSA:
+#if ALG_ECDAA // ECDAA is optional
+		  case TPM_ALG_ECDAA:
+#endif
+#if ALG_ECSCHNORR // Schnorr is also optional
+		  case TPM_ALG_ECSCHNORR:
+#endif
+#if ALG_SM2 // SM2 is optional
+		  case TPM_ALG_SM2:
+#endif
+		    break;
+		  default:
+		    isSignScheme = FALSE;
+		    break;
+		}
+	    break;
+#endif //TPM_ALG_ECC
+	  default:
+	    isSignScheme = FALSE;
+	    break;
+	}
+    return isSignScheme;
+}
+/* 10.2.6.6.12 CryptIsAsymDecryptScheme() */
+/* This function indicate if a scheme algorithm is a decrypt algorithm. */
+BOOL
+CryptIsAsymDecryptScheme(
+			 TPMI_ALG_PUBLIC          publicType,        // IN: Type of the object
+			 TPMI_ALG_ASYM_SCHEME     scheme             // IN: the scheme
+			 )
+{
+    BOOL        isDecryptScheme = TRUE;
+    switch(publicType)
+	{
+#if ALG_RSA
+	  case TPM_ALG_RSA:
+	    switch(scheme)
+		{
+		  case TPM_ALG_RSAES:
+		  case TPM_ALG_OAEP:
+		    break;
+		  default:
+		    isDecryptScheme = FALSE;
+		    break;
+		}
+	    break;
+#endif //TPM_ALG_RSA
+#if ALG_ECC
+	    // If ECC is implemented ECDH is required
+	  case TPM_ALG_ECC:
+	    switch(scheme)
+		{
+#if !ALG_ECDH
+#   error "ECDH is required for ECC"
+#endif
+		  case TPM_ALG_ECDH:
+#if ALG_SM2
+		  case TPM_ALG_SM2:
+#endif
+#if ALG_ECMQV
+		  case TPM_ALG_ECMQV:
+#endif
+		    break;
+		  default:
+		    isDecryptScheme = FALSE;
+		    break;
+		}
+	    break;
+#endif //TPM_ALG_ECC
+	  default:
+	    isDecryptScheme = FALSE;
+	    break;
+	}
+    return isDecryptScheme;
+}
+/* 10.2.6.6.13 CryptSelectSignScheme() */
+/* This function is used by the attestation and signing commands.  It implements the rules for
+   selecting the signature scheme to use in signing. This function requires that the signing key
+   either be TPM_RH_NULL or be loaded. */
+/* If a default scheme is defined in object, the default scheme should be chosen, otherwise, the
+   input scheme should be chosen. In the case that both object and input scheme has a non-NULL
+   scheme algorithm, if the schemes are compatible, the input scheme will be chosen. */
+/* This function should not be called if 'signObject->publicArea.type' == TPM_ALG_SYMCIPHER. */
+/* Return Values Meaning */
+/* TRUE scheme selected */
+/* FALSE both scheme and key's default scheme are empty; or scheme is empty while key's default
+   scheme requires explicit input scheme (split signing); or non-empty default key scheme differs
+   from scheme */
+BOOL
+CryptSelectSignScheme(
+		      OBJECT              *signObject,    // IN: signing key
+		      TPMT_SIG_SCHEME     *scheme         // IN/OUT: signing scheme
+		      )
+{
+    TPMT_SIG_SCHEME     *objectScheme;
+    TPMT_PUBLIC         *publicArea;
+    BOOL                 OK;
+    // If the signHandle is TPM_RH_NULL, then the NULL scheme is used, regardless
+    // of the setting of scheme
+    if(signObject == NULL)
+	{
+	    OK = TRUE;
+	    scheme->scheme = TPM_ALG_NULL;
+	    scheme->details.any.hashAlg = TPM_ALG_NULL;
+	}
+    else
+	{
+	    // assignment to save typing.
+	    publicArea = &signObject->publicArea;
+	    // A symmetric cipher can be used to encrypt and decrypt but it can't
+	    // be used for signing
+	    if(publicArea->type == TPM_ALG_SYMCIPHER)
+		return FALSE;
+	    // Point to the scheme object
+	    if(CryptIsAsymAlgorithm(publicArea->type))
+		objectScheme =
+		    (TPMT_SIG_SCHEME *)&publicArea->parameters.asymDetail.scheme;
+	    else
+		objectScheme =
+		    (TPMT_SIG_SCHEME *)&publicArea->parameters.keyedHashDetail.scheme;
+	    // If the object doesn't have a default scheme, then use the
+	    // input scheme.
+	    if(objectScheme->scheme == TPM_ALG_NULL)
+		{
+		    // Input and default can't both be NULL
+		    OK = (scheme->scheme != TPM_ALG_NULL);
+		    // Assume that the scheme is compatible with the key. If not,
+		    // an error will be generated in the signing operation.
+		}
+	    else if(scheme->scheme == TPM_ALG_NULL)
+		{
+		    // input scheme is NULL so use default
+		    // First, check to see if the default requires that the caller
+		    // provided scheme data
+		    OK = !CryptIsSplitSign(objectScheme->scheme);
+		    if(OK)
+			{
+			    // The object has a scheme and the input is TPM_ALG_NULL so copy
+			    // the object scheme as the final scheme. It is better to use a
+			    // structure copy than a copy of the individual fields.
+			    *scheme = *objectScheme;
+			}
+		}
+	    else
+		{
+		    // Both input and object have scheme selectors
+		    // If the scheme and the hash are not the same then...
+		    // NOTE: the reason that there is no copy here is that the input
+		    // might contain extra data for a split signing scheme and that
+		    // data is not in the object so, it has to be preserved.
+		    OK = (objectScheme->scheme == scheme->scheme)
+			 && (objectScheme->details.any.hashAlg
+			     == scheme->details.any.hashAlg);
+		}
+	}
+    return OK;
+}
+/* 10.2.6.6.14 CryptSign() */
+/* Sign a digest with asymmetric key or HMAC. This function is called by attestation commands and
+   the generic TPM2_Sign() command. This function checks the key scheme and digest size.  It does
+   not check if the sign operation is allowed for restricted key.  It should be checked before the
+   function is called. The function will assert if the key is not a signing key. */
+/* Error Returns Meaning */
+/* TPM_RC_SCHEME signScheme is not compatible with the signing key type */
+/* TPM_RC_VALUE digest value is greater than the modulus of signHandle or size of hashData does not
+   match hash algorithm insignScheme (for an RSA key); invalid commit status or failed to generate r
+   value (for an ECC key) */
+TPM_RC
+CryptSign(
+	  OBJECT              *signKey,       // IN: signing key
+	  TPMT_SIG_SCHEME     *signScheme,    // IN: sign scheme.
+	  TPM2B_DIGEST        *digest,        // IN: The digest being signed
+	  TPMT_SIGNATURE      *signature      // OUT: signature
+	  )
+{
+    TPM_RC               result = TPM_RC_SCHEME;
+    // Initialize signature scheme
+    signature->sigAlg = signScheme->scheme;
+    // If the signature algorithm is TPM_ALG_NULL or the signing key is NULL,
+    // then we are done
+    if((signature->sigAlg == TPM_ALG_NULL) || (signKey == NULL))
+	return TPM_RC_SUCCESS;
+    // Initialize signature hash
+    // Note: need to do the check for TPM_ALG_NULL first because the null scheme
+    // doesn't have a hashAlg member.
+    signature->signature.any.hashAlg = signScheme->details.any.hashAlg;
+    // perform sign operation based on different key type
+    switch(signKey->publicArea.type)
+	{
+#if ALG_RSA
+	  case TPM_ALG_RSA:
+	    result = CryptRsaSign(signature, signKey, digest, NULL);
+	    break;
+#endif //TPM_ALG_RSA
+#if ALG_ECC
+	  case TPM_ALG_ECC:
+	    // The reason that signScheme is passed to CryptEccSign but not to the
+	    // other signing methods is that the signing for ECC may be split and
+	    // need the 'r' value that is in the scheme but not in the signature.
+	    result = CryptEccSign(signature, signKey, digest,
+				  (TPMT_ECC_SCHEME *)signScheme, NULL);
+	    break;
+#endif //TPM_ALG_ECC
+	  case TPM_ALG_KEYEDHASH:
+	    result = CryptHmacSign(signature, signKey, digest);
+	    break;
+	  default:
+	    FAIL(FATAL_ERROR_INTERNAL);
+	    break;
+	}
+    return result;
+}
+/* 10.2.6.6.15 CryptValidateSignature() */
+/* This function is used to verify a signature.  It is called by TPM2_VerifySignature() and
+   TPM2_PolicySigned(). */
+/* Since this operation only requires use of a public key, no consistency checks are necessary for
+   the key to signature type because a caller can load any public key that they like with any scheme
+   that they like. This routine simply makes sure that the signature is correct, whatever the
+   type. */
+/* Error Returns Meaning */
+/* TPM_RC_SIGNATURE the signature is not genuine */
+/* TPM_RC_SCHEME the scheme is not supported */
+/* TPM_RC_HANDLE an HMAC key was selected but the private part of the key is not loaded */
+TPM_RC
+CryptValidateSignature(
+		       TPMI_DH_OBJECT   keyHandle,     // IN: The handle of sign key
+		       TPM2B_DIGEST    *digest,        // IN: The digest being validated
+		       TPMT_SIGNATURE  *signature      // IN: signature
+		       )
+{
+    // NOTE: HandleToObject will either return a pointer to a loaded object or
+    // will assert. It will never return a non-valid value. This makes it save
+    // to initialize 'publicArea' with the return value from HandleToObject()
+    // without checking it first.
+    OBJECT              *signObject = HandleToObject(keyHandle);
+    TPMT_PUBLIC         *publicArea = &signObject->publicArea;
+    TPM_RC               result = TPM_RC_SCHEME;
+    // The input unmarshaling should prevent any input signature from being
+    // a NULL signature, but just in case
+    if(signature->sigAlg == TPM_ALG_NULL)
+	return TPM_RC_SIGNATURE;
+    switch(publicArea->type)
+	{
+#if ALG_RSA
+	  case TPM_ALG_RSA:
+	      {
+		  //
+		  // Call RSA code to verify signature
+		  result = CryptRsaValidateSignature(signature, signObject, digest);
+		  break;
+	      }
+#endif //TPM_ALG_RSA
+#if ALG_ECC
+	  case TPM_ALG_ECC:
+	    result = CryptEccValidateSignature(signature, signObject, digest);
+	    break;
+#endif // TPM_ALG_ECC
+	  case TPM_ALG_KEYEDHASH:
+	    if(signObject->attributes.publicOnly)
+		result = TPM_RCS_HANDLE;
+	    else
+		result = CryptHMACVerifySignature(signObject, digest, signature);
+	    break;
+	  default:
+	    break;
+	}
+    return result;
+}
+/* 10.2.6.6.16 CryptGetTestResult */
+/* This function returns the results of a self-test function. */
+/* NOTE: the behavior in this function is NOT the correct behavior for a real TPM implementation.
+   An artificial behavior is placed here due to the limitation of a software simulation environment.
+   For the correct behavior, consult the part 3 specification for TPM2_GetTestResult(). */
+TPM_RC
+CryptGetTestResult(
+		   TPM2B_MAX_BUFFER    *outData        // OUT: test result data
+		   )
+{
+    outData->t.size = 0;
+    return TPM_RC_SUCCESS;
+}
+/* 10.2.6.6.17 CryptValidateKeys() */
+/* This function is used to verify that the key material of an object is valid. For a publicOnly
+   object, the key is verified for size and, if it is an ECC key, it is verified to be on the
+   specified curve. For a key with a sensitive area, the binding between the public and private
+   parts of the key are verified. If the nameAlg of the key is TPM_ALG_NULL, then the size of the
+   sensitive area is verified but the public portion is not verified, unless the key is an RSA
+   key. For an RSA key, the reason for loading the sensitive area is to use it. The only way to use
+   a private RSA key is to compute the private exponent. To compute the private exponent, the public
+   modulus is used. */
+/* Error Returns Meaning */
+/* TPM_RC_BINDING the public and private parts are not cryptographically bound */
+/* TPM_RC_HASH cannot have a publicOnly key with nameAlg of TPM_ALG_NULL */
+/* TPM_RC_KEY the public unique is not valid */
+/* TPM_RC_KEY_SIZE the private area key is not valid */
+/* TPM_RC_TYPE the types of the sensitive and private parts do not match */
+TPM_RC
+CryptValidateKeys(
+		  TPMT_PUBLIC      *publicArea,
+		  TPMT_SENSITIVE   *sensitive,
+		  TPM_RC            blamePublic,
+		  TPM_RC            blameSensitive
+		  )
+{
+    TPM_RC               result;
+    UINT16               keySizeInBytes;
+    UINT16               digestSize = CryptHashGetDigestSize(publicArea->nameAlg);
+    TPMU_PUBLIC_PARMS   *params = &publicArea->parameters;
+    TPMU_PUBLIC_ID      *unique = &publicArea->unique;
+    if(sensitive != NULL)
+	{
+	    // Make sure that the types of the public and sensitive are compatible
+	    if(publicArea->type != sensitive->sensitiveType)
+		return TPM_RCS_TYPE + blameSensitive;
+	    // Make sure that the authValue is not bigger than allowed
+	    // If there is no name algorithm, then the size just needs to be less than
+	    // the maximum size of the buffer used for authorization. That size check
+	    // was made during unmarshaling of the sensitive area
+	    if((sensitive->authValue.t.size) > digestSize && (digestSize > 0))
+		return TPM_RCS_SIZE + blameSensitive;
+	}
+    switch(publicArea->type)
+	{
+#if ALG_RSA
+	  case TPM_ALG_RSA:
+	    keySizeInBytes = BITS_TO_BYTES(params->rsaDetail.keyBits);
+	    // Regardless of whether there is a sensitive area, the public modulus
+	    // needs to have the correct size. Otherwise, it can't be used for
+	    // any public key operation nor can it be used to compute the private
+	    // exponent.
+	    // NOTE: This implementation only supports key sizes that are multiples
+	    // of 1024 bits which means that the MSb of the 0th byte will always be
+	    // SET in either a prime or the public modulus.
+	    if((unique->rsa.t.size != keySizeInBytes)
+	       || (unique->rsa.t.buffer[0] < 0x80))
+		return TPM_RCS_KEY + blamePublic;
+	    if(params->rsaDetail.exponent != 0
+	       && params->rsaDetail.exponent < 7)
+		return TPM_RCS_VALUE + blamePublic;
+	    if(sensitive != NULL)
+		{
+		    // If there is a sensitive area, it has to be the correct size
+		    // including having the correct high order bit SET.
+		    if(((sensitive->sensitive.rsa.t.size * 2) != keySizeInBytes)
+		       || (sensitive->sensitive.rsa.t.buffer[0] < 0x80))
+			return TPM_RCS_KEY_SIZE + blameSensitive;
+		}
+	    break;
+#endif
+#if ALG_ECC
+	  case TPM_ALG_ECC:
+	      {
+		  TPMI_ECC_CURVE      curveId;
+		  curveId = params->eccDetail.curveID;
+		  keySizeInBytes = BITS_TO_BYTES(CryptEccGetKeySizeForCurve(curveId));
+		  if(sensitive == NULL)
+		      {
+			  // Validate the public key size
+			  if(unique->ecc.x.t.size != keySizeInBytes
+			     || unique->ecc.y.t.size != keySizeInBytes)
+			      return TPM_RCS_KEY + blamePublic;
+			  if(publicArea->nameAlg != TPM_ALG_NULL)
+			      {
+				  if(!CryptEccIsPointOnCurve(curveId, &unique->ecc))
+				      return TPM_RCS_ECC_POINT + blamePublic;
+			      }
+		      }
+		  else
+		      {
+			  // If the nameAlg is TPM_ALG_NULL, then only verify that the
+			  // private part of the key is OK.
+			  if(!CryptEccIsValidPrivateKey(&sensitive->sensitive.ecc,
+							curveId))
+			      return TPM_RCS_KEY_SIZE;
+			  if(publicArea->nameAlg != TPM_ALG_NULL)
+			      {
+				  // Full key load, verify that the public point belongs to the
+				  // private key.
+				  TPMS_ECC_POINT          toCompare;
+				  result = CryptEccPointMultiply(&toCompare, curveId, NULL,
+								 &sensitive->sensitive.ecc,
+								 NULL, NULL);
+				  if(result != TPM_RC_SUCCESS)
+				      return TPM_RCS_BINDING;
+				  else
+				      {
+					  // Make sure that the private key generated the public key.
+					  // The input values and the values produced by the point
+					  // multiply may not be the same size so adjust the computed
+					  // value to match the size of the input value by adding or
+					  // removing zeros.
+					  AdjustNumberB(&toCompare.x.b, unique->ecc.x.t.size);
+					  AdjustNumberB(&toCompare.y.b, unique->ecc.y.t.size);
+					  if(!MemoryEqual2B(&unique->ecc.x.b, &toCompare.x.b)
+					     || !MemoryEqual2B(&unique->ecc.y.b, &toCompare.y.b))
+					      return TPM_RCS_BINDING;
+				      }
+			      }
+		      }
+		  break;
+	      }
+#endif
+	  default:
+	    // Checks for SYMCIPHER and KEYEDHASH are largely the same
+	    // If public area has a nameAlg, then validate the public area size
+	    // and if there is also a sensitive area, validate the binding
+	    // For consistency, if the object is public-only just make sure that
+	    // the unique field is consistent with the name algorithm
+	    if(sensitive == NULL)
+		{
+		    if(unique->sym.t.size != digestSize)
+			return TPM_RCS_KEY + blamePublic;
+		}
+	    else
+		{
+		    // Make sure that the key size in the sensitive area is consistent.
+		    if(publicArea->type == TPM_ALG_SYMCIPHER)
+			{
+			    result = CryptSymKeyValidate(&params->symDetail.sym,
+							 &sensitive->sensitive.sym);
+			    if(result != TPM_RC_SUCCESS)
+				return result + blameSensitive;
+			}
+		    else
+			{
+			    // For a keyed hash object, the key has to be less than the
+			    // smaller of the block size of the hash used in the scheme or
+			    // 128 bytes. The worst case value is limited by the
+			    // unmarshaling code so the only thing left to be checked is
+			    // that it does not exceed the block size of the hash.
+			    // by the hash algorithm of the scheme.
+			    TPMT_KEYEDHASH_SCHEME       *scheme;
+			    UINT16                       maxSize;
+			    scheme = &params->keyedHashDetail.scheme;
+			    if(scheme->scheme == TPM_ALG_XOR)
+				{
+				    maxSize = CryptHashGetBlockSize(scheme->details.xorr.hashAlg);
+				}
+			    else if(scheme->scheme == TPM_ALG_HMAC)
+				{
+				    maxSize = CryptHashGetBlockSize(scheme->details.hmac.hashAlg);
+				}
+			    else if(scheme->scheme == TPM_ALG_NULL)
+				{
+				    // Not signing or xor so must be a data block
+				    maxSize = 128;
+				}
+			    else
+				return TPM_RCS_SCHEME + blamePublic;
+			    if(sensitive->sensitive.bits.t.size > maxSize)
+				return TPM_RCS_KEY_SIZE + blameSensitive;
+			}
+		    // If there is a nameAlg, check the binding
+		    if(publicArea->nameAlg != TPM_ALG_NULL)
+			{
+			    TPM2B_DIGEST            compare;
+			    if(sensitive->seedValue.t.size != digestSize)
+				return TPM_RCS_KEY_SIZE + blameSensitive;
+			    CryptComputeSymmetricUnique(publicArea, sensitive, &compare);
+			    if(!MemoryEqual2B(&unique->sym.b, &compare.b))
+				return TPM_RC_BINDING;
+			}
+		}
+	    break;
+	}
+    // For a parent, need to check that the seedValue is the correct size for
+    // protections. It should be at least half the size of the nameAlg
+    if(IS_ATTRIBUTE(publicArea->objectAttributes, TPMA_OBJECT, restricted)
+       && IS_ATTRIBUTE(publicArea->objectAttributes, TPMA_OBJECT, decrypt)
+       && sensitive != NULL
+       && publicArea->nameAlg != TPM_ALG_NULL)
+	{
+	    if((sensitive->seedValue.t.size < (digestSize / 2))
+	       || (sensitive->seedValue.t.size > digestSize))
+		return TPM_RCS_SIZE + blameSensitive;
+	}
+    return TPM_RC_SUCCESS;
+}
+/* 10.2.6.6.18 CryptSelectMac() */
+/* This function is used to set the MAC scheme based on the key parameters and the input scheme. */
+/* Error Returns Meaning */
+/* TPM_RC_SCHEME the scheme is not a valid mac scheme */
+/* TPM_RC_TYPE the input key is not a type that supports a mac */
+/* TPM_RC_VALUE the input scheme and the key scheme are not compatible */
+TPM_RC
+CryptSelectMac(
+	       TPMT_PUBLIC             *publicArea,
+	       TPMI_ALG_MAC_SCHEME     *inMac
+	       )
+{
+    TPM_ALG_ID              macAlg = TPM_ALG_NULL;
+    switch(publicArea->type)
+	{
+	  case TPM_ALG_KEYEDHASH:
+	      {
+		  // Local value to keep lines from getting too long
+		  TPMT_KEYEDHASH_SCHEME   *scheme;
+		  scheme = &publicArea->parameters.keyedHashDetail.scheme;
+		  // Expect that the scheme is either HMAC or NULL
+		  if(scheme->scheme != TPM_ALG_NULL)
+		      macAlg = scheme->details.hmac.hashAlg;
+		  break;
+	      }
+	  case TPM_ALG_SYMCIPHER:
+	      {
+		  TPMT_SYM_DEF_OBJECT     *scheme;
+		  scheme = &publicArea->parameters.symDetail.sym;
+		  // Expect that the scheme is either valid symmetric cipher or NULL
+		  if(scheme->algorithm != TPM_ALG_NULL)
+		      macAlg = scheme->mode.sym;
+		  break;
+	      }
+	  default:
+	    return TPM_RCS_TYPE;
+	}
+    // If the input value is not TPM_ALG_NULL ...
+    if(*inMac != TPM_ALG_NULL)
+	{
+	    // ... then either the scheme in the key must be TPM_ALG_NULL or the input
+	    // value must match
+	    if((macAlg != TPM_ALG_NULL) && (*inMac != macAlg))
+		return TPM_RCS_VALUE;
+	}
+    else
+	{
+	    // Since the input value is TPM_ALG_NULL, then the key value can't be
+	    // TPM_ALG_NULL
+	    if(macAlg == TPM_ALG_NULL)
+		return TPM_RCS_VALUE;
+	    *inMac = macAlg;
+	}
+    if(!CryptMacIsValidForKey(publicArea->type, *inMac, FALSE))
+	return TPM_RCS_SCHEME;
+    return TPM_RC_SUCCESS;
+}
+/* 10.2.6.6.19 CryptMacIsValidForKey() */
+/* Check to see if the key type is compatible with the mac type */
+BOOL
+CryptMacIsValidForKey(
+		      TPM_ALG_ID          keyType,
+		      TPM_ALG_ID          macAlg,
+		      BOOL                flag
+		      )
+{
+    switch(keyType)
+	{
+	  case TPM_ALG_KEYEDHASH:
+	    return CryptHashIsValidAlg(macAlg, flag);
+	    break;
+	  case TPM_ALG_SYMCIPHER:
+	    return CryptSmacIsValidAlg(macAlg, flag);
+	    break;
+	  default:
+	    break;
+	}
+    return FALSE;
+}
+/* 10.2.6.6.20 CryptSmacIsValidAlg() */
+/* This function is used to test if an algorithm is a supported SMAC algorithm. It needs to be
+   updated as new algorithms are added. */
+BOOL
+CryptSmacIsValidAlg(
+		    TPM_ALG_ID      alg,
+		    BOOL            FLAG        // IN: Indicates if TPM_ALG_NULL is valid
+		    )
+{
+    switch (alg)
+	{
+#if ALG_CMAC
+	  case TPM_ALG_CMAC:
+	    return TRUE;
+	    break;
+#endif
+	  case TPM_ALG_NULL:
+	    return FLAG;
+	    break;
+	  default:
+	    return FALSE;
+	}
+}
+/* 10.2.6.6.21 CryptSymModeIsValid() */
+/* Function checks to see if an algorithm ID is a valid, symmetric block cipher mode for the TPM. If
+   flag is SET, them TPM_ALG_NULL is a valid mode. not include the modes used for SMAC */
+BOOL
+CryptSymModeIsValid(
+		    TPM_ALG_ID          mode,
+		    BOOL                flag
+		    )
+{
+    switch(mode)
+	{
+#if         ALG_CTR
+	  case TPM_ALG_CTR:
+#endif // ALG_CTR
+#if         ALG_OFB
+	  case TPM_ALG_OFB:
+#endif // ALG_OFB
+#if         ALG_CBC
+	  case TPM_ALG_CBC:
+#endif // ALG_CBC
+#if         ALG_CFB
+	  case TPM_ALG_CFB:
+#endif // ALG_CFB
+#if         ALG_ECB
+	  case TPM_ALG_ECB:
+#endif // ALG_ECB
+	    return TRUE;
+	  case TPM_ALG_NULL:
+	    return flag;
+	    break;
+	  default:
+	    break;
+	}
+    return FALSE;
+}

この差分においてかなりの量のファイルが変更されているため、一部のファイルを表示していません