From 68f44d6e68c6d715f8821e03b7f2e637bf89da33 Mon Sep 17 00:00:00 2001 From: "Li, Xun" Date: Thu, 13 Sep 2018 09:55:25 +0800 Subject: [PATCH] Linux 2.3 Open Source Gold Release Support for Ubuntu 18.04 LTS 64-bit Desktop and Server version Provided a new set of SGX common loader APIs in sgx_enclave_common.h Provided the sample code for Switchless Call Provided a new API in tcrypto: sgx_ecc256_calculate_pub_from_priv sgx_create_enclave API will ignore the parameter of launch token and will not update it after function successfully returns Change Intel SGX PSW installer for Ubuntu by - Using .deb installer. - Using name libsgx-enclave-common_{version string}-1_amd64.deb. - Installing Intel SGX Enclave Common loader library. Bug fixes Signed-off-by: Li, Xun --- .../OSGI-INF/l10n/bundle.properties | 2 +- Makefile | 3 + README.md | 104 +- SampleCode/Cxx11SGXDemo/App/App.cpp | 53 +- .../Enclave/TrustedLibrary/Libcxx.cpp | 1 + SampleCode/Cxx11SGXDemo/Makefile | 39 +- SampleCode/LocalAttestation/App/App.cpp | 4 +- .../LocalAttestation/Enclave1/Enclave1.cpp | 1 - .../LocalAttestation/Enclave1/Enclave1.edl | 1 - .../LocalAttestation/Enclave2/Enclave2.cpp | 1 - .../LocalAttestation/Enclave2/Enclave2.edl | 1 - .../LocalAttestation/Enclave3/Enclave3.cpp | 1 - .../LocalAttestation/Enclave3/Enclave3.edl | 1 - .../EnclaveMessageExchange.cpp | 1 - SampleCode/LocalAttestation/Makefile | 78 +- SampleCode/PowerTransition/App/App.cpp | 35 +- SampleCode/PowerTransition/Makefile | 27 +- SampleCode/RemoteAttestation/Makefile | 50 +- .../RemoteAttestation/isv_app/isv_app.cpp | 6 +- .../service_provider/ecp.cpp | 4 +- .../service_provider/ias_ra.cpp | 2 +- .../service_provider/ias_ra.h | 2 +- .../service_provider/network_ra.cpp | 6 +- .../service_provider/service_provider.cpp | 13 +- .../service_provider/service_provider.h | 2 +- .../SampleCommonLoader/App/enclave_entry.S | 25 +- SampleCode/SampleCommonLoader/App/sample.cpp | 187 ++ .../Include/enclave_entry.h | 136 + .../SampleCommonLoader/Include/linux-regs.h | 273 ++ .../Include/sgx_enclave_blob.h | 2340 +++++++++++++++++ .../Include/sgx_enclave_ss.h | 149 ++ SampleCode/SampleCommonLoader/Makefile | 55 + SampleCode/SampleCommonLoader/README.txt | 24 + SampleCode/SampleEnclave/App/App.cpp | 53 +- .../App/Edger8rSyntax/Functions.cpp | 4 - .../Enclave/Edger8rSyntax/Functions.cpp | 22 - .../Enclave/Edger8rSyntax/Functions.edl | 13 - .../Enclave/Edger8rSyntax/Pointers.cpp | 3 +- .../Enclave/Edger8rSyntax/Pointers.edl | 2 +- SampleCode/SampleEnclave/Makefile | 39 +- SampleCode/SampleEnclavePCL/App/App.cpp | 59 +- .../App/Edger8rSyntax/Functions.cpp | 4 - .../Enclave/Edger8rSyntax/Functions.cpp | 22 - .../Enclave/Edger8rSyntax/Functions.edl | 13 - .../Enclave/Edger8rSyntax/Pointers.cpp | 3 +- .../Enclave/Edger8rSyntax/Pointers.edl | 2 +- SampleCode/SampleEnclavePCL/Makefile | 33 +- SampleCode/SampleEnclavePCL/Seal/Seal.cpp | 2 +- SampleCode/SealedData/DRM_app/DRM_app.cpp | 16 +- SampleCode/SealedData/Makefile | 32 +- SampleCode/Switchless/App/App.cpp | 58 +- SampleCode/Switchless/Makefile | 33 +- common/inc/internal/global_data.h | 2 + common/inc/internal/ipp_wrapper.h | 59 +- common/inc/internal/se_version.h | 4 +- common/inc/sgx_tcrypto.h | 41 +- common/src/ipp_bn.cpp | 125 - common/src/ipp_rsa_pub_key.cpp | 110 - download_prebuilt.sh | 10 +- .../epid-sdk/epid/common-testhelper/Makefile | 4 +- external/epid-sdk/epid/common/Makefile | 4 +- external/epid-sdk/epid/member/Makefile | 16 +- external/epid-sdk/epid/verifier/Makefile | 4 +- external/epid-sdk/example/Makefile | 4 +- external/epid-sdk/ext/argtable3/Makefile | 2 +- external/sgxssl/prepare_sgxssl.sh | 16 +- external/tinyxml2/tinyxml2.cpp | 689 +++-- external/tinyxml2/tinyxml2.h | 440 ++-- .../BOMs/sgx-enclave-common_base.txt | 18 + .../BOMs/sgx-enclave-common_x64.txt | 5 + .../BOMs/sgx-enclave-common_x86.txt | 5 + .../common/libsgx-enclave-common/Makefile | 67 + .../libsgx-enclave-common/createTarball.sh | 74 + .../common/libsgx-enclave-common/install.sh | 240 ++ .../libsgx-enclave-common/installConfig.x64 | 8 + .../libsgx-enclave-common/installConfig.x86 | 8 + linux/installer/common/psw/BOMs/psw_x64.txt | 1 + linux/installer/common/psw/BOMs/psw_x86.txt | 1 + linux/installer/common/psw/Makefile | 7 + linux/installer/common/psw/createTarball.sh | 2 + linux/installer/common/psw/install.sh | 2 + linux/installer/common/sdk/BOMs/sdk_base.txt | 19 + linux/installer/common/sdk/install.sh | 2 +- .../deb/libsgx-enclave-common/build.sh | 113 + .../debian/changelog | 5 + .../libsgx-enclave-common-1.0/debian/compat | 1 + .../libsgx-enclave-common-1.0/debian/control | 14 + .../libsgx-enclave-common-1.0/debian/docs | 0 .../libsgx-enclave-common-1.0/debian/postinst | 40 + .../libsgx-enclave-common-1.0/debian/postrm | 41 + .../libsgx-enclave-common-1.0/debian/preinst | 36 + .../libsgx-enclave-common-1.0/debian/prerm | 38 + .../libsgx-enclave-common-1.0/debian/rules | 8 + .../debian/source/format | 1 + psw/ae/aesm_service/Makefile | 4 +- .../source/aesm/application/AEClass.h | 27 + .../source/aesm/application/aesm_logic.cpp | 51 +- .../source/aesm/application/aesm_logic.h | 1 + .../source/aesm/application/event_strings.cpp | 1 + .../source/aesm/application/event_strings.h | 1 + .../aesm/extension/endpoint_select_info.cpp | 11 +- .../aesm/extension/platform_info_logic.cpp | 14 + .../aesm_wrapper/src/AESMQueueManager.cpp | 3 +- .../epid_provision/epid_provision_msg1.cpp | 8 +- .../source/epid_provision/epid_utility.cpp | 3 + .../aesm_service/source/oal/internal_log.cpp | 3 + psw/ae/aesm_service/source/pce/PCEClass.cpp | 6 +- .../aesm_service/source/pse_op/PSEClass.cpp | 76 +- psw/ae/aesm_service/source/pse_op/PSEClass.h | 2 + .../source/pse_op/pse_op_logic.cpp | 4 + psw/ae/aesm_service/source/pve/pve_logic.cpp | 1 + psw/ae/aesm_service/source/qe/QEClass.cpp | 4 +- psw/ae/aesm_service/source/qe/qe_logic.cpp | 11 + .../BackendInterface/pse_crypto_helper.cpp | 17 +- psw/ae/common/pve_pub_key.cpp | 10 +- psw/ae/common/se_ecdsa_verify_internal.cpp | 16 +- .../cse_provision_tool/cse_provision_tool.cpp | 4 +- psw/ae/inc/aeerror.h | 4 + psw/ae/inc/internal/tlv_common.h | 4 +- psw/ae/pce/Makefile | 2 - psw/ae/pce/pce.cpp | 14 +- psw/ae/pce/pce_helper.cpp | 16 +- psw/ae/pse/pse_pr/X509Parser.cpp | 6 + .../pse/pse_pr/include/prepare_hmac_sha256.h | 2 + psw/ae/pse/pse_pr/prepare_hmac_sha256.cpp | 12 +- psw/ae/pve/Makefile | 4 +- psw/ae/pve/cipher.cpp | 20 +- psw/ae/pve/provision_msg3.cpp | 4 +- psw/ae/qe/Makefile | 4 +- psw/ae/qe/quoting_enclave.cpp | 38 +- psw/enclave_common/Makefile | 117 + psw/enclave_common/sgx_enclave_common.cpp | 558 ++++ psw/enclave_common/sgx_enclave_common.h | 203 ++ psw/enclave_common/sgx_enclave_common.lds | 11 + psw/uae_service/sgx_uae_service.cpp | 12 + psw/urts/enclave.cpp | 2 +- psw/urts/enclave_creator_hw.h | 7 +- psw/urts/enclave_creator_hw_com.cpp | 27 +- psw/urts/launch_checker.cpp | 2 +- psw/urts/linux/Makefile | 36 +- psw/urts/linux/enclave_creator_hw.cpp | 186 +- psw/urts/linux/isgx_user.h | 4 +- psw/urts/linux/urts.cpp | 10 +- psw/urts/linux/urts.lds | 1 - psw/urts/loader.cpp | 8 +- psw/urts/urts_com.h | 9 +- sdk/ec_dh_lib/ec_dh.cpp | 1 + sdk/edger8r/linux/Ast.ml | 48 +- sdk/edger8r/linux/CodeGen.ml | 201 +- sdk/edger8r/linux/Parser.mly | 18 +- sdk/edger8r/linux/Plugin.ml | 31 + sdk/libcapable/linux/sgx_capable_version.cpp | 2 +- .../sgx_tprotected_fs/file_version.cpp | 2 +- sdk/sign_tool/SignTool/manage_metadata.cpp | 19 +- sdk/sign_tool/SignTool/sign_tool.cpp | 83 +- sdk/sign_tool/SignTool/util_st.h | 2 +- sdk/simulation/tinst/t_instructions.cpp | 17 +- sdk/simulation/uinst/Makefile | 2 +- sdk/simulation/urtssim/urts_deploy.c | 6 - sdk/tkey_exchange/tkey_exchange_version.cpp | 2 +- sdk/tlibc/gen/sbrk.c | 8 +- sdk/tlibcrypto/ipp/sgx_ecc256.cpp | 172 +- sdk/tlibcrypto/ipp/sgx_ecc256_ecdsa.cpp | 2 +- sdk/tlibcrypto/ipp/sgx_ecc256_internal.cpp | 2 +- sdk/tlibcrypto/ipp/sgx_rsa3072.cpp | 2 +- sdk/tlibcrypto/ipp/sgx_rsa_encryption.cpp | 3 +- sdk/tlibcrypto/ipp/sgx_rsa_internal.cpp | 68 +- sdk/tlibcrypto/ipp/sgx_tcrypto_common.cpp | 2 +- sdk/tlibcrypto/ipp/sgx_tcrypto_common.h | 66 - sdk/tlibcrypto/sgxssl/sgx_cmac128.cpp | 2 - sdk/tlibcrypto/sgxssl/sgx_ecc256.cpp | 105 +- sdk/tlibcrypto/tcrypto_version.cpp | 2 +- sdk/tlibcxx/Makefile | 2 +- sdk/trts/init_enclave.cpp | 8 +- sdk/trts/linux/global_init.c | 2 - sdk/trts/trts_ecall.cpp | 6 +- sdk/trts/trts_veh.cpp | 4 +- sdk/tseal/tSeal.cpp | 20 +- sdk/tseal/tSeal_aad.cpp | 13 +- sdk/tsetjmp/Makefile | 5 - sdk/tsetjmp/_setjmp.S | 4 - sdk/ukey_exchange/ukey_exchange_version.cpp | 2 +- 182 files changed, 7025 insertions(+), 1836 deletions(-) rename sdk/tsetjmp/tlongjmp_version.cpp => SampleCode/SampleCommonLoader/App/enclave_entry.S (84%) create mode 100644 SampleCode/SampleCommonLoader/App/sample.cpp create mode 100644 SampleCode/SampleCommonLoader/Include/enclave_entry.h create mode 100644 SampleCode/SampleCommonLoader/Include/linux-regs.h create mode 100644 SampleCode/SampleCommonLoader/Include/sgx_enclave_blob.h create mode 100644 SampleCode/SampleCommonLoader/Include/sgx_enclave_ss.h create mode 100644 SampleCode/SampleCommonLoader/Makefile create mode 100644 SampleCode/SampleCommonLoader/README.txt delete mode 100644 common/src/ipp_bn.cpp delete mode 100644 common/src/ipp_rsa_pub_key.cpp create mode 100644 linux/installer/common/libsgx-enclave-common/BOMs/sgx-enclave-common_base.txt create mode 100644 linux/installer/common/libsgx-enclave-common/BOMs/sgx-enclave-common_x64.txt create mode 100644 linux/installer/common/libsgx-enclave-common/BOMs/sgx-enclave-common_x86.txt create mode 100644 linux/installer/common/libsgx-enclave-common/Makefile create mode 100755 linux/installer/common/libsgx-enclave-common/createTarball.sh create mode 100755 linux/installer/common/libsgx-enclave-common/install.sh create mode 100644 linux/installer/common/libsgx-enclave-common/installConfig.x64 create mode 100644 linux/installer/common/libsgx-enclave-common/installConfig.x86 create mode 100755 linux/installer/deb/libsgx-enclave-common/build.sh create mode 100644 linux/installer/deb/libsgx-enclave-common/libsgx-enclave-common-1.0/debian/changelog create mode 100644 linux/installer/deb/libsgx-enclave-common/libsgx-enclave-common-1.0/debian/compat create mode 100644 linux/installer/deb/libsgx-enclave-common/libsgx-enclave-common-1.0/debian/control create mode 100644 linux/installer/deb/libsgx-enclave-common/libsgx-enclave-common-1.0/debian/docs create mode 100644 linux/installer/deb/libsgx-enclave-common/libsgx-enclave-common-1.0/debian/postinst create mode 100644 linux/installer/deb/libsgx-enclave-common/libsgx-enclave-common-1.0/debian/postrm create mode 100644 linux/installer/deb/libsgx-enclave-common/libsgx-enclave-common-1.0/debian/preinst create mode 100644 linux/installer/deb/libsgx-enclave-common/libsgx-enclave-common-1.0/debian/prerm create mode 100755 linux/installer/deb/libsgx-enclave-common/libsgx-enclave-common-1.0/debian/rules create mode 100644 linux/installer/deb/libsgx-enclave-common/libsgx-enclave-common-1.0/debian/source/format create mode 100644 psw/enclave_common/Makefile create mode 100644 psw/enclave_common/sgx_enclave_common.cpp create mode 100644 psw/enclave_common/sgx_enclave_common.h create mode 100644 psw/enclave_common/sgx_enclave_common.lds delete mode 100644 sdk/tlibcrypto/ipp/sgx_tcrypto_common.h diff --git a/Linux_SGXEclipsePlugin/build_directory/plugins/com.intel.sgx/OSGI-INF/l10n/bundle.properties b/Linux_SGXEclipsePlugin/build_directory/plugins/com.intel.sgx/OSGI-INF/l10n/bundle.properties index b4e358bd..46262c06 100644 --- a/Linux_SGXEclipsePlugin/build_directory/plugins/com.intel.sgx/OSGI-INF/l10n/bundle.properties +++ b/Linux_SGXEclipsePlugin/build_directory/plugins/com.intel.sgx/OSGI-INF/l10n/bundle.properties @@ -12,4 +12,4 @@ Bundle-Vendor = Intel Corporation -Bundle-Name = SGX(R) Linux Eclipse Plugin \ No newline at end of file +Bundle-Name = Intel(R) SGX Linux Eclipse Plugin \ No newline at end of file diff --git a/Makefile b/Makefile index dc31838e..ae91cb70 100644 --- a/Makefile +++ b/Makefile @@ -47,6 +47,9 @@ sdk_install_pkg: sdk psw_install_pkg: psw ./linux/installer/bin/build-installpkg.sh psw +deb_sgx_enclave_common_pkg: psw + ./linux/installer/deb/libsgx-enclave-common/build.sh + clean: @$(MAKE) -C sdk/ clean @$(MAKE) -C psw/ clean diff --git a/README.md b/README.md index 9fb95e00..10f2c80d 100644 --- a/README.md +++ b/README.md @@ -34,22 +34,22 @@ Build the Intel(R) SGX SDK and Intel(R) SGX PSW Package ------------------------------------------------------- ### Prerequisites: - Ensure that you have one of the following required operating systems: - * Ubuntu\* 16.04 LTS Desktop 64bits - * Ubuntu\* 16.04 LTS Server 64bits + * Ubuntu\* 18.04 LTS Desktop 64bits + * Ubuntu\* 18.04 LTS Server 64bits * Red Hat Enterprise Linux Server release 7.4 64bits - * CentOS 7.4.1708 64bits + * CentOS 7.5 64bits * Fedora 27 Server 64bits * SUSE Linux Enterprise Server 12 64bits - Use the following command(s) to install the required tools to build the Intel(R) SGX SDK: - * On Ubuntu 16.04: + * On Ubuntu 18.04: ``` - $ sudo apt-get install build-essential ocaml automake autoconf libtool wget python + $ sudo apt-get install build-essential ocaml ocamlbuild automake autoconf libtool wget python libssl-dev ``` - * On Red Hat Enterprise Linux 7.4 and CentOS 7.4: + * On Red Hat Enterprise Linux 7.4 and CentOS 7.5: ``` $ sudo yum groupinstall 'Development Tools' - $ sudo yum install ocaml wget python + $ sudo yum install ocaml ocaml-ocamlbuild wget python openssl-devel ``` * On Fedora 27: ``` @@ -59,14 +59,14 @@ Build the Intel(R) SGX SDK and Intel(R) SGX PSW Package * On SUSE Linux Enterprise Server 12: ``` $ sudo zypper install --type pattern devel_basis - $ sudo zypper install ocaml ocaml-ocamlbuild automake autoconf libtool wget python + $ sudo zypper install ocaml ocaml-ocamlbuild automake autoconf libtool wget python libopenssl-devel ``` - Use the following command to install additional required tools to build the Intel(R) SGX PSW: - * On Ubuntu 16.04: + * On Ubuntu 18.04: ``` - $ sudo apt-get install libssl-dev libcurl4-openssl-dev protobuf-compiler libprotobuf-dev + $ sudo apt-get install libssl-dev libcurl4-openssl-dev protobuf-compiler libprotobuf-dev debhelper ``` - * On Red Hat Enterprise Linux 7.4, CentOS 7.4 and Fedora 27: + * On Red Hat Enterprise Linux 7.4, CentOS 7.5 and Fedora 27: ``` $ sudo yum install openssl-devel libcurl-devel protobuf-devel ``` @@ -127,33 +127,45 @@ $ make sdk_install_pkg DEBUG=1 ### Build the Intel(R) SGX PSW Installer To build the Intel(R) SGX PSW installer, enter the following command: -``` -$ make psw_install_pkg -``` -You can find the generated Intel(R) SGX PSW installer ``sgx_linux_x64_psw_${version}.bin`` located under `linux/installer/bin/`, where `${version}` refers to the version number. +- On Ubuntu 18.04: + ``` + $ make deb_sgx_enclave_common_pkg + ``` + You can find the generated Intel(R) SGX PSW installer ``libsgx-enclave-common_${version}-${revision}_${arch}.deb`` located under `linux/installer/deb/libsgx-enclave-common`, where `${version}` refers to the version number and the `${arch}` refers to the platform. -**Note**: The above command builds the Intel(R) SGX SDK and PSW with default configuration firstly and then generates the target PSW Installer. To build the Intel(R) SGX PSW Installer with debug information kept in the tools and libraries, enter the following command: -``` -$ make psw_install_pkg DEBUG=1 -``` + **Note**: The above command builds the Intel(R) SGX PSW with default configuration firstly and then generates the target PSW Installer. To build the Intel(R) SGX PSW Installer with debug information kept in the tools and libraries, enter the following command: + ``` + $ make deb_sgx_enclave_common_pkg DEBUG=1 + ``` +- On Red Hat Enterprise Linux 7.4 and CentOS 7.5: +- On Fedora 27: +- On SUSE Linux Enterprise Server 12: + ``` + $ make psw_install_pkg + ``` + You can find the generated Intel(R) SGX PSW installer ``sgx_linux_x64_psw_${version}.bin`` located under `linux/installer/bin/`, where `${version}` refers to the version number. + **Note**: The above command builds the Intel(R) SGX PSW with default configuration firstly and then generates the target PSW Installer. To build the Intel(R) SGX PSW Installer with debug information kept in the tools and libraries, enter the following command: + ``` + $ make psw_install_pkg DEBUG=1 + ``` Install the Intel(R) SGX SDK ------------------------ ### Prerequisites - Ensure that you have one of the following operating systems: - * Ubuntu\* 16.04 LTS Desktop 64bits - * Ubuntu\* 16.04 LTS Server 64bits + * Ubuntu\* 18.04 LTS Desktop 64bits + * Ubuntu\* 18.04 LTS Server 64bits * Red Hat Enterprise Linux Server release 7.4 64bits - * CentOS 7.4.1708 64bits + * CentOS 7.5 64bits * Fedora 27 Server 64bits * SUSE Linux Enterprise Server 12 64bits - Use the following command to install the required tool to use Intel(R) SGX SDK: - * On Ubuntu 16.04: + * On Ubuntu 18.04: ``` $ sudo apt-get install build-essential python ``` - * On Red Hat Enterprise Linux 7.4 and CentOS 7.4: + * On Red Hat Enterprise Linux 7.4 and CentOS 7.5: ``` $ sudo yum groupinstall 'Development Tools' $ sudo yum install python @@ -205,10 +217,10 @@ Install the Intel(R) SGX PSW ---------------------------- ### Prerequisites - Ensure that you have one of the following operating systems: - * Ubuntu\* 16.04 LTS Desktop 64bits - * Ubuntu\* 16.04 LTS Server 64bits + * Ubuntu\* 18.04 LTS Desktop 64bits + * Ubuntu\* 18.04 LTS Server 64bits * Red Hat Enterprise Linux Server release 7.4 64bits - * CentOS 7.4.1708 64bits + * CentOS 7.5 64bits * Fedora 27 Server 64bits * SUSE Linux Enterprise Server 12 64bits - Ensure that you have a system with the following required hardware: @@ -216,11 +228,11 @@ Install the Intel(R) SGX PSW - Configure the system with the **Intel SGX hardware enabled** option and install Intel(R) SGX driver in advance. See the earlier topic, *Build and Install the Intel(R) SGX Driver*, for information on how to install the Intel(R) SGX driver. - Install the library using the following command: - * On Ubuntu 16.04: + * On Ubuntu 18.04: ``` $ sudo apt-get install libssl-dev libcurl4-openssl-dev libprotobuf-dev ``` - * On Red Hat Enterprise Linux 7.4, CentOS 7.4 and Fedora 27: + * On Red Hat Enterprise Linux 7.4, CentOS 7.5 and Fedora 27: ``` $ sudo yum install openssl-devel libcurl-devel protobuf-devel ``` @@ -228,16 +240,16 @@ Install the Intel(R) SGX PSW ``` $ sudo zypper install libopenssl-devel libcurl-devel protobuf-devel ``` -- To use Trusted Platform Service functions: +- `iclsClient` and `JHI` are optional prerequisite components and are needed if you need to use Intel(R) SGX Platform Service. To install these components: Ensure `mei_me` driver is enabled and `/dev/mei0` exists. Download [iclsClient](https://software.intel.com/en-us/sgx-sdk/download) and install it using the following commands: - * On Ubuntu 16.04: + * On Ubuntu 18.04: ``` $ sudo apt-get install alien $ sudo alien --scripts iclsClient-1.45.449.12-1.x86_64.rpm $ sudo dpkg -i iclsclient_1.45.449.12-2_amd64.deb ``` - * On Red Hat Enterprise Linux 7.4, CentOS 7.4 and Fedora 27: + * On Red Hat Enterprise Linux 7.4, CentOS 7.5 and Fedora 27: ``` $ sudo yum install iclsClient-1.45.449.12-1.x86_64.rpm ``` @@ -246,12 +258,12 @@ Install the Intel(R) SGX PSW $ sudo zypper install iclsClient-1.45.449.12-1.x86_64.rpm ``` Download source code from [dynamic-application-loader-host-interface](https://github.com/01org/dynamic-application-loader-host-interface) project. In the source code folder, build and install the `JHI` service using the following commands: - * On Ubuntu 16.04: + * On Ubuntu 18.04: ``` $ sudo apt-get install uuid-dev libxml2-dev cmake pkg-config $ cmake .;make;sudo make install;sudo systemctl enable jhi ``` - * On Red Hat Enterprise Linux 7.4, CentOS 7.4 and Fedora 27: + * On Red Hat Enterprise Linux 7.4, CentOS 7.5 and Fedora 27: ``` $ sudo yum install libuuid-devel libxml2-devel cmake pkgconfig $ cmake .;make;sudo make install;sudo ldconfig;sudo systemctl enable jhi @@ -263,12 +275,24 @@ Install the Intel(R) SGX PSW ``` ### Install the Intel(R) SGX PSW -To install the Intel(R) SGX PSW, invoke the installer with root privilege: -``` -$ cd linux/installer/bin -$ sudo ./sgx_linux_x64_psw_${version}.bin -``` - +To install the Intel(R) SGX PSW, invoke the installer with root privilege: +- On Ubuntu 18.04: + ``` + $ cd linux/installer/deb/libsgx-enclave-common + $ sudo dpkg -i ./libsgx-enclave-common_${version}-${revision}_${arch}.deb + ``` + To debug with sgx-gdb, enter the following command: + ``` + $ cd linux/installer/deb/libsgx-enclave-common + $ sudo dpkg -i ./libsgx-enclave-common-dbgsym_${version}-${revision}_${arch}.ddeb + ``` +- On Red Hat Enterprise Linux 7.4 and CentOS 7.5: +- On Fedora 27: +- On SUSE Linux Enterprise Server 12: + ``` + $ cd linux/installer/bin + $ sudo ./sgx_linux_x64_psw_${version}.bin + ``` ### Start or Stop aesmd Service The Intel(R) SGX PSW installer installs an aesmd service in your machine, which is running in a special linux account `aesmd`. To stop the service: `$ sudo service aesmd stop` diff --git a/SampleCode/Cxx11SGXDemo/App/App.cpp b/SampleCode/Cxx11SGXDemo/App/App.cpp index 83cf3ebe..5dcc5224 100644 --- a/SampleCode/Cxx11SGXDemo/App/App.cpp +++ b/SampleCode/Cxx11SGXDemo/App/App.cpp @@ -155,71 +155,22 @@ void print_error_message(sgx_status_t ret) } /* Initialize the enclave: - * Step 1: try to retrieve the launch token saved by last transaction - * Step 2: call sgx_create_enclave to initialize an enclave instance - * Step 3: save the launch token if it is updated + * Call sgx_create_enclave to initialize an enclave instance */ int initialize_enclave(void) { - char token_path[MAX_PATH] = {'\0'}; sgx_launch_token_t token = {0}; sgx_status_t ret = SGX_ERROR_UNEXPECTED; int updated = 0; - /* Step 1: try to retrieve the launch token saved by last transaction - * if there is no token, then create a new one. - */ - /* try to get the token saved in $HOME */ - const char *home_dir = getpwuid(getuid())->pw_dir; - - if (home_dir != NULL && - (strlen(home_dir)+strlen("/")+sizeof(TOKEN_FILENAME)+1) <= MAX_PATH) { - /* compose the token path */ - strncpy(token_path, home_dir, strlen(home_dir)); - strncat(token_path, "/", strlen("/")); - strncat(token_path, TOKEN_FILENAME, sizeof(TOKEN_FILENAME)+1); - } else { - /* if token path is too long or $HOME is NULL */ - strncpy(token_path, TOKEN_FILENAME, sizeof(TOKEN_FILENAME)); - } - - FILE *fp = fopen(token_path, "rb"); - if (fp == NULL && (fp = fopen(token_path, "wb")) == NULL) { - printf("Warning: Failed to create/open the launch token file \"%s\".\n", token_path); - } - - if (fp != NULL) { - /* read the token from saved file */ - size_t read_num = fread(token, 1, sizeof(sgx_launch_token_t), fp); - if (read_num != 0 && read_num != sizeof(sgx_launch_token_t)) { - /* if token is invalid, clear the buffer */ - memset(&token, 0x0, sizeof(sgx_launch_token_t)); - printf("Warning: Invalid launch token read from \"%s\".\n", token_path); - } - } - /* Step 2: call sgx_create_enclave to initialize an enclave instance */ + /* Call sgx_create_enclave to initialize an enclave instance */ /* Debug Support: set 2nd parameter to 1 */ ret = sgx_create_enclave(ENCLAVE_FILENAME, SGX_DEBUG_FLAG, &token, &updated, &global_eid, NULL); if (ret != SGX_SUCCESS) { print_error_message(ret); - if (fp != NULL) fclose(fp); return -1; } - /* Step 3: save the launch token if it is updated */ - if (updated == FALSE || fp == NULL) { - /* if the token is not updated, or file handler is invalid, do not perform saving */ - if (fp != NULL) fclose(fp); - return 0; - } - - /* reopen the file with write capablity */ - fp = freopen(token_path, "wb", fp); - if (fp == NULL) return 0; - size_t write_num = fwrite(token, 1, sizeof(sgx_launch_token_t), fp); - if (write_num != sizeof(sgx_launch_token_t)) - printf("Warning: Failed to save launch token to \"%s\".\n", token_path); - fclose(fp); return 0; } diff --git a/SampleCode/Cxx11SGXDemo/Enclave/TrustedLibrary/Libcxx.cpp b/SampleCode/Cxx11SGXDemo/Enclave/TrustedLibrary/Libcxx.cpp index b407715b..2da47854 100644 --- a/SampleCode/Cxx11SGXDemo/Enclave/TrustedLibrary/Libcxx.cpp +++ b/SampleCode/Cxx11SGXDemo/Enclave/TrustedLibrary/Libcxx.cpp @@ -228,6 +228,7 @@ public: Base(const Base &) = delete; Base() = default; virtual void f_must_be_overrided() {}; + virtual ~Base() {}; }; /* Helper class for ecall_virtual_function_control_demo.*/ diff --git a/SampleCode/Cxx11SGXDemo/Makefile b/SampleCode/Cxx11SGXDemo/Makefile index b3dfa683..4c9cf4df 100644 --- a/SampleCode/Cxx11SGXDemo/Makefile +++ b/SampleCode/Cxx11SGXDemo/Makefile @@ -43,12 +43,12 @@ else ifeq ($(findstring -m32, $(CXXFLAGS)), -m32) endif ifeq ($(SGX_ARCH), x86) - SGX_COMMON_CFLAGS := -m32 + SGX_COMMON_FLAGS := -m32 SGX_LIBRARY_PATH := $(SGX_SDK)/lib SGX_ENCLAVE_SIGNER := $(SGX_SDK)/bin/x86/sgx_sign SGX_EDGER8R := $(SGX_SDK)/bin/x86/sgx_edger8r else - SGX_COMMON_CFLAGS := -m64 + SGX_COMMON_FLAGS := -m64 SGX_LIBRARY_PATH := $(SGX_SDK)/lib64 SGX_ENCLAVE_SIGNER := $(SGX_SDK)/bin/x64/sgx_sign SGX_EDGER8R := $(SGX_SDK)/bin/x64/sgx_edger8r @@ -61,11 +61,18 @@ endif endif ifeq ($(SGX_DEBUG), 1) - SGX_COMMON_CFLAGS += -O0 -g + SGX_COMMON_FLAGS += -O0 -g else - SGX_COMMON_CFLAGS += -O2 + SGX_COMMON_FLAGS += -O2 endif +SGX_COMMON_FLAGS += -Wall -Wextra -Winit-self -Wpointer-arith -Wreturn-type \ + -Waddress -Wsequence-point -Wformat-security \ + -Wmissing-include-dirs -Wfloat-equal -Wundef -Wshadow \ + -Wcast-align -Wcast-qual -Wconversion -Wredundant-decls +SGX_COMMON_CFLAGS := $(SGX_COMMON_FLAGS) -Wjump-misses-init -Wstrict-prototypes -Wunsuffixed-float-constants +SGX_COMMON_CXXFLAGS := $(SGX_COMMON_FLAGS) -Wnon-virtual-dtor -std=c++11 + ######## App Settings ######## ifneq ($(SGX_MODE), HW) @@ -75,9 +82,9 @@ else endif App_Cpp_Files := App/App.cpp $(wildcard App/TrustedLibrary/*.cpp) -App_Include_Paths := -IInclude -IApp -I$(SGX_SDK)/include +App_Include_Paths := -IApp -I$(SGX_SDK)/include -App_C_Flags := $(SGX_COMMON_CFLAGS) -fPIC -Wno-attributes $(App_Include_Paths) +App_C_Flags := -fPIC -Wno-attributes $(App_Include_Paths) # Three configuration modes - Debug, prerelease, release # Debug - Macro DEBUG enabled. @@ -91,8 +98,8 @@ else App_C_Flags += -DNDEBUG -UEDEBUG -UDEBUG endif -App_Cpp_Flags := $(App_C_Flags) -std=c++11 -App_Link_Flags := $(SGX_COMMON_CFLAGS) -L$(SGX_LIBRARY_PATH) -l$(Urts_Library_Name) -lpthread +App_Cpp_Flags := $(App_C_Flags) +App_Link_Flags := -L$(SGX_LIBRARY_PATH) -l$(Urts_Library_Name) -lpthread ifneq ($(SGX_MODE), HW) App_Link_Flags += -lsgx_uae_service_sim @@ -126,10 +133,10 @@ endif Crypto_Library_Name := sgx_tcrypto Enclave_Cpp_Files := Enclave/Enclave.cpp $(wildcard Enclave/TrustedLibrary/*.cpp) -Enclave_Include_Paths := -IInclude -IEnclave -I$(SGX_SDK)/include -I$(SGX_SDK)/include/libcxx -I$(SGX_SDK)/include/tlibc +Enclave_Include_Paths := -IEnclave -I$(SGX_SDK)/include -I$(SGX_SDK)/include/libcxx -I$(SGX_SDK)/include/tlibc -Enclave_C_Flags := $(SGX_COMMON_CFLAGS) -nostdinc -fvisibility=hidden -fpie -fstack-protector $(Enclave_Include_Paths) -Enclave_Cpp_Flags := $(Enclave_C_Flags) -nostdinc++ -std=c++11 +Enclave_C_Flags := -nostdinc -fvisibility=hidden -fpie -fstack-protector $(Enclave_Include_Paths) +Enclave_Cpp_Flags := $(Enclave_C_Flags) -nostdinc++ # To generate a proper enclave, it is recommended to follow below guideline to link the trusted libraries: # 1. Link sgx_trts with the `--whole-archive' and `--no-whole-archive' options, @@ -138,7 +145,7 @@ Enclave_Cpp_Flags := $(Enclave_C_Flags) -nostdinc++ -std=c++11 # Use `--start-group' and `--end-group' to link these libraries. # Do NOT move the libraries linked with `--start-group' and `--end-group' within `--whole-archive' and `--no-whole-archive' options. # Otherwise, you may get some undesirable errors. -Enclave_Link_Flags := $(SGX_COMMON_CFLAGS) -Wl,--no-undefined -nostdlib -nodefaultlibs -nostartfiles -L$(SGX_LIBRARY_PATH) \ +Enclave_Link_Flags := -Wl,--no-undefined -nostdlib -nodefaultlibs -nostartfiles -L$(SGX_LIBRARY_PATH) \ -Wl,--whole-archive -l$(Trts_Library_Name) -Wl,--no-whole-archive \ -Wl,--start-group -lsgx_tstdc -lsgx_tcxx -l$(Crypto_Library_Name) -l$(Service_Library_Name) -Wl,--end-group \ -Wl,-Bstatic -Wl,-Bsymbolic -Wl,--no-undefined \ @@ -209,11 +216,11 @@ App/Enclave_u.c: $(SGX_EDGER8R) Enclave/Enclave.edl @echo "GEN => $@" App/Enclave_u.o: App/Enclave_u.c - @$(CC) $(App_C_Flags) -c $< -o $@ + @$(CC) $(SGX_COMMON_CFLAGS) $(App_C_Flags) -c $< -o $@ @echo "CC <= $<" App/%.o: App/%.cpp - @$(CXX) $(App_Cpp_Flags) -c $< -o $@ + @$(CXX) $(SGX_COMMON_CXXFLAGS) $(App_Cpp_Flags) -c $< -o $@ @echo "CXX <= $<" $(App_Name): App/Enclave_u.o $(App_Cpp_Objects) @@ -231,11 +238,11 @@ Enclave/Enclave_t.c: $(SGX_EDGER8R) Enclave/Enclave.edl @echo "GEN => $@" Enclave/Enclave_t.o: Enclave/Enclave_t.c - @$(CC) $(Enclave_C_Flags) -c $< -o $@ + @$(CC) $(SGX_COMMON_CFLAGS) $(Enclave_C_Flags) -c $< -o $@ @echo "CC <= $<" Enclave/%.o: Enclave/%.cpp - @$(CXX) $(Enclave_Cpp_Flags) -c $< -o $@ + @$(CXX) $(SGX_COMMON_CXXFLAGS) $(Enclave_Cpp_Flags) -c $< -o $@ @echo "CXX <= $<" $(Enclave_Name): Enclave/Enclave_t.o $(Enclave_Cpp_Objects) diff --git a/SampleCode/LocalAttestation/App/App.cpp b/SampleCode/LocalAttestation/App/App.cpp index aa5c5a20..8c81f2f0 100644 --- a/SampleCode/LocalAttestation/App/App.cpp +++ b/SampleCode/LocalAttestation/App/App.cpp @@ -66,6 +66,7 @@ void waitForKeyPress() int temp; printf("\n\nHit a key....\n"); temp = scanf_s("%c", &ch); + (void) temp; } uint32_t load_enclaves() @@ -435,10 +436,7 @@ int _tmain(int argc, _TCHAR* argv[]) } } -#pragma warning (push) -#pragma warning (disable : 4127) }while(0); -#pragma warning (pop) sgx_destroy_enclave(e1_enclave_id); sgx_destroy_enclave(e2_enclave_id); diff --git a/SampleCode/LocalAttestation/Enclave1/Enclave1.cpp b/SampleCode/LocalAttestation/Enclave1/Enclave1.cpp index ff5b1da9..043f43bc 100644 --- a/SampleCode/LocalAttestation/Enclave1/Enclave1.cpp +++ b/SampleCode/LocalAttestation/Enclave1/Enclave1.cpp @@ -36,7 +36,6 @@ #include "EnclaveMessageExchange.h" #include "error_codes.h" #include "Utility_E1.h" -#include "sgx_thread.h" #include "sgx_dh.h" #include diff --git a/SampleCode/LocalAttestation/Enclave1/Enclave1.edl b/SampleCode/LocalAttestation/Enclave1/Enclave1.edl index da2b6ab9..b986919d 100644 --- a/SampleCode/LocalAttestation/Enclave1/Enclave1.edl +++ b/SampleCode/LocalAttestation/Enclave1/Enclave1.edl @@ -32,7 +32,6 @@ enclave { include "sgx_eid.h" from "../LocalAttestationCode/LocalAttestationCode.edl" import *; - from "sgx_tstdc.edl" import *; trusted{ public uint32_t test_create_session(sgx_enclave_id_t src_enclave_id, sgx_enclave_id_t dest_enclave_id); public uint32_t test_enclave_to_enclave_call(sgx_enclave_id_t src_enclave_id, sgx_enclave_id_t dest_enclave_id); diff --git a/SampleCode/LocalAttestation/Enclave2/Enclave2.cpp b/SampleCode/LocalAttestation/Enclave2/Enclave2.cpp index 85e21b5c..bce517d8 100644 --- a/SampleCode/LocalAttestation/Enclave2/Enclave2.cpp +++ b/SampleCode/LocalAttestation/Enclave2/Enclave2.cpp @@ -36,7 +36,6 @@ #include "EnclaveMessageExchange.h" #include "error_codes.h" #include "Utility_E2.h" -#include "sgx_thread.h" #include "sgx_dh.h" #include diff --git a/SampleCode/LocalAttestation/Enclave2/Enclave2.edl b/SampleCode/LocalAttestation/Enclave2/Enclave2.edl index 6886a828..4e0c0094 100644 --- a/SampleCode/LocalAttestation/Enclave2/Enclave2.edl +++ b/SampleCode/LocalAttestation/Enclave2/Enclave2.edl @@ -33,7 +33,6 @@ enclave { include "sgx_eid.h" from "../LocalAttestationCode/LocalAttestationCode.edl" import *; - from "sgx_tstdc.edl" import *; trusted{ public uint32_t test_create_session(sgx_enclave_id_t src_enclave_id, sgx_enclave_id_t dest_enclave_id); public uint32_t test_enclave_to_enclave_call(sgx_enclave_id_t src_enclave_id, sgx_enclave_id_t dest_enclave_id); diff --git a/SampleCode/LocalAttestation/Enclave3/Enclave3.cpp b/SampleCode/LocalAttestation/Enclave3/Enclave3.cpp index 70e677d9..ddced88b 100644 --- a/SampleCode/LocalAttestation/Enclave3/Enclave3.cpp +++ b/SampleCode/LocalAttestation/Enclave3/Enclave3.cpp @@ -36,7 +36,6 @@ #include "EnclaveMessageExchange.h" #include "error_codes.h" #include "Utility_E3.h" -#include "sgx_thread.h" #include "sgx_dh.h" #include diff --git a/SampleCode/LocalAttestation/Enclave3/Enclave3.edl b/SampleCode/LocalAttestation/Enclave3/Enclave3.edl index a850546d..a1e83a9d 100644 --- a/SampleCode/LocalAttestation/Enclave3/Enclave3.edl +++ b/SampleCode/LocalAttestation/Enclave3/Enclave3.edl @@ -32,7 +32,6 @@ enclave { include "sgx_eid.h" from "../LocalAttestationCode/LocalAttestationCode.edl" import *; - from "sgx_tstdc.edl" import *; trusted{ public uint32_t test_create_session(sgx_enclave_id_t src_enclave_id, sgx_enclave_id_t dest_enclave_id); public uint32_t test_enclave_to_enclave_call(sgx_enclave_id_t src_enclave_id, sgx_enclave_id_t dest_enclave_id); diff --git a/SampleCode/LocalAttestation/LocalAttestationCode/EnclaveMessageExchange.cpp b/SampleCode/LocalAttestation/LocalAttestationCode/EnclaveMessageExchange.cpp index c97f44bc..5a1978f9 100644 --- a/SampleCode/LocalAttestation/LocalAttestationCode/EnclaveMessageExchange.cpp +++ b/SampleCode/LocalAttestation/LocalAttestationCode/EnclaveMessageExchange.cpp @@ -61,7 +61,6 @@ uint32_t verify_peer_enclave_trust(sgx_dh_session_enclave_identity_t* peer_encla uint32_t g_session_count = 0; ATTESTATION_STATUS generate_session_id(uint32_t *session_id); -ATTESTATION_STATUS end_session(sgx_enclave_id_t src_enclave_id); //Array of open session ids session_id_tracker_t *g_session_id_tracker[MAX_SESSION_COUNT]; diff --git a/SampleCode/LocalAttestation/Makefile b/SampleCode/LocalAttestation/Makefile index a90c857a..3023067c 100644 --- a/SampleCode/LocalAttestation/Makefile +++ b/SampleCode/LocalAttestation/Makefile @@ -43,12 +43,12 @@ else ifeq ($(findstring -m32, $(CXXFLAGS)), -m32) endif ifeq ($(SGX_ARCH), x86) - SGX_COMMON_CFLAGS := -m32 + SGX_COMMON_FLAGS := -m32 SGX_LIBRARY_PATH := $(SGX_SDK)/lib SGX_ENCLAVE_SIGNER := $(SGX_SDK)/bin/x86/sgx_sign SGX_EDGER8R := $(SGX_SDK)/bin/x86/sgx_edger8r else - SGX_COMMON_CFLAGS := -m64 + SGX_COMMON_FLAGS := -m64 SGX_LIBRARY_PATH := $(SGX_SDK)/lib64 SGX_ENCLAVE_SIGNER := $(SGX_SDK)/bin/x64/sgx_sign SGX_EDGER8R := $(SGX_SDK)/bin/x64/sgx_edger8r @@ -61,25 +61,33 @@ endif endif ifeq ($(SGX_DEBUG), 1) - SGX_COMMON_CFLAGS += -O0 -g + SGX_COMMON_FLAGS += -O0 -g else - SGX_COMMON_CFLAGS += -O2 + SGX_COMMON_FLAGS += -O2 endif +SGX_COMMON_FLAGS += -v -Wall -Wextra -Winit-self -Wpointer-arith -Wreturn-type \ + -Waddress -Wsequence-point -Wformat-security \ + -Wmissing-include-dirs -Wfloat-equal -Wundef -Wshadow \ + -Wcast-align -Wcast-qual -Wconversion -Wredundant-decls +SGX_COMMON_CFLAGS := $(SGX_COMMON_FLAGS) -Wjump-misses-init -Wstrict-prototypes -Wunsuffixed-float-constants +SGX_COMMON_CXXFLAGS := $(SGX_COMMON_FLAGS) -Wnon-virtual-dtor -std=c++11 + ######## Library Settings ######## Trust_Lib_Name := libLocalAttestation_Trusted.a TrustLib_Cpp_Files := $(wildcard LocalAttestationCode/*.cpp) TrustLib_Cpp_Objects := $(TrustLib_Cpp_Files:.cpp=.o) -TrustLib_Include_Paths := -I$(SGX_SDK)/include -I$(SGX_SDK)/include/tlibc -I$(SGX_SDK)/include/libcxx -I$(SGX_SDK)/include/epid -I./Include -TrustLib_Compile_Flags := $(SGX_COMMON_CFLAGS) -nostdinc -fvisibility=hidden -fpie -fstack-protector $(TrustLib_Include_Paths) -TrustLib_Compile_Cxx_Flags := -std=c++11 -nostdinc++ +TrustLib_Include_Paths := -I$(SGX_SDK)/include -I$(SGX_SDK)/include/tlibc -I$(SGX_SDK)/include/libcxx -I./Include #-I$(SGX_SDK)/include/epid -I./Include +TrustLib_C_Flags := -nostdinc -fvisibility=hidden -fpie -fstack-protector $(TrustLib_Include_Paths) +TrustLib_Cxx_Flags := $(TrustLib_C_Flags) $(SGX_COMMON_CXXFLAGS) -nostdinc++ +TrustLib_C_Flags += $(SGX_COMMON_CFLAGS) UnTrustLib_Name := libLocalAttestation_unTrusted.a UnTrustLib_Cpp_Files := $(wildcard Untrusted_LocalAttestation/*.cpp) UnTrustLib_Cpp_Objects := $(UnTrustLib_Cpp_Files:.cpp=.o) -UnTrustLib_Include_Paths := -I$(SGX_SDK)/include -I$(SGX_SDK)/include/ippcp -I./Include -I./LocalAttestationCode -UnTrustLib_Compile_Flags := $(SGX_COMMON_CFLAGS) -fPIC -Wno-attributes -std=c++11 $(UnTrustLib_Include_Paths) +UnTrustLib_Include_Paths := -I$(SGX_SDK)/include -I./Include -I./LocalAttestationCode +UnTrustLib_Cxx_Flags := $(SGX_COMMON_CXXFLAGS) -fPIC -Wno-attributes $(UnTrustLib_Include_Paths) ######## App Settings ######## @@ -90,22 +98,25 @@ else endif App_Cpp_Files := $(wildcard App/*.cpp) -App_Include_Paths := -I$(SGX_SDK)/include -I$(SGX_SDK)/include/ippcp -I./Include -I./LocalAttestationCode +App_Include_Paths := -I$(SGX_SDK)/include -I./Include -I./LocalAttestationCode -App_Compile_Flags := $(SGX_COMMON_CFLAGS) -fPIC -Wno-attributes $(App_Include_Paths) +App_C_Flags := -fPIC -Wno-attributes $(App_Include_Paths) # Three configuration modes - Debug, prerelease, release # Debug - Macro DEBUG enabled. # Prerelease - Macro NDEBUG and EDEBUG enabled. # Release - Macro NDEBUG enabled. ifeq ($(SGX_DEBUG), 1) - App_Compile_Flags += -DDEBUG -UNDEBUG -UEDEBUG + App_C_Flags += -DDEBUG -UNDEBUG -UEDEBUG else ifeq ($(SGX_PRERELEASE), 1) - App_Compile_Flags += -DNDEBUG -DEDEBUG -UDEBUG + App_C_Flags += -DNDEBUG -DEDEBUG -UDEBUG else - App_Compile_Flags += -DNDEBUG -UEDEBUG -UDEBUG + App_C_Flags += -DNDEBUG -UEDEBUG -UDEBUG endif -App_Link_Flags := $(SGX_COMMON_CFLAGS) -L$(SGX_LIBRARY_PATH) -l$(Urts_Library_Name) -L. -lpthread -lLocalAttestation_unTrusted +App_Cxx_Flags := $(App_C_Flags) $(SGX_COMMON_CXXFLAGS) +App_C_Flags += $(SGX_COMMON_CFLAGS) + +App_Link_Flags := -L$(SGX_LIBRARY_PATH) -l$(Urts_Library_Name) -L. -lpthread -lLocalAttestation_unTrusted ifneq ($(SGX_MODE), HW) App_Link_Flags += -lsgx_uae_service_sim @@ -138,12 +149,14 @@ Enclave_Include_Paths := -I$(SGX_SDK)/include -I$(SGX_SDK)/include/tlibc -I$(SGX CC_BELOW_4_9 := $(shell expr "`$(CC) -dumpversion`" \< "4.9") ifeq ($(CC_BELOW_4_9), 1) - Enclave_Compile_Flags := $(SGX_COMMON_CFLAGS) -nostdinc -fvisibility=hidden -fpie -ffunction-sections -fdata-sections -fstack-protector + Enclave_C_Flags := -nostdinc -fvisibility=hidden -fpie -ffunction-sections -fdata-sections -fstack-protector else - Enclave_Compile_Flags := $(SGX_COMMON_CFLAGS) -nostdinc -fvisibility=hidden -fpie -ffunction-sections -fdata-sections -fstack-protector-strong + Enclave_C_Flags := -nostdinc -fvisibility=hidden -fpie -ffunction-sections -fdata-sections -fstack-protector-strong endif -Enclave_Compile_Flags += $(Enclave_Include_Paths) +Enclave_C_Flags += $(Enclave_Include_Paths) +Enclave_Cxx_Flags := $(Enclave_C_Flags) $(SGX_COMMON_CXXFLAGS) -nostdinc++ +Enclave_C_Flasg += $(SGX_COMMON_CFLAGS) # To generate a proper enclave, it is recommended to follow below guideline to link the trusted libraries: # 1. Link sgx_trts with the `--whole-archive' and `--no-whole-archive' options, @@ -152,7 +165,7 @@ Enclave_Compile_Flags += $(Enclave_Include_Paths) # Use `--start-group' and `--end-group' to link these libraries. # Do NOT move the libraries linked with `--start-group' and `--end-group' within `--whole-archive' and `--no-whole-archive' options. # Otherwise, you may get some undesirable errors. -Common_Enclave_Link_Flags := $(SGX_COMMON_CFLAGS) -Wl,--no-undefined -nostdlib -nodefaultlibs -nostartfiles -L$(SGX_LIBRARY_PATH) \ +Common_Enclave_Link_Flags := -Wl,--no-undefined -nostdlib -nodefaultlibs -nostartfiles -L$(SGX_LIBRARY_PATH) \ -Wl,--whole-archive -l$(Trts_Library_Name) -Wl,--no-whole-archive \ -Wl,--start-group -lsgx_tstdc -lsgx_tcxx -l$(Crypto_Library_Name) -L. -lLocalAttestation_Trusted -l$(Service_Library_Name) -Wl,--end-group \ -Wl,-Bstatic -Wl,-Bsymbolic -Wl,--no-undefined \ @@ -224,11 +237,11 @@ LocalAttestationCode/LocalAttestationCode_t.c LocalAttestationCode/LocalAttestat @echo "GEN => $@" LocalAttestationCode/LocalAttestationCode_t.o: LocalAttestationCode/LocalAttestationCode_t.c - @$(CC) $(TrustLib_Compile_Flags) -c $< -o $@ + @$(CC) $(TrustLib_C_Flags) -c $< -o $@ @echo "CC <= $<" LocalAttestationCode/%.o: LocalAttestationCode/%.cpp LocalAttestationCode/LocalAttestationCode_t.h - @$(CXX) $(TrustLib_Compile_Flags) $(TrustLib_Compile_Cxx_Flags) -c $< -o $@ + @$(CXX) $(TrustLib_Cxx_Flags) -c $< -o $@ @echo "CC <= $<" $(Trust_Lib_Name): LocalAttestationCode/LocalAttestationCode_t.o $(TrustLib_Cpp_Objects) @@ -236,7 +249,7 @@ $(Trust_Lib_Name): LocalAttestationCode/LocalAttestationCode_t.o $(TrustLib_Cpp_ @echo "GEN => $@" Untrusted_LocalAttestation/%.o: Untrusted_LocalAttestation/%.cpp - @$(CXX) $(UnTrustLib_Compile_Flags) -c $< -o $@ + @$(CXX) $(UnTrustLib_Cxx_Flags) -c $< -o $@ @echo "CC <= $<" $(UnTrustLib_Name): $(UnTrustLib_Cpp_Objects) @@ -249,7 +262,7 @@ Enclave1/Enclave1_u.c Enclave1/Enclave1_u.h: $(SGX_EDGER8R) Enclave1/Enclave1.ed @echo "GEN => $@" App/Enclave1_u.o: Enclave1/Enclave1_u.c - @$(CC) $(App_Compile_Flags) -c $< -o $@ + @$(CC) $(App_C_Flags) -c $< -o $@ @echo "CC <= $<" Enclave2/Enclave2_u.c Enclave2/Enclave2_u.h: $(SGX_EDGER8R) Enclave2/Enclave2.edl @@ -257,7 +270,7 @@ Enclave2/Enclave2_u.c Enclave2/Enclave2_u.h: $(SGX_EDGER8R) Enclave2/Enclave2.ed @echo "GEN => $@" App/Enclave2_u.o: Enclave2/Enclave2_u.c - @$(CC) $(App_Compile_Flags) -c $< -o $@ + @$(CC) $(App_C_Flags) -c $< -o $@ @echo "CC <= $<" Enclave3/Enclave3_u.c Enclave3/Enclave3_u.h: $(SGX_EDGER8R) Enclave3/Enclave3.edl @@ -265,11 +278,11 @@ Enclave3/Enclave3_u.c Enclave3/Enclave3_u.h: $(SGX_EDGER8R) Enclave3/Enclave3.ed @echo "GEN => $@" App/Enclave3_u.o: Enclave3/Enclave3_u.c - @$(CC) $(App_Compile_Flags) -c $< -o $@ + @$(CC) $(App_C_Flags) -c $< -o $@ @echo "CC <= $<" App/%.o: App/%.cpp Enclave1/Enclave1_u.h Enclave2/Enclave2_u.h Enclave3/Enclave3_u.h - @$(CXX) $(App_Compile_Flags) -c $< -o $@ + @$(CXX) $(App_Cxx_Flags) -c $< -o $@ @echo "CXX <= $<" $(App_Name): App/Enclave1_u.o App/Enclave2_u.o App/Enclave3_u.o $(App_Cpp_Objects) $(UnTrustLib_Name) @@ -284,11 +297,11 @@ Enclave1/Enclave1_t.c Enclave1/Enclave1_t.h: $(SGX_EDGER8R) Enclave1/Enclave1.ed @echo "GEN => $@" Enclave1/Enclave1_t.o: Enclave1/Enclave1_t.c - @$(CC) $(Enclave_Compile_Flags) -c $< -o $@ + @$(CC) $(Enclave_C_Flags) -c $< -o $@ @echo "CC <= $<" Enclave1/%.o: Enclave1/%.cpp Enclave1/Enclave1_t.h - @$(CXX) -std=c++11 -nostdinc++ $(Enclave_Compile_Flags) -c $< -o $@ + @$(CXX) $(Enclave_Cxx_Flags) -c $< -o $@ @echo "CXX <= $<" Enclave1.so: Enclave1/Enclave1_t.o $(Enclave_Cpp_Objects_1) $(Trust_Lib_Name) @@ -304,11 +317,11 @@ Enclave2/Enclave2_t.c: $(SGX_EDGER8R) Enclave2/Enclave2.edl @echo "GEN => $@" Enclave2/Enclave2_t.o: Enclave2/Enclave2_t.c - @$(CC) $(Enclave_Compile_Flags) -c $< -o $@ + @$(CC) $(Enclave_C_Flags) -c $< -o $@ @echo "CC <= $<" Enclave2/%.o: Enclave2/%.cpp - @$(CXX) -std=c++11 -nostdinc++ $(Enclave_Compile_Flags) -c $< -o $@ + @$(CXX) $(Enclave_Cxx_Flags) -c $< -o $@ @echo "CXX <= $<" Enclave2.so: Enclave2/Enclave2_t.o $(Enclave_Cpp_Objects_2) $(Trust_Lib_Name) @@ -324,11 +337,11 @@ Enclave3/Enclave3_t.c: $(SGX_EDGER8R) Enclave3/Enclave3.edl @echo "GEN => $@" Enclave3/Enclave3_t.o: Enclave3/Enclave3_t.c - @$(CC) $(Enclave_Compile_Flags) -c $< -o $@ + @$(CC) $(Enclave_C_Flags) -c $< -o $@ @echo "CC <= $<" Enclave3/%.o: Enclave3/%.cpp - @$(CXX) -std=c++11 -nostdinc++ $(Enclave_Compile_Flags) -c $< -o $@ + @$(CXX) $(Enclave_Cxx_Flags) -c $< -o $@ @echo "CXX <= $<" Enclave3.so: Enclave3/Enclave3_t.o $(Enclave_Cpp_Objects_3) $(Trust_Lib_Name) @@ -344,3 +357,4 @@ $(Enclave_Name_3): Enclave3.so clean: @rm -rf .config_* $(App_Name) *.so *.a App/*.o Enclave1/*.o Enclave1/*_t.* Enclave1/*_u.* Enclave2/*.o Enclave2/*_t.* Enclave2/*_u.* Enclave3/*.o Enclave3/*_t.* Enclave3/*_u.* LocalAttestationCode/*.o Untrusted_LocalAttestation/*.o LocalAttestationCode/*_t.* + diff --git a/SampleCode/PowerTransition/App/App.cpp b/SampleCode/PowerTransition/App/App.cpp index fe0593c8..3546d156 100644 --- a/SampleCode/PowerTransition/App/App.cpp +++ b/SampleCode/PowerTransition/App/App.cpp @@ -48,13 +48,11 @@ #include "ErrorSupport.h" #define ENCLAVE_NAME "libenclave.signed.so" -#define TOKEN_NAME "Enclave.token" #define THREAD_NUM 3 // Global data sgx_enclave_id_t global_eid = 0; -sgx_launch_token_t token = {0}; rwlock_t lock_eid; struct sealed_buf_t sealed_buf; @@ -68,9 +66,10 @@ void print(const char *str) // load_and_initialize_enclave(): // To load and initialize the enclave -sgx_status_t load_and_initialize_enclave(sgx_enclave_id_t *eid, struct sealed_buf_t *sealed_buf) +sgx_status_t load_and_initialize_enclave(sgx_enclave_id_t *eid, struct sealed_buf_t *buf) { sgx_status_t ret = SGX_SUCCESS; + sgx_launch_token_t token = {0}; int retval = 0; int updated = 0; @@ -89,23 +88,11 @@ sgx_status_t load_and_initialize_enclave(sgx_enclave_id_t *eid, struct sealed_bu if(ret != SGX_SUCCESS) return ret; - // Save the launch token if updated - if(updated == 1) - { - ofstream ofs(TOKEN_NAME, std::ios::binary|std::ios::out); - if(!ofs.good()) - { - cout<< "Warning: Failed to save the launch token to \"" <(&token), sizeof(sgx_launch_token_t)); - if(ifs.fail()) - { - memset(&token, 0, sizeof(sgx_launch_token_t)); - } - } - // Allocate memory to save the sealed data. uint32_t sealed_len = sizeof(sgx_sealed_data_t) + sizeof(uint32_t); for(int i = 0; i < BUF_NUM; i++) diff --git a/SampleCode/PowerTransition/Makefile b/SampleCode/PowerTransition/Makefile index b1dd29f5..797e6d20 100644 --- a/SampleCode/PowerTransition/Makefile +++ b/SampleCode/PowerTransition/Makefile @@ -43,12 +43,12 @@ else ifeq ($(findstring -m32, $(CXXFLAGS)), -m32) endif ifeq ($(SGX_ARCH), x86) - SGX_COMMON_CFLAGS := -m32 + SGX_COMMON_FLAGS := -m32 SGX_LIBRARY_PATH := $(SGX_SDK)/lib SGX_ENCLAVE_SIGNER := $(SGX_SDK)/bin/x86/sgx_sign SGX_EDGER8R := $(SGX_SDK)/bin/x86/sgx_edger8r else - SGX_COMMON_CFLAGS := -m64 + SGX_COMMON_FLAGS := -m64 SGX_LIBRARY_PATH := $(SGX_SDK)/lib64 SGX_ENCLAVE_SIGNER := $(SGX_SDK)/bin/x64/sgx_sign SGX_EDGER8R := $(SGX_SDK)/bin/x64/sgx_edger8r @@ -61,11 +61,18 @@ endif endif ifeq ($(SGX_DEBUG), 1) - SGX_COMMON_CFLAGS += -O0 -g + SGX_COMMON_FLAGS += -O0 -g else - SGX_COMMON_CFLAGS += -O2 + SGX_COMMON_FLAGS += -O2 endif +SGX_COMMON_FLAGS += -Wall -Wextra -Winit-self -Wpointer-arith -Wreturn-type \ + -Waddress -Wsequence-point -Wformat-security \ + -Wmissing-include-dirs -Wfloat-equal -Wundef -Wshadow \ + -Wcast-align -Wcast-qual -Wconversion -Wredundant-decls +SGX_COMMON_CFLAGS := $(SGX_COMMON_FLAGS) -Wjump-misses-init -Wstrict-prototypes -Wunsuffixed-float-constants +SGX_COMMON_CXXFLAGS := $(SGX_COMMON_FLAGS) -Wnon-virtual-dtor -std=c++11 + ######## App Settings ######## ifneq ($(SGX_MODE), HW) @@ -90,7 +97,7 @@ else App_Compile_CFlags += -DNDEBUG -UEDEBUG -UDEBUG endif -App_Compile_CXXFlags := -std=c++11 $(App_Compile_CFlags) +App_Compile_CXXFlags := $(App_Compile_CFlags) App_Link_Flags := -L$(SGX_LIBRARY_PATH) -l$(Urts_Library_Name) -lpthread ifneq ($(SGX_MODE), HW) @@ -129,7 +136,7 @@ else Enclave_Compile_CFlags := -fstack-protector-strong endif Enclave_Compile_CFlags += -nostdinc -ffreestanding -fvisibility=hidden -fpie -ffunction-sections -fdata-sections $(Enclave_Include_Paths) -Enclave_Compile_CXXFlags := -nostdinc++ -std=c++11 $(Enclave_Compile_CFlags) +Enclave_Compile_CXXFlags := -nostdinc++ $(Enclave_Compile_CFlags) # To generate a proper enclave, it is recommended to follow below guideline to link the trusted libraries: # 1. Link sgx_trts with the `--whole-archive' and `--no-whole-archive' options, @@ -210,11 +217,11 @@ $(Gen_Untrusted_Object): $(Gen_Untrusted_Source) @echo "CC <= $<" App/%.o: App/%.cpp - @$(CXX) $(SGX_COMMON_CFLAGS) $(App_Compile_CXXFlags) -c $< -o $@ + @$(CXX) $(SGX_COMMON_CXXFLAGS) $(App_Compile_CXXFlags) -c $< -o $@ @echo "CXX <= $<" $(App_Name): $(App_Objects) - @$(CXX) $(SGX_COMMON_CFLAGS) $^ -o $@ $(App_Link_Flags) + @$(CXX) $^ -o $@ $(App_Link_Flags) @echo "LINK => $@" @@ -228,11 +235,11 @@ $(Gen_Trusted_Object): $(Gen_Trusted_Source) @echo "CC <= $<" Enclave/%.o: Enclave/%.cpp - @$(CXX) $(SGX_COMMON_CFLAGS) $(Enclave_Compile_CXXFlags) -c $< -o $@ + @$(CXX) $(SGX_COMMON_CXXFLAGS) $(Enclave_Compile_CXXFlags) -c $< -o $@ @echo "CXX <= $<" $(Enclave_Name): $(Enclave_Objects) - @$(CXX) $(SGX_COMMON_CFLAGS) $(Enclave_Objects) -o $@ $(Enclave_Link_Flags) + @$(CXX) $^ -o $@ $(Enclave_Link_Flags) @echo "LINK => $@" $(Signed_Enclave_Name): $(Enclave_Name) diff --git a/SampleCode/RemoteAttestation/Makefile b/SampleCode/RemoteAttestation/Makefile index 89e6d187..46a12abd 100644 --- a/SampleCode/RemoteAttestation/Makefile +++ b/SampleCode/RemoteAttestation/Makefile @@ -43,12 +43,12 @@ else ifeq ($(findstring -m32, $(CXXFLAGS)), -m32) endif ifeq ($(SGX_ARCH), x86) - SGX_COMMON_CFLAGS := -m32 + SGX_COMMON_FLAGS := -m32 SGX_LIBRARY_PATH := $(SGX_SDK)/lib SGX_ENCLAVE_SIGNER := $(SGX_SDK)/bin/x86/sgx_sign SGX_EDGER8R := $(SGX_SDK)/bin/x86/sgx_edger8r else - SGX_COMMON_CFLAGS := -m64 + SGX_COMMON_FLAGS := -m64 SGX_LIBRARY_PATH := $(SGX_SDK)/lib64 SGX_ENCLAVE_SIGNER := $(SGX_SDK)/bin/x64/sgx_sign SGX_EDGER8R := $(SGX_SDK)/bin/x64/sgx_edger8r @@ -61,14 +61,22 @@ endif endif ifeq ($(SGX_DEBUG), 1) - SGX_COMMON_CFLAGS += -O0 -g + SGX_COMMON_FLAGS += -O0 -g else - SGX_COMMON_CFLAGS += -O2 + SGX_COMMON_FLAGS += -O2 endif ifeq ($(SUPPLIED_KEY_DERIVATION), 1) - SGX_COMMON_CFLAGS += -DSUPPLIED_KEY_DERIVATION + SGX_COMMON_FLAGS += -DSUPPLIED_KEY_DERIVATION endif + +SGX_COMMON_FLAGS += -Wall -Wextra -Winit-self -Wpointer-arith -Wreturn-type \ + -Waddress -Wsequence-point -Wformat-security \ + -Wmissing-include-dirs -Wfloat-equal -Wundef -Wshadow \ + -Wcast-align -Wconversion -Wredundant-decls +SGX_COMMON_CFLAGS := $(SGX_COMMON_FLAGS) -Wjump-misses-init -Wstrict-prototypes -Wunsuffixed-float-constants +SGX_COMMON_CXXFLAGS := $(SGX_COMMON_FLAGS) -Wnon-virtual-dtor -std=c++11 + ######## App Settings ######## ifneq ($(SGX_MODE), HW) @@ -80,7 +88,7 @@ endif App_Cpp_Files := isv_app/isv_app.cpp App_Include_Paths := -Iservice_provider -I$(SGX_SDK)/include -App_C_Flags := $(SGX_COMMON_CFLAGS) -fPIC -Wno-attributes $(App_Include_Paths) +App_C_Flags := -fPIC -Wno-attributes $(App_Include_Paths) # Three configuration modes - Debug, prerelease, release # Debug - Macro DEBUG enabled. @@ -94,8 +102,8 @@ else App_C_Flags += -DNDEBUG -UEDEBUG -UDEBUG endif -App_Cpp_Flags := $(App_C_Flags) -std=c++11 -App_Link_Flags := $(SGX_COMMON_CFLAGS) -L$(SGX_LIBRARY_PATH) -l$(Urts_Library_Name) -L. -lsgx_ukey_exchange -lpthread -lservice_provider -Wl,-rpath=$(CURDIR)/sample_libcrypto -Wl,-rpath=$(CURDIR) +App_Cpp_Flags := $(App_C_Flags) +App_Link_Flags := -L$(SGX_LIBRARY_PATH) -l$(Urts_Library_Name) -L. -lsgx_ukey_exchange -lpthread -lservice_provider -Wl,-rpath=$(CURDIR)/sample_libcrypto -Wl,-rpath=$(CURDIR) ifneq ($(SGX_MODE), HW) App_Link_Flags += -lsgx_uae_service_sim @@ -112,9 +120,9 @@ App_Name := app ServiceProvider_Cpp_Files := service_provider/ecp.cpp service_provider/network_ra.cpp service_provider/service_provider.cpp service_provider/ias_ra.cpp ServiceProvider_Include_Paths := -I$(SGX_SDK)/include -I$(SGX_SDK)/include/tlibc -I$(SGX_SDK)/include/libcxx -Isample_libcrypto -ServiceProvider_C_Flags := $(SGX_COMMON_CFLAGS) -fPIC -Wno-attributes -I$(SGX_SDK)/include -Isample_libcrypto -ServiceProvider_Cpp_Flags := $(ServiceProvider_C_Flags) -std=c++11 -ServiceProvider_Link_Flags := -shared $(SGX_COMMON_CFLAGS) -L$(SGX_LIBRARY_PATH) -lsample_libcrypto -Lsample_libcrypto +ServiceProvider_C_Flags := -fPIC -Wno-attributes -I$(SGX_SDK)/include -Isample_libcrypto +ServiceProvider_Cpp_Flags := $(ServiceProvider_C_Flags) +ServiceProvider_Link_Flags := -shared -L$(SGX_LIBRARY_PATH) -lsample_libcrypto -Lsample_libcrypto ServiceProvider_Cpp_Objects := $(ServiceProvider_Cpp_Files:.cpp=.o) @@ -132,14 +140,14 @@ Crypto_Library_Name := sgx_tcrypto Enclave_Cpp_Files := isv_enclave/isv_enclave.cpp Enclave_Include_Paths := -I$(SGX_SDK)/include -I$(SGX_SDK)/include/tlibc -I$(SGX_SDK)/include/libcxx +Enclave_C_Flags := $(Enclave_Include_Paths) -nostdinc -fvisibility=hidden -fpie -ffunction-sections -fdata-sections CC_BELOW_4_9 := $(shell expr "`$(CC) -dumpversion`" \< "4.9") ifeq ($(CC_BELOW_4_9), 1) - Enclave_C_Flags := $(SGX_COMMON_CFLAGS) -nostdinc -fvisibility=hidden -fpie -ffunction-sections -fdata-sections -fstack-protector + Enclave_C_Flags += -fstack-protector else - Enclave_C_Flags := $(SGX_COMMON_CFLAGS) -nostdinc -fvisibility=hidden -fpie -ffunction-sections -fdata-sections -fstack-protector-strong + Enclave_C_Flags += -fstack-protector-strong endif -Enclave_C_Flags += $(Enclave_Include_Paths) -Enclave_Cpp_Flags := $(Enclave_C_Flags) -std=c++11 -nostdinc++ +Enclave_Cpp_Flags := $(Enclave_C_Flags) -nostdinc++ # To generate a proper enclave, it is recommended to follow below guideline to link the trusted libraries: # 1. Link sgx_trts with the `--whole-archive' and `--no-whole-archive' options, @@ -148,7 +156,7 @@ Enclave_Cpp_Flags := $(Enclave_C_Flags) -std=c++11 -nostdinc++ # Use `--start-group' and `--end-group' to link these libraries. # Do NOT move the libraries linked with `--start-group' and `--end-group' within `--whole-archive' and `--no-whole-archive' options. # Otherwise, you may get some undesirable errors. -Enclave_Link_Flags := $(SGX_COMMON_CFLAGS) -Wl,--no-undefined -nostdlib -nodefaultlibs -nostartfiles -L$(SGX_LIBRARY_PATH) \ +Enclave_Link_Flags := -Wl,--no-undefined -nostdlib -nodefaultlibs -nostartfiles -L$(SGX_LIBRARY_PATH) \ -Wl,--whole-archive -l$(Trts_Library_Name) -Wl,--no-whole-archive \ -Wl,--start-group -lsgx_tstdc -lsgx_tcxx -lsgx_tkey_exchange -l$(Crypto_Library_Name) -l$(Service_Library_Name) -Wl,--end-group \ -Wl,-Bstatic -Wl,-Bsymbolic -Wl,--no-undefined \ @@ -224,11 +232,11 @@ isv_app/isv_enclave_u.c: $(SGX_EDGER8R) isv_enclave/isv_enclave.edl @echo "GEN => $@" isv_app/isv_enclave_u.o: isv_app/isv_enclave_u.c - @$(CC) $(App_C_Flags) -c $< -o $@ + @$(CC) $(SGX_COMMON_CFLAGS) $(App_C_Flags) -c $< -o $@ @echo "CC <= $<" isv_app/%.o: isv_app/%.cpp - @$(CXX) $(App_Cpp_Flags) -c $< -o $@ + @$(CXX) $(SGX_COMMON_CXXFLAGS) $(App_Cpp_Flags) -c $< -o $@ @echo "CXX <= $<" $(App_Name): isv_app/isv_enclave_u.o $(App_Cpp_Objects) @@ -239,7 +247,7 @@ $(App_Name): isv_app/isv_enclave_u.o $(App_Cpp_Objects) service_provider/%.o: service_provider/%.cpp - @$(CXX) $(ServiceProvider_Cpp_Flags) -c $< -o $@ + @$(CXX) $(SGX_COMMON_CXXFLAGS) $(ServiceProvider_Cpp_Flags) -c $< -o $@ @echo "CXX <= $<" libservice_provider.so: $(ServiceProvider_Cpp_Objects) @@ -253,11 +261,11 @@ isv_enclave/isv_enclave_t.c: $(SGX_EDGER8R) isv_enclave/isv_enclave.edl @echo "GEN => $@" isv_enclave/isv_enclave_t.o: isv_enclave/isv_enclave_t.c - @$(CC) $(Enclave_C_Flags) -c $< -o $@ + @$(CC) $(SGX_COMMON_CFLAGS) $(Enclave_C_Flags) -c $< -o $@ @echo "CC <= $<" isv_enclave/%.o: isv_enclave/%.cpp - @$(CXX) $(Enclave_Cpp_Flags) -c $< -o $@ + @$(CXX) $(SGX_COMMON_CXXFLAGS) $(Enclave_Cpp_Flags) -c $< -o $@ @echo "CXX <= $<" $(Enclave_Name): isv_enclave/isv_enclave_t.o $(Enclave_Cpp_Objects) diff --git a/SampleCode/RemoteAttestation/isv_app/isv_app.cpp b/SampleCode/RemoteAttestation/isv_app/isv_app.cpp index 74ec080d..6d29cfce 100644 --- a/SampleCode/RemoteAttestation/isv_app/isv_app.cpp +++ b/SampleCode/RemoteAttestation/isv_app/isv_app.cpp @@ -393,7 +393,7 @@ int main(int argc, char* argv[]) msg2_full_size); PRINT_BYTE_ARRAY(OUTPUT, p_msg2_full, - sizeof(ra_samp_response_header_t) + (uint32_t)sizeof(ra_samp_response_header_t) + p_msg2_full->size); } else @@ -425,7 +425,7 @@ int main(int argc, char* argv[]) fprintf(OUTPUT, "\nSent MSG1 to remote attestation service " "provider. Received the following MSG2:\n"); PRINT_BYTE_ARRAY(OUTPUT, p_msg2_full, - sizeof(ra_samp_response_header_t) + (uint32_t)sizeof(ra_samp_response_header_t) + p_msg2_full->size); fprintf(OUTPUT, "\nA more descriptive representation of MSG2:\n"); @@ -446,7 +446,7 @@ int main(int argc, char* argv[]) "value for MSG2 does NOT match.\n"); fprintf(OUTPUT, "\nPrecomputed value for MSG2:\n"); PRINT_BYTE_ARRAY(OUTPUT, precomputed_msg2, - sizeof(ra_samp_response_header_t) + (uint32_t)sizeof(ra_samp_response_header_t) + precomputed_msg2->size); fprintf(OUTPUT, "\nA more descriptive representation " "of precomputed value for MSG2:\n"); diff --git a/SampleCode/RemoteAttestation/service_provider/ecp.cpp b/SampleCode/RemoteAttestation/service_provider/ecp.cpp index 75c9d1ea..d074c487 100644 --- a/SampleCode/RemoteAttestation/service_provider/ecp.cpp +++ b/SampleCode/RemoteAttestation/service_provider/ecp.cpp @@ -179,8 +179,8 @@ bool derive_key( memset(&cmac_key, 0, MAC_KEY_SIZE); sample_ret = sample_rijndael128_cmac_msg( - (sample_cmac_128bit_key_t *)&cmac_key, - (uint8_t*)p_shared_key, + (const sample_cmac_128bit_key_t *)&cmac_key, + (const uint8_t*)p_shared_key, sizeof(sample_ec_dh_shared_t), (sample_cmac_128bit_tag_t *)&key_derive_key); if (sample_ret != SAMPLE_SUCCESS) diff --git a/SampleCode/RemoteAttestation/service_provider/ias_ra.cpp b/SampleCode/RemoteAttestation/service_provider/ias_ra.cpp index 1c9311a9..6867b4bc 100644 --- a/SampleCode/RemoteAttestation/service_provider/ias_ra.cpp +++ b/SampleCode/RemoteAttestation/service_provider/ias_ra.cpp @@ -104,7 +104,7 @@ static sample_spid_t g_sim_spid = {"Service X"}; // @return int int ias_verify_attestation_evidence( - sample_quote_t *p_isv_quote, + const sample_quote_t *p_isv_quote, uint8_t* pse_manifest, ias_att_report_t* p_attestation_verification_report) { diff --git a/SampleCode/RemoteAttestation/service_provider/ias_ra.h b/SampleCode/RemoteAttestation/service_provider/ias_ra.h index cd4e4ee1..fd228973 100644 --- a/SampleCode/RemoteAttestation/service_provider/ias_ra.h +++ b/SampleCode/RemoteAttestation/service_provider/ias_ra.h @@ -199,7 +199,7 @@ int ias_enroll(int sp_credentials, sample_spid_t* spid, int* authentication_token); int ias_get_sigrl(const sample_epid_group_id_t gid, uint32_t* p_sig_rl_size, uint8_t** p_sig_rl); -int ias_verify_attestation_evidence(sample_quote_t* p_isv_quote, +int ias_verify_attestation_evidence(const sample_quote_t* p_isv_quote, uint8_t* pse_manifest, ias_att_report_t* attestation_verification_report); #ifdef __cplusplus diff --git a/SampleCode/RemoteAttestation/service_provider/network_ra.cpp b/SampleCode/RemoteAttestation/service_provider/network_ra.cpp index 7c693440..75cbc802 100644 --- a/SampleCode/RemoteAttestation/service_provider/network_ra.cpp +++ b/SampleCode/RemoteAttestation/service_provider/network_ra.cpp @@ -67,7 +67,7 @@ int ra_network_send_receive(const char *server_url, { case TYPE_RA_MSG0: - ret = sp_ra_proc_msg0_req((const sample_ra_msg0_t*)((uint8_t*)p_req + ret = sp_ra_proc_msg0_req((const sample_ra_msg0_t*)((size_t)p_req + sizeof(ra_samp_request_header_t)), p_req->size); if (0 != ret) @@ -78,7 +78,7 @@ int ra_network_send_receive(const char *server_url, break; case TYPE_RA_MSG1: - ret = sp_ra_proc_msg1_req((const sample_ra_msg1_t*)((uint8_t*)p_req + ret = sp_ra_proc_msg1_req((const sample_ra_msg1_t*)((size_t)p_req + sizeof(ra_samp_request_header_t)), p_req->size, &p_resp_msg); @@ -94,7 +94,7 @@ int ra_network_send_receive(const char *server_url, break; case TYPE_RA_MSG3: - ret =sp_ra_proc_msg3_req((const sample_ra_msg3_t*)((uint8_t*)p_req + + ret =sp_ra_proc_msg3_req((const sample_ra_msg3_t*)((size_t)p_req + sizeof(ra_samp_request_header_t)), p_req->size, &p_resp_msg); diff --git a/SampleCode/RemoteAttestation/service_provider/service_provider.cpp b/SampleCode/RemoteAttestation/service_provider/service_provider.cpp index 3e388808..30241edf 100644 --- a/SampleCode/RemoteAttestation/service_provider/service_provider.cpp +++ b/SampleCode/RemoteAttestation/service_provider/service_provider.cpp @@ -323,7 +323,7 @@ int sp_ra_proc_msg1_req(const sample_ra_msg1_t *p_msg1, } #endif - uint32_t msg2_size = sizeof(sample_ra_msg2_t) + sig_rl_size; + uint32_t msg2_size = (uint32_t)sizeof(sample_ra_msg2_t) + sig_rl_size; p_msg2_full = (ra_samp_response_header_t*)malloc(msg2_size + sizeof(ra_samp_response_header_t)); if(!p_msg2_full) @@ -442,7 +442,7 @@ int sp_ra_proc_msg3_req(const sample_ra_msg3_t *p_msg3, int ret = 0; sample_status_t sample_ret = SAMPLE_SUCCESS; const uint8_t *p_msg3_cmaced = NULL; - sample_quote_t *p_quote = NULL; + const sample_quote_t *p_quote = NULL; sample_sha_state_handle_t sha_handle = NULL; sample_report_data_t report_data = {0}; sample_ra_att_result_msg_t *p_att_result_msg = NULL; @@ -472,7 +472,7 @@ int sp_ra_proc_msg3_req(const sample_ra_msg3_t *p_msg3, break; } //Make sure that msg3_size is bigger than sample_mac_t. - uint32_t mac_size = msg3_size - sizeof(sample_mac_t); + uint32_t mac_size = msg3_size - (uint32_t)sizeof(sample_mac_t); p_msg3_cmaced = reinterpret_cast(p_msg3); p_msg3_cmaced += sizeof(sample_mac_t); @@ -506,7 +506,7 @@ int sp_ra_proc_msg3_req(const sample_ra_msg3_t *p_msg3, break; } - p_quote = (sample_quote_t *)p_msg3->quote; + p_quote = (const sample_quote_t*)p_msg3->quote; // Check the quote version if needed. Only check the Quote.version field if the enclave // identity fields have changed or the size of the quote has changed. The version may @@ -564,7 +564,7 @@ int sp_ra_proc_msg3_req(const sample_ra_msg3_t *p_msg3, break; } ret = memcmp((uint8_t *)&report_data, - (uint8_t *)&(p_quote->report_body.report_data), + &(p_quote->report_body.report_data), sizeof(report_data)); if(ret) { @@ -579,7 +579,8 @@ int sp_ra_proc_msg3_req(const sample_ra_msg3_t *p_msg3, // Verify quote with attestation server. // In the product, an attestation server could use a REST message and JSON formatting to request // attestation Quote verification. The sample only simulates this interface. - ias_att_report_t attestation_report = {0}; + ias_att_report_t attestation_report; + memset(&attestation_report, 0, sizeof(attestation_report)); ret = g_sp_extended_epid_group_id->verify_attestation_evidence(p_quote, NULL, &attestation_report); if(0 != ret) diff --git a/SampleCode/RemoteAttestation/service_provider/service_provider.h b/SampleCode/RemoteAttestation/service_provider/service_provider.h index e6847d5c..b34fded1 100644 --- a/SampleCode/RemoteAttestation/service_provider/service_provider.h +++ b/SampleCode/RemoteAttestation/service_provider/service_provider.h @@ -141,7 +141,7 @@ typedef int (*sample_enroll)(int sp_credentials, sample_spid_t* spid, typedef int(*sample_get_sigrl)(const sample_epid_group_id_t gid, uint32_t* p_sig_rl_size, uint8_t** p_sig_rl); -typedef int(*sample_verify_attestation_evidence)(sample_quote_t* p_isv_quote, +typedef int(*sample_verify_attestation_evidence)(const sample_quote_t* p_isv_quote, uint8_t* pse_manifest, ias_att_report_t* attestation_verification_report); diff --git a/sdk/tsetjmp/tlongjmp_version.cpp b/SampleCode/SampleCommonLoader/App/enclave_entry.S similarity index 84% rename from sdk/tsetjmp/tlongjmp_version.cpp rename to SampleCode/SampleCommonLoader/App/enclave_entry.S index c0afd42f..26e53d4f 100644 --- a/sdk/tsetjmp/tlongjmp_version.cpp +++ b/SampleCode/SampleCommonLoader/App/enclave_entry.S @@ -29,17 +29,20 @@ * */ -#include "se_version.h" -#define __CONCAT(x, y) x/**/y +#include "enclave_entry.h" -#define SGX_TSETJMP_VERSION_STR __CONCAT("SGX_TSETJMP_VERSION_", STRFILEVER) +.text + .global sgx_get_token +sgx_get_token: + EENTER_PROLOG -#ifdef __cplusplus -extern "C" { -#endif -__attribute__((visibility("default"))) -const char * sgx_tsetjmp_version = SGX_TSETJMP_VERSION_STR; -#ifdef __cplusplus -} -#endif + mov $0x2, %rax + mov %rsi, %rbx + mov frame_arg0, %rdi + lea_pic sgx_async_exit, %rcx +sgx_async_exit: + enclu + + EENTER_EPILOG + ret diff --git a/SampleCode/SampleCommonLoader/App/sample.cpp b/SampleCode/SampleCommonLoader/App/sample.cpp new file mode 100644 index 00000000..ed53d8cd --- /dev/null +++ b/SampleCode/SampleCommonLoader/App/sample.cpp @@ -0,0 +1,187 @@ +/* + * Copyright (C) 2011-2018 Intel Corporation. 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 name of Intel 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 + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + + +#include +#include +#include +#include "sgx_enclave_common.h" +#include "sgx_enclave_ss.h" +#include "sgx_enclave_blob.h" + +#define SGX_PAGE_SIZE 0x1000 + +#define SGX_FLAGS_INITTED 0x0000000000000001ULL +#define SGX_FLAGS_DEBUG 0x0000000000000002ULL +#define SGX_FLAGS_MODE64BIT 0x0000000000000004ULL +#define SGX_FLAGS_PROVISION_KEY 0x0000000000000010ULL +#define SGX_FLAGS_EINITTOKEN_KEY 0x0000000000000020ULL + +#define SGX_SECS_RESERVED1_SIZE 24 +#define SGX_SECS_RESERVED2_SIZE 32 +#define SGX_SECS_RESERVED3_SIZE 96 +#define SGX_SECS_RESERVED4_SIZE 3836 + +/*SECS data structure*/ +typedef struct _secs_t +{ + uint64_t size; + uint64_t base; + uint32_t ssaframesize; + uint32_t miscselect; + uint8_t reserved1[SGX_SECS_RESERVED1_SIZE]; + uint64_t attributes; + uint64_t xfrm; + uint32_t mrenclave[8]; + uint8_t reserved2[SGX_SECS_RESERVED2_SIZE]; + uint32_t mrsigner[8]; + uint8_t reserved3[SGX_SECS_RESERVED3_SIZE]; + uint16_t isvprodid; + uint16_t isvsvn; + uint8_t reserved4[SGX_SECS_RESERVED4_SIZE]; +} secs_t; + +extern "C" void sgx_get_token(void *req, void *entry); + +static bool create_enclave(secs_t *secs) +{ + assert(secs != NULL); + + for (secs->size = SGX_PAGE_SIZE; secs->size < sgx_enclave_blob_length; ) + secs->size <<= 1; + + enclave_create_sgx_t create_ioc = {0}; + memcpy(create_ioc.secs, secs, SECS_SIZE); + + uint32_t enclave_error = ENCLAVE_ERROR_SUCCESS; + void *enclave_base = enclave_create(NULL, (size_t)secs->size, sgx_enclave_blob_length, ENCLAVE_TYPE_SGX1, &create_ioc, sizeof(create_ioc), &enclave_error); + + if (enclave_error) + { + printf("create enclave error! error code - %#x\n", enclave_error); + return false; + } + + secs->base = (uint64_t)enclave_base; + + return true; +} + +static bool add_enclave_page(secs_t *secs) +{ + assert(secs != NULL); + + uint32_t enclave_error = ENCLAVE_ERROR_SUCCESS; + + // load the TCS page + enclave_load_data((void *)(secs->base), SGX_PAGE_SIZE, (void *)((uint64_t)sgx_enclave_blob), ENCLAVE_PAGE_THREAD_CONTROL | ENCLAVE_PAGE_READ | ENCLAVE_PAGE_WRITE, &enclave_error); + + if (enclave_error) + { + printf("add TCS page error! error code - %#x\n", enclave_error); + return false; + } + + // load the regular pages + enclave_load_data((void *)(secs->base + SGX_PAGE_SIZE), sgx_enclave_blob_length - SGX_PAGE_SIZE, (void *)((uint64_t)sgx_enclave_blob + SGX_PAGE_SIZE), ENCLAVE_PAGE_READ | ENCLAVE_PAGE_WRITE | ENCLAVE_PAGE_EXECUTE, &enclave_error); + + if (enclave_error) + { + printf("add regular page error! error code - %#x\n", enclave_error); + return false; + } + + return true; +} + +static bool init_enclave(secs_t *secs) +{ + assert(secs != NULL); + + enclave_init_sgx_t init_ioc = {0}; + memcpy(init_ioc.sigstruct, sgx_enclave_ss, SIGSTRUCT_SIZE); + + uint32_t enclave_error = ENCLAVE_ERROR_SUCCESS; + enclave_initialize((void *)secs->base, &init_ioc, sizeof(init_ioc), &enclave_error); + + if (enclave_error) + { + printf("init enclave error! error code - %#x\n", enclave_error); + return false; + } + + return true; +} + +static bool destroy_enclave(secs_t *secs) +{ + assert(secs != NULL); + + uint32_t enclave_error = ENCLAVE_ERROR_SUCCESS; + enclave_delete((void*)secs->base, &enclave_error); + + if (enclave_error) + { + printf("destroy enclave error! error code - %#x\n", enclave_error); + return false; + } + + return true; +} + +int main(void) +{ + secs_t secs; + memset(&secs, 0, sizeof(secs)); + + secs.ssaframesize = 1; + secs.attributes = SGX_FLAGS_MODE64BIT; + secs.xfrm = 3; + + if (false == create_enclave(&secs)) + return 1; + + if (false == add_enclave_page(&secs)) + return 1; + + if (false == init_enclave(&secs)) + return 1; + + // enclave is ready to use. + sgx_get_token(NULL, (void *)secs.base); + + if (false == destroy_enclave(&secs)) + return 1; + + printf("Success!\n"); + + return 0; +} diff --git a/SampleCode/SampleCommonLoader/Include/enclave_entry.h b/SampleCode/SampleCommonLoader/Include/enclave_entry.h new file mode 100644 index 00000000..d9d0df97 --- /dev/null +++ b/SampleCode/SampleCommonLoader/Include/enclave_entry.h @@ -0,0 +1,136 @@ +/* + * Copyright (C) 2011-2018 Intel Corporation. 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 name of Intel 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 + * OWNER 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. + * + */ + + +/* ------------------------------------------------------------ + * Normal function enter/leave wrappers. + * ------------------------------------------------------------ + */ + +#ifndef _ENCLAVE_ENTRY_H_ +#define _ENCLAVE_ENTRY_H_ + +#include "linux-regs.h" + +/* macro for enter_enclave + * There is no .cfi_xxx to describe unwind information, because we want c++ exception can't across enclave boundary +*/ +.macro EENTER_PROLOG +push %xbp +mov %xsp, %xbp + +#if defined(__i386__) +push %ebx +push %esi +push %edi + +/* These 3 wordsize buffer are used for paddings, so that the + * stack-boundary can be kept 16-byte aligned. + * + * Note that, by default GCC assumes + * -mpreferred-stack-boundary=4 + * which results to 16 (2^4) byte alignment of stack boundary. + * + * | parameters | <- previous frame + * ==+================+====== + * | return address | ^ + * +----------------+ | + * | ebp | | + * +----------------+ 16 bytes <- current frame + * | ebx | | + * +----------------+ | + * | esi | v + * +----------------+ ---- + * | edi | 4 bytes + * +----------------+ + * | paddings | 3*4 bytes + * ==+================+====== + * | ENCLU | + */ +sub $(3 * SE_WORDSIZE), %esp + +#elif defined(__x86_64__) +push %rbx +push %r12 +push %r13 +push %r14 +push %r15 +/*save 5 parameter*/ +push %r8 +push %rcx +push %rdx +push %rsi +push %rdi +#else +# error unknown platform +#endif +.endm + +.macro EENTER_EPILOG +#if defined(__i386__) +mov -SE_WORDSIZE*1(%ebp), %ebx +mov -SE_WORDSIZE*2(%ebp), %esi +mov -SE_WORDSIZE*3(%ebp), %edi +#elif defined(__x86_64__) +mov -SE_WORDSIZE*1(%rbp), %rbx +mov -SE_WORDSIZE*2(%rbp), %r12 +mov -SE_WORDSIZE*3(%rbp), %r13 +mov -SE_WORDSIZE*4(%rbp), %r14 +mov -SE_WORDSIZE*5(%rbp), %r15 +#else +# error unknown platform +#endif +/* don't need recover rdi, rsi, rdx, rcx */ +mov %xbp, %xsp +pop %xbp +ret +.endm + +#if defined(__i386__) +#define frame_arg0 2*SE_WORDSIZE(%ebp) +#define frame_arg1 3*SE_WORDSIZE(%ebp) +#define frame_arg2 4*SE_WORDSIZE(%ebp) +#define frame_arg3 5*SE_WORDSIZE(%ebp) +#define frame_arg4 6*SE_WORDSIZE(%ebp) +#elif defined(__x86_64__) +#define frame_arg0 -10*SE_WORDSIZE(%rbp) +#define frame_arg1 -9*SE_WORDSIZE(%rbp) +#define frame_arg2 -8*SE_WORDSIZE(%rbp) +#define frame_arg3 -7*SE_WORDSIZE(%rbp) +#define frame_arg4 -6*SE_WORDSIZE(%rbp) +#else +# error unknown platform +#endif + +//refer sgx_error.h +#define SE_ERROR_READ_LOCK_FAIL 0xc0002202 + +#endif diff --git a/SampleCode/SampleCommonLoader/Include/linux-regs.h b/SampleCode/SampleCommonLoader/Include/linux-regs.h new file mode 100644 index 00000000..df066d8c --- /dev/null +++ b/SampleCode/SampleCommonLoader/Include/linux-regs.h @@ -0,0 +1,273 @@ +/* + * Copyright (C) 2011-2018 Intel Corporation. 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 name of Intel 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 + * OWNER 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. + * + */ + + +/* + * This header wraps the register names for x86/x64. + */ + +#ifndef LINUX_REGS_H__ +#define LINUX_REGS_H__ + +#if defined(__i386) || defined(__i386__) +# define LINUX32 1 +# define SE_WORDSIZE 4 + +/* Generic argument picker for `naked' functions */ +# define naked_arg0 4(%esp) +# define naked_arg1 8(%esp) +# define naked_arg2 12(%esp) +# define naked_arg3 16(%esp) + +# define xax eax +# define xbx ebx +# define xcx ecx +# define xdx edx + +# define xsi esi +# define xdi edi +# define xbp ebp +# define xsp esp +#elif defined(__x86_64) || defined(__x86_64__) +# define LINUX64 1 +# define SE_WORDSIZE 8 + +/* For x86_64, the first six parameters are passed by + * rdi, rsi, rdx, rcx, r8, r9. + */ +# define naked_arg0 %rdi +# define naked_arg1 %rsi +# define naked_arg2 %rdx +# define naked_arg3 %rcx + +# define xax rax +# define xbx rbx +# define xcx rcx +# define xdx rdx + +# define xsi rsi +# define xdi rdi +# define xbp rbp +# define xsp rsp +#else +# error unknown platform! +#endif + +/* SE instructions - needs to be sync-up with inst70.h */ +#define SE_EREPORT 0 +#define SE_EGETKEY 1 +#define SE_EENTER 2 +#define SE_EEXIT 4 + +#define SE_ECREATE 0 +#define SE_EADD 1 +#define SE_EINIT 2 +#define SE_EREMOVE 3 + +/* + * Macros for GNU assembly + */ +.macro ENCLU +#ifdef SE_SIM + cmp $SE_EEXIT, %xax + jne 1f + + /* if leaf is EEXIT, xbp and xsp need to be passed by xdx and xcx */ + mov %xbp, %xdx + mov %xsp, %xcx +1: + push %xdi + push %xsi + push %xdx + push %xcx + push %xbx + push %xax + +# ifdef LINUX64 + pop %rdi + pop %rsi + pop %rdx + pop %rcx + pop %r8 + pop %r9 +# endif + +.type _SE3,@function +.protected _SE3 + call _SE3 + +# ifdef LINUX32 + add $(SE_WORDSIZE * 6), %esp +# endif + +#else /* SE_SIM */ +.byte 0x0f, 0x01, 0xd7 /* 0xf3 */ +#endif /* !SE_SIM */ +.endm + +/* declare a function with default visibility */ +.macro DECLARE_GLOBAL_FUNC name + .globl \name + .type \name, @function +\name: +.endm + +/* declare a function with visibility='hidden' */ +.macro DECLARE_LOCAL_FUNC name + .globl \name + .hidden \name + .type \name, @function +\name: +.endm + +.macro NAKED_PROLOG + push %xbp + mov %xsp, %xbp + sub $(7 * SE_WORDSIZE), %xsp +.endm + +.macro NAKED_EPILOG + mov %xbp, %xsp + pop %xbp +.endm + +/* `paramN' (N = 1,2,3,4) should be registers. */ +.macro SET_PARAMS param1:req, param2, param3, param4 +#if defined(LINUX32) + +.ifnb \param4 + mov \param4, 3*SE_WORDSIZE(%esp) +.endif + +.ifnb \param3 + mov \param3, 2*SE_WORDSIZE(%esp) +.endif + +.ifnb \param2 + mov \param2, 1*SE_WORDSIZE(%esp) +.endif + + mov \param1, 0*SE_WORDSIZE(%esp) + +#else /* LINUX32 */ + +.ifnb \param4 +.ifnc \param4, %rcx + mov \param4, %rcx +.endif +.endif + +.ifnb \param3 +.ifnc \param3, %rdx + mov \param3, %rdx +.endif +.endif + +.ifnb \param2 +.ifnc \param2, %rsi + mov \param2, %rsi +.endif +.endif + +.ifnc \param1, %rdi + mov \param1, %rdi +.endif + +#endif /* LINUX64 */ +.endm + +/*******************************************************************/ + +.macro SE_PROLOG + .cfi_startproc + +#ifdef LINUX32 + pushl %ebp + movl %esp, %ebp +#endif + + push %xbx + push %xcx + push %xdx + +#if defined LINUX64 + movq %rdi, %rbx + movq %rsi, %rcx + /* rdx remains the same, rdi/rsi is not used by _SE0 + */ +#elif defined LINUX32 + movl 2*SE_WORDSIZE(%ebp), %ebx + movl 3*SE_WORDSIZE(%ebp), %ecx + movl 4*SE_WORDSIZE(%ebp), %edx +#endif + +.endm + +/*******************************************************************/ + +.macro SE_EPILOG + pop %xdx + pop %xcx + pop %xbx + +#ifdef LINUX32 + movl %ebp, %esp + popl %ebp +#endif + + ret + .cfi_endproc +.endm + +/*******************************************************************/ + +/* load the address of `symbol' to the register `reg' in PIC way. */ +.macro lea_pic symbol, reg +#ifdef LINUX64 + lea \symbol(%rip), \reg +#else +/* The real code on x86 would look like this (get `bar' from `foo'): + * + * 00000198 : + * 198: c3 ret + * + * 00000199 : + * 199: e8 00 00 00 00 call 19e + * 19e: 58 pop %eax + * 19f: 8d 40 fa lea -0x6(%eax),%eax + */ + call . + 0x5 /* No label here to avoid interfering w/ calling code */ + pop \reg + lea (\symbol - . + 1)(\reg), \reg +#endif +.endm + +#endif /* LINUX_REGS_H__ */ diff --git a/SampleCode/SampleCommonLoader/Include/sgx_enclave_blob.h b/SampleCode/SampleCommonLoader/Include/sgx_enclave_blob.h new file mode 100644 index 00000000..f910fe11 --- /dev/null +++ b/SampleCode/SampleCommonLoader/Include/sgx_enclave_blob.h @@ -0,0 +1,2340 @@ +/* + * Copyright (C) 2011-2018 Intel Corporation. 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 name of Intel 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 + * OWNER 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. + * + */ + + +const int sgx_enclave_blob_length = 36864; + +const unsigned char sgx_enclave_blob[36864] = { + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00, + 0x1d,0x16,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x55,0x48,0x89,0xe5,0x48,0x89,0x7d,0xe8,0xc7,0x45,0xfc,0x00,0x00,0x00,0x00,0xeb, + 0x20,0x0f,0xc7,0xf0,0x48,0x8b,0x55,0xe8,0x89,0x02,0xba,0x01,0x00,0x00,0x00,0x0f, + 0x42,0xc2,0x85,0xc0,0x74,0x07,0xb8,0x01,0x00,0x00,0x00,0xeb,0x0f,0x83,0x45,0xfc, + 0x01,0x83,0x7d,0xfc,0x09,0x7e,0xda,0xb8,0x00,0x00,0x00,0x00,0x5d,0xc3,0x4c,0x8d, + 0x54,0x24,0x08,0x48,0x81,0xe4,0x00,0xfe,0xff,0xff,0x41,0xff,0x72,0xf8,0x55,0x48, + 0x89,0xe5,0x41,0x52,0x48,0x81,0xec,0xe8,0x07,0x00,0x00,0x48,0x89,0xbd,0xf8,0xf9, + 0xff,0xff,0x48,0x8b,0x85,0xf8,0xf9,0xff,0xff,0x48,0x05,0x00,0x01,0x00,0x00,0x48, + 0x89,0x85,0x00,0xfe,0xff,0xff,0xc7,0x85,0x0c,0xfe,0xff,0xff,0x00,0x00,0x00,0x00, + 0xeb,0x3a,0x8b,0x85,0x0c,0xfe,0xff,0xff,0x48,0x98,0x48,0x8d,0x14,0x85,0x00,0x00, + 0x00,0x00,0x48,0x8b,0x85,0x00,0xfe,0xff,0xff,0x48,0x01,0xd0,0x48,0x89,0xc7,0xe8, + 0x5c,0xff,0xff,0xff,0x83,0xf0,0x01,0x84,0xc0,0x74,0x0a,0xb8,0x00,0x00,0x00,0x00, + 0xe9,0xa1,0x01,0x00,0x00,0x83,0x85,0x0c,0xfe,0xff,0xff,0x01,0x8b,0x85,0x0c,0xfe, + 0xff,0xff,0x83,0xf8,0x07,0x76,0xbb,0x48,0x8d,0x85,0x10,0xfa,0xff,0xff,0xba,0x00, + 0x02,0x00,0x00,0xbe,0x00,0x00,0x00,0x00,0x48,0x89,0xc7,0xe8,0xc5,0x05,0x00,0x00, + 0x66,0xc7,0x85,0x10,0xfa,0xff,0xff,0x00,0x00,0x48,0x8b,0x85,0xf8,0xf9,0xff,0xff, + 0x48,0x05,0x00,0x01,0x00,0x00,0x48,0x8b,0x10,0x48,0x89,0x95,0x38,0xfa,0xff,0xff, + 0x48,0x8b,0x50,0x08,0x48,0x89,0x95,0x40,0xfa,0xff,0xff,0x48,0x8b,0x50,0x10,0x48, + 0x89,0x95,0x48,0xfa,0xff,0xff,0x48,0x8b,0x40,0x18,0x48,0x89,0x85,0x50,0xfa,0xff, + 0xff,0x48,0x8b,0x85,0xf8,0xf9,0xff,0xff,0x48,0x05,0xc0,0x00,0x00,0x00,0x48,0x8b, + 0x50,0x08,0x48,0x8b,0x00,0x48,0x89,0x85,0x18,0xfa,0xff,0xff,0x48,0x89,0x95,0x20, + 0xfa,0xff,0xff,0x48,0x8b,0x85,0xf8,0xf9,0xff,0xff,0x48,0x05,0xd2,0x00,0x00,0x00, + 0x0f,0xb7,0x00,0x66,0x89,0x85,0x14,0xfa,0xff,0xff,0x48,0xc7,0x85,0x28,0xfa,0xff, + 0xff,0xfb,0xff,0xff,0xff,0x48,0xc7,0x85,0x30,0xfa,0xff,0xff,0x00,0x00,0x00,0x00, + 0xc7,0x85,0x58,0xfa,0xff,0xff,0xff,0xff,0xff,0xff,0x48,0x8b,0x85,0xf8,0xf9,0xff, + 0xff,0x8b,0x90,0xec,0x00,0x00,0x00,0x8b,0x85,0x58,0xfa,0xff,0xff,0x21,0xc2,0x48, + 0x8b,0x85,0xf8,0xf9,0xff,0xff,0x89,0x90,0xec,0x00,0x00,0x00,0x48,0x8b,0x85,0xf8, + 0xf9,0xff,0xff,0x48,0x8b,0x90,0xf0,0x00,0x00,0x00,0x48,0x8b,0x85,0x28,0xfa,0xff, + 0xff,0x48,0x21,0xc2,0x48,0x8b,0x85,0xf8,0xf9,0xff,0xff,0x48,0x89,0x90,0xf0,0x00, + 0x00,0x00,0x48,0x8b,0x85,0xf8,0xf9,0xff,0xff,0x48,0x8b,0x90,0xf8,0x00,0x00,0x00, + 0x48,0x8b,0x85,0x30,0xfa,0xff,0xff,0x48,0x21,0xc2,0x48,0x8b,0x85,0xf8,0xf9,0xff, + 0xff,0x48,0x89,0x90,0xf8,0x00,0x00,0x00,0x48,0x8d,0x95,0x00,0xfa,0xff,0xff,0x48, + 0x8d,0x85,0x10,0xfa,0xff,0xff,0x48,0x89,0xd6,0x48,0x89,0xc7,0xe8,0x91,0x04,0x00, + 0x00,0x85,0xc0,0x74,0x07,0xb8,0x00,0x00,0x00,0x00,0xeb,0x4a,0x48,0x8b,0x85,0xf8, + 0xf9,0xff,0xff,0x48,0x8d,0x90,0x20,0x01,0x00,0x00,0x48,0x8b,0xb5,0xf8,0xf9,0xff, + 0xff,0x48,0x8d,0x85,0x00,0xfa,0xff,0xff,0x48,0x89,0xd1,0xba,0xc0,0x00,0x00,0x00, + 0x48,0x89,0xc7,0xe8,0x54,0x0d,0x00,0x00,0x48,0x8d,0x85,0x00,0xfa,0xff,0xff,0xba, + 0x10,0x00,0x00,0x00,0xbe,0x00,0x00,0x00,0x00,0x48,0x89,0xc7,0xe8,0x54,0x04,0x00, + 0x00,0xb8,0x01,0x00,0x00,0x00,0x48,0x81,0xc4,0xe8,0x07,0x00,0x00,0x41,0x5a,0x5d, + 0x49,0x8d,0x62,0xf8,0xc3,0x4c,0x8d,0x54,0x24,0x08,0x48,0x81,0xe4,0x00,0xfe,0xff, + 0xff,0x41,0xff,0x72,0xf8,0x55,0x48,0x89,0xe5,0x41,0x52,0x48,0x81,0xec,0xe8,0x07, + 0x00,0x00,0x48,0x89,0xbd,0x88,0xf9,0xff,0xff,0x48,0x89,0xb5,0x80,0xf9,0xff,0xff, + 0x48,0x89,0x95,0x78,0xf9,0xff,0xff,0x48,0x89,0x8d,0x70,0xf9,0xff,0xff,0x4c,0x89, + 0x85,0x68,0xf9,0xff,0xff,0x48,0x8b,0x85,0x78,0xf9,0xff,0xff,0x48,0x83,0xe0,0xc9, + 0x48,0x85,0xc0,0x74,0x0a,0xb8,0x00,0x00,0x00,0x00,0xe9,0xb6,0x01,0x00,0x00,0x48, + 0x8d,0x85,0x10,0xfc,0xff,0xff,0xba,0x00,0x02,0x00,0x00,0xbe,0x00,0x00,0x00,0x00, + 0x48,0x89,0xc7,0xe8,0xcd,0x03,0x00,0x00,0x48,0x8d,0x85,0x90,0xf9,0xff,0xff,0xba, + 0x40,0x00,0x00,0x00,0xbe,0x00,0x00,0x00,0x00,0x48,0x89,0xc7,0xe8,0xb4,0x03,0x00, + 0x00,0x48,0x8d,0x85,0x10,0xfa,0xff,0xff,0xba,0xb0,0x01,0x00,0x00,0xbe,0x00,0x00, + 0x00,0x00,0x48,0x89,0xc7,0xe8,0x9b,0x03,0x00,0x00,0x48,0x8d,0x95,0x10,0xfa,0xff, + 0xff,0x48,0x8d,0x8d,0x90,0xf9,0xff,0xff,0x48,0x8d,0x85,0x10,0xfc,0xff,0xff,0x48, + 0x89,0xce,0x48,0x89,0xc7,0xe8,0x59,0x03,0x00,0x00,0x85,0xc0,0x74,0x0a,0xb8,0x00, + 0x00,0x00,0x00,0xe9,0x3d,0x01,0x00,0x00,0x48,0x8b,0x85,0x68,0xf9,0xff,0xff,0xba, + 0x30,0x01,0x00,0x00,0xbe,0x00,0x00,0x00,0x00,0x48,0x89,0xc7,0xe8,0x54,0x03,0x00, + 0x00,0x48,0x8b,0x85,0x68,0xf9,0xff,0xff,0xc7,0x00,0x01,0x00,0x00,0x00,0x48,0x8b, + 0x85,0x68,0xf9,0xff,0xff,0x48,0x8d,0x48,0x40,0x48,0x8b,0x85,0x88,0xf9,0xff,0xff, + 0xba,0x20,0x00,0x00,0x00,0x48,0x89,0xc6,0x48,0x89,0xcf,0xe8,0x63,0x03,0x00,0x00, + 0x48,0x8b,0x85,0x68,0xf9,0xff,0xff,0x48,0x8d,0x88,0x80,0x00,0x00,0x00,0x48,0x8b, + 0x85,0x80,0xf9,0xff,0xff,0xba,0x20,0x00,0x00,0x00,0x48,0x89,0xc6,0x48,0x89,0xcf, + 0xe8,0x3e,0x03,0x00,0x00,0x48,0x8b,0x85,0x68,0xf9,0xff,0xff,0x48,0x8b,0x95,0x78, + 0xf9,0xff,0xff,0x48,0x89,0x50,0x30,0x48,0x8b,0x85,0x68,0xf9,0xff,0xff,0x48,0x8b, + 0x95,0x70,0xf9,0xff,0xff,0x48,0x89,0x50,0x38,0x48,0x8b,0x85,0x68,0xf9,0xff,0xff, + 0x48,0x8d,0x88,0xc0,0x00,0x00,0x00,0x48,0x8b,0x85,0x10,0xfa,0xff,0xff,0x48,0x8b, + 0x95,0x18,0xfa,0xff,0xff,0x48,0x89,0x01,0x48,0x89,0x51,0x08,0x0f,0xb7,0x95,0x12, + 0xfb,0xff,0xff,0x48,0x8b,0x85,0x68,0xf9,0xff,0xff,0x66,0x89,0x90,0xd2,0x00,0x00, + 0x00,0x0f,0xb7,0x95,0x10,0xfb,0xff,0xff,0x48,0x8b,0x85,0x68,0xf9,0xff,0xff,0x66, + 0x89,0x90,0xd0,0x00,0x00,0x00,0x48,0x8b,0x95,0x40,0xfa,0xff,0xff,0x48,0x8b,0x85, + 0x68,0xf9,0xff,0xff,0x48,0x89,0x90,0xf0,0x00,0x00,0x00,0x48,0x8b,0x95,0x48,0xfa, + 0xff,0xff,0x48,0x8b,0x85,0x68,0xf9,0xff,0xff,0x48,0x89,0x90,0xf8,0x00,0x00,0x00, + 0x8b,0x95,0x20,0xfa,0xff,0xff,0x48,0x8b,0x85,0x68,0xf9,0xff,0xff,0x89,0x90,0xec, + 0x00,0x00,0x00,0x48,0x8b,0x85,0x68,0xf9,0xff,0xff,0x48,0x89,0xc7,0xe8,0xdc,0xfb, + 0xff,0xff,0x83,0xf0,0x01,0x84,0xc0,0x74,0x07,0xb8,0x00,0x00,0x00,0x00,0xeb,0x05, + 0xb8,0x01,0x00,0x00,0x00,0x48,0x81,0xc4,0xe8,0x07,0x00,0x00,0x41,0x5a,0x5d,0x49, + 0x8d,0x62,0xf8,0xc3,0x55,0x48,0x89,0xe5,0x48,0x81,0xec,0xa0,0x01,0x00,0x00,0x48, + 0x89,0xbd,0x68,0xfe,0xff,0xff,0x48,0x83,0xbd,0x68,0xfe,0xff,0xff,0x00,0x0f,0x84, + 0x73,0x01,0x00,0x00,0x48,0x8b,0x85,0x68,0xfe,0xff,0xff,0x48,0x8b,0x10,0x48,0x89, + 0x95,0xa0,0xfe,0xff,0xff,0x48,0x8b,0x50,0x08,0x48,0x89,0x95,0xa8,0xfe,0xff,0xff, + 0x48,0x8b,0x50,0x10,0x48,0x89,0x95,0xb0,0xfe,0xff,0xff,0x48,0x8b,0x40,0x18,0x48, + 0x89,0x85,0xb8,0xfe,0xff,0xff,0x48,0x8b,0x85,0x68,0xfe,0xff,0xff,0x48,0x83,0xc0, + 0x20,0x48,0x8b,0x10,0x48,0x89,0x95,0x80,0xfe,0xff,0xff,0x48,0x8b,0x50,0x08,0x48, + 0x89,0x95,0x88,0xfe,0xff,0xff,0x48,0x8b,0x50,0x10,0x48,0x89,0x95,0x90,0xfe,0xff, + 0xff,0x48,0x8b,0x40,0x18,0x48,0x89,0x85,0x98,0xfe,0xff,0xff,0x48,0x8b,0x85,0x68, + 0xfe,0xff,0xff,0x48,0x83,0xc0,0x40,0x48,0x8b,0x00,0x48,0x89,0x85,0x78,0xfe,0xff, + 0xff,0x48,0x8b,0x85,0x68,0xfe,0xff,0xff,0x48,0x83,0xc0,0x48,0x48,0x8b,0x00,0x48, + 0x89,0x85,0x70,0xfe,0xff,0xff,0x48,0x8d,0x85,0xc0,0xfe,0xff,0xff,0xba,0x30,0x01, + 0x00,0x00,0xbe,0x00,0x00,0x00,0x00,0x48,0x89,0xc7,0xe8,0x56,0x01,0x00,0x00,0x48, + 0x8b,0x85,0x78,0xfe,0xff,0xff,0x83,0xe0,0x10,0x48,0x85,0xc0,0x74,0x60,0xc7,0x45, + 0xfc,0x00,0x00,0x00,0x00,0xeb,0x36,0x8b,0x45,0xfc,0x48,0x98,0x48,0xc1,0xe0,0x05, + 0x48,0x89,0xc2,0x48,0x8d,0x05,0x86,0x1a,0x00,0x00,0x48,0x8d,0x0c,0x02,0x48,0x8d, + 0x85,0x80,0xfe,0xff,0xff,0xba,0x20,0x00,0x00,0x00,0x48,0x89,0xc6,0x48,0x89,0xcf, + 0xe8,0x98,0x01,0x00,0x00,0x85,0xc0,0x74,0x0e,0x83,0x45,0xfc,0x01,0x8b,0x45,0xfc, + 0x83,0xf8,0x02,0x76,0xc2,0xeb,0x01,0x90,0x83,0x7d,0xfc,0x03,0x75,0x10,0x48,0x8b, + 0x85,0x68,0xfe,0xff,0xff,0xc7,0x40,0x50,0x00,0x00,0x00,0x00,0xeb,0x5d,0x48,0x8b, + 0x8d,0x70,0xfe,0xff,0xff,0x48,0x8b,0x95,0x78,0xfe,0xff,0xff,0x48,0x8d,0xbd,0xc0, + 0xfe,0xff,0xff,0x48,0x8d,0xb5,0x80,0xfe,0xff,0xff,0x48,0x8d,0x85,0xa0,0xfe,0xff, + 0xff,0x49,0x89,0xf8,0x48,0x89,0xc7,0xe8,0x79,0xfc,0xff,0xff,0x83,0xf0,0x01,0x84, + 0xc0,0x75,0x27,0x48,0x8b,0x85,0x68,0xfe,0xff,0xff,0x48,0x8d,0x48,0x50,0x48,0x8d, + 0x85,0xc0,0xfe,0xff,0xff,0xba,0x30,0x01,0x00,0x00,0x48,0x89,0xc6,0x48,0x89,0xcf, + 0xe8,0xce,0x00,0x00,0x00,0xeb,0x04,0x90,0xeb,0x01,0x90,0xc9,0xc3,0x48,0x8d,0x83, + 0x00,0x90,0x00,0x00,0x48,0x94,0x50,0x51,0x53,0xe8,0x56,0xfe,0xff,0xff,0x5b,0x48, + 0xb8,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x48,0xba,0xff,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x48,0x8d,0xbb,0x00,0x50,0x00,0x00,0x0f,0xae,0x0f,0x48,0x31,0xc9, + 0x48,0x31,0xd2,0x48,0x31,0xff,0x48,0x31,0xf6,0x4d,0x31,0xc0,0x4d,0x31,0xc9,0x4d, + 0x31,0xd2,0x4d,0x31,0xdb,0x4d,0x31,0xe4,0x4d,0x31,0xed,0x4d,0x31,0xf6,0x4d,0x31, + 0xff,0x48,0x01,0xd2,0x5b,0x58,0x48,0x89,0xc4,0x48,0xc7,0xc0,0x04,0x00,0x00,0x00, + 0x0f,0x01,0xd7,0x53,0x48,0x31,0xc0,0x48,0x89,0xfb,0x48,0x89,0xf1,0x0f,0x01,0xd7, + 0x5b,0xc3,0x53,0x48,0xc7,0xc0,0x01,0x00,0x00,0x00,0x48,0x89,0xfb,0x48,0x89,0xf1, + 0x0f,0x01,0xd7,0x5b,0xc3,0x55,0x48,0x89,0xe5,0x48,0x89,0x7d,0xe8,0x89,0x75,0xe4, + 0x48,0x89,0x55,0xd8,0x48,0xc7,0x45,0xf8,0x00,0x00,0x00,0x00,0xeb,0x15,0x48,0x8b, + 0x55,0xe8,0x48,0x8b,0x45,0xf8,0x48,0x01,0xd0,0x8b,0x55,0xe4,0x88,0x10,0x48,0x83, + 0x45,0xf8,0x01,0x48,0x8b,0x45,0xf8,0x48,0x3b,0x45,0xd8,0x72,0xe1,0x48,0x8b,0x45, + 0xe8,0x5d,0xc3,0x55,0x48,0x89,0xe5,0x48,0x89,0x7d,0xe8,0x48,0x89,0x75,0xe0,0x48, + 0x89,0x55,0xd8,0x48,0xc7,0x45,0xf8,0x00,0x00,0x00,0x00,0xeb,0x20,0x48,0x8b,0x55, + 0xe8,0x48,0x8b,0x45,0xf8,0x48,0x01,0xc2,0x48,0x8b,0x4d,0xe0,0x48,0x8b,0x45,0xf8, + 0x48,0x01,0xc8,0x0f,0xb6,0x00,0x88,0x02,0x48,0x83,0x45,0xf8,0x01,0x48,0x8b,0x45, + 0xf8,0x48,0x3b,0x45,0xd8,0x72,0xd6,0x48,0x8b,0x45,0xe8,0x5d,0xc3,0x55,0x48,0x89, + 0xe5,0x48,0x89,0x7d,0xe8,0x48,0x89,0x75,0xe0,0x48,0x89,0x55,0xd8,0x48,0xc7,0x45, + 0xf8,0x00,0x00,0x00,0x00,0xeb,0x4d,0x48,0x8b,0x55,0xe8,0x48,0x8b,0x45,0xf8,0x48, + 0x01,0xd0,0x0f,0xb6,0x10,0x48,0x8b,0x4d,0xe0,0x48,0x8b,0x45,0xf8,0x48,0x01,0xc8, + 0x0f,0xb6,0x00,0x38,0xc2,0x74,0x28,0x48,0x8b,0x55,0xe8,0x48,0x8b,0x45,0xf8,0x48, + 0x01,0xd0,0x0f,0xb6,0x00,0x0f,0xbe,0xd0,0x48,0x8b,0x4d,0xe0,0x48,0x8b,0x45,0xf8, + 0x48,0x01,0xc8,0x0f,0xb6,0x00,0x0f,0xbe,0xc0,0x29,0xc2,0x89,0xd0,0xeb,0x14,0x48, + 0x83,0x45,0xf8,0x01,0x48,0x8b,0x45,0xf8,0x48,0x3b,0x45,0xd8,0x72,0xa9,0xb8,0x00, + 0x00,0x00,0x00,0x5d,0xc3,0x55,0x48,0x89,0xe5,0x48,0x89,0x7d,0xd8,0x48,0x89,0x75, + 0xd0,0x48,0x8b,0x45,0xd8,0x48,0x89,0x45,0xf8,0x48,0x8b,0x45,0xd0,0x48,0x89,0x45, + 0xf0,0xc7,0x45,0xec,0x00,0x00,0x00,0x00,0xeb,0x30,0x48,0x8b,0x45,0xf8,0x0f,0xb6, + 0x00,0x0f,0xb6,0xd0,0x48,0x8b,0x45,0xf0,0x0f,0xb6,0x00,0x0f,0xb6,0xc0,0x29,0xc2, + 0x89,0xd0,0x89,0x45,0xec,0x83,0x7d,0xec,0x00,0x74,0x05,0x8b,0x45,0xec,0xeb,0x25, + 0x48,0x83,0x45,0xf8,0x01,0x48,0x83,0x45,0xf0,0x01,0x48,0x8b,0x45,0xf8,0x0f,0xb6, + 0x00,0x84,0xc0,0x75,0xc5,0x48,0x8b,0x45,0xf0,0x0f,0xb6,0x00,0x84,0xc0,0x75,0xba, + 0xb8,0x00,0x00,0x00,0x00,0x5d,0xc3,0x55,0x48,0x89,0xe5,0x48,0x89,0x7d,0xf8,0x48, + 0x89,0x75,0xf0,0x48,0x89,0x55,0xe8,0x48,0x8b,0x45,0xf8,0x48,0x8b,0x40,0x08,0x48, + 0x8b,0x55,0xf0,0x48,0x8b,0x75,0xe8,0xf3,0x0f,0x6f,0x02,0xf3,0x0f,0x6f,0x08,0x66, + 0x0f,0xef,0xc1,0x48,0x83,0xc0,0x10,0x48,0xc7,0xc1,0x09,0x00,0x00,0x00,0xf3,0x0f, + 0x6f,0x08,0x66,0x0f,0x38,0xdc,0xc1,0x48,0x83,0xc0,0x10,0x48,0x83,0xe9,0x01,0x75, + 0xed,0xf3,0x0f,0x6f,0x08,0x66,0x0f,0x38,0xdd,0xc1,0xf3,0x0f,0x7f,0x06,0xb8,0x00, + 0x00,0x00,0x00,0x5d,0xc3,0x55,0x48,0x89,0xe5,0x48,0x89,0x7d,0xf8,0x48,0x89,0x75, + 0xf0,0x48,0x8b,0x55,0xf8,0x48,0x8b,0x4d,0xf0,0xf3,0x0f,0x6f,0x01,0xf3,0x0f,0x7f, + 0x02,0xeb,0x2d,0x66,0x0f,0x70,0xc9,0xff,0x66,0x0f,0xef,0xc8,0x66,0x0f,0x73,0xf8, + 0x04,0x66,0x0f,0xef,0xc8,0x66,0x0f,0x73,0xf8,0x04,0x66,0x0f,0xef,0xc8,0x66,0x0f, + 0x73,0xf8,0x04,0x66,0x0f,0xef,0xc1,0x48,0x83,0xc2,0x10,0xf3,0x0f,0x7f,0x02,0xc3, + 0x66,0x0f,0x3a,0xdf,0xc8,0x01,0xe8,0xc8,0xff,0xff,0xff,0x66,0x0f,0x3a,0xdf,0xc8, + 0x02,0xe8,0xbd,0xff,0xff,0xff,0x66,0x0f,0x3a,0xdf,0xc8,0x04,0xe8,0xb2,0xff,0xff, + 0xff,0x66,0x0f,0x3a,0xdf,0xc8,0x08,0xe8,0xa7,0xff,0xff,0xff,0x66,0x0f,0x3a,0xdf, + 0xc8,0x10,0xe8,0x9c,0xff,0xff,0xff,0x66,0x0f,0x3a,0xdf,0xc8,0x20,0xe8,0x91,0xff, + 0xff,0xff,0x66,0x0f,0x3a,0xdf,0xc8,0x40,0xe8,0x86,0xff,0xff,0xff,0x66,0x0f,0x3a, + 0xdf,0xc8,0x80,0xe8,0x7b,0xff,0xff,0xff,0x66,0x0f,0x3a,0xdf,0xc8,0x1b,0xe8,0x70, + 0xff,0xff,0xff,0x66,0x0f,0x3a,0xdf,0xc8,0x36,0xe8,0x65,0xff,0xff,0xff,0x90,0x5d, + 0xc3,0x55,0x48,0x89,0xe5,0x48,0x89,0x7d,0xe8,0x48,0x89,0x75,0xe0,0x48,0x8b,0x45, + 0xe8,0x48,0x89,0x45,0xf8,0xeb,0x0f,0x48,0x8b,0x45,0xf8,0x48,0x8d,0x50,0x01,0x48, + 0x89,0x55,0xf8,0xc6,0x00,0x00,0x48,0x8b,0x45,0xe0,0x48,0x8d,0x50,0xff,0x48,0x89, + 0x55,0xe0,0x48,0x85,0xc0,0x75,0xe0,0x90,0x5d,0xc3,0x55,0x48,0x89,0xe5,0x48,0x89, + 0x7d,0xd8,0x48,0x89,0x75,0xd0,0xc6,0x45,0xf7,0x87,0xc6,0x45,0xff,0x00,0x48,0xc7, + 0x45,0xe8,0x10,0x00,0x00,0x00,0x0f,0xb6,0x45,0xf7,0x88,0x45,0xe7,0x48,0x8b,0x45, + 0xe8,0x83,0xe8,0x01,0x89,0x45,0xf8,0xeb,0x46,0x8b,0x45,0xf8,0x48,0x63,0xd0,0x48, + 0x8b,0x45,0xd8,0x48,0x01,0xd0,0x8b,0x55,0xf8,0x48,0x63,0xca,0x48,0x8b,0x55,0xd0, + 0x48,0x01,0xca,0x0f,0xb6,0x12,0x0f,0xb6,0xd2,0x01,0xd2,0x89,0xd1,0x0f,0xb6,0x55, + 0xff,0x09,0xca,0x88,0x10,0x8b,0x45,0xf8,0x48,0x63,0xd0,0x48,0x8b,0x45,0xd0,0x48, + 0x01,0xd0,0x0f,0xb6,0x00,0xc0,0xe8,0x07,0x88,0x45,0xff,0x83,0x6d,0xf8,0x01,0x83, + 0x7d,0xf8,0x00,0x79,0xb4,0x48,0x8b,0x45,0xd0,0x0f,0xb6,0x00,0xc0,0xf8,0x07,0x88, + 0x45,0xe6,0x48,0x8b,0x45,0xe8,0x48,0x8d,0x50,0xff,0x48,0x8b,0x45,0xd8,0x48,0x01, + 0xc2,0x48,0x8b,0x45,0xe8,0x48,0x8d,0x48,0xff,0x48,0x8b,0x45,0xd8,0x48,0x01,0xc8, + 0x0f,0xb6,0x08,0x0f,0xb6,0x45,0xe7,0x22,0x45,0xe6,0x31,0xc8,0x88,0x02,0xb8,0x00, + 0x00,0x00,0x00,0x5d,0xc3,0x55,0x48,0x89,0xe5,0x48,0x83,0xec,0x38,0x48,0x89,0x7d, + 0xd8,0x48,0x89,0x75,0xd0,0x48,0x89,0x55,0xc8,0x48,0x8d,0x45,0xe0,0xbe,0x10,0x00, + 0x00,0x00,0x48,0x89,0xc7,0xe8,0xe7,0xfe,0xff,0xff,0x48,0x8b,0x45,0xd8,0x48,0x8b, + 0x40,0x18,0x48,0x8d,0x55,0xe0,0x48,0x8d,0x4d,0xe0,0x48,0x89,0xce,0x48,0x89,0xc7, + 0xe8,0xb2,0xfd,0xff,0xff,0x89,0x45,0xfc,0x83,0x7d,0xfc,0x00,0x75,0x38,0x48,0x8d, + 0x55,0xe0,0x48,0x8b,0x45,0xd0,0x48,0x89,0xd6,0x48,0x89,0xc7,0xe8,0xe9,0xfe,0xff, + 0xff,0x89,0x45,0xfc,0x83,0x7d,0xfc,0x00,0x75,0x1f,0x48,0x8b,0x55,0xd0,0x48,0x8b, + 0x45,0xc8,0x48,0x89,0xd6,0x48,0x89,0xc7,0xe8,0xcd,0xfe,0xff,0xff,0x89,0x45,0xfc, + 0x83,0x7d,0xfc,0x00,0xeb,0x04,0x90,0xeb,0x01,0x90,0x48,0x8d,0x45,0xe0,0xbe,0x10, + 0x00,0x00,0x00,0x48,0x89,0xc7,0xe8,0x76,0xfe,0xff,0xff,0x8b,0x45,0xfc,0xc9,0xc3, + 0x55,0x48,0x89,0xe5,0x48,0x83,0xec,0x20,0x48,0x89,0x7d,0xe8,0x48,0x89,0x75,0xe0, + 0x48,0x83,0x7d,0xe8,0x00,0x75,0x07,0xb8,0x00,0x9f,0xff,0xff,0xeb,0x38,0x48,0x8b, + 0x45,0xe8,0x48,0x8b,0x40,0x18,0x48,0x89,0x45,0xf8,0x48,0x8b,0x45,0xf8,0x48,0x8d, + 0x50,0x10,0x48,0x8b,0x45,0xf8,0x48,0x89,0x50,0x08,0x48,0x8b,0x45,0xf8,0x48,0x8b, + 0x40,0x08,0x48,0x8b,0x55,0xe0,0x48,0x89,0xd6,0x48,0x89,0xc7,0xe8,0x64,0xfd,0xff, + 0xff,0xb8,0x00,0x00,0x00,0x00,0xc9,0xc3,0x55,0x48,0x89,0xe5,0x48,0x89,0x7d,0xe8, + 0x48,0x89,0x75,0xe0,0x48,0x89,0x55,0xd8,0x48,0xc7,0x45,0xf8,0x00,0x00,0x00,0x00, + 0xeb,0x30,0x48,0x8b,0x55,0xe8,0x48,0x8b,0x45,0xf8,0x48,0x01,0xd0,0x48,0x8b,0x4d, + 0xe0,0x48,0x8b,0x55,0xf8,0x48,0x01,0xca,0x0f,0xb6,0x32,0x48,0x8b,0x4d,0xd8,0x48, + 0x8b,0x55,0xf8,0x48,0x01,0xca,0x0f,0xb6,0x12,0x31,0xf2,0x88,0x10,0x48,0x83,0x45, + 0xf8,0x01,0x48,0x83,0x7d,0xf8,0x0f,0x76,0xc9,0x90,0x5d,0xc3,0x55,0x48,0x89,0xe5, + 0x48,0x89,0x7d,0xe8,0x48,0x89,0x75,0xe0,0x48,0x89,0x55,0xd8,0x48,0x89,0x4d,0xd0, + 0x48,0xc7,0x45,0xf8,0x00,0x00,0x00,0x00,0xeb,0x54,0x48,0x8b,0x45,0xf8,0x48,0x3b, + 0x45,0xd0,0x73,0x1d,0x48,0x8b,0x55,0xe8,0x48,0x8b,0x45,0xf8,0x48,0x01,0xc2,0x48, + 0x8b,0x4d,0xd8,0x48,0x8b,0x45,0xf8,0x48,0x01,0xc8,0x0f,0xb6,0x00,0x88,0x02,0xeb, + 0x28,0x48,0x8b,0x45,0xf8,0x48,0x3b,0x45,0xd0,0x75,0x10,0x48,0x8b,0x55,0xe8,0x48, + 0x8b,0x45,0xf8,0x48,0x01,0xd0,0xc6,0x00,0x80,0xeb,0x0e,0x48,0x8b,0x55,0xe8,0x48, + 0x8b,0x45,0xf8,0x48,0x01,0xd0,0xc6,0x00,0x00,0x48,0x83,0x45,0xf8,0x01,0x48,0x8b, + 0x45,0xf8,0x48,0x3b,0x45,0xe0,0x72,0xa2,0x90,0x5d,0xc3,0x55,0x48,0x89,0xe5,0x48, + 0x83,0xec,0x50,0x48,0x89,0x7d,0xc8,0x48,0x89,0x75,0xc0,0x48,0x89,0x55,0xb8,0xc7, + 0x45,0xfc,0x00,0x00,0x00,0x00,0x48,0x83,0x7d,0xc8,0x00,0x74,0x14,0x48,0x83,0x7d, + 0xc0,0x00,0x74,0x0d,0x48,0x8b,0x45,0xc8,0x48,0x8b,0x40,0x20,0x48,0x85,0xc0,0x75, + 0x0a,0xb8,0x00,0x9f,0xff,0xff,0xe9,0xc1,0x01,0x00,0x00,0x48,0x8b,0x45,0xc8,0x48, + 0x8b,0x40,0x20,0x48,0x89,0x45,0xe8,0x48,0xc7,0x45,0xe0,0x10,0x00,0x00,0x00,0x48, + 0x8b,0x45,0xc8,0x48,0x8b,0x40,0x20,0x48,0x89,0x45,0xd8,0x48,0x8b,0x45,0xe8,0x48, + 0x8b,0x40,0x20,0x48,0x85,0xc0,0x0f,0x84,0xc2,0x00,0x00,0x00,0x48,0x8b,0x45,0xe8, + 0x48,0x8b,0x40,0x20,0x48,0x8b,0x55,0xe0,0x48,0x29,0xc2,0x48,0x89,0xd0,0x48,0x3b, + 0x45,0xb8,0x0f,0x83,0xa6,0x00,0x00,0x00,0x48,0x8b,0x45,0xe8,0x48,0x8b,0x40,0x20, + 0x48,0x8b,0x55,0xe0,0x48,0x29,0xc2,0x48,0x8b,0x45,0xe8,0x48,0x8b,0x40,0x20,0x48, + 0x8d,0x48,0x10,0x48,0x8b,0x45,0xe8,0x48,0x01,0xc1,0x48,0x8b,0x45,0xc0,0x48,0x89, + 0xc6,0x48,0x89,0xcf,0xe8,0x3a,0xfa,0xff,0xff,0x48,0x8b,0x45,0xe8,0x48,0x8d,0x48, + 0x10,0x48,0x8b,0x55,0xd8,0x48,0x8b,0x45,0xd8,0x48,0x89,0xce,0x48,0x89,0xc7,0xe8, + 0x54,0xfe,0xff,0xff,0x48,0x8b,0x45,0xc8,0x48,0x8b,0x40,0x18,0x48,0x8b,0x55,0xd8, + 0x48,0x8b,0x4d,0xd8,0x48,0x89,0xce,0x48,0x89,0xc7,0xe8,0x38,0xfb,0xff,0xff,0x89, + 0x45,0xfc,0x83,0x7d,0xfc,0x00,0x0f,0x85,0xf9,0x00,0x00,0x00,0x48,0x8b,0x45,0xe8, + 0x48,0x8b,0x40,0x20,0x48,0x8b,0x55,0xe0,0x48,0x29,0xc2,0x48,0x89,0xd0,0x48,0x01, + 0x45,0xc0,0x48,0x8b,0x45,0xe8,0x48,0x8b,0x40,0x20,0x48,0x2b,0x45,0xe0,0x48,0x01, + 0x45,0xb8,0x48,0x8b,0x45,0xe8,0x48,0xc7,0x40,0x20,0x00,0x00,0x00,0x00,0x48,0x8b, + 0x55,0xb8,0x48,0x8b,0x45,0xe0,0x48,0x01,0xd0,0x48,0x83,0xe8,0x01,0xba,0x00,0x00, + 0x00,0x00,0x48,0xf7,0x75,0xe0,0x48,0x89,0x45,0xd0,0x48,0xc7,0x45,0xf0,0x01,0x00, + 0x00,0x00,0xeb,0x50,0x48,0x8b,0x55,0xd8,0x48,0x8b,0x4d,0xc0,0x48,0x8b,0x45,0xd8, + 0x48,0x89,0xce,0x48,0x89,0xc7,0xe8,0xbd,0xfd,0xff,0xff,0x48,0x8b,0x45,0xc8,0x48, + 0x8b,0x40,0x18,0x48,0x8b,0x55,0xd8,0x48,0x8b,0x4d,0xd8,0x48,0x89,0xce,0x48,0x89, + 0xc7,0xe8,0xa1,0xfa,0xff,0xff,0x89,0x45,0xfc,0x83,0x7d,0xfc,0x00,0x75,0x69,0x48, + 0x8b,0x45,0xe0,0x48,0x29,0x45,0xb8,0x48,0x8b,0x45,0xe0,0x48,0x01,0x45,0xc0,0x48, + 0x83,0x45,0xf0,0x01,0x48,0x8b,0x45,0xf0,0x48,0x3b,0x45,0xd0,0x72,0xa6,0x48,0x83, + 0x7d,0xb8,0x00,0x74,0x44,0x48,0x8b,0x45,0xe8,0x48,0x8b,0x40,0x20,0x48,0x8d,0x50, + 0x10,0x48,0x8b,0x45,0xe8,0x48,0x8d,0x0c,0x02,0x48,0x8b,0x55,0xb8,0x48,0x8b,0x45, + 0xc0,0x48,0x89,0xc6,0x48,0x89,0xcf,0xe8,0x17,0xf9,0xff,0xff,0x48,0x8b,0x45,0xe8, + 0x48,0x8b,0x50,0x20,0x48,0x8b,0x45,0xb8,0x48,0x01,0xc2,0x48,0x8b,0x45,0xe8,0x48, + 0x89,0x50,0x20,0xeb,0x04,0x90,0xeb,0x01,0x90,0x8b,0x45,0xfc,0xc9,0xc3,0x55,0x48, + 0x89,0xe5,0x48,0x83,0xec,0x70,0x48,0x89,0x7d,0x98,0x48,0x89,0x75,0x90,0x48,0x83, + 0x7d,0x98,0x00,0x74,0x14,0x48,0x8b,0x45,0x98,0x48,0x8b,0x40,0x20,0x48,0x85,0xc0, + 0x74,0x07,0x48,0x83,0x7d,0x90,0x00,0x75,0x0a,0xb8,0x00,0x9f,0xff,0xff,0xe9,0x67, + 0x01,0x00,0x00,0x48,0x8b,0x45,0x98,0x48,0x8b,0x40,0x20,0x48,0x89,0x45,0xf8,0x48, + 0xc7,0x45,0xf0,0x10,0x00,0x00,0x00,0x48,0x8b,0x45,0xf8,0x48,0x89,0x45,0xe8,0x48, + 0x8d,0x45,0xc0,0xbe,0x10,0x00,0x00,0x00,0x48,0x89,0xc7,0xe8,0xe1,0xfa,0xff,0xff, + 0x48,0x8d,0x45,0xb0,0xbe,0x10,0x00,0x00,0x00,0x48,0x89,0xc7,0xe8,0xd0,0xfa,0xff, + 0xff,0x48,0x8d,0x55,0xb0,0x48,0x8d,0x4d,0xc0,0x48,0x8b,0x45,0x98,0x48,0x89,0xce, + 0x48,0x89,0xc7,0xe8,0xad,0xfb,0xff,0xff,0x48,0x8b,0x45,0xf8,0x48,0x83,0xc0,0x10, + 0x48,0x89,0x45,0xe0,0x48,0x8b,0x45,0xf8,0x48,0x8b,0x40,0x20,0x48,0x3b,0x45,0xf0, + 0x73,0x35,0x48,0x8b,0x45,0xf8,0x48,0x8b,0x48,0x20,0x48,0x8b,0x55,0xe0,0x48,0x8b, + 0x75,0xf0,0x48,0x8d,0x45,0xa0,0x48,0x89,0xc7,0xe8,0xbe,0xfc,0xff,0xff,0x48,0x8d, + 0x55,0xb0,0x48,0x8d,0x4d,0xa0,0x48,0x8d,0x45,0xa0,0x48,0x89,0xce,0x48,0x89,0xc7, + 0xe8,0x53,0xfc,0xff,0xff,0xeb,0x17,0x48,0x8d,0x55,0xc0,0x48,0x8b,0x4d,0xe0,0x48, + 0x8d,0x45,0xa0,0x48,0x89,0xce,0x48,0x89,0xc7,0xe8,0x3a,0xfc,0xff,0xff,0x48,0x8b, + 0x55,0xe8,0x48,0x8d,0x4d,0xa0,0x48,0x8b,0x45,0xe8,0x48,0x89,0xce,0x48,0x89,0xc7, + 0xe8,0x23,0xfc,0xff,0xff,0x48,0x8b,0x45,0x98,0x48,0x8b,0x40,0x18,0x48,0x8b,0x55, + 0xe8,0x48,0x8b,0x4d,0xe8,0x48,0x89,0xce,0x48,0x89,0xc7,0xe8,0x07,0xf9,0xff,0xff, + 0x89,0x45,0xdc,0x83,0x7d,0xdc,0x00,0x75,0x19,0x48,0x8b,0x55,0xf0,0x48,0x8b,0x4d, + 0xe8,0x48,0x8b,0x45,0x90,0x48,0x89,0xce,0x48,0x89,0xc7,0xe8,0xb3,0xf7,0xff,0xff, + 0xeb,0x01,0x90,0x48,0x8d,0x45,0xc0,0xbe,0x10,0x00,0x00,0x00,0x48,0x89,0xc7,0xe8, + 0xed,0xf9,0xff,0xff,0x48,0x8d,0x45,0xb0,0xbe,0x10,0x00,0x00,0x00,0x48,0x89,0xc7, + 0xe8,0xdc,0xf9,0xff,0xff,0x48,0x8b,0x45,0xf8,0x48,0xc7,0x40,0x20,0x00,0x00,0x00, + 0x00,0x48,0x8b,0x45,0xf8,0x48,0x83,0xc0,0x10,0xbe,0x10,0x00,0x00,0x00,0x48,0x89, + 0xc7,0xe8,0xbb,0xf9,0xff,0xff,0x48,0x8b,0x45,0xe8,0xbe,0x10,0x00,0x00,0x00,0x48, + 0x89,0xc7,0xe8,0xaa,0xf9,0xff,0xff,0x8b,0x45,0xdc,0xc9,0xc3,0x55,0x48,0x89,0xe5, + 0x48,0x81,0xec,0xa0,0x01,0x00,0x00,0x48,0x89,0xbd,0x78,0xfe,0xff,0xff,0x48,0x89, + 0xb5,0x70,0xfe,0xff,0xff,0x48,0x89,0x95,0x68,0xfe,0xff,0xff,0x48,0x89,0x8d,0x60, + 0xfe,0xff,0xff,0x48,0x83,0xbd,0x78,0xfe,0xff,0xff,0x00,0x74,0x14,0x48,0x83,0xbd, + 0x70,0xfe,0xff,0xff,0x00,0x74,0x0a,0x48,0x83,0xbd,0x60,0xfe,0xff,0xff,0x00,0x75, + 0x0a,0xb8,0x00,0x9f,0xff,0xff,0xe9,0x12,0x01,0x00,0x00,0x48,0x8d,0x45,0xd0,0xba, + 0x28,0x00,0x00,0x00,0xbe,0x00,0x00,0x00,0x00,0x48,0x89,0xc7,0xe8,0xb4,0xf6,0xff, + 0xff,0x48,0x8d,0x85,0xb0,0xfe,0xff,0xff,0xba,0x20,0x01,0x00,0x00,0xbe,0x00,0x00, + 0x00,0x00,0x48,0x89,0xc7,0xe8,0x9b,0xf6,0xff,0xff,0x48,0x8d,0x85,0xb0,0xfe,0xff, + 0xff,0x48,0x89,0x45,0xe8,0x48,0x8d,0x85,0x80,0xfe,0xff,0xff,0xba,0x28,0x00,0x00, + 0x00,0xbe,0x00,0x00,0x00,0x00,0x48,0x89,0xc7,0xe8,0x77,0xf6,0xff,0xff,0x48,0x8d, + 0x85,0x80,0xfe,0xff,0xff,0xbe,0x10,0x00,0x00,0x00,0x48,0x89,0xc7,0xe8,0xef,0xf8, + 0xff,0xff,0x48,0x8d,0x85,0x80,0xfe,0xff,0xff,0x48,0x89,0x45,0xf0,0x48,0x8b,0x95, + 0x78,0xfe,0xff,0xff,0x48,0x8d,0x45,0xd0,0x48,0x89,0xd6,0x48,0x89,0xc7,0xe8,0x5d, + 0xfa,0xff,0xff,0x89,0x45,0xfc,0x83,0x7d,0xfc,0x00,0x75,0x41,0x48,0x8b,0x95,0x68, + 0xfe,0xff,0xff,0x48,0x8b,0x8d,0x70,0xfe,0xff,0xff,0x48,0x8d,0x45,0xd0,0x48,0x89, + 0xce,0x48,0x89,0xc7,0xe8,0x62,0xfb,0xff,0xff,0x89,0x45,0xfc,0x83,0x7d,0xfc,0x00, + 0x75,0x1e,0x48,0x8b,0x95,0x60,0xfe,0xff,0xff,0x48,0x8d,0x45,0xd0,0x48,0x89,0xd6, + 0x48,0x89,0xc7,0xe8,0x46,0xfd,0xff,0xff,0x89,0x45,0xfc,0xeb,0x04,0x90,0xeb,0x01, + 0x90,0x48,0x8d,0x85,0x80,0xfe,0xff,0xff,0xbe,0x28,0x00,0x00,0x00,0x48,0x89,0xc7, + 0xe8,0x6c,0xf8,0xff,0xff,0x48,0x8d,0x85,0xb0,0xfe,0xff,0xff,0xbe,0x20,0x01,0x00, + 0x00,0x48,0x89,0xc7,0xe8,0x58,0xf8,0xff,0xff,0x48,0x8d,0x45,0xd0,0xbe,0x28,0x00, + 0x00,0x00,0x48,0x89,0xc7,0xe8,0x47,0xf8,0xff,0xff,0x8b,0x45,0xfc,0xc9,0xc3,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0xec,0x15,0xb1,0x07,0x87,0xd2,0xf8,0x46,0x67,0xce,0xb0,0xb5,0x98,0xff,0xc4,0x4a, + 0x1f,0x1c,0xb8,0x0f,0x67,0x0a,0xae,0x5d,0xf9,0xe8,0xfa,0x9f,0x63,0x76,0xe1,0xf8, + 0xc5,0x4a,0x62,0xf2,0xbe,0x9e,0xf7,0x6e,0xfb,0x1f,0x39,0x30,0xad,0x81,0xea,0x7f, + 0x60,0xde,0xfc,0x1f,0x5f,0x25,0xe0,0x9b,0x7c,0x06,0x7a,0x81,0x5a,0xe0,0xc6,0xcb, + 0xe4,0xbd,0x9f,0xc2,0x12,0x98,0x35,0xba,0x1d,0xcc,0xa1,0x93,0x9d,0x57,0xd0,0x8e, + 0x88,0x56,0x1b,0x34,0x74,0x0d,0x59,0x40,0x59,0x72,0xd4,0xba,0x25,0xa7,0xe5,0xf7, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x7f,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x1f,0x00,0x00,0xff,0xff,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +}; diff --git a/SampleCode/SampleCommonLoader/Include/sgx_enclave_ss.h b/SampleCode/SampleCommonLoader/Include/sgx_enclave_ss.h new file mode 100644 index 00000000..dcfbda9f --- /dev/null +++ b/SampleCode/SampleCommonLoader/Include/sgx_enclave_ss.h @@ -0,0 +1,149 @@ +/* + * Copyright (C) 2011-2018 Intel Corporation. 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 name of Intel 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 + * OWNER 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. + * + */ + + +const int sgx_enclave_ss_length = 1808; + +const unsigned char sgx_enclave_ss[1808] = { + 0x06,0x00,0x00,0x00,0xe1,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x00,0x00,0x60,0x00,0x00,0x00, + 0x60,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x11,0x7e,0x78,0xc9,0x6e,0xa6,0xa9,0x32,0xc8,0x79,0x2d,0x97,0x7b,0xd0,0x91,0xff, + 0xf7,0x2a,0x74,0xfc,0x82,0xb9,0x76,0x8d,0x0e,0xbf,0x2e,0x21,0x27,0x91,0x40,0xc3, + 0x0f,0x2c,0xc4,0xe4,0xc3,0x70,0x78,0x9d,0xc5,0x31,0x07,0x04,0x35,0x69,0xcd,0x57, + 0xe3,0x5d,0xe1,0x41,0x21,0x01,0x8a,0x1c,0x94,0x5d,0x6c,0x22,0x6a,0xc8,0x3e,0xc3, + 0x92,0x08,0x75,0xec,0x9d,0x9c,0x38,0x5f,0x88,0x54,0x43,0x83,0xbd,0x66,0xde,0x2f, + 0x97,0x3e,0xb6,0x68,0x6d,0x26,0x48,0x08,0x4b,0xbb,0x27,0x4a,0x05,0x7b,0x06,0x47, + 0x2e,0x15,0xe9,0xa8,0x34,0xb0,0xd1,0x40,0xd7,0x86,0x36,0xd8,0x23,0xbd,0x4c,0xca, + 0x90,0x08,0xb4,0x09,0xe2,0xdc,0x4f,0x37,0x9b,0x9c,0xe5,0xba,0x39,0xe3,0x21,0x5d, + 0x1a,0xe4,0xe0,0x46,0x3c,0x1b,0x25,0xbd,0x86,0xdd,0x0f,0x93,0x91,0x1f,0x0c,0xd5, + 0xf0,0x3d,0xa4,0x6f,0xd2,0xf0,0xe0,0xae,0x6f,0x8f,0x47,0x2c,0xb4,0x98,0xe8,0x2d, + 0x8d,0xb0,0x21,0x45,0x18,0x22,0xf5,0x2a,0x0a,0x20,0x23,0x90,0xbc,0x11,0x31,0x1c, + 0x33,0x6e,0xe8,0x0f,0x08,0xd2,0x7e,0xea,0xec,0x3b,0x13,0xd4,0x18,0xf3,0x26,0x0e, + 0x46,0x2d,0x94,0x30,0xd9,0x92,0x8e,0x0d,0x8d,0x94,0xa8,0xd5,0x5e,0x90,0x85,0x73, + 0xec,0x55,0xd3,0xec,0xfa,0x07,0x07,0x53,0xc0,0xb9,0xb7,0xfe,0xc0,0xd8,0x95,0x43, + 0x3d,0x0b,0x59,0x78,0x27,0x23,0x99,0x2c,0x4b,0x3e,0x20,0xa5,0x7a,0xd9,0x9a,0x6f, + 0x24,0x10,0xee,0xe8,0x6a,0xdb,0xb1,0x76,0x22,0xf0,0x42,0x33,0x15,0xc2,0xaf,0x03, + 0xad,0x6a,0xfc,0x26,0xe1,0x6c,0xb3,0xe1,0xff,0x49,0xc2,0x32,0x84,0x67,0x05,0xa8, + 0x18,0x6b,0x75,0x6c,0x38,0x1e,0xca,0x21,0x12,0x79,0xc6,0x44,0x81,0x2b,0xbe,0x57, + 0x06,0xe8,0xb9,0x0e,0x9b,0xa5,0xfe,0x3e,0xc2,0x41,0xf4,0x3f,0x6c,0x63,0x39,0x78, + 0xe3,0x76,0x1a,0x55,0x51,0xce,0x56,0xc0,0x74,0x16,0xba,0x73,0x02,0x09,0xcf,0x08, + 0x2d,0xcb,0x29,0xab,0xae,0x5f,0x63,0x29,0xf7,0x2c,0xde,0x1d,0xb4,0x88,0xbe,0x83, + 0xca,0x1e,0x51,0xcd,0xb3,0x79,0xe0,0x7e,0x75,0x68,0x31,0xaa,0x71,0x92,0x06,0xc0, + 0xd0,0x6c,0x7c,0x86,0x7a,0x64,0x36,0x52,0xb6,0x3a,0x9c,0x5c,0x5c,0xda,0x1b,0xaa, + 0x6f,0x45,0x49,0x77,0x5d,0x47,0xf9,0xb9,0x40,0xf8,0x9c,0x9e,0x14,0xea,0xeb,0xcd, + 0x03,0x00,0x00,0x00,0xbe,0x61,0xa4,0x7c,0x63,0x53,0x92,0x68,0xfa,0xbc,0xfc,0xe1, + 0xfd,0x8c,0x59,0xfb,0xe7,0xa3,0x38,0x81,0x3b,0x19,0x76,0x71,0x7c,0x4b,0xa5,0xdd, + 0x67,0x49,0xdc,0xa6,0x72,0xe6,0x18,0xc3,0x4e,0x29,0xa0,0x5c,0xe4,0x40,0xfe,0xcd, + 0x38,0x48,0x7d,0xb9,0xfa,0x3d,0xea,0xe3,0x5b,0x81,0x9d,0x5a,0x78,0x08,0x9d,0xf8, + 0xd4,0x53,0xc9,0xfd,0x44,0xd3,0x33,0x68,0x95,0x02,0xa7,0xc0,0x95,0x9a,0x64,0x14, + 0xc8,0x10,0xb0,0xf6,0xa9,0x53,0x70,0x3e,0xe5,0x84,0xeb,0x8f,0xd2,0x8f,0xfb,0xcc, + 0xe3,0xfd,0x34,0x07,0x6b,0x2d,0xc7,0x74,0xee,0xdb,0x7a,0xf5,0x8f,0x7a,0xd0,0x69, + 0xab,0x19,0x89,0x3e,0xf4,0x82,0xa1,0x80,0x1a,0x51,0xa6,0x9c,0x7a,0xb7,0x6a,0xbf, + 0x3d,0xd5,0x68,0xc3,0xe9,0xbc,0xdc,0xcd,0x32,0xb2,0xa7,0x77,0xf1,0x92,0xd5,0x9a, + 0x58,0x97,0xee,0xb6,0x3a,0xa4,0x51,0x18,0x43,0x0e,0xa5,0xf5,0xb3,0x5a,0x42,0x11, + 0x47,0x9a,0x29,0xab,0xca,0x98,0x25,0x89,0xd3,0xa8,0x5c,0x7c,0xe7,0xa4,0xe2,0xdf, + 0x5f,0x9b,0xab,0x12,0xe5,0x5b,0x42,0xfe,0x05,0x54,0xa8,0xbf,0x13,0x33,0x4b,0xdd, + 0x0e,0x0f,0x10,0xbb,0xe5,0xd2,0xfb,0xb9,0x77,0x59,0x99,0x6c,0xaa,0x2c,0x34,0x5c, + 0xac,0xcf,0xc7,0x24,0x2f,0x32,0x18,0x17,0xc7,0x7a,0x50,0xe8,0xf6,0xf6,0x53,0x6f, + 0xc2,0x3c,0xa3,0xb8,0x77,0x2b,0xc8,0xe6,0xce,0xbb,0xe2,0xb3,0x7a,0xd8,0xd1,0xbe, + 0x12,0x7b,0x8b,0xb5,0xbe,0x5b,0xb6,0x2f,0x4a,0xf5,0x2c,0xf6,0x77,0xb8,0x1a,0xb2, + 0xd3,0xb9,0x67,0xf1,0xf2,0xda,0xf6,0xfe,0x70,0x0d,0x94,0xfb,0x2d,0x9f,0xab,0xd3, + 0x36,0xf8,0x1f,0xac,0xdb,0x61,0x74,0x75,0x2f,0x69,0xb0,0xea,0x92,0xf4,0xe1,0x56, + 0xb2,0xf2,0x25,0xdf,0x3f,0x3e,0x3c,0x1d,0x8f,0xe0,0x90,0x66,0x67,0x0c,0x61,0xa7, + 0xc9,0xd2,0x1e,0x7b,0xb3,0xd2,0x08,0x23,0x7a,0x1b,0x28,0x0e,0xdd,0xe9,0x14,0x8d, + 0xc5,0x0a,0xa9,0xe9,0x06,0x00,0x67,0x20,0xf3,0x3e,0x0b,0x39,0xd5,0x4e,0xe4,0x48, + 0x63,0xa2,0xcd,0xe8,0x37,0x18,0x49,0x81,0x14,0x39,0xe7,0xe4,0x5c,0x68,0x0b,0x70, + 0x95,0xcb,0xc8,0x00,0x7f,0xeb,0x18,0x37,0xee,0xeb,0xfe,0xe3,0x17,0xf5,0x51,0x63, + 0x70,0xbb,0x86,0x47,0x53,0x82,0x8b,0x7a,0xe7,0xc8,0xea,0xc5,0xab,0xf2,0xf4,0xc9, + 0xcc,0x01,0x96,0xb2,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x51,0x61,0x20,0xfe,0x45,0xfd,0x5d,0xf6,0x86,0xc4,0x3a,0x2f,0x73,0xbd,0x88,0x30, + 0x20,0xe7,0x7b,0xe6,0x18,0xf0,0x7f,0x5b,0xf8,0x4e,0x3d,0xe2,0xd6,0x7c,0xc3,0xe3, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x36,0x00,0x48,0xd0,0x72,0xce,0x36,0xc5,0xd6,0xdf,0x15,0x17,0x77,0x3c,0x2d,0x7b, + 0xba,0x08,0x4f,0x4b,0xf8,0x43,0x19,0x7c,0x33,0x3e,0x99,0xbf,0x03,0xa1,0x75,0xaf, + 0xec,0x39,0x5f,0xee,0xab,0x75,0x3f,0x89,0x6e,0x2e,0x37,0x20,0x15,0x06,0x0b,0x5a, + 0x23,0x88,0x7e,0x42,0x82,0xf1,0xc9,0x00,0xa1,0x0f,0x75,0xb1,0x86,0x25,0x23,0x21, + 0x67,0xef,0x92,0x09,0xae,0x2d,0xbc,0xfc,0x78,0x1f,0x0f,0x7b,0xf5,0x09,0x97,0x7c, + 0xa0,0xa6,0xa8,0x27,0x04,0x92,0x6c,0xbd,0x1b,0x97,0x56,0x27,0xa6,0xfb,0xd0,0x13, + 0xb1,0x43,0x7b,0x07,0xe2,0xa9,0x45,0xf9,0x02,0x19,0x7e,0x1a,0x8c,0xca,0xe3,0xaf, + 0x7c,0x31,0x10,0x7f,0xac,0xd5,0x0c,0x29,0x2f,0xb6,0x2b,0xec,0x66,0x3a,0x45,0xb7, + 0x00,0x71,0xe6,0x16,0xf4,0x6f,0x7b,0xa0,0xbd,0xc6,0x38,0x3f,0xbc,0xf8,0xbf,0xcf, + 0x78,0x99,0x51,0x5c,0xf7,0x69,0x4d,0xa7,0x67,0x22,0xda,0xcc,0x5b,0xcd,0x06,0xa9, + 0xfc,0x84,0xac,0x26,0xa6,0x5d,0x02,0x82,0x22,0xdd,0x1b,0xf6,0x8c,0xfe,0x7c,0xe5, + 0x18,0x12,0xee,0x1c,0x36,0xed,0x8c,0x58,0x69,0x04,0x3a,0x9c,0x72,0x71,0xa9,0x5f, + 0xcb,0xc7,0x98,0x79,0xaf,0x64,0x46,0x73,0xb7,0xd7,0xe9,0x7b,0x26,0xec,0x1a,0xa1, + 0x58,0x05,0xc9,0x41,0x56,0x4e,0x36,0x6a,0xd7,0x1b,0x3b,0x98,0x99,0x03,0x96,0xfd, + 0x46,0x91,0xb4,0x28,0x69,0x58,0x81,0x53,0xf1,0xdc,0x3a,0x8e,0xc5,0xdd,0xab,0x3f, + 0x60,0xab,0x28,0x87,0xe6,0xd6,0x46,0x07,0xe1,0xff,0x5d,0x40,0x91,0xaa,0x4d,0x88, + 0x73,0x36,0xa2,0x5c,0x13,0xe9,0x14,0x99,0x2b,0x46,0xa3,0x27,0x3b,0xea,0x08,0xd7, + 0xb1,0x9b,0xe5,0x4e,0x85,0x13,0x40,0xeb,0x4c,0x1e,0x32,0xfa,0x57,0x7a,0x1b,0xf0, + 0xc9,0x4a,0x34,0xa2,0xa2,0x3c,0x40,0x0e,0x8b,0x77,0xd3,0xdf,0xa3,0x0b,0xd4,0x3b, + 0xf2,0xe3,0xef,0xb3,0x94,0x83,0x1a,0xde,0x21,0x64,0x23,0x86,0x90,0x9d,0x68,0x7e, + 0x0f,0x8f,0x72,0xc5,0x3c,0xd0,0x0f,0x15,0x86,0xb5,0x49,0x80,0x90,0xb6,0xe7,0x17, + 0xa7,0xd3,0x79,0x60,0xe6,0xa6,0x45,0x35,0xfd,0x38,0x1f,0x07,0x72,0x11,0xb1,0x90, + 0xd8,0xd4,0x78,0x44,0x6e,0x79,0x74,0xbb,0x98,0xf8,0xa0,0x7b,0x52,0xa9,0x25,0x40, + 0x0f,0x6b,0xf9,0x99,0xa9,0x4a,0x77,0xe0,0xe6,0x2e,0x1a,0x9a,0xf9,0x0d,0xe1,0x9a, + 0xb6,0xa3,0xdc,0x01,0x6b,0xdc,0x7c,0x91,0x63,0xb7,0x44,0xc8,0xf5,0x36,0xfe,0x6d, + 0x12,0xe8,0x57,0x81,0x0c,0xcb,0xb7,0x17,0xa9,0xaf,0x07,0x8f,0x54,0x12,0x8c,0x56, + 0xdd,0x04,0xdd,0x45,0xf9,0xa3,0xb7,0x15,0xc0,0xa0,0xbd,0x96,0x3d,0x64,0x57,0xd0, + 0xb0,0x68,0x39,0x7a,0x18,0x7d,0xef,0x45,0x76,0x0b,0x60,0x2d,0xd6,0x2b,0x78,0x52, + 0x92,0x4a,0x20,0xff,0xfc,0x98,0xd6,0xf2,0x33,0xe4,0x00,0x20,0x9f,0xc3,0x15,0x61, + 0x87,0x44,0xfd,0x7c,0x3b,0x72,0xce,0xa7,0xb9,0x44,0x1f,0xc6,0x39,0x22,0x55,0x1d, + 0x84,0x8c,0x24,0x86,0x4e,0x0b,0x2d,0xd0,0x2e,0xfc,0x18,0xe1,0xde,0xfa,0x58,0x83, + 0x1b,0x6b,0x5a,0x35,0x14,0x43,0xee,0x13,0xf5,0x26,0xef,0x9e,0xe3,0xda,0x0b,0x55, + 0x9b,0x86,0xb1,0x95,0xe2,0xb1,0x5b,0x49,0xc1,0x2e,0xc8,0x2b,0x85,0x46,0x77,0x4f, + 0xb0,0x01,0x34,0x46,0xa1,0xb4,0x8a,0xbc,0x6d,0x2d,0xe1,0xe7,0x97,0xdf,0xd0,0x48, + 0x17,0xbb,0x82,0x95,0x76,0xec,0xde,0xde,0x57,0xa2,0x33,0x75,0x8e,0xde,0x9f,0xe2, + 0x86,0xad,0x5d,0x04,0xf5,0xd5,0xe7,0xd8,0x5a,0x0a,0x95,0xc1,0x39,0x15,0x57,0xf4, + 0xf9,0x16,0x9c,0x83,0xf6,0x0f,0xe2,0x3e,0x31,0xc5,0xcd,0xe7,0xb1,0xd3,0x7f,0x17, + 0x87,0x0b,0x7b,0x4b,0xee,0x7d,0x80,0x86,0x2c,0xf2,0xca,0xb7,0x1c,0xaa,0x73,0x52, + 0x94,0xaa,0x1e,0x33,0x47,0x6e,0x36,0xf4,0x4c,0xd0,0x8a,0xa4,0xef,0x3d,0x56,0x41, + 0x44,0x36,0x23,0xab,0x91,0xb3,0x61,0xe6,0x9b,0x31,0x02,0x2c,0x72,0x7a,0x80,0x02, + 0x07,0x1e,0x4d,0xb1,0xb1,0xf4,0x14,0x9e,0x36,0xb8,0xea,0xf5,0xfd,0xf1,0x6a,0x54, + 0x48,0xec,0x59,0xfd,0x92,0x35,0xc6,0x2e,0x18,0x44,0x6d,0x25,0x82,0x09,0xc6,0x66, + 0x11,0xb5,0xe9,0xfa,0x2f,0x37,0xf9,0xbf,0x5e,0x28,0xb9,0x77,0xe9,0x96,0xf6,0xe5, + 0xf2,0x62,0x5f,0x4d,0xb3,0xea,0xe3,0x6c,0x9e,0xd4,0x66,0x8d,0x54,0x9b,0xd4,0x1f, + 0x69,0x99,0x43,0x23,0xea,0x6c,0x83,0xea,0xb0,0x71,0x8c,0x07,0x9c,0x82,0x0d,0xb7, + 0xd6,0x31,0xfa,0xba,0xeb,0x96,0x2b,0x1f,0x8d,0xc8,0x95,0xf1,0x12,0xc0,0xb7,0xf4, + 0xbb,0x5e,0x27,0x40,0x78,0x72,0xb2,0xea,0xa7,0xdb,0xab,0xeb,0x11,0x18,0xfe,0x45, + 0xa6,0x2e,0xc0,0xb4,0xd9,0x6f,0x21,0xa7,0xf8,0x70,0x80,0xba,0xc0,0x5d,0x6c,0xac, +}; diff --git a/SampleCode/SampleCommonLoader/Makefile b/SampleCode/SampleCommonLoader/Makefile new file mode 100644 index 00000000..3892a078 --- /dev/null +++ b/SampleCode/SampleCommonLoader/Makefile @@ -0,0 +1,55 @@ +# +# Copyright (C) 2011-2018 Intel Corporation. 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 name of Intel 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 +# OWNER 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. +# +# + +SGX_SDK ?= /opt/intel/sgxsdk + +App_Objects := App/sample.o App/enclave_entry.o + +sample: $(App_Objects) + @$(CXX) $^ -o $@ -L. -lsgx_enclave_common + @echo "LINK => $@" + +App/%.o: App/%.cpp + @$(CXX) -c $< -o $@ -I./Include -I$(SGX_SDK)/include + @echo "GEN => $@" + +App/%.o: App/%.S + @$(CC) -c $< -o $@ -I./Include -I$(SGX_SDK)/include + @echo "GEN => $@" + +.PHONY: clean +clean: + @$(RM) sample $(App_Objects) + +.PHONY: rebuild +rebuild: + $(MAKE) clean + $(MAKE) sample diff --git a/SampleCode/SampleCommonLoader/README.txt b/SampleCode/SampleCommonLoader/README.txt new file mode 100644 index 00000000..73a1abc8 --- /dev/null +++ b/SampleCode/SampleCommonLoader/README.txt @@ -0,0 +1,24 @@ +------------------------ +Purpose of SampleCommonLoader +------------------------ +The project demonstrates how to use these Enclave Common Loader Layer APIs: +- enclave_create +- enclave_load_data +- enclave_initialize +- enclave_delete + +------------------------------------ +How to Build/Execute the Sample Code +------------------------------------ +1. Install Intel(R) Software Guard Extensions (Intel(R) SGX) PSW and Intel(R) SGX SDK for Linux* OS +2. Make sure your environment is set: + $ source ${sgx-sdk-install-path}/environment +3. Build the project with the prepared Makefile: + a. Build the project + $ make + b. Clean the project + $ make clean + c. Re-build the project + $ make rebuild +4. Execute the binary directly: + $ ./sample diff --git a/SampleCode/SampleEnclave/App/App.cpp b/SampleCode/SampleEnclave/App/App.cpp index c21763ca..74340a04 100644 --- a/SampleCode/SampleEnclave/App/App.cpp +++ b/SampleCode/SampleEnclave/App/App.cpp @@ -150,71 +150,22 @@ void print_error_message(sgx_status_t ret) } /* Initialize the enclave: - * Step 1: try to retrieve the launch token saved by last transaction - * Step 2: call sgx_create_enclave to initialize an enclave instance - * Step 3: save the launch token if it is updated + * Call sgx_create_enclave to initialize an enclave instance */ int initialize_enclave(void) { - char token_path[MAX_PATH] = {'\0'}; sgx_launch_token_t token = {0}; sgx_status_t ret = SGX_ERROR_UNEXPECTED; int updated = 0; - /* Step 1: try to retrieve the launch token saved by last transaction - * if there is no token, then create a new one. - */ - /* try to get the token saved in $HOME */ - const char *home_dir = getpwuid(getuid())->pw_dir; - - if (home_dir != NULL && - (strlen(home_dir)+strlen("/")+sizeof(TOKEN_FILENAME)+1) <= MAX_PATH) { - /* compose the token path */ - strncpy(token_path, home_dir, strlen(home_dir)); - strncat(token_path, "/", strlen("/")); - strncat(token_path, TOKEN_FILENAME, sizeof(TOKEN_FILENAME)+1); - } else { - /* if token path is too long or $HOME is NULL */ - strncpy(token_path, TOKEN_FILENAME, sizeof(TOKEN_FILENAME)); - } - - FILE *fp = fopen(token_path, "rb"); - if (fp == NULL && (fp = fopen(token_path, "wb")) == NULL) { - printf("Warning: Failed to create/open the launch token file \"%s\".\n", token_path); - } - - if (fp != NULL) { - /* read the token from saved file */ - size_t read_num = fread(token, 1, sizeof(sgx_launch_token_t), fp); - if (read_num != 0 && read_num != sizeof(sgx_launch_token_t)) { - /* if token is invalid, clear the buffer */ - memset(&token, 0x0, sizeof(sgx_launch_token_t)); - printf("Warning: Invalid launch token read from \"%s\".\n", token_path); - } - } - /* Step 2: call sgx_create_enclave to initialize an enclave instance */ + /* Call sgx_create_enclave to initialize an enclave instance */ /* Debug Support: set 2nd parameter to 1 */ ret = sgx_create_enclave(ENCLAVE_FILENAME, SGX_DEBUG_FLAG, &token, &updated, &global_eid, NULL); if (ret != SGX_SUCCESS) { print_error_message(ret); - if (fp != NULL) fclose(fp); return -1; } - /* Step 3: save the launch token if it is updated */ - if (updated == FALSE || fp == NULL) { - /* if the token is not updated, or file handler is invalid, do not perform saving */ - if (fp != NULL) fclose(fp); - return 0; - } - - /* reopen the file with write capablity */ - fp = freopen(token_path, "wb", fp); - if (fp == NULL) return 0; - size_t write_num = fwrite(token, 1, sizeof(sgx_launch_token_t), fp); - if (write_num != sizeof(sgx_launch_token_t)) - printf("Warning: Failed to save launch token to \"%s\".\n", token_path); - fclose(fp); return 0; } diff --git a/SampleCode/SampleEnclave/App/Edger8rSyntax/Functions.cpp b/SampleCode/SampleEnclave/App/Edger8rSyntax/Functions.cpp index 57f4fbf8..0826c634 100644 --- a/SampleCode/SampleEnclave/App/Edger8rSyntax/Functions.cpp +++ b/SampleCode/SampleEnclave/App/Edger8rSyntax/Functions.cpp @@ -43,10 +43,6 @@ void edger8r_function_attributes(void) { sgx_status_t ret = SGX_ERROR_UNEXPECTED; - ret = ecall_function_calling_convs(global_eid); - if (ret != SGX_SUCCESS) - abort(); - ret = ecall_function_public(global_eid); if (ret != SGX_SUCCESS) abort(); diff --git a/SampleCode/SampleEnclave/Enclave/Edger8rSyntax/Functions.cpp b/SampleCode/SampleEnclave/Enclave/Edger8rSyntax/Functions.cpp index 914f5cd1..a2e6ef9f 100644 --- a/SampleCode/SampleEnclave/Enclave/Edger8rSyntax/Functions.cpp +++ b/SampleCode/SampleEnclave/Enclave/Edger8rSyntax/Functions.cpp @@ -38,28 +38,6 @@ #include "../Enclave.h" #include "Enclave_t.h" -/* ecall_function_calling_convs: - * memccpy is defined in system C library. - */ -void ecall_function_calling_convs(void) -{ - sgx_status_t ret = SGX_ERROR_UNEXPECTED; - - char s1[] = "1234567890"; - char s2[] = "0987654321"; - - char buf[BUFSIZ] = {'\0'}; - memcpy(buf, s1, strlen(s1)); - - ret = memccpy(NULL, s1, s2, '\0', strlen(s1)); - - if (ret != SGX_SUCCESS) - abort(); - assert(memcmp(s1, s2, strlen(s1)) == 0); - - return; -} - /* ecall_function_public: * The public ECALL that invokes the OCALL 'ocall_function_allow'. */ diff --git a/SampleCode/SampleEnclave/Enclave/Edger8rSyntax/Functions.edl b/SampleCode/SampleEnclave/Enclave/Edger8rSyntax/Functions.edl index 3d33b01b..5e8520a2 100644 --- a/SampleCode/SampleEnclave/Enclave/Edger8rSyntax/Functions.edl +++ b/SampleCode/SampleEnclave/Enclave/Edger8rSyntax/Functions.edl @@ -43,8 +43,6 @@ enclave { trusted { - public void ecall_function_calling_convs(void); - /* * [public]: * public ECALL can be called directly in App. @@ -63,17 +61,6 @@ enclave { untrusted { - /* - * [cdecl]: - * tells edger8r the calling convention of the OCALLs is 'cdecl'. - * [dllimport]: - * indicats the OCALL is provided in DLLs. - * - * Note: memccpy() is provided by MS system DLL, we don't need to implement it in App side. - */ - - [cdecl, dllimport] void *memccpy([in, out, size=len] void *dest, [in, size=len] const void *src, int val, size_t len); - /* * [allow]: * OCALL 'ocall_function_allow' can invoke ECALL 'ecall_function_private' in App side. diff --git a/SampleCode/SampleEnclave/Enclave/Edger8rSyntax/Pointers.cpp b/SampleCode/SampleEnclave/Enclave/Edger8rSyntax/Pointers.cpp index 6c35a193..461c2713 100644 --- a/SampleCode/SampleEnclave/Enclave/Edger8rSyntax/Pointers.cpp +++ b/SampleCode/SampleEnclave/Enclave/Edger8rSyntax/Pointers.cpp @@ -184,8 +184,9 @@ void ecall_pointer_size(void *ptr, size_t len) /* ecall_pointer_count: * 'cnt' needs to be specified to tell Edger8r the number of elements in 'arr'. */ -void ecall_pointer_count(int *arr, int cnt) +void ecall_pointer_count(int *arr, size_t count) { + int cnt = (int) count; for (int i = (cnt - 1); i >= 0; i--) arr[i] = (cnt - 1 - i); } diff --git a/SampleCode/SampleEnclave/Enclave/Edger8rSyntax/Pointers.edl b/SampleCode/SampleEnclave/Enclave/Edger8rSyntax/Pointers.edl index bc7c928f..2072a5cf 100644 --- a/SampleCode/SampleEnclave/Enclave/Edger8rSyntax/Pointers.edl +++ b/SampleCode/SampleEnclave/Enclave/Edger8rSyntax/Pointers.edl @@ -110,7 +110,7 @@ enclave { * the attribute tells Edger8r the number of integers to be copied from 'arr'. */ - public void ecall_pointer_count([in, out, count=cnt] int *arr, int cnt); + public void ecall_pointer_count([in, out, count=cnt] int *arr, size_t cnt); /* * [isptr]: diff --git a/SampleCode/SampleEnclave/Makefile b/SampleCode/SampleEnclave/Makefile index 885ef130..23ec5028 100644 --- a/SampleCode/SampleEnclave/Makefile +++ b/SampleCode/SampleEnclave/Makefile @@ -43,12 +43,12 @@ else ifeq ($(findstring -m32, $(CXXFLAGS)), -m32) endif ifeq ($(SGX_ARCH), x86) - SGX_COMMON_CFLAGS := -m32 + SGX_COMMON_FLAGS := -m32 SGX_LIBRARY_PATH := $(SGX_SDK)/lib SGX_ENCLAVE_SIGNER := $(SGX_SDK)/bin/x86/sgx_sign SGX_EDGER8R := $(SGX_SDK)/bin/x86/sgx_edger8r else - SGX_COMMON_CFLAGS := -m64 + SGX_COMMON_FLAGS := -m64 SGX_LIBRARY_PATH := $(SGX_SDK)/lib64 SGX_ENCLAVE_SIGNER := $(SGX_SDK)/bin/x64/sgx_sign SGX_EDGER8R := $(SGX_SDK)/bin/x64/sgx_edger8r @@ -61,11 +61,18 @@ endif endif ifeq ($(SGX_DEBUG), 1) - SGX_COMMON_CFLAGS += -O0 -g + SGX_COMMON_FLAGS += -O0 -g else - SGX_COMMON_CFLAGS += -O2 + SGX_COMMON_FLAGS += -O2 endif +SGX_COMMON_FLAGS += -Wall -Wextra -Winit-self -Wpointer-arith -Wreturn-type \ + -Waddress -Wsequence-point -Wformat-security \ + -Wmissing-include-dirs -Wfloat-equal -Wundef -Wshadow \ + -Wcast-align -Wcast-qual -Wconversion -Wredundant-decls +SGX_COMMON_CFLAGS := $(SGX_COMMON_FLAGS) -Wjump-misses-init -Wstrict-prototypes -Wunsuffixed-float-constants +SGX_COMMON_CXXFLAGS := $(SGX_COMMON_FLAGS) -Wnon-virtual-dtor -std=c++11 + ######## App Settings ######## ifneq ($(SGX_MODE), HW) @@ -77,7 +84,7 @@ endif App_Cpp_Files := App/App.cpp $(wildcard App/Edger8rSyntax/*.cpp) $(wildcard App/TrustedLibrary/*.cpp) App_Include_Paths := -IInclude -IApp -I$(SGX_SDK)/include -App_C_Flags := $(SGX_COMMON_CFLAGS) -fPIC -Wno-attributes $(App_Include_Paths) +App_C_Flags := -fPIC -Wno-attributes $(App_Include_Paths) # Three configuration modes - Debug, prerelease, release # Debug - Macro DEBUG enabled. @@ -91,8 +98,8 @@ else App_C_Flags += -DNDEBUG -UEDEBUG -UDEBUG endif -App_Cpp_Flags := $(App_C_Flags) -std=c++11 -App_Link_Flags := $(SGX_COMMON_CFLAGS) -L$(SGX_LIBRARY_PATH) -l$(Urts_Library_Name) -lpthread +App_Cpp_Flags := $(App_C_Flags) +App_Link_Flags := -L$(SGX_LIBRARY_PATH) -l$(Urts_Library_Name) -lpthread ifneq ($(SGX_MODE), HW) App_Link_Flags += -lsgx_uae_service_sim @@ -118,15 +125,15 @@ Crypto_Library_Name := sgx_tcrypto Enclave_Cpp_Files := Enclave/Enclave.cpp $(wildcard Enclave/Edger8rSyntax/*.cpp) $(wildcard Enclave/TrustedLibrary/*.cpp) Enclave_Include_Paths := -IInclude -IEnclave -I$(SGX_SDK)/include -I$(SGX_SDK)/include/tlibc -I$(SGX_SDK)/include/libcxx +Enclave_C_Flags := $(Enclave_Include_Paths) -nostdinc -fvisibility=hidden -fpie -ffunction-sections -fdata-sections CC_BELOW_4_9 := $(shell expr "`$(CC) -dumpversion`" \< "4.9") ifeq ($(CC_BELOW_4_9), 1) - Enclave_C_Flags := $(SGX_COMMON_CFLAGS) -nostdinc -fvisibility=hidden -fpie -ffunction-sections -fdata-sections -fstack-protector + Enclave_C_Flags += -fstack-protector else - Enclave_C_Flags := $(SGX_COMMON_CFLAGS) -nostdinc -fvisibility=hidden -fpie -ffunction-sections -fdata-sections -fstack-protector-strong + Enclave_C_Flags += -fstack-protector-strong endif -Enclave_C_Flags += $(Enclave_Include_Paths) -Enclave_Cpp_Flags := $(Enclave_C_Flags) -std=c++11 -nostdinc++ +Enclave_Cpp_Flags := $(Enclave_C_Flags) -nostdinc++ # To generate a proper enclave, it is recommended to follow below guideline to link the trusted libraries: # 1. Link sgx_trts with the `--whole-archive' and `--no-whole-archive' options, @@ -135,7 +142,7 @@ Enclave_Cpp_Flags := $(Enclave_C_Flags) -std=c++11 -nostdinc++ # Use `--start-group' and `--end-group' to link these libraries. # Do NOT move the libraries linked with `--start-group' and `--end-group' within `--whole-archive' and `--no-whole-archive' options. # Otherwise, you may get some undesirable errors. -Enclave_Link_Flags := $(SGX_COMMON_CFLAGS) -Wl,--no-undefined -nostdlib -nodefaultlibs -nostartfiles -L$(SGX_LIBRARY_PATH) \ +Enclave_Link_Flags := -Wl,--no-undefined -nostdlib -nodefaultlibs -nostartfiles -L$(SGX_LIBRARY_PATH) \ -Wl,--whole-archive -l$(Trts_Library_Name) -Wl,--no-whole-archive \ -Wl,--start-group -lsgx_tstdc -lsgx_tcxx -l$(Crypto_Library_Name) -l$(Service_Library_Name) -Wl,--end-group \ -Wl,-Bstatic -Wl,-Bsymbolic -Wl,--no-undefined \ @@ -206,11 +213,11 @@ App/Enclave_u.c: $(SGX_EDGER8R) Enclave/Enclave.edl @echo "GEN => $@" App/Enclave_u.o: App/Enclave_u.c - @$(CC) $(App_C_Flags) -c $< -o $@ + @$(CC) $(SGX_COMMON_CFLAGS) $(App_C_Flags) -c $< -o $@ @echo "CC <= $<" App/%.o: App/%.cpp - @$(CXX) $(App_Cpp_Flags) -c $< -o $@ + @$(CXX) $(SGX_COMMON_CXXFLAGS) $(App_Cpp_Flags) -c $< -o $@ @echo "CXX <= $<" $(App_Name): App/Enclave_u.o $(App_Cpp_Objects) @@ -228,11 +235,11 @@ Enclave/Enclave_t.c: $(SGX_EDGER8R) Enclave/Enclave.edl @echo "GEN => $@" Enclave/Enclave_t.o: Enclave/Enclave_t.c - @$(CC) $(Enclave_C_Flags) -c $< -o $@ + @$(CC) $(SGX_COMMON_CFLAGS) $(Enclave_C_Flags) -c $< -o $@ @echo "CC <= $<" Enclave/%.o: Enclave/%.cpp - @$(CXX) $(Enclave_Cpp_Flags) -c $< -o $@ + @$(CXX) $(SGX_COMMON_CXXFLAGS) $(Enclave_Cpp_Flags) -c $< -o $@ @echo "CXX <= $<" $(Enclave_Name): Enclave/Enclave_t.o $(Enclave_Cpp_Objects) diff --git a/SampleCode/SampleEnclavePCL/App/App.cpp b/SampleCode/SampleEnclavePCL/App/App.cpp index 9ef3dbe9..90acaaee 100644 --- a/SampleCode/SampleEnclavePCL/App/App.cpp +++ b/SampleCode/SampleEnclavePCL/App/App.cpp @@ -180,50 +180,16 @@ void print_error_message(sgx_status_t ret) } /* Initialize the enclave: - * Step 1: try to retrieve the launch token saved by last transaction - * Step 2: call sgx_create_enclave to initialize an enclave instance - * Step 3: save the launch token if it is updated + * Call sgx_create_enclave to initialize an enclave instance */ sgx_status_t initialize_enclave ( const char *file_name, sgx_enclave_id_t* eid ) { - char token_path[MAX_PATH] = {'\0'}; sgx_launch_token_t token = {0}; sgx_status_t ret = SGX_ERROR_UNEXPECTED; int updated = 0; size_t read_num = 0; - /* Step 1: try to retrieve the launch token saved by last transaction - * if there is no token, then create a new one. - */ - /* try to get the token saved in $HOME */ - const char *home_dir = getpwuid(getuid())->pw_dir; - - if (home_dir != NULL && - (strlen(home_dir)+strlen("/")+sizeof(TOKEN_FILENAME)+1) <= MAX_PATH) { - /* compose the token path */ - strncpy(token_path, home_dir, strlen(home_dir)); - strncat(token_path, "/", strlen("/")); - strncat(token_path, TOKEN_FILENAME, sizeof(TOKEN_FILENAME)+1); - } else { - /* if token path is too long or $HOME is NULL */ - strncpy(token_path, TOKEN_FILENAME, sizeof(TOKEN_FILENAME)); - } - - FILE *fp = fopen(token_path, "rb"); - if (fp == NULL && (fp = fopen(token_path, "wb")) == NULL) { - printf("Warning: Failed to create/open the launch token file \"%s\".\n", token_path); - } - - if (fp != NULL) { - /* read the token from saved file */ - read_num = fread(token, 1, sizeof(sgx_launch_token_t), fp); - if (read_num != 0 && read_num != sizeof(sgx_launch_token_t)) { - /* if token is invalid, clear the buffer */ - memset(&token, 0x0, sizeof(sgx_launch_token_t)); - printf("Warning: Invalid launch token read from \"%s\".\n", token_path); - } - } - /* Step 2: call sgx_create_enclave to initialize an enclave instance */ + /* Call sgx_create_enclave to initialize an enclave instance */ /* Debug Support: set 2nd parameter to 1 */ #ifdef SGX_USE_PCL bool open_seal_enclave = true; @@ -263,10 +229,6 @@ sgx_status_t initialize_enclave ( const char *file_name, sgx_enclave_id_t* eid if (SGX_SUCCESS != ret) { print_error_message(ret); - if(NULL != fp) - { - fclose(fp); - } return ret; } ret = ecall_get_sealed_blob_size(seal_eid, &sealed_blob_size); @@ -303,24 +265,9 @@ sgx_status_t initialize_enclave ( const char *file_name, sgx_enclave_id_t* eid #endif // SGX_USE_PCL if (ret != SGX_SUCCESS) { print_error_message(ret); - if (fp != NULL) fclose(fp); return ret; } - /* Step 3: save the launch token if it is updated */ - if (updated == FALSE || fp == NULL) { - /* if the token is not updated, or file handler is invalid, do not perform saving */ - if (fp != NULL) fclose(fp); - return SGX_SUCCESS; - } - - /* reopen the file with write capablity */ - fp = freopen(token_path, "wb", fp); - if (fp == NULL) return SGX_SUCCESS; - size_t write_num = fwrite(token, 1, sizeof(sgx_launch_token_t), fp); - if (write_num != sizeof(sgx_launch_token_t)) - printf("Warning: Failed to save launch token to \"%s\".\n", token_path); - fclose(fp); return SGX_SUCCESS; } @@ -360,7 +307,7 @@ int SGX_CDECL main(int argc, char *argv[]) /* Destroy the enclave */ sgx_destroy_enclave(global_eid); - printf("Info: SampleEnclave successfully returned.\n"); + printf("Info: SampleEnclavePCL successfully returned.\n"); return 0; } diff --git a/SampleCode/SampleEnclavePCL/App/Edger8rSyntax/Functions.cpp b/SampleCode/SampleEnclavePCL/App/Edger8rSyntax/Functions.cpp index 57f4fbf8..0826c634 100644 --- a/SampleCode/SampleEnclavePCL/App/Edger8rSyntax/Functions.cpp +++ b/SampleCode/SampleEnclavePCL/App/Edger8rSyntax/Functions.cpp @@ -43,10 +43,6 @@ void edger8r_function_attributes(void) { sgx_status_t ret = SGX_ERROR_UNEXPECTED; - ret = ecall_function_calling_convs(global_eid); - if (ret != SGX_SUCCESS) - abort(); - ret = ecall_function_public(global_eid); if (ret != SGX_SUCCESS) abort(); diff --git a/SampleCode/SampleEnclavePCL/Enclave/Edger8rSyntax/Functions.cpp b/SampleCode/SampleEnclavePCL/Enclave/Edger8rSyntax/Functions.cpp index 914f5cd1..a2e6ef9f 100644 --- a/SampleCode/SampleEnclavePCL/Enclave/Edger8rSyntax/Functions.cpp +++ b/SampleCode/SampleEnclavePCL/Enclave/Edger8rSyntax/Functions.cpp @@ -38,28 +38,6 @@ #include "../Enclave.h" #include "Enclave_t.h" -/* ecall_function_calling_convs: - * memccpy is defined in system C library. - */ -void ecall_function_calling_convs(void) -{ - sgx_status_t ret = SGX_ERROR_UNEXPECTED; - - char s1[] = "1234567890"; - char s2[] = "0987654321"; - - char buf[BUFSIZ] = {'\0'}; - memcpy(buf, s1, strlen(s1)); - - ret = memccpy(NULL, s1, s2, '\0', strlen(s1)); - - if (ret != SGX_SUCCESS) - abort(); - assert(memcmp(s1, s2, strlen(s1)) == 0); - - return; -} - /* ecall_function_public: * The public ECALL that invokes the OCALL 'ocall_function_allow'. */ diff --git a/SampleCode/SampleEnclavePCL/Enclave/Edger8rSyntax/Functions.edl b/SampleCode/SampleEnclavePCL/Enclave/Edger8rSyntax/Functions.edl index 3d33b01b..5e8520a2 100644 --- a/SampleCode/SampleEnclavePCL/Enclave/Edger8rSyntax/Functions.edl +++ b/SampleCode/SampleEnclavePCL/Enclave/Edger8rSyntax/Functions.edl @@ -43,8 +43,6 @@ enclave { trusted { - public void ecall_function_calling_convs(void); - /* * [public]: * public ECALL can be called directly in App. @@ -63,17 +61,6 @@ enclave { untrusted { - /* - * [cdecl]: - * tells edger8r the calling convention of the OCALLs is 'cdecl'. - * [dllimport]: - * indicats the OCALL is provided in DLLs. - * - * Note: memccpy() is provided by MS system DLL, we don't need to implement it in App side. - */ - - [cdecl, dllimport] void *memccpy([in, out, size=len] void *dest, [in, size=len] const void *src, int val, size_t len); - /* * [allow]: * OCALL 'ocall_function_allow' can invoke ECALL 'ecall_function_private' in App side. diff --git a/SampleCode/SampleEnclavePCL/Enclave/Edger8rSyntax/Pointers.cpp b/SampleCode/SampleEnclavePCL/Enclave/Edger8rSyntax/Pointers.cpp index 70ccfc0d..a4bb2917 100644 --- a/SampleCode/SampleEnclavePCL/Enclave/Edger8rSyntax/Pointers.cpp +++ b/SampleCode/SampleEnclavePCL/Enclave/Edger8rSyntax/Pointers.cpp @@ -180,8 +180,9 @@ void ecall_pointer_size(void *ptr, size_t len) /* ecall_pointer_count: * 'cnt' needs to be specified to tell Edger8r the number of elements in 'arr'. */ -void ecall_pointer_count(int *arr, int cnt) +void ecall_pointer_count(int *arr, size_t count) { + int cnt = (int) count; for (int i = (cnt - 1); i >= 0; i--) arr[i] = (cnt - 1 - i); } diff --git a/SampleCode/SampleEnclavePCL/Enclave/Edger8rSyntax/Pointers.edl b/SampleCode/SampleEnclavePCL/Enclave/Edger8rSyntax/Pointers.edl index bc7c928f..2072a5cf 100644 --- a/SampleCode/SampleEnclavePCL/Enclave/Edger8rSyntax/Pointers.edl +++ b/SampleCode/SampleEnclavePCL/Enclave/Edger8rSyntax/Pointers.edl @@ -110,7 +110,7 @@ enclave { * the attribute tells Edger8r the number of integers to be copied from 'arr'. */ - public void ecall_pointer_count([in, out, count=cnt] int *arr, int cnt); + public void ecall_pointer_count([in, out, count=cnt] int *arr, size_t cnt); /* * [isptr]: diff --git a/SampleCode/SampleEnclavePCL/Makefile b/SampleCode/SampleEnclavePCL/Makefile index 1484900b..79cd4e86 100644 --- a/SampleCode/SampleEnclavePCL/Makefile +++ b/SampleCode/SampleEnclavePCL/Makefile @@ -48,13 +48,13 @@ ifeq ($(SGX_ARCH), x86) ifneq ($(SGX_PCL), 0) $(error SGX PCL feature is not supported for 32bit mode!) else - SGX_COMMON_CFLAGS := -m32 + SGX_COMMON_FLAGS := -m32 SGX_LIBRARY_PATH := $(SGX_SDK)/lib SGX_ENCLAVE_SIGNER := $(SGX_SDK)/bin/x86/sgx_sign SGX_EDGER8R := $(SGX_SDK)/bin/x86/sgx_edger8r endif else - SGX_COMMON_CFLAGS := -m64 + SGX_COMMON_FLAGS := -m64 SGX_LIBRARY_PATH := $(SGX_SDK)/lib64 SGX_ENCLAVE_SIGNER := $(SGX_SDK)/bin/x64/sgx_sign SGX_EDGER8R := $(SGX_SDK)/bin/x64/sgx_edger8r @@ -67,12 +67,19 @@ endif endif ifeq ($(SGX_DEBUG), 1) - SGX_COMMON_CFLAGS += -O0 -g + SGX_COMMON_FLAGS += -O0 -g Encryption_Tool_Flags := -d else - SGX_COMMON_CFLAGS += -O2 + SGX_COMMON_FLAGS += -O2 endif +SGX_COMMON_FLAGS += -Wall -Wextra -Winit-self -Wpointer-arith -Wreturn-type \ + -Waddress -Wsequence-point -Wformat-security \ + -Wmissing-include-dirs -Wfloat-equal -Wundef -Wshadow \ + -Wcast-align -Wcast-qual -Wconversion -Wredundant-decls +SGX_COMMON_CFLAGS := $(SGX_COMMON_FLAGS) -Wjump-misses-init -Wstrict-prototypes -Wunsuffixed-float-constants +SGX_COMMON_CXXFLAGS := $(SGX_COMMON_FLAGS) -Wnon-virtual-dtor -std=c++11 + ######## App Settings ######## ifneq ($(SGX_MODE), HW) @@ -84,7 +91,7 @@ endif App_Cpp_Files := App/App.cpp $(wildcard App/Edger8rSyntax/*.cpp) $(wildcard App/TrustedLibrary/*.cpp) App_Include_Paths := -IInclude -IApp -I$(SGX_SDK)/include -App_C_Flags := $(SGX_COMMON_CFLAGS) -fPIC -Wno-attributes $(App_Include_Paths) +App_C_Flags := -fPIC -Wno-attributes $(App_Include_Paths) # Three configuration modes - Debug, prerelease, release # Debug - Macro DEBUG enabled. @@ -99,11 +106,12 @@ else endif ifneq ($(SGX_PCL), 0) -App_C_Flags += -DSGX_USE_PCL -I../Seal +App_C_Flags += -DSGX_USE_PCL -ISeal endif -App_Cpp_Flags := $(App_C_Flags) -std=c++11 -App_Link_Flags := $(SGX_COMMON_CFLAGS) -L$(SGX_LIBRARY_PATH) -l$(Urts_Library_Name) -lpthread +App_Cpp_Flags := $(App_C_Flags) $(SGX_COMMON_CXXFLAGS) +App_C_Flags += $(SGX_COMMON_CFLAGS) +App_Link_Flags := -L$(SGX_LIBRARY_PATH) -l$(Urts_Library_Name) -lpthread ifneq ($(SGX_MODE), HW) App_Link_Flags += -lsgx_uae_service_sim @@ -131,13 +139,14 @@ Enclave_Include_Paths := -IInclude -IEnclave -I$(SGX_SDK)/include -I$(SGX_SDK)/i CC_BELOW_4_9 := $(shell expr "`$(CC) -dumpversion`" \< "4.9") ifeq ($(CC_BELOW_4_9), 1) - Enclave_C_Flags := $(SGX_COMMON_CFLAGS) -nostdinc -fvisibility=hidden -fpie -ffunction-sections -fdata-sections -fstack-protector + Enclave_C_Flags := -nostdinc -fvisibility=hidden -fpie -ffunction-sections -fdata-sections -fstack-protector else - Enclave_C_Flags := $(SGX_COMMON_CFLAGS) -nostdinc -fvisibility=hidden -fpie -ffunction-sections -fdata-sections -fstack-protector-strong + Enclave_C_Flags := -nostdinc -fvisibility=hidden -fpie -ffunction-sections -fdata-sections -fstack-protector-strong endif Enclave_C_Flags += $(Enclave_Include_Paths) -Enclave_Cpp_Flags := $(Enclave_C_Flags) -std=c++11 -nostdinc++ +Enclave_Cpp_Flags := $(Enclave_C_Flags) $(SGX_COMMON_CXXFLAGS) -nostdinc++ +Enclave_C_Flags += $(SGX_COMMON_CFLAGS) # To generate a proper enclave, it is recommended to follow below guideline to link the trusted libraries: # 1. Link sgx_trts with the `--whole-archive' and `--no-whole-archive' options, @@ -146,7 +155,7 @@ Enclave_Cpp_Flags := $(Enclave_C_Flags) -std=c++11 -nostdinc++ # Use `--start-group' and `--end-group' to link these libraries. # Do NOT move the libraries linked with `--start-group' and `--end-group' within `--whole-archive' and `--no-whole-archive' options. # Otherwise, you may get some undesirable errors. -Enclave_Link_Flags := $(SGX_COMMON_CFLAGS) -Wl,--no-undefined -nostdlib -nodefaultlibs -nostartfiles -L$(SGX_LIBRARY_PATH) \ +Enclave_Link_Flags := -Wl,--no-undefined -nostdlib -nodefaultlibs -nostartfiles -L$(SGX_LIBRARY_PATH) \ -Wl,--whole-archive -l$(Trts_Library_Name) -Wl,--no-whole-archive \ -Wl,--start-group -lsgx_tstdc -lsgx_tcxx -l$(Crypto_Library_Name) -l$(Service_Library_Name) -Wl,--end-group \ -Wl,-Bstatic -Wl,-Bsymbolic -Wl,--no-undefined \ diff --git a/SampleCode/SampleEnclavePCL/Seal/Seal.cpp b/SampleCode/SampleEnclavePCL/Seal/Seal.cpp index 69536d32..301386e8 100644 --- a/SampleCode/SampleEnclavePCL/Seal/Seal.cpp +++ b/SampleCode/SampleEnclavePCL/Seal/Seal.cpp @@ -115,7 +115,7 @@ sgx_status_t ecall_generate_sealed_blob(uint8_t* sealed_blob, size_t sealed_blob g_pcl_guid, // AAD SGX_AESGCM_KEY_SIZE, // Key len key, // Key - sealed_blob_size, // Resulting blob size + (uint32_t)sealed_blob_size, // Resulting blob size (sgx_sealed_data_t*)sealed_blob ); // Resulting blob memset(key, 0,SGX_AESGCM_KEY_SIZE); diff --git a/SampleCode/SealedData/DRM_app/DRM_app.cpp b/SampleCode/SealedData/DRM_app/DRM_app.cpp index a6da8b6a..8dc097e6 100644 --- a/SampleCode/SealedData/DRM_app/DRM_app.cpp +++ b/SampleCode/SealedData/DRM_app/DRM_app.cpp @@ -286,19 +286,19 @@ uint32_t test_time_based_policy_expiration() #define _T(x) x int main(int argc, char* argv[]) { - argc; /* unused parameter */ - argv; /* unused parameter */ - uint32_t result; + (void)argc; /* unused parameter */ + (void)argv; /* unused parameter */ + /* normal operation */ - result = test_replay_protected_drm_operation(); + test_replay_protected_drm_operation(); /* trigger update limitation */ - result = test_replay_protected_drm_update_limitation(); + test_replay_protected_drm_update_limitation(); /* replay attack */ - result = test_replay_protected_drm_replay_attack_protection(); + test_replay_protected_drm_replay_attack_protection(); /* normal operation */ - result = test_time_based_policy_operation(); + test_time_based_policy_operation(); /* trigger expiration */ - result = test_time_based_policy_expiration(); + test_time_based_policy_expiration(); printf("Enter a character before exit ...\n"); getchar(); diff --git a/SampleCode/SealedData/Makefile b/SampleCode/SealedData/Makefile index e3a8bada..03d3b3eb 100644 --- a/SampleCode/SealedData/Makefile +++ b/SampleCode/SealedData/Makefile @@ -43,12 +43,12 @@ else ifeq ($(findstring -m32, $(CXXFLAGS)), -m32) endif ifeq ($(SGX_ARCH), x86) - SGX_COMMON_CFLAGS := -m32 + SGX_COMMON_FLAGS := -m32 SGX_LIBRARY_PATH := $(SGX_SDK)/lib SGX_ENCLAVE_SIGNER := $(SGX_SDK)/bin/x86/sgx_sign SGX_EDGER8R := $(SGX_SDK)/bin/x86/sgx_edger8r else - SGX_COMMON_CFLAGS := -m64 + SGX_COMMON_FLAGS := -m64 SGX_LIBRARY_PATH := $(SGX_SDK)/lib64 SGX_ENCLAVE_SIGNER := $(SGX_SDK)/bin/x64/sgx_sign SGX_EDGER8R := $(SGX_SDK)/bin/x64/sgx_edger8r @@ -61,11 +61,18 @@ endif endif ifeq ($(SGX_DEBUG), 1) - SGX_COMMON_CFLAGS += -O0 -g + SGX_COMMON_FLAGS += -O0 -g else - SGX_COMMON_CFLAGS += -O2 + SGX_COMMON_FLAGS += -O2 endif +SGX_COMMON_FLAGS += -Wall -Wextra -Winit-self -Wpointer-arith -Wreturn-type \ + -Waddress -Wsequence-point -Wformat-security \ + -Wmissing-include-dirs -Wfloat-equal -Wundef -Wshadow \ + -Wcast-align -Wcast-qual -Wconversion -Wredundant-decls +SGX_COMMON_CFLAGS := $(SGX_COMMON_FLAGS) -Wjump-misses-init -Wstrict-prototypes -Wunsuffixed-float-constants +SGX_COMMON_CXXFLAGS := $(SGX_COMMON_FLAGS) -Wnon-virtual-dtor -std=c++11 + ######## App Settings ######## ifneq ($(SGX_MODE), HW) @@ -77,7 +84,7 @@ endif App_Cpp_Files := $(wildcard DRM_app/*.cpp) App_Include_Paths := -I$(SGX_SDK)/include -App_C_Flags := $(SGX_COMMON_CFLAGS) -fPIC -Wno-attributes $(App_Include_Paths) +App_C_Flags := -fPIC -Wno-attributes $(App_Include_Paths) # Three configuration modes - Debug, prerelease, release # Debug - Macro DEBUG enabled. @@ -91,8 +98,9 @@ else App_C_Flags += -DNDEBUG -UEDEBUG -UDEBUG endif -App_Cpp_Flags := $(App_C_Flags) -std=c++11 -App_Link_Flags := $(SGX_COMMON_CFLAGS) -L$(SGX_LIBRARY_PATH) -l$(Urts_Library_Name) -L. -lpthread -Wl,-rpath=$(CURDIR)/sample_libcrypto -Wl,-rpath=$(CURDIR) +App_Cpp_Flags := $(App_C_Flags) $(SGX_COMMON_CXXFLAGS) +App_C_Flags += $(SGX_COMMON_CFLAGS) +App_Link_Flags := -L$(SGX_LIBRARY_PATH) -l$(Urts_Library_Name) -L. -lpthread -Wl,-rpath=$(CURDIR)/sample_libcrypto -Wl,-rpath=$(CURDIR) ifneq ($(SGX_MODE), HW) App_Link_Flags += -lsgx_uae_service_sim @@ -118,14 +126,16 @@ Crypto_Library_Name := sgx_tcrypto Enclave_Cpp_Files := DRM_enclave/DRM_enclave.cpp Enclave_Include_Paths := -I$(SGX_SDK)/include -I$(SGX_SDK)/include/tlibc -I$(SGX_SDK)/include/libcxx +Enclave_C_Flags := -nostdinc -fvisibility=hidden -fpie -ffunction-sections -fdata-sections CC_BELOW_4_9 := $(shell expr "`$(CC) -dumpversion`" \< "4.9") ifeq ($(CC_BELOW_4_9), 1) - Enclave_C_Flags := $(SGX_COMMON_CFLAGS) -nostdinc -fvisibility=hidden -fpie -ffunction-sections -fdata-sections -fstack-protector + Enclave_C_Flags += -fstack-protector else - Enclave_C_Flags := $(SGX_COMMON_CFLAGS) -nostdinc -fvisibility=hidden -fpie -ffunction-sections -fdata-sections -fstack-protector-strong + Enclave_C_Flags += -fstack-protector-strong endif Enclave_C_Flags += $(Enclave_Include_Paths) -Enclave_Cpp_Flags := $(Enclave_C_Flags) -std=c++11 -nostdinc++ +Enclave_Cpp_Flags := $(Enclave_C_Flags) $(SGX_COMMON_CXXFLAGS) -nostdinc++ +Enclave_C_Flags += $(SGX_COMMON_CFLAGS) # To generate a proper enclave, it is recommended to follow below guideline to link the trusted libraries: # 1. Link sgx_trts with the `--whole-archive' and `--no-whole-archive' options, @@ -134,7 +144,7 @@ Enclave_Cpp_Flags := $(Enclave_C_Flags) -std=c++11 -nostdinc++ # Use `--start-group' and `--end-group' to link these libraries. # Do NOT move the libraries linked with `--start-group' and `--end-group' within `--whole-archive' and `--no-whole-archive' options. # Otherwise, you may get some undesirable errors. -Enclave_Link_Flags := $(SGX_COMMON_CFLAGS) -Wl,--no-undefined -nostdlib -nodefaultlibs -nostartfiles -L$(SGX_LIBRARY_PATH) \ +Enclave_Link_Flags := -Wl,--no-undefined -nostdlib -nodefaultlibs -nostartfiles -L$(SGX_LIBRARY_PATH) \ -Wl,--whole-archive -l$(Trts_Library_Name) -Wl,--no-whole-archive \ -Wl,--start-group -lsgx_tstdc -lsgx_tcxx -l$(Crypto_Library_Name) -l$(Service_Library_Name) -Wl,--end-group \ -Wl,-Bstatic -Wl,-Bsymbolic -Wl,--no-undefined \ diff --git a/SampleCode/Switchless/App/App.cpp b/SampleCode/Switchless/App/App.cpp index 08fc5903..1a6fb16c 100644 --- a/SampleCode/Switchless/App/App.cpp +++ b/SampleCode/Switchless/App/App.cpp @@ -154,76 +154,27 @@ void print_error_message(sgx_status_t ret) } /* Initialize the enclave: - * Step 1: try to retrieve the launch token saved by last transaction - * Step 2: call sgx_create_enclave to initialize an enclave instance - * Step 3: save the launch token if it is updated + * Call sgx_create_enclave to initialize an enclave instance */ int initialize_enclave(const sgx_uswitchless_config_t* us_config) { - char token_path[MAX_PATH] = {'\0'}; sgx_launch_token_t token = {0}; sgx_status_t ret = SGX_ERROR_UNEXPECTED; int updated = 0; - /* Step 1: try to retrieve the launch token saved by last transaction - * if there is no token, then create a new one. - */ - /* try to get the token saved in $HOME */ - const char *home_dir = getpwuid(getuid())->pw_dir; - - if (home_dir != NULL && - (strlen(home_dir)+strlen("/")+sizeof(TOKEN_FILENAME)+1) <= MAX_PATH) { - /* compose the token path */ - strncpy(token_path, home_dir, strlen(home_dir)); - strncat(token_path, "/", strlen("/")); - strncat(token_path, TOKEN_FILENAME, sizeof(TOKEN_FILENAME)+1); - } else { - /* if token path is too long or $HOME is NULL */ - strncpy(token_path, TOKEN_FILENAME, sizeof(TOKEN_FILENAME)); - } - - FILE *fp = fopen(token_path, "rb"); - if (fp == NULL && (fp = fopen(token_path, "wb")) == NULL) { - printf("Warning: Failed to create/open the launch token file \"%s\".\n", token_path); - } - - if (fp != NULL) { - /* read the token from saved file */ - size_t read_num = fread(token, 1, sizeof(sgx_launch_token_t), fp); - if (read_num != 0 && read_num != sizeof(sgx_launch_token_t)) { - /* if token is invalid, clear the buffer */ - memset(&token, 0x0, sizeof(sgx_launch_token_t)); - printf("Warning: Invalid launch token read from \"%s\".\n", token_path); - } - } - /* Step 2: call sgx_create_enclave to initialize an enclave instance */ + /* Call sgx_create_enclave to initialize an enclave instance */ /* Debug Support: set 2nd parameter to 1 */ const void* enclave_ex_p[32] = { 0 }; - enclave_ex_p[SGX_CREATE_ENCLAVE_EX_SWITCHLESS_BIT_IDX] = (void*)us_config; + enclave_ex_p[SGX_CREATE_ENCLAVE_EX_SWITCHLESS_BIT_IDX] = (const void*)us_config; ret = sgx_create_enclave_ex(ENCLAVE_FILENAME, SGX_DEBUG_FLAG, &token, &updated, &global_eid, NULL, SGX_CREATE_ENCLAVE_EX_SWITCHLESS, enclave_ex_p); if (ret != SGX_SUCCESS) { print_error_message(ret); - if (fp != NULL) fclose(fp); return -1; } - /* Step 3: save the launch token if it is updated */ - if (updated == FALSE || fp == NULL) { - /* if the token is not updated, or file handler is invalid, do not perform saving */ - if (fp != NULL) fclose(fp); - return 0; - } - - /* reopen the file with write capablity */ - fp = freopen(token_path, "wb", fp); - if (fp == NULL) return 0; - size_t write_num = fwrite(token, 1, sizeof(sgx_launch_token_t), fp); - if (write_num != sizeof(sgx_launch_token_t)) - printf("Warning: Failed to save launch token to \"%s\".\n", token_path); - fclose(fp); return 0; } @@ -282,6 +233,9 @@ void benchmark_empty_ecall(int is_switchless) /* Application entry */ int SGX_CDECL main(int argc, char *argv[]) { + (void) argc; + (void) argv; + /* Configuration for Switchless SGX */ sgx_uswitchless_config_t us_config = SGX_USWITCHLESS_CONFIG_INITIALIZER; us_config.num_uworkers = 2; diff --git a/SampleCode/Switchless/Makefile b/SampleCode/Switchless/Makefile index d3ea853f..85ea7035 100644 --- a/SampleCode/Switchless/Makefile +++ b/SampleCode/Switchless/Makefile @@ -43,12 +43,12 @@ else ifeq ($(findstring -m32, $(CXXFLAGS)), -m32) endif ifeq ($(SGX_ARCH), x86) - SGX_COMMON_CFLAGS := -m32 + SGX_COMMON_FLAGS := -m32 SGX_LIBRARY_PATH := $(SGX_SDK)/lib SGX_ENCLAVE_SIGNER := $(SGX_SDK)/bin/x86/sgx_sign SGX_EDGER8R := $(SGX_SDK)/bin/x86/sgx_edger8r else - SGX_COMMON_CFLAGS := -m64 + SGX_COMMON_FLAGS := -m64 SGX_LIBRARY_PATH := $(SGX_SDK)/lib64 SGX_ENCLAVE_SIGNER := $(SGX_SDK)/bin/x64/sgx_sign SGX_EDGER8R := $(SGX_SDK)/bin/x64/sgx_edger8r @@ -61,11 +61,18 @@ endif endif ifeq ($(SGX_DEBUG), 1) - SGX_COMMON_CFLAGS += -O0 -g + SGX_COMMON_FLAGS += -O0 -g else - SGX_COMMON_CFLAGS += -O2 + SGX_COMMON_FLAGS += -O2 endif +SGX_COMMON_FLAGS += -Wall -Wextra -Winit-self -Wpointer-arith -Wreturn-type \ + -Waddress -Wsequence-point -Wformat-security \ + -Wmissing-include-dirs -Wfloat-equal -Wundef -Wshadow \ + -Wcast-align -Wcast-qual -Wconversion -Wredundant-decls +SGX_COMMON_CFLAGS := $(SGX_COMMON_FLAGS) -Wjump-misses-init -Wstrict-prototypes -Wunsuffixed-float-constants +SGX_COMMON_CXXFLAGS := $(SGX_COMMON_FLAGS) -Wnon-virtual-dtor -std=c++11 + ######## App Settings ######## ifneq ($(SGX_MODE), HW) @@ -75,9 +82,9 @@ else endif App_Cpp_Files := App/App.cpp -App_Include_Paths := -IInclude -IApp -I$(SGX_SDK)/include +App_Include_Paths := -IApp -I$(SGX_SDK)/include -App_C_Flags := $(SGX_COMMON_CFLAGS) -fPIC -Wno-attributes $(App_Include_Paths) +App_C_Flags := -fPIC -Wno-attributes $(App_Include_Paths) # Three configuration modes - Debug, prerelease, release # Debug - Macro DEBUG enabled. @@ -91,8 +98,9 @@ else App_C_Flags += -DNDEBUG -UEDEBUG -UDEBUG endif -App_Cpp_Flags := $(App_C_Flags) -std=c++11 -App_Link_Flags := $(SGX_COMMON_CFLAGS) -L$(SGX_LIBRARY_PATH) -l$(Urts_Library_Name) -lpthread +App_Cpp_Flags := $(App_C_Flags) $(SGX_COMMON_CXXFLAGS) +App_C_Flags += $(SGX_COMMON_CFLAGS) +App_Link_Flags := -L$(SGX_LIBRARY_PATH) -l$(Urts_Library_Name) -lpthread ifneq ($(SGX_MODE), HW) App_Link_Flags += -lsgx_uae_service_sim @@ -116,10 +124,11 @@ endif Crypto_Library_Name := sgx_tcrypto Enclave_Cpp_Files := Enclave/Enclave.cpp -Enclave_Include_Paths := -IInclude -IEnclave -I$(SGX_SDK)/include -I$(SGX_SDK)/include/tlibc -I$(SGX_SDK)/include/stlport +Enclave_Include_Paths := -IEnclave -I$(SGX_SDK)/include -I$(SGX_SDK)/include/tlibc -I$(SGX_SDK)/include/stlport -Enclave_C_Flags := $(SGX_COMMON_CFLAGS) -nostdinc -fvisibility=hidden -fpie -fstack-protector $(Enclave_Include_Paths) -Enclave_Cpp_Flags := $(Enclave_C_Flags) -std=c++03 -nostdinc++ +Enclave_C_Flags := -nostdinc -fvisibility=hidden -fpie -fstack-protector $(Enclave_Include_Paths) +Enclave_Cpp_Flags := $(Enclave_C_Flags) $(SGX_COMMON_CXXFLAGS) -nostdinc++ +Enclave_C_Flags += $(SGX_COMMON_CFLAGS) # To generate a proper enclave, it is recommended to follow below guideline to link the trusted libraries: # 1. Link sgx_trts with the `--whole-archive' and `--no-whole-archive' options, @@ -135,7 +144,7 @@ Enclave_Cpp_Flags := $(Enclave_C_Flags) -std=c++03 -nostdinc++ # -lsgx_tswitchless option must be put between -Wl,--whole-archive and # -Wl,--no-whole-archive with -l$(TRTS_LIBRARY) and before the linker options # for other libraries (e.g., -lsgx_tstdc). -Enclave_Link_Flags := $(SGX_COMMON_CFLAGS) -Wl,--no-undefined -nostdlib -nodefaultlibs -nostartfiles -L$(SGX_LIBRARY_PATH) \ +Enclave_Link_Flags := -Wl,--no-undefined -nostdlib -nodefaultlibs -nostartfiles -L$(SGX_LIBRARY_PATH) \ -Wl,--whole-archive -lsgx_tswitchless -l$(Trts_Library_Name) -Wl,--no-whole-archive \ -Wl,--start-group -lsgx_tstdc -lsgx_tstdcxx -l$(Crypto_Library_Name) -l$(Service_Library_Name) -Wl,--end-group \ -Wl,-Bstatic -Wl,-Bsymbolic -Wl,--no-undefined \ diff --git a/common/inc/internal/global_data.h b/common/inc/internal/global_data.h index af219f0b..2073bcab 100644 --- a/common/inc/internal/global_data.h +++ b/common/inc/internal/global_data.h @@ -63,6 +63,8 @@ typedef struct _global_data_t #define ENCLAVE_INIT_DONE 2 #define ENCLAVE_CRASHED 3 +#define RELRO_SECTION_NAME ".data.rel.ro" + #ifdef __cplusplus extern "C" { #endif diff --git a/common/inc/internal/ipp_wrapper.h b/common/inc/internal/ipp_wrapper.h index 550cc6fb..9519be00 100644 --- a/common/inc/internal/ipp_wrapper.h +++ b/common/inc/internal/ipp_wrapper.h @@ -29,10 +29,23 @@ * */ -#ifndef _IPP_WRAPPER_H -#define _IPP_WRAPPER_H + +#ifndef _IPP_WRAPPER_H_ +#define _IPP_WRAPPER_H_ #include "ippcp.h" +#include "sgx_trts.h" +#include "sgx_tcrypto.h" +#include "util.h" +#include "stdlib.h" +#include "string.h" + +#ifndef ERROR_BREAK +#define ERROR_BREAK(x) if(x != ippStsNoErr){break;} +#endif +#ifndef SAFE_FREE +#define SAFE_FREE(ptr) {if (NULL != (ptr)) {free(ptr); (ptr)=NULL;}} +#endif #ifndef CLEAR_FREE_MEM #define CLEAR_FREE_MEM(address, size) { \ @@ -54,42 +67,36 @@ }} #endif -#ifndef ERROR_BREAK -#define ERROR_BREAK(x) if(x != ippStsNoErr){break;} -#endif #ifndef NULL_BREAK #define NULL_BREAK(x) if(!x){break;} #endif -#ifdef __cplusplus +#define RSA_SEED_SIZE_SHA256 32 + +#define sgx_create_rsa_pub_key sgx_create_rsa_pub1_key + +IppStatus sgx_ipp_newBN(const Ipp32u *p_data, int size_in_bytes, IppsBigNumState **p_new_BN); +void sgx_ipp_secure_free_BN(IppsBigNumState *pBN, int size_in_bytes); +IppStatus IPP_STDCALL sgx_ipp_DRNGen(Ipp32u* pRandBNU, int nBits, void* pCtx); +IppStatus sgx_ipp_newPrimeGen(int nMaxBits, IppsPrimeState ** pPrimeG); + +#ifdef __cplusplus extern "C" { #endif -IppStatus newBN(const Ipp32u *data, int size_in_bytes, IppsBigNumState **p_new_BN); -IppStatus newPrimeGen(int nMaxBits, IppsPrimeState ** pPrimeG); -IppStatus newPRNG(IppsPRNGState **pRandGen); -IppStatus create_rsa_priv1_key(int n_byte_size, int d_byte_size, const Ipp32u *n, const Ipp32u *d, IppsRSAPrivateKeyState **new_pri_key1); - -IppStatus create_rsa_priv2_key(int p_byte_size, const Ipp32u *p, const Ipp32u *q, - const Ipp32u *dmp1, const Ipp32u *dmq1, const Ipp32u *iqmp, - IppsRSAPrivateKeyState **new_pri_key2); - -IppStatus create_rsa_pub_key(int n_byte_size, int e_byte_size, const Ipp32u *n, const Ipp32u *e, IppsRSAPublicKeyState **new_pub_key); - -void secure_free_BN(IppsBigNumState *pBN, int size_in_bytes); - -void secure_free_rsa_pri1_key(int n_byte_size, int d_byte_size, IppsRSAPrivateKeyState *pri_key1); - void secure_free_rsa_pri2_key(int p_byte_size, IppsRSAPrivateKeyState *pri_key2); void secure_free_rsa_pub_key(int n_byte_size, int e_byte_size, IppsRSAPublicKeyState *pub_key); - - -#ifdef __cplusplus +#ifdef __cplusplus } #endif +static inline IppStatus check_copy_size(size_t target_size, size_t source_size) +{ + if(target_size < source_size) + return ippStsSizeErr; + return ippStsNoErr; +} + #endif - - diff --git a/common/inc/internal/se_version.h b/common/inc/internal/se_version.h index a96aa6f9..cc1e60eb 100644 --- a/common/inc/internal/se_version.h +++ b/common/inc/internal/se_version.h @@ -28,6 +28,8 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * */ -#define STRFILEVER "2.2.100.45311" +#define STRFILEVER "2.3.100.46354" #define COPYRIGHT "Copyright (C) 2018 Intel Corporation" +#define URTS_VERSION "1.0.101.0" +#define ENCLAVE_COMMON_VERSION "1.0.101.0" diff --git a/common/inc/sgx_tcrypto.h b/common/inc/sgx_tcrypto.h index 24df102b..5cfd848e 100644 --- a/common/inc/sgx_tcrypto.h +++ b/common/inc/sgx_tcrypto.h @@ -154,14 +154,14 @@ typedef enum { #define DMQ1_SIZE_IN_BYTES 192 #define IQMP_SIZE_IN_BYTES 192 -#define N_SIZE_IN_UINT N_SIZE_IN_BYTES/sizeof(unsigned int) -#define E_SIZE_IN_UINT E_SIZE_IN_BYTES/sizeof(unsigned int) -#define D_SIZE_IN_UINT D_SIZE_IN_BYTES/sizeof(unsigned int) -#define P_SIZE_IN_UINT P_SIZE_IN_BYTES/sizeof(unsigned int) -#define Q_SIZE_IN_UINT Q_SIZE_IN_BYTES/sizeof(unsigned int) -#define DMP1_SIZE_IN_UINT DMP1_SIZE_IN_BYTES/sizeof(unsigned int) -#define DMQ1_SIZE_IN_UINT DMQ1_SIZE_IN_BYTES/sizeof(unsigned int) -#define IQMP_SIZE_IN_UINT IQMP_SIZE_IN_BYTES/sizeof(unsigned int) +#define N_SIZE_IN_UINT (N_SIZE_IN_BYTES/sizeof(unsigned int)) +#define E_SIZE_IN_UINT (E_SIZE_IN_BYTES/sizeof(unsigned int)) +#define D_SIZE_IN_UINT (D_SIZE_IN_BYTES/sizeof(unsigned int)) +#define P_SIZE_IN_UINT (P_SIZE_IN_BYTES/sizeof(unsigned int)) +#define Q_SIZE_IN_UINT (Q_SIZE_IN_BYTES/sizeof(unsigned int)) +#define DMP1_SIZE_IN_UINT (DMP1_SIZE_IN_BYTES/sizeof(unsigned int)) +#define DMQ1_SIZE_IN_UINT (DMQ1_SIZE_IN_BYTES/sizeof(unsigned int)) +#define IQMP_SIZE_IN_UINT (IQMP_SIZE_IN_BYTES/sizeof(unsigned int)) typedef struct _rsa_params_t { unsigned int n[N_SIZE_IN_UINT]; @@ -778,22 +778,33 @@ extern "C" { */ sgx_status_t sgx_free_rsa_key(void *p_rsa_key, sgx_rsa_key_type_t key_type, int mod_size, int exp_size); - /** Create an ECDSA private key based on input random seed. + /** Generates an ECDSA private key based on input random seed. * * Parameters: * Return: sgx_status_t - SGX_SUCCESS or failure as defined in sgx_error.h - * Inputs: hash_drg - Input seed - * hash_drg_len - Seed len - * sgx_nistp256_r_m1 - - * sgx_nistp256_r_m1_len - nistp256 len - * Output: out_key - ECDSA private key - * out_key_len - ECDSA private key length + * Inputs: hash_drg - Pointer to the input random seed. + * hash_drg_len - Length of the input random seed. + * sgx_nistp256_r_m1 - Pointer to the buffer for n-1 where n is order of the ECC group used. + * sgx_nistp256_r_m1_len - Length for the buffer for nistp256. + * Output: out_key - Pointer to the generated ECDSA private key - BIG ENDIAN + * out_key_len - Length of the prepared buffer for ECDSA private key. * */ sgx_status_t sgx_calculate_ecdsa_priv_key(const unsigned char* hash_drg, int hash_drg_len, const unsigned char* sgx_nistp256_r_m1, int sgx_nistp256_r_m1_len, unsigned char* out_key, int out_key_len); + /** Generates an ECC public key based on a given ECC private key. + * + * Parameters: + * Return: sgx_status_t - SGX_SUCCESS or failure as defined in sgx_error.h + * Input: p_att_priv_key - Input private key + * Output: p_att_pub_key - Output public key - LITTLE ENDIAN + * + */ + sgx_status_t sgx_ecc256_calculate_pub_from_priv(const sgx_ec256_private_t *p_att_priv_key, + sgx_ec256_public_t *p_att_pub_key); + #ifdef __cplusplus } #endif diff --git a/common/src/ipp_bn.cpp b/common/src/ipp_bn.cpp deleted file mode 100644 index 09a9cfdb..00000000 --- a/common/src/ipp_bn.cpp +++ /dev/null @@ -1,125 +0,0 @@ -/* - * Copyright (C) 2011-2018 Intel Corporation. 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 name of Intel 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 - * OWNER 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. - * - */ - - -/** -* File: -* ipp_bn.cpp -*Description: -* Wrappers for Big number generation and free functions -* -*/ - - - -#include "ipp_wrapper.h" - -#include -#include - -#ifndef _TLIBC_CDECL_ -extern "C" int memset_s(void *s, size_t smax, int c, size_t n); -#endif - -extern "C" IppStatus - newBN(const Ipp32u *data, int size_in_bytes, IppsBigNumState **p_new_BN) -{ - IppsBigNumState *pBN=0; - int bn_size = 0; - - if(p_new_BN == NULL || size_in_bytes <= 0 || size_in_bytes % sizeof(Ipp32u)) - return ippStsBadArgErr; - - /* Get the size of the IppsBigNumState context in bytes */ - IppStatus error_code = ippsBigNumGetSize(size_in_bytes/(int)sizeof(Ipp32u), &bn_size); - if(error_code != ippStsNoErr) - { - *p_new_BN = 0; - return error_code; - } - pBN = (IppsBigNumState *) malloc(bn_size); - if(!pBN) - { - error_code = ippStsMemAllocErr; - *p_new_BN = 0; - return error_code; - } - /* Initializes context and partitions allocated buffer */ - error_code = ippsBigNumInit(size_in_bytes/(int)sizeof(Ipp32u), pBN); - if(error_code != ippStsNoErr) - { - SAFE_FREE_MM(pBN); - *p_new_BN = 0; - return error_code; - } - if(data) - { - error_code = ippsSet_BN(IppsBigNumPOS, size_in_bytes/(int)sizeof(Ipp32u), data, pBN); - if(error_code != ippStsNoErr) - { - SAFE_FREE_MM(pBN); - *p_new_BN = 0; - return error_code; - } - } - *p_new_BN = pBN; - return error_code; - -} - - -extern "C" void secure_free_BN(IppsBigNumState *pBN, int size_in_bytes) -{ - if(pBN == NULL || size_in_bytes <= 0 || size_in_bytes % sizeof(Ipp32u)) - { - if(pBN) - { - free(pBN); - } - return; - } - - int bn_size = 0; - - /* Get the size of the IppsBigNumState context in bytes - * Since we have checked the size_in_bytes before and the &bn_size is not NULL, - * ippsBigNumGetSize never returns failure - */ - if(ippsBigNumGetSize(size_in_bytes/(int)sizeof(Ipp32u), &bn_size) != ippStsNoErr) - { - free(pBN); - return; - } - /* Clear the buffer before free. */ - memset_s(pBN, bn_size, 0, bn_size); - free(pBN); - return; -} diff --git a/common/src/ipp_rsa_pub_key.cpp b/common/src/ipp_rsa_pub_key.cpp deleted file mode 100644 index 17f10a29..00000000 --- a/common/src/ipp_rsa_pub_key.cpp +++ /dev/null @@ -1,110 +0,0 @@ -/* - * Copyright (C) 2011-2018 Intel Corporation. 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 name of Intel 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 - * OWNER 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. - * - */ - - -/** -* File: -* ipp_rsa_pub_key.cpp -*Description: -* Wrapper for rsa public key generation and free -* -*/ - -#include "ipp_wrapper.h" - -#include -#include - -#ifndef _TLIBC_CDECL_ -extern "C" int memset_s(void *s, size_t smax, int c, size_t n); -#endif - -extern "C" IppStatus create_rsa_pub_key(int n_byte_size, int e_byte_size, const Ipp32u *n, const Ipp32u *e, IppsRSAPublicKeyState **new_pub_key) -{ - IppsRSAPublicKeyState *p_pub_key = NULL; - IppsBigNumState *p_n = NULL, *p_e = NULL; - int rsa_size = 0; - if(n_byte_size <= 0 || e_byte_size <= 0 || n == NULL || e == NULL || new_pub_key == NULL) - { - return ippStsBadArgErr; - } - - IppStatus error_code = ippStsNoErr; - do{ - error_code = newBN(n, n_byte_size, &p_n); - ERROR_BREAK(error_code); - error_code = newBN(e, e_byte_size, &p_e); - ERROR_BREAK(error_code); - - error_code = ippsRSA_GetSizePublicKey(n_byte_size * 8, e_byte_size * 8, &rsa_size); - ERROR_BREAK(error_code); - p_pub_key = (IppsRSAPublicKeyState *)malloc(rsa_size); - NULL_BREAK(p_pub_key); - error_code = ippsRSA_InitPublicKey(n_byte_size * 8, e_byte_size * 8, p_pub_key, rsa_size); - ERROR_BREAK(error_code); - error_code = ippsRSA_SetPublicKey(p_n, p_e, p_pub_key); - ERROR_BREAK(error_code); - }while(0); - secure_free_BN(p_n, n_byte_size); - secure_free_BN(p_e, e_byte_size); - if(error_code != ippStsNoErr || p_pub_key == NULL) - { - if(error_code == ippStsNoErr ) - error_code = ippStsMemAllocErr; - - secure_free_rsa_pub_key(n_byte_size, e_byte_size, p_pub_key); - return error_code; - } - - *new_pub_key = p_pub_key; - return error_code; - -} - -extern "C" void secure_free_rsa_pub_key(int n_byte_size, int e_byte_size, IppsRSAPublicKeyState *pub_key) -{ - if(n_byte_size <= 0 || e_byte_size <= 0 || pub_key == NULL) - { - if(pub_key) - free(pub_key); - return; - } - int rsa_size = 0; - if(ippsRSA_GetSizePublicKey(n_byte_size * 8, e_byte_size * 8, &rsa_size) != ippStsNoErr) - { - free(pub_key); - return; - } - /* Clear the buffer before free. */ - memset_s(pub_key, rsa_size, 0, rsa_size); - free(pub_key); - return; -} diff --git a/download_prebuilt.sh b/download_prebuilt.sh index 33c9b7a9..5eb6b9eb 100755 --- a/download_prebuilt.sh +++ b/download_prebuilt.sh @@ -33,16 +33,16 @@ top_dir=`dirname $0` out_dir=$top_dir -optlib_name=optimized_libs_2.2.tar.gz -ae_file_name=prebuilt_ae_2.2.tar.gz -checksum_file=SHA256SUM_prebuilt_2.2.txt -server_url_path=https://download.01.org/intel-sgx/linux-2.2/ +optlib_name=optimized_libs_2.3.tar.gz +ae_file_name=prebuilt_ae_2.3.tar.gz +checksum_file=SHA256SUM_prebuilt_2.3.txt +server_url_path=https://download.01.org/intel-sgx/linux-2.3/ server_optlib_url=$server_url_path/$optlib_name server_ae_url=$server_url_path/$ae_file_name server_checksum_url=$server_url_path/$checksum_file rm -f $out_dir/$optlib_name -wget $server_optlib_url -P $out_dir +wget $server_optlib_url -P $out_dir if [ $? -ne 0 ]; then echo "Fail to download file $server_optlib_url" exit -1 diff --git a/external/epid-sdk/epid/common-testhelper/Makefile b/external/epid-sdk/epid/common-testhelper/Makefile index 1b9559b1..103813ad 100644 --- a/external/epid-sdk/epid/common-testhelper/Makefile +++ b/external/epid-sdk/epid/common-testhelper/Makefile @@ -9,8 +9,8 @@ COMMON_TESTHELPER_11_INCLUDE_DIR = ../../1.1 COMMON_TESTHELPER_SRC = $(wildcard ./*.cc) COMMON_TESTHELPER_SRC += $(wildcard ./1.1/*.cc) COMMON_TESTHELPER_UTEST_SRC = $(wildcard ./unittests/*.cc) -COMMON_TESTHELPER_OBJ = $(COMMON_TESTHELPER_SRC:.cc=.o) -COMMON_TESTHELPER_UTEST_OBJ = $(COMMON_TESTHELPER_UTEST_SRC:.cc=.o) +COMMON_TESTHELPER_OBJ = $(sort $(COMMON_TESTHELPER_SRC:.cc=.o)) +COMMON_TESTHELPER_UTEST_OBJ = $(sort $(COMMON_TESTHELPER_UTEST_SRC:.cc=.o)) COMMON_TESTHELPER_LIB = ./libcommon-testhelper.a COMMON_TESTHELPER_UTEST_EXE = ./unittests/common-testhelper-utest$(EXE_EXTENSION) diff --git a/external/epid-sdk/epid/common/Makefile b/external/epid-sdk/epid/common/Makefile index 4dfe984a..0d9d9e31 100644 --- a/external/epid-sdk/epid/common/Makefile +++ b/external/epid-sdk/epid/common/Makefile @@ -18,14 +18,14 @@ COMMON_MATH_INCLUDE_DIR = ./math COMMON_SRC = $(wildcard ./src/*.c) COMMON_SRC += $(wildcard ./math/src/*.c) COMMON_SRC += $(wildcard ./1.1/src/*.c) -COMMON_OBJ = $(COMMON_SRC:.c=.o) +COMMON_OBJ = $(sort $(COMMON_SRC:.c=.o)) COMMON_LIB = ./libcommon.a COMMON_UTEST_EXE = ./common-utest$(EXE_EXTENSION) COMMON_UTEST_SRC = $(wildcard ./math/unittests/*.cc) COMMON_UTEST_SRC += $(wildcard ./unittests/*.cc) COMMON_UTEST_SRC += $(wildcard ./1.1/unittests/*.cc) -COMMON_UTEST_OBJ = $(COMMON_UTEST_SRC:.cc=.o) +COMMON_UTEST_OBJ = $(sort $(COMMON_UTEST_SRC:.cc=.o)) LIB_COMMON_DIR = . LIB_COMMON_TESTHELPER_DIR = ../common-testhelper LIB_IPPCP_DIR = ../../ext/ipp/sources/ippcp/src diff --git a/external/epid-sdk/epid/member/Makefile b/external/epid-sdk/epid/member/Makefile index 29e0cf35..d56e708f 100644 --- a/external/epid-sdk/epid/member/Makefile +++ b/external/epid-sdk/epid/member/Makefile @@ -42,16 +42,16 @@ MEMBER_UTEST_SRC = $(wildcard ./unittests/*.cc) \ TINY_MEMBER_UTEST_SRC = $(wildcard ./tiny/unittests/*.cc) TINY_MEMBER_MATH_UTEST_SRC = $(wildcard ./tiny/math/unittests/*.cc) ifneq ($(TINY),) - MEMBER_OBJ = $(TINY_MEMBER_SRC:.c=.o) - MATH_OBJ = $(TINY_MEMBER_MATH_SRC:.c=.o) - STDLIB_OBJ = $(TINY_STDLIB_MEMBER_SRC:.c=.o) - MEMBER_UTEST_OBJ = $(TINY_MEMBER_UTEST_SRC:.cc=.o) - TINY_MEMBER_MATH_UTEST_OBJ = $(TINY_MEMBER_MATH_UTEST_SRC:.cc=.o) + MEMBER_OBJ = $(sort $(TINY_MEMBER_SRC:.c=.o)) + MATH_OBJ = $(sort $(TINY_MEMBER_MATH_SRC:.c=.o)) + STDLIB_OBJ = $(sort $(TINY_STDLIB_MEMBER_SRC:.c=.o)) + MEMBER_UTEST_OBJ = $(sort $(TINY_MEMBER_UTEST_SRC:.cc=.o)) + TINY_MEMBER_MATH_UTEST_OBJ = $(sort $(TINY_MEMBER_MATH_UTEST_SRC:.cc=.o)) MEMBER_INCLUDE_DIR += -I$(TINY_MEMBER_INCLUDE_DIR) else - MEMBER_OBJ = $(MEMBER_SRC:.c=.o) - MEMBER_UTEST_OBJ = $(MEMBER_UTEST_SRC:.cc=.o) - MEMBER_TPM2_UTEST_OBJ = $(MEMBER_TPM2_UTEST_SRC:.cc=.o) + MEMBER_OBJ = $(sort $(MEMBER_SRC:.c=.o)) + MEMBER_UTEST_OBJ = $(sort $(MEMBER_UTEST_SRC:.cc=.o)) + MEMBER_TPM2_UTEST_OBJ = $(sort $(MEMBER_TPM2_UTEST_SRC:.cc=.o)) endif LIB_MEMBER_DIR = . diff --git a/external/epid-sdk/epid/verifier/Makefile b/external/epid-sdk/epid/verifier/Makefile index ee3386bf..6f64d67e 100644 --- a/external/epid-sdk/epid/verifier/Makefile +++ b/external/epid-sdk/epid/verifier/Makefile @@ -19,13 +19,13 @@ VERIFIER_11_INCLUDE_DIR = ../../1.1 VERIFIER_SRC = $(wildcard ./src/*.c) VERIFIER_SRC += $(wildcard ./1.1/src/*.c) -VERIFIER_OBJ = $(VERIFIER_SRC:.c=.o) +VERIFIER_OBJ = $(sort $(VERIFIER_SRC:.c=.o)) VERIFIER_LIB = ./libverifier.a VERIFIER_UTEST_EXE = ./verifier-utest$(EXE_EXTENSION) VERIFIER_UTEST_SRC = $(wildcard ./unittests/*.cc) VERIFIER_UTEST_SRC += $(wildcard ./1.1/unittests/*.cc) -VERIFIER_UTEST_OBJ = $(VERIFIER_UTEST_SRC:.cc=.o) +VERIFIER_UTEST_OBJ = $(sort $(VERIFIER_UTEST_SRC:.cc=.o)) LIB_VERIFIER_DIR = . LIB_COMMON_TESTHELPER_DIR = ../common-testhelper LIB_COMMON_DIR = ../common diff --git a/external/epid-sdk/example/Makefile b/external/epid-sdk/example/Makefile index 5ee6f069..e9ee44af 100644 --- a/external/epid-sdk/example/Makefile +++ b/external/epid-sdk/example/Makefile @@ -7,12 +7,12 @@ COMPRESSED_DEFAULT_FILES_INSTALL_DIR = $(epidinstalldir)/compressed_example SIGNMSG_INCLUDE_DIR = ./signmsg SIGNMSG_SRC = $(wildcard ./signmsg/src/*.c) -SIGNMSG_OBJ = $(SIGNMSG_SRC:.c=.o) +SIGNMSG_OBJ = $(sort $(SIGNMSG_SRC:.c=.o)) SIGNMSG_EXE = ./signmsg/src/signmsg$(EXE_EXTENSION) VERIFYSIG_INCLUDE_DIR = ./verifysig VERIFYSIG_SRC = $(wildcard ./verifysig/src/*.c) -VERIFYSIG_OBJ = $(VERIFYSIG_SRC:.c=.o) +VERIFYSIG_OBJ = $(sort $(VERIFYSIG_SRC:.c=.o)) VERIFYSIG_EXE = ./verifysig/src/verifysig$(EXE_EXTENSION) diff --git a/external/epid-sdk/ext/argtable3/Makefile b/external/epid-sdk/ext/argtable3/Makefile index db761277..afa53361 100644 --- a/external/epid-sdk/ext/argtable3/Makefile +++ b/external/epid-sdk/ext/argtable3/Makefile @@ -1,7 +1,7 @@ #!/usr/bin/make -f ARGTABLE_SRC = $(wildcard *.c) -ARGTABLE_OBJ = $(ARGTABLE_SRC:.c=.o) +ARGTABLE_OBJ = $(sort $(ARGTABLE_SRC:.c=.o)) ARGTABLE_LIB = libargtable3.a diff --git a/external/sgxssl/prepare_sgxssl.sh b/external/sgxssl/prepare_sgxssl.sh index f1055252..61e29ee1 100755 --- a/external/sgxssl/prepare_sgxssl.sh +++ b/external/sgxssl/prepare_sgxssl.sh @@ -43,14 +43,15 @@ full_openssl_url_old=$server_url_path/old/1.1.0/$openssl_ver_name.tar.gz sgxssl_chksum=e2ad431ef7ef1377d1d91266ac95e1dd2e83b2491e91bbb5460e8b043a169ab7 openssl_chksum=5835626cde9e99656585fc7aaa2302a73a7e1340bf8c14fd635a62c66802a517 +rm -f check_sum_sgxssl.txt check_sum_openssl.txt if [ ! -f $build_script ]; then wget $sgxssl_github_archive/$sgxssl_ver_name.zip -P $top_dir || exit 1 sha256sum $top_dir/$sgxssl_ver_name.zip > check_sum_sgxssl.txt grep $sgxssl_chksum check_sum_sgxssl.txt if [ $? -ne 0 ]; then - echo "File $top_dir/$sgxssl_ver_name.zip checksum failure" - rm -f $top_dir/$sgxssl_ver_name.zip check_sum_sgxssl.txt - exit -1 + echo "File $top_dir/$sgxssl_ver_name.zip checksum failure" + rm -f $top_dir/$sgxssl_ver_name.zip + exit -1 fi unzip -qq $top_dir/$sgxssl_ver_name.zip -d $top_dir || exit 1 mv $top_dir/intel-sgx-ssl-$sgxssl_ver/* $top_dir || exit 1 @@ -62,13 +63,12 @@ if [ ! -f $openssl_out_dir/$openssl_ver_name.tar.gz ]; then wget $full_openssl_url_old -P $openssl_out_dir || wget $full_openssl_url -P $openssl_out_dir || exit 1 sha256sum $openssl_out_dir/$openssl_ver_name.tar.gz > check_sum_openssl.txt grep $openssl_chksum check_sum_openssl.txt - if [ $? -ne 0 ]; then - echo "File $openssl_out_dir/$openssl_ver_name.tar.gz checksum failure" - rm -f $openssl_out_dir/$openssl_ver_name.tar.gz check_sum_openssl.txt - exit -1 + if [ $? -ne 0 ]; then + echo "File $openssl_out_dir/$openssl_ver_name.tar.gz checksum failure" + rm -f $openssl_out_dir/$openssl_ver_name.tar.gz + exit -1 fi fi -rm -f check_sum_sgxssl.txt check_sum_openssl.txt pushd $top_dir/Linux/ make clean all LINUX_SGX_BUILD=1 diff --git a/external/tinyxml2/tinyxml2.cpp b/external/tinyxml2/tinyxml2.cpp index 745f7155..b27612e9 100644 --- a/external/tinyxml2/tinyxml2.cpp +++ b/external/tinyxml2/tinyxml2.cpp @@ -149,6 +149,7 @@ void StrPair::TransferTo( StrPair* other ) // This in effect implements the assignment operator by "moving" // ownership (as in auto_ptr). + TIXMLASSERT( other != 0 ); TIXMLASSERT( other->_flags == 0 ); TIXMLASSERT( other->_start == 0 ); TIXMLASSERT( other->_end == 0 ); @@ -164,6 +165,7 @@ void StrPair::TransferTo( StrPair* other ) _end = 0; } + void StrPair::Reset() { if ( _flags & NEEDS_DELETE ) { @@ -188,9 +190,11 @@ void StrPair::SetStr( const char* str, int flags ) } -char* StrPair::ParseText( char* p, const char* endTag, int strFlags ) +char* StrPair::ParseText( char* p, const char* endTag, int strFlags, int* curLineNumPtr ) { + TIXMLASSERT( p ); TIXMLASSERT( endTag && *endTag ); + TIXMLASSERT(curLineNumPtr); char* start = p; char endChar = *endTag; @@ -201,8 +205,11 @@ char* StrPair::ParseText( char* p, const char* endTag, int strFlags ) if ( *p == endChar && strncmp( p, endTag, length ) == 0 ) { Set( start, p, strFlags ); return p + length; + } else if (*p == '\n') { + ++(*curLineNumPtr); } ++p; + TIXMLASSERT( p ); } return 0; } @@ -233,15 +240,15 @@ void StrPair::CollapseWhitespace() // Adjusting _start would cause undefined behavior on delete[] TIXMLASSERT( ( _flags & NEEDS_DELETE ) == 0 ); // Trim leading space. - _start = XMLUtil::SkipWhiteSpace( _start ); + _start = XMLUtil::SkipWhiteSpace( _start, 0 ); if ( *_start ) { - char* p = _start; // the read pointer + const char* p = _start; // the read pointer char* q = _start; // the write pointer while( *p ) { if ( XMLUtil::IsWhiteSpace( *p )) { - p = XMLUtil::SkipWhiteSpace( p ); + p = XMLUtil::SkipWhiteSpace( p, 0 ); if ( *p == 0 ) { break; // don't write to q; this trims the trailing space. } @@ -266,7 +273,7 @@ const char* StrPair::GetStr() _flags ^= NEEDS_FLUSH; if ( _flags ) { - char* p = _start; // the read pointer + const char* p = _start; // the read pointer char* q = _start; // the write pointer while( p < _end ) { @@ -280,7 +287,8 @@ const char* StrPair::GetStr() else { ++p; } - *q++ = LF; + *q = LF; + ++q; } else if ( (_flags & NEEDS_NEWLINE_NORMALIZATION) && *p == LF ) { if ( *(p+1) == CR ) { @@ -289,7 +297,8 @@ const char* StrPair::GetStr() else { ++p; } - *q++ = LF; + *q = LF; + ++q; } else if ( (_flags & NEEDS_ENTITY_PROCESSING) && *p == '&' ) { // Entities handled by tinyXML2: @@ -360,6 +369,19 @@ const char* StrPair::GetStr() // --------- XMLUtil ----------- // +const char* XMLUtil::writeBoolTrue = "true"; +const char* XMLUtil::writeBoolFalse = "false"; + +void XMLUtil::SetBoolSerialization(const char* writeTrue, const char* writeFalse) +{ + static const char* defTrue = "true"; + static const char* defFalse = "false"; + + writeBoolTrue = (writeTrue) ? writeTrue : defTrue; + writeBoolFalse = (writeFalse) ? writeFalse : defFalse; +} + + const char* XMLUtil::ReadBOM( const char* p, bool* bom ) { TIXMLASSERT( p ); @@ -403,23 +425,24 @@ void XMLUtil::ConvertUTF32ToUTF8( unsigned long input, char* output, int* length output += *length; - // Scary scary fall throughs. + // Scary scary fall throughs are annotated with carefully designed comments + // to suppress compiler warnings such as -Wimplicit-fallthrough in gcc switch (*length) { case 4: --output; *output = (char)((input | BYTE_MARK) & BYTE_MASK); input >>= 6; - /* fallthrough */ + //fall through case 3: --output; *output = (char)((input | BYTE_MARK) & BYTE_MASK); input >>= 6; - /* fallthrough */ + //fall through case 2: --output; *output = (char)((input | BYTE_MARK) & BYTE_MASK); input >>= 6; - /* fallthrough */ + //fall through case 1: --output; *output = (char)(input | FIRST_BYTE_MARK[*length]); @@ -540,7 +563,7 @@ void XMLUtil::ToStr( unsigned v, char* buffer, int bufferSize ) void XMLUtil::ToStr( bool v, char* buffer, int bufferSize ) { - TIXML_SNPRINTF( buffer, bufferSize, "%d", v ? 1 : 0 ); + TIXML_SNPRINTF( buffer, bufferSize, "%s", v ? writeBoolTrue : writeBoolFalse); } /* @@ -635,7 +658,8 @@ char* XMLDocument::Identify( char* p, XMLNode** node ) TIXMLASSERT( node ); TIXMLASSERT( p ); char* const start = p; - p = XMLUtil::SkipWhiteSpace( p ); + int const startLine = _parseCurLineNum; + p = XMLUtil::SkipWhiteSpace( p, &_parseCurLineNum ); if( !*p ) { *node = 0; TIXMLASSERT( p ); @@ -659,42 +683,37 @@ char* XMLDocument::Identify( char* p, XMLNode** node ) TIXMLASSERT( sizeof( XMLComment ) == sizeof( XMLDeclaration ) ); // use same memory pool XMLNode* returnNode = 0; if ( XMLUtil::StringEqual( p, xmlHeader, xmlHeaderLen ) ) { - TIXMLASSERT( sizeof( XMLDeclaration ) == _commentPool.ItemSize() ); - returnNode = new (_commentPool.Alloc()) XMLDeclaration( this ); - returnNode->_memPool = &_commentPool; + returnNode = CreateUnlinkedNode( _commentPool ); + returnNode->_parseLineNum = _parseCurLineNum; p += xmlHeaderLen; } else if ( XMLUtil::StringEqual( p, commentHeader, commentHeaderLen ) ) { - TIXMLASSERT( sizeof( XMLComment ) == _commentPool.ItemSize() ); - returnNode = new (_commentPool.Alloc()) XMLComment( this ); - returnNode->_memPool = &_commentPool; + returnNode = CreateUnlinkedNode( _commentPool ); + returnNode->_parseLineNum = _parseCurLineNum; p += commentHeaderLen; } else if ( XMLUtil::StringEqual( p, cdataHeader, cdataHeaderLen ) ) { - TIXMLASSERT( sizeof( XMLText ) == _textPool.ItemSize() ); - XMLText* text = new (_textPool.Alloc()) XMLText( this ); + XMLText* text = CreateUnlinkedNode( _textPool ); returnNode = text; - returnNode->_memPool = &_textPool; + returnNode->_parseLineNum = _parseCurLineNum; p += cdataHeaderLen; text->SetCData( true ); } else if ( XMLUtil::StringEqual( p, dtdHeader, dtdHeaderLen ) ) { - TIXMLASSERT( sizeof( XMLUnknown ) == _commentPool.ItemSize() ); - returnNode = new (_commentPool.Alloc()) XMLUnknown( this ); - returnNode->_memPool = &_commentPool; + returnNode = CreateUnlinkedNode( _commentPool ); + returnNode->_parseLineNum = _parseCurLineNum; p += dtdHeaderLen; } else if ( XMLUtil::StringEqual( p, elementHeader, elementHeaderLen ) ) { - TIXMLASSERT( sizeof( XMLElement ) == _elementPool.ItemSize() ); - returnNode = new (_elementPool.Alloc()) XMLElement( this ); - returnNode->_memPool = &_elementPool; + returnNode = CreateUnlinkedNode( _elementPool ); + returnNode->_parseLineNum = _parseCurLineNum; p += elementHeaderLen; } else { - TIXMLASSERT( sizeof( XMLText ) == _textPool.ItemSize() ); - returnNode = new (_textPool.Alloc()) XMLText( this ); - returnNode->_memPool = &_textPool; + returnNode = CreateUnlinkedNode( _textPool ); + returnNode->_parseLineNum = _parseCurLineNum; // Report line of first non-whitespace character p = start; // Back it up, all the text counts. + _parseCurLineNum = startLine; } TIXMLASSERT( returnNode ); @@ -723,6 +742,8 @@ bool XMLDocument::Accept( XMLVisitor* visitor ) const XMLNode::XMLNode( XMLDocument* doc ) : _document( doc ), _parent( 0 ), + _value(), + _parseLineNum( 0 ), _firstChild( 0 ), _lastChild( 0 ), _prev( 0 ), _next( 0 ), _userData( 0 ), @@ -739,9 +760,9 @@ XMLNode::~XMLNode() } } -const char* XMLNode::Value() const +const char* XMLNode::Value() const { - // Catch an edge case: XMLDocuments don't have a a Value. Carefully return nullptr. + // Edge case: XMLDocuments don't have a Value. Return null. if ( this->ToDocument() ) return 0; return _value.GetStr(); @@ -757,16 +778,24 @@ void XMLNode::SetValue( const char* str, bool staticMem ) } } +XMLNode* XMLNode::DeepClone(XMLDocument* target) const +{ + XMLNode* clone = this->ShallowClone(target); + if (!clone) return 0; + + for (const XMLNode* child = this->FirstChild(); child; child = child->NextSibling()) { + XMLNode* childClone = child->DeepClone(target); + TIXMLASSERT(childClone); + clone->InsertEndChild(childClone); + } + return clone; +} void XMLNode::DeleteChildren() { while( _firstChild ) { TIXMLASSERT( _lastChild ); - TIXMLASSERT( _firstChild->_document == _document ); - XMLNode* node = _firstChild; - Unlink( node ); - - DeleteNode( node ); + DeleteChild( _firstChild ); } _firstChild = _lastChild = 0; } @@ -790,6 +819,8 @@ void XMLNode::Unlink( XMLNode* child ) if ( child->_next ) { child->_next->_prev = child->_prev; } + child->_next = 0; + child->_prev = 0; child->_parent = 0; } @@ -800,6 +831,9 @@ void XMLNode::DeleteChild( XMLNode* node ) TIXMLASSERT( node->_document == _document ); TIXMLASSERT( node->_parent == this ); Unlink( node ); + TIXMLASSERT(node->_prev == 0); + TIXMLASSERT(node->_next == 0); + TIXMLASSERT(node->_parent == 0); DeleteNode( node ); } @@ -879,6 +913,13 @@ XMLNode* XMLNode::InsertAfterChild( XMLNode* afterThis, XMLNode* addThis ) TIXMLASSERT( false ); return 0; } + if ( afterThis == addThis ) { + // Current state: BeforeThis -> AddThis -> OneAfterAddThis + // Now AddThis must disappear from it's location and then + // reappear between BeforeThis and OneAfterAddThis. + // So just leave it where it is. + return addThis; + } if ( afterThis->_next == 0 ) { // The last node or the only node. @@ -899,11 +940,9 @@ XMLNode* XMLNode::InsertAfterChild( XMLNode* afterThis, XMLNode* addThis ) const XMLElement* XMLNode::FirstChildElement( const char* name ) const { for( const XMLNode* node = _firstChild; node; node = node->_next ) { - const XMLElement* element = node->ToElement(); + const XMLElement* element = node->ToElementWithName( name ); if ( element ) { - if ( !name || XMLUtil::StringEqual( element->Name(), name ) ) { - return element; - } + return element; } } return 0; @@ -913,11 +952,9 @@ const XMLElement* XMLNode::FirstChildElement( const char* name ) const const XMLElement* XMLNode::LastChildElement( const char* name ) const { for( const XMLNode* node = _lastChild; node; node = node->_prev ) { - const XMLElement* element = node->ToElement(); + const XMLElement* element = node->ToElementWithName( name ); if ( element ) { - if ( !name || XMLUtil::StringEqual( element->Name(), name ) ) { - return element; - } + return element; } } return 0; @@ -927,9 +964,8 @@ const XMLElement* XMLNode::LastChildElement( const char* name ) const const XMLElement* XMLNode::NextSiblingElement( const char* name ) const { for( const XMLNode* node = _next; node; node = node->_next ) { - const XMLElement* element = node->ToElement(); - if ( element - && (!name || XMLUtil::StringEqual( name, element->Name() ))) { + const XMLElement* element = node->ToElementWithName( name ); + if ( element ) { return element; } } @@ -940,9 +976,8 @@ const XMLElement* XMLNode::NextSiblingElement( const char* name ) const const XMLElement* XMLNode::PreviousSiblingElement( const char* name ) const { for( const XMLNode* node = _prev; node; node = node->_prev ) { - const XMLElement* element = node->ToElement(); - if ( element - && (!name || XMLUtil::StringEqual( name, element->Name() ))) { + const XMLElement* element = node->ToElementWithName( name ); + if ( element ) { return element; } } @@ -950,7 +985,7 @@ const XMLElement* XMLNode::PreviousSiblingElement( const char* name ) const } -char* XMLNode::ParseDeep( char* p, StrPair* parentEnd ) +char* XMLNode::ParseDeep( char* p, StrPair* parentEndTag, int* curLineNumPtr ) { // This is a recursive method, but thinking about it "at the current level" // it is a pretty simple flat list: @@ -969,41 +1004,58 @@ char* XMLNode::ParseDeep( char* p, StrPair* parentEnd ) // 'endTag' is the end tag for this node, it is returned by a call to a child. // 'parentEnd' is the end tag for the parent, which is filled in and returned. - while( p && *p ) { + XMLDocument::DepthTracker tracker(_document); + if (_document->Error()) + return 0; + + while( p && *p ) { XMLNode* node = 0; p = _document->Identify( p, &node ); + TIXMLASSERT( p ); if ( node == 0 ) { break; } + int initialLineNum = node->_parseLineNum; + StrPair endTag; - p = node->ParseDeep( p, &endTag ); + p = node->ParseDeep( p, &endTag, curLineNumPtr ); if ( !p ) { DeleteNode( node ); if ( !_document->Error() ) { - _document->SetError( XML_ERROR_PARSING, 0, 0 ); + _document->SetError( XML_ERROR_PARSING, initialLineNum, 0); } break; } XMLDeclaration* decl = node->ToDeclaration(); if ( decl ) { - // A declaration can only be the first child of a document. - // Set error, if document already has children. - if ( !_document->NoChildren() ) { - _document->SetError( XML_ERROR_PARSING_DECLARATION, decl->Value(), 0); - DeleteNode( decl ); + // Declarations are only allowed at document level + bool wellLocated = ( ToDocument() != 0 ); + if ( wellLocated ) { + // Multiple declarations are allowed but all declarations + // must occur before anything else + for ( const XMLNode* existingNode = _document->FirstChild(); existingNode; existingNode = existingNode->NextSibling() ) { + if ( !existingNode->ToDeclaration() ) { + wellLocated = false; break; + } } + } + if ( !wellLocated ) { + _document->SetError( XML_ERROR_PARSING_DECLARATION, initialLineNum, "XMLDeclaration value=%s", decl->Value()); + DeleteNode( node ); + break; + } } XMLElement* ele = node->ToElement(); if ( ele ) { // We read the end tag. Return it to the parent. if ( ele->ClosingType() == XMLElement::CLOSING ) { - if ( parentEnd ) { - ele->_value.TransferTo( parentEnd ); + if ( parentEndTag ) { + ele->_value.TransferTo( parentEndTag ); } node->_memPool->SetTracked(); // created and then immediately deleted. DeleteNode( node ); @@ -1027,7 +1079,7 @@ char* XMLNode::ParseDeep( char* p, StrPair* parentEnd ) } } if ( mismatch ) { - _document->SetError( XML_ERROR_MISMATCHED_ELEMENT, ele->Name(), 0 ); + _document->SetError( XML_ERROR_MISMATCHED_ELEMENT, initialLineNum, "XMLElement name=%s", ele->Name()); DeleteNode( node ); break; } @@ -1037,11 +1089,16 @@ char* XMLNode::ParseDeep( char* p, StrPair* parentEnd ) return 0; } -void XMLNode::DeleteNode( XMLNode* node ) +/*static*/ void XMLNode::DeleteNode( XMLNode* node ) { if ( node == 0 ) { return; } + TIXMLASSERT(node->_document); + if (!node->ToDocument()) { + node->_document->MarkInUse(node); + } + MemPool* pool = node->_memPool; node->~XMLNode(); pool->Free( node ); @@ -1052,20 +1109,37 @@ void XMLNode::InsertChildPreamble( XMLNode* insertThis ) const TIXMLASSERT( insertThis ); TIXMLASSERT( insertThis->_document == _document ); - if ( insertThis->_parent ) + if (insertThis->_parent) { insertThis->_parent->Unlink( insertThis ); - else + } + else { + insertThis->_document->MarkInUse(insertThis); insertThis->_memPool->SetTracked(); + } +} + +const XMLElement* XMLNode::ToElementWithName( const char* name ) const +{ + const XMLElement* element = this->ToElement(); + if ( element == 0 ) { + return 0; + } + if ( name == 0 ) { + return element; + } + if ( XMLUtil::StringEqual( element->Name(), name ) ) { + return element; + } + return 0; } // --------- XMLText ---------- // -char* XMLText::ParseDeep( char* p, StrPair* ) +char* XMLText::ParseDeep( char* p, StrPair*, int* curLineNumPtr ) { - const char* start = p; if ( this->CData() ) { - p = _value.ParseText( p, "]]>", StrPair::NEEDS_NEWLINE_NORMALIZATION ); + p = _value.ParseText( p, "]]>", StrPair::NEEDS_NEWLINE_NORMALIZATION, curLineNumPtr ); if ( !p ) { - _document->SetError( XML_ERROR_PARSING_CDATA, start, 0 ); + _document->SetError( XML_ERROR_PARSING_CDATA, _parseLineNum, 0 ); } return p; } @@ -1075,12 +1149,12 @@ char* XMLText::ParseDeep( char* p, StrPair* ) flags |= StrPair::NEEDS_WHITESPACE_COLLAPSING; } - p = _value.ParseText( p, "<", flags ); + p = _value.ParseText( p, "<", flags, curLineNumPtr ); if ( p && *p ) { return p-1; } if ( !p ) { - _document->SetError( XML_ERROR_PARSING_TEXT, start, 0 ); + _document->SetError( XML_ERROR_PARSING_TEXT, _parseLineNum, 0 ); } } return 0; @@ -1100,6 +1174,7 @@ XMLNode* XMLText::ShallowClone( XMLDocument* doc ) const bool XMLText::ShallowEqual( const XMLNode* compare ) const { + TIXMLASSERT( compare ); const XMLText* text = compare->ToText(); return ( text && XMLUtil::StringEqual( text->Value(), Value() ) ); } @@ -1124,13 +1199,12 @@ XMLComment::~XMLComment() } -char* XMLComment::ParseDeep( char* p, StrPair* ) +char* XMLComment::ParseDeep( char* p, StrPair*, int* curLineNumPtr ) { // Comment parses as text. - const char* start = p; - p = _value.ParseText( p, "-->", StrPair::COMMENT ); + p = _value.ParseText( p, "-->", StrPair::COMMENT, curLineNumPtr ); if ( p == 0 ) { - _document->SetError( XML_ERROR_PARSING_COMMENT, start, 0 ); + _document->SetError( XML_ERROR_PARSING_COMMENT, _parseLineNum, 0 ); } return p; } @@ -1174,13 +1248,12 @@ XMLDeclaration::~XMLDeclaration() } -char* XMLDeclaration::ParseDeep( char* p, StrPair* ) +char* XMLDeclaration::ParseDeep( char* p, StrPair*, int* curLineNumPtr ) { // Declaration parses as text. - const char* start = p; - p = _value.ParseText( p, "?>", StrPair::NEEDS_NEWLINE_NORMALIZATION ); + p = _value.ParseText( p, "?>", StrPair::NEEDS_NEWLINE_NORMALIZATION, curLineNumPtr ); if ( p == 0 ) { - _document->SetError( XML_ERROR_PARSING_DECLARATION, start, 0 ); + _document->SetError( XML_ERROR_PARSING_DECLARATION, _parseLineNum, 0 ); } return p; } @@ -1223,14 +1296,12 @@ XMLUnknown::~XMLUnknown() } -char* XMLUnknown::ParseDeep( char* p, StrPair* ) +char* XMLUnknown::ParseDeep( char* p, StrPair*, int* curLineNumPtr ) { // Unknown parses as text. - const char* start = p; - - p = _value.ParseText( p, ">", StrPair::NEEDS_NEWLINE_NORMALIZATION ); + p = _value.ParseText( p, ">", StrPair::NEEDS_NEWLINE_NORMALIZATION, curLineNumPtr ); if ( !p ) { - _document->SetError( XML_ERROR_PARSING_UNKNOWN, start, 0 ); + _document->SetError( XML_ERROR_PARSING_UNKNOWN, _parseLineNum, 0 ); } return p; } @@ -1262,17 +1333,17 @@ bool XMLUnknown::Accept( XMLVisitor* visitor ) const // --------- XMLAttribute ---------- // -const char* XMLAttribute::Name() const +const char* XMLAttribute::Name() const { return _name.GetStr(); } -const char* XMLAttribute::Value() const +const char* XMLAttribute::Value() const { return _value.GetStr(); } -char* XMLAttribute::ParseDeep( char* p, bool processEntities ) +char* XMLAttribute::ParseDeep( char* p, bool processEntities, int* curLineNumPtr ) { // Parse using the name rules: bug fix, was using ParseText before p = _name.ParseName( p ); @@ -1281,13 +1352,13 @@ char* XMLAttribute::ParseDeep( char* p, bool processEntities ) } // Skip white space before = - p = XMLUtil::SkipWhiteSpace( p ); + p = XMLUtil::SkipWhiteSpace( p, curLineNumPtr ); if ( *p != '=' ) { return 0; } ++p; // move up to opening quote - p = XMLUtil::SkipWhiteSpace( p ); + p = XMLUtil::SkipWhiteSpace( p, curLineNumPtr ); if ( *p != '\"' && *p != '\'' ) { return 0; } @@ -1295,7 +1366,7 @@ char* XMLAttribute::ParseDeep( char* p, bool processEntities ) char endTag[2] = { *p, 0 }; ++p; // move past opening quote - p = _value.ParseText( p, endTag, processEntities ? StrPair::ATTRIBUTE_VALUE : StrPair::ATTRIBUTE_VALUE_LEAVE_ENTITIES ); + p = _value.ParseText( p, endTag, processEntities ? StrPair::ATTRIBUTE_VALUE : StrPair::ATTRIBUTE_VALUE_LEAVE_ENTITIES, curLineNumPtr ); return p; } @@ -1415,7 +1486,7 @@ void XMLAttribute::SetAttribute( float v ) // --------- XMLElement ---------- // XMLElement::XMLElement( XMLDocument* doc ) : XMLNode( doc ), - _closingType( 0 ), + _closingType( OPEN ), _rootAttribute( 0 ) { } @@ -1454,6 +1525,47 @@ const char* XMLElement::Attribute( const char* name, const char* value ) const return 0; } +int XMLElement::IntAttribute(const char* name, int defaultValue) const +{ + int i = defaultValue; + QueryIntAttribute(name, &i); + return i; +} + +unsigned XMLElement::UnsignedAttribute(const char* name, unsigned defaultValue) const +{ + unsigned i = defaultValue; + QueryUnsignedAttribute(name, &i); + return i; +} + +int64_t XMLElement::Int64Attribute(const char* name, int64_t defaultValue) const +{ + int64_t i = defaultValue; + QueryInt64Attribute(name, &i); + return i; +} + +bool XMLElement::BoolAttribute(const char* name, bool defaultValue) const +{ + bool b = defaultValue; + QueryBoolAttribute(name, &b); + return b; +} + +double XMLElement::DoubleAttribute(const char* name, double defaultValue) const +{ + double d = defaultValue; + QueryDoubleAttribute(name, &d); + return d; +} + +float XMLElement::FloatAttribute(const char* name, float defaultValue) const +{ + float f = defaultValue; + QueryFloatAttribute(name, &f); + return f; +} const char* XMLElement::GetText() const { @@ -1475,7 +1587,7 @@ void XMLElement::SetText( const char* inText ) } -void XMLElement::SetText( int v ) +void XMLElement::SetText( int v ) { char buf[BUF_SIZE]; XMLUtil::ToStr( v, buf, BUF_SIZE ); @@ -1483,7 +1595,7 @@ void XMLElement::SetText( int v ) } -void XMLElement::SetText( unsigned v ) +void XMLElement::SetText( unsigned v ) { char buf[BUF_SIZE]; XMLUtil::ToStr( v, buf, BUF_SIZE ); @@ -1507,7 +1619,7 @@ void XMLElement::SetText( bool v ) } -void XMLElement::SetText( float v ) +void XMLElement::SetText( float v ) { char buf[BUF_SIZE]; XMLUtil::ToStr( v, buf, BUF_SIZE ); @@ -1515,7 +1627,7 @@ void XMLElement::SetText( float v ) } -void XMLElement::SetText( double v ) +void XMLElement::SetText( double v ) { char buf[BUF_SIZE]; XMLUtil::ToStr( v, buf, BUF_SIZE ); @@ -1600,6 +1712,47 @@ XMLError XMLElement::QueryFloatText( float* fval ) const return XML_NO_TEXT_NODE; } +int XMLElement::IntText(int defaultValue) const +{ + int i = defaultValue; + QueryIntText(&i); + return i; +} + +unsigned XMLElement::UnsignedText(unsigned defaultValue) const +{ + unsigned i = defaultValue; + QueryUnsignedText(&i); + return i; +} + +int64_t XMLElement::Int64Text(int64_t defaultValue) const +{ + int64_t i = defaultValue; + QueryInt64Text(&i); + return i; +} + +bool XMLElement::BoolText(bool defaultValue) const +{ + bool b = defaultValue; + QueryBoolText(&b); + return b; +} + +double XMLElement::DoubleText(double defaultValue) const +{ + double d = defaultValue; + QueryDoubleText(&d); + return d; +} + +float XMLElement::FloatText(float defaultValue) const +{ + float f = defaultValue; + QueryFloatText(&f); + return f; +} XMLAttribute* XMLElement::FindOrCreateAttribute( const char* name ) @@ -1614,17 +1767,17 @@ XMLAttribute* XMLElement::FindOrCreateAttribute( const char* name ) } } if ( !attrib ) { - TIXMLASSERT( sizeof( XMLAttribute ) == _document->_attributePool.ItemSize() ); - attrib = new (_document->_attributePool.Alloc() ) XMLAttribute(); - attrib->_memPool = &_document->_attributePool; + attrib = CreateAttribute(); + TIXMLASSERT( attrib ); if ( last ) { + TIXMLASSERT( last->_next == 0 ); last->_next = attrib; } else { + TIXMLASSERT( _rootAttribute == 0 ); _rootAttribute = attrib; } attrib->SetName( name ); - attrib->_memPool->SetTracked(); // always created and linked. } return attrib; } @@ -1649,30 +1802,30 @@ void XMLElement::DeleteAttribute( const char* name ) } -char* XMLElement::ParseAttributes( char* p ) +char* XMLElement::ParseAttributes( char* p, int* curLineNumPtr ) { - const char* start = p; XMLAttribute* prevAttribute = 0; // Read the attributes. while( p ) { - p = XMLUtil::SkipWhiteSpace( p ); + p = XMLUtil::SkipWhiteSpace( p, curLineNumPtr ); if ( !(*p) ) { - _document->SetError( XML_ERROR_PARSING_ELEMENT, start, Name() ); + _document->SetError( XML_ERROR_PARSING_ELEMENT, _parseLineNum, "XMLElement name=%s", Name() ); return 0; } // attribute. if (XMLUtil::IsNameStartChar( *p ) ) { - TIXMLASSERT( sizeof( XMLAttribute ) == _document->_attributePool.ItemSize() ); - XMLAttribute* attrib = new (_document->_attributePool.Alloc() ) XMLAttribute(); - attrib->_memPool = &_document->_attributePool; - attrib->_memPool->SetTracked(); + XMLAttribute* attrib = CreateAttribute(); + TIXMLASSERT( attrib ); + attrib->_parseLineNum = _document->_parseCurLineNum; - p = attrib->ParseDeep( p, _document->ProcessEntities() ); + int attrLineNum = attrib->_parseLineNum; + + p = attrib->ParseDeep( p, _document->ProcessEntities(), curLineNumPtr ); if ( !p || Attribute( attrib->Name() ) ) { DeleteAttribute( attrib ); - _document->SetError( XML_ERROR_PARSING_ATTRIBUTE, start, p ); + _document->SetError( XML_ERROR_PARSING_ATTRIBUTE, attrLineNum, "XMLElement name=%s", Name() ); return 0; } // There is a minor bug here: if the attribute in the source xml @@ -1681,9 +1834,11 @@ char* XMLElement::ParseAttributes( char* p ) // avoids re-scanning the attribute list. Preferring performance for // now, may reconsider in the future. if ( prevAttribute ) { + TIXMLASSERT( prevAttribute->_next == 0 ); prevAttribute->_next = attrib; } else { + TIXMLASSERT( _rootAttribute == 0 ); _rootAttribute = attrib; } prevAttribute = attrib; @@ -1699,7 +1854,7 @@ char* XMLElement::ParseAttributes( char* p ) return p+2; // done; sealed element. } else { - _document->SetError( XML_ERROR_PARSING_ELEMENT, start, p ); + _document->SetError( XML_ERROR_PARSING_ELEMENT, _parseLineNum, 0 ); return 0; } } @@ -1716,14 +1871,24 @@ void XMLElement::DeleteAttribute( XMLAttribute* attribute ) pool->Free( attribute ); } +XMLAttribute* XMLElement::CreateAttribute() +{ + TIXMLASSERT( sizeof( XMLAttribute ) == _document->_attributePool.ItemSize() ); + XMLAttribute* attrib = new (_document->_attributePool.Alloc() ) XMLAttribute(); + TIXMLASSERT( attrib ); + attrib->_memPool = &_document->_attributePool; + attrib->_memPool->SetTracked(); + return attrib; +} + // // // foobar // -char* XMLElement::ParseDeep( char* p, StrPair* strPair ) +char* XMLElement::ParseDeep( char* p, StrPair* parentEndTag, int* curLineNumPtr ) { // Read the element name. - p = XMLUtil::SkipWhiteSpace( p ); + p = XMLUtil::SkipWhiteSpace( p, curLineNumPtr ); // The closing element is the form. It is // parsed just like a regular element then deleted from @@ -1738,12 +1903,12 @@ char* XMLElement::ParseDeep( char* p, StrPair* strPair ) return 0; } - p = ParseAttributes( p ); - if ( !p || !*p || _closingType ) { + p = ParseAttributes( p, curLineNumPtr ); + if ( !p || !*p || _closingType != OPEN ) { return p; } - p = XMLNode::ParseDeep( p, strPair ); + p = XMLNode::ParseDeep( p, parentEndTag, curLineNumPtr ); return p; } @@ -1812,10 +1977,10 @@ const char* XMLDocument::_errorNames[XML_ERROR_COUNT] = { "XML_ERROR_FILE_NOT_FOUND", "XML_ERROR_FILE_COULD_NOT_BE_OPENED", "XML_ERROR_FILE_READ_ERROR", - "XML_ERROR_ELEMENT_MISMATCH", + "UNUSED_XML_ERROR_ELEMENT_MISMATCH", "XML_ERROR_PARSING_ELEMENT", "XML_ERROR_PARSING_ATTRIBUTE", - "XML_ERROR_IDENTIFYING_TAG", + "UNUSED_XML_ERROR_IDENTIFYING_TAG", "XML_ERROR_PARSING_TEXT", "XML_ERROR_PARSING_CDATA", "XML_ERROR_PARSING_COMMENT", @@ -1825,19 +1990,27 @@ const char* XMLDocument::_errorNames[XML_ERROR_COUNT] = { "XML_ERROR_MISMATCHED_ELEMENT", "XML_ERROR_PARSING", "XML_CAN_NOT_CONVERT_TEXT", - "XML_NO_TEXT_NODE" + "XML_NO_TEXT_NODE", + "XML_ELEMENT_DEPTH_EXCEEDED" }; -XMLDocument::XMLDocument( bool processEntities, Whitespace whitespace ) : +XMLDocument::XMLDocument( bool processEntities, Whitespace whitespaceMode ) : XMLNode( 0 ), _writeBOM( false ), _processEntities( processEntities ), _errorID(XML_SUCCESS), - _whitespace( whitespace ), - _errorStr1( 0 ), - _errorStr2( 0 ), - _charBuffer( 0 ) + _whitespaceMode( whitespaceMode ), + _errorStr(), + _errorLineNum( 0 ), + _charBuffer( 0 ), + _parseCurLineNum( 0 ), + _parsingDepth(0), + _unlinked(), + _elementPool(), + _attributePool(), + _textPool(), + _commentPool() { // avoid VC++ C4355 warning about 'this' in initializer list (C4355 is off by default in VS2012+) _document = this; @@ -1850,19 +2023,34 @@ XMLDocument::~XMLDocument() } +void XMLDocument::MarkInUse(XMLNode* node) +{ + TIXMLASSERT(node); + TIXMLASSERT(node->_parent == 0); + + for (int i = 0; i < _unlinked.Size(); ++i) { + if (node == _unlinked[i]) { + _unlinked.SwapRemove(i); + break; + } + } +} + void XMLDocument::Clear() { DeleteChildren(); + while( _unlinked.Size()) { + DeleteNode(_unlinked[0]); // Will remove from _unlinked as part of delete. + } -#ifdef DEBUG +#ifdef TINYXML2_DEBUG const bool hadError = Error(); #endif - _errorID = XML_SUCCESS; - _errorStr1 = 0; - _errorStr2 = 0; + ClearError(); delete [] _charBuffer; _charBuffer = 0; + _parsingDepth = 0; #if 0 _textPool.Trace( "text" ); @@ -1870,8 +2058,8 @@ void XMLDocument::Clear() _commentPool.Trace( "comment" ); _attributePool.Trace( "attribute" ); #endif - -#ifdef DEBUG + +#ifdef TINYXML2_DEBUG if ( !hadError ) { TIXMLASSERT( _elementPool.CurrentAllocs() == _elementPool.Untracked() ); TIXMLASSERT( _attributePool.CurrentAllocs() == _attributePool.Untracked() ); @@ -1882,11 +2070,22 @@ void XMLDocument::Clear() } +void XMLDocument::DeepCopy(XMLDocument* target) const +{ + TIXMLASSERT(target); + if (target == this) { + return; // technically success - a no-op. + } + + target->Clear(); + for (const XMLNode* node = this->FirstChild(); node; node = node->NextSibling()) { + target->InsertEndChild(node->DeepClone(target)); + } +} + XMLElement* XMLDocument::NewElement( const char* name ) { - TIXMLASSERT( sizeof( XMLElement ) == _elementPool.ItemSize() ); - XMLElement* ele = new (_elementPool.Alloc()) XMLElement( this ); - ele->_memPool = &_elementPool; + XMLElement* ele = CreateUnlinkedNode( _elementPool ); ele->SetName( name ); return ele; } @@ -1894,9 +2093,7 @@ XMLElement* XMLDocument::NewElement( const char* name ) XMLComment* XMLDocument::NewComment( const char* str ) { - TIXMLASSERT( sizeof( XMLComment ) == _commentPool.ItemSize() ); - XMLComment* comment = new (_commentPool.Alloc()) XMLComment( this ); - comment->_memPool = &_commentPool; + XMLComment* comment = CreateUnlinkedNode( _commentPool ); comment->SetValue( str ); return comment; } @@ -1904,9 +2101,7 @@ XMLComment* XMLDocument::NewComment( const char* str ) XMLText* XMLDocument::NewText( const char* str ) { - TIXMLASSERT( sizeof( XMLText ) == _textPool.ItemSize() ); - XMLText* text = new (_textPool.Alloc()) XMLText( this ); - text->_memPool = &_textPool; + XMLText* text = CreateUnlinkedNode( _textPool ); text->SetValue( str ); return text; } @@ -1914,9 +2109,7 @@ XMLText* XMLDocument::NewText( const char* str ) XMLDeclaration* XMLDocument::NewDeclaration( const char* str ) { - TIXMLASSERT( sizeof( XMLDeclaration ) == _commentPool.ItemSize() ); - XMLDeclaration* dec = new (_commentPool.Alloc()) XMLDeclaration( this ); - dec->_memPool = &_commentPool; + XMLDeclaration* dec = CreateUnlinkedNode( _commentPool ); dec->SetValue( str ? str : "xml version=\"1.0\" encoding=\"UTF-8\"" ); return dec; } @@ -1924,9 +2117,7 @@ XMLDeclaration* XMLDocument::NewDeclaration( const char* str ) XMLUnknown* XMLDocument::NewUnknown( const char* str ) { - TIXMLASSERT( sizeof( XMLUnknown ) == _commentPool.ItemSize() ); - XMLUnknown* unk = new (_commentPool.Alloc()) XMLUnknown( this ); - unk->_memPool = &_commentPool; + XMLUnknown* unk = CreateUnlinkedNode( _commentPool ); unk->SetValue( str ); return unk; } @@ -1946,7 +2137,7 @@ static FILE* callfopen( const char* filepath, const char* mode ) #endif return fp; } - + void XMLDocument::DeleteNode( XMLNode* node ) { TIXMLASSERT( node ); TIXMLASSERT(node->_document == this ); @@ -1967,10 +2158,16 @@ void XMLDocument::DeleteNode( XMLNode* node ) { XMLError XMLDocument::LoadFile( const char* filename ) { + if ( !filename ) { + TIXMLASSERT( false ); + SetError( XML_ERROR_FILE_COULD_NOT_BE_OPENED, 0, "filename=" ); + return _errorID; + } + Clear(); FILE* fp = callfopen( filename, "rb" ); if ( !fp ) { - SetError( XML_ERROR_FILE_NOT_FOUND, filename, 0 ); + SetError( XML_ERROR_FILE_NOT_FOUND, 0, "filename=%s", filename ); return _errorID; } LoadFile( fp ); @@ -2049,9 +2246,15 @@ XMLError XMLDocument::LoadFile( FILE* fp ) XMLError XMLDocument::SaveFile( const char* filename, bool compact ) { + if ( !filename ) { + TIXMLASSERT( false ); + SetError( XML_ERROR_FILE_COULD_NOT_BE_OPENED, 0, "filename=" ); + return _errorID; + } + FILE* fp = callfopen( filename, "w" ); if ( !fp ) { - SetError( XML_ERROR_FILE_COULD_NOT_BE_OPENED, filename, 0 ); + SetError( XML_ERROR_FILE_COULD_NOT_BE_OPENED, 0, "filename=%s", filename ); return _errorID; } SaveFile(fp, compact); @@ -2064,7 +2267,7 @@ XMLError XMLDocument::SaveFile( FILE* fp, bool compact ) { // Clear any error from the last save, otherwise it will get reported // for *this* call. - SetError(XML_SUCCESS, 0, 0); + ClearError(); XMLPrinter stream( fp, compact ); Print( &stream ); return _errorID; @@ -2114,66 +2317,97 @@ void XMLDocument::Print( XMLPrinter* streamer ) const } -void XMLDocument::SetError( XMLError error, const char* str1, const char* str2 ) +void XMLDocument::SetError( XMLError error, int lineNum, const char* format, ... ) { TIXMLASSERT( error >= 0 && error < XML_ERROR_COUNT ); _errorID = error; - _errorStr1 = str1; - _errorStr2 = str2; + _errorLineNum = lineNum; + _errorStr.Reset(); + + size_t BUFFER_SIZE = 1000; + char* buffer = new char[BUFFER_SIZE]; + + TIXML_SNPRINTF(buffer, BUFFER_SIZE, "Error=%s ErrorID=%d (0x%x) Line number=%d", ErrorIDToName(error), int(error), int(error), lineNum); + + if (format) { + size_t len = strlen(buffer); + TIXML_SNPRINTF(buffer + len, BUFFER_SIZE - len, ": "); + len = strlen(buffer); + + va_list va; + va_start(va, format); + TIXML_VSNPRINTF(buffer + len, BUFFER_SIZE - len, format, va); + va_end(va); + } + _errorStr.SetStr(buffer); + delete[] buffer; } -const char* XMLDocument::ErrorName() const + +/*static*/ const char* XMLDocument::ErrorIDToName(XMLError errorID) { - TIXMLASSERT( _errorID >= 0 && _errorID < XML_ERROR_COUNT ); - const char* errorName = _errorNames[_errorID]; + TIXMLASSERT( errorID >= 0 && errorID < XML_ERROR_COUNT ); + const char* errorName = _errorNames[errorID]; TIXMLASSERT( errorName && errorName[0] ); return errorName; } +const char* XMLDocument::ErrorStr() const +{ + return _errorStr.Empty() ? "" : _errorStr.GetStr(); +} + + void XMLDocument::PrintError() const { - if ( Error() ) { - static const int LEN = 20; - char buf1[LEN] = { 0 }; - char buf2[LEN] = { 0 }; + printf("%s\n", ErrorStr()); +} - if ( _errorStr1 ) { - TIXML_SNPRINTF( buf1, LEN, "%s", _errorStr1 ); - } - if ( _errorStr2 ) { - TIXML_SNPRINTF( buf2, LEN, "%s", _errorStr2 ); - } - - // Should check INT_MIN <= _errorID && _errorId <= INT_MAX, but that - // causes a clang "always true" -Wtautological-constant-out-of-range-compare warning - TIXMLASSERT( 0 <= _errorID && XML_ERROR_COUNT - 1 <= INT_MAX ); - printf( "XMLDocument error id=%d '%s' str1=%s str2=%s\n", - static_cast( _errorID ), ErrorName(), buf1, buf2 ); - } +const char* XMLDocument::ErrorName() const +{ + return ErrorIDToName(_errorID); } void XMLDocument::Parse() { TIXMLASSERT( NoChildren() ); // Clear() must have been called previously TIXMLASSERT( _charBuffer ); + _parseCurLineNum = 1; + _parseLineNum = 1; char* p = _charBuffer; - p = XMLUtil::SkipWhiteSpace( p ); + p = XMLUtil::SkipWhiteSpace( p, &_parseCurLineNum ); p = const_cast( XMLUtil::ReadBOM( p, &_writeBOM ) ); if ( !*p ) { SetError( XML_ERROR_EMPTY_DOCUMENT, 0, 0 ); return; } - ParseDeep(p, 0 ); + ParseDeep(p, 0, &_parseCurLineNum ); +} + +void XMLDocument::PushDepth() +{ + _parsingDepth++; + if (_parsingDepth == TINYXML2_MAX_ELEMENT_DEPTH) { + SetError(XML_ELEMENT_DEPTH_EXCEEDED, _parseCurLineNum, "Element nesting is too deep." ); + } +} + +void XMLDocument::PopDepth() +{ + TIXMLASSERT(_parsingDepth > 0); + --_parsingDepth; } XMLPrinter::XMLPrinter( FILE* file, bool compact, int depth ) : _elementJustOpened( false ), + _stack(), _firstElement( true ), _fp( file ), _depth( depth ), _textDepth( -1 ), _processEntities( true ), - _compactMode( compact ) + _compactMode( compact ), + _buffer() { for( int i=0; i(size) ) - 1; // back up over the null terminator. + memcpy( p, data, size ); + p[size] = 0; + } +} + + +void XMLPrinter::Putc( char ch ) +{ + if ( _fp ) { + fputc ( ch, _fp); + } + else { + char* p = _buffer.PushArr( sizeof(char) ) - 1; // back up over the null terminator. + p[0] = ch; + p[1] = 0; + } +} + + void XMLPrinter::PrintSpace( int depth ) { for( int i=0; i( bom ) ); } if ( writeDec ) { PushDeclaration( "xml version=\"1.0\"" ); @@ -2289,13 +2553,15 @@ void XMLPrinter::OpenElement( const char* name, bool compactMode ) _stack.Push( name ); if ( _textDepth < 0 && !_firstElement && !compactMode ) { - Print( "\n" ); + Putc( '\n' ); } if ( !compactMode ) { PrintSpace( _depth ); } - Print( "<%s", name ); + Write ( "<" ); + Write ( name ); + _elementJustOpened = true; _firstElement = false; ++_depth; @@ -2305,9 +2571,11 @@ void XMLPrinter::OpenElement( const char* name, bool compactMode ) void XMLPrinter::PushAttribute( const char* name, const char* value ) { TIXMLASSERT( _elementJustOpened ); - Print( " %s=\"", name ); + Putc ( ' ' ); + Write( name ); + Write( "=\"" ); PrintString( value, false ); - Print( "\"" ); + Putc ( '\"' ); } @@ -2357,21 +2625,23 @@ void XMLPrinter::CloseElement( bool compactMode ) const char* name = _stack.Pop(); if ( _elementJustOpened ) { - Print( "/>" ); + Write( "/>" ); } else { if ( _textDepth < 0 && !compactMode) { - Print( "\n" ); + Putc( '\n' ); PrintSpace( _depth ); } - Print( "", name ); + Write ( "" ); } if ( _textDepth == _depth ) { _textDepth = -1; } if ( _depth == 0 && !compactMode) { - Print( "\n" ); + Putc( '\n' ); } _elementJustOpened = false; } @@ -2383,7 +2653,7 @@ void XMLPrinter::SealElementIfJustOpened() return; } _elementJustOpened = false; - Print( ">" ); + Putc( '>' ); } @@ -2393,13 +2663,22 @@ void XMLPrinter::PushText( const char* text, bool cdata ) SealElementIfJustOpened(); if ( cdata ) { - Print( "", text ); + Write( "" ); } else { PrintString( text, true ); } } +void XMLPrinter::PushText( int64_t value ) +{ + char buf[BUF_SIZE]; + XMLUtil::ToStr( value, buf, BUF_SIZE ); + PushText( buf, false ); +} + void XMLPrinter::PushText( int value ) { char buf[BUF_SIZE]; @@ -2444,11 +2723,14 @@ void XMLPrinter::PushComment( const char* comment ) { SealElementIfJustOpened(); if ( _textDepth < 0 && !_firstElement && !_compactMode) { - Print( "\n" ); + Putc( '\n' ); PrintSpace( _depth ); } _firstElement = false; - Print( "", comment ); + + Write( "" ); } @@ -2456,11 +2738,14 @@ void XMLPrinter::PushDeclaration( const char* value ) { SealElementIfJustOpened(); if ( _textDepth < 0 && !_firstElement && !_compactMode) { - Print( "\n" ); + Putc( '\n' ); PrintSpace( _depth ); } _firstElement = false; - Print( "", value ); + + Write( "" ); } @@ -2468,11 +2753,14 @@ void XMLPrinter::PushUnknown( const char* value ) { SealElementIfJustOpened(); if ( _textDepth < 0 && !_firstElement && !_compactMode) { - Print( "\n" ); + Putc( '\n' ); PrintSpace( _depth ); } _firstElement = false; - Print( "", value ); + + Write( "' ); } @@ -2536,4 +2824,3 @@ bool XMLPrinter::Visit( const XMLUnknown& unknown ) } } // namespace tinyxml2 - diff --git a/external/tinyxml2/tinyxml2.h b/external/tinyxml2/tinyxml2.h index 60280c06..1075eb2f 100644 --- a/external/tinyxml2/tinyxml2.h +++ b/external/tinyxml2/tinyxml2.h @@ -47,15 +47,15 @@ distribution. */ /* gcc: - g++ -Wall -DDEBUG tinyxml2.cpp xmltest.cpp -o gccxmltest.exe + g++ -Wall -DTINYXML2_DEBUG tinyxml2.cpp xmltest.cpp -o gccxmltest.exe Formatting, Artistic Style: AStyle.exe --style=1tbs --indent-switches --break-closing-brackets --indent-preprocessor tinyxml2.cpp tinyxml2.h */ -#if defined( _DEBUG ) || defined( DEBUG ) || defined (__DEBUG__) -# ifndef DEBUG -# define DEBUG +#if defined( _DEBUG ) || defined (__DEBUG__) +# ifndef TINYXML2_DEBUG +# define TINYXML2_DEBUG # endif #endif @@ -72,12 +72,14 @@ distribution. # else # define TINYXML2_LIB # endif +#elif __GNUC__ >= 4 +# define TINYXML2_LIB __attribute__((visibility("default"))) #else # define TINYXML2_LIB #endif -#if defined(DEBUG) +#if defined(TINYXML2_DEBUG) # if defined(_MSC_VER) # // "(void)0," is for suppressing C4127 warning in "assert(false)", "assert(true)" and the like # define TIXMLASSERT( x ) if ( !((void)0,(x))) { __debugbreak(); } @@ -96,9 +98,20 @@ distribution. /* Versioning, past 1.0.14: http://semver.org/ */ -static const int TIXML2_MAJOR_VERSION = 4; -static const int TIXML2_MINOR_VERSION = 0; -static const int TIXML2_PATCH_VERSION = 1; +static const int TIXML2_MAJOR_VERSION = 6; +static const int TIXML2_MINOR_VERSION = 2; +static const int TIXML2_PATCH_VERSION = 0; + +#define TINYXML2_MAJOR_VERSION 6 +#define TINYXML2_MINOR_VERSION 2 +#define TINYXML2_PATCH_VERSION 0 + +// A fixed element depth limit is problematic. There needs to be a +// limit to avoid a stack overflow. However, that limit varies per +// system, and the capacity of the stack. On the other hand, it's a trivial +// attack that can result from ill, malicious, or even correctly formed XML, +// so there needs to be a limit in place. +static const int TINYXML2_MAX_ELEMENT_DEPTH = 100; namespace tinyxml2 { @@ -125,18 +138,20 @@ public: NEEDS_NEWLINE_NORMALIZATION = 0x02, NEEDS_WHITESPACE_COLLAPSING = 0x04, - TEXT_ELEMENT = NEEDS_ENTITY_PROCESSING | NEEDS_NEWLINE_NORMALIZATION, + TEXT_ELEMENT = NEEDS_ENTITY_PROCESSING | NEEDS_NEWLINE_NORMALIZATION, TEXT_ELEMENT_LEAVE_ENTITIES = NEEDS_NEWLINE_NORMALIZATION, - ATTRIBUTE_NAME = 0, - ATTRIBUTE_VALUE = NEEDS_ENTITY_PROCESSING | NEEDS_NEWLINE_NORMALIZATION, - ATTRIBUTE_VALUE_LEAVE_ENTITIES = NEEDS_NEWLINE_NORMALIZATION, - COMMENT = NEEDS_NEWLINE_NORMALIZATION + ATTRIBUTE_NAME = 0, + ATTRIBUTE_VALUE = NEEDS_ENTITY_PROCESSING | NEEDS_NEWLINE_NORMALIZATION, + ATTRIBUTE_VALUE_LEAVE_ENTITIES = NEEDS_NEWLINE_NORMALIZATION, + COMMENT = NEEDS_NEWLINE_NORMALIZATION }; StrPair() : _flags( 0 ), _start( 0 ), _end( 0 ) {} ~StrPair(); void Set( char* start, char* end, int flags ) { + TIXMLASSERT( start ); + TIXMLASSERT( end ); Reset(); _start = start; _end = end; @@ -156,13 +171,13 @@ public: void SetStr( const char* str, int flags=0 ); - char* ParseText( char* in, const char* endTag, int strFlags ); + char* ParseText( char* in, const char* endTag, int strFlags, int* curLineNumPtr ); char* ParseName( char* in ); void TransferTo( StrPair* other ); + void Reset(); private: - void Reset(); void CollapseWhitespace(); enum { @@ -188,10 +203,11 @@ template class DynArray { public: - DynArray() { - _mem = _pool; - _allocated = INITIAL_SIZE; - _size = 0; + DynArray() : + _mem( _pool ), + _allocated( INITIAL_SIZE ), + _size( 0 ) + { } ~DynArray() { @@ -207,7 +223,8 @@ public: void Push( T t ) { TIXMLASSERT( _size < INT_MAX ); EnsureCapacity( _size+1 ); - _mem[_size++] = t; + _mem[_size] = t; + ++_size; } T* PushArr( int count ) { @@ -221,7 +238,8 @@ public: T Pop() { TIXMLASSERT( _size > 0 ); - return _mem[--_size]; + --_size; + return _mem[_size]; } void PopArr( int count ) { @@ -258,6 +276,13 @@ public: return _allocated; } + void SwapRemove(int i) { + TIXMLASSERT(i >= 0 && i < _size); + TIXMLASSERT(_size > 0); + _mem[i] = _mem[_size - 1]; + --_size; + } + const T* Mem() const { TIXMLASSERT( _mem ); return _mem; @@ -278,6 +303,7 @@ private: TIXMLASSERT( cap <= INT_MAX / 2 ); int newAllocated = cap * 2; T* newMem = new T[newAllocated]; + TIXMLASSERT( newAllocated >= _size ); memcpy( newMem, _mem, sizeof(T)*_size ); // warning: not using constructors, only works for PODs if ( _mem != _pool ) { delete [] _mem; @@ -315,11 +341,11 @@ public: /* Template child class to create pools of the correct type. */ -template< int SIZE > +template< int ITEM_SIZE > class MemPoolT : public MemPool { public: - MemPoolT() : _root(0), _currentAllocs(0), _nAllocs(0), _maxAllocs(0), _nUntracked(0) {} + MemPoolT() : _blockPtrs(), _root(0), _currentAllocs(0), _nAllocs(0), _maxAllocs(0), _nUntracked(0) {} ~MemPoolT() { Clear(); } @@ -327,8 +353,8 @@ public: void Clear() { // Delete the blocks. while( !_blockPtrs.Empty()) { - Block* b = _blockPtrs.Pop(); - delete b; + Block* lastBlock = _blockPtrs.Pop(); + delete lastBlock; } _root = 0; _currentAllocs = 0; @@ -338,7 +364,7 @@ public: } virtual int ItemSize() const { - return SIZE; + return ITEM_SIZE; } int CurrentAllocs() const { return _currentAllocs; @@ -350,21 +376,23 @@ public: Block* block = new Block(); _blockPtrs.Push( block ); - for( int i=0; ichunk[i].next = &block->chunk[i+1]; + Item* blockItems = block->items; + for( int i = 0; i < ITEMS_PER_BLOCK - 1; ++i ) { + blockItems[i].next = &(blockItems[i + 1]); } - block->chunk[COUNT-1].next = 0; - _root = block->chunk; + blockItems[ITEMS_PER_BLOCK - 1].next = 0; + _root = blockItems; } - void* result = _root; + Item* const result = _root; + TIXMLASSERT( result != 0 ); _root = _root->next; ++_currentAllocs; if ( _currentAllocs > _maxAllocs ) { _maxAllocs = _currentAllocs; } - _nAllocs++; - _nUntracked++; + ++_nAllocs; + ++_nUntracked; return result; } @@ -373,20 +401,21 @@ public: return; } --_currentAllocs; - Chunk* chunk = static_cast( mem ); -#ifdef DEBUG - memset( chunk, 0xfe, sizeof(Chunk) ); + Item* item = static_cast( mem ); +#ifdef TINYXML2_DEBUG + memset( item, 0xfe, sizeof( *item ) ); #endif - chunk->next = _root; - _root = chunk; + item->next = _root; + _root = item; } void Trace( const char* name ) { printf( "Mempool %s watermark=%d [%dk] current=%d size=%d nAlloc=%d blocks=%d\n", - name, _maxAllocs, _maxAllocs*SIZE/1024, _currentAllocs, SIZE, _nAllocs, _blockPtrs.Size() ); + name, _maxAllocs, _maxAllocs * ITEM_SIZE / 1024, _currentAllocs, + ITEM_SIZE, _nAllocs, _blockPtrs.Size() ); } void SetTracked() { - _nUntracked--; + --_nUntracked; } int Untracked() const { @@ -402,21 +431,23 @@ public: // 16k: 5200 // 32k: 4300 // 64k: 4000 21000 - enum { COUNT = (4*1024)/SIZE }; // Some compilers do not accept to use COUNT in private part if COUNT is private + // Declared public because some compilers do not accept to use ITEMS_PER_BLOCK + // in private part if ITEMS_PER_BLOCK is private + enum { ITEMS_PER_BLOCK = (4 * 1024) / ITEM_SIZE }; private: MemPoolT( const MemPoolT& ); // not supported void operator=( const MemPoolT& ); // not supported - union Chunk { - Chunk* next; - char mem[SIZE]; + union Item { + Item* next; + char itemData[ITEM_SIZE]; }; struct Block { - Chunk chunk[COUNT]; + Item items[ITEMS_PER_BLOCK]; }; DynArray< Block*, 10 > _blockPtrs; - Chunk* _root; + Item* _root; int _currentAllocs; int _nAllocs; @@ -494,10 +525,10 @@ enum XMLError { XML_ERROR_FILE_NOT_FOUND, XML_ERROR_FILE_COULD_NOT_BE_OPENED, XML_ERROR_FILE_READ_ERROR, - XML_ERROR_ELEMENT_MISMATCH, + UNUSED_XML_ERROR_ELEMENT_MISMATCH, // remove at next major version XML_ERROR_PARSING_ELEMENT, XML_ERROR_PARSING_ATTRIBUTE, - XML_ERROR_IDENTIFYING_TAG, + UNUSED_XML_ERROR_IDENTIFYING_TAG, // remove at next major version XML_ERROR_PARSING_TEXT, XML_ERROR_PARSING_CDATA, XML_ERROR_PARSING_COMMENT, @@ -508,6 +539,7 @@ enum XMLError { XML_ERROR_PARSING, XML_CAN_NOT_CONVERT_TEXT, XML_NO_TEXT_NODE, + XML_ELEMENT_DEPTH_EXCEEDED, XML_ERROR_COUNT }; @@ -516,19 +548,23 @@ enum XMLError { /* Utility functionality. */ -class XMLUtil +class TINYXML2_LIB XMLUtil { public: - static const char* SkipWhiteSpace( const char* p ) { + static const char* SkipWhiteSpace( const char* p, int* curLineNumPtr ) { TIXMLASSERT( p ); + while( IsWhiteSpace(*p) ) { + if (curLineNumPtr && *p == '\n') { + ++(*curLineNumPtr); + } ++p; } TIXMLASSERT( p ); return p; } - static char* SkipWhiteSpace( char* p ) { - return const_cast( SkipWhiteSpace( const_cast(p) ) ); + static char* SkipWhiteSpace( char* p, int* curLineNumPtr ) { + return const_cast( SkipWhiteSpace( const_cast(p), curLineNumPtr ) ); } // Anything in the high order range of UTF-8 is assumed to not be whitespace. This isn't @@ -559,6 +595,9 @@ public: if ( p == q ) { return true; } + TIXMLASSERT( p ); + TIXMLASSERT( q ); + TIXMLASSERT( nChar >= 0 ); return strncmp( p, q, nChar ) == 0; } @@ -587,6 +626,17 @@ public: static bool ToFloat( const char* str, float* value ); static bool ToDouble( const char* str, double* value ); static bool ToInt64(const char* str, int64_t* value); + + // Changes what is serialized for a boolean value. + // Default to "true" and "false". Shouldn't be changed + // unless you have a special testing or compatibility need. + // Be careful: static, global, & not thread safe. + // Be sure to set static const memory as parameters. + static void SetBoolSerialization(const char* writeTrue, const char* writeFalse); + +private: + static const char* writeBoolTrue; + static const char* writeBoolFalse; }; @@ -692,6 +742,9 @@ public: */ void SetValue( const char* val, bool staticMem=false ); + /// Gets the line number the node is in, if the document was parsed from a file. + int GetLineNum() const { return _parseLineNum; } + /// Get the parent of this node on the DOM. const XMLNode* Parent() const { return _parent; @@ -825,6 +878,21 @@ public: */ virtual XMLNode* ShallowClone( XMLDocument* document ) const = 0; + /** + Make a copy of this node and all its children. + + If the 'target' is null, then the nodes will + be allocated in the current document. If 'target' + is specified, the memory will be allocated is the + specified XMLDocument. + + NOTE: This is probably not the correct tool to + copy a document, since XMLDocuments can have multiple + top level XMLNodes. You probably want to use + XMLDocument::DeepCopy() + */ + XMLNode* DeepClone( XMLDocument* target ) const; + /** Test if 2 nodes are the same, but don't test children. The 2 nodes do not need to be in the same Document. @@ -875,11 +943,12 @@ protected: XMLNode( XMLDocument* ); virtual ~XMLNode(); - virtual char* ParseDeep( char*, StrPair* ); + virtual char* ParseDeep( char* p, StrPair* parentEndTag, int* curLineNumPtr); XMLDocument* _document; XMLNode* _parent; mutable StrPair _value; + int _parseLineNum; XMLNode* _firstChild; XMLNode* _lastChild; @@ -894,6 +963,7 @@ private: void Unlink( XMLNode* child ); static void DeleteNode( XMLNode* node ); void InsertChildPreamble( XMLNode* insertThis ) const; + const XMLElement* ToElementWithName( const char* name ) const; XMLNode( const XMLNode& ); // not supported XMLNode& operator=( const XMLNode& ); // not supported @@ -941,7 +1011,7 @@ protected: XMLText( XMLDocument* doc ) : XMLNode( doc ), _isCData( false ) {} virtual ~XMLText() {} - char* ParseDeep( char*, StrPair* endTag ); + char* ParseDeep( char* p, StrPair* parentEndTag, int* curLineNumPtr ); private: bool _isCData; @@ -972,7 +1042,7 @@ protected: XMLComment( XMLDocument* doc ); virtual ~XMLComment(); - char* ParseDeep( char*, StrPair* endTag ); + char* ParseDeep( char* p, StrPair* parentEndTag, int* curLineNumPtr); private: XMLComment( const XMLComment& ); // not supported @@ -1011,7 +1081,7 @@ protected: XMLDeclaration( XMLDocument* doc ); virtual ~XMLDeclaration(); - char* ParseDeep( char*, StrPair* endTag ); + char* ParseDeep( char* p, StrPair* parentEndTag, int* curLineNumPtr ); private: XMLDeclaration( const XMLDeclaration& ); // not supported @@ -1046,7 +1116,7 @@ protected: XMLUnknown( XMLDocument* doc ); virtual ~XMLUnknown(); - char* ParseDeep( char*, StrPair* endTag ); + char* ParseDeep( char* p, StrPair* parentEndTag, int* curLineNumPtr ); private: XMLUnknown( const XMLUnknown& ); // not supported @@ -1071,6 +1141,9 @@ public: /// The value of the attribute. const char* Value() const; + /// Gets the line number the attribute is in, if the document was parsed from a file. + int GetLineNum() const { return _parseLineNum; } + /// The next attribute in the list. const XMLAttribute* Next() const { return _next; @@ -1118,7 +1191,7 @@ public: } /** QueryIntValue interprets the attribute as an integer, and returns the value - in the provided parameter. The function will return XML_NO_ERROR on success, + in the provided parameter. The function will return XML_SUCCESS on success, and XML_WRONG_ATTRIBUTE_TYPE if the conversion is not successful. */ XMLError QueryIntValue( int* value ) const; @@ -1151,17 +1224,18 @@ public: private: enum { BUF_SIZE = 200 }; - XMLAttribute() : _next( 0 ), _memPool( 0 ) {} + XMLAttribute() : _name(), _value(),_parseLineNum( 0 ), _next( 0 ), _memPool( 0 ) {} virtual ~XMLAttribute() {} XMLAttribute( const XMLAttribute& ); // not supported void operator=( const XMLAttribute& ); // not supported void SetName( const char* name ); - char* ParseDeep( char* p, bool processEntities ); + char* ParseDeep( char* p, bool processEntities, int* curLineNumPtr ); mutable StrPair _name; mutable StrPair _value; + int _parseLineNum; XMLAttribute* _next; MemPool* _memPool; }; @@ -1218,51 +1292,25 @@ public: const char* Attribute( const char* name, const char* value=0 ) const; /** Given an attribute name, IntAttribute() returns the value - of the attribute interpreted as an integer. 0 will be - returned if there is an error. For a method with error - checking, see QueryIntAttribute() + of the attribute interpreted as an integer. The default + value will be returned if the attribute isn't present, + or if there is an error. (For a method with error + checking, see QueryIntAttribute()). */ - int IntAttribute( const char* name ) const { - int i=0; - QueryIntAttribute( name, &i ); - return i; - } - + int IntAttribute(const char* name, int defaultValue = 0) const; /// See IntAttribute() - unsigned UnsignedAttribute( const char* name ) const { - unsigned i=0; - QueryUnsignedAttribute( name, &i ); - return i; - } - + unsigned UnsignedAttribute(const char* name, unsigned defaultValue = 0) const; /// See IntAttribute() - int64_t Int64Attribute(const char* name) const { - int64_t i = 0; - QueryInt64Attribute(name, &i); - return i; - } - + int64_t Int64Attribute(const char* name, int64_t defaultValue = 0) const; /// See IntAttribute() - bool BoolAttribute( const char* name ) const { - bool b=false; - QueryBoolAttribute( name, &b ); - return b; - } + bool BoolAttribute(const char* name, bool defaultValue = false) const; /// See IntAttribute() - double DoubleAttribute( const char* name ) const { - double d=0; - QueryDoubleAttribute( name, &d ); - return d; - } + double DoubleAttribute(const char* name, double defaultValue = 0) const; /// See IntAttribute() - float FloatAttribute( const char* name ) const { - float f=0; - QueryFloatAttribute( name, &f ); - return f; - } + float FloatAttribute(const char* name, float defaultValue = 0) const; /** Given an attribute name, QueryIntAttribute() returns - XML_NO_ERROR, XML_WRONG_ATTRIBUTE_TYPE if the conversion + XML_SUCCESS, XML_WRONG_ATTRIBUTE_TYPE if the conversion can't be performed, or XML_NO_ATTRIBUTE if the attribute doesn't exist. If successful, the result of the conversion will be written to 'value'. If not successful, nothing will @@ -1325,9 +1373,20 @@ public: return a->QueryFloatValue( value ); } + /// See QueryIntAttribute() + XMLError QueryStringAttribute(const char* name, const char** value) const { + const XMLAttribute* a = FindAttribute(name); + if (!a) { + return XML_NO_ATTRIBUTE; + } + *value = a->Value(); + return XML_SUCCESS; + } + + /** Given an attribute name, QueryAttribute() returns - XML_NO_ERROR, XML_WRONG_ATTRIBUTE_TYPE if the conversion + XML_SUCCESS, XML_WRONG_ATTRIBUTE_TYPE if the conversion can't be performed, or XML_NO_ATTRIBUTE if the attribute doesn't exist. It is overloaded for the primitive types, and is a generally more convenient replacement of @@ -1533,20 +1592,33 @@ public: /// See QueryIntText() XMLError QueryFloatText( float* fval ) const; + int IntText(int defaultValue = 0) const; + + /// See QueryIntText() + unsigned UnsignedText(unsigned defaultValue = 0) const; + /// See QueryIntText() + int64_t Int64Text(int64_t defaultValue = 0) const; + /// See QueryIntText() + bool BoolText(bool defaultValue = false) const; + /// See QueryIntText() + double DoubleText(double defaultValue = 0) const; + /// See QueryIntText() + float FloatText(float defaultValue = 0) const; + // internal: - enum { + enum ElementClosingType { OPEN, // CLOSED, // CLOSING // }; - int ClosingType() const { + ElementClosingType ClosingType() const { return _closingType; } virtual XMLNode* ShallowClone( XMLDocument* document ) const; virtual bool ShallowEqual( const XMLNode* compare ) const; protected: - char* ParseDeep( char* p, StrPair* endTag ); + char* ParseDeep( char* p, StrPair* parentEndTag, int* curLineNumPtr ); private: XMLElement( XMLDocument* doc ); @@ -1559,11 +1631,12 @@ private: } XMLAttribute* FindOrCreateAttribute( const char* name ); //void LinkAttribute( XMLAttribute* attrib ); - char* ParseAttributes( char* p ); + char* ParseAttributes( char* p, int* curLineNumPtr ); static void DeleteAttribute( XMLAttribute* attribute ); + XMLAttribute* CreateAttribute(); enum { BUF_SIZE = 200 }; - int _closingType; + ElementClosingType _closingType; // The attribute list is ordered; there is no 'lastAttribute' // because the list needs to be scanned for dupes before adding // a new attribute. @@ -1585,9 +1658,16 @@ enum Whitespace { class TINYXML2_LIB XMLDocument : public XMLNode { friend class XMLElement; + // Gives access to SetError and Push/PopDepth, but over-access for everything else. + // Wishing C++ had "internal" scope. + friend class XMLNode; + friend class XMLText; + friend class XMLComment; + friend class XMLDeclaration; + friend class XMLUnknown; public: /// constructor - XMLDocument( bool processEntities = true, Whitespace = PRESERVE_WHITESPACE ); + XMLDocument( bool processEntities = true, Whitespace whitespaceMode = PRESERVE_WHITESPACE ); ~XMLDocument(); virtual XMLDocument* ToDocument() { @@ -1601,7 +1681,7 @@ public: /** Parse an XML file from a character string. - Returns XML_NO_ERROR (0) on success, or + Returns XML_SUCCESS (0) on success, or an errorID. You may optionally pass in the 'nBytes', which is @@ -1613,7 +1693,7 @@ public: /** Load an XML file from disk. - Returns XML_NO_ERROR (0) on success, or + Returns XML_SUCCESS (0) on success, or an errorID. */ XMLError LoadFile( const char* filename ); @@ -1626,14 +1706,14 @@ public: not text in order for TinyXML-2 to correctly do newline normalization. - Returns XML_NO_ERROR (0) on success, or + Returns XML_SUCCESS (0) on success, or an errorID. */ XMLError LoadFile( FILE* ); /** Save the XML file to disk. - Returns XML_NO_ERROR (0) on success, or + Returns XML_SUCCESS (0) on success, or an errorID. */ XMLError SaveFile( const char* filename, bool compact = false ); @@ -1642,7 +1722,7 @@ public: Save the XML file to disk. You are responsible for providing and closing the FILE*. - Returns XML_NO_ERROR (0) on success, or + Returns XML_SUCCESS (0) on success, or an errorID. */ XMLError SaveFile( FILE* fp, bool compact = false ); @@ -1651,7 +1731,7 @@ public: return _processEntities; } Whitespace WhitespaceMode() const { - return _whitespace; + return _whitespaceMode; } /** @@ -1736,7 +1816,9 @@ public: */ void DeleteNode( XMLNode* node ); - void SetError( XMLError error, const char* str1, const char* str2 ); + void ClearError() { + SetError(XML_SUCCESS, 0, 0); + } /// Return true if there was an error parsing the document. bool Error() const { @@ -1747,24 +1829,40 @@ public: return _errorID; } const char* ErrorName() const; + static const char* ErrorIDToName(XMLError errorID); - /// Return a possibly helpful diagnostic location or string. - const char* GetErrorStr1() const { - return _errorStr1; - } - /// Return a possibly helpful secondary diagnostic location or string. - const char* GetErrorStr2() const { - return _errorStr2; - } - /// If there is an error, print it to stdout. + /** Returns a "long form" error description. A hopefully helpful + diagnostic with location, line number, and/or additional info. + */ + const char* ErrorStr() const; + + /// A (trivial) utility function that prints the ErrorStr() to stdout. void PrintError() const; + + /// Return the line where the error occured, or zero if unknown. + int ErrorLineNum() const + { + return _errorLineNum; + } /// Clear the document, resetting it to the initial state. void Clear(); - // internal + /** + Copies this document to a target document. + The target will be completely cleared before the copy. + If you want to copy a sub-tree, see XMLNode::DeepClone(). + + NOTE: that the 'target' must be non-null. + */ + void DeepCopy(XMLDocument* target) const; + + // internal char* Identify( char* p, XMLNode** node ); + // internal + void MarkInUse(XMLNode*); + virtual XMLNode* ShallowClone( XMLDocument* /*document*/ ) const { return 0; } @@ -1776,13 +1874,22 @@ private: XMLDocument( const XMLDocument& ); // not supported void operator=( const XMLDocument& ); // not supported - bool _writeBOM; - bool _processEntities; - XMLError _errorID; - Whitespace _whitespace; - const char* _errorStr1; - const char* _errorStr2; - char* _charBuffer; + bool _writeBOM; + bool _processEntities; + XMLError _errorID; + Whitespace _whitespaceMode; + mutable StrPair _errorStr; + int _errorLineNum; + char* _charBuffer; + int _parseCurLineNum; + int _parsingDepth; + // Memory tracking does add some overhead. + // However, the code assumes that you don't + // have a bunch of unlinked nodes around. + // Therefore it takes less memory to track + // in the document vs. a linked list in the XMLNode, + // and the performance is the same. + DynArray _unlinked; MemPoolT< sizeof(XMLElement) > _elementPool; MemPoolT< sizeof(XMLAttribute) > _attributePool; @@ -1792,8 +1899,43 @@ private: static const char* _errorNames[XML_ERROR_COUNT]; void Parse(); + + void SetError( XMLError error, int lineNum, const char* format, ... ); + + // Something of an obvious security hole, once it was discovered. + // Either an ill-formed XML or an excessively deep one can overflow + // the stack. Track stack depth, and error out if needed. + class DepthTracker { + public: + DepthTracker(XMLDocument * document) { + this->_document = document; + document->PushDepth(); + } + ~DepthTracker() { + _document->PopDepth(); + } + private: + XMLDocument * _document; + }; + void PushDepth(); + void PopDepth(); + + template + NodeType* CreateUnlinkedNode( MemPoolT& pool ); }; +template +inline NodeType* XMLDocument::CreateUnlinkedNode( MemPoolT& pool ) +{ + TIXMLASSERT( sizeof( NodeType ) == PoolElementSize ); + TIXMLASSERT( sizeof( NodeType ) == pool.ItemSize() ); + NodeType* returnNode = new (pool.Alloc()) NodeType( this ); + TIXMLASSERT( returnNode ); + returnNode->_memPool = &pool; + + _unlinked.Push(returnNode); + return returnNode; +} /** A XMLHandle is a class that wraps a node pointer with null checks; this is @@ -1854,16 +1996,13 @@ class TINYXML2_LIB XMLHandle { public: /// Create a handle from any node (at any depth of the tree.) This can be a null pointer. - XMLHandle( XMLNode* node ) { - _node = node; + XMLHandle( XMLNode* node ) : _node( node ) { } /// Create a handle from a node. - XMLHandle( XMLNode& node ) { - _node = &node; + XMLHandle( XMLNode& node ) : _node( &node ) { } /// Copy constructor - XMLHandle( const XMLHandle& ref ) { - _node = ref._node; + XMLHandle( const XMLHandle& ref ) : _node( ref._node ) { } /// Assignment XMLHandle& operator=( const XMLHandle& ref ) { @@ -1910,19 +2049,19 @@ public: } /// Safe cast to XMLElement. This can return null. XMLElement* ToElement() { - return ( ( _node == 0 ) ? 0 : _node->ToElement() ); + return ( _node ? _node->ToElement() : 0 ); } /// Safe cast to XMLText. This can return null. XMLText* ToText() { - return ( ( _node == 0 ) ? 0 : _node->ToText() ); + return ( _node ? _node->ToText() : 0 ); } /// Safe cast to XMLUnknown. This can return null. XMLUnknown* ToUnknown() { - return ( ( _node == 0 ) ? 0 : _node->ToUnknown() ); + return ( _node ? _node->ToUnknown() : 0 ); } /// Safe cast to XMLDeclaration. This can return null. XMLDeclaration* ToDeclaration() { - return ( ( _node == 0 ) ? 0 : _node->ToDeclaration() ); + return ( _node ? _node->ToDeclaration() : 0 ); } private: @@ -1937,14 +2076,11 @@ private: class TINYXML2_LIB XMLConstHandle { public: - XMLConstHandle( const XMLNode* node ) { - _node = node; + XMLConstHandle( const XMLNode* node ) : _node( node ) { } - XMLConstHandle( const XMLNode& node ) { - _node = &node; + XMLConstHandle( const XMLNode& node ) : _node( &node ) { } - XMLConstHandle( const XMLConstHandle& ref ) { - _node = ref._node; + XMLConstHandle( const XMLConstHandle& ref ) : _node( ref._node ) { } XMLConstHandle& operator=( const XMLConstHandle& ref ) { @@ -1982,16 +2118,16 @@ public: return _node; } const XMLElement* ToElement() const { - return ( ( _node == 0 ) ? 0 : _node->ToElement() ); + return ( _node ? _node->ToElement() : 0 ); } const XMLText* ToText() const { - return ( ( _node == 0 ) ? 0 : _node->ToText() ); + return ( _node ? _node->ToText() : 0 ); } const XMLUnknown* ToUnknown() const { - return ( ( _node == 0 ) ? 0 : _node->ToUnknown() ); + return ( _node ? _node->ToUnknown() : 0 ); } const XMLDeclaration* ToDeclaration() const { - return ( ( _node == 0 ) ? 0 : _node->ToDeclaration() ); + return ( _node ? _node->ToDeclaration() : 0 ); } private: @@ -2125,6 +2261,7 @@ public: void ClearBuffer() { _buffer.Clear(); _buffer.Push(0); + _firstElement = true; } protected: @@ -2135,6 +2272,9 @@ protected: */ virtual void PrintSpace( int depth ); void Print( const char* format, ... ); + void Write( const char* data, size_t size ); + inline void Write( const char* data ) { Write( data, strlen( data ) ); } + void Putc( char ch ); void SealElementIfJustOpened(); bool _elementJustOpened; @@ -2158,6 +2298,10 @@ private: bool _restrictedEntityFlag[ENTITY_RANGE]; DynArray< char, 20 > _buffer; + + // Prohibit cloning, intentionally not implemented + XMLPrinter( const XMLPrinter& ); + XMLPrinter& operator=( const XMLPrinter& ); }; diff --git a/linux/installer/common/libsgx-enclave-common/BOMs/sgx-enclave-common_base.txt b/linux/installer/common/libsgx-enclave-common/BOMs/sgx-enclave-common_base.txt new file mode 100644 index 00000000..a643e665 --- /dev/null +++ b/linux/installer/common/libsgx-enclave-common/BOMs/sgx-enclave-common_base.txt @@ -0,0 +1,18 @@ +DeliveryName InstallName FileCheckSum FileFeature FileOwner +/build/linux/aesmd.conf /package/aesm/aesmd.conf 0 main STP +/build/linux/aesmd.service /package/aesm/aesmd.service 0 main STP +/build/linux/aesm_service /package/aesm/aesm_service 0 main STP +/build/linux/le_prod_css.bin /package/aesm/le_prod_css.bin 0 main STP +/build/linux/libsgx_le.signed.so /package/aesm/libsgx_le.signed.so 0 main STP +/build/linux/libsgx_pve.signed.so /package/aesm/libsgx_pve.signed.so 0 main STP +/build/linux/libsgx_qe.signed.so /package/aesm/libsgx_qe.signed.so 0 main STP +/build/linux/libsgx_pce.signed.so /package/aesm/libsgx_pce.signed.so 0 main STP +/build/linux/libsgx_pse_pr.signed.so /package/aesm/libsgx_pse_pr.signed.so 0 main STP +/build/linux/libsgx_pse_op.signed.so /package/aesm/libsgx_pse_op.signed.so 0 main STP +/build/linux/PSDA.dalp /package/aesm/PSDA.dalp 0 main STP +/linux/installer/common/libsgx-enclave-common/install.sh /scripts/install.sh 0 main STP +/linux/installer/common/libsgx-enclave-common/Makefile /Makefile 0 main STP +/psw/ae/aesm_service/config/network/aesmd.conf /package/aesm/conf/aesmd.conf 0 main STP +/psw/ae/aesm_service/data/white_list_cert_to_be_verify.bin /package/aesm/data/white_list_cert_to_be_verify.bin 0 main STP +/psw/ae/aesm_service/data/prebuild_pse_vmc.db /package/aesm/data/prebuild_pse_vmc.db 0 main STP +/build/linux/cse_provision_tool /package/aesm/cse_provision_tool 0 main STP diff --git a/linux/installer/common/libsgx-enclave-common/BOMs/sgx-enclave-common_x64.txt b/linux/installer/common/libsgx-enclave-common/BOMs/sgx-enclave-common_x64.txt new file mode 100644 index 00000000..37d9b290 --- /dev/null +++ b/linux/installer/common/libsgx-enclave-common/BOMs/sgx-enclave-common_x64.txt @@ -0,0 +1,5 @@ +DeliveryName InstallName FileCheckSum FileFeature FileOwner +/build/linux/libsgx_uae_service.so /package/lib64/libsgx_uae_service.so 0 main STP +/build/linux/libsgx_urts.so /package/lib64/libsgx_urts.so 0 main STP +/build/linux/libsgx_enclave_common.so /package/lib64/libsgx_enclave_common.so 0 main STP +/linux/installer/common/libsgx-enclave-common/installConfig.x64 /scripts/installConfig 0 main STP diff --git a/linux/installer/common/libsgx-enclave-common/BOMs/sgx-enclave-common_x86.txt b/linux/installer/common/libsgx-enclave-common/BOMs/sgx-enclave-common_x86.txt new file mode 100644 index 00000000..6824c9d0 --- /dev/null +++ b/linux/installer/common/libsgx-enclave-common/BOMs/sgx-enclave-common_x86.txt @@ -0,0 +1,5 @@ +DeliveryName InstallName FileCheckSum FileFeature FileOwner +/build/linux/libsgx_uae_service.so /package/lib/libsgx_uae_service.so 0 main STP +/build/linux/libsgx_urts.so /package/lib/libsgx_urts.so 0 main STP +/build/linux/libsgx_enclave_common.so /package/lib/libsgx_enclave_common.so 0 main STP +/linux/installer/common/libsgx-enclave-common/installConfig.x86 /scripts/installConfig 0 main STP diff --git a/linux/installer/common/libsgx-enclave-common/Makefile b/linux/installer/common/libsgx-enclave-common/Makefile new file mode 100644 index 00000000..60a232e8 --- /dev/null +++ b/linux/installer/common/libsgx-enclave-common/Makefile @@ -0,0 +1,67 @@ +# +# Copyright (C) 2011-2018 Intel Corporation. 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 name of Intel 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 +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +# +# + +include scripts/installConfig + +SOURCE_FOLDER=package +SCRIPTS_FOLDER=scripts + +INSTALL_PATH=$(shell readlink -m $(DESTDIR)/$(ECL_PACKAGES_PATH)/$(ECL_PKG_NAME)) +SOURCE_INSTALL_PATH=$(INSTALL_PATH) +SCRIPTS_INSTALL_PATH=$(INSTALL_PATH)/$(SCRIPTS_FOLDER) +ECL_LIB_PATH=$(SOURCE_INSTALL_PATH)/$(LIB_DIR) +USR_LIB_PATH=$(addsuffix /$(shell dpkg-architecture -qDEB_HOST_MULTIARCH), $(addprefix $(DESTDIR)/usr/, $(notdir $(shell gcc -print-multi-os-directory)))) + +URTS_VER=1.0.0 +ECL_VER=1.0.0 + +default: + +install: + install -d $(SOURCE_INSTALL_PATH) + install -d $(SCRIPTS_INSTALL_PATH) + install -d $(USR_LIB_PATH) + cp -r $(SOURCE_FOLDER)/* $(SOURCE_INSTALL_PATH) + install $(SCRIPTS_FOLDER)/* $(SCRIPTS_INSTALL_PATH) + mv $(ECL_LIB_PATH)/libsgx_uae_service.so $(USR_LIB_PATH) + mv $(ECL_LIB_PATH)/libsgx_urts.so $(USR_LIB_PATH) + mv $(ECL_LIB_PATH)/libsgx_enclave_common.so $(USR_LIB_PATH) + rmdir $(ECL_LIB_PATH) + cd $(USR_LIB_PATH) && \ + mv libsgx_uae_service.so libsgx_uae_service.so.$(ECL_VER) && \ + ln -fs libsgx_uae_service.so.$(ECL_VER) libsgx_uae_service.so.$(shell echo $(ECL_VER) |awk -F. '{print $$1}') && \ + ln -fs libsgx_uae_service.so.$(shell echo $(ECL_VER) |awk -F. '{print $$1}') libsgx_uae_service.so && \ + mv libsgx_urts.so libsgx_urts.so.$(ECL_VER) && \ + ln -fs libsgx_urts.so.$(ECL_VER) libsgx_urts.so.$(shell echo $(ECL_VER) |awk -F. '{print $$1}') && \ + ln -fs libsgx_urts.so.$(shell echo $(ECL_VER) |awk -F. '{print $$1}') libsgx_urts.so && \ + mv libsgx_enclave_common.so libsgx_enclave_common.so.$(ECL_VER) && \ + ln -fs libsgx_enclave_common.so.$(ECL_VER) libsgx_enclave_common.so.$(shell echo $(ECL_VER) |awk -F. '{print $$1}') && \ + ln -fs libsgx_enclave_common.so.$(shell echo $(ECL_VER) |awk -F. '{print $$1}') libsgx_enclave_common.so diff --git a/linux/installer/common/libsgx-enclave-common/createTarball.sh b/linux/installer/common/libsgx-enclave-common/createTarball.sh new file mode 100755 index 00000000..0a225f77 --- /dev/null +++ b/linux/installer/common/libsgx-enclave-common/createTarball.sh @@ -0,0 +1,74 @@ +#!/usr/bin/env bash +# +# Copyright (C) 2011-2018 Intel Corporation. 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 name of Intel 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 +# OWNER 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. +# +# + + +set -e + +SCRIPT_DIR=$(dirname "$0") +ROOT_DIR="${SCRIPT_DIR}/../../../../" +BUILD_DIR="${ROOT_DIR}/build/linux" +LINUX_INSTALLER_DIR="${ROOT_DIR}/linux/installer" +LINUX_INSTALLER_COMMON_DIR="${LINUX_INSTALLER_DIR}/common" + +INSTALL_PATH=${SCRIPT_DIR}/output + +# Cleanup +rm -fr ${INSTALL_PATH} + +# Get the architecture of the build from generated binary +get_arch() +{ + local a=$(readelf -h $(find ${BUILD_DIR} -name "*.so*" |head -n 1) | sed -n '2p' | awk '/:/{print $6}') + test $a = 02 && echo 'x64' || echo 'x86' +} + +ARCH=$(get_arch) + +# Get the configuration for this package +source ${SCRIPT_DIR}/installConfig.${ARCH} + +# Fetch the gen_source script +cp ${LINUX_INSTALLER_COMMON_DIR}/gen_source/gen_source.py ${SCRIPT_DIR} + +# Copy the files according to the BOM +python ${SCRIPT_DIR}/gen_source.py --bom=BOMs/sgx-enclave-common_base.txt +python ${SCRIPT_DIR}/gen_source.py --bom=BOMs/sgx-enclave-common_${ARCH}.txt --cleanup=false +python ${SCRIPT_DIR}/gen_source.py --bom=../licenses/BOM_license.txt --cleanup=false + +# Create the tarball +URTS_VER=$(awk '/URTS_VERSION/ {print $3}' ${ROOT_DIR}/common/inc/internal/se_version.h|sed 's/^\"\(.*\)\"$/\1/') +ECL_VER=$(awk '/ENCLAVE_COMMON_VERSION/ {print $3}' ${ROOT_DIR}/common/inc/internal/se_version.h|sed 's/^\"\(.*\)\"$/\1/') +pushd ${INSTALL_PATH} &> /dev/null +sed -i "s/URTS_VER=.*/URTS_VER=${URTS_VER}/" Makefile +sed -i "s/ECL_VER=.*/ECL_VER=${ECL_VER}/" Makefile +tar -zcvf ${TARBALL_NAME} * +popd &> /dev/null diff --git a/linux/installer/common/libsgx-enclave-common/install.sh b/linux/installer/common/libsgx-enclave-common/install.sh new file mode 100755 index 00000000..3b67a801 --- /dev/null +++ b/linux/installer/common/libsgx-enclave-common/install.sh @@ -0,0 +1,240 @@ +#!/usr/bin/env bash +# +# Copyright (C) 2011-2018 Intel Corporation. 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 name of Intel 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 +# OWNER 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. +# +# + + +set -e + +SCRIPT_DIR=$(dirname "$0") +source ${SCRIPT_DIR}/installConfig + +ECL_DST_PATH=${ECL_PACKAGES_PATH}/${ECL_PKG_NAME} +AESM_PATH=$ECL_DST_PATH/aesm + +# Install the AESM service + +cut -d: -f1 /etc/passwd | grep -q -w aesmd || \ + /usr/sbin/useradd -r -U -c "User for aesmd" \ + -d /var/opt/aesmd -s /sbin/nologin aesmd + +mkdir -p /var/opt/aesmd +cp -rf $AESM_PATH/data /var/opt/aesmd/ +rm -rf $AESM_PATH/data +cp -rf $AESM_PATH/conf/aesmd.conf /etc/aesmd.conf +rm -rf $AESM_PATH/conf +chmod 0644 /etc/aesmd.conf +chown -R aesmd:aesmd /var/opt/aesmd +chmod 0750 /var/opt/aesmd + +# By default the AESM's communication socket will be created in +# /var/run/aesmd. Putting the socket in the aesmd sub-directory +# as opposed to directly in /var/run allows the user to create a +# mount a volume at /var/run/aesmd and thus expose the socket to +# a different filesystem or namespace, e.g. a Docker container. +mkdir -p /var/run/aesmd +chown -R aesmd:aesmd /var/run/aesmd +chmod 0755 /var/run/aesmd + +# Stop aesmd first. +/usr/sbin/service aesmd stop &> /dev/null || echo + +if [ -d /run/systemd/system ]; then + AESMD_NAME=aesmd.service + AESMD_TEMP=$AESM_PATH/$AESMD_NAME + if [ -d /lib/systemd/system ]; then + AESMD_DEST=/lib/systemd/system/$AESMD_NAME + else + AESMD_DEST=/usr/lib/systemd/system/$AESMD_NAME + fi + echo -n "Installing $AESMD_NAME service ..." + sed -e "s:@aesm_folder@:$AESM_PATH:" \ + $AESMD_TEMP > $AESMD_DEST + chmod 0644 $AESMD_DEST + rm -f $AESMD_TEMP + rm -f $AESM_PATH/aesmd.conf + DISABLE_AESMD="systemctl disable aesmd" + systemctl enable aesmd + retval=$? +elif [ -d /etc/init/ ]; then + AESMD_NAME=aesmd.conf + AESMD_TEMP=$AESM_PATH/$AESMD_NAME + AESMD_DEST=/etc/init/$AESMD_NAME + echo -n "Installing $AESMD_NAME service ..." + sed -e "s:@aesm_folder@:$AESM_PATH:" \ + $AESMD_TEMP > $AESMD_DEST + chmod 0644 $AESMD_DEST + rm -f $AESMD_TEMP + rm -f $AESM_PATH/aesmd.service + /sbin/initctl reload-configuration + retval=$? +else + echo " failed." + echo "Unsupported platform - neither systemctl nor initctl is found." + exit 5 +fi + +if test $retval -ne 0; then + echo "$rcmngr failed to install $AESMD_NAME." + exit 6 +fi + +echo " done." + + +cat > $ECL_DST_PATH/uninstall.sh < /dev/null +/usr/sbin/groupdel aesmd 2> /dev/null + +# Removing AESM folder +rm -fr $ECL_DST_PATH +EOF + +chmod +x $ECL_DST_PATH/uninstall.sh + +$AESM_PATH/cse_provision_tool || true +rm $AESM_PATH/cse_provision_tool + +cat > $AESM_PATH/linksgx.sh < /dev/null + /sbin/modprobe -r isgx &> /dev/null +else + /sbin/modprobe isgx &> /dev/null || /sbin/modprobe --allow-unsupported isgx &> /dev/null +fi +echo "" +EOF + +chmod +x $AESM_PATH/linksgx.sh + +# Start the aesmd service +if [ -d /run/systemd/system ]; then + systemctl start aesmd +elif [ -d /etc/init/ ]; then + /sbin/initctl start aesmd +fi + +rm -fr $ECL_DST_PATH/scripts + +exit 0 + diff --git a/linux/installer/common/libsgx-enclave-common/installConfig.x64 b/linux/installer/common/libsgx-enclave-common/installConfig.x64 new file mode 100644 index 00000000..cbf4e904 --- /dev/null +++ b/linux/installer/common/libsgx-enclave-common/installConfig.x64 @@ -0,0 +1,8 @@ +ECL_VERSION="1.0" +TARBALL_NAME=libsgx-enclave-common_1.0.orig.tar.gz + +ECL_PACKAGES_PATH=/opt/intel +ECL_PKG_NAME=libsgx-enclave-common + +LIB_DIR=lib64 +BIN_DIR="bin/x64" diff --git a/linux/installer/common/libsgx-enclave-common/installConfig.x86 b/linux/installer/common/libsgx-enclave-common/installConfig.x86 new file mode 100644 index 00000000..369c24c1 --- /dev/null +++ b/linux/installer/common/libsgx-enclave-common/installConfig.x86 @@ -0,0 +1,8 @@ +ECL_VERSION="1.0" +TARBALL_NAME=libsgx-enclave-common_1.0.orig.tar.gz + +ECL_PACKAGES_PATH=/opt/intel +ECL_PKG_NAME=libsgx-enclave-common + +LIB_DIR=lib +BIN_DIR="bin/x86" diff --git a/linux/installer/common/psw/BOMs/psw_x64.txt b/linux/installer/common/psw/BOMs/psw_x64.txt index 88502f37..f66d5323 100644 --- a/linux/installer/common/psw/BOMs/psw_x64.txt +++ b/linux/installer/common/psw/BOMs/psw_x64.txt @@ -1,4 +1,5 @@ DeliveryName InstallName FileCheckSum FileFeature FileOwner /build/linux/libsgx_uae_service.so /package/lib64/libsgx_uae_service.so 0 main STP /build/linux/libsgx_urts.so /package/lib64/libsgx_urts.so 0 main STP +/build/linux/libsgx_enclave_common.so /package/lib64/libsgx_enclave_common.so 0 main STP /linux/installer/common/psw/installConfig.x64 /scripts/installConfig 0 main STP diff --git a/linux/installer/common/psw/BOMs/psw_x86.txt b/linux/installer/common/psw/BOMs/psw_x86.txt index 715c3db8..e57d7181 100644 --- a/linux/installer/common/psw/BOMs/psw_x86.txt +++ b/linux/installer/common/psw/BOMs/psw_x86.txt @@ -1,4 +1,5 @@ DeliveryName InstallName FileCheckSum FileFeature FileOwner /build/linux/libsgx_uae_service.so /package/lib/libsgx_uae_service.so 0 main STP /build/linux/libsgx_urts.so /package/lib/libsgx_urts.so 0 main STP +/build/linux/libsgx_enclave_common.so /package/lib/libsgx_enclave_common.so 0 main STP /linux/installer/common/psw/installConfig.x86 /scripts/installConfig 0 main STP diff --git a/linux/installer/common/psw/Makefile b/linux/installer/common/psw/Makefile index 528c41d9..a70f7ca0 100644 --- a/linux/installer/common/psw/Makefile +++ b/linux/installer/common/psw/Makefile @@ -40,6 +40,8 @@ SCRIPTS_INSTALL_PATH=$(INSTALL_PATH)/$(SCRIPTS_FOLDER) PSW_LIB_PATH=$(SOURCE_INSTALL_PATH)/$(LIB_DIR) USR_LIB_PATH=$(addprefix $(DESTDIR)/usr/, $(notdir $(shell gcc -print-multi-os-directory))) +ECL_VER=1.0.0 + default: install: @@ -50,4 +52,9 @@ install: install $(SCRIPTS_FOLDER)/* $(SCRIPTS_INSTALL_PATH) mv $(PSW_LIB_PATH)/libsgx_uae_service.so $(USR_LIB_PATH) mv $(PSW_LIB_PATH)/libsgx_urts.so $(USR_LIB_PATH) + mv $(PSW_LIB_PATH)/libsgx_enclave_common.so $(USR_LIB_PATH) rmdir $(PSW_LIB_PATH) + cd $(USR_LIB_PATH) && \ + mv libsgx_enclave_common.so libsgx_enclave_common.so.$(ECL_VER) && \ + ln -fs libsgx_enclave_common.so.$(ECL_VER) libsgx_enclave_common.so.$(shell echo $(ECL_VER) |awk -F. '{print $$1}') && \ + ln -fs libsgx_enclave_common.so.$(shell echo $(ECL_VER) |awk -F. '{print $$1}') libsgx_enclave_common.so \ No newline at end of file diff --git a/linux/installer/common/psw/createTarball.sh b/linux/installer/common/psw/createTarball.sh index 9c19dd10..01b4b3df 100755 --- a/linux/installer/common/psw/createTarball.sh +++ b/linux/installer/common/psw/createTarball.sh @@ -65,6 +65,8 @@ python ${SCRIPT_DIR}/gen_source.py --bom=BOMs/psw_${ARCH}.txt --cleanup=false python ${SCRIPT_DIR}/gen_source.py --bom=../licenses/BOM_license.txt --cleanup=false # Create the tarball +ECL_VER=$(awk '/ENCLAVE_COMMON_VERSION/ {print $3}' ${ROOT_DIR}/common/inc/internal/se_version.h|sed 's/^\"\(.*\)\"$/\1/') pushd ${INSTALL_PATH} &> /dev/null +sed -i "s/ECL_VER=.*/ECL_VER=${ECL_VER}/" Makefile tar -zcvf ${TARBALL_NAME} * popd &> /dev/null diff --git a/linux/installer/common/psw/install.sh b/linux/installer/common/psw/install.sh index e79f1166..c0d3a00d 100755 --- a/linux/installer/common/psw/install.sh +++ b/linux/installer/common/psw/install.sh @@ -164,8 +164,10 @@ rm -fr /var/run/aesmd # Removing runtime libraries rm -f /usr/\$(get_lib)/libsgx_uae_service.so rm -f /usr/\$(get_lib)/libsgx_urts.so +rm -f /usr/\$(get_lib)/libsgx_enclave_common.so* rm -f /usr/lib/i386-linux-gnu/libsgx_uae_service.so rm -f /usr/lib/i386-linux-gnu/libsgx_urts.so +rm -f /usr/lib/i386-linux-gnu/libsgx_enclave_common.so* # Removing AESM user and group /usr/sbin/userdel aesmd 2> /dev/null diff --git a/linux/installer/common/sdk/BOMs/sdk_base.txt b/linux/installer/common/sdk/BOMs/sdk_base.txt index c47db1ce..5e811aa6 100644 --- a/linux/installer/common/sdk/BOMs/sdk_base.txt +++ b/linux/installer/common/sdk/BOMs/sdk_base.txt @@ -70,6 +70,7 @@ DeliveryName InstallName FileCheckSum FileFeature FileOwner /common/inc/tlibc/mbusafecrt.h /package/include/tlibc/mbusafecrt.h 0 main STP /common/src/se_memory.c /package/ptrace/se_memory.c 0 main STP /common/src/se_trace.c /package/ptrace/se_trace.c 0 main STP +/psw/enclave_common/sgx_enclave_common.h /package/include/./sgx_enclave_common.h 0 main STP /external/ippcp_internal/inc/ippcp.h /package/include/ipp/ippcp.h 0 main STP /external/ippcp_internal/inc/ippcpdefs.h /package/include/ipp/ippcpdefs.h 0 main STP /external/ippcp_internal/inc/ippversion.h /package/include/ipp/ippversion.h 0 main STP @@ -258,6 +259,24 @@ DeliveryName InstallName FileCheckSum FileFeature FileOwner /SampleCode/Cxx11SGXDemo/.project /package/SampleCode/Cxx11SGXDemo/.project 0 main STP /SampleCode/Cxx11SGXDemo/.cproject /package/SampleCode/Cxx11SGXDemo/.cproject 0 main STP /SampleCode/Cxx11SGXDemo/.settings/language.settings.xml /package/SampleCode/Cxx11SGXDemo/.settings/language.settings.xml 0 main STP +/SampleCode/Switchless/Makefile /package/SampleCode/Switchless/Makefile 0 N/A N/A +/SampleCode/Switchless/README.txt /package/SampleCode/Switchless/README.txt 0 N/A N/A +/SampleCode/Switchless/App/App.h /package/SampleCode/Switchless/App/App.h 0 N/A N/A +/SampleCode/Switchless/App/App.cpp /package/SampleCode/Switchless/App/App.cpp 0 N/A N/A +/SampleCode/Switchless/Enclave/Enclave.h /package/SampleCode/Switchless/Enclave/Enclave.h 0 N/A N/A +/SampleCode/Switchless/Enclave/Enclave.cpp /package/SampleCode/Switchless/Enclave/Enclave.cpp 0 N/A N/A +/SampleCode/Switchless/Enclave/Enclave.edl /package/SampleCode/Switchless/Enclave/Enclave.edl 0 N/A N/A +/SampleCode/Switchless/Enclave/Enclave.lds /package/SampleCode/Switchless/Enclave/Enclave.lds 0 N/A N/A +/SampleCode/Switchless/Enclave/Enclave.config.xml /package/SampleCode/Switchless/Enclave/Enclave.config.xml 0 N/A N/A +/SampleCode/Switchless/Enclave/Enclave_private.pem /package/SampleCode/Switchless/Enclave/Enclave_private.pem 0 N/A N/A +/SampleCode/SampleCommonLoader/Makefile /package/SampleCode/SampleCommonLoader/Makefile 0 N/A N/A +/SampleCode/SampleCommonLoader/README.txt /package/SampleCode/SampleCommonLoader/README.txt 0 N/A N/A +/SampleCode/SampleCommonLoader/App/enclave_entry.S /package/SampleCode/SampleCommonLoader/App/enclave_entry.S 0 N/A N/A +/SampleCode/SampleCommonLoader/App/sample.cpp /package/SampleCode/SampleCommonLoader/App/sample.cpp 0 N/A N/A +/SampleCode/SampleCommonLoader/Include/enclave_entry.h /package/SampleCode/SampleCommonLoader/Include/enclave_entry.h 0 N/A N/A +/SampleCode/SampleCommonLoader/Include/linux-regs.h /package/SampleCode/SampleCommonLoader/Include/linux-regs.h 0 N/A N/A +/SampleCode/SampleCommonLoader/Include/sgx_enclave_blob.h /package/SampleCode/SampleCommonLoader/Include/sgx_enclave_blob.h 0 N/A N/A +/SampleCode/SampleCommonLoader/Include/sgx_enclave_ss.h /package/SampleCode/SampleCommonLoader/Include/sgx_enclave_ss.h 0 N/A N/A /sdk/debugger_interface/linux/se_ptrace.c /package/ptrace/se_ptrace.c 0 main STP /sdk/sample_libcrypto/sample_libcrypto.h /package/SampleCode/RemoteAttestation/sample_libcrypto/sample_libcrypto.h 0 main STP /sdk/tlibstdcxx/stlport/algorithm /package/include/stlport/algorithm 0 main STP diff --git a/linux/installer/common/sdk/install.sh b/linux/installer/common/sdk/install.sh index 923acc85..39e22bb1 100755 --- a/linux/installer/common/sdk/install.sh +++ b/linux/installer/common/sdk/install.sh @@ -36,7 +36,7 @@ set -e SCRIPT_DIR=$(dirname "$0") source ${SCRIPT_DIR}/installConfig -# Generate the script to preload Intel(R) SGX ptrace library for gdb +# Generate the script to preload Intel(R) Software Guard Extensions (Intel(R) SGX) ptrace library for gdb SDK_DST_PATH=${SGX_PACKAGES_PATH}/${SDK_PKG_NAME} SDK_LIB_PATH=${SDK_DST_PATH}/${LIB_DIR} diff --git a/linux/installer/deb/libsgx-enclave-common/build.sh b/linux/installer/deb/libsgx-enclave-common/build.sh new file mode 100755 index 00000000..138ab617 --- /dev/null +++ b/linux/installer/deb/libsgx-enclave-common/build.sh @@ -0,0 +1,113 @@ +#!/usr/bin/env bash +# +# Copyright (C) 2011-2018 Intel Corporation. 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 name of Intel 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 +# OWNER 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. +# +# + + +set -e + +SCRIPT_DIR=$(dirname "$0") +ROOT_DIR="${SCRIPT_DIR}/../../../../" +LINUX_INSTALLER_DIR="${ROOT_DIR}/linux/installer" +LINUX_INSTALLER_COMMON_DIR="${LINUX_INSTALLER_DIR}/common" +LINUX_INSTALLER_COMMON_ECL_DIR="${LINUX_INSTALLER_COMMON_DIR}/libsgx-enclave-common" + +source ${LINUX_INSTALLER_COMMON_ECL_DIR}/installConfig.x64 +DEB_FOLDER=${ECL_PKG_NAME}-${ECL_VERSION} + +SGX_VERSION=$(awk '/STRFILEVER/ {print $3}' ${ROOT_DIR}/common/inc/internal/se_version.h|sed 's/^\"\(.*\)\"$/\1/') +DEB_BUILD_FOLDER=${ECL_PKG_NAME}-${SGX_VERSION} + +main() { + pre_build + create_upstream_tarball + unpack_upstream_tarball + generate_copyright_file + update_changelog_version + rename_tarball + build_deb_package + post_build +} + +pre_build() { + rm -fR ${SCRIPT_DIR}/${DEB_BUILD_FOLDER} + cp -fR ${SCRIPT_DIR}/${DEB_FOLDER} ${SCRIPT_DIR}/${DEB_BUILD_FOLDER} +} + +post_build() { + for FILE in $(ls ${SCRIPT_DIR}/*dbgsym*.deb 2> /dev/null); do + mv "${FILE}" "${FILE%.deb}".ddeb + done + rm -fR ${SCRIPT_DIR}/${DEB_BUILD_FOLDER} +} + +create_upstream_tarball() { + ${LINUX_INSTALLER_COMMON_ECL_DIR}/createTarball.sh + cp ${LINUX_INSTALLER_COMMON_ECL_DIR}/output/${TARBALL_NAME} ${SCRIPT_DIR} +} + +unpack_upstream_tarball() { + pushd ${SCRIPT_DIR}/${DEB_BUILD_FOLDER} + cp ../${TARBALL_NAME} . + tar xvf ${TARBALL_NAME} + rm -f ${TARBALL_NAME} + popd +} + +generate_copyright_file() { + pushd ${SCRIPT_DIR}/${DEB_BUILD_FOLDER} + rm -f debian/copyright + find package/licenses/ -type f -print0 | xargs -0 -n1 cat >> debian/copyright + popd +} + +update_changelog_version() { + pushd ${SCRIPT_DIR}/${DEB_BUILD_FOLDER} + + INS_VERSION=$(echo $(dpkg-parsechangelog |grep "Version" | cut -d: -f2)) + DEB_VERSION=$(echo $INS_VERSION | cut -d- -f2) + + sed -i "s/${INS_VERSION}/${SGX_VERSION}-${DEB_VERSION}/" debian/changelog + + popd +} + +rename_tarball() { + TARBALL_NAME_NEW_VERSION=$(echo ${TARBALL_NAME} | sed "s/${ECL_VERSION}/${SGX_VERSION}/") + mv ${SCRIPT_DIR}/${TARBALL_NAME} ${SCRIPT_DIR}/${TARBALL_NAME_NEW_VERSION} +} + +build_deb_package() { + pushd ${SCRIPT_DIR}/${DEB_BUILD_FOLDER} + SOURCE_DATE_EPOCH="$(date +%s)" dpkg-buildpackage -us -uc + popd +} + +main $@ diff --git a/linux/installer/deb/libsgx-enclave-common/libsgx-enclave-common-1.0/debian/changelog b/linux/installer/deb/libsgx-enclave-common/libsgx-enclave-common-1.0/debian/changelog new file mode 100644 index 00000000..fbb2855a --- /dev/null +++ b/linux/installer/deb/libsgx-enclave-common/libsgx-enclave-common-1.0/debian/changelog @@ -0,0 +1,5 @@ +libsgx-enclave-common (1.0-1) unstable; urgency=low + + * Initial release (Closes: #nnnn) + + -- TODO Tue, 09 May 2018 11:47:23 +0300 diff --git a/linux/installer/deb/libsgx-enclave-common/libsgx-enclave-common-1.0/debian/compat b/linux/installer/deb/libsgx-enclave-common/libsgx-enclave-common-1.0/debian/compat new file mode 100644 index 00000000..ec635144 --- /dev/null +++ b/linux/installer/deb/libsgx-enclave-common/libsgx-enclave-common-1.0/debian/compat @@ -0,0 +1 @@ +9 diff --git a/linux/installer/deb/libsgx-enclave-common/libsgx-enclave-common-1.0/debian/control b/linux/installer/deb/libsgx-enclave-common/libsgx-enclave-common-1.0/debian/control new file mode 100644 index 00000000..003d4712 --- /dev/null +++ b/linux/installer/deb/libsgx-enclave-common/libsgx-enclave-common-1.0/debian/control @@ -0,0 +1,14 @@ +Source: libsgx-enclave-common +Section: libs +Priority: optional +Maintainer: +Build-Depends: debhelper (>= 8.0.0) +Standards-Version: 3.9.4 +Homepage: +#Vcs-Git: git://git.debian.org/collab-maint/libsgx-enclave-common.git +#Vcs-Browser: http://git.debian.org/?p=collab-maint/libsgx-enclave-common.git;a=summary + +Package: libsgx-enclave-common +Architecture: i386 ia64 amd64 +Depends: ${shlibs:Depends}, ${misc:Depends} +Description: SGX Enclave Common Loader diff --git a/linux/installer/deb/libsgx-enclave-common/libsgx-enclave-common-1.0/debian/docs b/linux/installer/deb/libsgx-enclave-common/libsgx-enclave-common-1.0/debian/docs new file mode 100644 index 00000000..e69de29b diff --git a/linux/installer/deb/libsgx-enclave-common/libsgx-enclave-common-1.0/debian/postinst b/linux/installer/deb/libsgx-enclave-common/libsgx-enclave-common-1.0/debian/postinst new file mode 100644 index 00000000..2784b423 --- /dev/null +++ b/linux/installer/deb/libsgx-enclave-common/libsgx-enclave-common-1.0/debian/postinst @@ -0,0 +1,40 @@ +#!/usr/bin/env bash +# postinst script for libsgx-enclave-common +# +# see: dh_installdeb(1) + +set -e + +# summary of how this script can be called: +# * `configure' +# * `abort-upgrade' +# * `abort-remove' `in-favour' +# +# * `abort-remove' +# * `abort-deconfigure' `in-favour' +# `removing' +# +# for details, see http://www.debian.org/doc/debian-policy/ or +# the debian-policy package + + +case "$1" in + configure) + [[ -x /opt/intel/libsgx-enclave-common/scripts/install.sh ]] && /opt/intel/libsgx-enclave-common/scripts/install.sh + ;; + + abort-upgrade|abort-remove|abort-deconfigure) + ;; + + *) + echo "postinst called with unknown argument \`$1'" >&2 + exit 1 + ;; +esac + +# dh_installdeb will replace this with shell code automatically +# generated by other debhelper scripts. + +#DEBHELPER# + +exit 0 diff --git a/linux/installer/deb/libsgx-enclave-common/libsgx-enclave-common-1.0/debian/postrm b/linux/installer/deb/libsgx-enclave-common/libsgx-enclave-common-1.0/debian/postrm new file mode 100644 index 00000000..f25e70c5 --- /dev/null +++ b/linux/installer/deb/libsgx-enclave-common/libsgx-enclave-common-1.0/debian/postrm @@ -0,0 +1,41 @@ +#!/usr/bin/env bash +# postrm script for libsgx-enclave-common +# +# see: dh_installdeb(1) + +set -e + +# summary of how this script can be called: +# * `remove' +# * `purge' +# * `upgrade' +# * `failed-upgrade' +# * `abort-install' +# * `abort-install' +# * `abort-upgrade' +# * `disappear' +# +# for details, see http://www.debian.org/doc/debian-policy/ or +# the debian-policy package + + +case "$1" in + remove) + [[ -x /opt/intel/libsgx-enclave-common/uninstall.sh ]] && /opt/intel/libsgx-enclave-common/uninstall.sh + ;; + + purge|upgrade|failed-upgrade|abort-install|abort-upgrade|disappear) + ;; + + *) + echo "postrm called with unknown argument \`$1'" >&2 + exit 1 + ;; +esac + +# dh_installdeb will replace this with shell code automatically +# generated by other debhelper scripts. + +#DEBHELPER# + +exit 0 diff --git a/linux/installer/deb/libsgx-enclave-common/libsgx-enclave-common-1.0/debian/preinst b/linux/installer/deb/libsgx-enclave-common/libsgx-enclave-common-1.0/debian/preinst new file mode 100644 index 00000000..f5035b6e --- /dev/null +++ b/linux/installer/deb/libsgx-enclave-common/libsgx-enclave-common-1.0/debian/preinst @@ -0,0 +1,36 @@ +#!/usr/bin/env bash +# preinst script for libsgx-enclave-common +# +# see: dh_installdeb(1) + +set -e + +# summary of how this script can be called: +# * `install' +# * `install' +# * `upgrade' +# * `abort-upgrade' +# for details, see http://www.debian.org/doc/debian-policy/ or +# the debian-policy package + + +case "$1" in + install|upgrade) + [[ -x /opt/intel/sgxpsw/uninstall.sh ]] && /opt/intel/sgxpsw/uninstall.sh + ;; + + abort-upgrade) + ;; + + *) + echo "preinst called with unknown argument \`$1'" >&2 + exit 1 + ;; +esac + +# dh_installdeb will replace this with shell code automatically +# generated by other debhelper scripts. + +#DEBHELPER# + +exit 0 diff --git a/linux/installer/deb/libsgx-enclave-common/libsgx-enclave-common-1.0/debian/prerm b/linux/installer/deb/libsgx-enclave-common/libsgx-enclave-common-1.0/debian/prerm new file mode 100644 index 00000000..0da2624e --- /dev/null +++ b/linux/installer/deb/libsgx-enclave-common/libsgx-enclave-common-1.0/debian/prerm @@ -0,0 +1,38 @@ +#!/usr/bin/env bash +# prerm script for libsgx-enclave-common +# +# see: dh_installdeb(1) + +set -e + +# summary of how this script can be called: +# * `remove' +# * `upgrade' +# * `failed-upgrade' +# * `remove' `in-favour' +# * `deconfigure' `in-favour' +# `removing' +# +# for details, see http://www.debian.org/doc/debian-policy/ or +# the debian-policy package + + +case "$1" in + remove|upgrade|deconfigure) + ;; + + failed-upgrade) + ;; + + *) + echo "prerm called with unknown argument \`$1'" >&2 + exit 1 + ;; +esac + +# dh_installdeb will replace this with shell code automatically +# generated by other debhelper scripts. + +#DEBHELPER# + +exit 0 diff --git a/linux/installer/deb/libsgx-enclave-common/libsgx-enclave-common-1.0/debian/rules b/linux/installer/deb/libsgx-enclave-common/libsgx-enclave-common-1.0/debian/rules new file mode 100755 index 00000000..79fd842d --- /dev/null +++ b/linux/installer/deb/libsgx-enclave-common/libsgx-enclave-common-1.0/debian/rules @@ -0,0 +1,8 @@ +#!/usr/bin/make -f +# -*- makefile -*- + +# Uncomment this to turn on verbose mode. +#export DH_VERBOSE=1 + +%: + dh $@ diff --git a/linux/installer/deb/libsgx-enclave-common/libsgx-enclave-common-1.0/debian/source/format b/linux/installer/deb/libsgx-enclave-common/libsgx-enclave-common-1.0/debian/source/format new file mode 100644 index 00000000..163aaf8d --- /dev/null +++ b/linux/installer/deb/libsgx-enclave-common/libsgx-enclave-common-1.0/debian/source/format @@ -0,0 +1 @@ +3.0 (quilt) diff --git a/psw/ae/aesm_service/Makefile b/psw/ae/aesm_service/Makefile index 2b537fad..c128e9e8 100644 --- a/psw/ae/aesm_service/Makefile +++ b/psw/ae/aesm_service/Makefile @@ -155,8 +155,6 @@ COMMON_SRC := ./source/le/LEClass.cpp \ aesm_logic.cpp \ ./source/oal/oal_power.cpp \ aesm_rand.cpp \ - ipp_bn.cpp \ - ipp_rsa_pub_key.cpp \ ./source/oal/error_report.cpp \ ./source/oal/internal_log.cpp \ sgx_memset_s.cpp \ @@ -320,7 +318,7 @@ sqlite3.o :sqlite3.c $(CC) $(SQLITECFLAGS) $(INCLUDE) -c $< -o $@ $(APPNAME): $(OBJ) $(LIBNAME) sgx_tcrypto -lrdrand urts - $(CXX) $(CXXFLAGS) $(OBJ) $(LIBNAME) $(LDUFLAGS) $(EXTERNAL_LIB) -o $@ -ldl + $(CXX) $(CXXFLAGS) $(OBJ) $(LIBNAME) $(LDUFLAGS) $(EXTERNAL_LIB) sgx_memset_s.o -o $@ -ldl $(APPNAME_DEBUG): $(APPNAME) ifndef DEBUG diff --git a/psw/ae/aesm_service/source/aesm/application/AEClass.h b/psw/ae/aesm_service/source/aesm/application/AEClass.h index ec60d0b9..c3fbc873 100644 --- a/psw/ae/aesm_service/source/aesm/application/AEClass.h +++ b/psw/ae/aesm_service/source/aesm/application/AEClass.h @@ -32,6 +32,7 @@ #define _AE_CLASS_H_ #include "sgx_eid.h" #include "sgx_key.h" +#include "sgx_report.h" #include "se_thread.h" #include "sgx_urts.h" #include "internal/se_stdio.h" @@ -82,14 +83,18 @@ public: virtual ae_error_t load_enclave(); void unload_enclave(); + ae_error_t set_mrenclave(const sgx_measurement_t& mrenclave); + ae_error_t get_mrenclave(sgx_measurement_t& mrenclave); protected: sgx_enclave_id_t m_enclave_id; sgx_launch_token_t m_launch_token; sgx_misc_attribute_t m_attributes; + sgx_measurement_t m_mrenclave; SingletonEnclave():m_enclave_id(0) { memset(&m_launch_token, 0, sizeof(m_launch_token)); memset(&m_attributes, 0, sizeof(m_attributes)); + memset(&m_mrenclave, 0, sizeof(m_mrenclave)); } ~SingletonEnclave(){} virtual void before_enclave_load() {} @@ -151,6 +156,28 @@ void SingletonEnclave::unload_enclave() return; } +template +ae_error_t SingletonEnclave::get_mrenclave(sgx_measurement_t& mrenclave) +{ + if(0!=memcpy_s(&mrenclave, sizeof(mrenclave), &m_mrenclave, sizeof(m_mrenclave))) + { + AESM_DBG_ERROR("memcpy failed"); + return AE_FAILURE; + } + return AE_SUCCESS; +} + +template +ae_error_t SingletonEnclave::set_mrenclave(const sgx_measurement_t& mrenclave) +{ + if(0!=memcpy_s(&m_mrenclave, sizeof(m_mrenclave), &mrenclave, sizeof(mrenclave))) + { + AESM_DBG_ERROR("memcpy failed"); + return AE_FAILURE; + } + return AE_SUCCESS; +} + template T * volatile Singleton::_instance = 0; diff --git a/psw/ae/aesm_service/source/aesm/application/aesm_logic.cpp b/psw/ae/aesm_service/source/aesm/application/aesm_logic.cpp index 790c7f20..f6647ac4 100644 --- a/psw/ae/aesm_service/source/aesm/application/aesm_logic.cpp +++ b/psw/ae/aesm_service/source/aesm/application/aesm_logic.cpp @@ -270,6 +270,12 @@ void AESMLogic::service_stop() } (void)aesm_free_thread(pse_thread);//release thread handle to free memory + ae_ret = aesm_wait_thread(CPSEClass::instance().icls_thread, &thread_ret, AESM_STOP_TIMEOUT); + if (ae_ret != AE_SUCCESS || thread_ret != AE_SUCCESS) + { + AESM_DBG_INFO("aesm_wait_thread failed(icls_thread):(ae %d) (%d)", ae_ret, thread_ret); + } + (void)aesm_free_thread(CPSEClass::instance().icls_thread);//release thread handle to free memory //waiting for pending threads util timeout stop_all_long_lived_threads(0);//waiting for pending threads util timeout CPVEClass::instance().unload_enclave(); @@ -599,6 +605,22 @@ ae_error_t AESMLogic::set_psvn(uint16_t prod_id, uint16_t isv_svn, sgx_cpu_svn_t return AE_SUCCESS; } + +ae_error_t AESMLogic::set_mrenclave(const sgx_measurement_t& mrenclave, uint32_t mrsigner_index, uint16_t isv_prod_id, const sgx_attributes_t* attributes) +{ + if(mrsigner_index==PCE_MR_SIGNER){ + ae_error_t ret = CPCEClass::instance().set_mrenclave(mrenclave); + return ret; + } + else if (isv_prod_id == QE_PROD_ID && (attributes->flags & SGX_FLAGS_PROVISION_KEY) == 0) { + // this is QE + ae_error_t ret = CQEClass::instance().set_mrenclave(mrenclave); + return ret; + } + //only cache MRENCLAVE of PCE + return AE_SUCCESS; +} + sgx_status_t AESMLogic::get_launch_token(const enclave_css_t* signature, const sgx_attributes_t* attribute, sgx_launch_token_t* launch_token) @@ -676,6 +698,11 @@ sgx_status_t AESMLogic::get_launch_token(const enclave_css_t* signature, return SGX_ERROR_UNEXPECTED; } + ret_le = set_mrenclave(signature->body.enclave_hash, mrsigner_index, signature->body.isv_prod_id, attribute); + if(AE_SUCCESS != ret_le) { + AESM_DBG_ERROR("fail to save mrenclave:(ae%d)", ret_le); + return SGX_ERROR_UNEXPECTED; + } return SGX_SUCCESS; } @@ -704,6 +731,9 @@ aesm_error_t AESMLogic::create_session( } else psStatus = PlatformInfoLogic::create_session_pre_internal(); + if (AE_SUCCESS != psStatus) { + AESM_DBG_ERROR("psStatus = 0x%X in create_session", psStatus); + } if (OAL_THREAD_TIMEOUT_ERROR == psStatus){ AESM_DBG_INFO("AESM is busy in intializing for pse"); return AESM_BUSY; @@ -720,11 +750,28 @@ aesm_error_t AESMLogic::create_session( AESM_DBG_INFO("PSW software update required"); return AESM_UPDATE_AVAILABLE; } - if(AESM_AE_OUT_OF_EPC == psStatus) - return AESM_OUT_OF_EPC; + if (AESM_AE_OUT_OF_EPC == psStatus){ + AESM_DBG_INFO("AE out of EPC"); + return AESM_OUT_OF_EPC; + } + if (OAL_NETWORK_UNAVAILABLE_ERROR == psStatus){ + AESM_DBG_INFO("Network is unavailable"); + return AESM_NETWORK_ERROR; + } + if (AESM_PSDA_PLATFORM_KEYS_REVOKED == psStatus) { + AESM_DBG_INFO("This platform was revoked"); + return AESM_EPID_REVOKED_ERROR; + } + + if (PVE_PROV_ATTEST_KEY_TCB_OUT_OF_DATE == psStatus) { + AESM_DBG_INFO("TCB out of date reported by Provisioning backend"); + return AESM_UPDATE_AVAILABLE; + } + if (AE_SUCCESS != psStatus) { AESM_DBG_ERROR("psStatus = 0x%X in create_session", psStatus); } + return PSEOPAESMLogic::create_session(session_id, se_dh_msg1, se_dh_msg1_size); } diff --git a/psw/ae/aesm_service/source/aesm/application/aesm_logic.h b/psw/ae/aesm_service/source/aesm/application/aesm_logic.h index 19d7a649..385f9444 100644 --- a/psw/ae/aesm_service/source/aesm/application/aesm_logic.h +++ b/psw/ae/aesm_service/source/aesm/application/aesm_logic.h @@ -87,6 +87,7 @@ private: static bool _is_qe_psvn_set, _is_pse_psvn_set, _is_pce_psvn_set; static uint32_t active_extended_epid_group_id; static ae_error_t set_psvn(uint16_t prod_id, uint16_t isv_svn, sgx_cpu_svn_t cpu_svn, uint32_t mrsigner_index); + static ae_error_t set_mrenclave(const sgx_measurement_t& mrenclave, uint32_t mrsigner_index, uint16_t isv_prod_id, const sgx_attributes_t* attributes); static ae_error_t save_unverified_white_list(const uint8_t *white_list_cert, uint32_t white_list_cert_size); static ae_error_t get_white_list_size_without_lock(uint32_t *white_list_cert_size); public: diff --git a/psw/ae/aesm_service/source/aesm/application/event_strings.cpp b/psw/ae/aesm_service/source/aesm/application/event_strings.cpp index 5c9ac2fb..ba3df5aa 100644 --- a/psw/ae/aesm_service/source/aesm/application/event_strings.cpp +++ b/psw/ae/aesm_service/source/aesm/application/event_strings.cpp @@ -108,4 +108,5 @@ const char* g_admin_event_string_table[] = { "EPID Provisioning failed. Platform is revoked.", // SGX_ADMIN_EVENT_EPID_PROV_FAIL_REVOKED "Platform Services error, resource limit reached", // SGX_ADMIN_EVENT_PS_RESOURCE_ERROR "EPID Provisioning protocol error reported by Backend", // SGX_ADMIN_EVENT_EPID_PROV_BACKEND_PROTOCOL_ERROR + "The platform keys are revoked.", // SGX_ADMIN_EVENT_PLATFORM_REVOKED }; diff --git a/psw/ae/aesm_service/source/aesm/application/event_strings.h b/psw/ae/aesm_service/source/aesm/application/event_strings.h index c12d18b7..67c1d5d6 100644 --- a/psw/ae/aesm_service/source/aesm/application/event_strings.h +++ b/psw/ae/aesm_service/source/aesm/application/event_strings.h @@ -100,6 +100,7 @@ typedef enum { SGX_ADMIN_EVENT_EPID_PROV_FAIL_REVOKED, SGX_ADMIN_EVENT_PS_RESOURCE_ERROR, SGX_ADMIN_EVENT_EPID_PROV_BACKEND_PROTOCOL_ERROR, + SGX_ADMIN_EVENT_PLATFORM_REVOKED, }sgx_admin_event_string_table_t; extern const char* g_admin_event_string_table[]; diff --git a/psw/ae/aesm_service/source/aesm/extension/endpoint_select_info.cpp b/psw/ae/aesm_service/source/aesm/extension/endpoint_select_info.cpp index 78ad72e8..3362ca4a 100644 --- a/psw/ae/aesm_service/source/aesm/extension/endpoint_select_info.cpp +++ b/psw/ae/aesm_service/source/aesm/extension/endpoint_select_info.cpp @@ -179,7 +179,7 @@ ae_error_t EndpointSelectionInfo::get_url_info(aesm_server_url_infos_t& server_u } ae_error_t aesm_check_pek_signature(const signed_pek_t& signed_pek, const extended_epid_group_blob_t& xegb); -IppStatus get_provision_server_rsa_pub_key_in_ipp_format(const signed_pek_t& pek, IppsRSAPublicKeyState **rsa_pub_key); +sgx_status_t get_provision_server_rsa_pub_key_in_ipp_format(const signed_pek_t& pek, IppsRSAPublicKeyState **rsa_pub_key); //The function is to verify the PEK ECDSA Signature and RSA Signature for ES Msg2 // When PvE uses PEK, it will re-check the ECDSA Signature //The function will only be called after ES protocol is completed. But it will not be called when reading data back from persitent storage @@ -199,6 +199,7 @@ ae_error_t EndpointSelectionInfo::verify_signature(const endpoint_selection_info int vr = 0; uint16_t ttl=_htons(provision_ttl); IppStatus ipp_status = ippStsNoErr; + sgx_status_t sgx_status = SGX_SUCCESS; uint8_t msg_buf[XID_SIZE + sizeof(ttl) + MAX_PATH]; uint32_t buf_size = 0; extended_epid_group_blob_t xegb; @@ -223,10 +224,10 @@ ae_error_t EndpointSelectionInfo::verify_signature(const endpoint_selection_info goto ret_point; } - ipp_status = get_provision_server_rsa_pub_key_in_ipp_format(es_info.pek, &rsa_pub_key); - if(ippStsNoErr != ipp_status){ - AESM_DBG_ERROR("Fail to load rsa public key from PEK:%d", ipp_status); - ae_err = ipp_error_to_ae_error(ipp_status); + sgx_status = get_provision_server_rsa_pub_key_in_ipp_format(es_info.pek, &rsa_pub_key); + if(SGX_SUCCESS != sgx_status){ + AESM_DBG_ERROR("Fail to load rsa public key from PEK:%d", sgx_status); + ae_err = sgx_error_to_ae_error(sgx_status); goto ret_point; } ipp_status = ippsRSA_GetBufferSizePublicKey(&public_key_buffer_size, rsa_pub_key); diff --git a/psw/ae/aesm_service/source/aesm/extension/platform_info_logic.cpp b/psw/ae/aesm_service/source/aesm/extension/platform_info_logic.cpp index 28d53b2f..23c589c4 100644 --- a/psw/ae/aesm_service/source/aesm/extension/platform_info_logic.cpp +++ b/psw/ae/aesm_service/source/aesm/extension/platform_info_logic.cpp @@ -147,6 +147,10 @@ ae_error_t PlatformInfoLogic::check_ltp_thread_func(bool& is_new_pairing) { return AESM_AE_OUT_OF_EPC; } + case AESM_PSDA_PLATFORM_KEYS_REVOKED: + { + return AESM_PSDA_PLATFORM_KEYS_REVOKED; + } case AESM_NPC_NO_PSE_CERT: case AESM_LTP_PSE_CERT_REVOKED: case PSE_PAIRING_BLOB_UNSEALING_ERROR: @@ -186,6 +190,7 @@ ae_error_t PlatformInfoLogic::check_ltp_thread_func(bool& is_new_pairing) case OAL_PROXY_SETTING_ASSIST: case AESM_AE_OUT_OF_EPC: case OAL_THREAD_TIMEOUT_ERROR: + case AESM_PSDA_PLATFORM_KEYS_REVOKED: { AESM_DBG_ERROR("long_term_pairing Return: (ae0x%X)", ltpStatus); psStatus = ltpStatus; @@ -300,6 +305,9 @@ ae_error_t PlatformInfoLogic::create_session_pre_internal(void) case AESM_AE_OUT_OF_EPC: AESM_LOG_ERROR_ADMIN("%s", g_admin_event_string_table[SGX_ADMIN_EVENT_PS_INIT_FAIL]); break; + case AESM_PSDA_PLATFORM_KEYS_REVOKED: + AESM_LOG_ERROR_ADMIN("%s", g_admin_event_string_table[SGX_ADMIN_EVENT_PLATFORM_REVOKED]); + break; case AESM_PCP_NEED_PSE_UPDATE: case AESM_PCP_PSE_CERT_PROVISIONING_ATTESTATION_FAILURE_NEED_EPID_UPDATE: case AESM_PCP_PSE_CERT_PROVISIONING_ATTESTATION_FAILURE_MIGHT_NEED_EPID_UPDATE: @@ -379,6 +387,7 @@ ae_error_t PlatformInfoLogic::update_pse_thread_func(const platform_info_blob_wr case OAL_PROXY_SETTING_ASSIST: case PSW_UPDATE_REQUIRED: case AESM_AE_OUT_OF_EPC: + case AESM_PSDA_PLATFORM_KEYS_REVOKED: { AESM_DBG_TRACE("long_term_pairing Return: (ae%d)", ltpStatus); retVal = ltpStatus; @@ -627,6 +636,8 @@ aesm_error_t PlatformInfoLogic::report_attestation_status( return AESM_BUSY; case PVE_PROV_ATTEST_KEY_NOT_FOUND: return AESM_UNRECOGNIZED_PLATFORM; + case PVE_PROV_ATTEST_KEY_TCB_OUT_OF_DATE: + return AESM_UPDATE_AVAILABLE; case OAL_PROXY_SETTING_ASSIST: // don't log an error here return AESM_PROXY_SETTING_ASSIST; @@ -636,6 +647,9 @@ aesm_error_t PlatformInfoLogic::report_attestation_status( case AESM_AE_OUT_OF_EPC: AESM_LOG_ERROR_ADMIN("%s", g_admin_event_string_table[SGX_ADMIN_EVENT_PS_INIT_FAIL_LTP]); return AESM_OUT_OF_EPC; + case AESM_PSDA_PLATFORM_KEYS_REVOKED: + AESM_LOG_ERROR_ADMIN("%s", g_admin_event_string_table[SGX_ADMIN_EVENT_PLATFORM_REVOKED]); + return AESM_EPID_REVOKED_ERROR; case AESM_LTP_SIMPLE_LTP_ERROR: default: AESM_LOG_ERROR_ADMIN("%s", g_admin_event_string_table[SGX_ADMIN_EVENT_PS_INIT_FAIL_LTP]); diff --git a/psw/ae/aesm_service/source/aesm_wrapper/src/AESMQueueManager.cpp b/psw/ae/aesm_service/source/aesm_wrapper/src/AESMQueueManager.cpp index e6f663da..4a93760c 100644 --- a/psw/ae/aesm_service/source/aesm_wrapper/src/AESMQueueManager.cpp +++ b/psw/ae/aesm_service/source/aesm_wrapper/src/AESMQueueManager.cpp @@ -80,7 +80,8 @@ void AESMQueueManager::enqueue(RequestData* requestData) } }else { - delete requestData; + if(requestData != NULL) + delete requestData; AESM_LOG_ERROR("Malformed request received (May be forged for attack)"); } } diff --git a/psw/ae/aesm_service/source/epid_provision/epid_provision_msg1.cpp b/psw/ae/aesm_service/source/epid_provision/epid_provision_msg1.cpp index 4c0afe0e..4b049837 100644 --- a/psw/ae/aesm_service/source/epid_provision/epid_provision_msg1.cpp +++ b/psw/ae/aesm_service/source/epid_provision/epid_provision_msg1.cpp @@ -59,7 +59,7 @@ //the key is received in endpoint selection from Provision Server which is used for rsa-oaep in ProvMsg1 //secure_free_rsa_pub_key should be called to release the memory on successfully returned rsa_pub_key //return PVEC_SUCCESS on success -IppStatus get_provision_server_rsa_pub_key_in_ipp_format(const signed_pek_t& pek, IppsRSAPublicKeyState **rsa_pub_key); +sgx_status_t get_provision_server_rsa_pub_key_in_ipp_format(const signed_pek_t& pek, IppsRSAPublicKeyState **rsa_pub_key); //Function to initialize request header for ProvMsg1 @@ -266,9 +266,9 @@ ret_point: } //transform rsa format PEK public key of Provision Server into IPP library format IppsRSAPublicKeyState *rsa_pub_key = NULL; - IppStatus ippStatus = get_provision_server_rsa_pub_key_in_ipp_format(pve_data.pek, &rsa_pub_key); - if( ippStsNoErr != ippStatus){ - AESM_DBG_ERROR("Fail to decode PEK:%d",ippStatus); + sgx_status = get_provision_server_rsa_pub_key_in_ipp_format(pve_data.pek, &rsa_pub_key); + if( SGX_SUCCESS != sgx_status){ + AESM_DBG_ERROR("Fail to decode PEK:%d",sgx_status); return AE_FAILURE; } uint8_t field0[RSA_3072_KEY_BYTES]; diff --git a/psw/ae/aesm_service/source/epid_provision/epid_utility.cpp b/psw/ae/aesm_service/source/epid_provision/epid_utility.cpp index 9aa170cf..21fa339b 100644 --- a/psw/ae/aesm_service/source/epid_provision/epid_utility.cpp +++ b/psw/ae/aesm_service/source/epid_provision/epid_utility.cpp @@ -112,6 +112,7 @@ ae_error_t check_epid_pve_pg_status_after_mac_verification(const provision_resp case SE_PRS_STATUS_INTEGRITY_FAILED: return PVE_INTEGRITY_CHECK_ERROR; case SE_PRS_PLATFORM_REVOKED: + case SE_PRS_PROV_ATTEST_KEY_REVOKED: return PVE_REVOKED_ERROR; case SE_PRS_PERFORMANCE_REKEY_NOT_SUPPORTED: return PVE_PERFORMANCE_REKEY_NOT_SUPPORTED; @@ -119,6 +120,8 @@ ae_error_t check_epid_pve_pg_status_after_mac_verification(const provision_resp return PVE_PROV_ATTEST_KEY_NOT_FOUND; case SE_PRS_INVALID_REPORT: return PVE_INVALID_REPORT; + case SE_PRS_PROV_ATTEST_KEY_TCB_OUT_OF_DATE: + return PVE_PROV_ATTEST_KEY_TCB_OUT_OF_DATE; default: return PVE_SERVER_REPORTED_ERROR; } diff --git a/psw/ae/aesm_service/source/oal/internal_log.cpp b/psw/ae/aesm_service/source/oal/internal_log.cpp index 79b88a90..00c41933 100644 --- a/psw/ae/aesm_service/source/oal/internal_log.cpp +++ b/psw/ae/aesm_service/source/oal/internal_log.cpp @@ -522,6 +522,9 @@ static const char *get_ae_error_t_string(ae_error_t ae_error) CASE_ENUM_RET_STRING(LE_WHITE_LIST_QUERY_BUSY) CASE_ENUM_RET_STRING(AESM_AE_NO_DEVICE) CASE_ENUM_RET_STRING(EXTENDED_GROUP_NOT_AVAILABLE) + CASE_ENUM_RET_STRING(LE_WHITE_LIST_ALREADY_UPDATED) + CASE_ENUM_RET_STRING(PCE_CRYPTO_ERROR) + CASE_ENUM_RET_STRING(PVE_PROV_ATTEST_KEY_TCB_OUT_OF_DATE) default: return "Unknown ae_error_t"; } diff --git a/psw/ae/aesm_service/source/pce/PCEClass.cpp b/psw/ae/aesm_service/source/pce/PCEClass.cpp index df69e7ff..7f3d200c 100644 --- a/psw/ae/aesm_service/source/pce/PCEClass.cpp +++ b/psw/ae/aesm_service/source/pce/PCEClass.cpp @@ -54,9 +54,6 @@ void CPCEClass::before_enclave_load() { uint32_t CPCEClass::get_pce_target( sgx_target_info_t *p_pce_target) { - token_t *p_token = - reinterpret_cast(&m_launch_token); - /* We need to make sure the PCE is successfully loaded and then we can use the cached attributes and launch token. */ assert(m_enclave_id); @@ -66,8 +63,7 @@ uint32_t CPCEClass::get_pce_target( memcpy_s(&p_pce_target->misc_select, sizeof(p_pce_target->misc_select), &m_attributes.misc_select, sizeof(m_attributes.misc_select)); memcpy_s(&p_pce_target->mr_enclave, sizeof(p_pce_target->mr_enclave), - &p_token->body.mr_enclave, - sizeof(p_token->body.mr_enclave)); + &m_mrenclave, sizeof(m_mrenclave)); return AE_SUCCESS; } diff --git a/psw/ae/aesm_service/source/pse_op/PSEClass.cpp b/psw/ae/aesm_service/source/pse_op/PSEClass.cpp index 5dc02d4f..0ddf3554 100644 --- a/psw/ae/aesm_service/source/pse_op/PSEClass.cpp +++ b/psw/ae/aesm_service/source/pse_op/PSEClass.cpp @@ -67,6 +67,21 @@ extern uint32_t upse_iclsInit(); +static ae_error_t thread_to_init_icls(aesm_thread_arg_type_t arg) +{ + UNUSED(arg); + AESM_DBG_INFO("start to init_icls"); + // Just ignore the return value because the ME may still be working + uint32_t status_provision = upse_iclsInit(); + if (status_provision != 0) + { + // Provisioning failed , maybe caused by missing of iCls client, etc. + AESM_LOG_INFO_ADMIN("%s", g_admin_event_string_table[SGX_ADMIN_EVENT_PS_INIT_START]); + // This is logged as a WARNING here, since the system may not require PS capability + AESM_LOG_INFO_ADMIN("%s", g_admin_event_string_table[SGX_ADMIN_EVENT_PS_INIT_FAIL_DAL]); + } + return AE_SUCCESS; +} ae_error_t CPSEClass::init_ps(void) { // Try to establish PSDA session during startup @@ -88,36 +103,57 @@ ae_error_t CPSEClass::init_ps(void) //Logic here is that ME FW mode is used(Emulator is not running) //provisioning is attempted using iclsclient and the return code is not verified //In case of emulator the emulator provisioning tool is used to provision for epid 1.1 and if not long term pairing will return not provisioned error. - - // Always call upse_iclsInit because TCB recovery may occur - // Ignore the return value because the ME may still be working - uint32_t status_provision = upse_iclsInit(); - if (status_provision != 0) - { - // Provisioning failed , maybe caused by missing of iCls client, etc. - AESM_LOG_INFO_ADMIN("%s", g_admin_event_string_table[SGX_ADMIN_EVENT_PS_INIT_START]); - // This is logged as a WARNING here, since the system may not require PS capability - AESM_LOG_WARN_ADMIN("%s", g_admin_event_string_table[SGX_ADMIN_EVENT_PS_INIT_FAIL_DAL]); - } - pse_pr_interface_psda* pPSDA = new(std::nothrow) pse_pr_interface_psda(); - if (pPSDA == NULL) { + if (pPSDA == NULL) + { return AE_OUT_OF_MEMORY_ERROR; } + // Will fail if CSME is not provisioned ae_error_t ret = pPSDA->get_csme_gid(&PSDAService::instance().csme_gid); + bool bCalledIcls = false; + if (ret != AE_SUCCESS) + { + // As long as get_csme_gid fails, call iclsInit to trigger provisioning + uint32_t status_provision = upse_iclsInit(); + bCalledIcls = true; + if (status_provision != 0) + { + // Provisioning failed , maybe caused by missing of iCls client, etc. + AESM_LOG_INFO_ADMIN("%s", g_admin_event_string_table[SGX_ADMIN_EVENT_PS_INIT_START]); + // This is logged as a WARNING here, since the system may not require PS capability + AESM_LOG_WARN_ADMIN("%s", g_admin_event_string_table[SGX_ADMIN_EVENT_PS_INIT_FAIL_DAL]); + delete pPSDA; + pPSDA = NULL; + return AESM_PSE_PR_PSDA_PROVISION_ERROR; + } + else + { + // try to get CSME GID again + ret = pPSDA->get_csme_gid(&PSDAService::instance().csme_gid); + if (ret != AE_SUCCESS) + { + // Failed to get CSME GID + AESM_LOG_INFO_ADMIN("%s", g_admin_event_string_table[SGX_ADMIN_EVENT_PS_INIT_START]); + // This is logged as a WARNING here, since the system may not require PS capability + AESM_LOG_WARN_ADMIN("%s", g_admin_event_string_table[SGX_ADMIN_EVENT_PS_INIT_FAIL_DAL]); + delete pPSDA; + pPSDA = NULL; + return ret; + } + } + } delete pPSDA; pPSDA = NULL; - if (ret != AE_SUCCESS) + if (!bCalledIcls) { - // Failed to get CSME GID - AESM_LOG_INFO_ADMIN("%s", g_admin_event_string_table[SGX_ADMIN_EVENT_PS_INIT_START]); - // This is logged as a WARNING here, since the system may not require PS capability - AESM_LOG_WARN_ADMIN("%s", g_admin_event_string_table[SGX_ADMIN_EVENT_PS_INIT_FAIL_DAL]); - return ret; + // call iclsInit in a separate thread to trigger re-key if iclsInit was not called + ae_error_t ae_thread_ret = aesm_create_thread(thread_to_init_icls, 0, &icls_thread); + if (AE_SUCCESS != ae_thread_ret) { + AESM_DBG_WARN("Fail to create thread to init icls:( ae %d)", ae_thread_ret); + } } - // Set state to PROVISIONED m_status = PSE_STATUS_CSE_PROVISIONED; diff --git a/psw/ae/aesm_service/source/pse_op/PSEClass.h b/psw/ae/aesm_service/source/pse_op/PSEClass.h index 74050f18..fdb07f9c 100644 --- a/psw/ae/aesm_service/source/pse_op/PSEClass.h +++ b/psw/ae/aesm_service/source/pse_op/PSEClass.h @@ -60,6 +60,7 @@ protected: m_status = PSE_STATUS_INIT; m_ps_cap = PS_CAP_NOT_AVAILABLE; m_freq = se_get_tick_count_freq(); + icls_thread = NULL; }; ~CPSEClass(){ }; @@ -70,6 +71,7 @@ protected: uint64_t m_ps_cap; uint64_t m_freq; public: + aesm_thread_t icls_thread; ae_error_t init_ps(void); ae_error_t create_session( diff --git a/psw/ae/aesm_service/source/pse_op/pse_op_logic.cpp b/psw/ae/aesm_service/source/pse_op/pse_op_logic.cpp index 6c794007..8f8fd1aa 100644 --- a/psw/ae/aesm_service/source/pse_op/pse_op_logic.cpp +++ b/psw/ae/aesm_service/source/pse_op/pse_op_logic.cpp @@ -179,6 +179,7 @@ ae_error_t PSEOPAESMLogic::certificate_provisioning_and_long_term_pairing_func(b case AE_SUCCESS: case OAL_PROXY_SETTING_ASSIST: case AESM_AE_OUT_OF_EPC: + case AESM_PSDA_PLATFORM_KEYS_REVOKED: return ltpStatus; // for below errors need to check cert status case AESM_NPC_NO_PSE_CERT: @@ -213,6 +214,7 @@ ae_error_t PSEOPAESMLogic::certificate_provisioning_and_long_term_pairing_func(b case OAL_PROXY_SETTING_ASSIST: case AESM_AE_OUT_OF_EPC: case OAL_THREAD_TIMEOUT_ERROR: + case AESM_PSDA_PLATFORM_KEYS_REVOKED: psStatus = ltpStatus; break; @@ -266,6 +268,8 @@ static aesm_error_t redo_long_term_pairing( return AESM_BUSY; case PVE_PROV_ATTEST_KEY_NOT_FOUND: return AESM_UNRECOGNIZED_PLATFORM; + case PVE_PROV_ATTEST_KEY_TCB_OUT_OF_DATE: + return AESM_UPDATE_AVAILABLE; case OAL_PROXY_SETTING_ASSIST: return AESM_PROXY_SETTING_ASSIST; case PSW_UPDATE_REQUIRED: diff --git a/psw/ae/aesm_service/source/pve/pve_logic.cpp b/psw/ae/aesm_service/source/pve/pve_logic.cpp index d6748d4a..26fce708 100644 --- a/psw/ae/aesm_service/source/pve/pve_logic.cpp +++ b/psw/ae/aesm_service/source/pve/pve_logic.cpp @@ -275,6 +275,7 @@ aesm_error_t PvEAESMLogic::pve_error_postprocess(ae_error_t ae_error) case AE_OUT_OF_MEMORY_ERROR: return AESM_OUT_OF_MEMORY_ERROR; case PSW_UPDATE_REQUIRED: + case PVE_PROV_ATTEST_KEY_TCB_OUT_OF_DATE: return AESM_UPDATE_AVAILABLE; case AESM_AE_OUT_OF_EPC: return AESM_OUT_OF_EPC; diff --git a/psw/ae/aesm_service/source/qe/QEClass.cpp b/psw/ae/aesm_service/source/qe/QEClass.cpp index 67d581e1..7588eabc 100644 --- a/psw/ae/aesm_service/source/qe/QEClass.cpp +++ b/psw/ae/aesm_service/source/qe/QEClass.cpp @@ -61,8 +61,8 @@ uint32_t CQEClass::get_qe_target( memcpy_s(&p_qe_target->misc_select, sizeof(p_qe_target->misc_select), &m_attributes.misc_select, sizeof(m_attributes.misc_select)); memcpy_s(&p_qe_target->mr_enclave, sizeof(p_qe_target->mr_enclave), - &p_launch->body.mr_enclave, - sizeof(p_launch->body.mr_enclave)); + &m_mrenclave, + sizeof(m_mrenclave)); return AE_SUCCESS; } diff --git a/psw/ae/aesm_service/source/qe/qe_logic.cpp b/psw/ae/aesm_service/source/qe/qe_logic.cpp index 12ba63de..a30a4c94 100644 --- a/psw/ae/aesm_service/source/qe/qe_logic.cpp +++ b/psw/ae/aesm_service/source/qe/qe_logic.cpp @@ -136,6 +136,17 @@ aesm_error_t QEAESMLogic::init_quote( aesm_result = AESM_UNEXPECTED_ERROR; goto ret_point; } + if (epid_data.cur_pi.pve_svn == 4) { // Detect the EPID blob is provisioned by PSW 1.6 + sgx_sealed_data_t *sealed_epid = reinterpret_cast(epid_data.trusted_epid_blob); + uint32_t plain_text_offset = sealed_epid->plain_text_offset; + se_plaintext_epid_data_sdk_t* plain_text_sdk = reinterpret_cast(epid_data.trusted_epid_blob + sizeof(sgx_sealed_data_t) + plain_text_offset); + if(plain_text_sdk->epid_key_version == EPID_KEY_BLOB_VERSION_SDK){ // Detect the EPID blob has been converted into SDK format, which is problematic + (void)epid_blob.remove(); + if (AESM_SUCCESS != (aesm_result = try_reprovision_if_not(updated, epid_data))) { + goto ret_point; + } + } + } se_static_assert(SGX_TRUSTED_EPID_BLOB_SIZE_SDK>=SGX_TRUSTED_EPID_BLOB_SIZE_SIK); ae_ret = static_cast(CQEClass::instance().verify_blob(epid_data.trusted_epid_blob, SGX_TRUSTED_EPID_BLOB_SIZE_SDK, diff --git a/psw/ae/aesm_service/source/upse/BackendInterface/pse_crypto_helper.cpp b/psw/ae/aesm_service/source/upse/BackendInterface/pse_crypto_helper.cpp index 22977eaa..1d7d567c 100644 --- a/psw/ae/aesm_service/source/upse/BackendInterface/pse_crypto_helper.cpp +++ b/psw/ae/aesm_service/source/upse/BackendInterface/pse_crypto_helper.cpp @@ -83,20 +83,20 @@ const public_key_t& CertificateProvisioningProtocol::get_intel_pek() //Function to get the rsa public key of intel backend server for IPP functions //The output rsa_pub_key should be released by function free_rsa_key -static IppStatus get_intel_rsa_pub_key_in_ipp_format(const public_key_t& publicKey, IppsRSAPublicKeyState **rsa_pub_key) +static sgx_status_t get_intel_rsa_pub_key_in_ipp_format(const public_key_t& publicKey, IppsRSAPublicKeyState **rsa_pub_key) { if (sizeof(publicKey.n) != RSA_3072_KEY_BYTES) - return ippStsSizeErr; + return SGX_ERROR_INVALID_PARAMETER; if (NULL == rsa_pub_key) - return ippStsNullPtrErr; + return SGX_ERROR_INVALID_PARAMETER; - IppStatus status = create_rsa_pub_key( + sgx_status_t status = sgx_create_rsa_pub_key( sizeof(publicKey.n), sizeof(publicKey.e), - (const Ipp32u*)publicKey.n, - (const Ipp32u*)&publicKey.e, - rsa_pub_key); + (const unsigned char*)publicKey.n, + (const unsigned char*)&publicKey.e, + (void **)rsa_pub_key); return status; } @@ -266,8 +266,7 @@ ae_error_t CertificateProvisioningProtocol::encryptRSA_OAEP_SHA256(const public_ do { - ippReturnStatus = get_intel_rsa_pub_key_in_ipp_format(publicKey, &rsa_pub_key); - if (ippStsNoErr != ippReturnStatus) + if(SGX_SUCCESS != get_intel_rsa_pub_key_in_ipp_format(publicKey, &rsa_pub_key)) break; uint8_t seed[IPP_SHA256_DIGEST_BITSIZE / 8]; diff --git a/psw/ae/common/pve_pub_key.cpp b/psw/ae/common/pve_pub_key.cpp index f2b04875..e4eae6e8 100644 --- a/psw/ae/common/pve_pub_key.cpp +++ b/psw/ae/common/pve_pub_key.cpp @@ -50,13 +50,13 @@ static void get_provision_server_rsa_key_little_endian_order(const signed_pek_t& //Function to get the rsa public key of backend server for IPP functions //The output rsa_pub_key should be released by function free_rsa_key -IppStatus get_provision_server_rsa_pub_key_in_ipp_format(const signed_pek_t& pek, IppsRSAPublicKeyState **rsa_pub_key) +sgx_status_t get_provision_server_rsa_pub_key_in_ipp_format(const signed_pek_t& pek, IppsRSAPublicKeyState **rsa_pub_key) { signed_pek_t little_endian_key; get_provision_server_rsa_key_little_endian_order(pek, little_endian_key); - return create_rsa_pub_key(RSA_3072_KEY_BYTES, + return sgx_create_rsa_pub_key(RSA_3072_KEY_BYTES, sizeof(little_endian_key.e), - reinterpret_cast(little_endian_key.n), - reinterpret_cast(&little_endian_key.e), - rsa_pub_key); + reinterpret_cast(little_endian_key.n), + reinterpret_cast(&little_endian_key.e), + reinterpret_cast(rsa_pub_key)); } diff --git a/psw/ae/common/se_ecdsa_verify_internal.cpp b/psw/ae/common/se_ecdsa_verify_internal.cpp index 0b5ed8eb..9657af53 100644 --- a/psw/ae/common/se_ecdsa_verify_internal.cpp +++ b/psw/ae/common/se_ecdsa_verify_internal.cpp @@ -115,7 +115,7 @@ sgx_status_t se_ecdsa_verify_internal( const int order_size = sizeof(g_nistp256_r); - ipp_ret = newBN(g_nistp256_r, order_size, &p_bn_ecp_order); + ipp_ret = sgx_ipp_newBN(g_nistp256_r, order_size, &p_bn_ecp_order); if(ipp_ret != ippStsNoErr) { ret = SGX_ERROR_UNEXPECTED; @@ -124,7 +124,7 @@ sgx_status_t se_ecdsa_verify_internal( memcpy(sig_rl_hash_le, p_sig_rl_hash->hash, sizeof(sig_rl_hash_le)); SWAP_ENDIAN_32B(sig_rl_hash_le); - ipp_ret = newBN(sig_rl_hash_le, sizeof(sig_rl_hash_le), + ipp_ret = sgx_ipp_newBN(sig_rl_hash_le, sizeof(sig_rl_hash_le), &p_bn_sig_rl_hash); if(ipp_ret != ippStsNoErr) { @@ -132,7 +132,7 @@ sgx_status_t se_ecdsa_verify_internal( goto CLEANUP; } - ipp_ret = newBN(0, order_size, &p_bn_sig_rl_msg); + ipp_ret = sgx_ipp_newBN(0, order_size, &p_bn_sig_rl_msg); if(ipp_ret != ippStsNoErr) { ret = SGX_ERROR_UNEXPECTED; @@ -146,7 +146,7 @@ sgx_status_t se_ecdsa_verify_internal( goto CLEANUP; } - ipp_ret = newBN(p_signature->x, order_size, &p_bn_sign_x); + ipp_ret = sgx_ipp_newBN(p_signature->x, order_size, &p_bn_sign_x); if(ipp_ret != ippStsNoErr) { ret = SGX_ERROR_UNEXPECTED; @@ -154,7 +154,7 @@ sgx_status_t se_ecdsa_verify_internal( } // Create a Big Number whose value is zero - ipp_ret = newBN(&zero, sizeof(zero), &p_bn_zero); + ipp_ret = sgx_ipp_newBN(&zero, sizeof(zero), &p_bn_zero); if(ipp_ret != ippStsNoErr) { ret = SGX_ERROR_UNEXPECTED; @@ -176,7 +176,7 @@ sgx_status_t se_ecdsa_verify_internal( goto CLEANUP; } - ipp_ret = newBN(p_signature->y, order_size, &p_bn_sign_y); + ipp_ret = sgx_ipp_newBN(p_signature->y, order_size, &p_bn_sign_y); if(ipp_ret != ippStsNoErr) { ret = SGX_ERROR_UNEXPECTED; @@ -197,14 +197,14 @@ sgx_status_t se_ecdsa_verify_internal( goto CLEANUP; } - ipp_ret = newBN((Ipp32u *)p_pubkey->gx, order_size, &p_bn_p_x); + ipp_ret = sgx_ipp_newBN((Ipp32u *)p_pubkey->gx, order_size, &p_bn_p_x); if(ipp_ret != ippStsNoErr) { ret = SGX_ERROR_UNEXPECTED; goto CLEANUP; } - ipp_ret = newBN((Ipp32u *)p_pubkey->gy, order_size, &p_bn_p_y); + ipp_ret = sgx_ipp_newBN((Ipp32u *)p_pubkey->gy, order_size, &p_bn_p_y); if(ipp_ret != ippStsNoErr) { ret = SGX_ERROR_UNEXPECTED; diff --git a/psw/ae/cse_provision_tool/cse_provision_tool.cpp b/psw/ae/cse_provision_tool/cse_provision_tool.cpp index 755649c9..89ae4e6d 100644 --- a/psw/ae/cse_provision_tool/cse_provision_tool.cpp +++ b/psw/ae/cse_provision_tool/cse_provision_tool.cpp @@ -57,11 +57,11 @@ static char USAGE_STRING[] = \ "Invoke iclsclient to provision CSE Fw. Root privilege is required.\n"; static char MISSING_STRING[] = \ - "libiclsclient.so or iclsInit() cannot be found.\n"\ + "Optional modules libiclsclient.so or iclsInit() cannot be found.\n"\ "Trusted platform service is unavailable. Refer to README for details.\n"; static char ERR_STRING[] = \ - "iclsInit() returned error.\n"\ + "Optional modules iclsInit() returned error.\n"\ "Trusted platform service is unavailable. "\ "Check log in /opt/Intel/iclsClient/log/iclsClient.log.\n"; diff --git a/psw/ae/inc/aeerror.h b/psw/ae/inc/aeerror.h index c2074ce6..88b2f817 100644 --- a/psw/ae/inc/aeerror.h +++ b/psw/ae/inc/aeerror.h @@ -273,6 +273,10 @@ typedef enum _ae_error_t{ PSE_OP_ERROR_KDF_MISMATCH =212, LE_WHITE_LIST_ALREADY_UPDATED =213, + + PCE_CRYPTO_ERROR =215, + + PVE_PROV_ATTEST_KEY_TCB_OUT_OF_DATE =216, } ae_error_t; #define AE_FAILED(x) (AE_SUCCESS != (x)) diff --git a/psw/ae/inc/internal/tlv_common.h b/psw/ae/inc/internal/tlv_common.h index c416dec7..e14357c9 100644 --- a/psw/ae/inc/internal/tlv_common.h +++ b/psw/ae/inc/internal/tlv_common.h @@ -144,7 +144,9 @@ enum _se_protocol_response_status_t SE_PRS_PROVISIONING_ERROR, SE_PRS_INVALID_REQUEST, SE_PRS_PROV_ATTEST_KEY_NOT_FOUND, - SE_PRS_INVALID_REPORT + SE_PRS_INVALID_REPORT, + SE_PRS_PROV_ATTEST_KEY_REVOKED, + SE_PRS_PROV_ATTEST_KEY_TCB_OUT_OF_DATE }; typedef uint16_t pse_protocol_response_status_t; diff --git a/psw/ae/pce/Makefile b/psw/ae/pce/Makefile index 12117435..f11af8d1 100644 --- a/psw/ae/pce/Makefile +++ b/psw/ae/pce/Makefile @@ -52,8 +52,6 @@ TCRYPTO_LIBDIR := $(LINUX_SDK_DIR)/tlibcrypto EXTERNAL_LIB += -L$(TCRYPTO_LIBDIR) -lsgx_tcrypto SRC := $(wildcard *.cpp) -SRC += ipp_bn.cpp \ - ipp_rsa_pub_key.cpp OBJ := $(SRC:.cpp=.o) OBJS := $(sort $(OBJ) version.o) diff --git a/psw/ae/pce/pce.cpp b/psw/ae/pce/pce.cpp index f8966b18..a5579a4e 100644 --- a/psw/ae/pce/pce.cpp +++ b/psw/ae/pce/pce.cpp @@ -139,7 +139,7 @@ uint32_t get_pc_info(const sgx_report_t* report, //verify the report data is SHA256(crypto_suite||public_key)||0-padding if(memcmp(hash_buf, &report->body.report_data, sizeof(report->body.report_data))!=0){ - return AE_INVALID_PARAMETER; + return PCE_CRYPTO_ERROR; } ppid_t ppid_buf; @@ -169,16 +169,16 @@ uint32_t get_pc_info(const sgx_report_t* report, le_n[i] = *(public_key + RSA_MOD_SIZE - 1 - i);//create little endian n } - ipp_ret = create_rsa_pub_key(RSA_MOD_SIZE, RSA_E_SIZE, - reinterpret_cast(le_n), - &little_endian_e, - &pub_key); + sgx_ret = sgx_create_rsa_pub_key(RSA_MOD_SIZE, RSA_E_SIZE, + reinterpret_cast(le_n), + reinterpret_cast(&little_endian_e), + reinterpret_cast(&pub_key)); free(le_n); - if (ippStsMemAllocErr == ipp_ret){ + if (SGX_ERROR_OUT_OF_MEMORY == sgx_ret){ ae_ret = AE_OUT_OF_MEMORY_ERROR; goto RETURN_POINT; } - else if(ippStsNoErr != ipp_ret){//possible invalid rsa public key + else if(SGX_SUCCESS != sgx_ret){//possible invalid rsa public key ae_ret = AE_FAILURE; goto RETURN_POINT; } diff --git a/psw/ae/pce/pce_helper.cpp b/psw/ae/pce/pce_helper.cpp index 67f3ead0..9fe90333 100644 --- a/psw/ae/pce/pce_helper.cpp +++ b/psw/ae/pce/pce_helper.cpp @@ -204,16 +204,16 @@ ae_error_t get_pce_priv_key( goto ret_point; \ } - ipp_status = newBN(reinterpret_cast(hash_drg_output), HASH_DRBG_OUT_LEN, &bn_d); + ipp_status = sgx_ipp_newBN(reinterpret_cast(hash_drg_output), HASH_DRBG_OUT_LEN, &bn_d); IPP_ERROR_TRANS(ipp_status); - ipp_status = newBN(reinterpret_cast(sgx_nistp256_r_m1), sizeof(sgx_nistp256_r_m1), &bn_m);//generate mod to be n-1 where n is order of ECC Group + ipp_status = sgx_ipp_newBN(reinterpret_cast(sgx_nistp256_r_m1), sizeof(sgx_nistp256_r_m1), &bn_m);//generate mod to be n-1 where n is order of ECC Group IPP_ERROR_TRANS(ipp_status); - ipp_status = newBN(NULL, sizeof(sgx_nistp256_r_m1), &bn_o);//alloc memory for output + ipp_status = sgx_ipp_newBN(NULL, sizeof(sgx_nistp256_r_m1), &bn_o);//alloc memory for output IPP_ERROR_TRANS(ipp_status); ipp_status = ippsMod_BN(bn_d, bn_m, bn_o); IPP_ERROR_TRANS(ipp_status); i=1; - ipp_status = newBN(&i, sizeof(uint32_t), &bn_one);//create big number 1 + ipp_status = sgx_ipp_newBN(&i, sizeof(uint32_t), &bn_one);//create big number 1 IPP_ERROR_TRANS(ipp_status); ipp_status = ippsAdd_BN(bn_o, bn_one, bn_o);//added by 1 @@ -224,16 +224,16 @@ ae_error_t get_pce_priv_key( IPP_ERROR_TRANS(ipp_status); ret_point: if(NULL!=bn_d){ - secure_free_BN(bn_d, HASH_DRBG_OUT_LEN); + sgx_ipp_secure_free_BN(bn_d, HASH_DRBG_OUT_LEN); } if(NULL!=bn_m){ - secure_free_BN(bn_m, sizeof(sgx_nistp256_r_m1)); + sgx_ipp_secure_free_BN(bn_m, sizeof(sgx_nistp256_r_m1)); } if(NULL!=bn_o){ - secure_free_BN(bn_o, sizeof(sgx_nistp256_r_m1)); + sgx_ipp_secure_free_BN(bn_o, sizeof(sgx_nistp256_r_m1)); } if(NULL!=bn_one){ - secure_free_BN(bn_one, sizeof(uint32_t)); + sgx_ipp_secure_free_BN(bn_one, sizeof(uint32_t)); } (void)memset_s(&key_tmp, sizeof(key_tmp), 0, sizeof(key_tmp)); (void)memset_s(&hash_drg_output, sizeof(hash_drg_output), 0, sizeof(hash_drg_output)); diff --git a/psw/ae/pse/pse_pr/X509Parser.cpp b/psw/ae/pse/pse_pr/X509Parser.cpp index 96919f0a..e3cfedd4 100644 --- a/psw/ae/pse/pse_pr/X509Parser.cpp +++ b/psw/ae/pse/pse_pr/X509Parser.cpp @@ -121,13 +121,19 @@ UINT32 X509Parser::ParseGroupCertificate uint8_t gidArray[sizeof(GroupId)] = {0}; if (certificateFields->serialNumber.length > sizeof(gidArray)) + { + status = X509_GENERAL_ERROR; break; + } int index = static_cast(sizeof(gidArray)-certificateFields->serialNumber.length); memcpy(&gidArray[index], certificateFields->serialNumber.buffer, certificateFields->serialNumber.length); if(certificateFields->algorithmIdentifierForSubjectPublicKey != X509_intel_sigma_epidGroupPublicKey_epid11)//Only Epid Group Public Key Epid1.1 are permitted to be subject key + { + status = X509_GENERAL_ERROR; break; + } SessMgrEpidGroupPublicKey* EpidKey = (SessMgrEpidGroupPublicKey*)certificateFields->subjectPublicKey.buffer; diff --git a/psw/ae/pse/pse_pr/include/prepare_hmac_sha256.h b/psw/ae/pse/pse_pr/include/prepare_hmac_sha256.h index b364cf2d..5c29a1e3 100644 --- a/psw/ae/pse/pse_pr/include/prepare_hmac_sha256.h +++ b/psw/ae/pse/pse_pr/include/prepare_hmac_sha256.h @@ -54,6 +54,8 @@ private: IppStatus m_ippstatus; IppsHMACState *m_pCtx; + int m_nSizeCtx; + // Disable class operations (default constructor, copy constructor, assignment operator, and address-of operator) PrepareHMACSHA256(); // default constructor diff --git a/psw/ae/pse/pse_pr/prepare_hmac_sha256.cpp b/psw/ae/pse/pse_pr/prepare_hmac_sha256.cpp index d5cbdfda..5a8b450d 100644 --- a/psw/ae/pse/pse_pr/prepare_hmac_sha256.cpp +++ b/psw/ae/pse/pse_pr/prepare_hmac_sha256.cpp @@ -30,13 +30,13 @@ */ #include "prepare_hmac_sha256.h" +#include "sgx_memset_s.h" #include PrepareHMACSHA256::PrepareHMACSHA256(const Ipp8u* key, size_t keyLength) - : m_ippstatus(ippStsNoErr), m_pCtx(0) + : m_ippstatus(ippStsNoErr), m_pCtx(0), m_nSizeCtx(0) { - int size; do { @@ -46,11 +46,11 @@ PrepareHMACSHA256::PrepareHMACSHA256(const Ipp8u* key, size_t keyLength) break; } - m_ippstatus = ippsHMAC_GetSize(&size); + m_ippstatus = ippsHMAC_GetSize(&m_nSizeCtx); if (m_ippstatus != ippStsNoErr) break; - m_pCtx = (IppsHMACState*) malloc(size); + m_pCtx = (IppsHMACState*) malloc(m_nSizeCtx); if (NULL == m_pCtx) { m_ippstatus = ippStsNoMemErr; @@ -67,6 +67,8 @@ PrepareHMACSHA256::PrepareHMACSHA256(const Ipp8u* key, size_t keyLength) m_ippstatus = ippsHMAC_Init(key, (int)keyLength, m_pCtx, IPP_ALG_HASH_SHA256); if (m_ippstatus != ippStsNoErr) { + // clear secret for defense-in-depth + memset_s(m_pCtx, m_nSizeCtx, 0, m_nSizeCtx); free(m_pCtx); m_pCtx = NULL; break; @@ -77,6 +79,8 @@ PrepareHMACSHA256::PrepareHMACSHA256(const Ipp8u* key, size_t keyLength) PrepareHMACSHA256::~PrepareHMACSHA256(void) { if (m_pCtx) { + // clear secret for defense-in-depth + memset_s(m_pCtx, m_nSizeCtx, 0, m_nSizeCtx); free(m_pCtx); m_pCtx = NULL; } diff --git a/psw/ae/pve/Makefile b/psw/ae/pve/Makefile index c9ebacba..76e9486f 100644 --- a/psw/ae/pve/Makefile +++ b/psw/ae/pve/Makefile @@ -55,9 +55,7 @@ EXTERNAL_LIB += -L$(EPID_LIBDIR)/epid/member -lmember \ -L$(TCRYPTO_LIBDIR) -lsgx_tcrypto SRC := $(wildcard *.cpp) -SRC += ipp_bn.cpp \ - ipp_rsa_pub_key.cpp \ - se_ecdsa_verify_internal.cpp \ +SRC += se_ecdsa_verify_internal.cpp \ pve_qe_common.cpp \ pve_pub_key.cpp \ pek_pub_key.cpp diff --git a/psw/ae/pve/cipher.cpp b/psw/ae/pve/cipher.cpp index a9a18d2d..b35e61c3 100644 --- a/psw/ae/pve/cipher.cpp +++ b/psw/ae/pve/cipher.cpp @@ -85,16 +85,16 @@ pve_status_t gen_epid_priv_f( se_static_assert(sizeof(FpElemStr)%4==0); /*sizeof FpElemStr should be multiple of 4*/ se_static_assert(PRIV_F_RAND_SIZE%4==0); /*the number of bytes of random number should be multiple of 4*/ //First create the mod P which is in little endian - ipp_status = newBN(NULL, sizeof(FpElemStr), &p_BN);//initialize integer buffer + ipp_status = sgx_ipp_newBN(NULL, sizeof(FpElemStr), &p_BN);//initialize integer buffer IPP_ERROR_BREAK(ipp_status); ipp_status = ippsSetOctString_BN(p_data, sizeof(FpElemStr), p_BN);//Input data in Bigendian format IPP_ERROR_BREAK(ipp_status); - ipp_status = newBN(NULL, sizeof(FpElemStr), &r_BN);//create buffer to hold temp and output result + ipp_status = sgx_ipp_newBN(NULL, sizeof(FpElemStr), &r_BN);//create buffer to hold temp and output result IPP_ERROR_BREAK(ipp_status); //initialize a lower bound - ipp_status = newBN(reinterpret_cast(&lower_bound), sizeof(lower_bound), &h_BN); + ipp_status = sgx_ipp_newBN(reinterpret_cast(&lower_bound), sizeof(lower_bound), &h_BN); IPP_ERROR_BREAK(ipp_status); - ipp_status = newBN(reinterpret_cast(&diff), sizeof(diff), &d_BN);//2*PRIV_F_LOWER_BOUND-1 + ipp_status = sgx_ipp_newBN(reinterpret_cast(&diff), sizeof(diff), &d_BN);//2*PRIV_F_LOWER_BOUND-1 IPP_ERROR_BREAK(ipp_status); //random generate a number f with 96 bits extra data // to make sure the output result f%(p_data-(2*PRIV_F_LOWER_BOUND-1)) is uniform distributed @@ -104,7 +104,7 @@ pve_status_t gen_epid_priv_f( } ipp_status = ippsSub_BN(p_BN, d_BN, r_BN);// r = p_data - (2*PRIV_F_LOWER_BOUND-1) IPP_ERROR_BREAK(ipp_status); - ipp_status = newBN(reinterpret_cast(f_temp_buf), static_cast(PRIV_F_RAND_SIZE), &f_BN);//create big number by f + ipp_status = sgx_ipp_newBN(reinterpret_cast(f_temp_buf), static_cast(PRIV_F_RAND_SIZE), &f_BN);//create big number by f IPP_ERROR_BREAK(ipp_status); ipp_status = ippsMod_BN(f_BN, r_BN, p_BN); //calculate p_BN = f (mod r_BN=(p_data - (2*PRIV_F_LOWER_BOUND-1))) IPP_ERROR_BREAK(ipp_status); @@ -115,11 +115,11 @@ pve_status_t gen_epid_priv_f( IPP_ERROR_BREAK(ipp_status); ret_point: (void)memset_s(f_temp_buf, sizeof(f_temp_buf), 0, sizeof(f_temp_buf)); - secure_free_BN(h_BN, sizeof(lower_bound));//free big integer securely (The function will also memset_s the buffer) - secure_free_BN(f_BN, static_cast(PRIV_F_RAND_SIZE)); - secure_free_BN(p_BN, sizeof(FpElemStr)); - secure_free_BN(r_BN,sizeof(FpElemStr)); - secure_free_BN(d_BN, sizeof(diff)); + sgx_ipp_secure_free_BN(h_BN, sizeof(lower_bound));//free big integer securely (The function will also memset_s the buffer) + sgx_ipp_secure_free_BN(f_BN, static_cast(PRIV_F_RAND_SIZE)); + sgx_ipp_secure_free_BN(p_BN, sizeof(FpElemStr)); + sgx_ipp_secure_free_BN(r_BN,sizeof(FpElemStr)); + sgx_ipp_secure_free_BN(d_BN, sizeof(diff)); return ret; } diff --git a/psw/ae/pve/provision_msg3.cpp b/psw/ae/pve/provision_msg3.cpp index 598b4426..e1e99dc3 100644 --- a/psw/ae/pve/provision_msg3.cpp +++ b/psw/ae/pve/provision_msg3.cpp @@ -468,8 +468,8 @@ pve_status_t gen_prov_msg3_data(const proc_prov_msg2_blob_input_t *msg2_blob_inp le_n[i]=pek.n[sizeof(pek.n)/sizeof(pek.n[0])-i-1]; } - ipp_status = create_rsa_pub_key(sizeof(pek.n), sizeof(pek.e), - reinterpret_cast(le_n), &le_e, &pub_key); + ipp_status = sgx_create_rsa_pub_key(sizeof(pek.n), sizeof(pek.e), + reinterpret_cast(le_n), reinterpret_cast(&le_e), reinterpret_cast(&pub_key)); if(ippStsNoErr != ipp_status){ ret = ipp_error_to_pve_error(ipp_status); goto ret_point; diff --git a/psw/ae/qe/Makefile b/psw/ae/qe/Makefile index 3656d805..b53be5d3 100644 --- a/psw/ae/qe/Makefile +++ b/psw/ae/qe/Makefile @@ -47,9 +47,7 @@ INCLUDE += -I$(LINUX_PSW_DIR)/ae/data/constants/linux \ -I$(LINUX_PSW_DIR)/ae/inc/internal SRC := $(wildcard *.cpp) -SRC += ipp_bn.cpp \ - ipp_rsa_pub_key.cpp \ - se_ecdsa_verify_internal.cpp \ +SRC += se_ecdsa_verify_internal.cpp \ se_sig_rl.cpp \ pve_qe_common.cpp diff --git a/psw/ae/qe/quoting_enclave.cpp b/psw/ae/qe/quoting_enclave.cpp index 4afd19a0..ae2e9572 100644 --- a/psw/ae/qe/quoting_enclave.cpp +++ b/psw/ae/qe/quoting_enclave.cpp @@ -118,6 +118,7 @@ static ae_error_t verify_blob_internal( + sizeof(secret_epid_data) + sizeof(plaintext_epid_data)] = {0}; + MemberCtx *p_ctx = NULL; do { // We will use plaintext_old_format as buffer to hold the output of sgx_unseal_data. @@ -196,25 +197,25 @@ static ae_error_t verify_blob_internal( /* Create EPID member context if required. PvE is responsible for verifying the Cert signature before storing them in the EPID blob. */ - if (create_context) + if (create_context || is_old_format) { EpidStatus epid_ret = kEpidNoErr; - epid_ret = epid_member_create(rand_func, NULL, NULL, pp_epid_context); + epid_ret = epid_member_create(rand_func, NULL, NULL, &p_ctx); BREAK_IF_TRUE(kEpidNoErr != epid_ret, ret, QE_UNEXPECTED_ERROR); - epid_ret = EpidProvisionKey(*pp_epid_context, + epid_ret = EpidProvisionKey(p_ctx, &(plaintext_epid_data.epid_group_cert), (PrivKey*)&(secret_epid_data.epid_private_key), is_old_format ? NULL : &secret_epid_data.member_precomp_data); BREAK_IF_TRUE(kEpidNoErr != epid_ret, ret, QE_UNEXPECTED_ERROR); // start member - epid_ret = EpidMemberStartup(*pp_epid_context); + epid_ret = EpidMemberStartup(p_ctx); BREAK_IF_TRUE(kEpidNoErr != epid_ret, ret, QE_UNEXPECTED_ERROR); if (is_old_format) { - epid_ret = EpidMemberWritePrecomp(*pp_epid_context, &secret_epid_data.member_precomp_data); + epid_ret = EpidMemberWritePrecomp(p_ctx, &secret_epid_data.member_precomp_data); BREAK_IF_TRUE(kEpidNoErr != epid_ret, ret, QE_UNEXPECTED_ERROR); } } @@ -248,9 +249,16 @@ static ae_error_t verify_blob_internal( // Clear the output buffer to make sure nothing leaks. memset_s(&secret_epid_data, sizeof(secret_epid_data), 0, sizeof(secret_epid_data)); - if (ret != AE_SUCCESS) - { - epid_member_delete(pp_epid_context); + if (AE_SUCCESS != ret) { + if (p_ctx) + epid_member_delete(&p_ctx); + } + else if (!create_context) { + if (p_ctx) + epid_member_delete(&p_ctx); + } + else { + *pp_epid_context = p_ctx; } return ret; @@ -381,7 +389,7 @@ static ae_error_t qe_epid_sign( (uint8_t *)const_cast(p_basename), sizeof(*p_basename), &basic_sig, - NULL); + NULL); //Random basename, can be NULL if basename is provided if(kEpidNoErr != epid_ret) { ret = QE_UNEXPECTED_ERROR; @@ -473,12 +481,12 @@ static ae_error_t qe_epid_sign( } //Start encrypt the wrap key by RSA IPP algorithm. - ipp_ret = create_rsa_pub_key(sizeof(g_qsdk_pub_key_n), + se_ret = sgx_create_rsa_pub_key(sizeof(g_qsdk_pub_key_n), sizeof(g_qsdk_pub_key_e), - g_qsdk_pub_key_n, - g_qsdk_pub_key_e, - &pub_key); - if(ipp_ret != ippStsNoErr) + (const unsigned char *)g_qsdk_pub_key_n, + (const unsigned char *)g_qsdk_pub_key_e, + (void **)&pub_key); + if(se_ret != SGX_SUCCESS) { ret = QE_UNEXPECTED_ERROR; goto CLEANUP; @@ -666,7 +674,7 @@ static ae_error_t qe_epid_sign( epid_ret = EpidNrProve(p_epid_context, (uint8_t *)const_cast(p_quote_body), (uint32_t)QE_QUOTE_BODY_SIZE, - (uint8_t *)const_cast(p_basename), + (uint8_t *)const_cast(p_basename), // basename is required, otherwise it will return kEpidBadArgErr sizeof(*p_basename), &basic_sig, // Basic signature with 'b' and 'k' in it &entry, //Single entry in SigRl composed of 'b' and 'k' diff --git a/psw/enclave_common/Makefile b/psw/enclave_common/Makefile new file mode 100644 index 00000000..14e1d992 --- /dev/null +++ b/psw/enclave_common/Makefile @@ -0,0 +1,117 @@ +# +# Copyright (C) 2011-2018 Intel Corporation. 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 name of Intel 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 +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +# +# + +include ../../buildenv.mk + +ECL_VER:= $(shell awk '$$2 ~ /ENCLAVE_COMMON_VERSION/ { print substr($$3, 2, length($$3) - 2); }' $(COMMON_DIR)/inc/internal/se_version.h) +ECL_MAJOR_VER:= $(shell echo $(ECL_VER) |awk -F. '{print $$1}') + +ifndef DEBUG +CXXFLAGS += -DDISABLE_TRACE +CFLAGS += -DDISABLE_TRACE +endif + +CXXFLAGS += -fPIC -Werror -g +CXXFLAGS += $(ADDED_INC) + +CFLAGS += -fPIC -Werror -g +CFLAGS += $(ADDED_INC) + +INC += -I$(COMMON_DIR)/inc \ + -I$(COMMON_DIR)/inc/internal \ + -I$(COMMON_DIR)/inc/internal/linux \ + -I$(LINUX_PSW_DIR)/urts/ \ + -I$(LINUX_PSW_DIR)/urts/linux \ + -I$(LINUX_PSW_DIR)/enclave_common + +LDFLAGS := -lwrapper +LDFLAGS += -Wl,-Bdynamic -lsgx_uae_service +LDFLAGS += $(COMMON_LDFLAGS) -Wl,--version-script=sgx_enclave_common.lds -Wl,--gc-sections + +DIR1 := $(LINUX_PSW_DIR)/enclave_common +DIR2 := $(LINUX_PSW_DIR)/urts/linux + +LIB += -L$(COMMON_DIR)/se_wrapper \ + -L$(BUILD_DIR) + +OBJ := sgx_enclave_common.o edmm_utility.o + + +vpath %.cpp $(DIR1):$(DIR2) + +LIBWRAPPER := libwrapper.a +LIBSGX_ENCLAVE_COMMON := libsgx_enclave_common.so +LIBSGX_ENCLAVE_COMMON_DEBUG := libsgx_enclave_common.so.debug +LIBSGX_ENCLAVE_COMMON_STATIC := libsgx_enclave_common.a + +.PHONY: all +all: $(LIBENCLAVE_COMMON) $(LIBSGX_ENCLAVE_COMMON_DEBUG) $(LIBSGX_ENCLAVE_COMMON_STATIC) | $(BUILD_DIR) + @$(CP) $(LIBSGX_ENCLAVE_COMMON) $| + @$(CP) $(LIBSGX_ENCLAVE_COMMON_STATIC) $| +ifndef DEBUG + @$(CP) $(LIBSGX_ENCLAVE_COMMON_DEBUG) $| +endif + +$(LIBSGX_ENCLAVE_COMMON): $(OBJ) $(LIBWRAPPER) uae_service + $(CXX) $(CXXFLAGS) -shared -Wl,-soname=$@.$(ECL_MAJOR_VER) $(LIB) -o $@ $(OBJ) $(LDFLAGS) + +$(LIBSGX_ENCLAVE_COMMON_STATIC): $(OBJ) $(LIBWRAPPER) uae_service + $(CP) $(COMMON_DIR)/se_wrapper/libwrapper.a $@ + $(AR) rcs $@ $(OBJ) + +$(LIBSGX_ENCLAVE_COMMON_DEBUG): $(LIBSGX_ENCLAVE_COMMON) +ifndef DEBUG + $(CP) $(LIBSGX_ENCLAVE_COMMON) $(LIBSGX_ENCLAVE_COMMON).orig + $(OBJCOPY) --only-keep-debug $(LIBSGX_ENCLAVE_COMMON) $(LIBSGX_ENCLAVE_COMMON_DEBUG) + $(STRIP) -g $(LIBSGX_ENCLAVE_COMMON) + $(OBJCOPY) --add-gnu-debuglink=$(LIBSGX_ENCLAVE_COMMON_DEBUG) $(LIBSGX_ENCLAVE_COMMON) +endif + +$(OBJ): %.o: %.cpp + $(CXX) -c $(CXXFLAGS) $(INC) $< -o $@ + +$(LIBWRAPPER): + $(MAKE) -C $(COMMON_DIR)/se_wrapper/ + +.PHONY:uae_service +uae_service: + $(MAKE) -C $(LINUX_PSW_DIR)/uae_service/linux + +$(BUILD_DIR): + @$(MKDIR) $@ + +.PHONY: clean +clean:: + @$(RM) *.o $(LIBSGX_ENCLAVE_COMMON) $(LIBSGX_ENCLAVE_COMMON_DEBUG) $(LIBSGX_ENCLAVE_COMMON_STATIC) + @$(RM) $(BUILD_DIR)/$(LIBSGX_ENCLAVE_COMMON) $(BUILD_DIR)/$(LIBSGX_ENCLAVE_COMMON_DEBUG) $(BUILD_DIR)/$(LIBSGX_ENCLAVE_COMMON_STATIC) + @$(RM) $(LIBSGX_ENCLAVE_COMMON).orig $(BUILD_DIR)/$(LIBSGX_ENCLAVE_COMMON_DEBUG) + $(MAKE) -C $(COMMON_DIR)/se_wrapper/ clean + $(MAKE) -C $(LINUX_PSW_DIR)/uae_service/linux/ clean diff --git a/psw/enclave_common/sgx_enclave_common.cpp b/psw/enclave_common/sgx_enclave_common.cpp new file mode 100644 index 00000000..e55b1d3f --- /dev/null +++ b/psw/enclave_common/sgx_enclave_common.cpp @@ -0,0 +1,558 @@ +/* + * Copyright (C) 2011-2018 Intel Corporation. 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 name of Intel 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 + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#include "sgx_enclave_common.h" +#include "arch.h" +#include "edmm_utility.h" +#include "isgx_user.h" +#include "se_error_internal.h" +#include "se_map.h" +#include "se_thread.h" +#include "se_trace.h" +#include "uae_service_internal.h" +#include "util.h" +#include +#include +#include +#include + +#define POINTER_TO_U64(A) ((__u64)((uintptr_t)(A))) + +static se_file_handle_t s_hdevice = -1; +static bool s_is_kernel_driver = false; +static se_mutex_t s_device_mutex; + +static std::map s_enclave_size; +static std::map s_enclave_init; +static std::map s_secs_attr; +static se_mutex_t s_enclave_mutex; + +typedef struct _mem_region_t { + void* addr; + size_t len; + int prot; +} mem_region_t; + +static std::map s_enclave_mem_region; + +extern "C" bool open_device(void) +{ + se_mutex_lock(&s_device_mutex); + if (s_hdevice != -1) { + se_mutex_unlock(&s_device_mutex); + return true; + } + + if (true == open_se_device(&s_hdevice, &s_is_kernel_driver)) { + se_mutex_unlock(&s_device_mutex); + return true; + } + + s_hdevice = -1; + s_is_kernel_driver = false; + se_mutex_unlock(&s_device_mutex); + + return false; +} + +extern "C" void close_device(void) +{ + se_mutex_lock(&s_device_mutex); + + close_se_device(&s_hdevice); + s_is_kernel_driver = false; + + se_mutex_unlock(&s_device_mutex); +} + +static void __attribute__((constructor)) enclave_init(void) +{ + se_mutex_init(&s_device_mutex); + se_mutex_init(&s_enclave_mutex); +} + +static void __attribute__((destructor)) enclave_fini(void) +{ + close_device(); + se_mutex_destroy(&s_device_mutex); + se_mutex_destroy(&s_enclave_mutex); +} + +static uint32_t error_driver2api(int driver_error) +{ + uint32_t ret = ENCLAVE_UNEXPECTED; + + switch (driver_error) { + case SGX_INVALID_SIG_STRUCT: + ret = ENCLAVE_INVALID_SIG_STRUCT; + break; + case SGX_INVALID_SIGNATURE: + ret = ENCLAVE_INVALID_SIGNATURE; + break; + case SGX_INVALID_ATTRIBUTE: + ret = ENCLAVE_INVALID_ATTRIBUTE; + break; + case SGX_INVALID_MEASUREMENT: + ret = ENCLAVE_INVALID_MEASUREMENT; + break; + case (int)SGX_POWER_LOST_ENCLAVE: + ret = ENCLAVE_LOST; + break; + case SGX_UNMASKED_EVENT: + ret = ENCLAVE_RETRY; + break; + case SGX_INVALID_PRIVILEGE: + ret = ENCLAVE_NOT_AUTHORIZED; + break; + case (int)-ENOMEM: + ret = ENCLAVE_OUT_OF_MEMORY; + break; + case (int)-EINVAL: + ret = ENCLAVE_INVALID_PARAMETER; + break; + case (int)-EEXIST: + ret = ENCLAVE_INVALID_ADDRESS; + break; + default: + SE_TRACE(SE_TRACE_WARNING, "unexpected error %#x from driver, should be driver bug\n", driver_error); + ret = ENCLAVE_UNEXPECTED; + break; + } + + return ret; +} + +/* enclave_create() + * Parameters: + * base_address [in, optional] - An optional preferred base address for the enclave. + * virtual_size [in] - The virtual address range of the enclave in bytes. + * initial_commit[in] - The amount of physical memory to reserve for the initial load of the enclave in bytes. + * type [in] - The architecture type of the enclave that you want to create. + * info [in] - A pointer to the architecture-specific information to use to create the enclave. + * info_size [in] - The length of the structure that the info parameter points to, in bytes. + * enclave_error [out, optional] - An optional pointer to a variable that receives an enclave error code. + * Return Value: + * If the function succeeds, the return value is the base address of the created enclave. + * If the function fails, the return value is NULL. The extended error information will be in the enclave_error parameter if used. +*/ +extern "C" void* COMM_API enclave_create( + COMM_IN_OPT void* base_address, + COMM_IN size_t virtual_size, + COMM_IN size_t initial_commit, + COMM_IN uint32_t type, + COMM_IN const void* info, + COMM_IN size_t info_size, + COMM_OUT_OPT uint32_t* enclave_error) +{ + UNUSED(initial_commit); + + if ((type != ENCLAVE_TYPE_SGX1 && type != ENCLAVE_TYPE_SGX2) || info == NULL) { + if (enclave_error != NULL) + *enclave_error = ENCLAVE_INVALID_PARAMETER; + return NULL; + } + + const enclave_create_sgx_t* enclave_create_sgx = (const enclave_create_sgx_t*)info; + if (info_size == 0 || sizeof(*enclave_create_sgx) != info_size) { + if (enclave_error != NULL) + *enclave_error = ENCLAVE_INVALID_PARAMETER; + return NULL; + } + + secs_t* secs = (secs_t*)enclave_create_sgx->secs; + SE_TRACE(SE_TRACE_DEBUG, "\n secs->attibutes.flags = %llx, secs->attributes.xfrm = %llx \n", secs->attributes.flags, secs->attributes.xfrm); + + if (false == open_device()) { + if (enclave_error != NULL) + *enclave_error = ENCLAVE_NOT_SUPPORTED; + return NULL; + } + + void* enclave_base = mmap(base_address, virtual_size, PROT_NONE, MAP_SHARED, s_hdevice, 0); + if (enclave_base == MAP_FAILED) { + SE_TRACE(SE_TRACE_WARNING, "\ncreate enclave: mmap failed, errno = %d\n", errno); + if (enclave_error != NULL) + *enclave_error = ENCLAVE_OUT_OF_MEMORY; + return NULL; + } + + secs->base = enclave_base; + + struct sgx_enclave_create param = { 0 }; + param.src = POINTER_TO_U64(secs); + + int ret = ioctl(s_hdevice, SGX_IOC_ENCLAVE_CREATE, ¶m); + if (ret) { + SE_TRACE(SE_TRACE_WARNING, "\nSGX_IOC_ENCLAVE_CREATE failed: errno = %d\n", errno); + if (enclave_error != NULL) + *enclave_error = error_driver2api(ret); + return NULL; + } + + se_mutex_lock(&s_enclave_mutex); + + s_enclave_size[enclave_base] = virtual_size; + + sgx_attributes_t secs_attr; + memset(&secs_attr, 0, sizeof(sgx_attributes_t)); + memcpy(&secs_attr, &secs->attributes, sizeof(sgx_attributes_t)); + s_secs_attr[enclave_base] = secs_attr; + + s_enclave_mem_region[enclave_base].addr = 0; + s_enclave_mem_region[enclave_base].len = 0; + s_enclave_mem_region[enclave_base].prot = 0; + + se_mutex_unlock(&s_enclave_mutex); + + if (enclave_error != NULL) + *enclave_error = ENCLAVE_ERROR_SUCCESS; + return enclave_base; +} + +/* enclave_load_data() + * Parameters: + * target_address [in] - The address in the enclave where you want to load the data. + * target_size [in] - The size of the range that you want to load in the enclave, in bytes. + * source_buffer [in, optional] - An optional pointer to the data you want to load into the enclave. + * data_properties [in] - The properties of the pages you want to add to the enclave. + * enclave_error [out, optional] - An optional pointer to a variable that receives an enclave error code. + * Return Value: + * The return value is the number of bytes that was loaded into the enclave. + * If the number is different than target_size parameter an error occurred. The extended error information will be in the enclave_error parameter if used. +*/ +extern "C" size_t COMM_API enclave_load_data( + COMM_IN void* target_address, + COMM_IN size_t target_size, + COMM_IN_OPT const void* source_buffer, + COMM_IN uint32_t data_properties, + COMM_OUT_OPT uint32_t* enclave_error) +{ + if (target_address == NULL || ((uint64_t)(target_address) & ((1 << SE_PAGE_SHIFT) - 1)) != 0 || target_size < SE_PAGE_SIZE || target_size % SE_PAGE_SIZE != 0) { + if (enclave_error != NULL) + *enclave_error = ENCLAVE_INVALID_PARAMETER; + return 0; + } + + uint8_t* source = (uint8_t*)source_buffer; + if (source == NULL) { + source = (uint8_t*)malloc(target_size); + if (source == NULL) { + if (enclave_error != NULL) + *enclave_error = ENCLAVE_UNEXPECTED; + return 0; + } + + memset(source, 0, target_size); + } + + sec_info_t sec_info; + memset(&sec_info, 0, sizeof(sec_info_t)); + + sec_info.flags = data_properties; + if (!(sec_info.flags & ENCLAVE_PAGE_THREAD_CONTROL)) + sec_info.flags |= SI_FLAG_REG; + if (sec_info.flags & ENCLAVE_PAGE_UNVALIDATED) + sec_info.flags ^= ENCLAVE_PAGE_UNVALIDATED; + + size_t pages = target_size / SE_PAGE_SIZE; + for (size_t i = 0; i < pages; i++) { + struct sgx_enclave_add_page addp = { 0, 0, 0, 0 }; + addp.addr = POINTER_TO_U64((uint8_t*)target_address + SE_PAGE_SIZE * i); + addp.src = POINTER_TO_U64(source + SE_PAGE_SIZE * i); + addp.secinfo = POINTER_TO_U64(&sec_info); + if (!(data_properties & ENCLAVE_PAGE_UNVALIDATED)) + addp.mrmask |= 0xFFFF; + + int ret = ioctl(s_hdevice, SGX_IOC_ENCLAVE_ADD_PAGE, &addp); + if (ret) { + SE_TRACE(SE_TRACE_WARNING, "\nAdd Page - %p to %p... FAIL\n", source, target_address); + if (source_buffer == NULL && source != NULL) + free(source); + + if (enclave_error != NULL) + *enclave_error = error_driver2api(ret); + return SE_PAGE_SIZE * i; + } + } + + if (source_buffer == NULL && source != NULL) + free(source); + + int prot = (int)(sec_info.flags & SI_MASK_MEM_ATTRIBUTE); + // find the enclave base + void* enclave_base = NULL; + + for (auto rec : s_enclave_size) { + if ((uint64_t)target_address >= (uint64_t)rec.first && (uint64_t)target_address < (uint64_t)rec.first + (uint64_t)rec.second) { + enclave_base = (void*)rec.first; + break; + } + } + + if (enclave_base == NULL) { + if (enclave_error != NULL) + *enclave_error = ENCLAVE_INVALID_ENCLAVE; + return 0; + } + + se_mutex_lock(&s_enclave_mutex); + auto enclave_mem_region = &s_enclave_mem_region[enclave_base]; + se_mutex_unlock(&s_enclave_mutex); + + void* next_page = (void*)((uint64_t)enclave_mem_region->addr + (uint64_t)enclave_mem_region->len); + if ((enclave_mem_region->prot != prot) || (target_address != next_page)) { + if (enclave_mem_region->addr != 0) { + //the new load of enclave data either has a different protection or is not contiguous with the last one, mprotect the range stored in memory region structure + if (0 != mprotect(enclave_mem_region->addr, enclave_mem_region->len, enclave_mem_region->prot)) { + if (enclave_error != NULL) + *enclave_error = ENCLAVE_UNEXPECTED; + return 0; + } + } + //record the current load of enclave data in the memory region structure + enclave_mem_region->addr = target_address; + enclave_mem_region->len = target_size; + enclave_mem_region->prot = prot; + } else { + //this load of enclave data is extending the memory region + enclave_mem_region->len += target_size; + } + + if (enclave_error != NULL) + *enclave_error = ENCLAVE_ERROR_SUCCESS; + return target_size; +} + +/* enclave_initialize() + * Parameters: + * base_address [in] - The enclave base address as returned from the enclave_create API. + * info [in] - A pointer to the architecture-specific information to use to initialize the enclave. + * info_size [in] - The length of the structure that the info parameter points to, in bytes. + * enclave_error [out, optional] - An optional pointer to a variable that receives an enclave error code. + * Return Value: + * non-zero - The function succeeds. + * zero - The function fails and the extended error information will be in the enclave_error parameter if used. +*/ +extern "C" bool COMM_API enclave_initialize( + COMM_IN void* base_address, + COMM_IN const void* info, + COMM_IN size_t info_size, + COMM_OUT_OPT uint32_t* enclave_error) +{ + if (base_address == NULL || info == NULL) { + if (enclave_error != NULL) + *enclave_error = ENCLAVE_INVALID_PARAMETER; + return false; + } + + const enclave_init_sgx_t* enclave_init_sgx = (const enclave_init_sgx_t*)info; + if (info_size == 0 || sizeof(*enclave_init_sgx) != info_size) { + if (enclave_error != NULL) + *enclave_error = ENCLAVE_INVALID_PARAMETER; + return false; + } + + //mprotect the last region + se_mutex_lock(&s_enclave_mutex); + auto enclave_mem_region = &s_enclave_mem_region[base_address]; + se_mutex_unlock(&s_enclave_mutex); + if (enclave_mem_region->addr != 0) { + //the new load of enclave data either has a different protection or is not contiguous with the last one, mprotect the range stored in memory region structure + if (0 != mprotect(enclave_mem_region->addr, enclave_mem_region->len, enclave_mem_region->prot)) { + if (enclave_error != NULL) + *enclave_error = ENCLAVE_UNEXPECTED; + return 0; + } + //record the current load of enclave data in the memory region structure + enclave_mem_region->addr = 0; //just in case we need to call enclave_initialize twice + } + + int ret = 0; + if (s_is_kernel_driver == false) { + se_mutex_lock(&s_enclave_mutex); + std::map::iterator it = s_secs_attr.find(base_address); + if (it == s_secs_attr.end()) { + se_mutex_unlock(&s_enclave_mutex); + if (enclave_error != NULL) + *enclave_error = ENCLAVE_INVALID_PARAMETER; + return false; + } + se_mutex_unlock(&s_enclave_mutex); + + sgx_launch_token_t launch_token; + memset(launch_token, 0, sizeof(sgx_launch_token_t)); + + enclave_css_t* enclave_css = (enclave_css_t*)enclave_init_sgx->sigstruct; + if (0 == enclave_css->header.hw_version) { + if (0 != get_launch_token(enclave_css, &it->second, &launch_token)) { + if (enclave_error != NULL) + *enclave_error = ENCLAVE_UNEXPECTED; + return false; + } + } + + struct sgx_enclave_init initp = { 0, 0, 0 }; + initp.addr = POINTER_TO_U64(base_address); + initp.sigstruct = POINTER_TO_U64(enclave_css); + initp.einittoken = POINTER_TO_U64(&launch_token); + + ret = ioctl(s_hdevice, SGX_IOC_ENCLAVE_INIT, &initp); + } else { + struct sgx_enclave_init_in_kernel initp = { 0, 0 }; + initp.addr = POINTER_TO_U64(base_address); + initp.sigstruct = POINTER_TO_U64(enclave_init_sgx->sigstruct); + + ret = ioctl(s_hdevice, SGX_IOC_ENCLAVE_INIT_IN_KERNEL, &initp); + } + + if (ret) { + SE_TRACE(SE_TRACE_WARNING, "\nSGX_IOC_ENCLAVE_INIT failed error = %d\n", ret); + if (enclave_error != NULL) + *enclave_error = error_driver2api(ret); + return false; + } + + se_mutex_lock(&s_enclave_mutex); + std::map::iterator it = s_enclave_init.find(base_address); + if (it != s_enclave_init.end() && it->second) { + se_mutex_unlock(&s_enclave_mutex); + if (enclave_error != NULL) + *enclave_error = ENCLAVE_ALREADY_INITIALIZED; + return false; + } + + s_enclave_init[base_address] = true; + se_mutex_unlock(&s_enclave_mutex); + + if (enclave_error != NULL) + *enclave_error = ENCLAVE_ERROR_SUCCESS; + return true; +} + +/* enclave_delete() + * Parameters: + * base_address [in] - The enclave base address as returned from the enclave_create API. + * enclave_error [out, optional] - An optional pointer to a variable that receives an enclave error code. + * Return Value: + * non-zero - The function succeeds. + * zero - The function fails and the extended error information will be in the enclave_error parameter if used. +*/ +extern "C" bool COMM_API enclave_delete( + COMM_IN void* base_address, + COMM_OUT_OPT uint32_t* enclave_error) +{ + if (base_address == NULL) { + if (enclave_error != NULL) + *enclave_error = ENCLAVE_INVALID_PARAMETER; + return false; + } + + se_mutex_lock(&s_enclave_mutex); + std::map::iterator it = s_enclave_size.find(base_address); + if (it == s_enclave_size.end()) { + se_mutex_unlock(&s_enclave_mutex); + if (enclave_error != NULL) + *enclave_error = ENCLAVE_INVALID_PARAMETER; + return false; + } + + s_enclave_size.erase(base_address); + s_enclave_init.erase(base_address); + s_enclave_mem_region.erase(base_address); + se_mutex_unlock(&s_enclave_mutex); + + if (0 != munmap(base_address, it->second)) { + SE_TRACE(SE_TRACE_WARNING, "delete SGX enclave failed, error = %d\n", errno); + if (enclave_error != NULL) { + if (errno == EINVAL) + *enclave_error = ENCLAVE_INVALID_PARAMETER; + else + *enclave_error = ENCLAVE_UNEXPECTED; + } + return false; + } + + if (enclave_error != NULL) + *enclave_error = ENCLAVE_ERROR_SUCCESS; + return true; +} + +/* enclave_get_information() + * Parameters: + * base_address [in] - The enclave base address as returned from the enclave_create API. + * info_type[in] - Identifies the type of information requested. initialized. + * output_info[out] - Pointer to information returned by the API + * output_info_size[in, out] - Size of the output_info buffer, in bytes. If the API succeeds, then this will return the number of bytes returned in output_info. If the API fails with, ENCLAVE_INVALID_SIZE, then this will return the required size + * enclave_error [out, optional] - An optional pointer to a variable that receives an enclave error code. + */ +bool COMM_API enclave_get_information( + COMM_IN void* base_address, + COMM_IN uint32_t info_type, + COMM_OUT void* output_info, + COMM_IN_OUT size_t* output_info_size, + COMM_OUT_OPT uint32_t* enclave_error) +{ + UNUSED(base_address); + UNUSED(info_type); + UNUSED(output_info); + UNUSED(output_info_size); + + if (enclave_error) + *enclave_error = ENCLAVE_NOT_SUPPORTED; + + return false; +} + +/* enclave_set_information + * Parameters + * base_address [in] - The enclave base address as returned from the enclave_create API. + * info_type[in] - Identifies the type of information requested. not been initialized. + * input_info[in] - Pointer to information provided to the API + * input_info_size[in] - Size of the information, in bytes, provided in input_info from the API. + * enclave_error [out, optional] - An optional pointer to a variable that receives an enclave error code. + */ +bool COMM_API enclave_set_information( + COMM_IN void* base_address, + COMM_IN uint32_t info_type, + COMM_IN void* input_info, + COMM_IN size_t input_info_size, + COMM_OUT_OPT uint32_t* enclave_error) +{ + UNUSED(base_address); + UNUSED(info_type); + UNUSED(input_info); + UNUSED(input_info_size); + + if (enclave_error) + *enclave_error = ENCLAVE_NOT_SUPPORTED; + + return false; +} diff --git a/psw/enclave_common/sgx_enclave_common.h b/psw/enclave_common/sgx_enclave_common.h new file mode 100644 index 00000000..7dbdd66e --- /dev/null +++ b/psw/enclave_common/sgx_enclave_common.h @@ -0,0 +1,203 @@ +/* + * Copyright (C) 2011-2018 Intel Corporation. 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 name of Intel 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 + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#ifndef _SGX_ENCLAVE_COMMON_H_ +#define _SGX_ENCLAVE_COMMON_H_ + +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* The following macros are for GCC only */ +#define COMM_API +#define COMM_IN +#define COMM_IN_OPT +#define COMM_OUT +#define COMM_OUT_OPT +#define COMM_IN_OUT + +#define ENCLAVE_MK_ERROR(x) (0x00000000 | (x)) + +typedef enum { + ENCLAVE_ERROR_SUCCESS = ENCLAVE_MK_ERROR(0x0000), /* No error. */ + ENCLAVE_NOT_SUPPORTED = ENCLAVE_MK_ERROR(0x0001), /* Enclave type not supported, SGX not supported, or SGX device not present. */ + ENCLAVE_INVALID_SIG_STRUCT = ENCLAVE_MK_ERROR(0x0002), /* SGX - SIGSTRUCT contains an invalid value. */ + ENCLAVE_INVALID_SIGNATURE = ENCLAVE_MK_ERROR(0x0003), /* SGX – invalid Signature or SIGSTRUCT. */ + ENCLAVE_INVALID_ATTRIBUTE = ENCLAVE_MK_ERROR(0x0004), /* SGX – invalid SECS Attribute. */ + ENCLAVE_INVALID_MEASUREMENT = ENCLAVE_MK_ERROR(0x0005), /* SGX – invalid measurement. */ + ENCLAVE_NOT_AUTHORIZED = ENCLAVE_MK_ERROR(0x0006), /* Enclave not authorized to run. */ + ENCLAVE_INVALID_ENCLAVE = ENCLAVE_MK_ERROR(0x0007), /* Address is not a Valid Enclave. */ + ENCLAVE_LOST = ENCLAVE_MK_ERROR(0x0008), /* SGX – enclave is lost (likely due to a power event). */ + ENCLAVE_INVALID_PARAMETER = ENCLAVE_MK_ERROR(0x0009), /* Invalid Parameter (unspecified) – may be due to type length/format. */ + ENCLAVE_OUT_OF_MEMORY = ENCLAVE_MK_ERROR(0x000a), + ENCLAVE_DEVICE_NO_RESOURCES = ENCLAVE_MK_ERROR(0x000b), /* Out of EPC Memory. */ + ENCLAVE_ALREADY_INITIALIZED = ENCLAVE_MK_ERROR(0x000c), /* Enclave has already been initialized. */ + ENCLAVE_INVALID_ADDRESS = ENCLAVE_MK_ERROR(0x000d), /* Address is not within a valid enclave./ Address has already been committed. */ + ENCLAVE_RETRY = ENCLAVE_MK_ERROR(0x000e), /* Please retry the operation – there was an unmasked event in EINIT. */ + ENCLAVE_INVALID_SIZE = ENCLAVE_MK_ERROR(0x000f), /* An invalid size was entered. */ + ENCLAVE_NOT_INITIALIZED = ENCLAVE_MK_ERROR(0x0010), /* The enclave is not initialized – the operation requires that the enclave be initialized. */ + ENCLAVE_UNEXPECTED = ENCLAVE_MK_ERROR(0x1001), /* Unexpected error. */ +} enclave_error_t; + +typedef enum { + ENCLAVE_TYPE_SGX1 = 1, /* An enclave for the Intel Software Guard Extensions (SGX) architecture version 1. */ + ENCLAVE_TYPE_SGX2, /* An enclave for the Intel Software Guard Extensions (SGX) architecture version 2. */ +} enclave_type_t; + +typedef enum { + ENCLAVE_PAGE_READ = 1 << 0, /* Enables read access to the committed region of pages. */ + ENCLAVE_PAGE_WRITE = 1 << 1, /* Enables write access to the committed region of pages. */ + ENCLAVE_PAGE_EXECUTE = 1 << 2, /* Enables execute access to the committed region of pages. */ + ENCLAVE_PAGE_THREAD_CONTROL = 1 << 8, /* The page contains a thread control structure. */ + ENCLAVE_PAGE_UNVALIDATED = 1 << 12, /* The page contents that you supply are excluded from measurement and content validation. */ +} enclave_page_properties_t; + +typedef enum { + ENCLAVE_LAUNCH_TOKEN = 0x1, +} enclave_info_type_t; + +#define SECS_SIZE 4096 +#define SIGSTRUCT_SIZE 1808 + +typedef struct enclave_create_sgx_t { + uint8_t secs[SECS_SIZE]; +} enclave_create_sgx_t; + +typedef struct enclave_init_sgx_t { + uint8_t sigstruct[SIGSTRUCT_SIZE]; +} enclave_init_sgx_t; + +/* enclave_create() + * Parameters: + * base_address [in, optional] - An optional preferred base address for the enclave. + * virtual_size [in] - The virtual address range of the enclave in bytes. + * initial_commit[in] - The amount of physical memory to reserve for the initial load of the enclave in bytes. + * type [in] - The architecture type of the enclave that you want to create. + * info [in] - A pointer to the architecture-specific information to use to create the enclave. + * info_size [in] - The length of the structure that the info parameter points to, in bytes. + * enclave_error [out, optional] - An optional pointer to a variable that receives an enclave error code. + * Return Value: + * If the function succeeds, the return value is the base address of the created enclave. + * If the function fails, the return value is NULL. The extended error information will be in the enclave_error parameter if used. +*/ +void* COMM_API enclave_create( + COMM_IN_OPT void* base_address, + COMM_IN size_t virtual_size, + COMM_IN size_t initial_commit, + COMM_IN uint32_t type, + COMM_IN const void* info, + COMM_IN size_t info_size, + COMM_OUT_OPT uint32_t* enclave_error); + +/* enclave_load_data() + * Parameters: + * target_address [in] - The address in the enclave where you want to load the data. + * target_size [in] - The size of the range that you want to load in the enclave, in bytes. + * source_buffer [in, optional] - An optional pointer to the data you want to load into the enclave. + * data_properties [in] - The properties of the pages you want to add to the enclave. + * enclave_error [out, optional] - An optional pointer to a variable that receives an enclave error code. + * Return Value: + * The return value is the number of bytes that was loaded into the enclave. + * If the number is different than target_size parameter an error occurred. The extended error information will be in the enclave_error parameter if used. +*/ +size_t COMM_API enclave_load_data( + COMM_IN void* target_address, + COMM_IN size_t target_size, + COMM_IN_OPT const void* source_buffer, + COMM_IN uint32_t data_properties, + COMM_OUT_OPT uint32_t* enclave_error); + +/* enclave_initialize() + * Parameters: + * base_address [in] - The enclave base address as returned from the enclave_create API. + * info [in] - A pointer to the architecture-specific information to use to initialize the enclave. + * info_size [in] - The length of the structure that the info parameter points to, in bytes. + * enclave_error [out, optional] - An optional pointer to a variable that receives an enclave error code. + * Return Value: + * non-zero - The function succeeds. + * zero - The function fails and the extended error information will be in the enclave_error parameter if used. +*/ +bool COMM_API enclave_initialize( + COMM_IN void* base_address, + COMM_IN const void* info, + COMM_IN size_t info_size, + COMM_OUT_OPT uint32_t* enclave_error); + +/* enclave_delete() + * Parameters: + * base_address [in] - The enclave base address as returned from the enclave_create API. + * enclave_error [out, optional] - An optional pointer to a variable that receives an enclave error code. + * Return Value: + * non-zero - The function succeeds. + * zero - The function fails and the extended error information will be in the enclave_error parameter if used. +*/ +bool COMM_API enclave_delete( + COMM_IN void* base_address, + COMM_OUT_OPT uint32_t* enclave_error); + +/* enclave_get_information() + * Parameters: + * base_address [in] - The enclave base address as returned from the enclave_create API. + * info_type[in] - Identifies the type of information requested. initialized. + * output_info[out] - Pointer to information returned by the API + * output_info_size[in, out] - Size of the output_info buffer, in bytes. If the API succeeds, then this will return the number of bytes returned in output_info. If the API fails with, ENCLAVE_INVALID_SIZE, then this will return the required size + * enclave_error [out, optional] - An optional pointer to a variable that receives an enclave error code. + */ +bool COMM_API enclave_get_information( + COMM_IN void* base_address, + COMM_IN uint32_t info_type, + COMM_OUT void* output_info, + COMM_IN_OUT size_t* output_info_size, + COMM_OUT_OPT uint32_t* enclave_error); + +/* enclave_set_information + * Parameters + * base_address [in] - The enclave base address as returned from the enclave_create API. + * info_type[in] - Identifies the type of information requested. not been initialized. + * input_info[in] - Pointer to information provided to the API + * input_info_size[in] - Size of the information, in bytes, provided in input_info from the API. + * enclave_error [out, optional] - An optional pointer to a variable that receives an enclave error code. + */ +bool COMM_API enclave_set_information( + COMM_IN void* base_address, + COMM_IN uint32_t info_type, + COMM_IN void* input_info, + COMM_IN size_t input_info_size, + COMM_OUT_OPT uint32_t* enclave_error); +#ifdef __cplusplus +} +#endif + +#endif diff --git a/psw/enclave_common/sgx_enclave_common.lds b/psw/enclave_common/sgx_enclave_common.lds new file mode 100644 index 00000000..fef9df47 --- /dev/null +++ b/psw/enclave_common/sgx_enclave_common.lds @@ -0,0 +1,11 @@ +{ +global: + enclave_create; + enclave_load_data; + enclave_initialize; + enclave_delete; + enclave_get_information; + enclave_set_information; +local: + *; +}; diff --git a/psw/uae_service/sgx_uae_service.cpp b/psw/uae_service/sgx_uae_service.cpp index 3756d2a5..37fe1e97 100644 --- a/psw/uae_service/sgx_uae_service.cpp +++ b/psw/uae_service/sgx_uae_service.cpp @@ -332,6 +332,9 @@ sgx_status_t create_session_ocall( case AESM_OUT_OF_EPC: mapped = SGX_ERROR_OUT_OF_EPC; break; + case AESM_EPID_REVOKED_ERROR: + mapped = SGX_ERROR_EPID_MEMBER_REVOKED; + break; case AESM_MSG_ERROR: default: mapped = SGX_ERROR_UNEXPECTED; @@ -383,6 +386,9 @@ sgx_status_t exchange_report_ocall( case AESM_OUT_OF_EPC: mapped = SGX_ERROR_OUT_OF_EPC; break; + case AESM_EPID_REVOKED_ERROR: + mapped = SGX_ERROR_EPID_MEMBER_REVOKED; + break; default: mapped = SGX_ERROR_UNEXPECTED; } @@ -423,6 +429,9 @@ sgx_status_t close_session_ocall( case AESM_OUT_OF_EPC: mapped = SGX_ERROR_OUT_OF_EPC; break; + case AESM_EPID_REVOKED_ERROR: + mapped = SGX_ERROR_EPID_MEMBER_REVOKED; + break; default: mapped = SGX_ERROR_UNEXPECTED; } @@ -469,6 +478,9 @@ sgx_status_t invoke_service_ocall( case AESM_OUT_OF_EPC: mapped = SGX_ERROR_OUT_OF_EPC; break; + case AESM_EPID_REVOKED_ERROR: + mapped = SGX_ERROR_EPID_MEMBER_REVOKED; + break; case AESM_MSG_ERROR: default: mapped = SGX_ERROR_UNEXPECTED; diff --git a/psw/urts/enclave.cpp b/psw/urts/enclave.cpp index ae8a7d33..41b23422 100644 --- a/psw/urts/enclave.cpp +++ b/psw/urts/enclave.cpp @@ -336,7 +336,7 @@ int CEnclave::ocall(const unsigned int proc, const sgx_ocall_table_t *ocall_tabl { int error = SGX_ERROR_UNEXPECTED; - if (is_builtin_ocall(int(proc))) + if (is_builtin_ocall(proc)) { se_rdunlock(&m_rwlock); if ((int)proc == EDMM_TRIM) diff --git a/psw/urts/enclave_creator_hw.h b/psw/urts/enclave_creator_hw.h index 1be7c636..9675bb29 100644 --- a/psw/urts/enclave_creator_hw.h +++ b/psw/urts/enclave_creator_hw.h @@ -66,15 +66,16 @@ public: int trim_accept(uint64_t addr); int remove_range(uint64_t fromaddr, uint64_t numpages); private: - virtual bool open_se_device(); - virtual void close_se_device(); + virtual bool open_device(); + virtual void close_device(); int try_init_enclave(sgx_enclave_id_t enclave_id, enclave_css_t *enclave_css, token_t *launch); int error_driver2urts(int driver_error); + int error_api2urts(uint32_t api_error); se_file_handle_t m_hdevice; Mutex m_dev_mutex; bool m_sig_registered; se_mutex_t m_sig_mutex; - bool m_in_kernel_driver; + bool m_is_kernel_driver; }; #endif diff --git a/psw/urts/enclave_creator_hw_com.cpp b/psw/urts/enclave_creator_hw_com.cpp index 60f4b52e..e846a2b9 100644 --- a/psw/urts/enclave_creator_hw_com.cpp +++ b/psw/urts/enclave_creator_hw_com.cpp @@ -88,6 +88,7 @@ int EnclaveCreatorHW::initialize(sgx_enclave_id_t enclave_id) int EnclaveCreatorHW::get_misc_attr(sgx_misc_attribute_t *sgx_misc_attr, metadata_t *metadata, SGXLaunchToken * const lc, uint32_t debug_flag) { + UNUSED(lc); sgx_attributes_t *required_attr = &metadata->attributes; enclave_css_t *enclave_css = &metadata->enclave_css; sgx_attributes_t *secs_attr = &sgx_misc_attr->secs_attr; @@ -150,32 +151,6 @@ int EnclaveCreatorHW::get_misc_attr(sgx_misc_attribute_t *sgx_misc_attr, metadat // try to use maximum ablity of cpu sgx_misc_attr->misc_select = se_cap.misc_select & enclave_css->body.misc_select; - if(lc != NULL) - { - // Read launch token from lc - sgx_launch_token_t token; - memset(&token, 0, sizeof(token)); - if(lc->get_launch_token(&token) != SGX_SUCCESS) - return SGX_ERROR_UNEXPECTED; - token_t *launch = (token_t *)token; - if(1 == launch->body.valid) - { - //debug launch enclave cannot launch production enclave - if( !(secs_attr->flags & SGX_FLAGS_DEBUG) - && (launch->attributes_le.flags & SGX_FLAGS_DEBUG) ) - { - SE_TRACE(SE_TRACE_WARNING, "secs attributes is non-debug, \n"); - return SE_ERROR_INVALID_LAUNCH_TOKEN; - } - //verify attributes in lictoken are the same as the enclave - if(memcmp(&launch->body.attributes, secs_attr, sizeof(sgx_attributes_t))) - { - SE_TRACE(SE_TRACE_WARNING, "secs attributes does NOT match launch token attributes\n"); - return SGX_ERROR_INVALID_ATTRIBUTE; - } - } - } - return SGX_SUCCESS; } diff --git a/psw/urts/launch_checker.cpp b/psw/urts/launch_checker.cpp index f32a9930..649448da 100644 --- a/psw/urts/launch_checker.cpp +++ b/psw/urts/launch_checker.cpp @@ -123,7 +123,7 @@ sgx_status_t SGXLaunchToken::update_launch_token( if (force_update_tok || SE_ERROR_INVALID_LAUNCH_TOKEN == chk_launch_token(m_css, m_secs_attr, &m_launch)) { - status = ::get_launch_token(m_css, m_secs_attr, &m_launch); + //status = ::get_launch_token(m_css, m_secs_attr, &m_launch); if (status == SGX_SUCCESS) m_launch_updated = true; diff --git a/psw/urts/linux/Makefile b/psw/urts/linux/Makefile index 2ed884e0..4658a087 100644 --- a/psw/urts/linux/Makefile +++ b/psw/urts/linux/Makefile @@ -47,6 +47,7 @@ VTUNE_DIR = $(LINUX_EXTERNAL_DIR)/vtune/linux INC += -I$(COMMON_DIR)/inc \ -I$(COMMON_DIR)/inc/internal \ -I$(COMMON_DIR)/inc/internal/linux \ + -I$(LINUX_PSW_DIR)/enclave_common \ -I$(LINUX_PSW_DIR)/urts/ \ -I$(LINUX_PSW_DIR)/urts/linux \ -I$(LINUX_PSW_DIR)/urts/parser \ @@ -54,7 +55,7 @@ INC += -I$(COMMON_DIR)/inc \ -I$(VTUNE_DIR)/sdk/src/ittnotify LDFLAGS := -lwrapper -LDFLAGS += $(COMMON_LDFLAGS) -Wl,-Bdynamic -lsgx_uae_service +LDFLAGS += $(COMMON_LDFLAGS) -Wl,-Bdynamic -lsgx_enclave_common LDFLAGS += -L$(VTUNE_DIR)/sdk/src/ittnotify -littnotify -ldl LDFLAGS += -Wl,--version-script=urts.lds -Wl,--gc-sections @@ -108,10 +109,11 @@ INTERNAL_OBJ := $(OBJ3) $(CPP_OBJ) vpath %.cpp $(DIR1):$(DIR2):$(DIR3):$(DIR4) vpath %.S $(DIR1):$(DIR5) -LIBWRAPPER := libwrapper.a -LIBURTS := libsgx_urts.so -LIBURTS_INTERNAL := liburts_internal.a -LIBURTS_DEBUG := libsgx_urts.so.debug +LIBWRAPPER := libwrapper.a +LIBSGX_ENCLAVE_COMMON := libsgx_enclave_common.a +LIBURTS := libsgx_urts.so +LIBURTS_INTERNAL := liburts_internal.a +LIBURTS_DEBUG := libsgx_urts.so.debug # untrusted switchless settings USWITCHLESS_NAME := uswitchless @@ -127,17 +129,20 @@ ifndef DEBUG @$(CP) $(LIBURTS_DEBUG) $| endif -$(LIBURTS_INTERNAL): $(INTERNAL_OBJ) $(LIBWRAPPER) +$(LIBURTS_INTERNAL): $(INTERNAL_OBJ) $(LIBWRAPPER) $(LIBSGX_ENCLAVE_COMMON) $(LIBUSWITCHLESS) $(CP) $(COMMON_DIR)/se_wrapper/libwrapper.a $@ - $(AR) rcs $@ $(INTERNAL_OBJ) $(MKDIR) ./.switchless_tmp $(RM) ./.switchless_tmp/* cd ./.switchless_tmp && \ $(AR) x $(LIBUSWITCHLESS) - $(AR) rcs $@ ./.switchless_tmp/*.o - $(RM) -rf ./.switchless_tmp + @$(MKDIR) $(BUILD_DIR)/.sgx_enclave_common + @$(RM) -f $(BUILD_DIR)/.sgx_enclave_common/* + cd $(BUILD_DIR)/.sgx_enclave_common && $(AR) x $(BUILD_DIR)/$(LIBSGX_ENCLAVE_COMMON) + $(AR) rcs $@ $(INTERNAL_OBJ) ./.switchless_tmp/*.o $(BUILD_DIR)/.sgx_enclave_common/*.o + @$(RM) -rf ./.switchless_tmp + @$(RM) -rf $(BUILD_DIR)/.sgx_enclave_common -$(LIBURTS): $(URTS_OBJ) $(LIBWRAPPER) uae_service ittnotify +$(LIBURTS): $(URTS_OBJ) $(LIBWRAPPER) $(LIBSGX_ENCLAVE_COMMON) $(LIBUSWITCHLESS) ittnotify $(CXX) $(CXXFLAGS) -shared -Wl,-soname=$@ $(LIB) -o $@ $(URTS_OBJ) $(LDFLAGS) $(LIBURTS_DEBUG): $(LIBURTS) @@ -157,9 +162,11 @@ $(OBJ3): %.o: %.S $(LIBWRAPPER): $(MAKE) -C $(COMMON_DIR)/se_wrapper/ -.PHONY:uae_service -uae_service: - $(MAKE) -C $(LINUX_PSW_DIR)/uae_service/linux +$(LIBSGX_ENCLAVE_COMMON): + $(MAKE) -C $(LINUX_PSW_DIR)/enclave_common/ + +$(LIBUSWITCHLESS): + $(MAKE) -C $(LINUX_PSW_DIR)/uswitchless/ .PHONY: ittnotify ittnotify: @@ -174,5 +181,6 @@ clean:: @$(RM) $(BUILD_DIR)/$(LIBURTS) $(BUILD_DIR)/$(LIBURTS_INTERNAL) @$(RM) $(LIBURTS).orig $(BUILD_DIR)/$(LIBURTS_DEBUG) $(MAKE) -C $(COMMON_DIR)/se_wrapper/ clean - $(MAKE) -C $(LINUX_PSW_DIR)/uae_service/linux/ clean + $(MAKE) -C $(LINUX_PSW_DIR)/enclave_common/ clean + $(MAKE) -C $(LINUX_PSW_DIR)/uswitchless/ clean $(MAKE) -C $(VTUNE_DIR)/sdk/src/ittnotify clean diff --git a/psw/urts/linux/enclave_creator_hw.cpp b/psw/urts/linux/enclave_creator_hw.cpp index ac934f42..9696f491 100644 --- a/psw/urts/linux/enclave_creator_hw.cpp +++ b/psw/urts/linux/enclave_creator_hw.cpp @@ -33,6 +33,7 @@ #include "enclave.h" #include "enclave_creator_hw.h" #include "edmm_utility.h" +#include "sgx_enclave_common.h" #include "se_trace.h" #include "se_page_attr.h" #include "isgx_user.h" @@ -60,14 +61,14 @@ static uint64_t g_eid = 0x1; EnclaveCreatorHW::EnclaveCreatorHW(): m_hdevice(-1), m_sig_registered(false), - m_in_kernel_driver(false) + m_is_kernel_driver(false) { se_mutex_init(&m_sig_mutex); } EnclaveCreatorHW::~EnclaveCreatorHW() { - close_se_device(); + close_device(); } int EnclaveCreatorHW::error_driver2urts(int driver_error) @@ -79,6 +80,9 @@ int EnclaveCreatorHW::error_driver2urts(int driver_error) case SGX_INVALID_ATTRIBUTE: ret = SGX_ERROR_INVALID_ATTRIBUTE; break; + case SGX_INVALID_PRIVILEGE: + ret = SGX_ERROR_SERVICE_INVALID_PRIVILEGE; + break; case SGX_INVALID_MEASUREMENT: ret = SE_ERROR_INVALID_MEASUREMENT; break; @@ -109,106 +113,108 @@ int EnclaveCreatorHW::error_driver2urts(int driver_error) ret = SGX_ERROR_UNEXPECTED; break; } - + return ret; } + +int EnclaveCreatorHW::error_api2urts(uint32_t api_error) +{ + int ret = SGX_ERROR_UNEXPECTED; + + switch(api_error) + { + case ENCLAVE_ERROR_SUCCESS: + ret = SGX_SUCCESS; + break; + case ENCLAVE_NOT_SUPPORTED: + ret = SGX_ERROR_NO_DEVICE; + break; + case ENCLAVE_INVALID_SIG_STRUCT: + case ENCLAVE_INVALID_SIGNATURE: + ret = SGX_ERROR_INVALID_SIGNATURE; + break; + case ENCLAVE_INVALID_ATTRIBUTE: + ret = SGX_ERROR_INVALID_ATTRIBUTE; + break; + case ENCLAVE_NOT_AUTHORIZED: + ret = SGX_ERROR_SERVICE_INVALID_PRIVILEGE; + break; + case ENCLAVE_INVALID_MEASUREMENT: + ret = SE_ERROR_INVALID_MEASUREMENT; + break; + case ENCLAVE_INVALID_ENCLAVE: + ret = SGX_ERROR_INVALID_ENCLAVE; + break; + case ENCLAVE_LOST: + ret = SGX_ERROR_ENCLAVE_LOST; + break; + case ENCLAVE_INVALID_PARAMETER: + ret = SGX_ERROR_INVALID_PARAMETER; + break; + case ENCLAVE_OUT_OF_MEMORY: + case ENCLAVE_DEVICE_NO_RESOURCES: + ret = SGX_ERROR_OUT_OF_MEMORY; + break; + default: + SE_TRACE(SE_TRACE_WARNING, "unexpected error %#x from enclave common api, should be uRTS/driver bug\n", api_error); + ret = SGX_ERROR_UNEXPECTED; + break; + } + + return ret; +} int EnclaveCreatorHW::create_enclave(secs_t *secs, sgx_enclave_id_t *enclave_id, void **start_addr, bool ae) { assert(secs != NULL && enclave_id != NULL && start_addr != NULL); UNUSED(ae); - if (false == open_se_device()) - return SGX_ERROR_NO_DEVICE; + enclave_create_sgx_t enclave_create_sgx = {0}; + if (0 != memcpy_s(enclave_create_sgx.secs, SECS_SIZE, secs, SECS_SIZE)) + return SGX_ERROR_UNEXPECTED; - SE_TRACE(SE_TRACE_DEBUG, "\n secs.attibutes.flags = %llx, secs.attributes.xfrm = %llx \n" - , secs->attributes.flags, secs->attributes.xfrm); + uint32_t enclave_error = ENCLAVE_ERROR_SUCCESS; + void* enclave_base = enclave_create(NULL, (size_t)secs->size, 0, ENCLAVE_TYPE_SGX2, &enclave_create_sgx, sizeof(enclave_create_sgx_t), &enclave_error); - //SECS:BASEADDR must be naturally aligned on an SECS.SIZE boundary - //This alignment is guaranteed by driver - void* enclave_base = mmap(NULL, (size_t)secs->size, PROT_NONE, MAP_SHARED, m_hdevice, 0); - if(enclave_base == MAP_FAILED) - { - SE_TRACE(SE_TRACE_WARNING, "\ncreate enclave: mmap failed, errno = %d\n", errno); - return SGX_ERROR_OUT_OF_MEMORY; - } + if (enclave_error) + return error_api2urts(enclave_error); secs->base = enclave_base; - - struct sgx_enclave_create param = {0}; - param.src = POINTER_TO_U64(secs); - int ret = ioctl(m_hdevice, SGX_IOC_ENCLAVE_CREATE, ¶m); - if(ret) - { - if(ret == -1 && errno == EINTR) - { - return SGX_INTERNAL_ERROR_ENCLAVE_CREATE_INTERRUPTED; // Allow users to retry - } - SE_TRACE(SE_TRACE_WARNING, "\nSGX_IOC_ENCLAVE_CREATE failed: errno = %d\n", errno); - return error_driver2urts(ret); - } + *start_addr = enclave_base; *enclave_id = se_atomic_inc64(&g_eid); - *start_addr = secs->base; - return SGX_SUCCESS; + return error_api2urts(enclave_error); } - + int EnclaveCreatorHW::add_enclave_page(sgx_enclave_id_t enclave_id, void *src, uint64_t rva, const sec_info_t &sinfo, uint32_t attr) { assert((rva & ((1<(&color_page); + data_properties |= ENCLAVE_PAGE_UNVALIDATED; } + enclave_load_data((void*)(enclave_id + rva), SE_PAGE_SIZE, src, data_properties, &enclave_error); - int ret = 0; - struct sgx_enclave_add_page addp = { 0, 0, 0, 0 }; - - addp.addr = enclave_id + rva; - addp.src = POINTER_TO_U64(source); - addp.secinfo = POINTER_TO_U64(const_cast(&sinfo)); - if(((1<enclave_size); - if(enclave_creator->use_se_hw() == true) - { - set_memory_protection(false); - } } return ret; } @@ -526,6 +522,10 @@ int CLoader::build_image(SGXLaunchToken * const lc, sgx_attributes_t * const sec goto fail; } + if(get_enclave_creator()->use_se_hw() == true) + { + set_memory_protection(false); + } return SGX_SUCCESS; diff --git a/psw/urts/urts_com.h b/psw/urts/urts_com.h index da1e7b0f..2d252f4e 100644 --- a/psw/urts/urts_com.h +++ b/psw/urts/urts_com.h @@ -123,7 +123,7 @@ static sgx_status_t get_metadata(BinParser *parser, const int debug, metadata_t meta_rva = parser->get_metadata_offset(); do { *metadata = GET_PTR(metadata_t, base_addr, meta_rva); - if(metadata == NULL) + if(*metadata == NULL) { return SGX_ERROR_INVALID_METADATA; } @@ -463,15 +463,14 @@ sgx_status_t _create_enclave_ex(const bool debug, se_file_handle_t pfile, se_fil if (ex_features & SGX_CREATE_ENCLAVE_EX_PCL) { - uint8_t* sealed_key = (uint8_t*)ex_features_p[SGX_CREATE_ENCLAVE_EX_PCL_BIT_IDX]; - if (NULL == sealed_key) + if ((ex_features_p == NULL) || (ex_features_p[SGX_CREATE_ENCLAVE_EX_PCL_BIT_IDX] == NULL)) { ret = SGX_ERROR_INVALID_PARAMETER; goto clean_return; } - + if (!parser.is_enclave_encrypted()) { ret = SGX_ERROR_PCL_NOT_ENCRYPTED; @@ -565,7 +564,7 @@ extern "C" sgx_status_t sgx_destroy_enclave(const sgx_enclave_id_t enclave_id) { debug_enclave_info_t *debug_info = const_cast(enclave->get_debug_info()); generate_enclave_debug_event(URTS_EXCEPTION_PREREMOVEENCLAVE, debug_info); - enclave->destroy_uswitchless(); + enclave->destroy_uswitchless(); enclave->ecall(ECMD_UNINIT_ENCLAVE, NULL, NULL); CEnclavePool::instance()->unref_enclave(enclave); } diff --git a/sdk/ec_dh_lib/ec_dh.cpp b/sdk/ec_dh_lib/ec_dh.cpp index 618f2f68..b55aa5b5 100644 --- a/sdk/ec_dh_lib/ec_dh.cpp +++ b/sdk/ec_dh_lib/ec_dh.cpp @@ -104,6 +104,7 @@ static sgx_status_t dh_generate_message1(sgx_dh_msg1_t *msg1, sgx_internal_dh_se return se_ret; } + memset(msg1, 0, sizeof(sgx_dh_msg1_t)); memcpy(&msg1->target.mr_enclave, &temp_report.body.mr_enclave, sizeof(sgx_measurement_t)); diff --git a/sdk/edger8r/linux/Ast.ml b/sdk/edger8r/linux/Ast.ml index eb7ee315..d66a5375 100644 --- a/sdk/edger8r/linux/Ast.ml +++ b/sdk/edger8r/linux/Ast.ml @@ -29,19 +29,23 @@ * *) -(* Available types. *) +(* [unsigned] *) type signedness = Signed | Unsigned + +(* [short|long] *) type shortness = IShort | ILong | INone +(* [unsigned] [short|long] int *) type int_attr = { ia_signedness : signedness; ia_shortness : shortness; } +(* All available types. *) type atype = - | Char of signedness - | Long of signedness - | LLong of signedness + | Char of signedness (* 'char' *) + | Long of signedness (* 'long' *) + | LLong of signedness (* 'long long' *) | Int of int_attr | Float | Double | LDouble | Int8 | Int16 | Int32 | Int64 @@ -50,18 +54,19 @@ type atype = | Struct of string | Union of string | Enum of string - | Foreign of string - | Ptr of atype + | Foreign of string (* typedef in other places *) + | Ptr of atype (* Pointer to a type *) -(* Pointer parameter direction *) +(* Pointer parameter direction attribute 'in', 'out', 'inout' *) type ptr_direction = | PtrIn | PtrOut | PtrInOut | PtrNoDirection (* It holds possible values for a given attribute. *) type attr_value = - | AString of string - | ANumber of int + | AString of string (* a varable *) + | ANumber of int (* a number *) +(* Pointer parameter can have option attribute of 'size=' and 'count='. *) type ptr_size = { ps_size : attr_value option; ps_count : attr_value option; @@ -76,12 +81,12 @@ let empty_ptr_size = { type ptr_attr = { pa_direction : ptr_direction; pa_size : ptr_size; - pa_isptr : bool; (* If a foreign type is a pointer type *) - pa_isary : bool; (* If a foreign type is an array *) - pa_isstr : bool; - pa_iswstr : bool; - pa_rdonly : bool; (* If the pointer is 'const' qualified *) - pa_chkptr : bool; (* Whether to generate code to check pointer *) + pa_isptr : bool; (* If a foreign type is a pointer type, 'isptr' *) + pa_isary : bool; (* If a foreign type is an array, 'isary' *) + pa_isstr : bool; (* 'char*' pointer with length of strlen(x), 'isstr' *) + pa_iswstr : bool; (* 'wchar*' pointer with length of wcslen(x), 'iswstr' *) + pa_rdonly : bool; (* If the pointer is 'const' qualified, 'readonly' *) + pa_chkptr : bool; (* Whether to generate code to check pointer, 'user_check' *) } (* parameter type *) @@ -89,6 +94,7 @@ type parameter_type = | PTVal of atype (* Passed by value *) | PTPtr of atype * ptr_attr (* Passed by address *) +(* function calling convention *) type call_conv = CC_CDECL | CC_STDCALL | CC_FASTCALL | CC_NONE let get_call_conv_str (cc: call_conv) = @@ -154,17 +160,19 @@ type func_decl = { * have a bool tag to identify whether it is private or not (private * means it can only be accessed by an OCALL). *) +(* Trust function(aka ecall) declaration. *) type trusted_func = { tf_fdecl : func_decl; - tf_is_priv : bool; + tf_is_priv : bool; (* private or not, see above comment *) tf_is_switchless : bool; } +(* untrust function(aka ocall) declaration. *) type untrusted_func = { uf_fdecl : func_decl; - uf_fattr : func_attr; - uf_allow_list : string list; - uf_propagate_errno : bool; + uf_fattr : func_attr; (* function attribute *) + uf_allow_list : string list; (* allow list, see above comment *) + uf_propagate_errno : bool; (* whether this function changes errno *) uf_is_switchless : bool; } @@ -172,7 +180,7 @@ type enclave_func = | Trusted of trusted_func | Untrusted of untrusted_func -(* Module import declaration. *) +(* Module import declaration. 'import' *) type import_decl = { mname : string; (* from which to import functions. *) flist : string list; (* a list of functions to be imported. *) diff --git a/sdk/edger8r/linux/CodeGen.ml b/sdk/edger8r/linux/CodeGen.ml index 6b1d9338..06ebbd01 100644 --- a/sdk/edger8r/linux/CodeGen.ml +++ b/sdk/edger8r/linux/CodeGen.ml @@ -43,8 +43,8 @@ type enclave_content = Ast.enclave_content = { file_shortnm : string; (* the short name of original EDL file *) enclave_name : string; (* the normalized C identifier *) - include_list : string list; - import_exprs : Ast.import_decl list; + include_list : string list; (* include another .h *) + import_exprs : Ast.import_decl list; (* always empty list after finished reduce_import. *) comp_defs : Ast.composite_type list; tfunc_decls : Ast.trusted_func list; ufunc_decls : Ast.untrusted_func list; @@ -296,12 +296,24 @@ let get_typed_declr_str (ty: Ast.atype) (declr: Ast.declarator) = let mk_member_decl (ty: Ast.atype) (declr: Ast.declarator) = sprintf "\t%s;\n" (get_typed_declr_str ty declr) +(* Check whether given parameter is `const' specified. *) +let is_const_ptr (pt: Ast.parameter_type) = + match pt with + Ast.PTVal _ -> false + | Ast.PTPtr(aty, pa) -> + if not pa.Ast.pa_rdonly then false + else + match aty with + Ast.Foreign _ -> false + | _ -> true + (* Note that, for a foreign array type `foo_array_t' we will generate * foo_array_t* ms_field; * in the marshaling data structure to keep the pass-by-address scheme * as in the C programming language. *) let mk_ms_member_decl (pt: Ast.parameter_type) (declr: Ast.declarator) (isecall: bool) = + let qual = if is_const_ptr pt then "const " else "" in let aty = Ast.get_param_atype pt in let tystr = Ast.get_tystr aty in let ptr = if is_foreign_array pt then "* " else "" in @@ -322,7 +334,7 @@ let mk_ms_member_decl (pt: Ast.parameter_type) (declr: Ast.declarator) (isecall: let str_len = if need_str_len_var pt then sprintf "\tsize_t %s_len;\n" field else "" in let dmstr = get_array_dims declr.Ast.array_dims in - sprintf "\t%s%s %s%s;\n%s" tystr ptr field dmstr str_len + sprintf "\t%s%s%s %s%s;\n%s" qual tystr ptr field dmstr str_len (* Generate data structure definition *) let gen_comp_def (st: Ast.composite_type) = @@ -365,18 +377,6 @@ let gen_ocall_marshal_struct (uf: Ast.untrusted_func) = let errno_decl = if uf.Ast.uf_propagate_errno then "\tint ocall_errno;\n" else "" in gen_marshal_struct uf.Ast.uf_fdecl errno_decl false -(* Check whether given parameter is `const' specified. *) -let is_const_ptr (pt: Ast.parameter_type) = - let aty = Ast.get_param_atype pt in - match pt with - Ast.PTVal _ -> false - | Ast.PTPtr(_, pa) -> - if not pa.Ast.pa_rdonly then false - else - match aty with - Ast.Foreign _ -> false - | _ -> true - (* Generate parameter representation. *) let gen_parm_str (p: Ast.pdecl) = let (pt, (declr : Ast.declarator)) = p in @@ -493,7 +493,9 @@ let gen_tproxy_proto (fd: Ast.func_decl) = acc ^ ", " ^ gen_parm_str pd) (gen_parm_str x) xs in let retval_parm_str = gen_parm_retval fd.Ast.rtype in - if fd.Ast.plist = [] then + if fd.Ast.plist = [] && fd.Ast.rtype = Ast.Void then + sprintf "sgx_status_t SGX_CDECL %s(void)" fd.Ast.fname + else if fd.Ast.plist = [] then sprintf "sgx_status_t SGX_CDECL %s(%s)" fd.Ast.fname retval_parm_str else if fd.Ast.rtype = Ast.Void then sprintf "sgx_status_t SGX_CDECL %s(%s)" fd.Ast.fname parm_list @@ -529,7 +531,7 @@ let gen_uproxy_com_proto (fd: Ast.func_decl) (prefix: string) = let get_ret_tystr (fd: Ast.func_decl) = Ast.get_tystr fd.Ast.rtype let get_plist_str (fd: Ast.func_decl) = - if fd.Ast.plist = [] then "" + if fd.Ast.plist = [] then "void" else List.fold_left (fun acc pd -> acc ^ ", " ^ gen_parm_str pd) (gen_parm_str (List.hd fd.Ast.plist)) (List.tl fd.Ast.plist) @@ -547,8 +549,9 @@ let gen_ufunc_proto (uf: Ast.untrusted_func) = let cconv_str = "SGX_" ^ Ast.get_call_conv_str uf.Ast.uf_fattr.Ast.fa_convention in let func_name = uf.Ast.uf_fdecl.Ast.fname in let plist_str = get_plist_str uf.Ast.uf_fdecl in - sprintf "%s%s SGX_UBRIDGE(%s, %s, (%s))" - dllimport ret_tystr cconv_str func_name plist_str + let func_guard = sprintf "%s_DEFINED__" (String.uppercase func_name) in + sprintf "#ifndef %s\n#define %s\n%s%s SGX_UBRIDGE(%s, %s, (%s));\n#endif" + func_guard func_guard dllimport ret_tystr cconv_str func_name plist_str (* The preemble contains common include expressions. *) let gen_uheader_preemble (guard: string) (inclist: string)= @@ -590,7 +593,7 @@ let gen_untrusted_header (ec: enclave_content) = let out_chan = open_out header_fname in output_string out_chan (preemble_code ^ "\n"); List.iter (fun s -> output_string out_chan (s ^ "\n")) comp_def_list; - List.iter (fun s -> output_string out_chan (s ^ ";\n")) func_proto_ufunc; + List.iter (fun s -> output_string out_chan (s ^ "\n")) func_proto_ufunc; output_string out_chan "\n"; List.iter (fun s -> output_string out_chan (s ^ ";\n")) uproxy_com_proto; output_string out_chan header_footer; @@ -633,8 +636,6 @@ let mk_parm_name_raw (pt: Ast.parameter_type) (declr: Ast.declarator) = then let dims = get_array_dims (List.tl declr.Ast.array_dims) in sprintf "(%s (*)%s)" tystr dims - else if is_const_ptr pt then - sprintf "(const %s)" tystr else "" in cast_expr ^ mk_parm_accessor declr.Ast.identifier @@ -706,10 +707,8 @@ let fill_ms_field (isptr: bool) (pd: Ast.pdecl) = let (pt, declr) = pd in let param_name = declr.Ast.identifier in let ms_member_name = mk_ms_member_name param_name in - let assignment_str (use_cast: bool) (aty: Ast.atype) = - let cast_str = if use_cast then sprintf "(%s)" (Ast.get_tystr aty) else "" - in - sprintf "%s%s%s = %s%s;" ms_struct_val accessor ms_member_name cast_str param_name + let assignment_str (aty: Ast.atype) = + sprintf "%s%s%s = %s;" ms_struct_val accessor ms_member_name param_name in let gen_setup_foreign_array aty = sprintf "%s%s%s = (%s *)&%s[0];" @@ -725,17 +724,15 @@ let fill_ms_field (isptr: bool) (pd: Ast.pdecl) = in if declr.Ast.array_dims = [] then match pt with - Ast.PTVal(aty) -> assignment_str false aty + Ast.PTVal(aty) -> assignment_str aty | Ast.PTPtr(aty, pattr) -> if pattr.Ast.pa_isary then gen_setup_foreign_array aty else if pattr.Ast.pa_isstr - then assignment_str true aty ^ "\n\t" ^ gen_setup_foreign_str aty + then assignment_str aty ^ "\n\t" ^ gen_setup_foreign_str aty else if pattr.Ast.pa_iswstr - then assignment_str true aty ^ "\n\t" ^ gen_setup_foreign_wstr aty - else - if pattr.Ast.pa_rdonly then assignment_str true aty - else assignment_str false aty + then assignment_str aty ^ "\n\t" ^ gen_setup_foreign_wstr aty + else assignment_str aty else (* Arrays are passed by address. *) let tystr = Ast.get_tystr (Ast.Ptr (Ast.get_param_atype pt)) in @@ -823,7 +820,7 @@ let gen_ptr_size (ty: Ast.atype) (pattr: Ast.ptr_attr) (name: string) (get_parm: Ast.Ptr ty -> sprintf "sizeof(%s)" (Ast.get_tystr ty) | _ -> - if pattr.pa_isptr then + if pattr.Ast.pa_isptr then sprintf "sizeof(*%s)" parm_name else sprintf "sizeof(%s)" (Ast.get_tystr ty) @@ -958,7 +955,10 @@ let gen_parm_ptr_direction_pre (plist: Ast.pdecl list) = "\t\tstatus = SGX_ERROR_OUT_OF_MEMORY;"; "\t\tgoto err;"; "\t}\n"; - sprintf "\tmemcpy(%s, %s, %s);" in_ptr_dst_name tmp_ptr_name len_var; + sprintf "\tif (memcpy_s(%s, %s, %s, %s)) {" in_ptr_dst_name len_var tmp_ptr_name len_var; + "\t\tstatus = SGX_ERROR_UNEXPECTED;"; + "\t\tgoto err;"; + "\t}\n"; ] in let s1 = List.fold_left (fun acc s -> acc ^ pre_indent ^ s ^ "\n") "" code_template in @@ -1025,7 +1025,9 @@ let gen_parm_ptr_direction_post (plist: Ast.pdecl list) = "\t{"; sprintf "\t\t%s[%s - 1] = '\\0';" in_ptr_name len_var; sprintf "\t\t%s = strlen(%s) + 1;" len_var in_ptr_name; - sprintf "\t\tmemcpy((void*)%s, %s, %s);" (mk_tmp_var name) in_ptr_name len_var; + sprintf "\t\tif (memcpy_s((void*)%s, %s, %s, %s)) {" (mk_tmp_var name) len_var in_ptr_name len_var; + "\t\t\tstatus = SGX_ERROR_UNEXPECTED;"; + "\t\t}"; sprintf "\t\tfree(%s);" in_ptr_name; "\t}"; ] @@ -1037,19 +1039,25 @@ let gen_parm_ptr_direction_post (plist: Ast.pdecl list) = "\t{"; sprintf "\t\t%s[(%s - sizeof(wchar_t))/sizeof(wchar_t)] = (wchar_t)0;" in_ptr_name len_var; sprintf "\t\t%s = (wcslen(%s) + 1) * sizeof(wchar_t);" len_var in_ptr_name; - sprintf "\t\tmemcpy((void*)%s, %s, %s);" (mk_tmp_var name) in_ptr_name len_var; + sprintf "\t\tif (memcpy_s((void*)%s, %s, %s, %s)) {" (mk_tmp_var name) len_var in_ptr_name len_var; + "\t\t\tstatus = SGX_ERROR_UNEXPECTED;"; + "\t\t}"; sprintf "\t\tfree(%s);" in_ptr_name; "\t}"; ] in List.fold_left (fun acc s -> acc ^ s ^ "\n") "" code_template else - sprintf "\tif (%s) {\n\t\tmemcpy(%s, %s, %s);\n\t\tfree(%s);\n\t}\n" - in_ptr_name - (mk_tmp_var name) - in_ptr_name - len_var - in_ptr_name + let code_template = [ + sprintf "\tif (%s) {" in_ptr_name; + sprintf "\t\tif (memcpy_s(%s, %s, %s, %s)) {" (mk_tmp_var name) len_var in_ptr_name len_var; + "\t\t\tstatus = SGX_ERROR_UNEXPECTED;"; + "\t\t}"; + sprintf "\t\tfree(%s);" in_ptr_name; + "\t}" + ] + in + List.fold_left (fun acc s -> acc ^ s ^ "\n") "" code_template | _ -> "" in List.fold_left (fun acc (pty, declr) -> @@ -1141,10 +1149,12 @@ let mk_parm_name_tbridge (pt: Ast.parameter_type) (declr: Ast.declarator) = (* Generate local variables required for the trusted bridge. *) let gen_tbridge_local_vars (plist: Ast.pdecl list) = let status_var = "\tsgx_status_t status = SGX_SUCCESS;\n" in - let do_gen_local_var (ty: Ast.atype) (attr: Ast.ptr_attr) (name: string) = + let do_gen_local_var (pt: Ast.parameter_type) (attr: Ast.ptr_attr) (name: string) = + let qual = if is_const_ptr pt then "const " else "" in + let ty = Ast.get_param_atype pt in let tmp_var = (* Save a copy of pointer in case it might be modified in the marshaling structure. *) - sprintf "\t%s %s = %s;\n" (Ast.get_tystr ty) (mk_tmp_var name) (mk_parm_accessor name) + sprintf "\t%s%s %s = %s;\n" qual (Ast.get_tystr ty) (mk_tmp_var name) (mk_parm_accessor name) in let len_var = if not attr.Ast.pa_chkptr then "" @@ -1176,7 +1186,7 @@ let gen_tbridge_local_vars (plist: Ast.pdecl list) = | Ast.PTPtr (ty, attr) -> if is_foreign_array pty then gen_local_var_for_foreign_array ty attr declr.Ast.identifier - else do_gen_local_var ty attr declr.Ast.identifier + else do_gen_local_var pty attr declr.Ast.identifier in let new_param_list = List.map conv_array_to_ptr plist in @@ -1232,52 +1242,53 @@ let tproxy_fill_ms_field (pd: Ast.pdecl) (is_ocall_switchless: bool) = Ast.PTVal _ -> fill_ms_field true pd | Ast.PTPtr(ty, attr) -> let is_ary = (Ast.is_array declr || attr.Ast.pa_isary) in - let tystr = sprintf "%s%s" (get_param_tystr pt) (if is_ary then "*" else "") in - if not attr.Ast.pa_chkptr (* [user_check] specified *) - then sprintf "%s = SGX_CAST(%s, %s);" parm_accessor tystr name + let tystr = sprintf "%s%s%s" (if is_const_ptr pt then "const " else"")(get_param_tystr pt) (if is_ary then "*" else "") in + if not attr.Ast.pa_chkptr then (* [user_check] specified *) + if is_ary then sprintf "%s = SGX_CAST(%s, %s);" parm_accessor tystr name + else sprintf "%s = %s;" parm_accessor name else match attr.Ast.pa_direction with Ast.PtrOut -> let code_template = - [sprintf "if (%s != NULL && sgx_is_within_enclave(%s, %s)) {" name name len_var; + [sprintf "if (%s != NULL) {" name; sprintf "\t%s = (%s)__tmp;" parm_accessor tystr; sprintf "\t__tmp_%s = __tmp;" name; sprintf "\tmemset(__tmp_%s, 0, %s);" name len_var; sprintf "\t__tmp = (void *)((size_t)__tmp + %s);" len_var; - sprintf "} else if (%s == NULL) {" name; - sprintf "\t%s = NULL;" parm_accessor; + sprintf "\tocalloc_size -= %s;" len_var; "} else {"; - "\tsgx_ocfree();"; - "\treturn SGX_ERROR_INVALID_PARAMETER;"; + sprintf "\t%s = NULL;" parm_accessor; "}" ] in List.fold_left (fun acc s -> acc ^ s ^ "\n\t") "" code_template | Ast.PtrInOut -> let code_template = - [sprintf "if (%s != NULL && sgx_is_within_enclave(%s, %s)) {" name name len_var; + [sprintf "if (%s != NULL) {" name; sprintf "\t%s = (%s)__tmp;" parm_accessor tystr; sprintf "\t__tmp_%s = __tmp;" name; - sprintf "\tmemcpy(__tmp_%s, %s, %s);" name name len_var; + sprintf "\tif (memcpy_s(__tmp_%s, ocalloc_size, %s, %s)) {" name name len_var; + sprintf "\t\t%s();" sgx_ocfree_fn; + "\t\treturn SGX_ERROR_UNEXPECTED;"; + "\t}"; sprintf "\t__tmp = (void *)((size_t)__tmp + %s);" len_var; - sprintf "} else if (%s == NULL) {" name; - sprintf "\t%s = NULL;" parm_accessor; + sprintf "\tocalloc_size -= %s;" len_var; "} else {"; - sprintf "\t%s();" sgx_ocfree_fn; - "\treturn SGX_ERROR_INVALID_PARAMETER;"; + sprintf "\t%s = NULL;" parm_accessor; "}" ] in List.fold_left (fun acc s -> acc ^ s ^ "\n\t") "" code_template | _ -> let code_template = - [sprintf "if (%s != NULL && sgx_is_within_enclave(%s, %s)) {" name name len_var; + [sprintf "if (%s != NULL) {" name; sprintf "\t%s = (%s)__tmp;" parm_accessor tystr; - sprintf "\tmemcpy(__tmp, %s, %s);" name len_var; + sprintf "\tif (memcpy_s(__tmp, ocalloc_size, %s, %s)) {" name len_var; + sprintf "\t\t%s();" sgx_ocfree_fn; + "\t\treturn SGX_ERROR_UNEXPECTED;"; + "\t}"; sprintf "\t__tmp = (void *)((size_t)__tmp + %s);" len_var; - sprintf "} else if (%s == NULL) {" name; - sprintf "\t%s = NULL;" parm_accessor; + sprintf "\tocalloc_size -= %s;" len_var; "} else {"; - sprintf "\t%s();" sgx_ocfree_fn; - "\treturn SGX_ERROR_INVALID_PARAMETER;"; + sprintf "\t%s = NULL;" parm_accessor; "}" ] in List.fold_left (fun acc s -> acc ^ s ^ "\n\t") "" code_template @@ -1302,6 +1313,7 @@ let gen_tproxy_local_vars (plist: Ast.pdecl list) = (* Generate only one ocalloc block required for the trusted proxy. *) let gen_ocalloc_block (fname: string) (plist: Ast.pdecl list) (is_switchless: bool) = let ms_struct_name = mk_ms_struct_name fname in + let new_param_list = List.map conv_array_to_ptr plist in let local_vars_block = sprintf "%s* %s = NULL;\n\tsize_t ocalloc_size = sizeof(%s);\n\tvoid *__tmp = NULL;\n\n" ms_struct_name ms_struct_val ms_struct_name in let local_var (attr: Ast.ptr_attr) (name: string) = if not attr.Ast.pa_chkptr then "" @@ -1316,9 +1328,25 @@ let gen_ocalloc_block (fname: string) (plist: Ast.pdecl list) (is_switchless: bo Ast.PTVal _ -> "" | Ast.PTPtr (_, attr) -> local_var attr declr.Ast.identifier in + + let check_enclave_ptr_block = + let check_enclave_ptr (pd: Ast.pdecl) = + let checker = "CHECK_ENCLAVE_POINTER" in + let (pty, declr) = pd in + match pty with + Ast.PTVal _ -> "" + | Ast.PTPtr (ty, attr) -> + if not attr.Ast.pa_chkptr then "" + else sprintf "\t%s(%s, %s);\n" checker declr.Ast.identifier (mk_len_var declr.Ast.identifier) + in + let do_check_enclave_ptr = List.fold_left (fun acc pd -> acc ^ check_enclave_ptr pd) "" new_param_list in + let break_line = if do_check_enclave_ptr = "" then "" else "\n" in + break_line ^ do_check_enclave_ptr ^ break_line + in + let count_ocalloc_size (ty: Ast.atype) (attr: Ast.ptr_attr) (name: string) = if not attr.Ast.pa_chkptr then "" - else sprintf "\tocalloc_size += (%s != NULL && sgx_is_within_enclave(%s, %s)) ? %s : 0;\n" name name (mk_len_var name) (mk_len_var name) + else sprintf "\tocalloc_size += (%s != NULL) ? %s : 0;\n" name (mk_len_var name) in let do_count_ocalloc_size (pd: Ast.pdecl) = let (pty, declr) = pd in @@ -1336,14 +1364,13 @@ let gen_ocalloc_block (fname: string) (plist: Ast.pdecl list) (is_switchless: bo "\t}\n"; sprintf "\t%s = (%s*)__tmp;\n" ms_struct_val ms_struct_name; sprintf "\t__tmp = (void *)((size_t)__tmp + sizeof(%s));\n" ms_struct_name; + sprintf "\tocalloc_size -= sizeof(%s);\n" ms_struct_name; ] in - let new_param_list = List.map conv_array_to_ptr plist - in let s1 = List.fold_left (fun acc pd -> acc ^ do_local_var pd) local_vars_block new_param_list in - let s2 = List.fold_left (fun acc pd -> acc ^ do_count_ocalloc_size pd) s1 new_param_list in + let s2 = List.fold_left (fun acc pd -> acc ^ do_count_ocalloc_size pd) (s1 ^ check_enclave_ptr_block) new_param_list in List.fold_left (fun acc s -> acc ^ s) s2 do_gen_ocalloc_block - + (* Generate trusted proxy code for a given untrusted function. *) let gen_func_tproxy (ufunc: Ast.untrusted_func) (idx: int) = let fd = ufunc.Ast.uf_fdecl in @@ -1362,10 +1389,12 @@ let gen_func_tproxy (ufunc: Ast.untrusted_func) (idx: int) = Ast.PtrInOut | Ast.PtrOut -> if attr.Ast.pa_isstr then let code_template = [ - sprintf "\tif (%s)" name; - "\t{"; + sprintf "\tif (%s) {" name; sprintf "\t\tsize_t __tmp%s;" (mk_len_var name); - sprintf "\t\tmemcpy((void*)%s, __tmp_%s, %s);" name name (mk_len_var name); + sprintf "\t\tif (memcpy_s((void*)%s, %s, __tmp_%s, %s)) {" name (mk_len_var name) name (mk_len_var name); + sprintf "\t\t\t%s();" sgx_ocfree_fn; + "\t\t\treturn SGX_ERROR_UNEXPECTED;"; + "\t\t}"; sprintf "\t\t((char*)%s)[%s - 1] = '\\0';" name (mk_len_var name); sprintf "\t\t__tmp%s = strlen(%s) + 1;" (mk_len_var name) name; sprintf "\t\tmemset(%s +__tmp%s - 1, 0, %s -__tmp%s);" name (mk_len_var name) (mk_len_var name) (mk_len_var name); @@ -1375,10 +1404,12 @@ let gen_func_tproxy (ufunc: Ast.untrusted_func) (idx: int) = List.fold_left (fun acc s -> acc ^ "\t" ^ s ^ "\n") "" code_template else if attr.Ast.pa_iswstr then let code_template = [ - sprintf "\tif (%s)" name; - "\t{"; + sprintf "\tif (%s) {" name; sprintf "\t\tsize_t __tmp%s;" (mk_len_var name); - sprintf "\t\tmemcpy((void*)%s, __tmp_%s, %s);" name name (mk_len_var name); + sprintf "\t\tif (memcpy_s((void*)%s, %s, __tmp_%s, %s)) {" name (mk_len_var name) name (mk_len_var name); + sprintf "\t\t\t%s();" sgx_ocfree_fn; + "\t\t\treturn SGX_ERROR_UNEXPECTED;"; + "\t\t}"; sprintf "\t\t((wchar_t*)%s)[(%s - sizeof(wchar_t))/sizeof(wchar_t)] = (wchar_t)0;" name (mk_len_var name); sprintf "\t\t__tmp%s = (wcslen(%s) + 1) * sizeof(wchar_t);" (mk_len_var name) name; sprintf "\t\tmemset(((uint8_t*)%s) + __tmp%s - sizeof(wchar_t), 0, %s -__tmp%s);" name (mk_len_var name) (mk_len_var name) (mk_len_var name); @@ -1387,7 +1418,16 @@ let gen_func_tproxy (ufunc: Ast.untrusted_func) (idx: int) = in List.fold_left (fun acc s -> acc ^ "\t" ^ s ^ "\n") "" code_template else - sprintf "\t\tif (%s) memcpy((void*)%s, __tmp_%s, %s);\n" name name name (mk_len_var name) + let code_template = [ + sprintf "\tif (%s) {" name; + sprintf "\t\tif (memcpy_s((void*)%s, %s, __tmp_%s, %s)) {" name (mk_len_var name) name (mk_len_var name); + sprintf "\t\t\t%s();" sgx_ocfree_fn; + "\t\t\treturn SGX_ERROR_UNEXPECTED;"; + "\t\t}"; + "\t}"; + ] + in + List.fold_left (fun acc s -> acc ^ "\t" ^ s ^ "\n") "" code_template | _ -> "" in List.fold_left (fun acc (pty, declr) -> @@ -1473,7 +1513,7 @@ let gen_trusted_source (ec: enclave_content) = #include \"sgx_trts.h\" /* for sgx_ocalloc, sgx_is_outside_enclave */\n\ #include \"sgx_lfence.h\" /* for sgx_lfence */\n\n\ #include \n\ -#include /* for memcpy etc */\n\ +#include /* for memcpy_s etc */\n\ #include /* for malloc/free etc */\n\ \n\ #define CHECK_REF_POINTER(ptr, siz) do {\t\\\n\ @@ -1485,6 +1525,11 @@ let gen_trusted_source (ec: enclave_content) = \tif ((ptr) && ! sgx_is_outside_enclave((ptr), (siz)))\t\\\n\ \t\treturn SGX_ERROR_INVALID_PARAMETER;\\\n\ } while (0)\n\ +\n\ +#define CHECK_ENCLAVE_POINTER(ptr, siz) do {\t\\\n\ +\tif ((ptr) && ! sgx_is_within_enclave((ptr), (siz)))\t\\\n\ +\t\treturn SGX_ERROR_INVALID_PARAMETER;\\\n\ +} while (0)\n\ \n" in let trusted_fds = tf_list_to_fd_list ec.tfunc_decls in let tbridge_list = diff --git a/sdk/edger8r/linux/Parser.mly b/sdk/edger8r/linux/Parser.mly index 428630a9..84274414 100644 --- a/sdk/edger8r/linux/Parser.mly +++ b/sdk/edger8r/linux/Parser.mly @@ -637,15 +637,19 @@ propagate_errno: /* nothing */ { false } | Tpropagate_errno { true } ; -untrusted_func_def: attr_block func_def allow_list propagate_errno switchless_annotation { +untrusted_prefixes: /* nothing */ { [] } + | attr_block { $1 } + ; + +untrusted_postfixes: /* nothing */ { (false, false) } + | Tpropagate_errno switchless_annotation { (true, $2) } + | Tswitchless propagate_errno { ($2, true) } + ; + +untrusted_func_def: untrusted_prefixes func_def allow_list untrusted_postfixes { check_ptr_attr $2 (symbol_start_pos(), symbol_end_pos()); let fattr = get_func_attr $1 in - Ast.Untrusted { Ast.uf_fdecl = $2; Ast.uf_fattr = fattr; Ast.uf_allow_list = $3; Ast.uf_propagate_errno = $4; Ast.uf_is_switchless = $5; } - } - | func_def allow_list propagate_errno switchless_annotation { - check_ptr_attr $1 (symbol_start_pos(), symbol_end_pos()); - let fattr = get_func_attr [] in - Ast.Untrusted { Ast.uf_fdecl = $1; Ast.uf_fattr = fattr; Ast.uf_allow_list = $2; Ast.uf_propagate_errno = $3; Ast.uf_is_switchless = $4; } + Ast.Untrusted { Ast.uf_fdecl = $2; Ast.uf_fattr = fattr; Ast.uf_allow_list = $3; Ast.uf_propagate_errno = fst $4; Ast.uf_is_switchless = snd $4; } } ; diff --git a/sdk/edger8r/linux/Plugin.ml b/sdk/edger8r/linux/Plugin.ml index d751b151..1df44fee 100644 --- a/sdk/edger8r/linux/Plugin.ml +++ b/sdk/edger8r/linux/Plugin.ml @@ -1,3 +1,34 @@ +(* + * Copyright (C) 2011-2018 Intel Corporation. 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 name of Intel 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 + * OWNER 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. + * + *) + (* Dependency injection plugin to allow custom code generation from EDL. CodeGen.ml calls into Plugin.available to check diff --git a/sdk/libcapable/linux/sgx_capable_version.cpp b/sdk/libcapable/linux/sgx_capable_version.cpp index b1df38f8..aeb3c6b5 100644 --- a/sdk/libcapable/linux/sgx_capable_version.cpp +++ b/sdk/libcapable/linux/sgx_capable_version.cpp @@ -41,7 +41,7 @@ extern "C" { #endif __attribute__((visibility("default"))) -const char * sgx_capable_version = SGX_CAPABLE_VERSION_STR; +char sgx_capable_version[] = SGX_CAPABLE_VERSION_STR; #ifdef __cplusplus } diff --git a/sdk/protected_fs/sgx_tprotected_fs/file_version.cpp b/sdk/protected_fs/sgx_tprotected_fs/file_version.cpp index 215f3ff9..35610e17 100644 --- a/sdk/protected_fs/sgx_tprotected_fs/file_version.cpp +++ b/sdk/protected_fs/sgx_tprotected_fs/file_version.cpp @@ -39,7 +39,7 @@ extern "C" { #endif __attribute__((visibility("default"))) -const char * sgx_tprotectedfs_version = SGX_TPROTECTEDFS_VERSION_STR; +char sgx_tprotectedfs_version[] = SGX_TPROTECTEDFS_VERSION_STR; #ifdef __cplusplus } #endif diff --git a/sdk/sign_tool/SignTool/manage_metadata.cpp b/sdk/sign_tool/SignTool/manage_metadata.cpp index 46d9ed0a..d1ac76c5 100644 --- a/sdk/sign_tool/SignTool/manage_metadata.cpp +++ b/sdk/sign_tool/SignTool/manage_metadata.cpp @@ -749,13 +749,13 @@ bool CMetadata::build_patch_table() patches.push_back(patch); // patch the image header - uint64_t *zero = (uint64_t *)alloc_buffer_from_metadata(sizeof(*zero)); + uint32_t size = 0; + uint8_t *zero = (uint8_t *)alloc_buffer_from_metadata(0); // get addr only, size will be determined later if(zero == NULL) { se_trace(SE_TRACE_ERROR, INVALID_ENCLAVE_ERROR); return false; } - *zero = 0; bin_fmt_t bf = m_parser->get_bin_format(); if(bf == BF_ELF32) { @@ -764,16 +764,19 @@ bool CMetadata::build_patch_table() patch.src = (uint32_t)PTR_DIFF(zero, m_metadata); patch.size = (uint32_t)sizeof(elf_hdr->e_shnum); patches.push_back(patch); + if (patch.size > size) size = patch.size; patch.dst = (uint64_t)PTR_DIFF(&elf_hdr->e_shoff, base_addr); patch.src = (uint32_t)PTR_DIFF(zero, m_metadata); patch.size = (uint32_t)sizeof(elf_hdr->e_shoff); patches.push_back(patch); + if (patch.size > size) size = patch.size; patch.dst = (uint64_t)PTR_DIFF(&elf_hdr->e_shstrndx, base_addr); patch.src = (uint32_t)PTR_DIFF(zero, m_metadata); patch.size = (uint32_t)sizeof(elf_hdr->e_shstrndx); patches.push_back(patch); + if (patch.size > size) size = patch.size; // Modify GNU_RELRO info to eliminate the impact of enclave measurement. Elf32_Phdr *prg_hdr = GET_PTR(Elf32_Phdr, base_addr, elf_hdr->e_phoff); @@ -785,6 +788,7 @@ bool CMetadata::build_patch_table() patch.src = (uint32_t)PTR_DIFF(zero, m_metadata); patch.size = (uint32_t)sizeof(Elf32_Phdr); patches.push_back(patch); + if (patch.size > size) size = patch.size; break; } } @@ -797,17 +801,28 @@ bool CMetadata::build_patch_table() patch.src = (uint32_t)PTR_DIFF(zero, m_metadata); patch.size = (uint32_t)sizeof(elf_hdr->e_shnum); patches.push_back(patch); + if (patch.size > size) size = patch.size; patch.dst = (uint64_t)PTR_DIFF(&elf_hdr->e_shoff, base_addr); patch.src = (uint32_t)PTR_DIFF(zero, m_metadata); patch.size = (uint32_t)sizeof(elf_hdr->e_shoff); patches.push_back(patch); + if (patch.size > size) size = patch.size; patch.dst = (uint64_t)PTR_DIFF(&elf_hdr->e_shstrndx, base_addr); patch.src = (uint32_t)PTR_DIFF(zero, m_metadata); patch.size = (uint32_t)sizeof(elf_hdr->e_shstrndx); patches.push_back(patch); + if (patch.size > size) size = patch.size; } + zero = (uint8_t *)alloc_buffer_from_metadata(size); // alloc buffer again with the accurate size + if(zero == NULL) + { + se_trace(SE_TRACE_ERROR, INVALID_ENCLAVE_ERROR); + return false; + } + memset(zero, 0, size); + if(false == build_patch_entries(patches)) { se_trace(SE_TRACE_ERROR, NO_MEMORY_ERROR); diff --git a/sdk/sign_tool/SignTool/sign_tool.cpp b/sdk/sign_tool/SignTool/sign_tool.cpp index d320b1c4..4b4f70a0 100644 --- a/sdk/sign_tool/SignTool/sign_tool.cpp +++ b/sdk/sign_tool/SignTool/sign_tool.cpp @@ -877,7 +877,7 @@ static bool generate_compatible_metadata(metadata_t *metadata, const xml_paramet } // append 2_0 metadata - memcpy(metadata2, metadata, metadata->size); + memcpy_s(metadata2, metadata->size, metadata, metadata->size); metadata2->version = META_DATA_MAKE_VERSION(SGX_2_0_MAJOR_VERSION,SGX_2_0_MINOR_VERSION); if (!append_compatible_metadata(metadata2, metadata)) { @@ -889,69 +889,46 @@ static bool generate_compatible_metadata(metadata_t *metadata, const xml_paramet metadata2->version = META_DATA_MAKE_VERSION(SGX_1_9_MAJOR_VERSION,SGX_1_9_MINOR_VERSION); layout_t *start = GET_PTR(layout_t, metadata2, metadata2->dirs[DIR_LAYOUT].offset); layout_t *end = GET_PTR(layout_t, start, metadata2->dirs[DIR_LAYOUT].size); - layout_t tmp_layout, *first_dyn_entry = NULL, *first = NULL, *utility_td = NULL; + layout_t tmp_layout; + layout_t *ut_start = NULL, *ut_end = NULL, *after_ut = NULL; uint32_t size_to_reduce = 0; bool ret = false; + // locate utility thread start and end entries for (layout_t *l = start; l < end; l++) { - if ((l->entry.id == LAYOUT_ID_STACK_DYN_MAX) || - (l->entry.id == LAYOUT_ID_STACK_DYN_MIN)) - { - first_dyn_entry = l; + if (ut_start != NULL && ut_end != NULL) break; + + if ((ut_start == NULL) && (l->entry.id == LAYOUT_ID_GUARD)) + { + ut_start = l; + continue; + } + if ((ut_end == NULL) && (l->entry.id == LAYOUT_ID_TD)) + { + ut_end = l; + continue; } } - // no dynamic layout, append the metadata directly - if (first_dyn_entry == NULL) - { - ret = append_compatible_metadata(metadata2, metadata); - free(metadata2); - return ret; - } - - //sizeof(layout_t) for the guard page before LAYOUT_ID_STACK_DYN_MAX - size_to_reduce = (uint32_t)((size_t)end - (size_t)first_dyn_entry + sizeof(layout_t)); - - layout_t *last = &first_dyn_entry[-2]; - - for (layout_t *l = start; l <= last; l++) - { - if (l->entry.id == LAYOUT_ID_TD) - { - utility_td = l; - break; - } - } - assert(utility_td != NULL); - - //Besides dynamic threads, there's only a single utility thread - if (utility_td == last) - { - metadata_cleanup(metadata2, size_to_reduce); - ret = append_compatible_metadata(metadata2, metadata); - free(metadata2); - return ret; - } - - layout_t *utility_start = NULL; - for (layout_t *l = start; l <= last; l++) - { - if (l->entry.id == LAYOUT_ID_GUARD) - { - utility_start = l; - break; - } - } - assert(utility_start != NULL); + assert((ut_start != NULL) && (ut_end != NULL) && ((size_t)ut_end > (size_t)ut_start)); // entry/group layout if they all exist: // utility thread | minpool thread | minpool group | eremove thread | eremove group | dyn thread | dyn group + // there is only an utility thread in layout table + if (&ut_end[1] == end) + { + metadata_cleanup(metadata2, 0); + ret = append_compatible_metadata(metadata2, metadata); + free(metadata2); + return ret; + } + // build a group layout to represent all the possible minpool/eremoved layouts - first = &utility_td[1]; - uint16_t num_of_entries = (uint16_t)(first - utility_start); + after_ut = &ut_end[1]; + uint16_t num_of_entries = (uint16_t)(after_ut - ut_start); memset(&tmp_layout, 0, sizeof(tmp_layout)); tmp_layout.group.id = LAYOUT_ID_THREAD_GROUP; @@ -959,11 +936,11 @@ static bool generate_compatible_metadata(metadata_t *metadata, const xml_paramet tmp_layout.group.load_times = (uint32_t)parameter[TCSNUM].value - 1; for (uint32_t i = 0; i < tmp_layout.group.entry_count; i++) { - tmp_layout.group.load_step += (((uint64_t)utility_start[i].entry.page_count) << SE_PAGE_SHIFT); + tmp_layout.group.load_step += (((uint64_t)ut_start[i].entry.page_count) << SE_PAGE_SHIFT); } - memcpy_s(first, sizeof(layout_t), &tmp_layout, sizeof(layout_t)); - size_to_reduce += (uint32_t)((size_t)last - (size_t)first); + memcpy_s(after_ut, sizeof(layout_t), &tmp_layout, sizeof(layout_t)); + size_to_reduce = (uint32_t)((size_t)end - (size_t)(&after_ut[1])); metadata_cleanup(metadata2, size_to_reduce); ret = append_compatible_metadata(metadata2, metadata); free(metadata2); diff --git a/sdk/sign_tool/SignTool/util_st.h b/sdk/sign_tool/SignTool/util_st.h index 134531f7..47a4cfb1 100644 --- a/sdk/sign_tool/SignTool/util_st.h +++ b/sdk/sign_tool/SignTool/util_st.h @@ -96,7 +96,7 @@ // error message for fill_enclave_css() #define UNSIGNED_FILE_ERROR "The unsigned file \"%s\" is not correct.\n" -#define UNSIGNED_FILE_XML_MISMATCH "The unsigned file content doesn't match the configuration file.\n" +#define UNSIGNED_FILE_XML_MISMATCH "The unsigned file content doesn't match the configuration file (if provided) or the internal configuration defaults.\n" // error message for create_signature() #define SIG_FILE_ERROR "The signature file \"%s\" is not correct.\n" diff --git a/sdk/simulation/tinst/t_instructions.cpp b/sdk/simulation/tinst/t_instructions.cpp index 56f1f218..a3f80d7d 100644 --- a/sdk/simulation/tinst/t_instructions.cpp +++ b/sdk/simulation/tinst/t_instructions.cpp @@ -294,11 +294,10 @@ _EEXIT(uintptr_t dest, uintptr_t xcx, uintptr_t xdx, uintptr_t xsi, uintptr_t xd // By simulator convention, XDX contains XBP and XCX contains XSP. enclu_regs_t regs; - // when the code jump back to the ip after EENTER, the simulation code unwind the stack - // by adding 6*sizeof(uintptr_t), so we substract it in advance. - regs.xsp = xcx - 6 * sizeof(uintptr_t); - regs.xbp = xdx; - regs.xip = dest; + regs.xsp = xcx; // xcx = xsp = ssa.rsp_u + regs.xbp = xdx; // xdx = xbp = ssa.rbp_u + regs.xip = dest; // dest= xbx = xcx on EENTER = return address + // For the value of ssa.rsp_u, ssa.rbp_u, and return address, see _EENTER in u_instruction.cpp tcs_t *tcs = GET_TCS_PTR(xdx); GP_ON(tcs == NULL); @@ -319,6 +318,14 @@ _EEXIT(uintptr_t dest, uintptr_t xcx, uintptr_t xdx, uintptr_t xsi, uintptr_t xd load_regs(®s); + // jump back to the instruction after the call to _SE3 + // common/inc/internal/linux/linux-regs.h: + // call _SE3 + // ---------------------------> jump here + // # ifdef LINUX32 + // add $(SE_WORDSIZE * 6), %esp + // # endif + // Never returns..... } diff --git a/sdk/simulation/uinst/Makefile b/sdk/simulation/uinst/Makefile index bf6ff894..36215d7f 100644 --- a/sdk/simulation/uinst/Makefile +++ b/sdk/simulation/uinst/Makefile @@ -63,7 +63,7 @@ enclave_mngr.o: enclave_mngr.cpp # since the '_SE3' function has assumptions on stack layout. # u_instructions.o: u_instructions.cpp - $(CXX) $(CXXFLAGS) $(CPPFLAGS) -Wno-error=cpp -c $< -o $@ + $(CXX) $(CXXFLAGS) $(CPPFLAGS) -O0 -Wno-error=cpp -c $< -o $@ $(LIBSESIMU_U): u_instructions.o enclave_mngr.o $(OBJ1) $(AR) rcs $@ $^ diff --git a/sdk/simulation/urtssim/urts_deploy.c b/sdk/simulation/urtssim/urts_deploy.c index 2a56e277..ca6c7d9a 100644 --- a/sdk/simulation/urtssim/urts_deploy.c +++ b/sdk/simulation/urtssim/urts_deploy.c @@ -44,12 +44,6 @@ sgx_status_t sgx_create_enclave_ex() return SGX_ERROR_UNEXPECTED; } -sgx_status_t __sgx_create_enclave_ex() -{ - printf("Please use the correct uRTS library from PSW package.\n"); - return SGX_ERROR_UNEXPECTED; -} - sgx_status_t sgx_create_encrypted_enclave() { printf("Please use the correct uRTS library from PSW package.\n"); diff --git a/sdk/tkey_exchange/tkey_exchange_version.cpp b/sdk/tkey_exchange/tkey_exchange_version.cpp index 53332285..c8a19697 100644 --- a/sdk/tkey_exchange/tkey_exchange_version.cpp +++ b/sdk/tkey_exchange/tkey_exchange_version.cpp @@ -41,7 +41,7 @@ extern "C" { #endif __attribute__((visibility("default"))) -const char * sgx_tkey_exchange_version = SGX_TKEY_EXCHANGE_VERSION_STR; +char sgx_tkey_exchange_version[] = SGX_TKEY_EXCHANGE_VERSION_STR; #ifdef __cplusplus } diff --git a/sdk/tlibc/gen/sbrk.c b/sdk/tlibc/gen/sbrk.c index 0cc6bd3b..3bbd08a4 100644 --- a/sdk/tlibc/gen/sbrk.c +++ b/sdk/tlibc/gen/sbrk.c @@ -41,10 +41,10 @@ SE_DECLSPEC_EXPORT size_t g_peak_heap_used = 0; /* Please be aware of: sbrk is not thread safe by default. */ -static void *heap_base = NULL; -static size_t heap_size = 0; -static int is_edmm_supported = 0; -static size_t heap_min_size = 0; +static void *heap_base __attribute__((section(RELRO_SECTION_NAME))) = NULL; +static size_t heap_size __attribute__((section(RELRO_SECTION_NAME))) = 0; +static int is_edmm_supported __attribute__((section(RELRO_SECTION_NAME))) = 0; +static size_t heap_min_size __attribute__((section(RELRO_SECTION_NAME))) = 0; int heap_init(void *_heap_base, size_t _heap_size, size_t _heap_min_size, int _is_edmm_supported) { diff --git a/sdk/tlibcrypto/ipp/sgx_ecc256.cpp b/sdk/tlibcrypto/ipp/sgx_ecc256.cpp index bb380edc..574c0a4b 100644 --- a/sdk/tlibcrypto/ipp/sgx_ecc256.cpp +++ b/sdk/tlibcrypto/ipp/sgx_ecc256.cpp @@ -30,11 +30,12 @@ */ -#include "sgx_tcrypto_common.h" #include "ipp_wrapper.h" +#define ECC_FIELD_SIZE 256 + /* -* Elliptic Curve Crytpography - Based on GF(p), 256 bit +* Elliptic Curve Crytpography - Based on GF(p), 256 bits */ /* Allocates and initializes ecc context * Parameters: @@ -49,13 +50,13 @@ sgx_status_t sgx_ecc256_open_context(sgx_ecc_state_handle_t* p_ecc_handle) if (p_ecc_handle == NULL) return SGX_ERROR_INVALID_PARAMETER; - ipp_ret = ippsECCPGetSize(256, &ctx_size); + ipp_ret = ippsECCPGetSize(ECC_FIELD_SIZE, &ctx_size); if (ipp_ret != ippStsNoErr) return SGX_ERROR_UNEXPECTED; p_ecc_state = (IppsECCPState*)(malloc(ctx_size)); if (p_ecc_state == NULL) return SGX_ERROR_OUT_OF_MEMORY; - ipp_ret = ippsECCPInit(256, p_ecc_state); + ipp_ret = ippsECCPInit(ECC_FIELD_SIZE, p_ecc_state); if (ipp_ret != ippStsNoErr) { CLEAR_FREE_MEM(p_ecc_state, ctx_size); @@ -85,7 +86,7 @@ sgx_status_t sgx_ecc256_close_context(sgx_ecc_state_handle_t ecc_handle) } IppsECCPState* p_ecc_state = (IppsECCPState*)ecc_handle; int ctx_size = 0; - IppStatus ipp_ret = ippsECCPGetSize(256, &ctx_size); + IppStatus ipp_ret = ippsECCPGetSize(ECC_FIELD_SIZE, &ctx_size); if (ipp_ret != ippStsNoErr) { free(p_ecc_state); @@ -121,7 +122,7 @@ sgx_status_t sgx_ecc256_create_key_pair(sgx_ec256_private_t *p_private, do { //init eccp point - ipp_ret = ippsECCPPointGetSize(256, &ecPointSize); + ipp_ret = ippsECCPPointGetSize(ECC_FIELD_SIZE, &ecPointSize); ERROR_BREAK(ipp_ret); point_pub = (IppsECCPPointState*)(malloc(ecPointSize)); if (!point_pub) @@ -129,7 +130,7 @@ sgx_status_t sgx_ecc256_create_key_pair(sgx_ec256_private_t *p_private, ipp_ret = ippStsNoMemErr; break; } - ipp_ret = ippsECCPPointInit(256, point_pub); + ipp_ret = ippsECCPPointInit(ECC_FIELD_SIZE, point_pub); ERROR_BREAK(ipp_ret); ipp_ret = sgx_ipp_newBN(NULL, SGX_ECP256_KEY_SIZE, &dh_priv_BN); @@ -220,7 +221,7 @@ sgx_status_t sgx_ecc256_check_point(const sgx_ec256_public_t *p_point, do { - ipp_ret = ippsECCPPointGetSize(256, &ecPointSize); + ipp_ret = ippsECCPPointGetSize(ECC_FIELD_SIZE, &ecPointSize); ERROR_BREAK(ipp_ret); point2check = (IppsECCPPointState*)malloc(ecPointSize); if (!point2check) @@ -228,7 +229,7 @@ sgx_status_t sgx_ecc256_check_point(const sgx_ec256_public_t *p_point, ipp_ret = ippStsNoMemErr; break; } - ipp_ret = ippsECCPPointInit(256, point2check); + ipp_ret = ippsECCPPointInit(ECC_FIELD_SIZE, point2check); ERROR_BREAK(ipp_ret); ipp_ret = sgx_ipp_newBN((const Ipp32u *)p_point->gx, sizeof(p_point->gx), &BN_gx); @@ -306,7 +307,7 @@ sgx_status_t sgx_ecc256_compute_shared_dhkey(sgx_ec256_private_t *p_private_b, ERROR_BREAK(ipp_ret); ipp_ret = sgx_ipp_newBN((uint32_t*)p_public_ga->gy, sizeof(p_public_ga->gy), &pubA_gy); ERROR_BREAK(ipp_ret); - ipp_ret = ippsECCPPointGetSize(256, &ecPointSize); + ipp_ret = ippsECCPPointGetSize(ECC_FIELD_SIZE, &ecPointSize); ERROR_BREAK(ipp_ret); point_pubA = (IppsECCPPointState*)(malloc(ecPointSize)); if (!point_pubA) @@ -314,7 +315,7 @@ sgx_status_t sgx_ecc256_compute_shared_dhkey(sgx_ec256_private_t *p_private_b, ipp_ret = ippStsNoMemErr; break; } - ipp_ret = ippsECCPPointInit(256, point_pubA); + ipp_ret = ippsECCPPointInit(ECC_FIELD_SIZE, point_pubA); ERROR_BREAK(ipp_ret); ipp_ret = ippsECCPSetPoint(pubA_gx, pubA_gy, point_pubA, p_ecc_state); ERROR_BREAK(ipp_ret); @@ -370,3 +371,152 @@ sgx_status_t sgx_ecc256_compute_shared_dhkey(sgx_ec256_private_t *p_private_b, } } +/** Create an ECC public key based on a given ECC private key. +* +* Parameters: +* Return: sgx_status_t - SGX_SUCCESS or failure as defined in sgx_error.h +* Input: p_att_priv_key - Input private key +* Output: p_att_pub_key - Output public key - LITTLE ENDIAN +* +*/ +sgx_status_t sgx_ecc256_calculate_pub_from_priv(const sgx_ec256_private_t *p_att_priv_key, sgx_ec256_public_t *p_att_pub_key) +{ + if ((p_att_priv_key == NULL) || (p_att_pub_key == NULL)) { + return SGX_ERROR_INVALID_PARAMETER; + } + + IppsECCPState* p_ecc_state = NULL; + sgx_status_t ret = SGX_ERROR_UNEXPECTED; + int ctx_size = 0; + int point_size = 0; + IppsECCPPointState* public_key = NULL; + IppsBigNumState* bn_o = NULL; + IppsBigNumState* bn_x = NULL; + IppsBigNumState* bn_y = NULL; + sgx_ec256_private_t att_priv_key_be; + uint8_t* p_temp; + int size = 0; + IppsBigNumSGN sgn; + + do { + //get the size of the IppsECCPState context + // + if (ippsECCPGetSize(ECC_FIELD_SIZE, &ctx_size) != ippStsNoErr) { + break; + } + + //allocate ecc ctx + // + p_ecc_state = (IppsECCPState*)(malloc(ctx_size)); + if (NULL == p_ecc_state) { + ret = SGX_ERROR_OUT_OF_MEMORY; + break; + } + + //init ecc ctx + // + if (ippsECCPInit(ECC_FIELD_SIZE, p_ecc_state) != ippStsNoErr) { + break; + } + + //set up elliptic curve domain parameters over GF(p) + // + if (ippsECCPSetStd(IppECCPStd256r1, p_ecc_state) != ippStsNoErr) { + break; + } + + //get point (public key) size + // + if (ippsECCPPointGetSize(ECC_FIELD_SIZE, &point_size) != ippStsNoErr) { + break; + } + + //allocate point of point_size size + // + public_key = (IppsECCPPointState*)(malloc(point_size)); + if (NULL == public_key) { + ret = SGX_ERROR_OUT_OF_MEMORY; + break; + } + + //init point + // + if (ippsECCPPointInit(ECC_FIELD_SIZE, public_key) != ippStsNoErr) { + break; + } + + //allocate bn_o, will be used for private key + // + if (sgx_ipp_newBN(NULL, sizeof(sgx_ec256_private_t), &bn_o) != ippStsNoErr) { + break; + } + + //convert private key into big endian + // + p_temp = (uint8_t*)p_att_priv_key; + for (uint32_t i = 0; i(&att_priv_key_be), sizeof(sgx_ec256_private_t), bn_o) != ippStsNoErr) { + break; + } + + //compute public key from the given private key (bn_o) of the elliptic cryptosystem (p_ecc_state) over GF(p). + // + if (ippsECCPPublicKey(bn_o, public_key, p_ecc_state) != ippStsNoErr) { + break; + } + + //allocate BNs + // + if (sgx_ipp_newBN(NULL, sizeof(sgx_ec256_private_t), &bn_x) != ippStsNoErr) { + break; + } + + if (sgx_ipp_newBN(NULL, sizeof(sgx_ec256_private_t), &bn_y) != ippStsNoErr) { + break; + } + //assign public key into BNs + // + if (ippsECCPGetPoint(bn_x, bn_y, public_key, p_ecc_state) != ippStsNoErr) { + break; + } + + //output key in little endian order + // + //gx value + if (ippsGetSize_BN(bn_x, &size) != ippStsNoErr) { + break; + } + if (ippsGet_BN(&sgn, &size, reinterpret_cast(p_att_pub_key->gx), bn_x) != ippStsNoErr) { + break; + } + //gy value + // + if (ippsGetSize_BN(bn_y, &size) != ippStsNoErr) { + break; + } + if (ippsGet_BN(&sgn, &size, reinterpret_cast(p_att_pub_key->gy), bn_y) != ippStsNoErr) { + break; + } + + ret = SGX_SUCCESS; + } while (0); + + //in case of failure clear public key + // + if (ret != SGX_SUCCESS) { + (void)memset_s(p_att_pub_key, sizeof(sgx_ec256_public_t), 0, sizeof(sgx_ec256_public_t)); + } + + CLEAR_FREE_MEM(p_ecc_state, ctx_size); + CLEAR_FREE_MEM(public_key, point_size); + sgx_ipp_secure_free_BN(bn_o, sizeof(sgx_ec256_private_t)); + sgx_ipp_secure_free_BN(bn_x, sizeof(sgx_ec256_private_t)); + sgx_ipp_secure_free_BN(bn_y, sizeof(sgx_ec256_private_t)); + + return ret; +} diff --git a/sdk/tlibcrypto/ipp/sgx_ecc256_ecdsa.cpp b/sdk/tlibcrypto/ipp/sgx_ecc256_ecdsa.cpp index d595201f..50c6e499 100644 --- a/sdk/tlibcrypto/ipp/sgx_ecc256_ecdsa.cpp +++ b/sdk/tlibcrypto/ipp/sgx_ecc256_ecdsa.cpp @@ -30,7 +30,7 @@ */ -#include "sgx_tcrypto_common.h" +#include "ipp_wrapper.h" const uint32_t sgx_nistp256_r[] = { diff --git a/sdk/tlibcrypto/ipp/sgx_ecc256_internal.cpp b/sdk/tlibcrypto/ipp/sgx_ecc256_internal.cpp index 7d9f86bd..c85ee2c2 100644 --- a/sdk/tlibcrypto/ipp/sgx_ecc256_internal.cpp +++ b/sdk/tlibcrypto/ipp/sgx_ecc256_internal.cpp @@ -32,7 +32,7 @@ -#include "sgx_tcrypto_common.h" +#include "ipp_wrapper.h" #include "sgx_ecc256_internal.h" diff --git a/sdk/tlibcrypto/ipp/sgx_rsa3072.cpp b/sdk/tlibcrypto/ipp/sgx_rsa3072.cpp index 6943f4de..d13bfdc3 100644 --- a/sdk/tlibcrypto/ipp/sgx_rsa3072.cpp +++ b/sdk/tlibcrypto/ipp/sgx_rsa3072.cpp @@ -30,9 +30,9 @@ */ -#include "sgx_tcrypto_common.h" #include "ipp_wrapper.h" + sgx_status_t sgx_rsa3072_sign(const uint8_t * p_data, uint32_t data_size, const sgx_rsa3072_key_t * p_key, diff --git a/sdk/tlibcrypto/ipp/sgx_rsa_encryption.cpp b/sdk/tlibcrypto/ipp/sgx_rsa_encryption.cpp index 6f822035..a582c268 100644 --- a/sdk/tlibcrypto/ipp/sgx_rsa_encryption.cpp +++ b/sdk/tlibcrypto/ipp/sgx_rsa_encryption.cpp @@ -43,7 +43,6 @@ #include "sgx_trts.h" #include "ipp_wrapper.h" -#include "sgx_tcrypto_common.h" sgx_status_t sgx_create_rsa_key_pair(int n_byte_size, int e_byte_size, unsigned char *p_n, unsigned char *p_d, unsigned char *p_e, unsigned char *p_p, unsigned char *p_q, unsigned char *p_dmp1, @@ -355,7 +354,7 @@ sgx_status_t sgx_rsa_pub_encrypt_sha256(void* rsa_key, unsigned char* pout_data, ret_code = SGX_ERROR_OUT_OF_MEMORY; break; } - memset(p_scratch_buffer, 0, scratch_buff_size); + memset(p_scratch_buffer, 0, scratch_buff_size); //get random seed // diff --git a/sdk/tlibcrypto/ipp/sgx_rsa_internal.cpp b/sdk/tlibcrypto/ipp/sgx_rsa_internal.cpp index 842ea40d..6717c252 100644 --- a/sdk/tlibcrypto/ipp/sgx_rsa_internal.cpp +++ b/sdk/tlibcrypto/ipp/sgx_rsa_internal.cpp @@ -31,73 +31,7 @@ #include #include -#include "ipp_wrapper.h" - -extern "C" IppStatus newBN(const Ipp32u *data, int size_in_bytes, IppsBigNumState **p_new_BN) -{ - IppsBigNumState *pBN = 0; - int bn_size = 0; - - if (p_new_BN == NULL || size_in_bytes <= 0 || size_in_bytes % sizeof(Ipp32u)) - return ippStsBadArgErr; - - /* Get the size of the IppsBigNumState context in bytes */ - IppStatus error_code = ippsBigNumGetSize(size_in_bytes / (int)sizeof(Ipp32u), &bn_size); - if (error_code != ippStsNoErr) { - *p_new_BN = 0; - return error_code; - } - pBN = (IppsBigNumState *)malloc(bn_size); - if (!pBN) { - error_code = ippStsMemAllocErr; - *p_new_BN = 0; - return error_code; - } - /* Initializes context and partitions allocated buffer */ - error_code = ippsBigNumInit(size_in_bytes / (int)sizeof(Ipp32u), pBN); - if (error_code != ippStsNoErr) { - SAFE_FREE_MM(pBN); - *p_new_BN = 0; - return error_code; - } - if (data) { - error_code = ippsSet_BN(IppsBigNumPOS, size_in_bytes / (int)sizeof(Ipp32u), data, pBN); - if (error_code != ippStsNoErr) { - SAFE_FREE_MM(pBN); - *p_new_BN = 0; - return error_code; - } - } - *p_new_BN = pBN; - return error_code; - -} - - -extern "C" void secure_free_BN(IppsBigNumState *pBN, int size_in_bytes) -{ - if (pBN == NULL || size_in_bytes <= 0 || size_in_bytes % sizeof(Ipp32u)) { - if (pBN) { - free(pBN); - } - return; - } - - int bn_size = 0; - - /* Get the size of the IppsBigNumState context in bytes - * Since we have checked the size_in_bytes before and the &bn_size is not NULL, - * ippsBigNumGetSize never returns failure - */ - if (ippsBigNumGetSize(size_in_bytes / (int)sizeof(Ipp32u), &bn_size) != ippStsNoErr) { - free(pBN); - return; - } - /* Clear the buffer before free. */ - memset_s(pBN, bn_size, 0, bn_size); - free(pBN); - return; -} +#include "ippcp.h" extern "C" void secure_free_rsa_pri2_key(int p_byte_size, IppsRSAPrivateKeyState *pri_key2) { diff --git a/sdk/tlibcrypto/ipp/sgx_tcrypto_common.cpp b/sdk/tlibcrypto/ipp/sgx_tcrypto_common.cpp index 8980f662..98edfeb5 100644 --- a/sdk/tlibcrypto/ipp/sgx_tcrypto_common.cpp +++ b/sdk/tlibcrypto/ipp/sgx_tcrypto_common.cpp @@ -30,7 +30,7 @@ */ -#include "sgx_tcrypto_common.h" +#include "ipp_wrapper.h" IppStatus sgx_ipp_newBN(const Ipp32u *p_data, int size_in_bytes, IppsBigNumState **p_new_BN) diff --git a/sdk/tlibcrypto/ipp/sgx_tcrypto_common.h b/sdk/tlibcrypto/ipp/sgx_tcrypto_common.h deleted file mode 100644 index 794bd65a..00000000 --- a/sdk/tlibcrypto/ipp/sgx_tcrypto_common.h +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Copyright (C) 2011-2018 Intel Corporation. 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 name of Intel 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 - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - */ - - -#ifndef _SGX_TCRYPTO_COMMON_H_ -#define _SGX_TCRYPTO_COMMON_H_ - -#include "ippcp.h" -#include "sgx_trts.h" -#include "sgx_tcrypto.h" -#include "util.h" -#include "stdlib.h" -#include "string.h" - -#ifndef ERROR_BREAK -#define ERROR_BREAK(x) if(x != ippStsNoErr){break;} -#endif -#ifndef SAFE_FREE -#define SAFE_FREE(ptr) {if (NULL != (ptr)) {free(ptr); (ptr)=NULL;}} -#endif - -#define RSA_SEED_SIZE_SHA256 32 - -IppStatus sgx_ipp_newBN(const Ipp32u *p_data, int size_in_bytes, IppsBigNumState **p_new_BN); -void sgx_ipp_secure_free_BN(IppsBigNumState *pBN, int size_in_bytes); -IppStatus IPP_STDCALL sgx_ipp_DRNGen(Ipp32u* pRandBNU, int nBits, void* pCtx); - -IppStatus sgx_ipp_newPrimeGen(int nMaxBits, IppsPrimeState ** pPrimeG); - - -static inline IppStatus check_copy_size(size_t target_size, size_t source_size) -{ - if(target_size < source_size) - return ippStsSizeErr; - return ippStsNoErr; -} - -#endif diff --git a/sdk/tlibcrypto/sgxssl/sgx_cmac128.cpp b/sdk/tlibcrypto/sgxssl/sgx_cmac128.cpp index 1fc9e7e0..7dcb4139 100644 --- a/sdk/tlibcrypto/sgxssl/sgx_cmac128.cpp +++ b/sdk/tlibcrypto/sgxssl/sgx_cmac128.cpp @@ -55,8 +55,6 @@ sgx_status_t sgx_rijndael128_cmac_msg(const sgx_cmac_128bit_key_t *p_key, const size_t mactlen; sgx_status_t ret = SGX_ERROR_UNEXPECTED; - CLEAR_OPENSSL_ERROR_QUEUE; - do { //create a new ctx of CMAC // diff --git a/sdk/tlibcrypto/sgxssl/sgx_ecc256.cpp b/sdk/tlibcrypto/sgxssl/sgx_ecc256.cpp index 9ccc7170..d663c1c3 100644 --- a/sdk/tlibcrypto/sgxssl/sgx_ecc256.cpp +++ b/sdk/tlibcrypto/sgxssl/sgx_ecc256.cpp @@ -35,7 +35,7 @@ #include #include #include "sgx_tcrypto.h" - +#include "ssl_wrapper.h" #define POINT_NOT_ON_CURVE 0x1007c06b /* @@ -401,3 +401,106 @@ sgx_status_t sgx_ecc256_compute_shared_dhkey(sgx_ec256_private_t *p_private_b, return ret; } + +/** Create an ECC public key based on a given ECC private key. +* +* Parameters: +* Return: sgx_status_t - SGX_SUCCESS or failure as defined in sgx_error.h +* Input: p_att_priv_key - Input private key +* Output: p_att_pub_key - Output public key - LITTLE ENDIAN +* +*/ +sgx_status_t sgx_ecc256_calculate_pub_from_priv(const sgx_ec256_private_t *p_att_priv_key, sgx_ec256_public_t *p_att_pub_key) +{ + if ((p_att_priv_key == NULL) || (p_att_pub_key == NULL)) { + return SGX_ERROR_INVALID_PARAMETER; + } + + sgx_status_t ret = SGX_ERROR_UNEXPECTED; + EC_GROUP* ec_group = NULL; + EC_POINT *pub_ec_point = NULL; + BIGNUM *bn_o = NULL; + BIGNUM *bn_x = NULL; + BIGNUM *bn_y = NULL; + BN_CTX *tmp = NULL; + + CLEAR_OPENSSL_ERROR_QUEUE; + + do { + //create empty BNs + // + bn_x = BN_new(); + if (NULL == bn_x) { + ret = SGX_ERROR_OUT_OF_MEMORY; + break; + } + bn_y = BN_new(); + if (NULL == bn_y) { + ret = SGX_ERROR_OUT_OF_MEMORY; + break; + } + tmp = BN_CTX_new(); + if (NULL == tmp) { + ret = SGX_ERROR_OUT_OF_MEMORY; + break; + } + + //init bn_o with private key value + // + bn_o = BN_lebin2bn((const unsigned char*)p_att_priv_key, (int)sizeof(sgx_ec256_private_t), bn_o); + BN_CHECK_BREAK(bn_o); + + //create a new ecc group and initialize it to NID_X9_62_prime256v1 curve + // + ec_group = EC_GROUP_new_by_curve_name(NID_X9_62_prime256v1); + if (ec_group == NULL) { + break; + } + + //create a new EC point + // + pub_ec_point = EC_POINT_new(ec_group); + if (pub_ec_point == NULL) { + break; + } + + //calculate public key (point) based on private key. (pub = priv * curve_griup) + // + if (!EC_POINT_mul(ec_group, pub_ec_point, bn_o, NULL, NULL, tmp)) { + break; + } + + //retrieve x and y coordinates into BNs + // + if (!EC_POINT_get_affine_coordinates_GFp(ec_group, pub_ec_point, bn_x, bn_y, tmp)) { + break; + } + + //convert the absolute value of BNs into little-endian buffers + // + if (!BN_bn2lebinpad(bn_x, p_att_pub_key->gx, BN_num_bytes(bn_x))) { + break; + } + + if (!BN_bn2lebinpad(bn_y, p_att_pub_key->gy, BN_num_bytes(bn_y))) { + break; + } + + ret = SGX_SUCCESS; + } while (0); + + //in case of failure clear public key + // + if (ret != SGX_SUCCESS) { + (void)memset_s(p_att_pub_key, sizeof(sgx_ec256_public_t), 0, sizeof(sgx_ec256_public_t)); + } + + BN_clear_free(bn_o); + BN_clear_free(bn_x); + BN_clear_free(bn_y); + BN_CTX_free(tmp); + EC_GROUP_clear_free(ec_group); + EC_POINT_clear_free(pub_ec_point); + + return ret; +} diff --git a/sdk/tlibcrypto/tcrypto_version.cpp b/sdk/tlibcrypto/tcrypto_version.cpp index ed0ceded..9c0f38f9 100644 --- a/sdk/tlibcrypto/tcrypto_version.cpp +++ b/sdk/tlibcrypto/tcrypto_version.cpp @@ -40,7 +40,7 @@ extern "C" { #endif __attribute__((visibility("default"))) -const char * sgx_tcrypto_version = SGX_TCRYPTO_VERSION_STR; +char sgx_tcrypto_version[] = SGX_TCRYPTO_VERSION_STR; #ifdef __cplusplus } diff --git a/sdk/tlibcxx/Makefile b/sdk/tlibcxx/Makefile index da11ea01..f92f8b1b 100644 --- a/sdk/tlibcxx/Makefile +++ b/sdk/tlibcxx/Makefile @@ -50,7 +50,7 @@ CPPFLAGS += -I$(ROOT_DIR)/android/ndk-toolchain/sysroot/usr/include endif #ANDROID CPP_SRCS := $(wildcard src/*.cpp) -CPP_OBJS := $(CPP_SRCS:.cpp=.o) +CPP_OBJS := $(sort $(CPP_SRCS:.cpp=.o)) OBJS := $(CPP_OBJS) diff --git a/sdk/trts/init_enclave.cpp b/sdk/trts/init_enclave.cpp index 0fd5e137..2a36184f 100644 --- a/sdk/trts/init_enclave.cpp +++ b/sdk/trts/init_enclave.cpp @@ -51,16 +51,16 @@ #include "se_memcpy.h" // The global cpu feature bits from uRTS -uint64_t g_cpu_feature_indicator = 0; -int EDMM_supported = 0; -sdk_version_t g_sdk_version = SDK_VERSION_1_5; +uint64_t g_cpu_feature_indicator __attribute__((section(RELRO_SECTION_NAME))) = 0; +int EDMM_supported __attribute__((section(RELRO_SECTION_NAME))) = 0; +sdk_version_t g_sdk_version __attribute__((section(RELRO_SECTION_NAME))) = SDK_VERSION_1_5; const volatile global_data_t g_global_data __attribute__((section(".niprod"))) = {1, 2, 3, 4, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, {0, 0, 0, 0, 0, 0}, 0}, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 0, 0, {{{0, 0, 0, 0, 0, 0, 0}}}}; uint32_t g_enclave_state __attribute__((section(".nipd"))) = ENCLAVE_INIT_NOT_STARTED; extern "C" { -uintptr_t __stack_chk_guard = 0; +uintptr_t __stack_chk_guard __attribute__((section(RELRO_SECTION_NAME)))= 0; #define __weak_alias(alias,sym) \ __asm__(".weak " __STRING(alias) " ; " \ __STRING(alias) " = " __STRING(sym)) diff --git a/sdk/trts/linux/global_init.c b/sdk/trts/linux/global_init.c index e3bd69c2..cd75078e 100644 --- a/sdk/trts/linux/global_init.c +++ b/sdk/trts/linux/global_init.c @@ -120,10 +120,8 @@ int atexit(void (*fun)(void)) static void do_atexit_aux(void) { - sgx_spin_lock(&g_exit_function_lock); exit_function_t *exit_function = g_exit_function; g_exit_function = NULL; - sgx_spin_unlock(&g_exit_function_lock); while (exit_function != NULL) { diff --git a/sdk/trts/trts_ecall.cpp b/sdk/trts/trts_ecall.cpp index 4fd3526e..f1f358ba 100644 --- a/sdk/trts/trts_ecall.cpp +++ b/sdk/trts/trts_ecall.cpp @@ -374,7 +374,7 @@ sgx_status_t do_ecall_add_thread(void *ms) if (!sgx_is_outside_enclave(tcs, sizeof(struct ms_tcs))) { - abort(); + return status; } const struct ms_tcs mtcs = *tcs; @@ -384,7 +384,7 @@ sgx_status_t do_ecall_add_thread(void *ms) return status; } - __builtin_ia32_lfence(); + sgx_lfence(); status = do_save_tcs(ptcs); if(SGX_SUCCESS != status) @@ -413,7 +413,7 @@ sgx_status_t do_ecall_add_thread(void *ms) sgx_status_t do_uninit_enclave(void *tcs) { #ifndef SE_SIM - if(is_dynamic_thread_exist() && !is_utility_thread()) + if(EDMM_supported && !is_utility_thread()) return SGX_ERROR_UNEXPECTED; #endif tcs_node_t *tcs_node = g_tcs_node; diff --git a/sdk/trts/trts_veh.cpp b/sdk/trts/trts_veh.cpp index e0e34bfe..e2aeb358 100644 --- a/sdk/trts/trts_veh.cpp +++ b/sdk/trts/trts_veh.cpp @@ -309,10 +309,10 @@ extern "C" sgx_status_t trts_handle_exception(void *tcs) uintptr_t sp, *new_sp = NULL; size_t size = 0; - if (tcs == NULL) goto default_handler; + if ((thread_data == NULL) || (tcs == NULL)) goto default_handler; if (check_static_stack_canary(tcs) != 0) goto default_handler; - + if(get_enclave_state() != ENCLAVE_INIT_DONE) { goto default_handler; diff --git a/sdk/tseal/tSeal.cpp b/sdk/tseal/tSeal.cpp index 88ac9dff..862c2430 100644 --- a/sdk/tseal/tSeal.cpp +++ b/sdk/tseal/tSeal.cpp @@ -202,21 +202,23 @@ extern "C" sgx_status_t sgx_unseal_data(const sgx_sealed_data_t *p_sealed_data, { return SGX_ERROR_INVALID_PARAMETER; } - if (!sgx_is_within_enclave(p_decrypted_text,encrypt_text_length)) + if (!sgx_is_within_enclave(p_decrypted_text_length, sizeof(p_decrypted_text_length))) { return SGX_ERROR_INVALID_PARAMETER; } - if (!sgx_is_within_enclave(p_decrypted_text_length,sizeof(p_decrypted_text_length))) + uint32_t input_decrypted_text_length = *p_decrypted_text_length; + if (input_decrypted_text_length < encrypt_text_length) { return SGX_ERROR_INVALID_PARAMETER; } - // Ensure aad data does not cross enclave boundary - if ((add_text_length > 0) && - (!(sgx_is_within_enclave(p_additional_MACtext,add_text_length) || sgx_is_outside_enclave(p_additional_MACtext, add_text_length)))) + if (!sgx_is_within_enclave(p_decrypted_text, input_decrypted_text_length)) { return SGX_ERROR_INVALID_PARAMETER; } - if ((*p_decrypted_text_length) < encrypt_text_length) + + if((p_additional_MACtext_length != NULL) && + (!(sgx_is_within_enclave(p_additional_MACtext_length, sizeof(p_additional_MACtext_length)) || + sgx_is_outside_enclave(p_additional_MACtext_length, sizeof(p_additional_MACtext_length))))) { return SGX_ERROR_INVALID_PARAMETER; } @@ -224,6 +226,12 @@ extern "C" sgx_status_t sgx_unseal_data(const sgx_sealed_data_t *p_sealed_data, if (additional_MACtext_length < add_text_length) { return SGX_ERROR_INVALID_PARAMETER; } + // Ensure aad data does not cross enclave boundary + if ((add_text_length > 0) && + (!(sgx_is_within_enclave(p_additional_MACtext, additional_MACtext_length) || sgx_is_outside_enclave(p_additional_MACtext, additional_MACtext_length)))) + { + return SGX_ERROR_INVALID_PARAMETER; + } err = sgx_unseal_data_helper(p_sealed_data, p_additional_MACtext, add_text_length, p_decrypted_text, encrypt_text_length); diff --git a/sdk/tseal/tSeal_aad.cpp b/sdk/tseal/tSeal_aad.cpp index 5798de7e..8e2281ad 100644 --- a/sdk/tseal/tSeal_aad.cpp +++ b/sdk/tseal/tSeal_aad.cpp @@ -196,18 +196,21 @@ extern "C" sgx_status_t sgx_unmac_aadata(const sgx_sealed_data_t *p_sealed_data, { return SGX_ERROR_INVALID_PARAMETER; } - - // Ensure AAD does not cross enclave boundary - if (!(sgx_is_within_enclave(p_additional_MACtext, add_text_length) || - sgx_is_outside_enclave(p_additional_MACtext, add_text_length))) + if(!(sgx_is_within_enclave(p_additional_MACtext_length, sizeof(p_additional_MACtext_length)) || + sgx_is_outside_enclave(p_additional_MACtext_length, sizeof(p_additional_MACtext_length)))) { return SGX_ERROR_INVALID_PARAMETER; } - uint32_t additional_MACtext_length = *p_additional_MACtext_length; if (additional_MACtext_length < add_text_length) { return SGX_ERROR_INVALID_PARAMETER; } + // Ensure AAD does not cross enclave boundary + if (!(sgx_is_within_enclave(p_additional_MACtext, additional_MACtext_length) || + sgx_is_outside_enclave(p_additional_MACtext, additional_MACtext_length))) + { + return SGX_ERROR_INVALID_PARAMETER; + } err = sgx_unseal_data_helper(p_sealed_data, p_additional_MACtext, add_text_length, NULL, encrypt_text_length); diff --git a/sdk/tsetjmp/Makefile b/sdk/tsetjmp/Makefile index 81713ed6..14a40a88 100644 --- a/sdk/tsetjmp/Makefile +++ b/sdk/tsetjmp/Makefile @@ -44,11 +44,9 @@ CPPFLAGS += -I. \ -I ../trts -LIBLONGJMP_CPP_SRCS := tlongjmp_version.cpp LIBLONGJMP_ASM_SRCS := $(wildcard *.S) LIBLONGJMP_OBJS := $(sort $(LIBLONGJMP_ASM_SRCS:.S=.o)) -LIBLONGJMP_OBJS += $(LIBLONGJMP_CPP_SRCS:.cpp=.o) LIBLONGJMP_NAME := libsgx_tsetjmp.a @@ -58,9 +56,6 @@ all: $(LIBLONGJMP_NAME) $(LIBLONGJMP_NAME): $(LIBLONGJMP_OBJS) $(AR) rcs $@ $^ -%.o: %.cpp - $(CXX) $(CXXFLAGS) $(CPPFLAGS) -c $< -o $@ - %.o: %.S $(CC) $(ASFLAGS) $(CPPFLAGS) -c $< -o $@ diff --git a/sdk/tsetjmp/_setjmp.S b/sdk/tsetjmp/_setjmp.S index 0a8bb26d..45cfc656 100644 --- a/sdk/tsetjmp/_setjmp.S +++ b/sdk/tsetjmp/_setjmp.S @@ -274,10 +274,6 @@ DECLARE_GLOBAL_FUNC longjmp 1: ret -DECLARE_GLOBAL_FUNC set_sgx_tlongjmp_version - lea_pic sgx_tsetjmp_version, %xax - ret - .weak _setjmp _setjmp=setjmp .weak _longjmp diff --git a/sdk/ukey_exchange/ukey_exchange_version.cpp b/sdk/ukey_exchange/ukey_exchange_version.cpp index fefda37c..abe3f6c2 100644 --- a/sdk/ukey_exchange/ukey_exchange_version.cpp +++ b/sdk/ukey_exchange/ukey_exchange_version.cpp @@ -41,7 +41,7 @@ extern "C" { #endif __attribute__((visibility("default"))) -const char * sgx_ukey_exchange_version = SGX_UKEY_EXCHANGE_VERSION_STR; +char sgx_ukey_exchange_version[] = SGX_UKEY_EXCHANGE_VERSION_STR; #ifdef __cplusplus }