diff --git a/QuoteGeneration/Makefile b/QuoteGeneration/Makefile index 0ac78d29..c55c3619 100644 --- a/QuoteGeneration/Makefile +++ b/QuoteGeneration/Makefile @@ -31,17 +31,28 @@ CUR_MKFILE:= $(lastword $(MAKEFILE_LIST)) -.PHONY: all dcap opt_check_failed clean rebuild pce_logic qe3_logic qcnl_wrapper qpl_wrapper qve_wrapper +.PHONY: all dcap opt_check_failed clean rebuild pce_logic tdx_logic tdx_qgs tdx_attest qe3_logic qcnl_wrapper qpl_wrapper qve_wrapper all: dcap +#-------------------------------------------------------------------------------------- +# Function: get_distr_info +# Arguments: 1: the grep keyword to be searched from /etc/os-release +# Returns: Return the value for the Linux distribution info corresponding to the keyword +#--------------------------------------------------------------------------------------- +get_distr_info = $(patsubst "%",%,$(shell grep $(1) /etc/os-release 2> /dev/null | awk -F'=' '{print $$2}')) + +DISTR_ID := $(call get_distr_info, '^ID=') +DISTR_VER := $(call get_distr_info, '^VERSION_ID=') + + # DCAP requires prebuilt enclaves. CHECK_OPT := ifeq ("$(wildcard psw/ae/data/prebuilt)", "") CHECK_OPT := opt_check_failed endif -dcap: $(CHECK_OPT) pce_logic qe3_logic qcnl_wrapper qpl_wrapper qve_wrapper +dcap: tdx_logic tdx_qgs tdx_attest $(CHECK_OPT) pce_logic qe3_logic qcnl_wrapper qpl_wrapper qve_wrapper tdx_qe id_enclave opt_check_failed: @echo "Please run download_prebuilt.sh before compiling" @@ -50,6 +61,8 @@ opt_check_failed: pce_logic: $(MAKE) -C pce_wrapper/linux +id_enclave: + $(MAKE) -C quote_wrapper/quote/id_enclave/linux qe3_logic: pce_logic $(MAKE) -C quote_wrapper/ql/linux @@ -95,6 +108,35 @@ deb_sgx_ae_id_enclave_pkg: $(CHECK_OPT) deb_sgx_ae_qve_pkg: $(CHECK_OPT) ./installer/linux/deb/libsgx-ae-qve/build.sh +.PHONY: deb_sgx_ae_tdqe_pkg deb_sgx_tdx_logic_pkg deb_sgx_tdx_qgs_pkg deb_sgx_tdx_attest_pkg +ifeq ($(DISTR_ID)$(DISTR_VER),ubuntu18.04) +tdx_qe deb_sgx_ae_tdqe_pkg: + echo "Skip tdqe in ubuntu 18.04" +tdx_logic deb_sgx_tdx_logic_pkg: + echo "Skip tdx_logic in ubuntu 18.04" +tdx_qgs deb_sgx_tdx_qgs_pkg: + echo "Skip tdx_qgs in ubuntu 18.04" +tdx_attest deb_sgx_tdx_attest_pkg: + echo "Skip tdx_attest in ubuntu 18.04" +else +tdx_qe: + $(MAKE) -C quote_wrapper/tdx_quote/enclave/linux +tdx_logic: pce_logic + $(MAKE) -C quote_wrapper/tdx_quote/linux +tdx_qgs: tdx_logic + $(MAKE) -C quote_wrapper/qgs +tdx_attest: + $(MAKE) -C quote_wrapper/tdx_attest/linux +deb_sgx_ae_tdqe_pkg: $(CHECK_OPT) + ./installer/linux/deb/libsgx-ae-tdqe/build.sh +deb_sgx_tdx_logic_pkg: tdx_logic + ./installer/linux/deb/libsgx-tdx-logic/build.sh +deb_sgx_tdx_qgs_pkg: tdx_qgs + ./installer/linux/deb/tdx-qgs/build.sh +deb_sgx_tdx_attest_pkg: tdx_attest + ./installer/linux/deb/libtdx-attest/build.sh +endif + .PHONY: deb_sgx_qe3_logic_pkg deb_sgx_qe3_logic_pkg: qe3_logic ./installer/linux/deb/libsgx-qe3-logic/build.sh @@ -114,7 +156,7 @@ deb_sgx_ra_service_pkg: .PHONY: deb_pkg -deb_pkg: deb_sgx_pce_logic_pkg deb_sgx_qe3_logic_pkg deb_sgx_dcap_ql_pkg deb_sgx_dcap_quote_verify_pkg deb_sgx_dcap_default_qpl_pkg deb_sgx_dcap_pccs_pkg deb_sgx_ae_qe3_pkg deb_sgx_ae_id_enclave_pkg deb_sgx_ae_qve_pkg deb_sgx_pck_id_retrieval_tool_pkg deb_sgx_ra_service_pkg +deb_pkg: deb_sgx_pce_logic_pkg deb_sgx_qe3_logic_pkg deb_sgx_dcap_ql_pkg deb_sgx_dcap_quote_verify_pkg deb_sgx_dcap_default_qpl_pkg deb_sgx_dcap_pccs_pkg deb_sgx_ae_qe3_pkg deb_sgx_ae_tdqe_pkg deb_sgx_ae_id_enclave_pkg deb_sgx_ae_qve_pkg deb_sgx_tdx_logic_pkg deb_sgx_tdx_qgs_pkg deb_sgx_tdx_attest_pkg deb_sgx_pck_id_retrieval_tool_pkg deb_sgx_ra_service_pkg @$(RM) -f ./installer/linux/deb/*.deb ./installer/linux/deb/*.ddeb cp `find ./installer/linux/deb/ -name "*.deb" -o -name "*.ddeb"` ./installer/linux/deb/ cp `find ../tools/PCKRetrievalTool/installer/deb/ -name "*.deb" -o -name "*.ddeb"` ./installer/linux/deb/ @@ -139,6 +181,9 @@ rpm_sgx_dcap_pccs_pkg: rpm_sgx_ae_qe3_pkg: $(CHECK_OPT) ./installer/linux/rpm/libsgx-ae-qe3/build.sh +.PHONY: rpm_sgx_ae_tdqe_pkg +rpm_sgx_ae_tdqe_pkg: $(CHECK_OPT) + ./installer/linux/rpm/libsgx-ae-tdqe/build.sh .PHONY: rpm_sgx_ae_id_enclave_pkg rpm_sgx_ae_id_enclave_pkg: $(CHECK_OPT) ./installer/linux/rpm/libsgx-ae-id-enclave/build.sh @@ -146,6 +191,15 @@ rpm_sgx_ae_id_enclave_pkg: $(CHECK_OPT) .PHONY: rpm_sgx_ae_qve_pkg rpm_sgx_ae_qve_pkg: $(CHECK_OPT) qve_wrapper ./installer/linux/rpm/libsgx-ae-qve/build.sh +.PHONY: rpm_sgx_tdx_logic_pkg +rpm_sgx_tdx_logic_pkg: tdx_logic + ./installer/linux/rpm/libsgx-tdx-logic/build.sh +.PHONY: rpm_sgx_tdx_qgs_pkg +rpm_sgx_tdx_qgs_pkg: tdx_qgs + ./installer/linux/rpm/tdx-qgs/build.sh +.PHONY: rpm_sgx_tdx_attest_pkg +rpm_sgx_tdx_attest_pkg: tdx_attest + ./installer/linux/rpm/libtdx-attest/build.sh .PHONY: rpm_sgx_dcap_quote_verify_pkg rpm_sgx_dcap_quote_verify_pkg: $(CHECK_OPT) qve_wrapper @@ -169,7 +223,7 @@ rpm_sgx_ra_service_pkg: $(MAKE) -C ../tools/SGXPlatformRegistration/ rpm_pkg .PHONY: rpm_pkg -rpm_pkg: rpm_sgx_dcap_ql_pkg rpm_sgx_dcap_default_qpl_pkg rpm_sgx_dcap_pccs_pkg rpm_sgx_ae_qe3_pkg rpm_sgx_ae_id_enclave_pkg rpm_sgx_ae_qve_pkg rpm_sgx_dcap_quote_verify_pkg rpm_sgx_pce_logic_pkg rpm_sgx_qe3_logic_pkg rpm_sgx_pck_id_retrieval_tool_pkg rpm_sgx_ra_service_pkg +rpm_pkg: rpm_sgx_dcap_ql_pkg rpm_sgx_dcap_default_qpl_pkg rpm_sgx_dcap_pccs_pkg rpm_sgx_ae_qe3_pkg rpm_sgx_ae_tdqe_pkg rpm_sgx_ae_id_enclave_pkg rpm_sgx_ae_qve_pkg rpm_sgx_tdx_logic_pkg rpm_sgx_tdx_qgs_pkg rpm_sgx_tdx_attest_pkg rpm_sgx_dcap_quote_verify_pkg rpm_sgx_pce_logic_pkg rpm_sgx_qe3_logic_pkg rpm_sgx_pck_id_retrieval_tool_pkg rpm_sgx_ra_service_pkg @$(RM) -f ./installer/linux/rpm/*.rpm cp `find ./installer/linux/rpm/ -name "*.rpm"` ./installer/linux/rpm/ cp `find ../tools/PCKRetrievalTool/installer/rpm/ -name "*.rpm"` ./installer/linux/rpm/ @@ -178,6 +232,9 @@ rpm_pkg: rpm_sgx_dcap_ql_pkg rpm_sgx_dcap_default_qpl_pkg rpm_sgx_dcap_pccs_pkg clean: $(MAKE) -C pce_wrapper/linux clean $(MAKE) -C quote_wrapper/ql/linux clean + $(MAKE) -C quote_wrapper/qgs clean + $(MAKE) -C quote_wrapper/tdx_quote/linux clean + $(MAKE) -C quote_wrapper/tdx_attest/linux clean $(MAKE) -C qcnl/linux clean $(MAKE) -C qpl/linux clean $(MAKE) -C ../QuoteVerification clean @@ -190,20 +247,28 @@ clean: ./installer/linux/deb/libsgx-dcap-ql/clean.sh ./installer/linux/deb/libsgx-dcap-quote-verify/clean.sh ./installer/linux/deb/libsgx-ae-qe3/clean.sh + ./installer/linux/deb/libsgx-ae-tdqe/clean.sh ./installer/linux/deb/libsgx-ae-id-enclave/clean.sh ./installer/linux/deb/libsgx-ae-qve/clean.sh ./installer/linux/deb/libsgx-pce-logic/clean.sh ./installer/linux/deb/libsgx-qe3-logic/clean.sh + ./installer/linux/deb/libsgx-tdx-logic/clean.sh + ./installer/linux/deb/tdx-qgs/clean.sh + ./installer/linux/deb/libtdx-attest/clean.sh ./installer/linux/deb/libsgx-dcap-default-qpl/clean.sh ./installer/linux/deb/sgx-dcap-pccs/clean.sh ../tools/PCKRetrievalTool/installer/deb/sgx-pck-id-retrieval-tool/clean.sh ./installer/linux/rpm/libsgx-dcap-ql/clean.sh ./installer/linux/rpm/libsgx-ae-qe3/clean.sh + ./installer/linux/rpm/libsgx-ae-tdqe/clean.sh ./installer/linux/rpm/libsgx-ae-id-enclave/clean.sh ./installer/linux/rpm/libsgx-ae-qve/clean.sh ./installer/linux/rpm/libsgx-dcap-quote-verify/clean.sh ./installer/linux/rpm/libsgx-pce-logic/clean.sh ./installer/linux/rpm/libsgx-qe3-logic/clean.sh + ./installer/linux/rpm/libsgx-tdx-logic/clean.sh + ./installer/linux/rpm/tdx-qgs/clean.sh + ./installer/linux/rpm/libtdx-attest/clean.sh ./installer/linux/rpm/libsgx-dcap-default-qpl/clean.sh ./installer/linux/rpm/sgx-dcap-pccs/clean.sh ../tools/PCKRetrievalTool/installer/rpm/sgx-pck-id-retrieval-tool/clean.sh diff --git a/QuoteGeneration/README.md b/QuoteGeneration/README.md index 7b7c2810..94e0a7c7 100644 --- a/QuoteGeneration/README.md +++ b/QuoteGeneration/README.md @@ -2,7 +2,7 @@ Intel(R) Software Guard Extensions Data Center Attestation Primitives (Intel(R) ================================================ For Windows* OS ------------------ +----------------- ## Prerequisites - Ensure that you have the following required operating systems: * Windows* Server 2016 (Long-Term Servicing Channel) @@ -22,7 +22,7 @@ For Windows* OS ## How to build - In the top directory, open the Microsoft Visual Studio* solution `SGX_DCAP.sln` and run a build. - The Intel(R) SGX DCAP NuGet* package generation depends on a standalone tool `nuget.exe`. To build the Intel(R) SGX DCAP NuGet* package: - 1. Download the standalone tool `nuget.exe` from [nuget.org/downloads](https://nuget.org/downloads) and put it to `installer\win\` folder or add the folder where you placed `nuget.exe` to your PATH environment variable. + 1. Download the standalone tool `nuget.exe` from [nuget.org/downloads](https://nuget.org/downloads) and put it to `installer\win\` folder or add the folder where you placed `nuget.exe` to your PATH environment variable. 2. Go to `installer\win\` folder and run the following command from the Command Prompt: ``` DCAP_Components.bat @@ -33,11 +33,11 @@ For Windows* OS dcap_copy_file.bat dcap_generate.bat ``` - The target INF installers `sgx_dcap.inf` and `sgx_dcap_dev.inf` will be generated in the same folder. + The target INF installers `sgx_dcap.inf` and `sgx_dcap_dev.inf` will be generated in the same folder. **NOTE**:`sgx_dcap_dev.inf` is for Windows* Server 2016 LTSC and `sgx_dcap.inf` is for Windows* Server 2019 LTSC. ## How to install - Refer to the *"Installation Instructions"* section in the [Intel(R) Software Guard Extensions: Data Center Attestation Primitives Installation Guide For Windows* OS](https://download.01.org/intel-sgx/sgx-dcap/1.13/windows/docs/Intel_SGX_DCAP_Windows_SW_Installation_Guide.pdf) to install the right packages on your platform. + Refer to the *"Installation Instructions"* section in the [Intel(R) Software Guard Extensions: Data Center Attestation Primitives Installation Guide For Windows* OS](https://download.01.org/intel-sgx/sgx-dcap/1.14/windows/docs/Intel_SGX_DCAP_Windows_SW_Installation_Guide.pdf) to install the right packages on your platform. For Linux* OS @@ -47,8 +47,8 @@ For Linux* OS * Ubuntu* 18.04 LTS Desktop 64bits * Ubuntu* 18.04 LTS Server 64bits * Ubuntu* 20.04 LTS Server 64bits - * Red Hat Enterprise Linux Server release 8.2 64bits - * CentOS 8.2 64bits + * Red Hat Enterprise Linux Server release 8.5 64bits + * CentOS Stream 8 64bits - Ensure that you have the following required hardware: * 8th Generation Intel(R) Core(TM) Processor or newer with **Flexible Launch Control** support* * Intel(R) Atom(TM) Processor with **Flexible Launch Control** support* @@ -60,17 +60,17 @@ For Linux* OS ``` * On Ubuntu 20.04 ``` - $ sudo apt-get install build-essential wget python-is-python3 debhelper zip libcurl4-openssl-dev + $ sudo apt-get install build-essential wget python-is-python3 debhelper zip libcurl4-openssl-dev pkgconf libboost-dev libboost-system-dev protobuf-c-compiler libprotobuf-c-dev protobuf-compiler ``` - * On Red Hat Enterprise Linux 8.2 + * On Red Hat Enterprise Linux 8.5 ``` $ sudo yum groupinstall 'Development Tools' - $ sudo yum install wget python2 rpm-build zip + $ sudo yum install wget python2 rpm-build zip pkgconf boost-devel protobuf-lite-devel protobuf-c-compiler protobuf-c-devel ``` - * On CentOS 8.2 + * On CentOS Stream 8 ``` $ sudo dnf group install 'Development Tools' - $ sudo dnf --enablerepo=PowerTools install wget python2 rpm-build zip + $ sudo dnf --enablerepo=powertools install wget python2 rpm-build zip pkgconf boost-devel protobuf-lite-devel protobuf-c-compiler protobuf-c-devel ``` - Install latest prebuilt Intel(R) SGX SDK Installer from [01.org](https://01.org/intel-software-guard-extensions/downloads) ``` @@ -98,7 +98,7 @@ A `README.md` is provided in the Intel(R) SGX driver package for Intel(R) SGX DC - To build the Intel(R) SGX DCAP Quote Generation Library and the Intel(R) SGX Default Quote Provider Library, enter the following command: ``` $ make -``` +``` - To clean the files generated by previous `make` command, enter the following command: ``` $ make clean @@ -117,12 +117,12 @@ A `README.md` is provided in the Intel(R) SGX driver package for Intel(R) SGX DC $ make deb_pkg ``` You can find the generated installers located under `linux/installer/deb/`. - **Note**: On Ubuntu 18.04 and Ubuntu 20.04, the above command also generates another debug symbol package with extension name of `.ddeb` for debug purpose. + **Note**: On Ubuntu 18.04 and Ubuntu 20.04, the above command also generates another debug symbol package with extension name of `.ddeb` for debug purpose. **Note**: The above command builds the installers with default configuration firstly and then generates the target installers. To build the installers without optimization and with full debug information kept in the libraries, enter the following command: ``` $ make deb_pkg DEBUG=1 ``` - * On Red Hat Enterprise Linux 8.2 and CentOS 8.2: + * On Red Hat Enterprise Linux 8.5 and CentOS Stream 8: ``` $ make rpm_pkg ``` @@ -140,7 +140,7 @@ A `README.md` is provided in the Intel(R) SGX driver package for Intel(R) SGX DC ``` **NOTE**: Sometimes we will split old package into smaller ones or move files between different packages. In such cases, you need to add `--force-overwrite` to overwrite existing files. If you're doing a fresh install, you can omit this option. - * On Red Hat Enterprise Linux 8.2 and CentOS 8.2: + * On Red Hat Enterprise Linux 8.5 and CentOS Stream 8: ``` $ sudo rpm -ivh libsgx-ae-pce*.rpm libsgx-ae-qe3*.rpm libsgx-ae-id-enclave*.rpm libsgx-ae-qve*.rpm libsgx-enclave-common*.rpm libsgx-urts*.rpm ``` @@ -151,7 +151,7 @@ A `README.md` is provided in the Intel(R) SGX driver package for Intel(R) SGX DC ``` $ sudo dpkg -i libsgx-dcap-ql_*.deb ``` - * On Red Hat Enterprise Linux 8.2 and CentOS 8.2: + * On Red Hat Enterprise Linux 8.5 and CentOS Stream 8: ``` $ sudo rpm -ivh libsgx-dcap-ql*.rpm ``` @@ -162,7 +162,7 @@ A `README.md` is provided in the Intel(R) SGX driver package for Intel(R) SGX DC $ sudo dpkg -i libsgx-dcap-ql-dev_*.deb $ sudo dpkg -i libsgx-dcap-ql-dbgsym_*.deb ``` - * On Red Hat Enterprise Linux 8.2 and CentOS 8.2: + * On Red Hat Enterprise Linux 8.5 and CentOS Stream 8: ``` $ sudo rpm -ivh libsgx-dcap-ql-devel*.rpm $ sudo rpm -ivh libsgx-dcap-ql-debuginfo*.rpm @@ -175,7 +175,7 @@ A `README.md` is provided in the Intel(R) SGX driver package for Intel(R) SGX DC $ sudo dpkg -i libsgx-dcap-default-qpl_*.deb $ sudo dpkg -i sgx-dcap-pccs_*.deb ``` - * On Red Hat Enterprise Linux 8.2 and CentOS 8.2: + * On Red Hat Enterprise Linux 8.5 and CentOS Stream 8: ``` $ sudo rpm -ivh libsgx-dcap-default-qpl*.rpm $ sudo rpm -ivh sgx-dcap-pccs*.rpm @@ -187,8 +187,10 @@ A `README.md` is provided in the Intel(R) SGX driver package for Intel(R) SGX DC $ sudo dpkg -i libsgx-dcap-default-qpl-dev*.deb libsgx-headers*.deb $ sudo dpkg -i libsgx-dcap-default-qpl-dbgsym*.deb ``` - * On Red Hat Enterprise Linux 8.2 and CentOS 8.2: + * On Red Hat Enterprise Linux 8.5 and CentOS Stream 8: ``` $ sudo rpm -ivh libsgx-dcap-default-qpl-devel*.rpm libsgx-headers*.rpm $ sudo rpm -ivh libsgx-dcap-default-qpl-debuginfo*.rpm ``` +## TDX Attestation Support +- From version 1.14, TDX attestation feature is added into DCAP. Corresponding packages will be built along with the DCAP Quote Generation Library adn DCAP Quote Verification Library. Currently, TDX attestation support has been verified on Red Hat Enterprise Linux 8.5 and CentOS Stream 8 only. diff --git a/QuoteGeneration/common/inc/internal/se_trace.h b/QuoteGeneration/common/inc/internal/se_trace.h index 1aa03967..91a9c218 100644 --- a/QuoteGeneration/common/inc/internal/se_trace.h +++ b/QuoteGeneration/common/inc/internal/se_trace.h @@ -119,7 +119,7 @@ void __attribute__((weak)) sgx_proc_log_report(int level, const char* format, . #else #define SE_PROD_LOG(fmt, ...) \ do { \ - if(sgx_proc_log_report) { \ + if(sgx_proc_log_report != NULL) { \ sgx_proc_log_report(1, "[%s %s:%d] " fmt, __FUNCTION__, __FILE__, __LINE__, ##__VA_ARGS__); \ } else { \ se_trace_internal(SE_TRACE_ERROR, "[%s %s:%d] " fmt, __FUNCTION__, __FILE__, __LINE__, ##__VA_ARGS__); \ diff --git a/QuoteGeneration/common/inc/internal/se_version.h b/QuoteGeneration/common/inc/internal/se_version.h index df997c8f..9f8a558e 100644 --- a/QuoteGeneration/common/inc/internal/se_version.h +++ b/QuoteGeneration/common/inc/internal/se_version.h @@ -28,18 +28,21 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * */ -#define STRFILEVER "1.13.100.4" +#define STRFILEVER "1.14.100.3" #define COPYRIGHT "Copyright (C) 2022 Intel Corporation" -#define FILEVER 1,13,100,4 -#define PRODUCTVER 1,13,100,4 -#define STRPRODUCTVER "1.13.100.4" +#define FILEVER 1,14,100,3 +#define PRODUCTVER 1,14,100,3 +#define STRPRODUCTVER "1.14.100.3" #define COMPANYNAME "Intel Corporation" #define PRODUCTNAME "Intel® Software Guard Extensions" -#define DEFAULT_QPL_VERSION "1.12.102.0" -#define QUOTE_VERIFIER_VERSION "1.11.102.0" -#define QUOTE_LOADER_VERSION "1.11.102.1" +#define DEFAULT_QPL_VERSION "1.13.100.3" +#define QUOTE_VERIFIER_VERSION "1.12.100.3" +#define QUOTE_LOADER_VERSION "1.11.103.3" +#define TDQE_WRAPPER_VERSION "1.14.100.3" +#define PCE_WRAPPER_VERSION "1.14.100.3" -#define QE3_VERSION "1.11.101.1" -#define QVE_VERSION "1.11.101.1" -#define IDE_VERSION "1.11.101.1" +#define QE3_VERSION "1.14.100.2" +#define QVE_VERSION "1.14.100.2" +#define IDE_VERSION "1.14.100.2" +#define TDQE_VERSION "1.14.100.2" diff --git a/QuoteGeneration/download_prebuilt.bat b/QuoteGeneration/download_prebuilt.bat index e0e333af..9d4ebaf2 100644 --- a/QuoteGeneration/download_prebuilt.bat +++ b/QuoteGeneration/download_prebuilt.bat @@ -1,4 +1,4 @@ -@REM Copyright (C) 2011-2021 Intel Corporation. All rights reserved. +@REM Copyright (C) 2011-2022 Intel Corporation. All rights reserved. @REM @REM Redistribution and use in source and binary forms, with or without @REM modification, are permitted provided that the following conditions @@ -29,9 +29,9 @@ @echo off -set ae_file_name=prebuilt_windows_dcap_1.13.zip -set checksum_file=SHA256SUM_prebuilt_windows_dcap_1.13.cfg -set server_url_path=https://download.01.org//intel-sgx/sgx-dcap/1.13/windows/ +set ae_file_name=prebuilt_windows_dcap_1.14.zip +set checksum_file=SHA256SUM_prebuilt_windows_dcap_1.14.cfg +set server_url_path=https://download.01.org/intel-sgx/sgx-dcap/1.14/windows/ set server_ae_url=%server_url_path%/%ae_file_name% set server_checksum_url=%server_url_path%/%checksum_file% diff --git a/QuoteGeneration/download_prebuilt.sh b/QuoteGeneration/download_prebuilt.sh index 828e6ac9..00c21227 100755 --- a/QuoteGeneration/download_prebuilt.sh +++ b/QuoteGeneration/download_prebuilt.sh @@ -32,9 +32,9 @@ top_dir=`dirname $0` out_dir=$top_dir -ae_file_name=prebuilt_dcap_1.13.tar.gz -checksum_file=SHA256SUM_prebuilt_dcap_1.13.cfg -server_url_path=https://download.01.org/intel-sgx/sgx-dcap/1.13/linux +ae_file_name=prebuilt_dcap_1.14.tar.gz +checksum_file=SHA256SUM_prebuilt_dcap_1.14.cfg +server_url_path=https://download.01.org/intel-sgx/sgx-dcap/1.14/linux server_ae_url=$server_url_path/$ae_file_name server_checksum_url=$server_url_path/$checksum_file diff --git a/QuoteGeneration/installer/linux/common/libsgx-ae-tdqe/BOMs/libsgx-ae-tdqe-package.txt b/QuoteGeneration/installer/linux/common/libsgx-ae-tdqe/BOMs/libsgx-ae-tdqe-package.txt new file mode 100644 index 00000000..1aed0baa --- /dev/null +++ b/QuoteGeneration/installer/linux/common/libsgx-ae-tdqe/BOMs/libsgx-ae-tdqe-package.txt @@ -0,0 +1,3 @@ +DeliveryName InstallName FileCheckSum FileFeature FileOwner +/installer/linux/common/libsgx-ae-tdqe/installConfig /installConfig 0 main STP +/installer/linux/common/libsgx-ae-tdqe/Makefile /Makefile 0 main STP diff --git a/QuoteGeneration/installer/linux/common/libsgx-ae-tdqe/BOMs/libsgx-ae-tdqe.txt b/QuoteGeneration/installer/linux/common/libsgx-ae-tdqe/BOMs/libsgx-ae-tdqe.txt new file mode 100644 index 00000000..7445fa47 --- /dev/null +++ b/QuoteGeneration/installer/linux/common/libsgx-ae-tdqe/BOMs/libsgx-ae-tdqe.txt @@ -0,0 +1,2 @@ +DeliveryName InstallName FileCheckSum FileFeature FileOwner +/psw/ae/data/prebuilt/libsgx_tdqe.signed.so /lib/libsgx_tdqe.signed.so 0 main STP diff --git a/QuoteGeneration/installer/linux/common/libsgx-ae-tdqe/Makefile b/QuoteGeneration/installer/linux/common/libsgx-ae-tdqe/Makefile new file mode 100644 index 00000000..afb01bf7 --- /dev/null +++ b/QuoteGeneration/installer/linux/common/libsgx-ae-tdqe/Makefile @@ -0,0 +1,45 @@ +# +# Copyright (C) 2011-2021 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 installConfig + +USR_LIB_PATH=$(shell readlink -m $(DESTDIR)/usr/$(notdir $(shell gcc -print-multi-os-directory))/$(shell dpkg-architecture -qDEB_HOST_MULTIARCH 2> /dev/null)) + +USR_LIB_VER=1.0.0 +SPLIT_VERSION=$(word $2,$(subst ., ,$1)) +default: + +install: + install -d $(USR_LIB_PATH) + install ${LIB_DIR}/* $(USR_LIB_PATH) + cd $(USR_LIB_PATH) && \ + mv libsgx_tdqe.signed.so libsgx_tdqe.signed.so.$(USR_LIB_VER) && \ + ln -fs libsgx_tdqe.signed.so.$(USR_LIB_VER) libsgx_tdqe.signed.so.$(call SPLIT_VERSION,$(USR_LIB_VER),1) \ No newline at end of file diff --git a/QuoteGeneration/installer/linux/common/libsgx-ae-tdqe/createTarball.sh b/QuoteGeneration/installer/linux/common/libsgx-ae-tdqe/createTarball.sh new file mode 100755 index 00000000..9f5e4df4 --- /dev/null +++ b/QuoteGeneration/installer/linux/common/libsgx-ae-tdqe/createTarball.sh @@ -0,0 +1,62 @@ +#!/usr/bin/env bash +# +# Copyright (C) 2011-2021 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}/installer/linux" +LINUX_INSTALLER_COMMON_DIR="${LINUX_INSTALLER_DIR}/common" + +INSTALL_PATH=${SCRIPT_DIR}/output + +# Cleanup +rm -fr ${INSTALL_PATH} + +# Get the configuration for this package +source ${SCRIPT_DIR}/installConfig + +# 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/libsgx-ae-tdqe.txt +python ${SCRIPT_DIR}/gen_source.py --bom=BOMs/libsgx-ae-tdqe-package.txt --cleanup=false +python ${SCRIPT_DIR}/gen_source.py --bom=../licenses/BOM_license.txt --cleanup=false + +# Create the tarball +SGX_VERSION=$(awk '/TDQE_VERSION/ {print $3}' ${ROOT_DIR}/common/inc/internal/se_version.h|sed 's/^\"\(.*\)\"$/\1/') +pushd ${INSTALL_PATH} &> /dev/null +sed -i "s/USR_LIB_VER=.*/USR_LIB_VER=${SGX_VERSION}/" Makefile +tar -zcvf ${TARBALL_NAME} * +popd &> /dev/null diff --git a/QuoteGeneration/installer/linux/common/libsgx-ae-tdqe/installConfig b/QuoteGeneration/installer/linux/common/libsgx-ae-tdqe/installConfig new file mode 100644 index 00000000..9c3afe0b --- /dev/null +++ b/QuoteGeneration/installer/linux/common/libsgx-ae-tdqe/installConfig @@ -0,0 +1,6 @@ +AE_TDX_VERSION="1.0" +TARBALL_NAME=libsgx-ae-tdqe_1.0.orig.tar.gz + +AE_TDX_PACKAGE_NAME=libsgx-ae-tdqe + +LIB_DIR=lib diff --git a/QuoteGeneration/installer/linux/common/libsgx-pce-logic/Makefile b/QuoteGeneration/installer/linux/common/libsgx-pce-logic/Makefile index c269102d..5ef6e663 100644 --- a/QuoteGeneration/installer/linux/common/libsgx-pce-logic/Makefile +++ b/QuoteGeneration/installer/linux/common/libsgx-pce-logic/Makefile @@ -35,6 +35,8 @@ PACKAGE_ROOT_FOLDER=pkgroot PACKAGES=$(notdir $(wildcard $(PACKAGE_ROOT_FOLDER)/*)) USR_LIB_PATH=/usr/$(notdir $(shell gcc -print-multi-os-directory))/$(shell dpkg-architecture -qDEB_HOST_MULTIARCH 2> /dev/null) +USR_LIB_VER=1.0.0 +SPLIT_VERSION=$(word $2,$(subst ., ,$1)) default: @@ -44,3 +46,7 @@ $(PACKAGES): $(if $(wildcard $(PACKAGE_ROOT_FOLDER)/$@/$(LIB_DIR)/*.so), \ install -d $(shell readlink -m $(DESTDIR)/$(USR_LIB_PATH)) && \ mv $(PACKAGE_ROOT_FOLDER)/$@/$(LIB_DIR)/*.so $(DESTDIR)/$(USR_LIB_PATH)) + cd $(DESTDIR)/$(USR_LIB_PATH) && \ + mv libsgx_pce_logic.so libsgx_pce_logic.so.$(USR_LIB_VER) && \ + ln -fs libsgx_pce_logic.so.$(USR_LIB_VER) libsgx_pce_logic.so.$(call SPLIT_VERSION,$(USR_LIB_VER),1) && \ + ln -fs libsgx_pce_logic.so.$(call SPLIT_VERSION,$(USR_LIB_VER),1) libsgx_pce_logic.so diff --git a/QuoteGeneration/installer/linux/common/libsgx-pce-logic/createTarball.sh b/QuoteGeneration/installer/linux/common/libsgx-pce-logic/createTarball.sh index d36332c4..ebb12395 100755 --- a/QuoteGeneration/installer/linux/common/libsgx-pce-logic/createTarball.sh +++ b/QuoteGeneration/installer/linux/common/libsgx-pce-logic/createTarball.sh @@ -55,6 +55,8 @@ python ${SCRIPT_DIR}/gen_source.py --bom=BOMs/libsgx-pce-logic-package.txt --cl python ${SCRIPT_DIR}/gen_source.py --bom=../licenses/BOM_license.txt --cleanup=false # Create the tarball +SGX_VERSION=$(awk '/PCE_WRAPPER_VERSION/ {print $3}' ${ROOT_DIR}/common/inc/internal/se_version.h|sed 's/^\"\(.*\)\"$/\1/') pushd ${INSTALL_PATH} &> /dev/null +sed -i "s/USR_LIB_VER=.*/USR_LIB_VER=${SGX_VERSION}/" Makefile tar -zcvf ${TARBALL_NAME} * popd &> /dev/null diff --git a/QuoteGeneration/installer/linux/common/libsgx-tdx-logic/BOMs/libsgx-tdx-logic-dev.txt b/QuoteGeneration/installer/linux/common/libsgx-tdx-logic/BOMs/libsgx-tdx-logic-dev.txt new file mode 100644 index 00000000..d2966f42 --- /dev/null +++ b/QuoteGeneration/installer/linux/common/libsgx-tdx-logic/BOMs/libsgx-tdx-logic-dev.txt @@ -0,0 +1,2 @@ +DeliveryName InstallName FileCheckSum FileFeature FileOwner +/quote_wrapper/tdx_quote/td_ql_logic.h /include/td_ql_logic.h 0 main STP diff --git a/QuoteGeneration/installer/linux/common/libsgx-tdx-logic/BOMs/libsgx-tdx-logic-package.txt b/QuoteGeneration/installer/linux/common/libsgx-tdx-logic/BOMs/libsgx-tdx-logic-package.txt new file mode 100644 index 00000000..80c8cb40 --- /dev/null +++ b/QuoteGeneration/installer/linux/common/libsgx-tdx-logic/BOMs/libsgx-tdx-logic-package.txt @@ -0,0 +1,3 @@ +DeliveryName InstallName FileCheckSum FileFeature FileOwner +/installer/linux/common/libsgx-tdx-logic/installConfig /installConfig 0 main STP +/installer/linux/common/libsgx-tdx-logic/Makefile /Makefile 0 main STP diff --git a/QuoteGeneration/installer/linux/common/libsgx-tdx-logic/BOMs/libsgx-tdx-logic.txt b/QuoteGeneration/installer/linux/common/libsgx-tdx-logic/BOMs/libsgx-tdx-logic.txt new file mode 100644 index 00000000..7c17637b --- /dev/null +++ b/QuoteGeneration/installer/linux/common/libsgx-tdx-logic/BOMs/libsgx-tdx-logic.txt @@ -0,0 +1,3 @@ +DeliveryName InstallName FileCheckSum FileFeature FileOwner +/build/linux/libsgx_tdx_logic.so /lib/libsgx_tdx_logic.so 0 main STP + diff --git a/QuoteGeneration/installer/linux/common/libsgx-tdx-logic/Makefile b/QuoteGeneration/installer/linux/common/libsgx-tdx-logic/Makefile new file mode 100644 index 00000000..e703b11c --- /dev/null +++ b/QuoteGeneration/installer/linux/common/libsgx-tdx-logic/Makefile @@ -0,0 +1,59 @@ +# +# Copyright (C) 2011-2021 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 installConfig + +PACKAGE_ROOT_FOLDER=pkgroot +PACKAGES=$(notdir $(wildcard $(PACKAGE_ROOT_FOLDER)/*)) + +USR_LIB_PATH=/usr/$(notdir $(shell gcc -print-multi-os-directory))/$(shell dpkg-architecture -qDEB_HOST_MULTIARCH 2> /dev/null) +USR_INC_PATH=/usr/$(INC_DIR) +USR_LIB_VER=1.0.0 +SPLIT_VERSION=$(word $2,$(subst ., ,$1)) + +default: + +install: $(PACKAGES) + + +$(PACKAGES): + install -d $(shell readlink -m $(DESTDIR)/$@) + $(if $(wildcard $(PACKAGE_ROOT_FOLDER)/$@/$(LIB_DIR)/*.so), \ + install -d $(shell readlink -m $(DESTDIR)/$@/$(USR_LIB_PATH)) && \ + mv $(PACKAGE_ROOT_FOLDER)/$@/$(LIB_DIR)/*.so $(DESTDIR)/$@/$(USR_LIB_PATH) && \ + cd $(DESTDIR)/$@/$(USR_LIB_PATH) && \ + mv libsgx_tdx_logic.so libsgx_tdx_logic.so.$(USR_LIB_VER) && \ + ln -fs libsgx_tdx_logic.so.$(USR_LIB_VER) libsgx_tdx_logic.so.$(call SPLIT_VERSION,$(USR_LIB_VER),1) && \ + ln -fs libsgx_tdx_logic.so.$(call SPLIT_VERSION,$(USR_LIB_VER),1) libsgx_tdx_logic.so) + $(if $(wildcard $(PACKAGE_ROOT_FOLDER)/$@/$(INC_DIR)/.*), \ + install -d $(shell readlink -m $(DESTDIR)/$@/$(USR_INC_PATH)) && \ + install -d $(shell readlink -m $(DESTDIR)/$@/$(USR_LIB_PATH)) && \ + mv $(PACKAGE_ROOT_FOLDER)/$@/$(INC_DIR)/* $(DESTDIR)/$@/$(USR_INC_PATH)) diff --git a/QuoteGeneration/installer/linux/common/libsgx-tdx-logic/createTarball.sh b/QuoteGeneration/installer/linux/common/libsgx-tdx-logic/createTarball.sh new file mode 100755 index 00000000..80dff971 --- /dev/null +++ b/QuoteGeneration/installer/linux/common/libsgx-tdx-logic/createTarball.sh @@ -0,0 +1,63 @@ +#!/usr/bin/env bash +# +# Copyright (C) 2011-2021 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}/installer/linux" +LINUX_INSTALLER_COMMON_DIR="${LINUX_INSTALLER_DIR}/common" + +INSTALL_PATH=${SCRIPT_DIR}/output + +# Cleanup +rm -fr ${INSTALL_PATH} + +# Get the configuration for this package +source ${SCRIPT_DIR}/installConfig + +# 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/libsgx-tdx-logic.txt --installdir=pkgroot/libsgx-tdx-logic +python ${SCRIPT_DIR}/gen_source.py --bom=BOMs/libsgx-tdx-logic-dev.txt --cleanup=false --installdir=pkgroot/libsgx-tdx-logic-dev +python ${SCRIPT_DIR}/gen_source.py --bom=BOMs/libsgx-tdx-logic-package.txt --cleanup=false +python ${SCRIPT_DIR}/gen_source.py --bom=../licenses/BOM_license.txt --cleanup=false + +# Create the tarball +SGX_VERSION=$(awk '/TDQE_WRAPPER_VERSION/ {print $3}' ${ROOT_DIR}/common/inc/internal/se_version.h|sed 's/^\"\(.*\)\"$/\1/') +pushd ${INSTALL_PATH} &> /dev/null +sed -i "s/USR_LIB_VER=.*/USR_LIB_VER=${SGX_VERSION}/" Makefile +tar -zcvf ${TARBALL_NAME} * +popd &> /dev/null diff --git a/QuoteGeneration/installer/linux/common/libsgx-tdx-logic/installConfig b/QuoteGeneration/installer/linux/common/libsgx-tdx-logic/installConfig new file mode 100644 index 00000000..60cbfaa6 --- /dev/null +++ b/QuoteGeneration/installer/linux/common/libsgx-tdx-logic/installConfig @@ -0,0 +1,7 @@ +TDX_LOGIC_VERSION="1.0" +TARBALL_NAME=libsgx-tdx-logic_1.0.orig.tar.gz + +TDX_LOGIC_PACKAGE_NAME=libsgx-tdx-logic +TDX_LOGIC_DEV_PACKAGE_NAME=libsgx-tdx-logic-dev +LIB_DIR=lib +INC_DIR=include diff --git a/QuoteGeneration/installer/linux/common/libtdx-attest/BOMs/libtdx-attest-dev.txt b/QuoteGeneration/installer/linux/common/libtdx-attest/BOMs/libtdx-attest-dev.txt new file mode 100644 index 00000000..c0d1ce2b --- /dev/null +++ b/QuoteGeneration/installer/linux/common/libtdx-attest/BOMs/libtdx-attest-dev.txt @@ -0,0 +1,4 @@ +DeliveryName InstallName FileCheckSum FileFeature FileOwner +/quote_wrapper/tdx_attest/tdx_attest.h /include/tdx_attest.h 0 main STP +/quote_wrapper/tdx_attest/test_tdx_attest.c /sample/test_tdx_attest.c 0 main STP +/quote_wrapper/tdx_attest/Makefile.sample /sample/Makefile 0 main STP diff --git a/QuoteGeneration/installer/linux/common/libtdx-attest/BOMs/libtdx-attest-package.txt b/QuoteGeneration/installer/linux/common/libtdx-attest/BOMs/libtdx-attest-package.txt new file mode 100644 index 00000000..835062bd --- /dev/null +++ b/QuoteGeneration/installer/linux/common/libtdx-attest/BOMs/libtdx-attest-package.txt @@ -0,0 +1,3 @@ +DeliveryName InstallName FileCheckSum FileFeature FileOwner +/installer/linux/common/libtdx-attest/installConfig /installConfig 0 main STP +/installer/linux/common/libtdx-attest/Makefile /Makefile 0 main STP diff --git a/QuoteGeneration/installer/linux/common/libtdx-attest/BOMs/libtdx-attest.txt b/QuoteGeneration/installer/linux/common/libtdx-attest/BOMs/libtdx-attest.txt new file mode 100644 index 00000000..474bad91 --- /dev/null +++ b/QuoteGeneration/installer/linux/common/libtdx-attest/BOMs/libtdx-attest.txt @@ -0,0 +1,2 @@ +DeliveryName InstallName FileCheckSum FileFeature FileOwner +/build/linux/libtdx_attest.so /lib/libtdx_attest.so 0 main STP diff --git a/QuoteGeneration/installer/linux/common/libtdx-attest/Makefile b/QuoteGeneration/installer/linux/common/libtdx-attest/Makefile new file mode 100644 index 00000000..aa7768b3 --- /dev/null +++ b/QuoteGeneration/installer/linux/common/libtdx-attest/Makefile @@ -0,0 +1,62 @@ +# +# Copyright (C) 2011-2021 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 installConfig + +PACKAGE_ROOT_FOLDER=pkgroot +PACKAGES=$(notdir $(wildcard $(PACKAGE_ROOT_FOLDER)/*)) + +USR_LIB_PATH=/usr/$(notdir $(shell gcc -print-multi-os-directory))/$(shell dpkg-architecture -qDEB_HOST_MULTIARCH 2> /dev/null) +USR_INC_PATH=/usr/$(INC_DIR) +OPT_SAMPLE_PATH=/opt/intel/tdx-quote-generation-sample + +USR_LIB_VER=1.0.0 +SPLIT_VERSION=$(word $2,$(subst ., ,$1)) + +default: + +install: $(PACKAGES) + cd $(shell readlink -m $(DESTDIR)/$(TDX_ATTEST_PACKAGE_NAME)/$(USR_LIB_PATH)) && \ + mv libtdx_attest.so libtdx_attest.so.$(USR_LIB_VER) && \ + ln -fs libtdx_attest.so.$(USR_LIB_VER) libtdx_attest.so.$(call SPLIT_VERSION,$(USR_LIB_VER),1) + +$(PACKAGES): + install -d $(shell readlink -m $(DESTDIR)/$@) + $(if $(wildcard $(PACKAGE_ROOT_FOLDER)/$@/$(LIB_DIR)/*.so), \ + install -d $(shell readlink -m $(DESTDIR)/$@/$(USR_LIB_PATH)) && \ + mv $(PACKAGE_ROOT_FOLDER)/$@/$(LIB_DIR)/*.so $(DESTDIR)/$@/$(USR_LIB_PATH)) + $(if $(wildcard $(PACKAGE_ROOT_FOLDER)/$@/$(INC_DIR)/.*), \ + install -d $(shell readlink -m $(DESTDIR)/$@/$(USR_INC_PATH)) && \ + install -d $(shell readlink -m $(DESTDIR)/$@/$(USR_LIB_PATH)) && \ + mv $(PACKAGE_ROOT_FOLDER)/$@/$(INC_DIR)/* $(DESTDIR)/$@/$(USR_INC_PATH)) + $(if $(wildcard $(PACKAGE_ROOT_FOLDER)/$@/$(SAMPLE_DIR)/.*), \ + install -d $(shell readlink -m $(DESTDIR)/$@/$(OPT_SAMPLE_PATH)) && \ + mv $(PACKAGE_ROOT_FOLDER)/$@/$(SAMPLE_DIR)/* $(DESTDIR)/$@/$(OPT_SAMPLE_PATH)) diff --git a/QuoteGeneration/installer/linux/common/libtdx-attest/createTarball.sh b/QuoteGeneration/installer/linux/common/libtdx-attest/createTarball.sh new file mode 100755 index 00000000..4e530858 --- /dev/null +++ b/QuoteGeneration/installer/linux/common/libtdx-attest/createTarball.sh @@ -0,0 +1,65 @@ +#!/usr/bin/env bash +# +# Copyright (C) 2011-2021 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}/installer/linux" +LINUX_INSTALLER_COMMON_DIR="${LINUX_INSTALLER_DIR}/common" + +INSTALL_PATH=${SCRIPT_DIR}/output + +[[ -z "${SGX_SDK}" ]] && SGX_SDK=/opt/intel/sgxsdk + +# Cleanup +rm -fr ${INSTALL_PATH} + +# Get the configuration for this package +source ${SCRIPT_DIR}/installConfig + +# 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/libtdx-attest.txt --installdir=pkgroot/libtdx-attest +python ${SCRIPT_DIR}/gen_source.py --bom=BOMs/libtdx-attest-dev.txt --cleanup=false --installdir=pkgroot/libtdx-attest-dev +python ${SCRIPT_DIR}/gen_source.py --bom=BOMs/libtdx-attest-package.txt --cleanup=false +python ${SCRIPT_DIR}/gen_source.py --bom=../licenses/BOM_license.txt --cleanup=false + +# Create the tarball +SGX_VERSION=$(awk '/STRFILEVER/ {print $3}' ${ROOT_DIR}/common/inc/internal/se_version.h|sed 's/^\"\(.*\)\"$/\1/') +pushd ${INSTALL_PATH} &> /dev/null +sed -i "s/USR_LIB_VER=.*/USR_LIB_VER=${SGX_VERSION}/" Makefile +tar -zcvf ${TARBALL_NAME} * +popd &> /dev/null diff --git a/QuoteGeneration/installer/linux/common/libtdx-attest/installConfig b/QuoteGeneration/installer/linux/common/libtdx-attest/installConfig new file mode 100644 index 00000000..c0e45aa7 --- /dev/null +++ b/QuoteGeneration/installer/linux/common/libtdx-attest/installConfig @@ -0,0 +1,9 @@ +TDX_ATTEST_VERSION="1.0" +TARBALL_NAME=libtdx-attest_1.0.orig.tar.gz + +TDX_ATTEST_PACKAGE_NAME=libtdx-attest +TDX_ATTEST_DEV_PACKAGE_NAME=libtdx-attest-dev + +LIB_DIR=lib +INC_DIR=include +SAMPLE_DIR=sample diff --git a/QuoteGeneration/installer/linux/common/sgx-dcap-pccs/BOMs/sgx-dcap-pccs.txt b/QuoteGeneration/installer/linux/common/sgx-dcap-pccs/BOMs/sgx-dcap-pccs.txt index c5c70fe8..5d7820f9 100644 --- a/QuoteGeneration/installer/linux/common/sgx-dcap-pccs/BOMs/sgx-dcap-pccs.txt +++ b/QuoteGeneration/installer/linux/common/sgx-dcap-pccs/BOMs/sgx-dcap-pccs.txt @@ -43,6 +43,7 @@ DeliveryName InstallName FileCheckSum FileFeature FileOwner /pccs/migrations/00_db_initialize.up.sql /migrations/00_db_initialize.up.sql 0 main STP /pccs/migrations/01_db_version_1.js /migrations/01_db_version_1.js 0 main STP /pccs/migrations/02_db_version_2.js /migrations/02_db_version_2.js 0 main STP +/pccs/migrations/03_db_version_3.js /migrations/03_db_version_3.js 0 main STP /pccs/pcs_client/pcs_client.js /pcs_client/pcs_client.js 0 main STP /pccs/routes/index.js /routes/index.js 0 main STP /pccs/services/identityService.js /services/identityService.js 0 main STP @@ -69,4 +70,6 @@ DeliveryName InstallName FileCheckSum FileFeature FileOwner /pccs/package.json /package.json 0 main STP /pccs/pccs_server.js /pccs_server.js 0 main STP /pccs/pccs.service /pccs.service 0 main STP +/pccs/startup.sh /startup.sh 0 main STP +/pccs/cleanup.sh /cleanup.sh 0 main STP /pccs/README.md /README.md 0 main STP diff --git a/QuoteGeneration/installer/linux/common/sgx-dcap-pccs/Makefile b/QuoteGeneration/installer/linux/common/sgx-dcap-pccs/Makefile index 97c16dec..06f81f50 100644 --- a/QuoteGeneration/installer/linux/common/sgx-dcap-pccs/Makefile +++ b/QuoteGeneration/installer/linux/common/sgx-dcap-pccs/Makefile @@ -34,9 +34,24 @@ include installConfig PACKAGE_ROOT_FOLDER=pkgroot PACKAGES=$(notdir $(wildcard $(PACKAGE_ROOT_FOLDER)/*)) +PCCS_CONF=pccs.service +PCCS_CONF_PATH=$(if $(wildcard /run/systemd/system/.),$(if $(wildcard /lib/systemd/system/.),/lib/systemd/system,/usr/lib/systemd/system),$(if $(wildcard /etc/init/.),/etc/init/)) + +ifeq ($(PCCS_CONF_PATH),) +ifneq ($(shell awk -F/ '$$2 == "docker"' /proc/self/cgroup),) +PCCS_CONF_PATH=/lib/systemd/system +$(warning "You may need to start service manually after it's installed!") +else +(error "Unsupported platform - neither systemctl nor initctl is found!") +endif +endif + default: install: $(PACKAGES) + install -d $(shell readlink -m $(DESTDIR)/$(PCCS_CONF_PATH)) && \ + mv $(DESTDIR)/$(DCAP_PCCS_PACKAGE_PATH)/$(DCAP_PCCS_PACKAGE_NAME)/$(PCCS_CONF) $(DESTDIR)/$(PCCS_CONF_PATH) + $(PACKAGES): install -d $(shell readlink -m $(DESTDIR)/$(DCAP_PCCS_PACKAGE_PATH)/$(DCAP_PCCS_PACKAGE_NAME)) diff --git a/QuoteGeneration/installer/linux/common/tdx-qgs/BOMs/tdx-qgs-package.txt b/QuoteGeneration/installer/linux/common/tdx-qgs/BOMs/tdx-qgs-package.txt new file mode 100644 index 00000000..bf52fb38 --- /dev/null +++ b/QuoteGeneration/installer/linux/common/tdx-qgs/BOMs/tdx-qgs-package.txt @@ -0,0 +1,3 @@ +DeliveryName InstallName FileCheckSum FileFeature FileOwner +/installer/linux/common/tdx-qgs/installConfig /installConfig 0 main STP +/installer/linux/common/tdx-qgs/Makefile /Makefile 0 main STP diff --git a/QuoteGeneration/installer/linux/common/tdx-qgs/BOMs/tdx-qgs.txt b/QuoteGeneration/installer/linux/common/tdx-qgs/BOMs/tdx-qgs.txt new file mode 100644 index 00000000..51054d85 --- /dev/null +++ b/QuoteGeneration/installer/linux/common/tdx-qgs/BOMs/tdx-qgs.txt @@ -0,0 +1,8 @@ +DeliveryName InstallName FileCheckSum FileFeature FileOwner +/quote_wrapper/qgs/qgsd.service /qgsd.service 0 main STP +/quote_wrapper/qgs/qgsd.conf /qgsd.conf 0 main STP +/quote_wrapper/qgs/qgs.conf /conf/qgs.conf 0 main STP +/quote_wrapper/qgs/qgs /qgs 0 main STP +/installer/linux/common/tdx-qgs/startup.sh /startup.sh 0 main STP +/installer/linux/common/tdx-qgs/cleanup.sh /cleanup.sh 0 main STP +/installer/linux/common/tdx-qgs/linksgx.sh /linksgx.sh 0 main STP diff --git a/QuoteGeneration/installer/linux/common/tdx-qgs/Makefile b/QuoteGeneration/installer/linux/common/tdx-qgs/Makefile new file mode 100644 index 00000000..fcf4b7f7 --- /dev/null +++ b/QuoteGeneration/installer/linux/common/tdx-qgs/Makefile @@ -0,0 +1,73 @@ +# +# Copyright (C) 2011-2021 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 installConfig + +PACKAGE_ROOT_FOLDER=pkgroot +PACKAGES=$(notdir $(wildcard $(PACKAGE_ROOT_FOLDER)/*)) + +QGSD_CONF_NAME=$(if $(wildcard /run/systemd/system/.*),qgsd.service,$(if $(wildcard /etc/init/.*),qgsd.conf,)) +QGSD_CONF_DEL=$(if $(wildcard /run/systemd/system/.*),qgsd.conf,$(if $(wildcard /etc/init/.*),qgsd.service,)) +QGSD_CONF_PATH=$(if $(wildcard /run/systemd/system/.*),$(if $(wildcard /lib/systemd/system/.*),/lib/systemd/system,/usr/lib/systemd/system),$(if $(wildcard /etc/init/.*),/etc/init/)) + +ifeq ($(QGSD_CONF_NAME),) +ifneq ($(shell awk -F/ '$$2 == "docker"' /proc/self/cgroup),) +QGSD_CONF_NAME=qgsd.service +QGSD_CONF_DEL=qgsd.conf +QGSD_CONF_PATH=/lib/systemd/system +$(warning "You may need to start qgsd manually after it's installed!") +else +$(error "Unsupported platform - neither systemctl nor initctl is found!") +endif +endif + +default: + +install: $(PACKAGES) + install -d $(shell readlink -m $(DESTDIR)/$(QGSD_CONF_PATH)) + sed -e "s:@qgs_folder@:$(TDX_QGS_PACKAGE_PATH)/$(TDX_QGS_PACKAGE_NAME):" \ + $(DESTDIR)/$(TDX_QGS_PACKAGE_PATH)/$(TDX_QGS_PACKAGE_NAME)/$(QGSD_CONF_NAME) \ + > $(DESTDIR)/$(QGSD_CONF_PATH)/$(QGSD_CONF_NAME) + rm -f $(DESTDIR)/$(TDX_QGS_PACKAGE_PATH)/$(TDX_QGS_PACKAGE_NAME)/$(QGSD_CONF_NAME) + rm -f $(DESTDIR)/$(TDX_QGS_PACKAGE_PATH)/$(TDX_QGS_PACKAGE_NAME)/$(QGSD_CONF_DEL) + $(if $(shell grep '^ID=clear-linux-os' /usr/lib/os-release 2> /dev/null), \ + $(if $(wildcard $(DESTDIR)/$(TDX_QGS_PACKAGE_PATH)/$(TDX_QGS_PACKAGE_NAME)/conf/qgsd.conf), \ + mv $(DESTDIR)/$(TDX_QGS_PACKAGE_PATH)/$(TDX_QGS_PACKAGE_NAME)/conf/qgsd.conf \ + $(DESTDIR)/$(TDX_QGS_PACKAGE_PATH)/$(TDX_QGS_PACKAGE_NAME)/conf/qgsd.conf.sample), \ + $(if $(wildcard $(DESTDIR)/$(TDX_QGS_PACKAGE_PATH)/$(TDX_QGS_PACKAGE_NAME)/conf/.*), \ + install -d $(shell readlink -m $(DESTDIR)/$(ETC_DIR)) && \ + cp -fr $(DESTDIR)/$(TDX_QGS_PACKAGE_PATH)/$(TDX_QGS_PACKAGE_NAME)/conf/* \ + $(DESTDIR)/$(ETC_DIR) && \ + rm -fr $(DESTDIR)/$(TDX_QGS_PACKAGE_PATH)/$(TDX_QGS_PACKAGE_NAME)/conf)) + +$(PACKAGES): + install -d $(shell readlink -m $(DESTDIR)/$(TDX_QGS_PACKAGE_PATH)/$(TDX_QGS_PACKAGE_NAME)) + cp -r $(PACKAGE_ROOT_FOLDER)/$@/* $(DESTDIR)/$(TDX_QGS_PACKAGE_PATH)/$(TDX_QGS_PACKAGE_NAME) diff --git a/QuoteGeneration/installer/linux/common/tdx-qgs/cleanup.sh b/QuoteGeneration/installer/linux/common/tdx-qgs/cleanup.sh new file mode 100755 index 00000000..e0cf354b --- /dev/null +++ b/QuoteGeneration/installer/linux/common/tdx-qgs/cleanup.sh @@ -0,0 +1,55 @@ +#!/usr/bin/env bash +# +# Copyright (C) 2011-2021 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 + +if test $(id -u) -ne 0; then + echo "Root privilege is required." + exit 1 +fi + +# Kill qgsd service +if [ -d /run/systemd/system ]; then + systemctl daemon-reload + systemctl stop qgsd + systemctl disable qgsd 2> /dev/null +elif [ -d /etc/init/ ]; then + /sbin/initctl reload-configuration + /sbin/initctl stop qgsd +fi + +# Remove qgsd user and group +/usr/sbin/userdel qgsd 2> /dev/null || true +/usr/sbin/groupdel qgsd 2> /dev/null || true + +exit 0 diff --git a/QuoteGeneration/installer/linux/common/tdx-qgs/createTarball.sh b/QuoteGeneration/installer/linux/common/tdx-qgs/createTarball.sh new file mode 100755 index 00000000..6797401f --- /dev/null +++ b/QuoteGeneration/installer/linux/common/tdx-qgs/createTarball.sh @@ -0,0 +1,59 @@ +#!/usr/bin/env bash +# +# Copyright (C) 2011-2021 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}/installer/linux" +LINUX_INSTALLER_COMMON_DIR="${LINUX_INSTALLER_DIR}/common" + +INSTALL_PATH=${SCRIPT_DIR}/output + +# Cleanup +rm -fr ${INSTALL_PATH} + +# Get the configuration for this package +source ${SCRIPT_DIR}/installConfig + +# 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/tdx-qgs.txt --cleanup=false --installdir=pkgroot/tdx-qgs +python ${SCRIPT_DIR}/gen_source.py --bom=BOMs/tdx-qgs-package.txt --cleanup=false + +# Create the tarball +pushd ${INSTALL_PATH} &> /dev/null +tar -zcvf ${TARBALL_NAME} * +popd &> /dev/null diff --git a/QuoteGeneration/installer/linux/common/tdx-qgs/installConfig b/QuoteGeneration/installer/linux/common/tdx-qgs/installConfig new file mode 100644 index 00000000..811166c9 --- /dev/null +++ b/QuoteGeneration/installer/linux/common/tdx-qgs/installConfig @@ -0,0 +1,7 @@ +TDX_QGS_VERSION="1.0" +TARBALL_NAME=tdx-qgs_1.0.orig.tar.gz + +TDX_QGS_PACKAGE_PATH=/opt/intel +TDX_QGS_PACKAGE_NAME=tdx-qgs + +ETC_DIR=etc diff --git a/QuoteGeneration/installer/linux/common/tdx-qgs/linksgx.sh b/QuoteGeneration/installer/linux/common/tdx-qgs/linksgx.sh new file mode 100755 index 00000000..2d9bdb69 --- /dev/null +++ b/QuoteGeneration/installer/linux/common/tdx-qgs/linksgx.sh @@ -0,0 +1,63 @@ +#!/usr/bin/env bash +# +# Copyright (C) 2011-2021 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. +# +# + +if test $(id -u) -ne 0; then + echo "Root privilege is required." + exit 1 +fi + +if [ -c /dev/sgx_provision -o -c /dev/sgx/provision ]; then + getent group sgx_prv &> /dev/null + if [ "$?" != "0" ]; then + # Add sgx_prv for dcap driver, which ensures that no matter what + # the order of package installation, aesmd can have access to + # the sgx_provision device file. + groupadd sgx_prv + + if ! which udevadm &> /dev/null; then + exit 0 + fi + udevadm control --reload || : + udevadm trigger || : + fi + usermod -aG sgx_prv qgsd &> /dev/null + + # For systemd which supports https://github.com/systemd/systemd/pull/18944/files + if [ "sgx" = "$(stat -c '%G' /dev/sgx_enclave 2>/dev/null)" ]; then + usermod -aG sgx qgsd &> /dev/null + fi +fi + +/usr/sbin/modprobe vhost-vsock &> /dev/null +/usr/sbin/modprobe vsock_loopback &> /dev/null + +echo diff --git a/QuoteGeneration/installer/linux/common/tdx-qgs/startup.sh b/QuoteGeneration/installer/linux/common/tdx-qgs/startup.sh new file mode 100755 index 00000000..230c666d --- /dev/null +++ b/QuoteGeneration/installer/linux/common/tdx-qgs/startup.sh @@ -0,0 +1,57 @@ +#!/usr/bin/env bash +# +# Copyright (C) 2011-2021 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 + +if test $(id -u) -ne 0; then + echo "Root privilege is required." + exit 1 +fi + + +# Create user and group if not exist +id -u qgsd &> /dev/null || \ + /usr/sbin/useradd -r -U -c "User for qgsd" \ + -d /var/opt/qgsd -s /sbin/nologin qgsd + + +# Start the AESMD service +if [ -d /run/systemd/system ]; then + systemctl enable qgsd + systemctl start qgsd +elif [ -d /etc/init/ ]; then + /sbin/initctl reload-configuration + /sbin/initctl start qgsd +fi + +exit 0 diff --git a/QuoteGeneration/installer/linux/deb/libsgx-ae-tdqe/build.sh b/QuoteGeneration/installer/linux/deb/libsgx-ae-tdqe/build.sh new file mode 100755 index 00000000..6e62d93d --- /dev/null +++ b/QuoteGeneration/installer/linux/deb/libsgx-ae-tdqe/build.sh @@ -0,0 +1,116 @@ +#!/usr/bin/env bash +# +# Copyright (C) 2011-2021 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}/installer/linux" +LINUX_INSTALLER_COMMON_DIR="${LINUX_INSTALLER_DIR}/common" +LINUX_INSTALLER_COMMON_AE_TDX_DIR="${LINUX_INSTALLER_COMMON_DIR}/libsgx-ae-tdqe" +source ${LINUX_INSTALLER_COMMON_AE_TDX_DIR}/installConfig +DEB_FOLDER=${AE_TDX_PACKAGE_NAME}-${AE_TDX_VERSION} + +SGX_VERSION=$(awk '/STRFILEVER/ {print $3}' ${ROOT_DIR}/common/inc/internal/se_version.h|sed 's/^\"\(.*\)\"$/\1/') +DEB_BUILD_FOLDER=${AE_TDX_PACKAGE_NAME}-${SGX_VERSION} + +main() { + pre_build + create_upstream_tarball + unpack_upstream_tarball + generate_copyright + update_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() { + rm -fR ${SCRIPT_DIR}/${DEB_BUILD_FOLDER} +} + +create_upstream_tarball() { + ${LINUX_INSTALLER_COMMON_AE_TDX_DIR}/createTarball.sh + cp ${LINUX_INSTALLER_COMMON_AE_TDX_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() { + pushd ${SCRIPT_DIR}/${DEB_BUILD_FOLDER} + rm -f debian/copyright + find package/licenses/ -type f -print0 | xargs -0 -n1 cat >> debian/copyright + popd +} + +get_os_code() { + OS_CODE=$(lsb_release -cs 2> /dev/null) + if [ -z ${OS_CODE} ]; then + OS_CODE=$(grep "VERSION_CODENAME" /etc/os-release 2> /dev/null | cut -d= -f2) + fi + echo ${OS_CODE} +} + +update_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) + + FULL_VERSION=${SGX_VERSION}-$(get_os_code)${DEB_VERSION} + sed -i "s/${INS_VERSION}/${FULL_VERSION}/" debian/changelog + popd +} + +rename_tarball() { + TARBALL_NAME_NEW_VERSION=$(echo ${TARBALL_NAME} | sed "s/${AE_TDX_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/QuoteGeneration/installer/linux/deb/libsgx-ae-tdqe/clean.sh b/QuoteGeneration/installer/linux/deb/libsgx-ae-tdqe/clean.sh new file mode 100755 index 00000000..d9232837 --- /dev/null +++ b/QuoteGeneration/installer/linux/deb/libsgx-ae-tdqe/clean.sh @@ -0,0 +1,47 @@ +#!/usr/bin/env bash +# +# Copyright (C) 2011-2021 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") +COMMON_DIR="${SCRIPT_DIR}/../../common/libsgx-ae-tdqe" + +rm -f ${SCRIPT_DIR}/libsgx-ae-tdqe*.deb +rm -f ${SCRIPT_DIR}/libsgx-ae-tdqe*.ddeb +rm -f ${SCRIPT_DIR}/libsgx-ae-tdqe*.tar.gz +rm -f ${SCRIPT_DIR}/libsgx-ae-tdqe*.tar.xz +rm -f ${SCRIPT_DIR}/libsgx-ae-tdqe*.dsc +rm -f ${SCRIPT_DIR}/libsgx-ae-tdqe*.changes +rm -f ${SCRIPT_DIR}/libsgx-ae-tdqe*.buildinfo +rm -f ${COMMON_DIR}/gen_source.py +rm -rf ${COMMON_DIR}/output diff --git a/QuoteGeneration/installer/linux/deb/libsgx-ae-tdqe/libsgx-ae-tdqe-1.0/debian/changelog b/QuoteGeneration/installer/linux/deb/libsgx-ae-tdqe/libsgx-ae-tdqe-1.0/debian/changelog new file mode 100644 index 00000000..8c74db78 --- /dev/null +++ b/QuoteGeneration/installer/linux/deb/libsgx-ae-tdqe/libsgx-ae-tdqe-1.0/debian/changelog @@ -0,0 +1,5 @@ +libsgx-ae-tdqe (1.0-1) unstable; urgency=low + + * 0.1 pre-alpha release + + -- Qiu Feng Mon, 27 Jul 2020 10:54:41 +0800 diff --git a/QuoteGeneration/installer/linux/deb/libsgx-ae-tdqe/libsgx-ae-tdqe-1.0/debian/compat b/QuoteGeneration/installer/linux/deb/libsgx-ae-tdqe/libsgx-ae-tdqe-1.0/debian/compat new file mode 100644 index 00000000..ec635144 --- /dev/null +++ b/QuoteGeneration/installer/linux/deb/libsgx-ae-tdqe/libsgx-ae-tdqe-1.0/debian/compat @@ -0,0 +1 @@ +9 diff --git a/QuoteGeneration/installer/linux/deb/libsgx-ae-tdqe/libsgx-ae-tdqe-1.0/debian/control b/QuoteGeneration/installer/linux/deb/libsgx-ae-tdqe/libsgx-ae-tdqe-1.0/debian/control new file mode 100644 index 00000000..89010583 --- /dev/null +++ b/QuoteGeneration/installer/linux/deb/libsgx-ae-tdqe/libsgx-ae-tdqe-1.0/debian/control @@ -0,0 +1,11 @@ +Source: libsgx-ae-tdqe +Section: libs +Priority: optional +Maintainer: +Build-Depends: debhelper (>= 8.0.0) +Standards-Version: 3.9.4 +Homepage: https://github.com/intel/SGXDataCenterAttestationPrimitives + +Package: libsgx-ae-tdqe +Architecture: amd64 +Description: Intel(R) Trust Domain Extensions QE diff --git a/QuoteGeneration/installer/linux/deb/libsgx-ae-tdqe/libsgx-ae-tdqe-1.0/debian/docs b/QuoteGeneration/installer/linux/deb/libsgx-ae-tdqe/libsgx-ae-tdqe-1.0/debian/docs new file mode 100644 index 00000000..e69de29b diff --git a/QuoteGeneration/installer/linux/deb/libsgx-ae-tdqe/libsgx-ae-tdqe-1.0/debian/rules b/QuoteGeneration/installer/linux/deb/libsgx-ae-tdqe/libsgx-ae-tdqe-1.0/debian/rules new file mode 100755 index 00000000..ecf4506c --- /dev/null +++ b/QuoteGeneration/installer/linux/deb/libsgx-ae-tdqe/libsgx-ae-tdqe-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/QuoteGeneration/installer/linux/deb/libsgx-ae-tdqe/libsgx-ae-tdqe-1.0/debian/source/format b/QuoteGeneration/installer/linux/deb/libsgx-ae-tdqe/libsgx-ae-tdqe-1.0/debian/source/format new file mode 100644 index 00000000..163aaf8d --- /dev/null +++ b/QuoteGeneration/installer/linux/deb/libsgx-ae-tdqe/libsgx-ae-tdqe-1.0/debian/source/format @@ -0,0 +1 @@ +3.0 (quilt) diff --git a/QuoteGeneration/installer/linux/deb/libsgx-dcap-ql/build.sh b/QuoteGeneration/installer/linux/deb/libsgx-dcap-ql/build.sh index eac8450e..851eae8d 100755 --- a/QuoteGeneration/installer/linux/deb/libsgx-dcap-ql/build.sh +++ b/QuoteGeneration/installer/linux/deb/libsgx-dcap-ql/build.sh @@ -35,6 +35,7 @@ set -e SCRIPT_DIR=$(dirname "$0") ROOT_DIR="${SCRIPT_DIR}/../../../../" +LINUX_BUILD_DIR=$(readlink -m "${ROOT_DIR}/build/linux") LINUX_INSTALLER_DIR="${ROOT_DIR}/installer/linux" LINUX_INSTALLER_COMMON_DIR="${LINUX_INSTALLER_DIR}/common" LINUX_INSTALLER_COMMON_DCAP_QL_DIR="${LINUX_INSTALLER_COMMON_DIR}/libsgx-dcap-ql" @@ -117,8 +118,7 @@ rename_tarball() { build_deb_package() { pushd ${SCRIPT_DIR}/${DEB_BUILD_FOLDER} - SOURCE_DATE_EPOCH="$(date +%s)" dpkg-buildpackage -us -uc + SOURCE_DATE_EPOCH="$(date +%s)" LINUX_BUILD_DIR="${LINUX_BUILD_DIR}" dpkg-buildpackage -us -uc popd } - main $@ diff --git a/QuoteGeneration/installer/linux/deb/libsgx-dcap-ql/libsgx-dcap-ql-1.0/debian/control b/QuoteGeneration/installer/linux/deb/libsgx-dcap-ql/libsgx-dcap-ql-1.0/debian/control index 9d05d971..91ae8f13 100644 --- a/QuoteGeneration/installer/linux/deb/libsgx-dcap-ql/libsgx-dcap-ql-1.0/debian/control +++ b/QuoteGeneration/installer/linux/deb/libsgx-dcap-ql/libsgx-dcap-ql-1.0/debian/control @@ -9,11 +9,11 @@ Homepage: https://github.com/intel/SGXDataCenterAttestationPrimitives Package: libsgx-dcap-ql Architecture: amd64 Depends: libsgx-qe3-logic(>= @dep_version@), libsgx-pce-logic(>= @dep_version@), ${shlibs:Depends}, ${misc:Depends} -Recommends: libsgx-dcap-quote-verify(>= @dep_version@), libsgx-quote-ex(>= 2.16) +Recommends: libsgx-dcap-quote-verify(>= @dep_version@), libsgx-quote-ex(>= 2.17) Description: Intel(R) Software Guard Extensions Data Center Attestation Primitives Package: libsgx-dcap-ql-dev Section: devel Architecture: amd64 -Depends: libsgx-dcap-ql (= @dep_version@), libsgx-headers (>= 2.16) +Depends: libsgx-dcap-ql (= @dep_version@), libsgx-headers (>= 2.17) Description: Intel(R) Software Guard Extensions Data Center Attestation Primitives For Developers diff --git a/QuoteGeneration/installer/linux/deb/libsgx-dcap-ql/libsgx-dcap-ql-1.0/debian/rules b/QuoteGeneration/installer/linux/deb/libsgx-dcap-ql/libsgx-dcap-ql-1.0/debian/rules index ecf4506c..208b0b31 100755 --- a/QuoteGeneration/installer/linux/deb/libsgx-dcap-ql/libsgx-dcap-ql-1.0/debian/rules +++ b/QuoteGeneration/installer/linux/deb/libsgx-dcap-ql/libsgx-dcap-ql-1.0/debian/rules @@ -6,3 +6,6 @@ export DH_VERBOSE=1 %: dh $@ + +override_dh_shlibdeps: + dh_shlibdeps -l $(LINUX_BUILD_DIR) --dpkg-shlibdeps-params=--ignore-missing-info diff --git a/QuoteGeneration/installer/linux/deb/libsgx-dcap-quote-verify/libsgx-dcap-quote-verify-1.0/debian/control b/QuoteGeneration/installer/linux/deb/libsgx-dcap-quote-verify/libsgx-dcap-quote-verify-1.0/debian/control index 43047847..d64ae373 100644 --- a/QuoteGeneration/installer/linux/deb/libsgx-dcap-quote-verify/libsgx-dcap-quote-verify-1.0/debian/control +++ b/QuoteGeneration/installer/linux/deb/libsgx-dcap-quote-verify/libsgx-dcap-quote-verify-1.0/debian/control @@ -15,5 +15,5 @@ Description: Intel(R) Software Guard Extensions Data Center Attestation Primitiv Package: libsgx-dcap-quote-verify-dev Section: devel Architecture: amd64 -Depends: libsgx-dcap-quote-verify (= @dep_version@), libsgx-headers (>= 2.16) +Depends: libsgx-dcap-quote-verify (= @dep_version@), libsgx-headers (>= 2.17) Description: Intel(R) Software Guard Extensions Data Center Attestation Primitives For Developers diff --git a/QuoteGeneration/installer/linux/deb/libsgx-pce-logic/libsgx-pce-logic-1.0/debian/control b/QuoteGeneration/installer/linux/deb/libsgx-pce-logic/libsgx-pce-logic-1.0/debian/control index 3984c0e2..be6a5ecd 100644 --- a/QuoteGeneration/installer/linux/deb/libsgx-pce-logic/libsgx-pce-logic-1.0/debian/control +++ b/QuoteGeneration/installer/linux/deb/libsgx-pce-logic/libsgx-pce-logic-1.0/debian/control @@ -8,5 +8,5 @@ Homepage: https://github.com/intel/SGXDataCenterAttestationPrimitives Package: libsgx-pce-logic Architecture: amd64 -Depends: libsgx-urts (>= 2.16), libsgx-ae-pce(>= 2.16), ${shlibs:Depends}, ${misc:Depends} +Depends: libsgx-urts (>= 2.17), libsgx-ae-pce(>= 2.17), ${shlibs:Depends}, ${misc:Depends} Description: Intel(R) Software Guard Extensions Data Center Attestation Primitives diff --git a/QuoteGeneration/installer/linux/deb/libsgx-qe3-logic/libsgx-qe3-logic-1.0/debian/control b/QuoteGeneration/installer/linux/deb/libsgx-qe3-logic/libsgx-qe3-logic-1.0/debian/control index 5ea7cadf..accd0c1f 100644 --- a/QuoteGeneration/installer/linux/deb/libsgx-qe3-logic/libsgx-qe3-logic-1.0/debian/control +++ b/QuoteGeneration/installer/linux/deb/libsgx-qe3-logic/libsgx-qe3-logic-1.0/debian/control @@ -8,5 +8,5 @@ Homepage: https://github.com/intel/SGXDataCenterAttestationPrimitives Package: libsgx-qe3-logic Architecture: amd64 -Depends: libsgx-urts (>= 2.16), libsgx-ae-qe3(>= @dep_version@), libsgx-ae-id-enclave(>= @dep_version@), ${shlibs:Depends}, ${misc:Depends} +Depends: libsgx-urts (>= 2.17), libsgx-ae-qe3(>= @dep_version@), libsgx-ae-id-enclave(>= @dep_version@), ${shlibs:Depends}, ${misc:Depends} Description: Intel(R) Software Guard Extensions Data Center Attestation Primitives diff --git a/QuoteGeneration/installer/linux/deb/libsgx-tdx-logic/build.sh b/QuoteGeneration/installer/linux/deb/libsgx-tdx-logic/build.sh new file mode 100755 index 00000000..c6ba7fd3 --- /dev/null +++ b/QuoteGeneration/installer/linux/deb/libsgx-tdx-logic/build.sh @@ -0,0 +1,125 @@ +#!/usr/bin/env bash +# +# Copyright (C) 2011-2021 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_BUILD_DIR=$(readlink -m "${ROOT_DIR}/build/linux") +LINUX_INSTALLER_DIR="${ROOT_DIR}/installer/linux" +LINUX_INSTALLER_COMMON_DIR="${LINUX_INSTALLER_DIR}/common" +LINUX_INSTALLER_COMMON_TDX_LOGIC_DIR="${LINUX_INSTALLER_COMMON_DIR}/libsgx-tdx-logic" + +source ${LINUX_INSTALLER_COMMON_TDX_LOGIC_DIR}/installConfig +DEB_FOLDER=${TDX_LOGIC_PACKAGE_NAME}-${TDX_LOGIC_VERSION} + +SGX_VERSION=$(awk '/STRFILEVER/ {print $3}' ${ROOT_DIR}/common/inc/internal/se_version.h|sed 's/^\"\(.*\)\"$/\1/') +DEB_BUILD_FOLDER=${TDX_LOGIC_PACKAGE_NAME}-${SGX_VERSION} + +main() { + pre_build + create_upstream_tarball + unpack_upstream_tarball + generate_install + generate_copyright + update_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() { + rm -fR ${SCRIPT_DIR}/${DEB_BUILD_FOLDER} +} + +create_upstream_tarball() { + ${LINUX_INSTALLER_COMMON_TDX_LOGIC_DIR}/createTarball.sh + cp ${LINUX_INSTALLER_COMMON_TDX_LOGIC_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_install() { + echo "debian/tmp/${TDX_LOGIC_PACKAGE_NAME}/* ." > ${SCRIPT_DIR}/${DEB_BUILD_FOLDER}/debian/${TDX_LOGIC_PACKAGE_NAME}.install + echo "debian/tmp/${TDX_LOGIC_DEV_PACKAGE_NAME}/* ." > ${SCRIPT_DIR}/${DEB_BUILD_FOLDER}/debian/${TDX_LOGIC_DEV_PACKAGE_NAME}.install +} + +generate_copyright() { + pushd ${SCRIPT_DIR}/${DEB_BUILD_FOLDER} + rm -f debian/copyright + find package/licenses/ -type f -print0 | xargs -0 -n1 cat >> debian/copyright + popd +} + +get_os_code() { + OS_CODE=$(lsb_release -cs 2> /dev/null) + if [ -z ${OS_CODE} ]; then + OS_CODE=$(grep "VERSION_CODENAME" /etc/os-release 2> /dev/null | cut -d= -f2) + fi + echo ${OS_CODE} +} + +update_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) + + FULL_VERSION=${SGX_VERSION}-$(get_os_code)${DEB_VERSION} + sed -i "s/${INS_VERSION}/${FULL_VERSION}/" debian/changelog + sed -i "s/@dep_version@/${FULL_VERSION}/g" debian/control + popd +} + +rename_tarball() { + TARBALL_NAME_NEW_VERSION=$(echo ${TARBALL_NAME} | sed "s/${TDX_LOGIC_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)" LINUX_BUILD_DIR="${LINUX_BUILD_DIR}" dpkg-buildpackage -us -uc + popd +} + +main $@ diff --git a/QuoteGeneration/installer/linux/deb/libsgx-tdx-logic/clean.sh b/QuoteGeneration/installer/linux/deb/libsgx-tdx-logic/clean.sh new file mode 100755 index 00000000..552c65c2 --- /dev/null +++ b/QuoteGeneration/installer/linux/deb/libsgx-tdx-logic/clean.sh @@ -0,0 +1,47 @@ +#!/usr/bin/env bash +# +# Copyright (C) 2011-2021 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") +COMMON_DIR="${SCRIPT_DIR}/../../common/libsgx-tdx-logic" + +rm -f ${SCRIPT_DIR}/libsgx-tdx-logic*.deb +rm -f ${SCRIPT_DIR}/libsgx-tdx-logic*.ddeb +rm -f ${SCRIPT_DIR}/libsgx-tdx-logic*.tar.gz +rm -f ${SCRIPT_DIR}/libsgx-tdx-logic*.tar.xz +rm -f ${SCRIPT_DIR}/libsgx-tdx-logic*.dsc +rm -f ${SCRIPT_DIR}/libsgx-tdx-logic*.changes +rm -f ${SCRIPT_DIR}/libsgx-tdx-logic*.buildinfo +rm -f ${COMMON_DIR}/gen_source.py +rm -rf ${COMMON_DIR}/output diff --git a/QuoteGeneration/installer/linux/deb/libsgx-tdx-logic/libsgx-tdx-logic-1.0/debian/changelog b/QuoteGeneration/installer/linux/deb/libsgx-tdx-logic/libsgx-tdx-logic-1.0/debian/changelog new file mode 100644 index 00000000..cd61389f --- /dev/null +++ b/QuoteGeneration/installer/linux/deb/libsgx-tdx-logic/libsgx-tdx-logic-1.0/debian/changelog @@ -0,0 +1,5 @@ +libsgx-tdx-logic (1.0-1) unstable; urgency=low + + * 0.1 pre-alpha release + + -- Qiu Feng Mon, 27 Jul 2020 10:54:41 +0800 diff --git a/QuoteGeneration/installer/linux/deb/libsgx-tdx-logic/libsgx-tdx-logic-1.0/debian/compat b/QuoteGeneration/installer/linux/deb/libsgx-tdx-logic/libsgx-tdx-logic-1.0/debian/compat new file mode 100644 index 00000000..ec635144 --- /dev/null +++ b/QuoteGeneration/installer/linux/deb/libsgx-tdx-logic/libsgx-tdx-logic-1.0/debian/compat @@ -0,0 +1 @@ +9 diff --git a/QuoteGeneration/installer/linux/deb/libsgx-tdx-logic/libsgx-tdx-logic-1.0/debian/control b/QuoteGeneration/installer/linux/deb/libsgx-tdx-logic/libsgx-tdx-logic-1.0/debian/control new file mode 100644 index 00000000..0b965bc6 --- /dev/null +++ b/QuoteGeneration/installer/linux/deb/libsgx-tdx-logic/libsgx-tdx-logic-1.0/debian/control @@ -0,0 +1,18 @@ +Source: libsgx-tdx-logic +Section: libs +Priority: optional +Maintainer: +Build-Depends: debhelper (>= 8.0.0) +Standards-Version: 3.9.4 +Homepage: https://github.com/intel/SGXDataCenterAttestationPrimitives + +Package: libsgx-tdx-logic +Architecture: amd64 +Depends: libsgx-urts (>= 2.17), libsgx-pce-logic(>= @dep_version@), libsgx-ae-tdqe(>= @dep_version@), libsgx-ae-id-enclave(>= @dep_version@), ${shlibs:Depends}, ${misc:Depends} +Description: Intel(R) Trust Domain Extensions QE logic library + +Package: libsgx-tdx-logic-dev +Section: devel +Architecture: amd64 +Depends: libsgx-tdx-logic (= @dep_version@) +Description: Intel(R) Trust Domain Extensions QE logic library For Developers diff --git a/QuoteGeneration/installer/linux/deb/libsgx-tdx-logic/libsgx-tdx-logic-1.0/debian/docs b/QuoteGeneration/installer/linux/deb/libsgx-tdx-logic/libsgx-tdx-logic-1.0/debian/docs new file mode 100644 index 00000000..e69de29b diff --git a/QuoteGeneration/installer/linux/deb/libsgx-tdx-logic/libsgx-tdx-logic-1.0/debian/rules b/QuoteGeneration/installer/linux/deb/libsgx-tdx-logic/libsgx-tdx-logic-1.0/debian/rules new file mode 100755 index 00000000..208b0b31 --- /dev/null +++ b/QuoteGeneration/installer/linux/deb/libsgx-tdx-logic/libsgx-tdx-logic-1.0/debian/rules @@ -0,0 +1,11 @@ +#!/usr/bin/make -f +# -*- makefile -*- + +# Uncomment this to turn on verbose mode. +export DH_VERBOSE=1 + +%: + dh $@ + +override_dh_shlibdeps: + dh_shlibdeps -l $(LINUX_BUILD_DIR) --dpkg-shlibdeps-params=--ignore-missing-info diff --git a/QuoteGeneration/installer/linux/deb/libsgx-tdx-logic/libsgx-tdx-logic-1.0/debian/source/format b/QuoteGeneration/installer/linux/deb/libsgx-tdx-logic/libsgx-tdx-logic-1.0/debian/source/format new file mode 100644 index 00000000..163aaf8d --- /dev/null +++ b/QuoteGeneration/installer/linux/deb/libsgx-tdx-logic/libsgx-tdx-logic-1.0/debian/source/format @@ -0,0 +1 @@ +3.0 (quilt) diff --git a/QuoteGeneration/installer/linux/deb/libtdx-attest/build.sh b/QuoteGeneration/installer/linux/deb/libtdx-attest/build.sh new file mode 100755 index 00000000..f1ba8f9f --- /dev/null +++ b/QuoteGeneration/installer/linux/deb/libtdx-attest/build.sh @@ -0,0 +1,124 @@ +#!/usr/bin/env bash +# +# Copyright (C) 2011-2021 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}/installer/linux" +LINUX_INSTALLER_COMMON_DIR="${LINUX_INSTALLER_DIR}/common" +LINUX_INSTALLER_COMMON_TDX_ATTEST_DIR="${LINUX_INSTALLER_COMMON_DIR}/libtdx-attest" + +source ${LINUX_INSTALLER_COMMON_TDX_ATTEST_DIR}/installConfig +DEB_FOLDER=${TDX_ATTEST_PACKAGE_NAME}-${TDX_ATTEST_VERSION} + +SGX_VERSION=$(awk '/STRFILEVER/ {print $3}' ${ROOT_DIR}/common/inc/internal/se_version.h|sed 's/^\"\(.*\)\"$/\1/') +DEB_BUILD_FOLDER=${TDX_ATTEST_PACKAGE_NAME}-${SGX_VERSION} + +main() { + pre_build + create_upstream_tarball + unpack_upstream_tarball + generate_install + generate_copyright + update_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() { + rm -fR ${SCRIPT_DIR}/${DEB_BUILD_FOLDER} +} + +create_upstream_tarball() { + ${LINUX_INSTALLER_COMMON_TDX_ATTEST_DIR}/createTarball.sh + cp ${LINUX_INSTALLER_COMMON_TDX_ATTEST_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_install() { + echo "debian/tmp/${TDX_ATTEST_PACKAGE_NAME}/* ." > ${SCRIPT_DIR}/${DEB_BUILD_FOLDER}/debian/${TDX_ATTEST_PACKAGE_NAME}.install + echo "debian/tmp/${TDX_ATTEST_DEV_PACKAGE_NAME}/* ." > ${SCRIPT_DIR}/${DEB_BUILD_FOLDER}/debian/${TDX_ATTEST_DEV_PACKAGE_NAME}.install +} + +generate_copyright() { + pushd ${SCRIPT_DIR}/${DEB_BUILD_FOLDER} + rm -f debian/copyright + find package/licenses/ -type f -print0 | xargs -0 -n1 cat >> debian/copyright + popd +} + +get_os_code() { + OS_CODE=$(lsb_release -cs 2> /dev/null) + if [ -z ${OS_CODE} ]; then + OS_CODE=$(grep "VERSION_CODENAME" /etc/os-release 2> /dev/null | cut -d= -f2) + fi + echo ${OS_CODE} +} + +update_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) + + FULL_VERSION=${SGX_VERSION}-$(get_os_code)${DEB_VERSION} + sed -i "s/${INS_VERSION}/${FULL_VERSION}/" debian/changelog + sed -i "s/@dep_version@/${FULL_VERSION}/g" debian/control + popd +} + +rename_tarball() { + TARBALL_NAME_NEW_VERSION=$(echo ${TARBALL_NAME} | sed "s/${TDX_ATTEST_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/QuoteGeneration/installer/linux/deb/libtdx-attest/clean.sh b/QuoteGeneration/installer/linux/deb/libtdx-attest/clean.sh new file mode 100755 index 00000000..63175f24 --- /dev/null +++ b/QuoteGeneration/installer/linux/deb/libtdx-attest/clean.sh @@ -0,0 +1,47 @@ +#!/usr/bin/env bash +# +# Copyright (C) 2011-2021 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") +COMMON_DIR="${SCRIPT_DIR}/../../common/libsgx-dcap-ql" + +rm -f ${SCRIPT_DIR}/libsgx-dcap-ql*.deb +rm -f ${SCRIPT_DIR}/libsgx-dcap-ql*.ddeb +rm -f ${SCRIPT_DIR}/libsgx-dcap-ql*.tar.gz +rm -f ${SCRIPT_DIR}/libsgx-dcap-ql*.tar.xz +rm -f ${SCRIPT_DIR}/libsgx-dcap-ql*.dsc +rm -f ${SCRIPT_DIR}/libsgx-dcap-ql*.changes +rm -f ${SCRIPT_DIR}/libsgx-dcap-ql*.buildinfo +rm -f ${COMMON_DIR}/gen_source.py +rm -rf ${COMMON_DIR}/output diff --git a/QuoteGeneration/installer/linux/deb/libtdx-attest/libtdx-attest-1.0/debian/changelog b/QuoteGeneration/installer/linux/deb/libtdx-attest/libtdx-attest-1.0/debian/changelog new file mode 100644 index 00000000..e3443d07 --- /dev/null +++ b/QuoteGeneration/installer/linux/deb/libtdx-attest/libtdx-attest-1.0/debian/changelog @@ -0,0 +1,5 @@ +libtdx-attest (1.0-1) unstable; urgency=low + + * Initial revision + + -- Feng Qiu Wed, 20 Jan 2021 15:19:41 +0800 diff --git a/QuoteGeneration/installer/linux/deb/libtdx-attest/libtdx-attest-1.0/debian/compat b/QuoteGeneration/installer/linux/deb/libtdx-attest/libtdx-attest-1.0/debian/compat new file mode 100644 index 00000000..ec635144 --- /dev/null +++ b/QuoteGeneration/installer/linux/deb/libtdx-attest/libtdx-attest-1.0/debian/compat @@ -0,0 +1 @@ +9 diff --git a/QuoteGeneration/installer/linux/deb/libtdx-attest/libtdx-attest-1.0/debian/control b/QuoteGeneration/installer/linux/deb/libtdx-attest/libtdx-attest-1.0/debian/control new file mode 100644 index 00000000..72dfa2be --- /dev/null +++ b/QuoteGeneration/installer/linux/deb/libtdx-attest/libtdx-attest-1.0/debian/control @@ -0,0 +1,18 @@ +Source: libtdx-attest +Section: libs +Priority: optional +Maintainer: +Build-Depends: debhelper (>= 8.0.0) +Standards-Version: 3.9.4 +Homepage: https://github.com/intel/SGXDataCenterAttestationPrimitives + +Package: libtdx-attest +Architecture: amd64 +Depends: ${shlibs:Depends}, ${misc:Depends} +Description: Intel(R) Trust Domain Extensions Attestation library + +Package: libtdx-attest-dev +Section: devel +Architecture: amd64 +Depends: libtdx-attest (= @dep_version@) +Description: Intel(R) Trust Domain Extensions Attestation For Developers diff --git a/QuoteGeneration/installer/linux/deb/libtdx-attest/libtdx-attest-1.0/debian/docs b/QuoteGeneration/installer/linux/deb/libtdx-attest/libtdx-attest-1.0/debian/docs new file mode 100644 index 00000000..e69de29b diff --git a/QuoteGeneration/installer/linux/deb/libtdx-attest/libtdx-attest-1.0/debian/rules b/QuoteGeneration/installer/linux/deb/libtdx-attest/libtdx-attest-1.0/debian/rules new file mode 100755 index 00000000..ecf4506c --- /dev/null +++ b/QuoteGeneration/installer/linux/deb/libtdx-attest/libtdx-attest-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/QuoteGeneration/installer/linux/deb/libtdx-attest/libtdx-attest-1.0/debian/source/format b/QuoteGeneration/installer/linux/deb/libtdx-attest/libtdx-attest-1.0/debian/source/format new file mode 100644 index 00000000..163aaf8d --- /dev/null +++ b/QuoteGeneration/installer/linux/deb/libtdx-attest/libtdx-attest-1.0/debian/source/format @@ -0,0 +1 @@ +3.0 (quilt) diff --git a/QuoteGeneration/installer/linux/deb/sgx-dcap-pccs/build.sh b/QuoteGeneration/installer/linux/deb/sgx-dcap-pccs/build.sh index 62bcd847..d98b9d7f 100755 --- a/QuoteGeneration/installer/linux/deb/sgx-dcap-pccs/build.sh +++ b/QuoteGeneration/installer/linux/deb/sgx-dcap-pccs/build.sh @@ -107,7 +107,8 @@ update_version() { update_install_path() { pushd ${SCRIPT_DIR}/${DEB_BUILD_FOLDER} sed -i "s#@pkg_path@#${DCAP_PCCS_PACKAGE_PATH}/${DCAP_PCCS_PACKAGE_NAME}#" debian/conffiles - sed -i "s#@pkg_path@#${DCAP_PCCS_PACKAGE_PATH}/${DCAP_PCCS_PACKAGE_NAME}#" debian/postrm + sed -i "s#@pkg_path@#${DCAP_PCCS_PACKAGE_PATH}/${DCAP_PCCS_PACKAGE_NAME}#" debian/postinst + sed -i "s#@pkg_path@#${DCAP_PCCS_PACKAGE_PATH}/${DCAP_PCCS_PACKAGE_NAME}#" debian/prerm popd } diff --git a/QuoteGeneration/installer/linux/deb/sgx-dcap-pccs/sgx-dcap-pccs-1.0/debian/postinst b/QuoteGeneration/installer/linux/deb/sgx-dcap-pccs/sgx-dcap-pccs-1.0/debian/postinst index bd65d786..eafe0a64 100755 --- a/QuoteGeneration/installer/linux/deb/sgx-dcap-pccs/sgx-dcap-pccs-1.0/debian/postinst +++ b/QuoteGeneration/installer/linux/deb/sgx-dcap-pccs/sgx-dcap-pccs-1.0/debian/postinst @@ -17,49 +17,11 @@ set -e # for details, see http://www.debian.org/doc/debian-policy/ or # the debian-policy package +PACKAGE_PATH=@pkg_path@ case "$1" in configure) - PCCS_USER=pccs - PCCS_HOME=/opt/intel/sgx-dcap-pccs - if ! id "$PCCS_USER" &>/dev/null; then - adduser --quiet --system $PCCS_USER --group --home $PCCS_HOME --no-create-home --shell /bin/bash - fi - chown -R $PCCS_USER:$PCCS_USER $PCCS_HOME - if [ "${DEBIAN_FRONTEND}" != "noninteractive" ] - then - /bin/su -c "/opt/intel/sgx-dcap-pccs/install.sh" $PCCS_USER - fi - - #Install PCCS as system service - echo -n "Installing PCCS service ..." - if [ -d /run/systemd/system ]; then - PCCS_NAME=pccs.service - PCCS_TEMP=$PCCS_HOME/$PCCS_NAME - if [ -d /lib/systemd/system ]; then - PCCS_DEST=/lib/systemd/system/$PCCS_NAME - else - PCCS_DEST=/usr/lib/systemd/system/$PCCS_NAME - fi - cp $PCCS_TEMP $PCCS_DEST - chmod 0644 $PCCS_DEST - systemctl daemon-reload - systemctl enable pccs - systemctl start pccs - elif [ -d /etc/init/ ]; then - PCCS_NAME=pccs.service - PCCS_TEMP=$PCCS_HOME/$PCCS_NAME - PCCS_DEST=/etc/init/$PCCS_NAME - cp $PCCS_TEMP $PCCS_DEST - chmod 0644 $PCCS_DEST - /sbin/initctl reload-configuration - else - echo "failed." - echo "Unsupported platform - neither systemctl nor initctl was found." - exit 5 - fi - echo "finished." - echo "Installation completed successfully." + if [ -x ${PACKAGE_PATH}/startup.sh ]; then ${PACKAGE_PATH}/startup.sh debian; fi ;; abort-upgrade|abort-remove|abort-deconfigure) diff --git a/QuoteGeneration/installer/linux/deb/sgx-dcap-pccs/sgx-dcap-pccs-1.0/debian/postrm b/QuoteGeneration/installer/linux/deb/sgx-dcap-pccs/sgx-dcap-pccs-1.0/debian/postrm deleted file mode 100755 index 0d1376dc..00000000 --- a/QuoteGeneration/installer/linux/deb/sgx-dcap-pccs/sgx-dcap-pccs-1.0/debian/postrm +++ /dev/null @@ -1,67 +0,0 @@ -#!/usr/bin/env bash -# postrm script for sgx-dcap-pccs -# -# 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) - if [ -d @pkg_path@ ] - then - pushd @pkg_path@ &> /dev/null - rm -rf node_modules || true - popd &> /dev/null - fi - - #Remove PCCS system service - echo -n "Uninstalling PCCS service ..." - if [ -d /run/systemd/system ]; then - PCCS_NAME=pccs.service - if [ -d /lib/systemd/system ]; then - PCCS_DEST=/lib/systemd/system/$PCCS_NAME - else - PCCS_DEST=/usr/lib/systemd/system/$PCCS_NAME - fi - systemctl stop pccs || true - systemctl disable pccs || true - rm $PCCS_DEST || true - systemctl daemon-reload - elif [ -d /etc/init/ ]; then - PCCS_NAME=pccs.service - PCCS_DEST=/etc/init/$PCCS_NAME - rm $PCCS_DEST || true - /sbin/initctl reload-configuration - fi - echo "finished." - ;; - - 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/QuoteGeneration/installer/linux/deb/sgx-dcap-pccs/sgx-dcap-pccs-1.0/debian/prerm b/QuoteGeneration/installer/linux/deb/sgx-dcap-pccs/sgx-dcap-pccs-1.0/debian/prerm new file mode 100755 index 00000000..c6e81731 --- /dev/null +++ b/QuoteGeneration/installer/linux/deb/sgx-dcap-pccs/sgx-dcap-pccs-1.0/debian/prerm @@ -0,0 +1,41 @@ +#!/usr/bin/env bash +# prerm script for sgx-dcap-pccs +# +# 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 + + +PACKAGE_PATH=@pkg_path@ + +case "$1" in + remove|upgrade|deconfigure) + if [ -x ${PACKAGE_PATH}/cleanup.sh ]; then ${PACKAGE_PATH}/cleanup.sh; fi + ;; + + 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/QuoteGeneration/installer/linux/deb/tdx-qgs/build.sh b/QuoteGeneration/installer/linux/deb/tdx-qgs/build.sh new file mode 100755 index 00000000..f4e2f71a --- /dev/null +++ b/QuoteGeneration/installer/linux/deb/tdx-qgs/build.sh @@ -0,0 +1,129 @@ +#!/usr/bin/env bash +# +# Copyright (C) 2011-2021 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_BUILD_DIR=$(readlink -m "${ROOT_DIR}/build/linux") +LINUX_INSTALLER_DIR="${ROOT_DIR}/installer/linux" +LINUX_INSTALLER_COMMON_DIR="${LINUX_INSTALLER_DIR}/common" +LINUX_INSTALLER_COMMON_TDX_QGS_DIR="${LINUX_INSTALLER_COMMON_DIR}/tdx-qgs" + +source ${LINUX_INSTALLER_COMMON_TDX_QGS_DIR}/installConfig +DEB_FOLDER=${TDX_QGS_PACKAGE_NAME}-${TDX_QGS_VERSION} + +SGX_VERSION=$(awk '/STRFILEVER/ {print $3}' ${ROOT_DIR}/common/inc/internal/se_version.h|sed 's/^\"\(.*\)\"$/\1/') +DEB_BUILD_FOLDER=${TDX_QGS_PACKAGE_NAME}-${SGX_VERSION} + +PACKAGE_NAMES[0]=${TDX_QGS_PACKAGE_NAME} + +main() { + pre_build + create_upstream_tarball + unpack_upstream_tarball + generate_copyright + update_version + update_install_path + 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() { + rm -fR ${SCRIPT_DIR}/${DEB_BUILD_FOLDER} +} + +create_upstream_tarball() { + ${LINUX_INSTALLER_COMMON_TDX_QGS_DIR}/createTarball.sh + cp ${LINUX_INSTALLER_COMMON_TDX_QGS_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() { + pushd ${SCRIPT_DIR}/${DEB_BUILD_FOLDER} + rm -f debian/copyright + find package/licenses/ -type f -print0 | xargs -0 -n1 cat >> debian/copyright + popd +} + +get_os_code() { + OS_CODE=$(lsb_release -cs 2> /dev/null) + if [ -z ${OS_CODE} ]; then + OS_CODE=$(grep "VERSION_CODENAME" /etc/os-release 2> /dev/null | cut -d= -f2) + fi + echo ${OS_CODE} +} + +update_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) + + FULL_VERSION=${SGX_VERSION}-$(get_os_code)${DEB_VERSION} + sed -i "s/${INS_VERSION}/${FULL_VERSION}/" debian/changelog + sed -i "s/@dep_version@/${FULL_VERSION}/g" debian/control + popd +} + +update_install_path() { + pushd ${SCRIPT_DIR}/${DEB_BUILD_FOLDER} + sed -i "s#@pkg_path@#${TDX_QGS_PACKAGE_PATH}/${TDX_QGS_PACKAGE_NAME}#" debian/postinst + sed -i "s#@pkg_path@#${TDX_QGS_PACKAGE_PATH}/${TDX_QGS_PACKAGE_NAME}#" debian/prerm + popd +} + +rename_tarball() { + TARBALL_NAME_NEW_VERSION=$(echo ${TARBALL_NAME} | sed "s/${TDX_QGS_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)" LINUX_BUILD_DIR="${LINUX_BUILD_DIR}" dpkg-buildpackage -us -uc + popd +} + +main $@ diff --git a/QuoteGeneration/installer/linux/deb/tdx-qgs/clean.sh b/QuoteGeneration/installer/linux/deb/tdx-qgs/clean.sh new file mode 100755 index 00000000..1b71343b --- /dev/null +++ b/QuoteGeneration/installer/linux/deb/tdx-qgs/clean.sh @@ -0,0 +1,47 @@ +#!/usr/bin/env bash +# +# Copyright (C) 2011-2021 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") +COMMON_DIR="${SCRIPT_DIR}/../../common/tdx-qgs" + +rm -f ${SCRIPT_DIR}/tdx-qgs*.deb +rm -f ${SCRIPT_DIR}/tdx-qgs*dbgsym*.ddeb +rm -f ${SCRIPT_DIR}/tdx-qgs*.tar.gz +rm -f ${SCRIPT_DIR}/tdx-qgs*.tar.xz +rm -f ${SCRIPT_DIR}/tdx-qgs*.dsc +rm -f ${SCRIPT_DIR}/tdx-qgs*.changes +rm -f ${SCRIPT_DIR}/tdx-qgs*.buildinfo +rm -f ${COMMON_DIR}/gen_source.py +rm -rf ${COMMON_DIR}/output \ No newline at end of file diff --git a/QuoteGeneration/installer/linux/deb/tdx-qgs/tdx-qgs-1.0/debian/changelog b/QuoteGeneration/installer/linux/deb/tdx-qgs/tdx-qgs-1.0/debian/changelog new file mode 100644 index 00000000..b98dfd99 --- /dev/null +++ b/QuoteGeneration/installer/linux/deb/tdx-qgs/tdx-qgs-1.0/debian/changelog @@ -0,0 +1,5 @@ +tdx-qgs (1.0-1) unstable; urgency=low + + * Initial Release + + -- Xiangquan Liu Wed, 23 Dec 2020 15:23:51 +0800 diff --git a/QuoteGeneration/installer/linux/deb/tdx-qgs/tdx-qgs-1.0/debian/compat b/QuoteGeneration/installer/linux/deb/tdx-qgs/tdx-qgs-1.0/debian/compat new file mode 100644 index 00000000..ec635144 --- /dev/null +++ b/QuoteGeneration/installer/linux/deb/tdx-qgs/tdx-qgs-1.0/debian/compat @@ -0,0 +1 @@ +9 diff --git a/QuoteGeneration/installer/linux/deb/tdx-qgs/tdx-qgs-1.0/debian/control b/QuoteGeneration/installer/linux/deb/tdx-qgs/tdx-qgs-1.0/debian/control new file mode 100644 index 00000000..203779d4 --- /dev/null +++ b/QuoteGeneration/installer/linux/deb/tdx-qgs/tdx-qgs-1.0/debian/control @@ -0,0 +1,12 @@ +Source: tdx-qgs +Section: utils +Priority: optional +Maintainer: +Build-Depends: debhelper (>= 8.0.0) +Standards-Version: 3.9.4 +Homepage: https://github.com/intel/SGXDataCenterAttestationPrimitives + +Package: tdx-qgs +Architecture: amd64 +Depends: ${shlibs:Depends}, ${misc:Depends}, libsgx-tdx-logic(>= @dep_version@) +Description: Intel(R) TD Quoting Generation Service \ No newline at end of file diff --git a/QuoteGeneration/installer/linux/deb/tdx-qgs/tdx-qgs-1.0/debian/docs b/QuoteGeneration/installer/linux/deb/tdx-qgs/tdx-qgs-1.0/debian/docs new file mode 100644 index 00000000..e69de29b diff --git a/QuoteGeneration/installer/linux/deb/tdx-qgs/tdx-qgs-1.0/debian/postinst b/QuoteGeneration/installer/linux/deb/tdx-qgs/tdx-qgs-1.0/debian/postinst new file mode 100644 index 00000000..c5f96f3c --- /dev/null +++ b/QuoteGeneration/installer/linux/deb/tdx-qgs/tdx-qgs-1.0/debian/postinst @@ -0,0 +1,42 @@ +#!/usr/bin/env bash +# postinst script for tdx-qgs +# +# 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 + + +PACKAGE_PATH=@pkg_path@ + +case "$1" in + configure) + [[ -x ${PACKAGE_PATH}/startup.sh ]] && ${PACKAGE_PATH}/startup.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/QuoteGeneration/installer/linux/deb/tdx-qgs/tdx-qgs-1.0/debian/prerm b/QuoteGeneration/installer/linux/deb/tdx-qgs/tdx-qgs-1.0/debian/prerm new file mode 100644 index 00000000..20fcc99e --- /dev/null +++ b/QuoteGeneration/installer/linux/deb/tdx-qgs/tdx-qgs-1.0/debian/prerm @@ -0,0 +1,41 @@ +#!/usr/bin/env bash +# prerm script for tdx-qgs +# +# 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 + + +PACKAGE_PATH=@pkg_path@ + +case "$1" in + remove|upgrade|deconfigure) + [[ -x ${PACKAGE_PATH}/cleanup.sh ]] && ${PACKAGE_PATH}/cleanup.sh + ;; + + 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/QuoteGeneration/installer/linux/deb/tdx-qgs/tdx-qgs-1.0/debian/rules b/QuoteGeneration/installer/linux/deb/tdx-qgs/tdx-qgs-1.0/debian/rules new file mode 100755 index 00000000..7770058a --- /dev/null +++ b/QuoteGeneration/installer/linux/deb/tdx-qgs/tdx-qgs-1.0/debian/rules @@ -0,0 +1,11 @@ +#!/usr/bin/make -f +# -*- makefile -*- + +# Uncomment this to turn on verbose mode. +#export DH_VERBOSE=1 + +%: + dh $@ + +override_dh_shlibdeps: + dh_shlibdeps -l $(LINUX_BUILD_DIR) --dpkg-shlibdeps-params=--ignore-missing-info diff --git a/QuoteGeneration/installer/linux/deb/tdx-qgs/tdx-qgs-1.0/debian/source/format b/QuoteGeneration/installer/linux/deb/tdx-qgs/tdx-qgs-1.0/debian/source/format new file mode 100644 index 00000000..163aaf8d --- /dev/null +++ b/QuoteGeneration/installer/linux/deb/tdx-qgs/tdx-qgs-1.0/debian/source/format @@ -0,0 +1 @@ +3.0 (quilt) diff --git a/QuoteGeneration/installer/linux/rpm/libsgx-ae-tdqe/build.sh b/QuoteGeneration/installer/linux/rpm/libsgx-ae-tdqe/build.sh new file mode 100755 index 00000000..7888eb82 --- /dev/null +++ b/QuoteGeneration/installer/linux/rpm/libsgx-ae-tdqe/build.sh @@ -0,0 +1,88 @@ +#!/usr/bin/env bash +# +# Copyright (C) 2011-2021 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}/installer/linux" +LINUX_INSTALLER_COMMON_DIR="${LINUX_INSTALLER_DIR}/common" +LINUX_INSTALLER_COMMON_AE_TDX_DIR="${LINUX_INSTALLER_COMMON_DIR}/libsgx-ae-tdqe" + +source ${LINUX_INSTALLER_COMMON_AE_TDX_DIR}/installConfig + +SGX_VERSION=$(awk '/STRFILEVER/ {print $3}' ${ROOT_DIR}/common/inc/internal/se_version.h|sed 's/^\"\(.*\)\"$/\1/') +RPM_BUILD_FOLDER=${AE_TDX_PACKAGE_NAME}-${SGX_VERSION} + +main() { + pre_build + update_spec + create_upstream_tarball + build_rpm_package + post_build +} + +pre_build() { + rm -fR ${SCRIPT_DIR}/${RPM_BUILD_FOLDER} + mkdir -p ${SCRIPT_DIR}/${RPM_BUILD_FOLDER}/{BUILD,RPMS,SOURCES,SPECS,SRPMS} + cp -f ${SCRIPT_DIR}/${AE_TDX_PACKAGE_NAME}.spec ${SCRIPT_DIR}/${RPM_BUILD_FOLDER}/SPECS +} + +post_build() { + for FILE in $(find ${SCRIPT_DIR}/${RPM_BUILD_FOLDER} -name "*.rpm" 2> /dev/null); do + cp "${FILE}" ${SCRIPT_DIR} + done + rm -fR ${SCRIPT_DIR}/${RPM_BUILD_FOLDER} +} + +update_spec() { + pushd ${SCRIPT_DIR}/${RPM_BUILD_FOLDER} + sed -i "s/@version@/${SGX_VERSION}/" SPECS/${AE_TDX_PACKAGE_NAME}.spec + popd +} + +create_upstream_tarball() { + ${LINUX_INSTALLER_COMMON_AE_TDX_DIR}/createTarball.sh + tar -xvf ${LINUX_INSTALLER_COMMON_AE_TDX_DIR}/output/${TARBALL_NAME} -C ${SCRIPT_DIR}/${RPM_BUILD_FOLDER}/SOURCES + pushd ${SCRIPT_DIR}/${RPM_BUILD_FOLDER}/SOURCES + tar -zcvf ${RPM_BUILD_FOLDER}$(echo ${TARBALL_NAME}|awk -F'.' '{print "."$(NF-1)"."$(NF)}') * + popd +} + +build_rpm_package() { + pushd ${SCRIPT_DIR}/${RPM_BUILD_FOLDER} + rpmbuild --define="_topdir `pwd`" --define='_debugsource_template %{nil}' -ba SPECS/${AE_TDX_PACKAGE_NAME}.spec + popd +} + +main $@ diff --git a/QuoteGeneration/installer/linux/rpm/libsgx-ae-tdqe/clean.sh b/QuoteGeneration/installer/linux/rpm/libsgx-ae-tdqe/clean.sh new file mode 100755 index 00000000..5dc24ca3 --- /dev/null +++ b/QuoteGeneration/installer/linux/rpm/libsgx-ae-tdqe/clean.sh @@ -0,0 +1,41 @@ +#!/usr/bin/env bash +# +# Copyright (C) 2011-2021 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") +COMMON_DIR="${SCRIPT_DIR}/../../common/libsgx-ae-tdqe" + +rm -f ${SCRIPT_DIR}/libsgx*.rpm +rm -f ${COMMON_DIR}/gen_source.py +rm -rf ${COMMON_DIR}/output diff --git a/QuoteGeneration/installer/linux/rpm/libsgx-ae-tdqe/libsgx-ae-tdqe.spec b/QuoteGeneration/installer/linux/rpm/libsgx-ae-tdqe/libsgx-ae-tdqe.spec new file mode 100644 index 00000000..38301d3d --- /dev/null +++ b/QuoteGeneration/installer/linux/rpm/libsgx-ae-tdqe/libsgx-ae-tdqe.spec @@ -0,0 +1,66 @@ +# +# Copyright (C) 2011-2019 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. +# +# + +%define _license_file COPYING + +Name: libsgx-ae-tdqe +Version: @version@ +Release: 1%{?dist} +Summary: Intel(R) Trust Domain Extensions QE +Group: Development/Libraries + +License: BSD License +URL: https://github.com/intel/SGXDataCenterAttestationPrimitives +Source0: %{name}-%{version}.tar.gz + +%description +Intel(R) Trust Domain Extensions QE + +%prep +%setup -qc + +%build +make %{?_smp_mflags} + +%install +make DESTDIR=%{?buildroot} install +install -d %{?buildroot}%{_docdir}/%{name} +find %{?_sourcedir}/package/licenses/ -type f -print0 | xargs -0 -n1 cat >> %{?buildroot}%{_docdir}/%{name}/%{_license_file} +rm -f %{_specdir}/list-%{name} +for f in $(find %{?buildroot} -type f -o -type l); do + echo $f | sed -e "s#%{?buildroot}##" >> %{_specdir}/list-%{name} +done + +%files -f %{_specdir}/list-%{name} + +%changelog +* Mon Jul 27 2020 SGX Team +- Initial Release diff --git a/QuoteGeneration/installer/linux/rpm/libsgx-dcap-ql/libsgx-dcap-ql.spec b/QuoteGeneration/installer/linux/rpm/libsgx-dcap-ql/libsgx-dcap-ql.spec index 461e34dc..222c8a70 100644 --- a/QuoteGeneration/installer/linux/rpm/libsgx-dcap-ql/libsgx-dcap-ql.spec +++ b/QuoteGeneration/installer/linux/rpm/libsgx-dcap-ql/libsgx-dcap-ql.spec @@ -37,7 +37,7 @@ Release: 1%{?dist} Summary: Intel(R) Software Guard Extensions Data Center Attestation Primitives Group: Development/Libraries Requires: libsgx-qe3-logic >= %{version}-%{release} libsgx-pce-logic >= %{version}-%{release} -Recommends: libsgx-dcap-quote-verify >= %{version}-%{release} libsgx-quote-ex >= 2.16 +Recommends: libsgx-dcap-quote-verify >= %{version}-%{release} libsgx-quote-ex >= 2.17 License: BSD License URL: https://github.com/intel/SGXDataCenterAttestationPrimitives @@ -49,7 +49,7 @@ Intel(R) Software Guard Extensions Data Center Attestation Primitives %package devel Summary: Intel(R) Software Guard Extensions Data Center Attestation Primitives for Developers Group: Development/Libraries -Requires: %{name} = %{version}-%{release} libsgx-headers >= 2.16 +Requires: %{name} = %{version}-%{release} libsgx-headers >= 2.17 %description devel Intel(R) Software Guard Extensions Data Center Attestation Primitives for Developers diff --git a/QuoteGeneration/installer/linux/rpm/libsgx-dcap-quote-verify/libsgx-dcap-quote-verify.spec b/QuoteGeneration/installer/linux/rpm/libsgx-dcap-quote-verify/libsgx-dcap-quote-verify.spec index c81cae74..9d8db4cf 100644 --- a/QuoteGeneration/installer/linux/rpm/libsgx-dcap-quote-verify/libsgx-dcap-quote-verify.spec +++ b/QuoteGeneration/installer/linux/rpm/libsgx-dcap-quote-verify/libsgx-dcap-quote-verify.spec @@ -36,7 +36,7 @@ Version: @version@ Release: 1%{?dist} Summary: Intel(R) Software Guard Extensions Data Center Attestation Primitives Group: Development/Libraries -Recommends: libsgx-ae-qve >= %{version}-%{release} libsgx-urts >= %{version}-%{release} +Recommends: libsgx-ae-qve >= %{version}-%{release} libsgx-urts >= 2.17 License: BSD License URL: https://github.com/intel/SGXDataCenterAttestationPrimitives @@ -48,7 +48,7 @@ Intel(R) Software Guard Extensions Data Center Attestation Primitives %package devel Summary: Intel(R) Software Guard Extensions Data Center Attestation Primitives for Developers Group: Development/Libraries -Requires: %{name} = %{version}-%{release} libsgx-headers >= 2.16 +Requires: %{name} = %{version}-%{release} libsgx-headers >= 2.17 %description devel Intel(R) Software Guard Extensions Data Center Attestation Primitives for Developers diff --git a/QuoteGeneration/installer/linux/rpm/libsgx-pce-logic/libsgx-pce-logic.spec b/QuoteGeneration/installer/linux/rpm/libsgx-pce-logic/libsgx-pce-logic.spec index f288e5c5..b3bf250e 100644 --- a/QuoteGeneration/installer/linux/rpm/libsgx-pce-logic/libsgx-pce-logic.spec +++ b/QuoteGeneration/installer/linux/rpm/libsgx-pce-logic/libsgx-pce-logic.spec @@ -36,7 +36,7 @@ Version: @version@ Release: 1%{?dist} Summary: Intel(R) Software Guard Extensions PCE logic Group: Development/Libraries -Requires: libsgx-urts >= 2.16 libsgx-ae-pce >= 2.16 +Requires: libsgx-urts >= 2.17 libsgx-ae-pce >= 2.17 License: BSD License URL: https://github.com/intel/SGXDataCenterAttestationPrimitives diff --git a/QuoteGeneration/installer/linux/rpm/libsgx-qe3-logic/libsgx-qe3-logic.spec b/QuoteGeneration/installer/linux/rpm/libsgx-qe3-logic/libsgx-qe3-logic.spec index d6798cd3..3aeeaefc 100644 --- a/QuoteGeneration/installer/linux/rpm/libsgx-qe3-logic/libsgx-qe3-logic.spec +++ b/QuoteGeneration/installer/linux/rpm/libsgx-qe3-logic/libsgx-qe3-logic.spec @@ -36,7 +36,7 @@ Version: @version@ Release: 1%{?dist} Summary: Intel(R) Software Guard Extensions QE3 logic Group: Development/Libraries -Requires: libsgx-urts >= 2.16 libsgx-ae-qe3 >= %{version}-%{release} libsgx-ae-id-enclave >= %{version}-%{release} +Requires: libsgx-urts >= 2.17 libsgx-ae-qe3 >= %{version}-%{release} libsgx-ae-id-enclave >= %{version}-%{release} License: BSD License URL: https://github.com/intel/SGXDataCenterAttestationPrimitives diff --git a/QuoteGeneration/installer/linux/rpm/libsgx-tdx-logic/build.sh b/QuoteGeneration/installer/linux/rpm/libsgx-tdx-logic/build.sh new file mode 100755 index 00000000..e82cb5d1 --- /dev/null +++ b/QuoteGeneration/installer/linux/rpm/libsgx-tdx-logic/build.sh @@ -0,0 +1,88 @@ +#!/usr/bin/env bash +# +# Copyright (C) 2011-2021 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}/installer/linux" +LINUX_INSTALLER_COMMON_DIR="${LINUX_INSTALLER_DIR}/common" +LINUX_INSTALLER_COMMON_TDX_LOGIC_DIR="${LINUX_INSTALLER_COMMON_DIR}/libsgx-tdx-logic" + +source ${LINUX_INSTALLER_COMMON_TDX_LOGIC_DIR}/installConfig + +SGX_VERSION=$(awk '/STRFILEVER/ {print $3}' ${ROOT_DIR}/common/inc/internal/se_version.h|sed 's/^\"\(.*\)\"$/\1/') +RPM_BUILD_FOLDER=${TDX_LOGIC_PACKAGE_NAME}-${SGX_VERSION} + +main() { + pre_build + update_spec + create_upstream_tarball + build_rpm_package + post_build +} + +pre_build() { + rm -fR ${SCRIPT_DIR}/${RPM_BUILD_FOLDER} + mkdir -p ${SCRIPT_DIR}/${RPM_BUILD_FOLDER}/{BUILD,RPMS,SOURCES,SPECS,SRPMS} + cp -f ${SCRIPT_DIR}/${TDX_LOGIC_PACKAGE_NAME}.spec ${SCRIPT_DIR}/${RPM_BUILD_FOLDER}/SPECS +} + +post_build() { + for FILE in $(find ${SCRIPT_DIR}/${RPM_BUILD_FOLDER} -name "*.rpm" 2> /dev/null); do + cp "${FILE}" ${SCRIPT_DIR} + done + rm -fR ${SCRIPT_DIR}/${RPM_BUILD_FOLDER} +} + +update_spec() { + pushd ${SCRIPT_DIR}/${RPM_BUILD_FOLDER} + sed -i "s/@version@/${SGX_VERSION}/" SPECS/${TDX_LOGIC_PACKAGE_NAME}.spec + popd +} + +create_upstream_tarball() { + ${LINUX_INSTALLER_COMMON_TDX_LOGIC_DIR}/createTarball.sh + tar -xvf ${LINUX_INSTALLER_COMMON_TDX_LOGIC_DIR}/output/${TARBALL_NAME} -C ${SCRIPT_DIR}/${RPM_BUILD_FOLDER}/SOURCES + pushd ${SCRIPT_DIR}/${RPM_BUILD_FOLDER}/SOURCES + tar -zcvf ${RPM_BUILD_FOLDER}$(echo ${TARBALL_NAME}|awk -F'.' '{print "."$(NF-1)"."$(NF)}') * + popd +} + +build_rpm_package() { + pushd ${SCRIPT_DIR}/${RPM_BUILD_FOLDER} + rpmbuild --define="_topdir `pwd`" --define='_debugsource_template %{nil}' -ba SPECS/${TDX_LOGIC_PACKAGE_NAME}.spec + popd +} + +main $@ diff --git a/QuoteGeneration/installer/linux/rpm/libsgx-tdx-logic/clean.sh b/QuoteGeneration/installer/linux/rpm/libsgx-tdx-logic/clean.sh new file mode 100755 index 00000000..7b655737 --- /dev/null +++ b/QuoteGeneration/installer/linux/rpm/libsgx-tdx-logic/clean.sh @@ -0,0 +1,41 @@ +#!/usr/bin/env bash +# +# Copyright (C) 2011-2021 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") +COMMON_DIR="${SCRIPT_DIR}/../../common/libsgx-tdx-logic" + +rm -f ${SCRIPT_DIR}/libsgx*.rpm +rm -f ${COMMON_DIR}/gen_source.py +rm -rf ${COMMON_DIR}/output diff --git a/QuoteGeneration/installer/linux/rpm/libsgx-tdx-logic/libsgx-tdx-logic.spec b/QuoteGeneration/installer/linux/rpm/libsgx-tdx-logic/libsgx-tdx-logic.spec new file mode 100644 index 00000000..2f8a0a6a --- /dev/null +++ b/QuoteGeneration/installer/linux/rpm/libsgx-tdx-logic/libsgx-tdx-logic.spec @@ -0,0 +1,84 @@ +# +# Copyright (C) 2011-2019 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. +# +# + +%define _license_file COPYING + +Name: libsgx-tdx-logic +Version: @version@ +Release: 1%{?dist} +Summary: Intel(R) Trust Domain Extensions QE logic library +Group: Development/Libraries +Requires: libsgx-urts >= 2.17 libsgx-ae-tdqe >= %{version}-%{release} libsgx-ae-id-enclave >= %{version}-%{release} libsgx-pce-logic >= %{version}-%{release} + +License: BSD License +URL: https://github.com/intel/SGXDataCenterAttestationPrimitives +Source0: %{name}-%{version}.tar.gz + + +%description +Intel(R) Trust Domain Extensions QE logic library + +%package devel +Summary: Intel(R) Trust Domain Extensions QE logic library For Developers +Group: Development/Libraries +Requires: %{name} = %{version}-%{release} +%description devel +Intel(R) Trust Domain Extensions QE logic library For Developers +%prep +%setup -qc + + +%build +make %{?_smp_mflags} + +%install +make DESTDIR=%{?buildroot} install +install -d %{?buildroot}/%{name}%{_docdir}/%{name} +find %{?_sourcedir}/package/licenses/ -type f -print0 | xargs -0 -n1 cat >> %{?buildroot}/%{name}%{_docdir}/%{name}/%{_license_file} +rm -f %{_specdir}/list-%{name} +for f in $(find %{?buildroot}/%{name} -type f -o -type l); do + echo $f | sed -e "s#%{?buildroot}/%{name}##" >> %{_specdir}/list-%{name} +done +cp -r %{?buildroot}/%{name}/* %{?buildroot}/ +rm -fr %{?buildroot}/%{name} +rm -f %{_specdir}/list-%{name}-devel +for f in $(find %{?buildroot}/%{name}-dev -type f -o -type l); do + echo $f | sed -e "s#%{?buildroot}/%{name}-dev##" >> %{_specdir}/list-%{name}-devel +done +cp -r %{?buildroot}/%{name}-dev/* %{?buildroot}/ +rm -fr %{?buildroot}/%{name}-dev + +%files -f %{_specdir}/list-%{name} + +%files devel -f %{_specdir}/list-%{name}-devel +%changelog +* Mon Jul 27 2020 SGX Team +- Initial Release diff --git a/QuoteGeneration/installer/linux/rpm/libtdx-attest/build.sh b/QuoteGeneration/installer/linux/rpm/libtdx-attest/build.sh new file mode 100755 index 00000000..56faed39 --- /dev/null +++ b/QuoteGeneration/installer/linux/rpm/libtdx-attest/build.sh @@ -0,0 +1,94 @@ +#!/usr/bin/env bash +# +# Copyright (C) 2011-2021 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}/installer/linux" +LINUX_INSTALLER_COMMON_DIR="${LINUX_INSTALLER_DIR}/common" +LINUX_INSTALLER_COMMON_TDX_ATTEST_DIR="${LINUX_INSTALLER_COMMON_DIR}/libtdx-attest" + +source ${LINUX_INSTALLER_COMMON_TDX_ATTEST_DIR}/installConfig + +SGX_VERSION=$(awk '/STRFILEVER/ {print $3}' ${ROOT_DIR}/common/inc/internal/se_version.h|sed 's/^\"\(.*\)\"$/\1/') +RPM_BUILD_FOLDER=${TDX_ATTEST_PACKAGE_NAME}-${SGX_VERSION} + +main() { + pre_build + update_spec + create_upstream_tarball + build_rpm_package + post_build +} + +pre_build() { + rm -fR ${SCRIPT_DIR}/${RPM_BUILD_FOLDER} + mkdir -p ${SCRIPT_DIR}/${RPM_BUILD_FOLDER}/{BUILD,RPMS,SOURCES,SPECS,SRPMS} + cp -f ${SCRIPT_DIR}/${TDX_ATTEST_PACKAGE_NAME}.spec ${SCRIPT_DIR}/${RPM_BUILD_FOLDER}/SPECS +} + +post_build() { + for FILE in $(find ${SCRIPT_DIR}/${RPM_BUILD_FOLDER} -name "*.rpm" 2> /dev/null); do + cp "${FILE}" ${SCRIPT_DIR} + done + rm -fR ${SCRIPT_DIR}/${RPM_BUILD_FOLDER} +} + +update_spec() { + min_version="4.12" + rpm_version=$(rpmbuild --version 2> /dev/null | awk '{print $NF}') + cur_version=$(echo -e "${rpm_version}\n${min_version}" | sort -V | head -n 1) + pushd ${SCRIPT_DIR}/${RPM_BUILD_FOLDER} + sed -i "s/@version@/${SGX_VERSION}/" SPECS/${TDX_ATTEST_PACKAGE_NAME}.spec + if [ "${min_version}" != "${cur_version}" ]; then + sed -i "s/^Recommends:/Requires: /" SPECS/${TDX_ATTEST_PACKAGE_NAME}.spec + fi + popd +} + +create_upstream_tarball() { + ${LINUX_INSTALLER_COMMON_TDX_ATTEST_DIR}/createTarball.sh + tar -xvf ${LINUX_INSTALLER_COMMON_TDX_ATTEST_DIR}/output/${TARBALL_NAME} -C ${SCRIPT_DIR}/${RPM_BUILD_FOLDER}/SOURCES + pushd ${SCRIPT_DIR}/${RPM_BUILD_FOLDER}/SOURCES + tar -zcvf ${RPM_BUILD_FOLDER}$(echo ${TARBALL_NAME}|awk -F'.' '{print "."$(NF-1)"."$(NF)}') * + popd +} + +build_rpm_package() { + pushd ${SCRIPT_DIR}/${RPM_BUILD_FOLDER} + rpmbuild --define="_topdir `pwd`" --define='_debugsource_template %{nil}' -ba SPECS/${TDX_ATTEST_PACKAGE_NAME}.spec + popd +} + +main $@ diff --git a/QuoteGeneration/installer/linux/rpm/libtdx-attest/clean.sh b/QuoteGeneration/installer/linux/rpm/libtdx-attest/clean.sh new file mode 100755 index 00000000..b491cca9 --- /dev/null +++ b/QuoteGeneration/installer/linux/rpm/libtdx-attest/clean.sh @@ -0,0 +1,41 @@ +#!/usr/bin/env bash +# +# Copyright (C) 2011-2021 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") +COMMON_DIR="${SCRIPT_DIR}/../../common/libtdx-attest" + +rm -f ${SCRIPT_DIR}/libtdx-attest*.rpm +rm -f ${COMMON_DIR}/gen_source.py +rm -rf ${COMMON_DIR}/output diff --git a/QuoteGeneration/installer/linux/rpm/libtdx-attest/libtdx-attest.spec b/QuoteGeneration/installer/linux/rpm/libtdx-attest/libtdx-attest.spec new file mode 100644 index 00000000..0bcff481 --- /dev/null +++ b/QuoteGeneration/installer/linux/rpm/libtdx-attest/libtdx-attest.spec @@ -0,0 +1,84 @@ +# +# Copyright (C) 2011-2020 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. +# +# + +%define _license_file COPYING + +Name: libtdx-attest +Version: @version@ +Release: 1%{?dist} +Summary: Intel(R) Trust Domain Extensions Attestation library +Group: Development/Libraries + +License: BSD License +URL: https://github.com/intel/SGXDataCenterAttestationPrimitives +Source0: %{name}-%{version}.tar.gz + +%description +Intel(R) Trust Domain Extensions Attestation library + +%package devel +Summary: Intel(R) Trust Domain Extensions Attestation For Developers +Group: Development/Libraries +Requires: %{name} = %{version}-%{release} + +%description devel +Intel(R) Trust Domain Extensions Attestation For Developers + +%prep +%setup -qc + +%build +make %{?_smp_mflags} + +%install +make DESTDIR=%{?buildroot} install +install -d %{?buildroot}/%{name}%{_docdir}/%{name} +find %{?_sourcedir}/package/licenses/ -type f -print0 | xargs -0 -n1 cat >> %{?buildroot}/%{name}%{_docdir}/%{name}/%{_license_file} +rm -f %{_specdir}/list-%{name} +for f in $(find %{?buildroot}/%{name} -type f -o -type l); do + echo $f | sed -e "s#%{?buildroot}/%{name}##" >> %{_specdir}/list-%{name} +done +cp -r %{?buildroot}/%{name}/* %{?buildroot}/ +rm -fr %{?buildroot}/%{name} +rm -f %{_specdir}/list-%{name}-devel +for f in $(find %{?buildroot}/%{name}-dev -type f -o -type l); do + echo $f | sed -e "s#%{?buildroot}/%{name}-dev##" >> %{_specdir}/list-%{name}-devel +done +cp -r %{?buildroot}/%{name}-dev/* %{?buildroot}/ +rm -fr %{?buildroot}/%{name}-dev + +%files -f %{_specdir}/list-%{name} + +%files devel -f %{_specdir}/list-%{name}-devel + +%changelog +* Thu Feb 18 2021 SGX Team +- Initial Release diff --git a/QuoteGeneration/installer/linux/rpm/sgx-dcap-pccs/sgx-dcap-pccs.spec b/QuoteGeneration/installer/linux/rpm/sgx-dcap-pccs/sgx-dcap-pccs.spec index 61d7d84d..0c10ccf6 100644 --- a/QuoteGeneration/installer/linux/rpm/sgx-dcap-pccs/sgx-dcap-pccs.spec +++ b/QuoteGeneration/installer/linux/rpm/sgx-dcap-pccs/sgx-dcap-pccs.spec @@ -52,80 +52,35 @@ Intel(R) Software Guard Extensions PCK Caching Service %install make DESTDIR=%{?buildroot} install install -d %{?buildroot}%{_docdir}/%{name} -find %{?_sourcedir}/package/licenses/ -type f -print0 | xargs -0 -n1 cat >> %{?buildroot}%{_docdir}/%{name}/%{_license_file} -echo "%{_install_path}" > %{_specdir}/listfiles -echo %{_docdir}/%{name}/%{_license_file} >> %{_specdir}/listfiles -echo "%config %{_install_path}/config/default.json" >> %{_specdir}/listfiles -%files -f %{_specdir}/listfiles - -%post -PCCS_USER=pccs -PCCS_HOME=%{_install_path} -if [ ! $(getent group $PCCS_USER) ]; then - groupadd $PCCS_USER -fi -if ! id "$PCCS_USER" &>/dev/null; then - adduser --system $PCCS_USER -g $PCCS_USER --home $PCCS_HOME --no-create-home --shell /bin/bash -fi -chown -R $PCCS_USER:$PCCS_USER $PCCS_HOME -chmod 640 $PCCS_HOME/config/default.json -#Install PCCS as system service -echo -n "Installing PCCS service ..." -if [ -d /run/systemd/system ]; then - PCCS_NAME=pccs.service - PCCS_TEMP=$PCCS_HOME/$PCCS_NAME - if [ -d /lib/systemd/system ]; then - PCCS_DEST=/lib/systemd/system/$PCCS_NAME +find linux/installer/common/sdk/output/package/licenses/ -type f -print0 | \ +xargs -0 -n1 cat >> %{?buildroot}%{_docdir}/%{name}/%{_license_file} +find %{?buildroot} -type d -links 2 | \ +sed -e "s#^%{?buildroot}##" | \ +grep -v "^%{_libdir}" | \ +grep -v "^%{_bindir}" | \ +grep -v "^%{_sysconfdir}" | \ +grep -v "^%{_install_path}" | \ +sed -e "s#^#%dir #" > %{_specdir}/listfiles +for f in $(find %{?buildroot}); do + if [ -d ${f} ]; then + echo ${f} | \ + sed -e "s#^%{?buildroot}##" | \ + grep "^%{_install_path}" | \ + sed -e "s#^#%dir #" >> %{_specdir}/listfiles else - PCCS_DEST=/usr/lib/systemd/system/$PCCS_NAME + echo ${f} | \ + sed -e "s#^%{?buildroot}##" >> %{_specdir}/listfiles fi - cp $PCCS_TEMP $PCCS_DEST - chmod 0644 $PCCS_DEST - systemctl daemon-reload - systemctl enable pccs -elif [ -d /etc/init/ ]; then - PCCS_NAME=pccs.service - PCCS_TEMP=$PCCS_HOME/$PCCS_NAME - PCCS_DEST=/etc/init/$PCCS_NAME - cp $PCCS_TEMP $PCCS_DEST - chmod 0644 $PCCS_DEST - /sbin/initctl reload-configuration -else - echo " failed." - echo "Unsupported platform - neither systemctl nor initctl was found." - exit 5 -fi -echo "finished." -echo "Installation completed successfully." +done +sed -i 's#^%{_install_path}/config/default.json#%config &#' %{_specdir}/listfiles -%postun -if [ $1 == 0 ]; then - echo -n "Uninstalling PCCS service ..." - if [ -d /run/systemd/system ]; then - PCCS_NAME=pccs.service - if [ -d /lib/systemd/system ]; then - PCCS_DEST=/lib/systemd/system/$PCCS_NAME - else - PCCS_DEST=/usr/lib/systemd/system/$PCCS_NAME - fi - systemctl stop pccs || true - systemctl disable pccs || true - rm $PCCS_DEST || true - systemctl daemon-reload - elif [ -d /etc/init/ ]; then - PCCS_NAME=pccs.service - PCCS_DEST=/etc/init/$PCCS_NAME - rm $PCCS_DEST || true - /sbin/initctl reload-configuration - fi - echo "finished." +%files -f %{_specdir}/listfiles - if [ -d %{_install_path} ]; then - pushd %{_install_path} &> /dev/null - rm -rf node_modules || true - popd &> /dev/null - fi -fi +%post +if [ -x %{_install_path}/startup.sh ]; then %{_install_path}/startup.sh; fi + +%preun +if [ $1 == 0 -a -x %{_install_path}/cleanup.sh ]; then %{_install_path}/cleanup.sh; fi %changelog * Mon Mar 10 2020 SGX Team diff --git a/QuoteGeneration/installer/linux/rpm/tdx-qgs/build.sh b/QuoteGeneration/installer/linux/rpm/tdx-qgs/build.sh new file mode 100755 index 00000000..35cea473 --- /dev/null +++ b/QuoteGeneration/installer/linux/rpm/tdx-qgs/build.sh @@ -0,0 +1,95 @@ +#!/usr/bin/env bash +# +# Copyright (C) 2011-2021 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}/installer/linux" +LINUX_INSTALLER_COMMON_DIR="${LINUX_INSTALLER_DIR}/common" +LINUX_INSTALLER_COMMON_TDX_QGS_DIR="${LINUX_INSTALLER_COMMON_DIR}/tdx-qgs" + +source ${LINUX_INSTALLER_COMMON_TDX_QGS_DIR}/installConfig + +SGX_VERSION=$(awk '/STRFILEVER/ {print $3}' ${ROOT_DIR}/common/inc/internal/se_version.h|sed 's/^\"\(.*\)\"$/\1/') +RPM_BUILD_FOLDER=${TDX_QGS_PACKAGE_NAME}-${SGX_VERSION} + +main() { + pre_build + update_spec + create_upstream_tarball + build_rpm_package + post_build +} + +pre_build() { + rm -fR ${SCRIPT_DIR}/${RPM_BUILD_FOLDER} + mkdir -p ${SCRIPT_DIR}/${RPM_BUILD_FOLDER}/{BUILD,RPMS,SOURCES,SPECS,SRPMS} + cp -f ${SCRIPT_DIR}/${TDX_QGS_PACKAGE_NAME}.spec ${SCRIPT_DIR}/${RPM_BUILD_FOLDER}/SPECS +} + +post_build() { + for FILE in $(find ${SCRIPT_DIR}/${RPM_BUILD_FOLDER} -name "*.rpm" 2> /dev/null); do + cp "${FILE}" ${SCRIPT_DIR} + done + rm -fR ${SCRIPT_DIR}/${RPM_BUILD_FOLDER} +} + +update_spec() { + min_version="4.12" + rpm_version=$(rpmbuild --version 2> /dev/null | awk '{print $NF}') + cur_version=$(echo -e "${rpm_version}\n${min_version}" | sort -V | head -n 1) + pushd ${SCRIPT_DIR}/${RPM_BUILD_FOLDER} + sed -i "s#@version@#${SGX_VERSION}#" SPECS/${TDX_QGS_PACKAGE_NAME}.spec + sed -i "s#@install_path@#${TDX_QGS_PACKAGE_PATH}/${TDX_QGS_PACKAGE_NAME}#" SPECS/${TDX_QGS_PACKAGE_NAME}.spec + if [ "${min_version}" != "${cur_version}" ]; then + sed -i "s/^Recommends:/Requires: /" SPECS/${TDX_QGS_PACKAGE_NAME}.spec + fi + popd +} + +create_upstream_tarball() { + ${LINUX_INSTALLER_COMMON_TDX_QGS_DIR}/createTarball.sh + tar -xvf ${LINUX_INSTALLER_COMMON_TDX_QGS_DIR}/output/${TARBALL_NAME} -C ${SCRIPT_DIR}/${RPM_BUILD_FOLDER}/SOURCES + pushd ${SCRIPT_DIR}/${RPM_BUILD_FOLDER}/SOURCES + tar -zcvf ${RPM_BUILD_FOLDER}$(echo ${TARBALL_NAME}|awk -F'.' '{print "."$(NF-1)"."$(NF)}') * + popd +} + +build_rpm_package() { + pushd ${SCRIPT_DIR}/${RPM_BUILD_FOLDER} + rpmbuild --define="_topdir `pwd`" --define='_debugsource_template %{nil}' -ba SPECS/${TDX_QGS_PACKAGE_NAME}.spec + popd +} + +main $@ diff --git a/QuoteGeneration/installer/linux/rpm/tdx-qgs/clean.sh b/QuoteGeneration/installer/linux/rpm/tdx-qgs/clean.sh new file mode 100755 index 00000000..ba1c5cfe --- /dev/null +++ b/QuoteGeneration/installer/linux/rpm/tdx-qgs/clean.sh @@ -0,0 +1,41 @@ +#!/usr/bin/env bash +# +# Copyright (C) 2011-2021 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") +COMMON_DIR="${SCRIPT_DIR}/../../common/tdx-qgs" + +rm -f ${SCRIPT_DIR}/tdx-qgs*.rpm +rm -f ${COMMON_DIR}/gen_source.py +rm -rf ${COMMON_DIR}/output diff --git a/QuoteGeneration/installer/linux/rpm/tdx-qgs/tdx-qgs.spec b/QuoteGeneration/installer/linux/rpm/tdx-qgs/tdx-qgs.spec new file mode 100644 index 00000000..e602a23f --- /dev/null +++ b/QuoteGeneration/installer/linux/rpm/tdx-qgs/tdx-qgs.spec @@ -0,0 +1,72 @@ +# +# Copyright (C) 2011-2019 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. +# +# + +%define _install_path @install_path@ + +Name: tdx-qgs +Version: @version@ +Release: 1%{?dist} +Summary: Intel(R) TD Quoting Generation Service +Group: Development/System + +License: BSD License +URL: https://github.com/intel/linux-sgx +Source0: %{name}-%{version}.tar.gz + +%description +Intel(R) TD Quoting Generation Service + +%prep +%setup -qc + +%build +make %{?_smp_mflags} + +%install +make DESTDIR=%{?buildroot} install +echo "%{_install_path}" > %{_specdir}/list-%{name} +find %{?buildroot} | sort | \ +awk '$0 !~ last "/" {print last} {last=$0} END {print last}' | \ +sed -e "s#^%{?buildroot}##" | \ +grep -v "^%{_install_path}" >> %{_specdir}/list-%{name} || : +sed -i 's#^/etc/qgsd.conf#%config &#' %{_specdir}/list-%{name} + +%files -f %{_specdir}/list-%{name} + +%post +if [ -x %{_install_path}/startup.sh ]; then %{_install_path}/startup.sh; fi + +%preun +if [ -x %{_install_path}/cleanup.sh ]; then %{_install_path}/cleanup.sh; fi + +%changelog +* Thu Feb 18 2021 SGX Team +- Initial Release diff --git a/QuoteGeneration/installer/win/DCAP_Components.bat b/QuoteGeneration/installer/win/DCAP_Components.bat index a32befc9..98f6c945 100644 --- a/QuoteGeneration/installer/win/DCAP_Components.bat +++ b/QuoteGeneration/installer/win/DCAP_Components.bat @@ -5,7 +5,7 @@ set QGFOLDER="..\..\" set QVFOLDER="%TOPFOLDER%\QuoteVerification" set DEBUGFILEFOLDER="..\..\..\x64\Debug\" set RELEASEFILEFOLDER="..\..\..\x64\Release\" -set PACKAGETNAME=DCAP_Components.1.11.100.0 +set PACKAGETNAME=DCAP_Components.1.14.100.0 set pwd=%~dp0DCAP_Components pushd "%~dp0" diff --git a/QuoteGeneration/installer/win/DCAP_Components/DCAP_Components.nuspec b/QuoteGeneration/installer/win/DCAP_Components/DCAP_Components.nuspec index ca6e1abe..f9b3dd28 100644 --- a/QuoteGeneration/installer/win/DCAP_Components/DCAP_Components.nuspec +++ b/QuoteGeneration/installer/win/DCAP_Components/DCAP_Components.nuspec @@ -2,7 +2,7 @@ DCAP_Components - 1.13.100.4 + 1.14.100.3 DCAP Components Intel(R) SGX Intel @@ -10,7 +10,7 @@ DCAP Components Copyright (C) 2022 Intel Corporation - + diff --git a/QuoteGeneration/installer/win/Dcap/dcap_copy_file.bat b/QuoteGeneration/installer/win/Dcap/dcap_copy_file.bat index f0c85f0d..8bac9482 100644 --- a/QuoteGeneration/installer/win/Dcap/dcap_copy_file.bat +++ b/QuoteGeneration/installer/win/Dcap/dcap_copy_file.bat @@ -27,6 +27,7 @@ echo * Copy needed files * echo ************************************************** copy /y "%PREBUILTFILEFOLDER%\pce.signed.dll" "%~dp0output\pce.signed.dll" copy /y "%PREBUILTFILEFOLDER%\qe3.signed.dll" "%~dp0output\qe3.signed.dll" +copy /y "%PREBUILTFILEFOLDER%\id_enclave.signed.dll" "%~dp0output\id_enclave.signed.dll" copy /y "%RELEASEFILEFOLDER%\sgx_dcap_ql.dll" "%~dp0output\sgx_dcap_ql.dll" copy /y "%PREBUILTFILEFOLDER%\qve.signed.dll" "%~dp0output\qve.signed.dll" diff --git a/QuoteGeneration/installer/win/Dcap/dcap_generate.bat b/QuoteGeneration/installer/win/Dcap/dcap_generate.bat index bd4993ca..d7bad317 100644 --- a/QuoteGeneration/installer/win/Dcap/dcap_generate.bat +++ b/QuoteGeneration/installer/win/Dcap/dcap_generate.bat @@ -26,7 +26,7 @@ copy /y "%~dp0\sgx_dcap_default.inf" "%~dp0output\sgx_dcap.inf" copy /y "%~dp0\sgx_dcap_dev_default.inf" "%~dp0output\sgx_dcap_dev.inf" "%WindowsSdkDir%\bin\x86\stampinf.exe" -f "%~dp0output\sgx_dcap.inf" -k "1.9" -d "*" -a "amd64" -v "%1" -c "sgx_dcap.cat" "%WindowsSdkDir%\bin\x86\stampinf.exe" -f "%~dp0output\sgx_dcap_dev.inf" -k "1.9" -d "*" -a "amd64" -v "%1" -c "sgx_dcap_dev.cat" -"%WindowsSdkDir%\bin\x86\Inf2Cat.exe" /driver:"%~dp0output" /os:"10_x64" +"%WindowsSdkDir%\bin\x86\Inf2Cat.exe" /driver:"%~dp0output" /os:"10_x64" /uselocaltime echo ************************************************** echo * Signing INF installer * diff --git a/QuoteGeneration/installer/win/Dcap/sgx_dcap_default.inf b/QuoteGeneration/installer/win/Dcap/sgx_dcap_default.inf index b25a77b9..f17a2501 100644 --- a/QuoteGeneration/installer/win/Dcap/sgx_dcap_default.inf +++ b/QuoteGeneration/installer/win/Dcap/sgx_dcap_default.inf @@ -46,6 +46,7 @@ AddService = , %SPSVCINST_ASSOCSERVICE% [SgxDCAPComponentsDevice_CopyFiles] sgx_dcap_ql.dll qe3.signed.dll +id_enclave.signed.dll pce.signed.dll qve.signed.dll sgx_dcap_quoteverify.dll @@ -57,6 +58,7 @@ ThirdPartyLicenses.txt [SourceDisksFiles] sgx_dcap_ql.dll = 1 qe3.signed.dll = 1 +id_enclave.signed.dll = 1 pce.signed.dll = 1 qve.signed.dll = 1 sgx_dcap_quoteverify.dll = 1 diff --git a/QuoteGeneration/installer/win/Dcap/sgx_dcap_dev_default.inf b/QuoteGeneration/installer/win/Dcap/sgx_dcap_dev_default.inf index 9aa618a4..708defdf 100644 --- a/QuoteGeneration/installer/win/Dcap/sgx_dcap_dev_default.inf +++ b/QuoteGeneration/installer/win/Dcap/sgx_dcap_dev_default.inf @@ -49,6 +49,7 @@ AddService = , %SPSVCINST_ASSOCSERVICE% [SgxDCAPComponentsDevice_CopyFiles] sgx_dcap_ql.dll qe3.signed.dll +id_enclave.signed.dll pce.signed.dll qve.signed.dll sgx_dcap_quoteverify.dll @@ -60,6 +61,7 @@ ThirdPartyLicenses.txt [SourceDisksFiles] sgx_dcap_ql.dll = 1 qe3.signed.dll = 1 +id_enclave.signed.dll = 1 pce.signed.dll = 1 qve.signed.dll = 1 sgx_dcap_quoteverify.dll = 1 diff --git a/QuoteGeneration/pccs/cleanup.sh b/QuoteGeneration/pccs/cleanup.sh index 6719270c..7a9e827b 100755 --- a/QuoteGeneration/pccs/cleanup.sh +++ b/QuoteGeneration/pccs/cleanup.sh @@ -38,7 +38,8 @@ if test $(id -u) -ne 0; then exit 1 fi -rm -rf node_modules +PCCS_HOME=$(readlink -m $(dirname "$0")) +rm -rf ${PCCS_HOME}/node_modules #Remove PCCS system service echo -n "Uninstalling PCCS service ..." diff --git a/QuoteGeneration/pccs/config/test.json b/QuoteGeneration/pccs/config/test.json index 1e11692e..c991b4d1 100644 --- a/QuoteGeneration/pccs/config/test.json +++ b/QuoteGeneration/pccs/config/test.json @@ -1,7 +1,7 @@ { "HTTPS_PORT" : 8082, "hosts" : "0.0.0.0", - "uri": "https://api.trustedservices.intel.com/sgx/certification/v3/", + "uri": "https://api.trustedservices.intel.com/sgx/certification/v4/", "ApiKey": "", "RefreshSchedule": "0 0 1 * * *", "UserTokenHash" : "", diff --git a/QuoteGeneration/pccs/constants/index.js b/QuoteGeneration/pccs/constants/index.js index c52824b6..dce2e346 100644 --- a/QuoteGeneration/pccs/constants/index.js +++ b/QuoteGeneration/pccs/constants/index.js @@ -38,7 +38,6 @@ function define(name, value) { }); } -define('API_VERSION', 3); define('DB_VERSION', 2); define('PLATF_REG_NEW', 0); @@ -58,12 +57,14 @@ define('PROCESSOR_INTERMEDIATE_CERT_ID', 2); define('PROCESSOR_SIGNING_CERT_ID', 3); define('PLATFORM_INTERMEDIATE_CERT_ID', 4); -// Product Type +// Product Type : SGX or TDX define('PROD_TYPE_SGX', 0); +define('PROD_TYPE_TDX', 1); // Enclave Identity IDs define('QE_IDENTITY_ID', 1); define('QVE_IDENTITY_ID', 2); +define('TDQE_IDENTITY_ID', 3); //CAs define('CA_PROCESSOR', 'PROCESSOR'); @@ -71,6 +72,7 @@ define('CA_PLATFORM', 'PLATFORM'); //Certchain names define('SGX_PCK_CERTIFICATE_ISSUER_CHAIN', 'SGX-PCK-Certificate-Issuer-Chain'); +define('TCB_INFO_ISSUER_CHAIN', 'TCB-Info-Issuer-Chain'); define('SGX_TCB_INFO_ISSUER_CHAIN', 'SGX-TCB-Info-Issuer-Chain'); define('SGX_ENCLAVE_IDENTITY_ISSUER_CHAIN', 'SGX-Enclave-Identity-Issuer-Chain'); define('SGX_PCK_CRL_ISSUER_CHAIN', 'SGX-PCK-CRL-Issuer-Chain'); diff --git a/QuoteGeneration/pccs/container/Dockerfile b/QuoteGeneration/pccs/container/Dockerfile index 57beb763..1e96caa5 100644 --- a/QuoteGeneration/pccs/container/Dockerfile +++ b/QuoteGeneration/pccs/container/Dockerfile @@ -1,7 +1,7 @@ FROM ubuntu:20.04 AS builder # DCAP version (github repo branch, tag or commit hash) -ARG DCAP_VERSION=DCAP_1.13 +ARG DCAP_VERSION=DCAP_1.14 # update and install packages RUN DEBIAN_FRONTEND=noninteractive \ @@ -15,7 +15,7 @@ RUN DEBIAN_FRONTEND=noninteractive \ zip # install node.js -RUN curl -sL https://deb.nodesource.com/setup_14.x | bash - +RUN curl -sL https://deb.nodesource.com/setup_16.x | bash - RUN DEBIAN_FRONTEND=noninteractive apt-get install -yq --no-install-recommends nodejs RUN apt-get clean && rm -rf /var/lib/apt/lists/* diff --git a/QuoteGeneration/pccs/controllers/identityController.js b/QuoteGeneration/pccs/controllers/identityController.js index 132746fb..1a1eff4a 100644 --- a/QuoteGeneration/pccs/controllers/identityController.js +++ b/QuoteGeneration/pccs/controllers/identityController.js @@ -32,12 +32,15 @@ import { identityService } from '../services/index.js'; import PccsStatus from '../constants/pccs_status_code.js'; import Constants from '../constants/index.js'; +import * as appUtil from '../utils/apputil.js'; async function getEnclaveIdentity(req, res, next, enclave_id) { try { // call service + let version = appUtil.get_api_version_from_url(req.originalUrl); let enclaveIdentityJson = await identityService.getEnclaveIdentity( - enclave_id + enclave_id, + version ); // send response @@ -62,3 +65,6 @@ export async function getQveIdentity(req, res, next) { return getEnclaveIdentity(req, res, next, Constants.QVE_IDENTITY_ID); } +export async function getTdQeIdentity(req, res, next) { + return getEnclaveIdentity(req, res, next, Constants.TDQE_IDENTITY_ID); +} diff --git a/QuoteGeneration/pccs/controllers/platformCollateralController.js b/QuoteGeneration/pccs/controllers/platformCollateralController.js index 8c432b39..6cfc4db0 100644 --- a/QuoteGeneration/pccs/controllers/platformCollateralController.js +++ b/QuoteGeneration/pccs/controllers/platformCollateralController.js @@ -31,11 +31,13 @@ import { platformCollateralService } from '../services/index.js'; import PccsStatus from '../constants/pccs_status_code.js'; +import * as appUtil from '../utils/apputil.js'; export async function putPlatformCollateral(req, res, next) { try { // call service - let platf = await platformCollateralService.addPlatformCollateral(req.body); + let version = appUtil.get_api_version_from_url(req.originalUrl); + let platf = await platformCollateralService.addPlatformCollateral(req.body, version); // send response res diff --git a/QuoteGeneration/pccs/controllers/rootcacrlController.js b/QuoteGeneration/pccs/controllers/rootcacrlController.js index f9a134fc..7e306d7e 100644 --- a/QuoteGeneration/pccs/controllers/rootcacrlController.js +++ b/QuoteGeneration/pccs/controllers/rootcacrlController.js @@ -40,7 +40,7 @@ export async function getRootCaCrl(req, res, next) { // send response res .status(PccsStatus.PCCS_STATUS_SUCCESS[0]) - .header('Content-Type', 'application/x-pem-file') + .header('Content-Type', 'application/pkix-crl') .send(rootcacrl); } catch (err) { next(err); diff --git a/QuoteGeneration/pccs/controllers/tcbinfoController.js b/QuoteGeneration/pccs/controllers/tcbinfoController.js index 2cc45347..96460f41 100644 --- a/QuoteGeneration/pccs/controllers/tcbinfoController.js +++ b/QuoteGeneration/pccs/controllers/tcbinfoController.js @@ -33,12 +33,14 @@ import { tcbinfoService } from '../services/index.js'; import PccsError from '../utils/PccsError.js'; import PccsStatus from '../constants/pccs_status_code.js'; import Constants from '../constants/index.js'; +import * as appUtil from '../utils/apputil.js'; async function getTcbInfo(req, res, next, type) { const FMSPC_SIZE = 12; try { // validate request parameters + let version = appUtil.get_api_version_from_url(req.originalUrl); let fmspc = req.query.fmspc; if (fmspc == null || fmspc.length != FMSPC_SIZE) { throw new PccsError(PccsStatus.PCCS_STATUS_INVALID_REQ); @@ -48,14 +50,15 @@ async function getTcbInfo(req, res, next, type) { fmspc = fmspc.toUpperCase(); // call service - let tcbinfoJson = await tcbinfoService.getTcbInfo(type, fmspc); + let tcbinfoJson = await tcbinfoService.getTcbInfo(type, fmspc, version); + let issuerChainName = appUtil.getTcbInfoIssuerChainName(version); // send response res .status(PccsStatus.PCCS_STATUS_SUCCESS[0]) .header( - Constants.SGX_TCB_INFO_ISSUER_CHAIN, - tcbinfoJson[Constants.SGX_TCB_INFO_ISSUER_CHAIN] + issuerChainName, + tcbinfoJson[issuerChainName] ) .header('Content-Type', 'application/json') .send(tcbinfoJson['tcbinfo']); @@ -68,3 +71,6 @@ export async function getSgxTcbInfo(req, res, next) { await getTcbInfo(req, res, next, Constants.PROD_TYPE_SGX); } +export async function getTdxTcbInfo(req, res, next) { + await getTcbInfo(req, res, next, Constants.PROD_TYPE_TDX); +} diff --git a/QuoteGeneration/pccs/dao/enclaveIdentityDao.js b/QuoteGeneration/pccs/dao/enclaveIdentityDao.js index 4345084f..23a08857 100644 --- a/QuoteGeneration/pccs/dao/enclaveIdentityDao.js +++ b/QuoteGeneration/pccs/dao/enclaveIdentityDao.js @@ -34,9 +34,10 @@ import PccsError from '../utils/PccsError.js'; import PccsStatus from '../constants/pccs_status_code.js'; import { EnclaveIdentities, sequelize } from './models/index.js'; -export async function upsertEnclaveIdentity(id, identity) { +export async function upsertEnclaveIdentity(id, identity, version) { return await EnclaveIdentities.upsert({ id: id, + version: version, identity: identity, root_cert_id: Constants.PROCESSOR_ROOT_CERT_ID, signing_cert_id: Constants.PROCESSOR_SIGNING_CERT_ID, @@ -44,16 +45,16 @@ export async function upsertEnclaveIdentity(id, identity) { } //Query EnclaveIdentity -export async function getEnclaveIdentity(id) { +export async function getEnclaveIdentity(id, version) { const sql = 'select a.*,' + ' (select cert from pcs_certificates where id=a.root_cert_id) as root_cert,' + ' (select cert from pcs_certificates where id=a.signing_cert_id) as signing_cert' + ' from enclave_identities a ' + - ' where a.id=$id'; + ' where a.id=$id and a.version=$version'; const enclave_identity = await sequelize.query(sql, { type: sequelize.QueryTypes.SELECT, - bind: { id: id }, + bind: { id: id, version: version }, }); if (enclave_identity.length == 0) return null; else if (enclave_identity.length == 1) { diff --git a/QuoteGeneration/pccs/dao/fmspcTcbDao.js b/QuoteGeneration/pccs/dao/fmspcTcbDao.js index 18284e8b..a4da6f7e 100644 --- a/QuoteGeneration/pccs/dao/fmspcTcbDao.js +++ b/QuoteGeneration/pccs/dao/fmspcTcbDao.js @@ -40,6 +40,7 @@ export async function upsertFmspcTcb(tcbinfoJson) { return await FmspcTcbs.upsert({ type: tcbinfoJson.type, fmspc: tcbinfoJson.fmspc, + version: tcbinfoJson.version, tcbinfo: tcbinfoJson.tcbinfo, root_cert_id: Constants.PROCESSOR_ROOT_CERT_ID, signing_cert_id: Constants.PROCESSOR_SIGNING_CERT_ID, @@ -47,8 +48,8 @@ export async function upsertFmspcTcb(tcbinfoJson) { } //Query TCBInfo by fmspc -export async function getTcbInfo(type, fmspc) { - if (typeof type == 'undefined') { +export async function getTcbInfo(type, fmspc, version) { + if (typeof type == 'undefined' || typeof version == 'undefined') { throw new PccsError(PccsStatus.PCCS_STATUS_INTERNAL_ERROR); } @@ -58,12 +59,14 @@ export async function getTcbInfo(type, fmspc) { ' (select cert from pcs_certificates where id=a.signing_cert_id) as signing_cert' + ' from fmspc_tcbs a ' + ' where a.type=$type' + - ' and a.fmspc=$fmspc'; + ' and a.fmspc=$fmspc' + + ' and a.version=$version'; const tcbinfo = await sequelize.query(sql, { type: sequelize.QueryTypes.SELECT, bind: { type: type, fmspc: fmspc, + version: version, }, }); if (tcbinfo.length == 0) return null; diff --git a/QuoteGeneration/pccs/dao/models/enclave_identities.js b/QuoteGeneration/pccs/dao/models/enclave_identities.js index a0d77d0c..5dfb9d5d 100644 --- a/QuoteGeneration/pccs/dao/models/enclave_identities.js +++ b/QuoteGeneration/pccs/dao/models/enclave_identities.js @@ -35,6 +35,7 @@ export default class EnclaveIdentities extends Sequelize.Model { super.init( { id: { type: Sequelize.DataTypes.INTEGER, primaryKey: true }, + version: { type: Sequelize.DataTypes.INTEGER, primaryKey: true }, identity: { type: Sequelize.DataTypes.BLOB }, root_cert_id: { type: Sequelize.DataTypes.INTEGER }, signing_cert_id: { type: Sequelize.DataTypes.INTEGER }, diff --git a/QuoteGeneration/pccs/dao/models/fmspc_tcbs.js b/QuoteGeneration/pccs/dao/models/fmspc_tcbs.js index b358d2ce..076eadbf 100644 --- a/QuoteGeneration/pccs/dao/models/fmspc_tcbs.js +++ b/QuoteGeneration/pccs/dao/models/fmspc_tcbs.js @@ -36,6 +36,7 @@ export default class FmspcTcbs extends Sequelize.Model { { fmspc: { type: Sequelize.DataTypes.STRING, primaryKey: true }, type: { type: Sequelize.DataTypes.INTEGER, primaryKey: true }, + version: { type: Sequelize.DataTypes.INTEGER, primaryKey: true }, tcbinfo: { type: Sequelize.DataTypes.BLOB }, root_cert_id: { type: Sequelize.DataTypes.INTEGER }, signing_cert_id: { type: Sequelize.DataTypes.INTEGER }, diff --git a/QuoteGeneration/pccs/install.bat b/QuoteGeneration/pccs/install.bat index 195db158..215ebd29 100644 --- a/QuoteGeneration/pccs/install.bat +++ b/QuoteGeneration/pccs/install.bat @@ -6,7 +6,7 @@ echo Install npm packages ...... call npm install -call npm install node-windows -g +call npm install node-windows@1.0.0-beta.6 -g call npm link node-windows diff --git a/QuoteGeneration/pccs/middleware/auth.js b/QuoteGeneration/pccs/middleware/auth.js index 240ff305..4bdb4580 100644 --- a/QuoteGeneration/pccs/middleware/auth.js +++ b/QuoteGeneration/pccs/middleware/auth.js @@ -31,7 +31,7 @@ import Config from 'config'; import Crypto from 'crypto'; import PccsStatus from '../constants/pccs_status_code.js'; -import Constants from '../constants/index.js'; +import PccsError from '../utils/PccsError.js'; export function validateUser(req, res, next) { const HTTP_HEADER_USER_TOKEN = 'user-token'; @@ -42,16 +42,12 @@ export function validateUser(req, res, next) { let user_token_hash = hash.digest('hex'); if (user_token_hash != Config.get('UserTokenHash')) { - return res - .status(PccsStatus.PCCS_STATUS_UNAUTHORIZED[0]) - .send(PccsStatus.PCCS_STATUS_UNAUTHORIZED[1]); + throw new PccsError(PccsStatus.PCCS_STATUS_UNAUTHORIZED); } else { next(); } } else { - res - .status(PccsStatus.PCCS_STATUS_UNAUTHORIZED[0]) - .send(PccsStatus.PCCS_STATUS_UNAUTHORIZED[1]); + throw new PccsError(PccsStatus.PCCS_STATUS_UNAUTHORIZED); } } @@ -64,15 +60,11 @@ export function validateAdmin(req, res, next) { let admin_token_hash = hash.digest('hex'); if (admin_token_hash != Config.get('AdminTokenHash')) { - return res - .status(PccsStatus.PCCS_STATUS_UNAUTHORIZED[0]) - .send(PccsStatus.PCCS_STATUS_UNAUTHORIZED[1]); + throw new PccsError(PccsStatus.PCCS_STATUS_UNAUTHORIZED); } else { next(); } } else { - res - .status(PccsStatus.PCCS_STATUS_UNAUTHORIZED[0]) - .send(PccsStatus.PCCS_STATUS_UNAUTHORIZED[1]); + throw new PccsError(PccsStatus.PCCS_STATUS_UNAUTHORIZED); } } diff --git a/QuoteGeneration/pccs/migrations/03_db_version_3.js b/QuoteGeneration/pccs/migrations/03_db_version_3.js new file mode 100644 index 00000000..23a7defa --- /dev/null +++ b/QuoteGeneration/pccs/migrations/03_db_version_3.js @@ -0,0 +1,87 @@ +/* + * Copyright (C) 2011-2021 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. + * + */ +import logger from '../utils/Logger.js'; + +async function up(sequelize) { + await sequelize.transaction(async (t) => { + logger.info('DB Migration (Ver.2 -> 3) -- Start'); + + // update pcs_version table + logger.debug('DB Migration -- Update pcs_version table'); + let sql = 'UPDATE pcs_version SET db_version=3,api_version=4'; + await sequelize.query(sql); + + // update fmspc_tcbs table + // this is done by 1.Create new table 2.Copy data 3.Drop old table 4.Rename new into old + logger.debug('DB Migration -- update fmspc_tcbs'); + sql = + 'CREATE TABLE IF NOT EXISTS fmspc_tcbs_temp (fmspc VARCHAR(255) NOT NULL, type INTEGER NOT NULL, version INTEGER NOT NULL, ' + + ' tcbinfo BLOB, root_cert_id INTEGER, signing_cert_id INTEGER, ' + + ' created_time DATETIME NOT NULL, updated_time DATETIME NOT NULL, PRIMARY KEY(fmspc, type, version));'; + await sequelize.query(sql); + + sql = + 'INSERT INTO fmspc_tcbs_temp (fmspc, type, version, tcbinfo, root_cert_id, signing_cert_id, created_time, updated_time) ' + + ' SELECT fmspc, 0 as type, 3 as version, tcbinfo, root_cert_id, signing_cert_id, created_time, updated_time ' + + ' FROM fmspc_tcbs '; + await sequelize.query(sql); + + sql = 'DROP TABLE fmspc_tcbs'; + await sequelize.query(sql); + + sql = 'ALTER TABLE fmspc_tcbs_temp RENAME TO fmspc_tcbs'; + await sequelize.query(sql); + + // update enclave_identities table + // this is done by 1.Create new table 2.Copy data 3.Drop old table 4.Rename new into old + logger.debug('DB Migration -- update enclave_identities'); + sql = + 'CREATE TABLE IF NOT EXISTS enclave_identities_temp (id INTEGER NOTE NULL, version INTEGER NOT NULL, identity BLOB, root_cert_id INTEGER, ' + + ' signing_cert_id INTEGER, created_time DATETIME NOT NULL, updated_time DATETIME NOT NULL, PRIMARY KEY(id, version));'; + await sequelize.query(sql); + + sql = + 'INSERT INTO enclave_identities_temp (id, version, identity, root_cert_id, signing_cert_id, created_time, updated_time) ' + + ' SELECT id, 3 as version, identity, root_cert_id, signing_cert_id, created_time, updated_time ' + + ' FROM enclave_identities '; + await sequelize.query(sql); + + sql = 'DROP TABLE enclave_identities'; + await sequelize.query(sql); + + sql = 'ALTER TABLE enclave_identities_temp RENAME TO enclave_identities'; + await sequelize.query(sql); + + logger.info('DB Migration -- Done.'); + }); +} + +export default { up }; diff --git a/QuoteGeneration/pccs/package.json b/QuoteGeneration/pccs/package.json index 665408b7..23a29a26 100644 --- a/QuoteGeneration/pccs/package.json +++ b/QuoteGeneration/pccs/package.json @@ -1,14 +1,14 @@ { "name": "PCCS", "description": "Provisioning Certificate Caching Service", - "version": "1.13.0", + "version": "1.14.0", "dependencies": { "@fidm/x509": "^1.2.1", "ajv": "^6.12.4", "body-parser": "^1.19.0", "caw": "^2.0.1", "cls-hooked": "^4.2.2", - "config": "^3.3.1", + "config": "^3.3.7", "esm": "^3.2.25", "express": "^4.17.1", "ffi-napi": "^4.0.3", @@ -18,8 +18,8 @@ "node-schedule": "^2.1.0", "ref-array-di": "^1.2.2", "ref-napi": "^3.0.3", - "sequelize": "^6.6.5", - "sqlite3": "npm:@vscode/sqlite3@^5.0.7", + "sequelize": "^6.19.0", + "sqlite3": "^5.0.6", "umzug": "^2.3.0", "winston": "^3.3.3" }, diff --git a/QuoteGeneration/pccs/pccs_server.js b/QuoteGeneration/pccs/pccs_server.js index bd50543b..83e436cc 100644 --- a/QuoteGeneration/pccs/pccs_server.js +++ b/QuoteGeneration/pccs/pccs_server.js @@ -31,13 +31,12 @@ */ import Config from 'config'; -import Constants from './constants/index.js'; import morgan from 'morgan'; import express from 'express'; import logger from './utils/Logger.js'; import node_schedule from 'node-schedule'; import body_parser from 'body-parser'; -import { sgxRouter } from './routes/index.js'; +import { sgxRouter, tdxRouter } from './routes/index.js'; import * as fs from 'fs'; import * as https from 'https'; import * as auth from './middleware/auth.js'; @@ -65,6 +64,9 @@ const app = express(); const { urlencoded, json } = body_parser; const { scheduleJob } = node_schedule; + // Get PCS API version from the config file + global.PCS_VERSION = appUtil.get_api_version_from_url(Config.get('uri')); + // startup check if (!appUtil.startup_check()) { logger.endAndExitProcess(); @@ -77,7 +79,7 @@ appUtil.database_check().then((db_init_ok) => { // Change storage file permission if DB is sqlite if (Config.get('DB_CONFIG') == 'sqlite') { - fs.chmod(Config.get('sqlite').options.storage, 0o640, ()=>{}); + fs.chmod(Config.get('sqlite').options.storage, 0o640, () => {}); } // logger @@ -90,44 +92,36 @@ appUtil.database_check().then((db_init_ok) => { app.use(urlencoded({ extended: true })); app.use(json({ limit: '200000kb' })); - // authentication middleware - app.get( - '/sgx/certification/v' + Constants.API_VERSION + '/platforms', - auth.validateAdmin - ); - app.post( - '/sgx/certification/v' + Constants.API_VERSION + '/platforms', - auth.validateUser - ); - app.use( - '/sgx/certification/v' + Constants.API_VERSION + '/platformcollateral', - auth.validateAdmin - ); - app.use( - '/sgx/certification/v' + Constants.API_VERSION + '/refresh', - auth.validateAdmin - ); + // authentication middleware for v3 + app.get('/sgx/certification/v3/platforms', auth.validateAdmin); + app.post('/sgx/certification/v3/platforms', auth.validateUser); + app.use('/sgx/certification/v3/platformcollateral', auth.validateAdmin); + app.use('/sgx/certification/v3/refresh', auth.validateAdmin); + if (global.PCS_VERSION == 4) { + // authentication middleware for v4 + app.get('/sgx/certification/v4/platforms', auth.validateAdmin); + app.post('/sgx/certification/v4/platforms', auth.validateUser); + app.use('/sgx/certification/v4/platformcollateral', auth.validateAdmin); + app.use('/sgx/certification/v4/refresh', auth.validateAdmin); + } // router - app.use('/sgx/certification/v' + Constants.API_VERSION, sgxRouter); + app.use('/sgx/certification/v3', sgxRouter); + if (global.PCS_VERSION == 4) { + app.use('/sgx/certification/v4', sgxRouter); + app.use('/tdx/certification/v4', tdxRouter); + } // error handling middleware app.use(error.errorHandling); - //Config Options - const CONFIG_OPTION_CACHE_FILL_MODE = 'CachingFillMode'; - //Config values - const CACHE_FILL_MODE_LAZY = 'LAZY'; - const CACHE_FILL_MODE_REQ = 'REQ'; - const CACHE_FILL_MODE_OFFLINE = 'OFFLINE'; - // set caching mode - let cacheMode = Config.get(CONFIG_OPTION_CACHE_FILL_MODE); - if (cacheMode == CACHE_FILL_MODE_LAZY) { + let cacheMode = Config.get('CachingFillMode'); + if (cacheMode == 'LAZY') { cachingModeManager.cachingMode = new LazyCachingMode(); - } else if (cacheMode == CACHE_FILL_MODE_REQ) { + } else if (cacheMode == 'REQ') { cachingModeManager.cachingMode = new ReqCachingMode(); - } else if (cacheMode == CACHE_FILL_MODE_OFFLINE) { + } else if (cacheMode == 'OFFLINE') { cachingModeManager.cachingMode = new OfflineCachingMode(); } else { logger.error('Unknown caching mode. Please check your configuration file.'); diff --git a/QuoteGeneration/pccs/pcs_client/pcs_client.js b/QuoteGeneration/pccs/pcs_client/pcs_client.js index 98e99212..5a2e8a1a 100644 --- a/QuoteGeneration/pccs/pcs_client/pcs_client.js +++ b/QuoteGeneration/pccs/pcs_client/pcs_client.js @@ -79,14 +79,15 @@ async function do_request(url, options) { let response = await got(url, options); logger.info('Request-ID is : ' + response.headers['request-id']); + logger.debug('Request URL ' + url); if (response.statusCode != Constants.HTTP_SUCCESS) { - logger.error('Intel PCS server returns error. ' + response.body); + logger.error('Intel PCS server returns error(' + response.statusCode + ').' + response.body); } return response; } catch (err) { - logger.debug(err); + logger.error(err); if (err.response && err.response.headers) { logger.info('Request-ID is : ' + err.response.headers['request-id']); } @@ -94,6 +95,10 @@ async function do_request(url, options) { } } +function getTdxUrl(url) { + return url.replace('/sgx/', '/tdx/'); +} + export async function getCert(enc_ppid, cpusvn, pcesvn, pceid) { const options = { searchParams: { @@ -150,8 +155,8 @@ export async function getPckCrl(ca) { return do_request(Config.get('uri') + 'pckcrl', options); } -export async function getTcb(type, fmspc) { - if (type != Constants.PROD_TYPE_SGX) { +export async function getTcb(type, fmspc, version) { + if (type != Constants.PROD_TYPE_SGX && type != Constants.PROD_TYPE_TDX) { throw new PccsError(PccsStatus.PCCS_STATUS_INTERNAL_ERROR); } @@ -163,14 +168,23 @@ export async function getTcb(type, fmspc) { }; let uri = Config.get('uri') + 'tcb'; + if (type == Constants.PROD_TYPE_TDX) { + uri = getTdxUrl(uri); + } + + if (global.PCS_VERSION == 4 && version == 3) { + // A little tricky here because we need to use the v3 PCS URL though v4 is configured + uri = uri.replace('/v4/', '/v3/'); + } return do_request(uri, options); } -export async function getEnclaveIdentity(enclave_id) { +export async function getEnclaveIdentity(enclave_id, version) { if ( enclave_id != Constants.QE_IDENTITY_ID && - enclave_id != Constants.QVE_IDENTITY_ID + enclave_id != Constants.QVE_IDENTITY_ID && + enclave_id != Constants.TDQE_IDENTITY_ID ) { throw new PccsError(PccsStatus.PCCS_STATUS_INTERNAL_ERROR); } @@ -183,6 +197,13 @@ export async function getEnclaveIdentity(enclave_id) { let uri = Config.get('uri') + 'qe/identity'; if (enclave_id == Constants.QVE_IDENTITY_ID) { uri = Config.get('uri') + 'qve/identity'; + } else if (enclave_id == Constants.TDQE_IDENTITY_ID) { + uri = getTdxUrl(uri); + } + + if (global.PCS_VERSION == 4 && version == 3) { + // A little tricky here because we need to use the v3 PCS URL though v4 is configured + uri = uri.replace('/v4/', '/v3/'); } return do_request(uri, options); diff --git a/QuoteGeneration/pccs/routes/index.js b/QuoteGeneration/pccs/routes/index.js index 869a9d6c..7ee29652 100644 --- a/QuoteGeneration/pccs/routes/index.js +++ b/QuoteGeneration/pccs/routes/index.js @@ -43,6 +43,7 @@ import { // express routes for our API const sgxRouter = Router(); +const tdxRouter = Router(); //---------------- Routes for SGX APIs------------------------------- sgxRouter @@ -73,5 +74,9 @@ sgxRouter .post(refreshController.refreshCache) .get(refreshController.refreshCache); +//---------------- Routes for TDX APIs------------------------------- +tdxRouter.route('/tcb').get(tcbinfoController.getTdxTcbInfo); -export { sgxRouter }; +tdxRouter.route('/qe/identity').get(identityController.getTdQeIdentity); + +export { sgxRouter, tdxRouter }; diff --git a/QuoteGeneration/pccs/services/caching_modes/cachingMode.js b/QuoteGeneration/pccs/services/caching_modes/cachingMode.js index 82ed1864..e2a27eb8 100644 --- a/QuoteGeneration/pccs/services/caching_modes/cachingMode.js +++ b/QuoteGeneration/pccs/services/caching_modes/cachingMode.js @@ -72,7 +72,7 @@ class CachingMode { throw new PccsError(PccsStatus.PCCS_STATUS_PLATFORM_UNKNOWN); } - async getEnclaveIdentityFromPCS(enclave_id) { + async getEnclaveIdentityFromPCS(enclave_id, version) { throw new PccsError(PccsStatus.PCCS_STATUS_NO_CACHE_DATA); } @@ -84,7 +84,7 @@ class CachingMode { throw new PccsError(PccsStatus.PCCS_STATUS_NO_CACHE_DATA); } - async getTcbInfoFromPCS(type, fmspc) { + async getTcbInfoFromPCS(type, fmspc, version) { throw new PccsError(PccsStatus.PCCS_STATUS_NO_CACHE_DATA); } @@ -133,8 +133,8 @@ export class LazyCachingMode extends CachingMode { ); } - async getEnclaveIdentityFromPCS(enclave_id) { - return await CommonCacheLogic.getEnclaveIdentityFromPCS(enclave_id); + async getEnclaveIdentityFromPCS(enclave_id, version) { + return await CommonCacheLogic.getEnclaveIdentityFromPCS(enclave_id, version); } async getPckCrlFromPCS(ca) { @@ -149,8 +149,8 @@ export class LazyCachingMode extends CachingMode { return await CommonCacheLogic.getCrlFromPCS(uri); } - async getTcbInfoFromPCS(type, fmspc) { - return await CommonCacheLogic.getTcbInfoFromPCS(type, fmspc); + async getTcbInfoFromPCS(type, fmspc, version) { + return await CommonCacheLogic.getTcbInfoFromPCS(type, fmspc, version); } isRefreshable() { diff --git a/QuoteGeneration/pccs/services/caching_modes/cachingModeManager.js b/QuoteGeneration/pccs/services/caching_modes/cachingModeManager.js index c721d027..e0443ce0 100644 --- a/QuoteGeneration/pccs/services/caching_modes/cachingModeManager.js +++ b/QuoteGeneration/pccs/services/caching_modes/cachingModeManager.js @@ -61,8 +61,8 @@ class CachingModeManager { ); } - async getEnclaveIdentityFromPCS(enclave_id) { - return this._mode.getEnclaveIdentityFromPCS(enclave_id); + async getEnclaveIdentityFromPCS(enclave_id, version) { + return this._mode.getEnclaveIdentityFromPCS(enclave_id, version); } async getPckCrlFromPCS(ca) { @@ -73,8 +73,8 @@ class CachingModeManager { return this._mode.getRootCACrlFromPCS(rootca); } - async getTcbInfoFromPCS(type, fmspc) { - return this._mode.getTcbInfoFromPCS(type, fmspc); + async getTcbInfoFromPCS(type, fmspc, version) { + return this._mode.getTcbInfoFromPCS(type, fmspc, version); } isRefreshable() { diff --git a/QuoteGeneration/pccs/services/identityService.js b/QuoteGeneration/pccs/services/identityService.js index c00b3c62..755ba43b 100644 --- a/QuoteGeneration/pccs/services/identityService.js +++ b/QuoteGeneration/pccs/services/identityService.js @@ -32,14 +32,15 @@ import Constants from '../constants/index.js'; import * as enclaveIdentityDao from '../dao/enclaveIdentityDao.js'; import { cachingModeManager } from './caching_modes/cachingModeManager.js'; -export async function getEnclaveIdentity(enclave_id) { +export async function getEnclaveIdentity(enclave_id, version) { // query enclave identity from local database first const enclaveIdentity = await enclaveIdentityDao.getEnclaveIdentity( - enclave_id + enclave_id, + version ); let result = {}; if (enclaveIdentity == null) { - result = await cachingModeManager.getEnclaveIdentityFromPCS(enclave_id); + result = await cachingModeManager.getEnclaveIdentityFromPCS(enclave_id, version); } else { result[Constants.SGX_ENCLAVE_IDENTITY_ISSUER_CHAIN] = enclaveIdentity.signing_cert + enclaveIdentity.root_cert; diff --git a/QuoteGeneration/pccs/services/logic/commonCacheLogic.js b/QuoteGeneration/pccs/services/logic/commonCacheLogic.js index 3b968bb0..1459671d 100644 --- a/QuoteGeneration/pccs/services/logic/commonCacheLogic.js +++ b/QuoteGeneration/pccs/services/logic/commonCacheLogic.js @@ -32,6 +32,7 @@ import PccsError from '../../utils/PccsError.js'; import PccsStatus from '../../constants/pccs_status_code.js'; import Constants from '../../constants/index.js'; import logger from '../../utils/Logger.js'; +import X509 from '../../x509/x509.js'; import * as pckcertDao from '../../dao/pckcertDao.js'; import * as pckCertchainDao from '../../dao/pckCertchainDao.js'; import * as platformTcbsDao from '../../dao/platformTcbsDao.js'; @@ -43,8 +44,8 @@ import * as platformsDao from '../../dao/platformsDao.js'; import * as crlCacheDao from '../../dao/crlCacheDao.js'; import * as pcsClient from '../../pcs_client/pcs_client.js'; import * as pckLibWrapper from '../../lib_wrapper/pcklib_wrapper.js'; +import * as appUtil from '../../utils/apputil.js'; import { sequelize } from '../../dao/models/index.js'; -import X509 from '../../x509/x509.js'; import { cachingModeManager } from '../caching_modes/cachingModeManager.js'; // Try to get PCK certs from Intel PCS for the platform with {pce_id, platform_manifest}, @@ -73,9 +74,9 @@ export async function getPckCertFromPCS( pceid ); } else { - // if enc_ppid is all zero, return NOT_FOUND + // if enc_ppid is all zero, return NO_CACHE_DATA if (enc_ppid.match(/^0+$/)) { - throw new PccsError(PccsStatus.PCCS_STATUS_NOT_FOUND); + throw new PccsError(PccsStatus.PCCS_STATUS_NO_CACHE_DATA); } // Call Intel PCS API with encrypted PPID @@ -84,6 +85,10 @@ export async function getPckCertFromPCS( // check HTTP status if (pck_server_res.statusCode != Constants.HTTP_SUCCESS) { + logger.error( + 'Intel PCS server returns error. Error code : ' + + pck_server_res.statusCode + ); throw new PccsError(PccsStatus.PCCS_STATUS_NO_CACHE_DATA); } @@ -124,7 +129,7 @@ export async function getPckCertFromPCS( } // Make PEM certificates array - let pem_certs = pckcerts_valid.map((o) => unescape(o.cert)); + let pem_certs = pckcerts_valid.map((o) => decodeURIComponent(o.cert)); // Get fmspc and ca type from response header const fmspc = pcsClient @@ -141,8 +146,8 @@ export async function getPckCertFromPCS( throw new PccsError(PccsStatus.PCCS_STATUS_INTERNAL_ERROR); } - // get tcbinfo for this fmspc - pck_server_res = await pcsClient.getTcb(Constants.PROD_TYPE_SGX, fmspc); + // get SGX tcbinfo for this fmspc + pck_server_res = await pcsClient.getTcb(Constants.PROD_TYPE_SGX, fmspc, global.PCS_VERSION); if (pck_server_res.statusCode != Constants.HTTP_SUCCESS) { throw new PccsError(PccsStatus.PCCS_STATUS_NO_CACHE_DATA); } @@ -150,9 +155,18 @@ export async function getPckCertFromPCS( const tcbinfo_str = pck_server_res.body; const tcbinfo_issuer_chain = pcsClient.getHeaderValue( pck_server_res.headers, - Constants.SGX_TCB_INFO_ISSUER_CHAIN + appUtil.getTcbInfoIssuerChainName(global.PCS_VERSION) ); + // also get TDX tcbinfo for this fmspc if it exists + let tcbinfo_tdx = null; + if (global.PCS_VERSION >= 4) { + pck_server_res = await pcsClient.getTcb(Constants.PROD_TYPE_TDX, fmspc, global.PCS_VERSION); + if (pck_server_res.statusCode == Constants.HTTP_SUCCESS) { + tcbinfo_tdx = pck_server_res.rawBody; + } + } + // Before we flush the caching database, get current raw TCBs that are already cached // We need to re-run PCK cert selection tool for existing raw TCB levels due to certs change let cached_platform_tcbs = await platformTcbsDao.getPlatformTcbsById( @@ -178,7 +192,7 @@ export async function getPckCertFromPCS( qeid, pceid, pckcert.tcbm, - unescape(pckcert.cert) + decodeURIComponent(pckcert.cert) ); } @@ -189,8 +203,17 @@ export async function getPckCertFromPCS( await fmspcTcbDao.upsertFmspcTcb({ type: Constants.PROD_TYPE_SGX, fmspc: fmspc, + version: global.PCS_VERSION, tcbinfo: tcbinfo, }); + if (tcbinfo_tdx) { + await fmspcTcbDao.upsertFmspcTcb({ + type: Constants.PROD_TYPE_TDX, + fmspc: fmspc, + version: global.PCS_VERSION, + tcbinfo: tcbinfo_tdx, + }); + } // Update or insert PCK Certchain await pckCertchainDao.upsertPckCertchain(ca_type); // Update or insert PCS certificates @@ -289,17 +312,18 @@ export async function getPckCrlFromPCS(ca) { return result; } -export async function getTcbInfoFromPCS(type, fmspc) { - const pck_server_res = await pcsClient.getTcb(type, fmspc); +export async function getTcbInfoFromPCS(type, fmspc, version) { + const pck_server_res = await pcsClient.getTcb(type, fmspc, version); if (pck_server_res.statusCode != Constants.HTTP_SUCCESS) { throw new PccsError(PccsStatus.PCCS_STATUS_NO_CACHE_DATA); } let result = {}; - result[Constants.SGX_TCB_INFO_ISSUER_CHAIN] = pcsClient.getHeaderValue( + let issuerChainName = appUtil.getTcbInfoIssuerChainName(version); + result[issuerChainName] = pcsClient.getHeaderValue( pck_server_res.headers, - Constants.SGX_TCB_INFO_ISSUER_CHAIN + issuerChainName ); result['tcbinfo'] = pck_server_res.rawBody; @@ -308,22 +332,18 @@ export async function getTcbInfoFromPCS(type, fmspc) { await fmspcTcbDao.upsertFmspcTcb({ type: type, fmspc: fmspc, + version: version, tcbinfo: result['tcbinfo'], }); // update or insert certificate chain - await pcsCertificatesDao.upsertTcbInfoIssuerChain( - pcsClient.getHeaderValue( - pck_server_res.headers, - Constants.SGX_TCB_INFO_ISSUER_CHAIN - ) - ); + await pcsCertificatesDao.upsertTcbInfoIssuerChain(result[issuerChainName]); }); return result; } -export async function getEnclaveIdentityFromPCS(enclave_id) { - const pck_server_res = await pcsClient.getEnclaveIdentity(enclave_id); +export async function getEnclaveIdentityFromPCS(enclave_id, version) { + const pck_server_res = await pcsClient.getEnclaveIdentity(enclave_id, version); if (pck_server_res.statusCode != Constants.HTTP_SUCCESS) { throw new PccsError(PccsStatus.PCCS_STATUS_NO_CACHE_DATA); @@ -341,7 +361,8 @@ export async function getEnclaveIdentityFromPCS(enclave_id) { // update or insert QE Identity await enclaveIdentityDao.upsertEnclaveIdentity( enclave_id, - pck_server_res.rawBody + pck_server_res.rawBody, + version ); // update or insert certificate chain await pcsCertificatesDao.upsertEnclaveIdentityIssuerChain( @@ -360,7 +381,8 @@ export async function getRootCACrlFromPCS(rootca) { if (rootca == null) { // Root Cert not cached const pck_server_res = await pcsClient.getEnclaveIdentity( - Constants.QE_IDENTITY_ID + Constants.QE_IDENTITY_ID, + global.PCS_VERSION ); if (pck_server_res.statusCode == Constants.HTTP_SUCCESS) { // update certificates @@ -383,7 +405,7 @@ export async function getRootCACrlFromPCS(rootca) { } const x509 = new X509(); - if (!x509.parseCert(unescape(rootca.cert)) || !x509.cdp_uri) { + if (!x509.parseCert(decodeURIComponent(rootca.cert)) || !x509.cdp_uri) { // Certificate is invalid throw new Error('Invalid PCS certificate!'); } diff --git a/QuoteGeneration/pccs/services/logic/qvCollateralLogic.js b/QuoteGeneration/pccs/services/logic/qvCollateralLogic.js index 213fd229..80e1bee5 100644 --- a/QuoteGeneration/pccs/services/logic/qvCollateralLogic.js +++ b/QuoteGeneration/pccs/services/logic/qvCollateralLogic.js @@ -47,18 +47,63 @@ export async function checkQuoteVerificationCollateral() { // QE identity const qeid = await enclaveIdentityDao.getEnclaveIdentity( - Constants.QE_IDENTITY_ID + Constants.QE_IDENTITY_ID, + global.PCS_VERSION ); if (qeid == null) { - await CommonCacheLogic.getEnclaveIdentityFromPCS(Constants.QE_IDENTITY_ID); + await CommonCacheLogic.getEnclaveIdentityFromPCS( + Constants.QE_IDENTITY_ID, + global.PCS_VERSION + ); } // QVE identity const qveid = await enclaveIdentityDao.getEnclaveIdentity( - Constants.QVE_IDENTITY_ID + Constants.QVE_IDENTITY_ID, + global.PCS_VERSION ); if (qveid == null) { - await CommonCacheLogic.getEnclaveIdentityFromPCS(Constants.QVE_IDENTITY_ID); + await CommonCacheLogic.getEnclaveIdentityFromPCS( + Constants.QVE_IDENTITY_ID, + global.PCS_VERSION + ); } + + if (global.PCS_VERSION == 4) { + // QE identity v3 + const qeid = await enclaveIdentityDao.getEnclaveIdentity( + Constants.QE_IDENTITY_ID, + 3 + ); + if (qeid == null) { + await CommonCacheLogic.getEnclaveIdentityFromPCS( + Constants.QE_IDENTITY_ID, + 3 + ); + } + // QVE identity v3 + const qveid = await enclaveIdentityDao.getEnclaveIdentity( + Constants.QVE_IDENTITY_ID, + 3 + ); + if (qveid == null) { + await CommonCacheLogic.getEnclaveIdentityFromPCS( + Constants.QVE_IDENTITY_ID, + 3 + ); + } + // TD QE identity v4 + const tdqeid = await enclaveIdentityDao.getEnclaveIdentity( + Constants.TDQE_IDENTITY_ID, + 4 + ); + if (tdqeid == null) { + await CommonCacheLogic.getEnclaveIdentityFromPCS( + Constants.TDQE_IDENTITY_ID, + 4 + ); + } + } + // Root CA crl let rootca = await pcsCertificatesDao.getCertificateById( Constants.PROCESSOR_ROOT_CERT_ID diff --git a/QuoteGeneration/pccs/services/pccs_schemas.js b/QuoteGeneration/pccs/services/pccs_schemas.js index 675a7ee0..57955af1 100644 --- a/QuoteGeneration/pccs/services/pccs_schemas.js +++ b/QuoteGeneration/pccs/services/pccs_schemas.js @@ -61,7 +61,7 @@ export const PLATFORM_REG_SCHEMA = { required: ['qe_id', 'pce_id'], }; -export const PLATFORM_COLLATERAL_SCHEMA = { +export const PLATFORM_COLLATERAL_SCHEMA_V3 = { title: 'Platform Registration', description: 'Platform Registration Data Format', type: 'object', @@ -442,3 +442,441 @@ export const PLATFORM_COLLATERAL_SCHEMA = { }, required: ['platforms', 'collaterals'], }; + +export const PLATFORM_COLLATERAL_SCHEMA_V4 = { + title: 'Platform Registration', + description: 'Platform Registration Data Format', + type: 'object', + properties: { + platforms: { + type: 'array', + items: { + 'type:': 'object', + properties: { + qe_id: { + type: 'string', + minLength: 1, + maxLength: 260, + }, + pce_id: { + type: 'string', + pattern: '^[a-fA-F0-9]{4}$', + }, + cpu_svn: { + type: 'string', + pattern: '^[a-fA-F0-9]{32}$|^$', + }, + pce_svn: { + type: 'string', + pattern: '^[a-fA-F0-9]{4}$|^$', + }, + enc_ppid: { + type: 'string', + pattern: '^[a-fA-F0-9]{768}$|^$', + }, + platform_manifest: { + type: 'string', + }, + }, + required: ['qe_id', 'pce_id'], + }, + }, + collaterals: { + type: 'object', + properties: { + pck_certs: { + type: 'array', + items: { + type: 'object', + properties: { + qe_id: { + type: 'string', + minLength: 1, + maxLength: 260, + }, + pce_id: { + type: 'string', + pattern: '^[a-fA-F0-9]{4}$', + }, + enc_ppid: { + type: 'string', + pattern: '^[a-fA-F0-9]{768}$|^$', + }, + platform_manifest: { + type: 'string', + }, + certs: { + type: 'array', + items: { + type: 'object', + properties: { + tcb: { + type: 'object', + properties: { + sgxtcbcomp01svn: { + type: 'integer', + minimum: 0, + maximum: 255, + }, + sgxtcbcomp02svn: { + type: 'integer', + minimum: 0, + maximum: 255, + }, + sgxtcbcomp03svn: { + type: 'integer', + minimum: 0, + maximum: 255, + }, + sgxtcbcomp04svn: { + type: 'integer', + minimum: 0, + maximum: 255, + }, + sgxtcbcomp05svn: { + type: 'integer', + minimum: 0, + maximum: 255, + }, + sgxtcbcomp06svn: { + type: 'integer', + minimum: 0, + maximum: 255, + }, + sgxtcbcomp07svn: { + type: 'integer', + minimum: 0, + maximum: 255, + }, + sgxtcbcomp08svn: { + type: 'integer', + minimum: 0, + maximum: 255, + }, + sgxtcbcomp09svn: { + type: 'integer', + minimum: 0, + maximum: 255, + }, + sgxtcbcomp10svn: { + type: 'integer', + minimum: 0, + maximum: 255, + }, + sgxtcbcomp11svn: { + type: 'integer', + minimum: 0, + maximum: 255, + }, + sgxtcbcomp12svn: { + type: 'integer', + minimum: 0, + maximum: 255, + }, + sgxtcbcomp13svn: { + type: 'integer', + minimum: 0, + maximum: 255, + }, + sgxtcbcomp14svn: { + type: 'integer', + minimum: 0, + maximum: 255, + }, + sgxtcbcomp15svn: { + type: 'integer', + minimum: 0, + maximum: 255, + }, + sgxtcbcomp16svn: { + type: 'integer', + minimum: 0, + maximum: 255, + }, + pcesvn: { + type: 'integer', + minimum: 0, + maximum: 65535, + }, + }, + }, + tcbm: { + type: 'string', + pattern: '^[0-9a-fA-F]{36}$', + }, + cert: { + type: 'string', + }, + }, + required: ['tcb', 'tcbm', 'cert'], + }, + }, + }, + required: ['qe_id', 'pce_id', 'enc_ppid', 'certs'], + }, + }, + tcbinfos: { + type: 'array', + items: { + type: 'object', + properties: { + fmspc: { + type: 'string', + }, + sgx_tcbinfo: { + type: 'object', + properties: { + tcbInfo: { + type: 'object', + properties: { + id: { + const: 'SGX', + }, + version: { + type: 'integer', + }, + issueDate: { + type: 'string', + format: 'date-time', + }, + nextUpdate: { + type: 'string', + format: 'date-time', + }, + fmspc: { + type: 'string', + pattern: '^[0-9a-fA-F]{12}$', + }, + pceId: { + type: 'string', + pattern: '^[0-9a-fA-F]{4}$', + }, + tcbType: { + type: 'integer', + }, + tcbEvaluationDataNumber: { + type: 'integer', + }, + tcbLevels: { + type: 'array', + items: { + type: 'object', + properties: { + tcb: { + type: 'object', + properties: { + sgxtcbcomponents: { + type: 'array', + items: { + type: 'object', + properties: { + svn: { + type: 'integer', + }, + category: { + type: 'string', + }, + type: { + type: 'string', + }, + }, + required: ['svn'], + }, + }, + pcesvn: { + type: 'integer', + }, + }, + required: ['sgxtcbcomponents'], + }, + tcbDate: { + type: 'string', + format: 'date-time', + }, + tcbStatus: { + type: 'string', + }, + advisoryIDs: { + type: 'array', + items: { + type: 'string', + }, + }, + }, + }, + }, + }, + }, + signature: { + type: 'string', + }, + }, + required: ['tcbInfo', 'signature'], + }, + tdx_tcbinfo: { + type: 'object', + properties: { + tcbInfo: { + type: 'object', + properties: { + id: { + const: 'TDX', + }, + version: { + type: 'integer', + }, + issueDate: { + type: 'string', + format: 'date-time', + }, + nextUpdate: { + type: 'string', + format: 'date-time', + }, + fmspc: { + type: 'string', + pattern: '^[0-9a-fA-F]{12}$', + }, + pceId: { + type: 'string', + pattern: '^[0-9a-fA-F]{4}$', + }, + tcbType: { + type: 'integer', + }, + tcbEvaluationDataNumber: { + type: 'integer', + }, + mrsignerseam: { + type: 'string', + }, + tcbLevels: { + type: 'array', + items: { + type: 'object', + properties: { + tcb: { + type: 'object', + properties: { + sgxtcbcomponents: { + type: 'array', + items: { + type: 'object', + properties: { + svn: { + type: 'integer', + }, + category: { + type: 'string', + }, + type: { + type: 'string', + }, + }, + required: ['svn'], + }, + }, + pcesvn: { + type: 'integer', + }, + tdxtcbcomponents: { + type: 'array', + items: { + type: 'object', + properties: { + svn: { + type: 'integer', + }, + category: { + type: 'string', + }, + type: { + type: 'string', + }, + }, + required: ['svn'], + }, + }, + }, + required: ['sgxtcbcomponents'], + }, + tcbDate: { + type: 'string', + format: 'date-time', + }, + tcbStatus: { + type: 'string', + }, + advisoryIDs: { + type: 'array', + items: { + type: 'string', + }, + }, + }, + }, + }, + }, + }, + signature: { + type: 'string', + }, + }, + required: ['tcbInfo', 'signature'], + }, + }, + required: ['fmspc'], + }, + }, + pckcacrl: { + type: 'object', + properties: { + processorCrl: { + type: 'string', + }, + platformCrl: { + type: 'string', + }, + }, + }, + qeidentity: { + type: 'string', + }, + tdqeidentity: { + type: 'string', + }, + qveidentity: { + type: 'string', + }, + certificates: { + type: 'object', + properties: { + 'SGX-PCK-Certificate-Issuer-Chain': { + type: 'object', + properties: { + PROCESSOR: { + type: 'string', + }, + PLATFORM: { + type: 'string', + }, + }, + }, + 'SGX-TCB-Info-Issuer-Chain': { + type: 'string', + }, + 'SGX-Enclave-Identity-Issuer-Chain': { + type: 'string', + }, + }, + required: ['SGX-PCK-Certificate-Issuer-Chain'], + }, + rootcacrl: { + type: 'string', + }, + }, + required: ['pck_certs', 'tcbinfos', 'certificates'], + }, + }, + required: ['platforms', 'collaterals'], +}; diff --git a/QuoteGeneration/pccs/services/pckcertService.js b/QuoteGeneration/pccs/services/pckcertService.js index c7e7d2c1..30c6e69f 100644 --- a/QuoteGeneration/pccs/services/pckcertService.js +++ b/QuoteGeneration/pccs/services/pckcertService.js @@ -60,7 +60,7 @@ export async function pckCertSelection( } // Always use SGX tcb info for PCK cert selection - let tcbinfo = await fmspcTcbDao.getTcbInfo(Constants.PROD_TYPE_SGX, fmspc); + let tcbinfo = await fmspcTcbDao.getTcbInfo(Constants.PROD_TYPE_SGX, fmspc, global.PCS_VERSION); if (tcbinfo == null || tcbinfo.tcbinfo == null) throw new PccsError(PccsStatus.PCCS_STATUS_NO_CACHE_DATA); diff --git a/QuoteGeneration/pccs/services/platformCollateralService.js b/QuoteGeneration/pccs/services/platformCollateralService.js index b67284f4..3dd1e74b 100644 --- a/QuoteGeneration/pccs/services/platformCollateralService.js +++ b/QuoteGeneration/pccs/services/platformCollateralService.js @@ -43,7 +43,8 @@ import * as enclaveIdentityDao from '../dao/enclaveIdentityDao.js'; import * as pckCertchainDao from '../dao/pckCertchainDao.js'; import * as pcsCertificatesDao from '../dao/pcsCertificatesDao.js'; import * as pckLibWrapper from '../lib_wrapper/pcklib_wrapper.js'; -import { PLATFORM_COLLATERAL_SCHEMA } from './pccs_schemas.js'; +import * as appUtil from '../utils/apputil.js'; +import { PLATFORM_COLLATERAL_SCHEMA_V4 } from './pccs_schemas.js'; import { sequelize } from '../dao/models/index.js'; const ajv = new Ajv(); @@ -58,10 +59,13 @@ function verify_cert(root1, root2) { return true; } -export async function addPlatformCollateral(collateralJson) { +export async function addPlatformCollateral(collateralJson, version) { return await sequelize.transaction(async (t) => { //check parameters - let valid = ajv.validate(PLATFORM_COLLATERAL_SCHEMA, collateralJson); + let valid; + if (version < 4) + valid = ajv.validate(PLATFORM_COLLATERAL_SCHEMA_V3, collateralJson); + else valid = ajv.validate(PLATFORM_COLLATERAL_SCHEMA_V4, collateralJson); if (!valid) { throw new PccsError(PccsStatus.PCCS_STATUS_INVALID_REQ); } @@ -80,7 +84,7 @@ export async function addPlatformCollateral(collateralJson) { toUpper(platform_certs.qe_id), toUpper(platform_certs.pce_id), toUpper(cert.tcbm), - unescape(cert.cert) + decodeURIComponent(cert.cert) ); } @@ -133,7 +137,7 @@ export async function addPlatformCollateral(collateralJson) { } // parse arbitary cert to get fmspc value const x509 = new X509(); - if (!x509.parseCert(unescape(mycerts[0].cert))) { + if (!x509.parseCert(decodeURIComponent(mycerts[0].cert))) { logger.error('Invalid certificate format.'); throw new PccsError(PccsStatus.PCCS_STATUS_INVALID_REQ); } @@ -151,14 +155,18 @@ export async function addPlatformCollateral(collateralJson) { throw new PccsError(PccsStatus.PCCS_STATUS_INVALID_REQ); } - let pem_certs = mycerts.map((o) => unescape(o.cert)); + let tcbinfo_str; + if (version < 4) tcbinfo_str = JSON.stringify(tcbinfo.tcbinfo); + else tcbinfo_str = JSON.stringify(tcbinfo.sgx_tcbinfo); + + let pem_certs = mycerts.map((o) => decodeURIComponent(o.cert)); for (let platform of platforms_cleaned) { // get the best cert with PCKCertSelectionTool let cert_index = pckLibWrapper.pck_cert_select( platform.cpu_svn, platform.pce_svn, platform.pce_id, - JSON.stringify(tcbinfo.tcbinfo), + tcbinfo_str, pem_certs, pem_certs.length ); @@ -194,11 +202,24 @@ export async function addPlatformCollateral(collateralJson) { // loop through tcbinfos for (const tcbinfo of tcbinfos) { tcbinfo.fmspc = toUpper(tcbinfo.fmspc); - if (tcbinfo.tcbinfo) { + tcbinfo.version = version; + if (version < 4 && tcbinfo.tcbinfo) { tcbinfo.type = Constants.PROD_TYPE_SGX; tcbinfo.tcbinfo = Buffer.from(JSON.stringify(tcbinfo.tcbinfo)); await fmspcTcbDao.upsertFmspcTcb(tcbinfo); } + if (version >= 4) { + if (tcbinfo.sgx_tcbinfo) { + tcbinfo.type = Constants.PROD_TYPE_SGX; + tcbinfo.tcbinfo = Buffer.from(JSON.stringify(tcbinfo.sgx_tcbinfo)); + await fmspcTcbDao.upsertFmspcTcb(tcbinfo); + } + if (tcbinfo.tdx_tcbinfo) { + tcbinfo.type = Constants.PROD_TYPE_TDX; + tcbinfo.tcbinfo = Buffer.from(JSON.stringify(tcbinfo.tdx_tcbinfo)); + await fmspcTcbDao.upsertFmspcTcb(tcbinfo); + } + } } // Update or insert PCK CRL @@ -219,14 +240,24 @@ export async function addPlatformCollateral(collateralJson) { if (collaterals.qeidentity) { await enclaveIdentityDao.upsertEnclaveIdentity( Constants.QE_IDENTITY_ID, - collaterals.qeidentity + collaterals.qeidentity, + version + ); + } + // Update or insert TDQE Identity + if (collaterals.tdqeidentity) { + await enclaveIdentityDao.upsertEnclaveIdentity( + Constants.TDQE_IDENTITY_ID, + collaterals.tdqeidentity, + version ); } // Update or insert QvE Identity if (collaterals.qveidentity) { await enclaveIdentityDao.upsertEnclaveIdentity( Constants.QVE_IDENTITY_ID, - collaterals.qveidentity + collaterals.qveidentity, + version ); } @@ -271,10 +302,12 @@ export async function addPlatformCollateral(collateralJson) { } } if ( - Boolean(collaterals.certificates[Constants.SGX_TCB_INFO_ISSUER_CHAIN]) + Boolean( + collaterals.certificates[appUtil.getTcbInfoIssuerChainName(version)] + ) ) { rootCert[2] = await pcsCertificatesDao.upsertTcbInfoIssuerChain( - collaterals.certificates[Constants.SGX_TCB_INFO_ISSUER_CHAIN] + collaterals.certificates[appUtil.getTcbInfoIssuerChainName(version)] ); } if ( diff --git a/QuoteGeneration/pccs/services/refreshService.js b/QuoteGeneration/pccs/services/refreshService.js index 7179c6a3..e1f75546 100644 --- a/QuoteGeneration/pccs/services/refreshService.js +++ b/QuoteGeneration/pccs/services/refreshService.js @@ -32,6 +32,7 @@ import PccsError from '../utils/PccsError.js'; import PccsStatus from '../constants/pccs_status_code.js'; import Constants from '../constants/index.js'; import logger from '../utils/Logger.js'; +import X509 from '../x509/x509.js'; import * as pckcertDao from '../dao/pckcertDao.js'; import * as enclaveIdentityDao from '../dao/enclaveIdentityDao.js'; import * as pckcrlDao from '../dao/pckcrlDao.js'; @@ -43,27 +44,52 @@ import * as pcsCertificatesDao from '../dao/pcsCertificatesDao.js'; import * as crlCacheDao from '../dao/crlCacheDao.js'; import * as pcsClient from '../pcs_client/pcs_client.js'; import * as pckLibWrapper from '../lib_wrapper/pcklib_wrapper.js'; +import * as appUtil from '../utils/apputil.js'; import { sequelize } from '../dao/models/index.js'; import { cachingModeManager } from './caching_modes/cachingModeManager.js'; -import X509 from '../x509/x509.js'; // Refresh the enclave_identities table -async function refresh_enclave_identity(enclave_id) { - const pck_server_res = await pcsClient.getEnclaveIdentity(enclave_id); - if (pck_server_res.statusCode == Constants.HTTP_SUCCESS) { - // Then refresh cache DB - await enclaveIdentityDao.upsertEnclaveIdentity( - enclave_id, - pck_server_res.rawBody - ); - await pcsCertificatesDao.upsertEnclaveIdentityIssuerChain( - pcsClient.getHeaderValue( - pck_server_res.headers, - Constants.SGX_ENCLAVE_IDENTITY_ISSUER_CHAIN - ) +async function refresh_enclave_identities() { + let enclave_id_list; + if (global.PCS_VERSION == 3) { + enclave_id_list = [ + [Constants.QE_IDENTITY_ID, 3], + [Constants.QVE_IDENTITY_ID, 3], + ]; + } else if (global.PCS_VERSION == 4) { + enclave_id_list = [ + [Constants.QE_IDENTITY_ID, 3], + [Constants.QVE_IDENTITY_ID, 3], + [Constants.QE_IDENTITY_ID, 4], + [Constants.QVE_IDENTITY_ID, 4], + [Constants.TDQE_IDENTITY_ID, 4], + ]; + } + let issuer_chain_updated = false; // Update issuer chain only once + for (const enclave_id of enclave_id_list) { + const pck_server_res = await pcsClient.getEnclaveIdentity( + enclave_id[0], + enclave_id[1] ); - } else { - throw new PccsError(PccsStatus.PCCS_STATUS_SERVICE_UNAVAILABLE); + if (pck_server_res.statusCode == Constants.HTTP_SUCCESS) { + // Then refresh cache DB + await enclaveIdentityDao.upsertEnclaveIdentity( + enclave_id[0], + pck_server_res.rawBody, + enclave_id[1] + ); + if (!issuer_chain_updated) { + await pcsCertificatesDao.upsertEnclaveIdentityIssuerChain( + pcsClient.getHeaderValue( + pck_server_res.headers, + Constants.SGX_ENCLAVE_IDENTITY_ISSUER_CHAIN + ) + ); + issuer_chain_updated = true; + } + } else { + throw new PccsError(PccsStatus.PCCS_STATUS_SERVICE_UNAVAILABLE); + } } } @@ -152,7 +178,7 @@ async function refresh_all_pckcerts(fmspc_array) { const tcbinfo = pck_server_res.rawBody; tcbinfo_str = pck_server_res.body; - pem_certs = pckcerts.map((o) => unescape(o.cert)); + pem_certs = pckcerts.map((o) => decodeURIComponent(o.cert)); // flush and add PCK certs await pckcertDao.deleteCerts(platformTcb.qe_id, platformTcb.pce_id); @@ -161,7 +187,7 @@ async function refresh_all_pckcerts(fmspc_array) { platformTcb.qe_id, platformTcb.pce_id, pckcert.tcbm, - unescape(pckcert.cert) + decodeURIComponent(pckcert.cert) ); } } @@ -232,11 +258,10 @@ async function refresh_rootca_crl() { let rootca = await pcsCertificatesDao.getCertificateById( Constants.PROCESSOR_ROOT_CERT_ID ); - if (!rootca) - throw new PccsError(PccsStatus.PCCS_STATUS_INTERNAL_ERROR); + if (!rootca) throw new PccsError(PccsStatus.PCCS_STATUS_INTERNAL_ERROR); const x509 = new X509(); - if (!x509.parseCert(unescape(rootca.cert)) || !x509.cdp_uri) { + if (!x509.parseCert(decodeURIComponent(rootca.cert)) || !x509.cdp_uri) { // Certificate is invalid throw new Error('Invalid PCS certificate!'); } @@ -260,20 +285,21 @@ async function refresh_cached_crls() { } // Refresh the TCB info for the specified fmspc value -async function refresh_one_tcb(fmspc) { - const pck_server_res = await pcsClient.getTcb(Constants.PROD_TYPE_SGX, fmspc); +async function refresh_one_tcb(fmspc, type, version) { + const pck_server_res = await pcsClient.getTcb(type, fmspc, version); if (pck_server_res.statusCode == Constants.HTTP_SUCCESS) { // Then refresh cache DB await fmspcTcbDao.upsertFmspcTcb({ + type: type, fmspc: fmspc, - type: Constants.PROD_TYPE_SGX, + version: version, tcbinfo: pck_server_res.rawBody, }); // update or insert certificate chain await pcsCertificatesDao.upsertTcbInfoIssuerChain( pcsClient.getHeaderValue( pck_server_res.headers, - Constants.SGX_TCB_INFO_ISSUER_CHAIN + appUtil.getTcbInfoIssuerChainName(version) ) ); } else { @@ -289,7 +315,7 @@ async function refresh_all_tcbs() { const tcbs = await fmspcTcbDao.getAllTcbs(); for (let tcb of tcbs) { // refresh each tcb - await refresh_one_tcb(tcb.fmspc); + await refresh_one_tcb(tcb.fmspc, tcb.type, tcb.version); } } @@ -306,8 +332,7 @@ export async function refreshCache(type, fmspc) { await sequelize.transaction(async (t) => { await refresh_pck_crls(); await refresh_all_tcbs(); - await refresh_enclave_identity(Constants.QE_IDENTITY_ID); - await refresh_enclave_identity(Constants.QVE_IDENTITY_ID); + await refresh_enclave_identities(); await refresh_rootca_crl(); await refresh_cached_crls(); }); @@ -333,8 +358,7 @@ export async function scheduledRefresh() { await sequelize.transaction(async (t) => { await refresh_pck_crls(); await refresh_all_tcbs(); - await refresh_enclave_identity(Constants.QE_IDENTITY_ID); - await refresh_enclave_identity(Constants.QVE_IDENTITY_ID); + await refresh_enclave_identities(); await refresh_rootca_crl(); await refresh_cached_crls(); }); diff --git a/QuoteGeneration/pccs/services/tcbinfoService.js b/QuoteGeneration/pccs/services/tcbinfoService.js index 609636e1..95724573 100644 --- a/QuoteGeneration/pccs/services/tcbinfoService.js +++ b/QuoteGeneration/pccs/services/tcbinfoService.js @@ -28,19 +28,19 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * */ -import Constants from '../constants/index.js'; import * as fmspcTcbDao from '../dao/fmspcTcbDao.js'; +import * as appUtil from '../utils/apputil.js'; import { cachingModeManager } from './caching_modes/cachingModeManager.js'; -export async function getTcbInfo(type, fmspc) { +export async function getTcbInfo(type, fmspc, version) { // query tcbinfo from local database first - const tcbinfo = await fmspcTcbDao.getTcbInfo(type, fmspc); + const tcbinfo = await fmspcTcbDao.getTcbInfo(type, fmspc, version); let result = {}; if (tcbinfo == null) { - result = await cachingModeManager.getTcbInfoFromPCS(type, fmspc); + result = await cachingModeManager.getTcbInfoFromPCS(type, fmspc, version); } else { - result[Constants.SGX_TCB_INFO_ISSUER_CHAIN] = + result[appUtil.getTcbInfoIssuerChainName(version)] = tcbinfo.signing_cert + tcbinfo.root_cert; result['tcbinfo'] = tcbinfo.tcbinfo; } diff --git a/QuoteGeneration/pccs/startup.sh b/QuoteGeneration/pccs/startup.sh index 4ec6aa3d..c6e99930 100755 --- a/QuoteGeneration/pccs/startup.sh +++ b/QuoteGeneration/pccs/startup.sh @@ -40,11 +40,15 @@ fi PCCS_USER=pccs PCCS_HOME=$(readlink -m $(dirname "$0")) -if [ ! $(getent group $PCCS_USER) ]; then - groupadd $PCCS_USER -fi -if ! id "$PCCS_USER" &>/dev/null; then - adduser --system $PCCS_USER -g $PCCS_USER --home $PCCS_HOME --no-create-home --shell /bin/bash +if [ "$1" == "debian" ]; then + adduser --quiet --system $PCCS_USER --group --home $PCCS_HOME --no-create-home --shell /bin/bash +else + if [ ! $(getent group $PCCS_USER) ]; then + groupadd $PCCS_USER + fi + if ! id "$PCCS_USER" &>/dev/null; then + adduser --system $PCCS_USER -g $PCCS_USER --home $PCCS_HOME --no-create-home --shell /bin/bash + fi fi chown -R $PCCS_USER:$PCCS_USER $PCCS_HOME chmod 640 $PCCS_HOME/config/default.json diff --git a/QuoteGeneration/pccs/utils/apputil.js b/QuoteGeneration/pccs/utils/apputil.js index d50aa3ee..3da918db 100644 --- a/QuoteGeneration/pccs/utils/apputil.js +++ b/QuoteGeneration/pccs/utils/apputil.js @@ -35,22 +35,35 @@ import { sequelize, PcsVersion } from '../dao/models/index.js'; import Umzug from 'umzug'; import * as fs from 'fs'; +export function get_api_version_from_url(url) { + if (!url) return 0; + + let verstr = url.match(/\/v([1-9][0-9]*)\//); + if (!verstr || verstr[0].length < 4) { + throw new Error('Unsupported API version'); + } + let ver = parseInt(verstr[0].substr(2).slice(0, -1)); + if (ver != 3 && ver != 4) { + throw new Error('Unsupported API version'); + } + return ver; +} + +export function getTcbInfoIssuerChainName(version) { + if (version == 3) { + return Constants.SGX_TCB_INFO_ISSUER_CHAIN; + } else { + return Constants.TCB_INFO_ISSUER_CHAIN; + } +} + // Check the version of PCS service currently configured export function startup_check() { - let pcs_api_version; - let pcs_url = Config.get('uri'); - let verstr = pcs_url.match(/\/v([1-9][0-9]*)\//); - if (verstr.length == 0) pcs_api_version = 1; - let ver = verstr[0].substr(2).slice(0, -1); - pcs_api_version = parseInt(ver); - - if (pcs_api_version != Constants.API_VERSION) { + if (global.PCS_VERSION != 3 && global.PCS_VERSION != 4) { logger.error( 'The PCS API version ' + - verstr[0] + - ' configured is not supported. Should be version ' + - Constants.API_VERSION + - '.' + global.PCS_VERSION + + ' configured is not supported. Should be v3 or v4.' ); return false; } diff --git a/QuoteGeneration/pce_wrapper/linux/Makefile b/QuoteGeneration/pce_wrapper/linux/Makefile index de308747..9f73dc14 100644 --- a/QuoteGeneration/pce_wrapper/linux/Makefile +++ b/QuoteGeneration/pce_wrapper/linux/Makefile @@ -31,6 +31,9 @@ include ../../buildenv.mk +PCE_WRAPPER_VER:= $(shell awk '$$2 ~ /PCE_WRAPPER_VERSION/ { print substr($$3, 2, length($$3) - 2); }'\ + $(COMMON_DIR)/inc/internal/se_version.h) + INCLUDE += -I. -I../inc INCLUDE += -I$(SGX_SDK)/include \ -I$(COMMON_DIR)/inc/internal \ @@ -64,6 +67,7 @@ LDUFLAGS += -Wl,--version-script=pce_wrapper.lds -Wl,--gc-sections LIBNAME = libsgx_pce_logic.so STATIC_LIBNAME = libsgx_pce_logic.a +PCE_WRAPPER_SONAME:= $(LIBNAME).$(call SPLIT_VERSION,$(PCE_WRAPPER_VER),1) .PHONY: all all: install_lib @@ -71,9 +75,11 @@ all: install_lib .PHONY: install_lib install_lib: $(LIBNAME) $(STATIC_LIBNAME) | $(BUILD_DIR) @$(CP) $(LIBNAME) $| + @ln -fs $(LIBNAME) $(BUILD_DIR)/$(PCE_WRAPPER_SONAME) $(LIBNAME): $(OBJ) - $(CXX) $(CXXFLAGS) $(OBJ) -shared -Wl,-soname=$@ $(LDUFLAGS) $(Link_Flags) -o $@ + $(CXX) $(CXXFLAGS) $(OBJ) -shared $(LDUFLAGS) $(Link_Flags) \ + -Wl,-soname=$(PCE_WRAPPER_SONAME) -o $@ $(STATIC_LIBNAME): $(OBJ) $(AR) rcsD $@ $^ diff --git a/QuoteGeneration/psw/ae/data/prebuilt/README.md b/QuoteGeneration/psw/ae/data/prebuilt/README.md index 549cd5b1..3ed56647 100644 --- a/QuoteGeneration/psw/ae/data/prebuilt/README.md +++ b/QuoteGeneration/psw/ae/data/prebuilt/README.md @@ -1,11 +1,14 @@ # PCE source code -The PCE is part of Intel(R) Software Guard Extensions for Linux\* OS which is published in [linux-sgx](https://github.com/intel/linux-sgx/) Github repository. The libsgx_pce.signed.so in prebuilt package is built by [pce](https://github.com/intel/linux-sgx/tree/master/psw/ae/pce) with branch [sgx_2.15_reproducible](https://github.com/intel/linux-sgx/tree/sgx_2.15_reproducible) and signed by Intel. +The PCE is part of Intel(R) Software Guard Extensions for Linux\* OS which is published in [linux-sgx](https://github.com/intel/linux-sgx/) Github repository. The libsgx_pce.signed.so in prebuilt package is built by [pce](https://github.com/intel/linux-sgx/tree/master/psw/ae/pce) with branch [sgx_2.17_reproducible](https://github.com/intel/linux-sgx/tree/sgx_2.17_reproducible) and signed by Intel. # QE3 source code -The QE3 is part of [Intel(R) Software Guard Extensions Data Center Attestation Primitives](https://github.com/intel/SGXDataCenterAttestationPrimitives/) Github repository. The libsgx_qe3.signed.so in prebuilt package is built by [qe3](https://github.com/intel/SGXDataCenterAttestationPrimitives/tree/master/QuoteGeneration/quote_wrapper/quote/enclave) with branch [sgx_2.15_reproducible](https://github.com/intel/linux-sgx/tree/sgx_2.15_reproducible) and signed by Intel. +The QE3 is part of [Intel(R) Software Guard Extensions Data Center Attestation Primitives](https://github.com/intel/SGXDataCenterAttestationPrimitives/) Github repository. The libsgx_qe3.signed.so in prebuilt package is built by [qe3](https://github.com/intel/SGXDataCenterAttestationPrimitives/tree/master/QuoteGeneration/quote_wrapper/quote/enclave) with branch [sgx_2.17_reproducible](https://github.com/intel/linux-sgx/tree/sgx_2.17_reproducible) and signed by Intel. # QVE source code -The QVE is part of [Intel(R) Software Guard Extensions Data Center Attestation Primitives](https://github.com/intel/SGXDataCenterAttestationPrimitives/) Github repository. The libsgx_qve.signed.so in prebuilt package is built by [qve](https://github.com/intel/SGXDataCenterAttestationPrimitives/tree/master/QuoteVerification/QvE/Enclave) with branch [sgx_2.16_reproducible](https://github.com/intel/linux-sgx/tree/sgx_2.16_reproducible)and signed by Intel. +The QVE is part of [Intel(R) Software Guard Extensions Data Center Attestation Primitives](https://github.com/intel/SGXDataCenterAttestationPrimitives/) Github repository. The libsgx_qve.signed.so in prebuilt package is built by [qve](https://github.com/intel/SGXDataCenterAttestationPrimitives/tree/master/QuoteVerification/QvE/Enclave) with branch [sgx_2.17_reproducible](https://github.com/intel/linux-sgx/tree/sgx_2.17_reproducible)and signed by Intel. # IDE source code -The IDE is part of [Intel(R) Software Guard Extensions Data Center Attestation Primitives](https://github.com/intel/SGXDataCenterAttestationPrimitives/) Github repository. The libsgx_id_enclave.signed.so in prebuilt package is built by [id_enclave](https://github.com/intel/SGXDataCenterAttestationPrimitives/tree/master/QuoteGeneration/quote_wrapper/quote/id_enclave) with branch [sgx_2.16_reproducible](https://github.com/intel/linux-sgx/tree/sgx_2.16_reproducible) and signed by Intel. +The IDE is part of [Intel(R) Software Guard Extensions Data Center Attestation Primitives](https://github.com/intel/SGXDataCenterAttestationPrimitives/) Github repository. The libsgx_id_enclave.signed.so in prebuilt package is built by [id_enclave](https://github.com/intel/SGXDataCenterAttestationPrimitives/tree/master/QuoteGeneration/quote_wrapper/quote/id_enclave) with branch [sgx_2.17_reproducible](https://github.com/intel/linux-sgx/tree/sgx_2.17_reproducible) and signed by Intel. + +# TDQE source code +The TDQE is part of [Intel(R) Software Guard Extensions Data Center Attestation Primitives](https://github.com/intel/SGXDataCenterAttestationPrimitives/) Github repository. The libsgx_tdqe.signed.so in prebuilt package is built by [tdqe](https://github.com/intel/SGXDataCenterAttestationPrimitives/tree/master/QuoteGeneration/quote_wrapper/tdx_quote/enclave) with branch [sgx_2.17_reproducible](https://github.com/intel/linux-sgx/tree/sgx_2.17_reproducible) and signed by Intel. diff --git a/QuoteGeneration/qcnl/inc/network_wrapper.h b/QuoteGeneration/qcnl/inc/network_wrapper.h index 358118d1..ca07c046 100644 --- a/QuoteGeneration/qcnl/inc/network_wrapper.h +++ b/QuoteGeneration/qcnl/inc/network_wrapper.h @@ -38,8 +38,8 @@ #pragma once #include "sgx_default_qcnl_wrapper.h" -#include #include +#include using namespace std; diff --git a/QuoteGeneration/qcnl/inc/qcnl_config.h b/QuoteGeneration/qcnl/inc/qcnl_config.h index 5c531cc7..fcc3c629 100644 --- a/QuoteGeneration/qcnl/inc/qcnl_config.h +++ b/QuoteGeneration/qcnl/inc/qcnl_config.h @@ -39,6 +39,7 @@ #include "document.h" #include +#include using namespace std; using namespace rapidjson; @@ -84,10 +85,6 @@ class QcnlConfig { cache_expire_hour_(0) {} // To define the virtual destructor outside the class: virtual ~QcnlConfig() { - if (myInstance) { - delete myInstance; - myInstance = nullptr; - } }; public: @@ -96,8 +93,8 @@ class QcnlConfig { QcnlConfig &operator=(QcnlConfig const &) = delete; QcnlConfig &operator=(QcnlConfig &&) = delete; - static QcnlConfig *myInstance; - static QcnlConfig *Instance(); + static std::shared_ptr myInstance; + static std::shared_ptr Instance(); string getServerUrl() { return server_url_; diff --git a/QuoteGeneration/qcnl/inc/qv_collateral_provider.h b/QuoteGeneration/qcnl/inc/qv_collateral_provider.h index 198dc675..ae381aea 100644 --- a/QuoteGeneration/qcnl/inc/qv_collateral_provider.h +++ b/QuoteGeneration/qcnl/inc/qv_collateral_provider.h @@ -50,10 +50,11 @@ class QvCollateralProvider { string get_custom_param_string(); sgx_qcnl_error_t build_pck_crl_url(const char *ca, string &url); - sgx_qcnl_error_t build_tcbinfo_url(const char *fmspc, + sgx_qcnl_error_t build_tcbinfo_url(sgx_prod_type_t prod_type, + const char *fmspc, uint16_t fmspc_size, string &url); - sgx_qcnl_error_t build_qeidentity_url(string &url); + sgx_qcnl_error_t build_qeidentity_url(sgx_qe_type_t qe_type, string &url); sgx_qcnl_error_t build_qveidentity_url(string &url); sgx_qcnl_error_t build_root_ca_crl_url(const char *root_ca_cdp_url, string &url); public: @@ -65,11 +66,12 @@ class QvCollateralProvider { uint16_t ca_size, uint8_t **p_crl_chain, uint16_t *p_crl_chain_size); - sgx_qcnl_error_t get_tcbinfo(const char *fmspc, + sgx_qcnl_error_t get_tcbinfo(sgx_prod_type_t prod_type, + const char *fmspc, uint16_t fmspc_size, uint8_t **p_tcbinfo, uint16_t *p_tcbinfo_size); - sgx_qcnl_error_t get_qe_identity(uint8_t qe_type, + sgx_qcnl_error_t get_qe_identity(sgx_qe_type_t qe_type, uint8_t **p_qe_identity, uint16_t *p_qe_identity_size); sgx_qcnl_error_t get_qve_identity(char **pp_qve_identity, @@ -80,4 +82,4 @@ class QvCollateralProvider { uint8_t **p_root_ca_crl, uint16_t *p_root_ca_crl_size); }; -#endif \ No newline at end of file +#endif diff --git a/QuoteGeneration/qcnl/inc/sgx_default_qcnl_wrapper.h b/QuoteGeneration/qcnl/inc/sgx_default_qcnl_wrapper.h index 4fe5ffe2..f049d9c7 100644 --- a/QuoteGeneration/qcnl/inc/sgx_default_qcnl_wrapper.h +++ b/QuoteGeneration/qcnl/inc/sgx_default_qcnl_wrapper.h @@ -65,6 +65,11 @@ typedef enum _sgx_qcnl_error_t { SGX_QCNL_INVALID_CONFIG = SGX_QCNL_MK_ERROR(0x0030), ///< Error in configuration file } sgx_qcnl_error_t; +typedef enum _sgx_qe_type_t { + SGX_QE_TYPE_ECDSA = 0, + SGX_QE_TYPE_TD = 1, +} sgx_qe_type_t; + #if defined(__cplusplus) extern "C" { #endif @@ -90,7 +95,15 @@ sgx_qcnl_error_t sgx_qcnl_get_tcbinfo(const char *fmspc, void sgx_qcnl_free_tcbinfo(uint8_t *p_tcbinfo); -sgx_qcnl_error_t sgx_qcnl_get_qe_identity(uint8_t qe_type, +sgx_qcnl_error_t tdx_qcnl_get_tcbinfo(const char *fmspc, + uint16_t fmspc_size, + const char* custom_param_b64_string, + uint8_t **p_tcbinfo, + uint16_t *p_tcbinfo_size); + +void tdx_qcnl_free_tcbinfo(uint8_t *p_tcbinfo); + +sgx_qcnl_error_t sgx_qcnl_get_qe_identity(sgx_qe_type_t qe_type, const char* custom_param_b64_string, uint8_t **p_qe_identity, uint16_t *p_qe_identity_size); diff --git a/QuoteGeneration/qcnl/linux/network_wrapper.cpp b/QuoteGeneration/qcnl/linux/network_wrapper.cpp index e4ef353f..5c8ea1f7 100644 --- a/QuoteGeneration/qcnl/linux/network_wrapper.cpp +++ b/QuoteGeneration/qcnl/linux/network_wrapper.cpp @@ -30,15 +30,15 @@ */ /** * File: network_wrapper.cpp - * + * * Description: Network access logic * */ -#include "sgx_default_qcnl_wrapper.h" #include "network_wrapper.h" #include "qcnl_config.h" #include "se_memcpy.h" +#include "sgx_default_qcnl_wrapper.h" #include #include @@ -72,12 +72,12 @@ static size_t write_callback(void *ptr, size_t size, size_t nmemb, void *stream) } /** -* This method converts CURL error codes to QCNL error codes -* -* @param curl_error Curl library error codes -* -* @return Collateral Network Library Error Codes -*/ + * This method converts CURL error codes to QCNL error codes + * + * @param curl_error Curl library error codes + * + * @return Collateral Network Library Error Codes + */ static sgx_qcnl_error_t curl_error_to_qcnl_error(CURLcode curl_error) { switch (curl_error) { case CURLE_OK: @@ -104,12 +104,12 @@ static sgx_qcnl_error_t curl_error_to_qcnl_error(CURLcode curl_error) { } /** -* This method converts PCCS HTTP status codes to QCNL error codes -* -* @param pccs_status_code PCCS HTTP status codes -* -* @return Collateral Network Library Error Codes -*/ + * This method converts PCCS HTTP status codes to QCNL error codes + * + * @param pccs_status_code PCCS HTTP status codes + * + * @return Collateral Network Library Error Codes + */ static sgx_qcnl_error_t pccs_status_to_qcnl_error(long pccs_status_code) { switch (pccs_status_code) { case 200: // PCCS_STATUS_SUCCESS @@ -130,20 +130,20 @@ static sgx_qcnl_error_t pccs_status_to_qcnl_error(long pccs_status_code) { } /** -* This method calls curl library to perform https POST request with raw body in JSON format and returns response body and header -* -* @param url HTTPS GET/POST URL -* @param req_body Request body in raw JSON format. For GET request it should be NULL. -* @param req_body_size Size of request body. For GET request it should be 0. -* @param user_token user token to access PCCS v3/platforms API. For GET request it should be NULL. -* @param user_token_size Size of user token. For GET request it should be 0. -* @param resp_msg Output buffer of response body -* @param resp_size Size of response body -* @param resp_header Output buffer of response header -* @param header_size Size of response header -* -* @return SGX_QCNL_SUCCESS Call https post successfully. Other return codes indicate an error occured. -*/ + * This method calls curl library to perform https POST request with raw body in JSON format and returns response body and header + * + * @param url HTTPS GET/POST URL + * @param req_body Request body in raw JSON format. For GET request it should be NULL. + * @param req_body_size Size of request body. For GET request it should be 0. + * @param user_token user token to access PCCS v3/platforms API. For GET request it should be NULL. + * @param user_token_size Size of user token. For GET request it should be 0. + * @param resp_msg Output buffer of response body + * @param resp_size Size of response body + * @param resp_header Output buffer of response header + * @param header_size Size of response header + * + * @return SGX_QCNL_SUCCESS Call https post successfully. Other return codes indicate an error occured. + */ sgx_qcnl_error_t qcnl_https_request(const char *url, http_header_map &header_map, const char *req_body, @@ -241,20 +241,13 @@ sgx_qcnl_error_t qcnl_https_request(const char *url, if (curl_ret == CURLE_OK) { curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &http_code); qcnl_log(SGX_QL_LOG_INFO, "[QCNL] HTTP status code: %ld \n", http_code); - if (http_code == 404) { - ret = SGX_QCNL_ERROR_STATUS_NO_CACHE_DATA; - goto cleanup; + if (http_code == 200) { + break; } else if (http_code == 503) { // SERVICE_UNAVAILABLE need_retry = true; - } else if (http_code != 200) { - ret = pccs_status_to_qcnl_error(http_code); - goto cleanup; } } else if (curl_ret == CURLE_OPERATION_TIMEDOUT || curl_ret == CURLE_COULDNT_RESOLVE_HOST || curl_ret == CURLE_COULDNT_RESOLVE_PROXY || curl_ret == CURLE_COULDNT_CONNECT || curl_ret == CURLE_HTTP_RETURNED_ERROR) { need_retry = true; - } else { - ret = curl_error_to_qcnl_error(curl_ret); - goto cleanup; } retry_times--; @@ -267,9 +260,13 @@ sgx_qcnl_error_t qcnl_https_request(const char *url, } continue; } else { - break; + if (curl_ret != CURLE_OK) + ret = curl_error_to_qcnl_error(curl_ret); + else + ret = pccs_status_to_qcnl_error(http_code); + goto cleanup; } - } while (retry_times > 0); + } while (true); *resp_msg = res_body.base; resp_size = res_body.size; diff --git a/QuoteGeneration/qcnl/linux/qcnl_config_impl.cpp b/QuoteGeneration/qcnl/linux/qcnl_config_impl.cpp index fcaa37a3..60949252 100644 --- a/QuoteGeneration/qcnl/linux/qcnl_config_impl.cpp +++ b/QuoteGeneration/qcnl/linux/qcnl_config_impl.cpp @@ -75,14 +75,14 @@ bool QcnlConfigLegacy::load_config() { try { string::size_type sz; retry_times_ = stoi(value, &sz); - } catch (const invalid_argument &e) { + } catch (const invalid_argument &) { continue; } } else if (name.compare("RETRY_DELAY") == 0) { try { string::size_type sz; retry_delay_ = stoi(value, &sz); - } catch (const invalid_argument &e) { + } catch (const invalid_argument &) { continue; } } else if (name.compare("LOCAL_PCK_URL") == 0) { @@ -93,7 +93,7 @@ bool QcnlConfigLegacy::load_config() { cache_expire_hour_ = stoi(value, &sz); if (cache_expire_hour_ > CACHE_MAX_EXPIRY_HOURS) cache_expire_hour_ = CACHE_MAX_EXPIRY_HOURS; - } catch (const invalid_argument &e) { + } catch (const invalid_argument &) { continue; } } else { diff --git a/QuoteGeneration/qcnl/linux/sgx_default_qcnl.lds b/QuoteGeneration/qcnl/linux/sgx_default_qcnl.lds index 860bfda8..3dfb9a83 100644 --- a/QuoteGeneration/qcnl/linux/sgx_default_qcnl.lds +++ b/QuoteGeneration/qcnl/linux/sgx_default_qcnl.lds @@ -6,6 +6,8 @@ global: sgx_qcnl_free_pck_crl_chain; sgx_qcnl_get_tcbinfo; sgx_qcnl_free_tcbinfo; + tdx_qcnl_get_tcbinfo; + tdx_qcnl_free_tcbinfo; sgx_qcnl_get_qe_identity; sgx_qcnl_free_qe_identity; sgx_qcnl_get_qve_identity; diff --git a/QuoteGeneration/qcnl/qcnl_config.cpp b/QuoteGeneration/qcnl/qcnl_config.cpp index f8019ba7..ee2a055b 100644 --- a/QuoteGeneration/qcnl/qcnl_config.cpp +++ b/QuoteGeneration/qcnl/qcnl_config.cpp @@ -42,19 +42,19 @@ using namespace std; -QcnlConfig *QcnlConfig::myInstance = nullptr; +std::shared_ptr QcnlConfig::myInstance; -QcnlConfig *QcnlConfig::Instance() { - if (myInstance == nullptr) { +std::shared_ptr QcnlConfig::Instance() { + if (!myInstance) { QcnlConfigJson *pConfigJson = new QcnlConfigJson(); if (pConfigJson->load_config()) { - myInstance = pConfigJson; + myInstance.reset(pConfigJson); } else { delete pConfigJson; pConfigJson = nullptr; QcnlConfigLegacy *pConfigLegacy = new QcnlConfigLegacy(); pConfigLegacy->load_config(); - myInstance = pConfigLegacy; + myInstance.reset(pConfigLegacy); } } diff --git a/QuoteGeneration/qcnl/qcnl_util.cpp b/QuoteGeneration/qcnl/qcnl_util.cpp index c0ad234f..43fb8c35 100644 --- a/QuoteGeneration/qcnl/qcnl_util.cpp +++ b/QuoteGeneration/qcnl/qcnl_util.cpp @@ -127,6 +127,10 @@ bool byte_array_to_hex_string(const uint8_t *in_buf, uint32_t in_size, uint8_t * // This function is used to unescpae URL Codes, for example, %20 to SPACE character(0x20) string unescape(string &src) { + if (src.length() < 3) { + return src; + } + string dst; char ch; int i, value; diff --git a/QuoteGeneration/qcnl/qv_collateral_provider.cpp b/QuoteGeneration/qcnl/qv_collateral_provider.cpp index ca362cc3..d438d27e 100644 --- a/QuoteGeneration/qcnl/qv_collateral_provider.cpp +++ b/QuoteGeneration/qcnl/qv_collateral_provider.cpp @@ -165,12 +165,22 @@ sgx_qcnl_error_t QvCollateralProvider::get_pck_crl_chain(const char *ca, return ret; } -sgx_qcnl_error_t QvCollateralProvider::build_tcbinfo_url(const char *fmspc, +sgx_qcnl_error_t QvCollateralProvider::build_tcbinfo_url(sgx_prod_type_t prod_type, + const char *fmspc, uint16_t fmspc_size, string &url) { // initialize https request url url = QcnlConfig::Instance()->getCollateralServiceUrl(); + if (prod_type == SGX_PROD_TYPE_TDX) { + auto found = url.find("/sgx/"); + if (found != std::string::npos) { + url = url.replace(found, 5, "/tdx/"); + } else { + return SGX_QCNL_UNEXPECTED_ERROR; + } + } + // Append fmspc url.append("tcb?fmspc="); if (!concat_string_with_hex_buf(url, reinterpret_cast(fmspc), fmspc_size)) { @@ -185,12 +195,13 @@ sgx_qcnl_error_t QvCollateralProvider::build_tcbinfo_url(const char *fmspc, return SGX_QCNL_SUCCESS; } -sgx_qcnl_error_t QvCollateralProvider::get_tcbinfo(const char *fmspc, +sgx_qcnl_error_t QvCollateralProvider::get_tcbinfo(sgx_prod_type_t prod_type, + const char *fmspc, uint16_t fmspc_size, uint8_t **p_tcbinfo, uint16_t *p_tcbinfo_size) { string url(""); - sgx_qcnl_error_t ret = build_tcbinfo_url(fmspc, fmspc_size, url); + sgx_qcnl_error_t ret = build_tcbinfo_url(prod_type, fmspc, fmspc_size, url); if (ret != SGX_QCNL_SUCCESS) { return ret; } @@ -248,8 +259,18 @@ sgx_qcnl_error_t QvCollateralProvider::get_tcbinfo(const char *fmspc, return ret; } -sgx_qcnl_error_t QvCollateralProvider::build_qeidentity_url(string &url) { +sgx_qcnl_error_t QvCollateralProvider::build_qeidentity_url(sgx_qe_type_t qe_type, string &url) { url = QcnlConfig::Instance()->getCollateralServiceUrl(); + + if (qe_type == SGX_QE_TYPE_TD) { + auto found = url.find("/sgx/"); + if (found != std::string::npos) { + url = url.replace(found, 5, "/tdx/"); + } else { + return SGX_QCNL_UNEXPECTED_ERROR; + } + } + url.append("qe/identity"); if (!custom_param_.empty()) { url.append("?").append(get_custom_param_string()); @@ -260,13 +281,13 @@ sgx_qcnl_error_t QvCollateralProvider::build_qeidentity_url(string &url) { return SGX_QCNL_SUCCESS; } -sgx_qcnl_error_t QvCollateralProvider::get_qe_identity(uint8_t qe_type, +sgx_qcnl_error_t QvCollateralProvider::get_qe_identity(sgx_qe_type_t qe_type, uint8_t **p_qe_identity, uint16_t *p_qe_identity_size) { (void)qe_type; // initialize https request url string url(""); - sgx_qcnl_error_t ret = build_qeidentity_url(url); + sgx_qcnl_error_t ret = build_qeidentity_url(qe_type, url); if (ret != SGX_QCNL_SUCCESS) { return ret; } diff --git a/QuoteGeneration/qcnl/sgx_default_qcnl_wrapper.cpp b/QuoteGeneration/qcnl/sgx_default_qcnl_wrapper.cpp index b1befb18..595936a1 100644 --- a/QuoteGeneration/qcnl/sgx_default_qcnl_wrapper.cpp +++ b/QuoteGeneration/qcnl/sgx_default_qcnl_wrapper.cpp @@ -43,6 +43,7 @@ #include "sgx_pce.h" #include "qcnl_util.h" #include +#include static sgx_ql_logging_callback_t logger_callback = nullptr; @@ -153,6 +154,7 @@ void sgx_qcnl_free_pck_crl_chain(uint8_t *p_crl_chain) { * This API gets TCB information from PCCS server. The p_tcbinfo buffer allocated by this API * must be freed with sgx_qcnl_free_tcbinfo upon success. * +* @param prod_type SGX or TDX * @param fmspc Family-Model-Stepping value * @param fmspc_size Size of the fmspc buffer * @param p_tcbinfo Output buffer for TCB information @@ -160,11 +162,12 @@ void sgx_qcnl_free_pck_crl_chain(uint8_t *p_crl_chain) { * * @return SGX_QCNL_SUCCESS If the TCB information was retrieved from PCCS server successfully. */ -sgx_qcnl_error_t sgx_qcnl_get_tcbinfo(const char *fmspc, - uint16_t fmspc_size, - const char* custom_param_b64_string, - uint8_t **p_tcbinfo, - uint16_t *p_tcbinfo_size) { +sgx_qcnl_error_t qcnl_get_tcbinfo_internal(sgx_prod_type_t prod_type, + const char *fmspc, + uint16_t fmspc_size, + const char* custom_param_b64_string, + uint8_t **p_tcbinfo, + uint16_t *p_tcbinfo_size) { // Check input parameters // fmspc is always 6 bytes if (p_tcbinfo == NULL || p_tcbinfo_size == NULL) { @@ -175,7 +178,33 @@ sgx_qcnl_error_t sgx_qcnl_get_tcbinfo(const char *fmspc, } QvCollateralProvider qvCollateralProvider(custom_param_b64_string); - return qvCollateralProvider.get_tcbinfo(fmspc, fmspc_size, p_tcbinfo, p_tcbinfo_size); + return qvCollateralProvider.get_tcbinfo(prod_type, fmspc, fmspc_size, p_tcbinfo, p_tcbinfo_size); +} + +sgx_qcnl_error_t sgx_qcnl_get_tcbinfo(const char *fmspc, + uint16_t fmspc_size, + const char* custom_param_b64_string, + uint8_t **p_tcbinfo, + uint16_t *p_tcbinfo_size) { + return qcnl_get_tcbinfo_internal(SGX_PROD_TYPE_SGX, + fmspc, + fmspc_size, + custom_param_b64_string, + p_tcbinfo, + p_tcbinfo_size); +} + +sgx_qcnl_error_t tdx_qcnl_get_tcbinfo(const char *fmspc, + uint16_t fmspc_size, + const char* custom_param_b64_string, + uint8_t **p_tcbinfo, + uint16_t *p_tcbinfo_size) { + return qcnl_get_tcbinfo_internal(SGX_PROD_TYPE_TDX, + fmspc, + fmspc_size, + custom_param_b64_string, + p_tcbinfo, + p_tcbinfo_size); } /** @@ -188,22 +217,31 @@ void sgx_qcnl_free_tcbinfo(uint8_t *p_tcbinfo) { } } +/** +* This API frees the p_tcbinfo buffer allocated by tdx_qcnl_get_tcbinfo +*/ +void tdx_qcnl_free_tcbinfo(uint8_t *p_tcbinfo) { + if (p_tcbinfo) { + free(p_tcbinfo); + } +} + /** * This API gets QE identity from PCCS server. The p_qe_identity buffer allocated by this API * must be freed with sgx_qcnl_free_qe_identity upon success. * -* @param qe_type Currently only 0 (ECDSA QE) is supported +* @param qe_type Type of QE * @param p_qe_identity Output buffer for QE identity * @param p_qe_identity_size Size of QE identity * * @return SGX_QCNL_SUCCESS If the QE identity was retrieved from PCCS server successfully. */ -sgx_qcnl_error_t sgx_qcnl_get_qe_identity(uint8_t qe_type, +sgx_qcnl_error_t sgx_qcnl_get_qe_identity(sgx_qe_type_t qe_type, const char* custom_param_b64_string, uint8_t **p_qe_identity, uint16_t *p_qe_identity_size) { // Check input parameters - if (p_qe_identity == NULL || p_qe_identity_size == NULL || qe_type != 0) { + if (p_qe_identity == NULL || p_qe_identity_size == NULL ) { return SGX_QCNL_INVALID_PARAMETER; } @@ -297,20 +335,37 @@ void sgx_qcnl_free_root_ca_crl(uint8_t *p_root_ca_crl) { * This function returns the collateral version. */ bool sgx_qcnl_get_api_version(uint16_t *p_major_ver, uint16_t *p_minor_ver) { - *p_major_ver = 3; - *p_minor_ver = 1; - - if (!is_collateral_service_pcs()) { // PCCS - // Only 3.1 and 3.0 are supported - if (QcnlConfig::Instance()->getCollateralVersion() == "3.0") { - *p_minor_ver = 0; - } else if (QcnlConfig::Instance()->getCollateralVersion() != "3.1") { - *p_major_ver = 0; - *p_minor_ver = 0; + string version = QcnlConfig::Instance()->getCollateralVersion(); + if (!version.empty()) { + auto pos = version.find("."); + if (pos != std::string::npos) { + auto s_major = version.substr(0, pos); + auto s_minor = version.substr(pos + 1); + try { + string::size_type sz; + *p_major_ver = (uint16_t)stoi(s_major, &sz); + *p_minor_ver = (uint16_t)stoi(s_minor, &sz); + return true; + } catch (const invalid_argument &e) { + qcnl_log(SGX_QL_LOG_ERROR, "[QCNL] Failed to parse version string : %s", e.what()); + return false; + } + } else { return false; } } + string url = QcnlConfig::Instance()->getCollateralServiceUrl(); + if (url.find("/v3/") != std::string::npos) { + *p_major_ver = 3; + *p_minor_ver = 0; + } else if (url.find("/v4/") != std::string::npos) { + *p_major_ver = 4; + *p_minor_ver = 0; + } else { + return false; + } + return true; } diff --git a/QuoteGeneration/qcnl/win/qcnl_wrapper.def b/QuoteGeneration/qcnl/win/qcnl_wrapper.def index 1d0dc3b5..51f2e1fe 100644 --- a/QuoteGeneration/qcnl/win/qcnl_wrapper.def +++ b/QuoteGeneration/qcnl/win/qcnl_wrapper.def @@ -14,4 +14,6 @@ EXPORTS sgx_qcnl_get_root_ca_crl @11 sgx_qcnl_free_root_ca_crl @12 sgx_qcnl_get_api_version @13 - sgx_qcnl_set_logging_callback @14 \ No newline at end of file + sgx_qcnl_set_logging_callback @14 + tdx_qcnl_get_tcbinfo @15 + tdx_qcnl_free_tcbinfo @16 diff --git a/QuoteGeneration/qpl/inc/sgx_default_quote_provider.h b/QuoteGeneration/qpl/inc/sgx_default_quote_provider.h index ee820dd7..a0599240 100644 --- a/QuoteGeneration/qpl/inc/sgx_default_quote_provider.h +++ b/QuoteGeneration/qpl/inc/sgx_default_quote_provider.h @@ -48,7 +48,7 @@ extern "C" { quote3_error_t sgx_ql_get_quote_config(const sgx_ql_pck_cert_id_t *p_pck_cert_id, sgx_ql_config_t **pp_quote_config); quote3_error_t sgx_ql_free_quote_config(sgx_ql_config_t *p_quote_config); quote3_error_t sgx_ql_get_quote_verification_collateral(const uint8_t *fmspc, - uint16_t fmspc_size, + uint16_t fmspc_size, const char *pck_ca, sgx_ql_qve_collateral_t **pp_quote_collateral); quote3_error_t sgx_ql_get_quote_verification_collateral_with_params(const uint8_t *fmspc, @@ -58,6 +58,11 @@ quote3_error_t sgx_ql_get_quote_verification_collateral_with_params(const uint8_ const uint16_t custom_param_length, sgx_ql_qve_collateral_t **pp_quote_collateral); quote3_error_t sgx_ql_free_quote_verification_collateral(sgx_ql_qve_collateral_t *p_quote_collateral); +quote3_error_t tdx_ql_get_quote_verification_collateral(const uint8_t *fmspc, + uint16_t fmspc_size, + const char *pck_ca, + tdx_ql_qve_collateral_t **pp_quote_collateral); +quote3_error_t tdx_ql_free_quote_verification_collateral(tdx_ql_qve_collateral_t *p_quote_collateral); quote3_error_t sgx_ql_get_qve_identity(char **pp_qve_identity, uint32_t *p_qve_identity_size, char **pp_qve_identity_issuer_chain, diff --git a/QuoteGeneration/qpl/linux/sgx_default_quote_provider.lds b/QuoteGeneration/qpl/linux/sgx_default_quote_provider.lds index a8aacfbf..c65ece41 100644 --- a/QuoteGeneration/qpl/linux/sgx_default_quote_provider.lds +++ b/QuoteGeneration/qpl/linux/sgx_default_quote_provider.lds @@ -5,6 +5,8 @@ global: sgx_ql_get_quote_verification_collateral; sgx_ql_get_quote_verification_collateral_with_params; sgx_ql_free_quote_verification_collateral; + tdx_ql_get_quote_verification_collateral; + tdx_ql_free_quote_verification_collateral; sgx_ql_get_qve_identity; sgx_ql_free_qve_identity; sgx_ql_get_root_ca_crl; diff --git a/QuoteGeneration/qpl/linux/x509.cpp b/QuoteGeneration/qpl/linux/x509.cpp index d5f96c5c..044db8ce 100644 --- a/QuoteGeneration/qpl/linux/x509.cpp +++ b/QuoteGeneration/qpl/linux/x509.cpp @@ -34,6 +34,7 @@ * Description: X.509 parser * */ +#include "x509.h" #include #include #include diff --git a/QuoteGeneration/qpl/qpl_api.txt b/QuoteGeneration/qpl/qpl_api.txt index 6785eb50..9abd1731 100644 --- a/QuoteGeneration/qpl/qpl_api.txt +++ b/QuoteGeneration/qpl/qpl_api.txt @@ -50,7 +50,7 @@ Parameters Base 16-encoded representation of FMSPC. fmspc_size [In] Length of fmspc. - ca [In] + pck_ca [In] Null terminated string identifier of the PCK Cert CA that issued the PCK Certificates. pp_quote_collateral [Out] Pointer to a pointer to the PCK quote collateral data needed for quote verifcation. @@ -65,8 +65,64 @@ Return Values: SGX_QL_NO_QUOTE_COLLATERAL_DATA: The platform does not have the quote verification collateral data available. */ -quote3_error_t sgx_ql_get_quote_verification_collateral( const char *fmspc, uint16_t fmspc_size, const char *pck_ca, - sgx_ql_qve_collateral_t **pp_quote_collateral); +quote3_error_t sgx_ql_get_quote_verification_collateral( const uint8_t *fmspc, uint16_t fmspc_size, const char *pck_ca, + sgx_ql_qve_collateral_t **pp_quote_collateral); + +/** +Parameters + fmspc [In] + Base 16-encoded representation of FMSPC. + fmspc_size [In] + Length of fmspc. + pck_ca [In] + Null terminated string identifier of the PCK Cert CA that issued the PCK Certificates. + pp_quote_collateral [Out] + Pointer to a pointer to the PCK quote collateral data needed for quote verifcation. + +Return Values: + SGX_QL_SUCCESS: + The platform has the certification data available and has returned it in the p_quote_config buffer. + SGX_QL_INVALID_PARRAMETER: + The parameters are incorrect. + SGX_QL_OUT_OF_MEMORY: + Out of memory error. + SGX_QL_NO_QUOTE_COLLATERAL_DATA: + The platform does not have the quote verification collateral data available. +*/ +quote3_error_t tdx_ql_get_quote_verification_collateral( const uint8_t *fmspc, uint16_t fmspc_size, const char *pck_ca, + tdx_ql_qve_collateral_t **pp_quote_collateral); + +/** +Parameters + fmspc [In] + Base 16-encoded representation of FMSPC. + fmspc_size [In] + Length of fmspc. + pck_ca [In] + Null terminated string identifier of the PCK Cert CA that issued the PCK Certificates. + custom_param [In] + Custom parameter that will be appended to request URL in Base64 format ( ...&customParameters=Base64(custom_param) ) + custom_param_length [In] + Length of custom_param. + pp_quote_collateral [Out] + Pointer to a pointer to the PCK quote collateral data needed for quote verifcation. + +Return Values: + SGX_QL_SUCCESS: + The platform has the certification data available and has returned it in the p_quote_config buffer. + SGX_QL_INVALID_PARRAMETER: + The parameters are incorrect. + SGX_QL_OUT_OF_MEMORY: + Out of memory error. + SGX_QL_NO_QUOTE_COLLATERAL_DATA: + The platform does not have the quote verification collateral data available. +*/ +quote3_error_t sgx_ql_get_quote_verification_collateral_with_params(const uint8_t *fmspc, + const uint16_t fmspc_size, + const char *pck_ca, + const void* custom_param, + const uint16_t custom_param_length, + sgx_ql_qve_collateral_t **pp_quote_collateral); /** Parameters: @@ -78,6 +134,16 @@ Return Values: */ quote3_error_t sgx_ql_free_quote_verification_collateral(sgx_ql_qve_collateral_t *p_quote_collateral); +/** +Parameters: + p_quote_collateral [In] + Pointer to the PCK certification that the tdx_ql_get_quote_verification_collateral() API returns. +Return Values: + SGX_QL_SUCCESS: + The buffer was freed successfully. +*/ +quote3_error_t tdx_ql_free_quote_verification_collateral(tdx_ql_qve_collateral_t *p_quote_collateral); + /** Parameters: pp_qve_identity[Out] @@ -169,3 +235,5 @@ typedef struct _sgx_ql_qve_collateral_t char *qe_identity; /// QE Identity Structure uint32_t qe_identity_size; }sgx_ql_qve_collateral_t; + +typedef sgx_ql_qve_collateral_t tdx_ql_qve_collateral_t; \ No newline at end of file diff --git a/QuoteGeneration/qpl/sgx_default_quote_provider.cpp b/QuoteGeneration/qpl/sgx_default_quote_provider.cpp index 35eebeeb..a5c7013c 100644 --- a/QuoteGeneration/qpl/sgx_default_quote_provider.cpp +++ b/QuoteGeneration/qpl/sgx_default_quote_provider.cpp @@ -127,8 +127,10 @@ quote3_error_t sgx_ql_free_quote_config(sgx_ql_config_t *p_quote_config) { static quote3_error_t split_buffer(uint8_t *in_buf, uint16_t in_buf_size, char **__unaligned out_buf1, uint32_t *__unaligned out_buf1_size, char **__unaligned out_buf2, uint32_t *__unaligned out_buf2_size) { + const string delimiter = "-----BEGIN CERTIFICATE-----"; + string s0((char *)in_buf, in_buf_size); - size_t pos = s0.find(X509_DELIMITER); + size_t pos = s0.find(delimiter); if (pos == string::npos) { qpl_log(SGX_QL_LOG_ERROR, "[QPL] Invalid certificate chain.\n"); return SGX_QL_MESSAGE_ERROR; @@ -167,17 +169,13 @@ static quote3_error_t split_buffer(uint8_t *in_buf, uint16_t in_buf_size, char * return SGX_QL_SUCCESS; } -quote3_error_t sgx_ql_get_quote_verification_collateral(const uint8_t *fmspc, uint16_t fmspc_size, const char *pck_ca, - sgx_ql_qve_collateral_t **pp_quote_collateral) { - return sgx_ql_get_quote_verification_collateral_with_params(fmspc, fmspc_size, pck_ca, NULL, 0, pp_quote_collateral); -} - -quote3_error_t sgx_ql_get_quote_verification_collateral_with_params(const uint8_t *fmspc, - const uint16_t fmspc_size, - const char *pck_ca, - const void *custom_param, - const uint16_t custom_param_length, - sgx_ql_qve_collateral_t **pp_quote_collateral) { +quote3_error_t ql_get_quote_verification_collateral_internal(sgx_prod_type_t prod_type, + const uint8_t *fmspc, + const uint16_t fmspc_size, + const char *pck_ca, + const void* custom_param, + const uint16_t custom_param_length, + sgx_ql_qve_collateral_t **pp_quote_collateral) { if (fmspc == NULL || pck_ca == NULL || pp_quote_collateral == NULL || (custom_param != NULL && custom_param_length == 0) || (custom_param == NULL && custom_param_length != 0)) { @@ -237,7 +235,12 @@ quote3_error_t sgx_ql_get_quote_verification_collateral_with_params(const uint8_ } // Set TCBInfo and certchain - qcnl_ret = sgx_qcnl_get_tcbinfo(reinterpret_cast(fmspc), fmspc_size, base64_string, &p_tcbinfo, &tcbinfo_size); + if (prod_type == SGX_PROD_TYPE_SGX) { + qcnl_ret = sgx_qcnl_get_tcbinfo(reinterpret_cast(fmspc), fmspc_size, base64_string, &p_tcbinfo, &tcbinfo_size); + } else { + qcnl_ret = tdx_qcnl_get_tcbinfo(reinterpret_cast(fmspc), fmspc_size, base64_string, &p_tcbinfo, &tcbinfo_size); + } + if (qcnl_ret != SGX_QCNL_SUCCESS) { qpl_log(SGX_QL_LOG_ERROR, "[QPL] Failed to get TCBInfo : 0x%04x\n", qcnl_ret); ret = qcnl_error_to_ql_error(qcnl_ret); @@ -252,7 +255,12 @@ quote3_error_t sgx_ql_get_quote_verification_collateral_with_params(const uint8_ } // Set QEIdentity and certchain - qcnl_ret = sgx_qcnl_get_qe_identity(0, base64_string, &p_qe_identity, &qe_identity_size); + sgx_qe_type_t qe_type; + if (prod_type == SGX_PROD_TYPE_SGX) + qe_type = SGX_QE_TYPE_ECDSA; + else qe_type = SGX_QE_TYPE_TD; + + qcnl_ret = sgx_qcnl_get_qe_identity(qe_type, base64_string, &p_qe_identity, &qe_identity_size); if (qcnl_ret != SGX_QCNL_SUCCESS) { qpl_log(SGX_QL_LOG_ERROR, "[QPL] Failed to get QE identity : 0x%04x\n", qcnl_ret); ret = qcnl_error_to_ql_error(qcnl_ret); @@ -301,7 +309,11 @@ quote3_error_t sgx_ql_get_quote_verification_collateral_with_params(const uint8_ } while (0); sgx_qcnl_free_pck_crl_chain(p_pck_crl_chain); - sgx_qcnl_free_tcbinfo(p_tcbinfo); + if (prod_type == SGX_PROD_TYPE_SGX) { + sgx_qcnl_free_tcbinfo(p_tcbinfo); + } else { + tdx_qcnl_free_tcbinfo(p_tcbinfo); + } sgx_qcnl_free_qe_identity(p_qe_identity); if (base64_string) { free(base64_string); @@ -316,7 +328,7 @@ quote3_error_t sgx_ql_get_quote_verification_collateral_with_params(const uint8_ return ret; } -quote3_error_t sgx_ql_free_quote_verification_collateral(sgx_ql_qve_collateral_t *p_quote_collateral) { +quote3_error_t ql_free_quote_verification_collateral_internal(sgx_ql_qve_collateral_t *p_quote_collateral) { if (p_quote_collateral) { if (p_quote_collateral->pck_crl_issuer_chain) { free(p_quote_collateral->pck_crl_issuer_chain); @@ -353,6 +365,69 @@ quote3_error_t sgx_ql_free_quote_verification_collateral(sgx_ql_qve_collateral_t return SGX_QL_SUCCESS; } +quote3_error_t sgx_ql_get_quote_verification_collateral(const uint8_t *fmspc, + uint16_t fmspc_size, + const char *pck_ca, + sgx_ql_qve_collateral_t **pp_quote_collateral) { + quote3_error_t ret = ql_get_quote_verification_collateral_internal(SGX_PROD_TYPE_SGX, + fmspc, + fmspc_size, + pck_ca, + NULL, + 0, + pp_quote_collateral); + if (ret == SGX_QL_SUCCESS) { + (*pp_quote_collateral)->tee_type = 0x0; // SGX + } else { + qpl_log(SGX_QL_LOG_ERROR, "[QPL] Failed to get SGX quote verification collateral : %d\n", ret); + } + return ret; +} + +quote3_error_t sgx_ql_get_quote_verification_collateral_with_params(const uint8_t *fmspc, + const uint16_t fmspc_size, + const char *pck_ca, + const void* custom_param, + const uint16_t custom_param_length, + sgx_ql_qve_collateral_t **pp_quote_collateral) { + quote3_error_t ret = ql_get_quote_verification_collateral_internal(SGX_PROD_TYPE_SGX, + fmspc, + fmspc_size, + pck_ca, + custom_param, + custom_param_length, + pp_quote_collateral); + if (ret == SGX_QL_SUCCESS) { + (*pp_quote_collateral)->tee_type = 0x0; // SGX + } else { + qpl_log(SGX_QL_LOG_ERROR, "[QPL] Failed to get SGX quote verification collateral : %d\n", ret); + } + return ret; +} +quote3_error_t tdx_ql_get_quote_verification_collateral(const uint8_t *fmspc, uint16_t fmspc_size, const char *pck_ca, + sgx_ql_qve_collateral_t **pp_quote_collateral) { + quote3_error_t ret = ql_get_quote_verification_collateral_internal(SGX_PROD_TYPE_TDX, + fmspc, + fmspc_size, + pck_ca, + NULL, + 0, + pp_quote_collateral); + if (ret == SGX_QL_SUCCESS) { + (*pp_quote_collateral)->tee_type = 0x0; // SGX + } else { + qpl_log(SGX_QL_LOG_ERROR, "[QPL] Failed to get SGX quote verification collateral : %d\n", ret); + } + return ret; +} +quote3_error_t sgx_ql_free_quote_verification_collateral(sgx_ql_qve_collateral_t *p_quote_collateral) { + return ql_free_quote_verification_collateral_internal(p_quote_collateral); +} + +quote3_error_t tdx_ql_free_quote_verification_collateral(tdx_ql_qve_collateral_t *p_quote_collateral) { + return ql_free_quote_verification_collateral_internal((tdx_ql_qve_collateral_t *)p_quote_collateral); +} + quote3_error_t sgx_ql_get_qve_identity(char **pp_qve_identity, uint32_t *p_qve_identity_size, char **pp_qve_identity_issuer_chain, @@ -381,7 +456,7 @@ quote3_error_t sgx_ql_get_root_ca_crl(uint8_t **pp_root_ca_crl, uint16_t *p_root quote3_error_t ret = SGX_QL_ERROR_UNEXPECTED; // Get QEIdentity and certchain - sgx_qcnl_error_t qcnl_ret = sgx_qcnl_get_qe_identity(0, NULL, &p_qe_identity, &qe_identity_size); + sgx_qcnl_error_t qcnl_ret = sgx_qcnl_get_qe_identity(SGX_QE_TYPE_ECDSA, NULL, &p_qe_identity, &qe_identity_size); if (qcnl_ret != SGX_QCNL_SUCCESS) { qpl_log(SGX_QL_LOG_ERROR, "[QPL] Failed to get QE identity : 0x%04x\n", qcnl_ret); return qcnl_error_to_ql_error(qcnl_ret); diff --git a/QuoteGeneration/qpl/win/qpl.def b/QuoteGeneration/qpl/win/qpl.def index c1aaaf11..1b068e6b 100644 --- a/QuoteGeneration/qpl/win/qpl.def +++ b/QuoteGeneration/qpl/win/qpl.def @@ -11,3 +11,5 @@ EXPORTS sgx_ql_free_root_ca_crl @8 sgx_ql_set_logging_callback @9 sgx_ql_get_quote_verification_collateral_with_params @10 + tdx_ql_get_quote_verification_collateral @11 + tdx_ql_free_quote_verification_collateral @12 diff --git a/QuoteGeneration/quote_wrapper/quote/inc/ecdsa_quote.h b/QuoteGeneration/quote_wrapper/common/inc/ecdsa_quote.h similarity index 88% rename from QuoteGeneration/quote_wrapper/quote/inc/ecdsa_quote.h rename to QuoteGeneration/quote_wrapper/common/inc/ecdsa_quote.h index f69e19f8..7dde57bc 100644 --- a/QuoteGeneration/quote_wrapper/quote/inc/ecdsa_quote.h +++ b/QuoteGeneration/quote_wrapper/common/inc/ecdsa_quote.h @@ -59,25 +59,25 @@ * generate and store it on disk. It can be used later for the get_quote() to generate quotes using a pre-generated * and certified ECDSA Attestation Key. */ typedef struct _ref_plaintext_ecdsa_data_sdk_t { - uint8_t seal_blob_type; ///< Enclave-specific Sealblob Type, currently only one Sealblob type defined: REFQE3_SEAL_EPID_KEY_BLOB=0 + uint8_t seal_blob_type; ///< Enclave-specific Sealblob Type, currently only one Sealblob type defined: SGX_QL_SEAL_ECDSA_KEY_BLOB=0 uint8_t ecdsa_key_version; ///< Describes the version of the structure of this ECDSA blob. sgx_cpu_svn_t cert_cpu_svn; ///< The CPUSVN used to certify the ECDSA att key. - sgx_isv_svn_t cert_qe3_isv_svn; ///< The QE3's ISV_SVN when the ECDSA att key was generated. + sgx_isv_svn_t cert_qe_isv_svn; ///< The QE's ISV_SVN when the ECDSA att key was generated. sgx_pce_info_t cert_pce_info; ///< PCE ISVSVN and PCEID used to certify. sgx_ql_cert_key_type_t certification_key_type; ///< Certification key type of this blob. sgx_cpu_svn_t raw_cpu_svn; ///< The platform's raw CPUSVN when the ECDSA att key was certified. - sgx_pce_info_t raw_pce_info; ///< The platform's raw PCE ISV_SVN and PCIED when the ECDSA att key was certified.. - uint8_t signature_scheme; ///< Indicates the crypto algorithm used to sign the qe3_report + sgx_pce_info_t raw_pce_info; ///< The platform's raw PCE ISV_SVN and PCIED when the ECDSA att key was certified. + uint8_t signature_scheme; ///< Indicates the crypto algorithm used to sign the qe_report. sgx_target_info_t pce_target_info; ///< PCE Target info used when the key was certified. - sgx_report_t qe3_report; ///< Report of the QE3 used to generate the ECDSA Att Key. REPORTDATA = ECDSA_ID || AuthenticationData - sgx_ec256_signature_t qe3_report_cert_key_sig; ///< The ECDSA signature using the certification key (PCK for root signing). x and y each stored in Big Endian + sgx_report_t qe_report; ///< Report of the QE used to generate the ECDSA Att Key. REPORTDATA = ECDSA_ID || AuthenticationData + sgx_ec256_signature_t qe_report_cert_key_sig; ///< The ECDSA signature using the certification key (PCK for root signing). x and y each stored in Big Endian sgx_ec256_public_t ecdsa_att_public_key; ///< The public portion of the generated ECDSA Att Key. x and y each stored in Big Endian sgx_sha256_hash_t ecdsa_id; ///< The SHA256 hash of the ecdsa_att_public_key sgx_cpu_svn_t seal_cpu_svn; ///< The CPUSVN used to seal the blob. - sgx_isv_svn_t seal_qe3_isv_svn; ///< The QE3 ISV_SVN used to seal the blob. + sgx_isv_svn_t seal_qe_isv_svn; ///< The QE ISV_SVN used to seal the blob. uint32_t authentication_data_size; ///< The number of bytes in the authentication_data array. uint8_t authentication_data[REF_ECDSDA_AUTHENTICATION_DATA_SIZE]; ///< authentication_data buffer. - sgx_key_128bit_t qe3_id; + sgx_key_128bit_t qe_id; }ref_plaintext_ecdsa_data_sdk_t; #pragma pack(pop) diff --git a/QuoteGeneration/quote_wrapper/common/inc/sgx_ql_lib_common.h b/QuoteGeneration/quote_wrapper/common/inc/sgx_ql_lib_common.h index 502e9922..2bfc091e 100644 --- a/QuoteGeneration/quote_wrapper/common/inc/sgx_ql_lib_common.h +++ b/QuoteGeneration/quote_wrapper/common/inc/sgx_ql_lib_common.h @@ -165,12 +165,13 @@ typedef enum _sgx_ql_config_version_t typedef struct _sgx_ql_config_t { sgx_ql_config_version_t version; - sgx_cpu_svn_t cert_cpu_svn; ///< The CPUSVN used to generate the PCK Signature used to certify the attestation key. - sgx_isv_svn_t cert_pce_isv_svn; ///< The PCE ISVSVN used to generate the PCK Signature used to certify the attestation key. - uint32_t cert_data_size; ///< The size of the buffer pointed to by p_cert_data - uint8_t* p_cert_data; ///< The certificaton data used for the quote. - ///todo: It is the assumed to be the PCK Cert Chain. May want to change to support other cert types. -}sgx_ql_config_t; + sgx_cpu_svn_t cert_cpu_svn; ///< The CPUSVN used to generate the PCK Signature used to certify the attestation key. + sgx_isv_svn_t cert_pce_isv_svn; ///< The PCE ISVSVN used to generate the PCK Signature used to certify the attestation key. + uint32_t cert_data_size; ///< The size of the buffer pointed to by p_cert_data + uint8_t *p_cert_data; ///< The certificaton data used for the quote. + ///todo: It is the assumed to be the PCK Cert Chain. May want to change to support other cert types. +} sgx_ql_config_t; + #pragma pack(pop) #define MAX_PARAM_STRING_SIZE (256) @@ -198,7 +199,6 @@ typedef struct _sgx_ql_qve_collateral_t ///< in Base16 encoded DER. A minor version of 1 indicates the CRL’s are formatted in raw binary DER. }; }; - uint32_t tee_type; ///< 0x00000000: SGX or 0x00000081: TDX char *pck_crl_issuer_chain; uint32_t pck_crl_issuer_chain_size; @@ -233,4 +233,13 @@ typedef void (*sgx_ql_logging_callback_t)(sgx_ql_log_level_t level, const char* typedef sgx_ql_qve_collateral_t tdx_ql_qve_collateral_t; #endif +typedef enum _sgx_prod_type_t { + SGX_PROD_TYPE_SGX = 0, + SGX_PROD_TYPE_TDX = 1, +} sgx_prod_type_t; + +#ifndef tdx_ql_qve_collateral_t +typedef sgx_ql_qve_collateral_t tdx_ql_qve_collateral_t; +#endif + #endif //_SGX_QL_LIB_COMMON_H_ diff --git a/QuoteGeneration/quote_wrapper/common/inc/sgx_quote_3.h b/QuoteGeneration/quote_wrapper/common/inc/sgx_quote_3.h index b54e258c..9fc35aed 100644 --- a/QuoteGeneration/quote_wrapper/common/inc/sgx_quote_3.h +++ b/QuoteGeneration/quote_wrapper/common/inc/sgx_quote_3.h @@ -149,8 +149,8 @@ typedef struct _sgx_ql_certification_data_t { typedef struct _sgx_ql_ecdsa_sig_data_t { uint8_t sig[32*2]; ///< Signature over the Quote using the ECDSA Att key. Big Endian. uint8_t attest_pub_key[32*2]; ///< ECDSA Att Public Key. Hash in QE3Report.ReportData. Big Endian - sgx_report_body_t qe3_report; ///< QE3 Report of the QE when the Att key was generated. The ReportData will contain the ECDSA_ID - uint8_t qe3_report_sig[32*2]; ///< Signature of QE3 Report using the Certification Key (PCK for root signing). Big Endian + sgx_report_body_t qe_report; ///< QE3 Report of the QE when the Att key was generated. The ReportData will contain the ECDSA_ID + uint8_t qe_report_sig[32*2]; ///< Signature of QE Report using the Certification Key (PCK for root signing). Big Endian #ifdef _MSC_VER #pragma warning(push) #pragma warning ( disable:4200 ) diff --git a/QuoteGeneration/quote_wrapper/common/inc/sgx_quote_4.h b/QuoteGeneration/quote_wrapper/common/inc/sgx_quote_4.h new file mode 100644 index 00000000..11afbb87 --- /dev/null +++ b/QuoteGeneration/quote_wrapper/common/inc/sgx_quote_4.h @@ -0,0 +1,156 @@ +/* + * Copyright (C) 2011-2021 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: sgx_quote_4.h + * Description: Definition for quote structure. + * + * Quote structure and all relative structure will be defined in this file. + */ + +#ifndef _SGX_QUOTE_4_H_ +#define _SGX_QUOTE_4_H_ + +#include "sgx_quote_3.h" +#include "sgx_report2.h" + + +#pragma pack(push, 1) + +#define TD_INFO_RESERVED_BYTES 112 +typedef struct _tee_info_t /* 512 bytes */ +{ + tee_attributes_t attributes; /* ( 0) TD's attributes */ + tee_attributes_t xfam; /* ( 8) TD's XFAM */ + tee_measurement_t mr_td; /* ( 16) Measurement of the initial contents of the TD */ + tee_measurement_t mr_config_id; /* ( 64) Software defined ID for non-owner-defined configuration on the guest TD. e.g., runtime or OS configuration */ + tee_measurement_t mr_owner; /* (112) Software defined ID for the guest TD's owner */ + tee_measurement_t mr_owner_config; /* (160) Software defined ID for owner-defined configuration of the guest TD, e.g., specific to the workload rather than the runtime or OS */ + tee_measurement_t rt_mr[4]; /* (208) Array of 4(TDX1: NUM_RTMRS is 4) runtime extendable measurement registers */ + uint8_t reserved[TD_INFO_RESERVED_BYTES]; /* (400) Reserved, must be zero */ +} tee_info_t; + + +#define TEE_TCB_SVN_SIZE 16 +typedef struct _tee_tcb_svn_t +{ + uint8_t tcb_svn[TEE_TCB_SVN_SIZE]; +} tee_tcb_svn_t; + +#define TD_TEE_TCB_INFO_RESERVED_BYTES 111 +typedef struct _tee_tcb_info_t +{ + uint8_t valid[8]; /* ( 0) Indicates TEE_TCB_INFO fields which are valid + - 1 in the i-th significant bit reflects that the field starting at byte offset(8*i) + - 0 in the i-th significant bit reflects that either no field start by byte offset(8*i) or that + field is not populated and is set to zero. */ + tee_tcb_svn_t tee_tcb_svn; /* ( 8) TEE_TCB_SVN Array */ + tee_measurement_t mr_seam; /* ( 24) Measurement of the SEAM module */ + tee_measurement_t mr_seam_signer; /* ( 72) Measurement of SEAM module signer. (Not populated for Intel SEAM modules) */ + tee_attributes_t attributes; /* (120) Additional configuration attributes.(Not populated for Intel SEAM modules) */ + uint8_t reserved[TD_TEE_TCB_INFO_RESERVED_BYTES]; /* (128) Reserved, must be zero */ +} tee_tcb_info_t; + +/** The SGX_QL_SGX_QL_ALG_ECDSA_P256 specific data structure. Appears in the signature_data[] of the sgx_quote3_t + * structure. */ +typedef struct _sgx_qe_report_certification_data_t { + sgx_report_body_t qe_report; ///< QE Report of the QE when the Att key was generated. The ReportData will contain the ECDSA_ID + uint8_t qe_report_sig[32*2]; ///< Signature of QE Report using the Certification Key (PCK for root signing). Big Endian +#ifdef _MSC_VER +#pragma warning(push) +#pragma warning ( disable:4200 ) +#endif + uint8_t auth_certification_data[]; ///< Place holder for both the auth_data_t and certification_data_t. Concatenated in that order. +#ifdef _MSC_VER +#pragma warning(pop) +#endif +} sgx_qe_report_certification_data_t; + +typedef struct _sgx_ecdsa_sig_data_v4_t { + uint8_t sig[32*2]; ///< Signature over the Quote using the ECDSA Att key. Big Endian. + uint8_t attest_pub_key[32*2]; ///< ECDSA Att Public Key. Hash in QE Report.ReportData. Big Endian +#ifdef _MSC_VER +#pragma warning(push) +#pragma warning ( disable:4200 ) +#endif + uint8_t certification_data[]; ///< Certification data associated with the cert_key_type +#ifdef _MSC_VER +#pragma warning(pop) +#endif +} sgx_ecdsa_sig_data_v4_t; + +/** The quote header. It is designed to compatible with earlier versions of the quote. */ +typedef struct _sgx_quote4_header_t { + uint16_t version; ///< 0: The version this quote structure. + uint16_t att_key_type; ///< 2: sgx_attestation_algorithm_id_t. Describes the type of signature in the signature_data[] field. + uint32_t tee_type; ///< 4: Type of Trusted Execution Environment for which the Quote has been generated. + /// Supported values: 0 (SGX), 0x81(TDX) + uint32_t reserved; ///< 8: Reserved field. + uint8_t vendor_id[16]; ///< 12: Unique identifier of QE Vendor. + uint8_t user_data[20]; ///< 28: Custom attestation key owner data. +} sgx_quote4_header_t; + +/** SGX Report2 body */ +typedef struct _sgx_report2_body_t { + tee_tcb_svn_t tee_tcb_svn; ///< 0: TEE_TCB_SVN Array + tee_measurement_t mr_seam; ///< 16: Measurement of the SEAM module + tee_measurement_t mrsigner_seam; ///< 64: Measurement of a 3rd party SEAM module’s signer (SHA384 hash). + /// The value is 0’ed for Intel SEAM module + tee_attributes_t seam_attributes; ///< 112: MBZ: TDX 1.0 + tee_attributes_t td_attributes; ///< 120: TD's attributes + tee_attributes_t xfam; ///< 128: TD's XFAM + tee_measurement_t mr_td; ///< 136: Measurement of the initial contents of the TD + tee_measurement_t mr_config_id; ///< 184: Software defined ID for non-owner-defined configuration on the guest TD. e.g., runtime or OS configuration + tee_measurement_t mr_owner; ///< 232: Software defined ID for the guest TD's owner + tee_measurement_t mr_owner_config; ///< 280: Software defined ID for owner-defined configuration of the guest TD, e.g., specific to the workload rather than the runtime or OS + tee_measurement_t rt_mr[4]; ///< 328: Array of 4(TDX1: NUM_RTMRS is 4) runtime extendable measurement registers + tee_report_data_t report_data; ///< 520: Additional report data +}sgx_report2_body_t; + +/** The generic TD quote data structure. This is the common part of the quote. The signature_data[] contains the signature and supporting + * information of the key used to sign the quote and the contents depend on the sgx_quote_sign_type_t value. */ +typedef struct _sgx_quote4_t { + sgx_quote4_header_t header; ///< 0: The quote header. + sgx_report2_body_t report_body; ///< 48: The REPORT of the TD that is attesting remotely. + uint32_t signature_data_len; ///< 656: The length of the signature_data. Varies depending on the type of sign_type. +#ifdef _MSC_VER +#pragma warning(push) +#pragma warning ( disable:4200 ) +#endif + uint8_t signature_data[]; ///< 660: Contains the variable length containing the quote signature and support data for the signature. +#ifdef _MSC_VER +#pragma warning(pop) +#endif +} sgx_quote4_t; + +#pragma pack(pop) + +#endif //_SGX_QUOTE_4_H_ diff --git a/QuoteGeneration/quote_wrapper/common/inc/user_types.h b/QuoteGeneration/quote_wrapper/common/inc/user_types.h index 05174eea..6655b339 100644 --- a/QuoteGeneration/quote_wrapper/common/inc/user_types.h +++ b/QuoteGeneration/quote_wrapper/common/inc/user_types.h @@ -56,10 +56,10 @@ #define REF_ECP256_KEY_SIZE 32 #define REF_NISTP_ECP256_KEY_SIZE (REF_ECP256_KEY_SIZE/sizeof(uint32_t)) #define REF_SHA256_HASH_SIZE 32 -#define REF_RSA_OAEP_2048_MOD_SIZE 256 //hardcode n size to be 256 -#define REF_RSA_OAEP_2048_EXP_SIZE 4 //hardcode e size to be 4 -#define REF_RSA_OAEP_3072_MOD_SIZE 384 //hardcode n size to be 384 -#define REF_RSA_OAEP_3072_EXP_SIZE 4 //hardcode e size to be 4 +#define REF_RSA_OAEP_2048_MOD_SIZE 256 //hardcode n size to be 256 +#define REF_RSA_OAEP_2048_EXP_SIZE 4 //hardcode e size to be 4 +#define REF_RSA_OAEP_3072_MOD_SIZE 384 //hardcode n size to be 384 +#define REF_RSA_OAEP_3072_EXP_SIZE 4 //hardcode e size to be 4 #pragma pack(push, 1) typedef uint8_t ref_sha256_hash_t[REF_SHA256_HASH_SIZE]; @@ -87,10 +87,15 @@ typedef struct _sgx_psvn_t { typedef int errno_t; #endif +#ifndef _MSC_VER #define STATIC_ASSERT_UNUSED_ATTRIBUTE __attribute__((unused)) +#else +#define STATIC_ASSERT_UNUSED_ATTRIBUTE +#endif #define _ASSERT_CONCAT(a, b) a##b #define ASSERT_CONCAT(a, b) _ASSERT_CONCAT(a, b) -#define ref_static_assert(e) typedef char ASSERT_CONCAT(assert_line, __LINE__)[(e)?1:-1] +#define ref_static_assert(e) typedef char ASSERT_CONCAT(assert_line, __LINE__)[(e)?1:-1] \ + STATIC_ASSERT_UNUSED_ATTRIBUTE #define MIN(x, y) (((x)>(y))?(y):(x)) #define MAX(x, y) (((x)>(y))?(x):(y)) #define ARRAY_LENGTH(x) (sizeof(x)/sizeof(x[0])) diff --git a/QuoteGeneration/quote_wrapper/qgs/Makefile b/QuoteGeneration/quote_wrapper/qgs/Makefile new file mode 100644 index 00000000..30faa15c --- /dev/null +++ b/QuoteGeneration/quote_wrapper/qgs/Makefile @@ -0,0 +1,86 @@ +# +# Copyright (C) 2011-2021 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 Settings ######## +TOP_DIR = ../.. +include $(TOP_DIR)/buildenv.mk + +QGS_SRCS = se_trace.c server_main.cpp qgs_server.cpp qgs_log.cpp qgs.message.pb.cc +QGS_OBJS = $(patsubst %.c,%.o,$(patsubst %.cc,%.o,$(patsubst %.cpp,%.o,$(QGS_SRCS)))) + +PROTOBUF_CFLAGS = `pkg-config --cflags protobuf-lite` + +QGS_INC = -I$(SGX_SDK)/include \ + -I$(COMMON_DIR)/inc/internal \ + -I$(TOP_DIR)/qpl/inc \ + -I$(TOP_DIR)/quote_wrapper/tdx_quote +QGS_CFLAGS = -g -MMD $(CFLAGS) $(QGS_INC) $(PROTOBUF_CFLAGS) +QGS_CXXFLAGS = -g -MMD $(CXXFLAGS) $(QGS_INC) $(PROTOBUF_CFLAGS) +ifeq ($(CC_NO_LESS_THAN_8), 1) + QGS_CFLAGS += -fcf-protection=none + QGS_CXXFLAGS += -fcf-protection=none +endif + +DEPENDS = ${QGS_OBJS:.o=.d} + +# SGX related libraries +QGS_LFLAGS = -L$(TOP_DIR)/build/linux -lsgx_tdx_logic -lsgx_pce_logic -ldl \ + -L$(SGX_SDK)/lib64 -lsgx_urts -g +# add protobuf for link +QGS_LFLAGS += `pkg-config --libs protobuf-lite` +# add boost_system for link +QGS_LFLAGS += -lboost_system -lpthread + +vpath %.c $(COMMON_DIR)/src + +-include ${DEPENDS} + +all: qgs + +qgs: $(QGS_OBJS) + $(CXX) -o $@ $^ $(QGS_LFLAGS) + +qgs.message.pb.o: qgs.message.proto + protoc --cpp_out=. $^ + $(CXX) -c qgs.message.pb.cc $(QGS_CXXFLAGS) + +%.o: %.cpp qgs.message.pb.o + $(CXX) -c $(QGS_CXXFLAGS) $< + +%.o: %.c + $(CC) -c $(QGS_CFLAGS) $< + +clean: + rm -f *.pb.* + rm -f *_pb2.* + rm -f *.d + rm -f *.o + rm -f qgs diff --git a/QuoteGeneration/quote_wrapper/qgs/qgs.conf b/QuoteGeneration/quote_wrapper/qgs/qgs.conf new file mode 100644 index 00000000..3d4b74bd --- /dev/null +++ b/QuoteGeneration/quote_wrapper/qgs/qgs.conf @@ -0,0 +1,2 @@ +#set port number +port = 4050 diff --git a/QuoteGeneration/quote_wrapper/qgs/qgs.message.proto b/QuoteGeneration/quote_wrapper/qgs/qgs.message.proto new file mode 100644 index 00000000..c39192d8 --- /dev/null +++ b/QuoteGeneration/quote_wrapper/qgs/qgs.message.proto @@ -0,0 +1,33 @@ +syntax = "proto2"; +package qgs.message; +option optimize_for = LITE_RUNTIME; + +message UUID{ + required bytes value = 1; +} + +message Request{ + message GetQuoteRequest{ + required bytes report = 1; + repeated UUID id_list = 2; + } + + required uint32 type = 1; + oneof msg { + GetQuoteRequest getQuoteRequest = 2; + } +} + + +message Response{ + message GetQuoteResponse{ + required uint32 error_code = 1 [default = 1]; + optional UUID selected_id = 2; + optional bytes quote = 3; + } + + required uint32 type = 1; + oneof msg { + GetQuoteResponse getQuoteResponse = 2; + } +} diff --git a/QuoteGeneration/quote_wrapper/qgs/qgs_log.cpp b/QuoteGeneration/quote_wrapper/qgs/qgs_log.cpp new file mode 100644 index 00000000..a82e62ae --- /dev/null +++ b/QuoteGeneration/quote_wrapper/qgs/qgs_log.cpp @@ -0,0 +1,106 @@ +/* + * Copyright (C) 2011-2021 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 +#include "qgs_log.h" + +static bool _nosyslog = false; + +void qgs_log_init(void) +{ + if (!_nosyslog) { + openlog("qgsd", LOG_CONS|LOG_PID, LOG_USER); + } +} + +void qgs_log_init_ex(bool nosyslog) +{ + // If nosyslog is true, we will output logs to stdout instead of syslog + _nosyslog = nosyslog; + + qgs_log_init(); +} + +void qgs_log_fini(void) +{ + if (!_nosyslog) { + closelog(); + } +} + +extern "C" +void sgx_proc_log_report(int level, const char *format, ...) +{ + int priority = 0; + va_list ap; + // Make sure strlen(format) >= 1 + // so we can always add newline + if (!format || !(*format)) + return;//ignore + va_start(ap, format); + switch(level){ + case QGS_LOG_LEVEL_FATAL: + priority = LOG_CRIT; + break; + case QGS_LOG_LEVEL_ERROR: + priority = LOG_ERR; + break; + case QGS_LOG_LEVEL_WARNING: + priority = LOG_WARNING; + break; + case QGS_LOG_LEVEL_INFO: + priority = LOG_INFO; + break; + default: + return;//ignore + } + if (!_nosyslog) { + vsyslog(priority, format, ap); + } + else { + FILE* stream = nullptr; + if (level <= QGS_LOG_LEVEL_ERROR) { + stream = stderr; + } + else { + stream = stdout; + } + // Automatically add newline + vfprintf(stream, format, ap); + if (format[strlen(format)-1] != '\n') + fprintf(stream, "\n"); + fflush(stream); + } + va_end(ap); +} diff --git a/QuoteGeneration/quote_wrapper/qgs/qgs_log.h b/QuoteGeneration/quote_wrapper/qgs/qgs_log.h new file mode 100644 index 00000000..b06c1931 --- /dev/null +++ b/QuoteGeneration/quote_wrapper/qgs/qgs_log.h @@ -0,0 +1,70 @@ +/* + * Copyright (C) 2011-2021 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 __QGS_LOG_H__ +#define __QGS_LOG_H__ + +#include "se_trace.h" +#define QGS_LOG_LEVEL_FATAL 0 +#define QGS_LOG_LEVEL_ERROR 1 +#define QGS_LOG_LEVEL_WARNING 2 +#define QGS_LOG_LEVEL_INFO 3 +#ifdef __cplusplus +extern "C" { +#endif/*__cplusplus*/ + void qgs_log_init(void); + void qgs_log_init_ex(bool nosyslog); + void qgs_log_fini(void); +#ifdef __cplusplus +}; +#endif/*__cplusplus*/ + +#define QGS_LOG_FATAL(format, args...) \ + do {\ + sgx_proc_log_report(QGS_LOG_LEVEL_FATAL, format, ## args); \ + }while(0) +#define QGS_LOG_ERROR(format, args...) \ + do { \ + sgx_proc_log_report(QGS_LOG_LEVEL_ERROR, format, ## args); \ + }while(0); +#define QGS_LOG_WARN(format, args...) \ + do { \ + sgx_proc_log_report(QGS_LOG_LEVEL_WARNING, format, ## args); \ + }while(0) +#define QGS_LOG_INFO(format, args...) \ + do { \ + sgx_proc_log_report(QGS_LOG_LEVEL_INFO, format, ## args); \ + }while(0) +#define QGS_LOG_INIT() qgs_log_init() +#define QGS_LOG_INIT_EX(nosyslog) qgs_log_init_ex(nosyslog) +#define QGS_LOG_FINI() qgs_log_fini() + +#endif/*__QGS_LOG_H__*/ diff --git a/QuoteGeneration/quote_wrapper/qgs/qgs_msg_wrapper.h b/QuoteGeneration/quote_wrapper/qgs/qgs_msg_wrapper.h new file mode 100644 index 00000000..d19a5578 --- /dev/null +++ b/QuoteGeneration/quote_wrapper/qgs/qgs_msg_wrapper.h @@ -0,0 +1,102 @@ +/* + * Copyright (C) 2011-2021 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 QGS_MSG_WRAPPER_H +#define QGS_MSG_WRAPPER_H + +#include +#include +#include +#include +#include //for uint8_t + + +using data_buffer = std::vector; + +const unsigned HEADER_SIZE = 4; + +template +class QgsMsgWrapper +{ +public: + typedef boost::shared_ptr MessagePointer; + + explicit QgsMsgWrapper(MessagePointer msg = MessagePointer()) + : m_msg(msg) + {} + + void set_msg(MessagePointer msg) { + m_msg = msg; + } + + MessagePointer get_msg() { + return m_msg; + } + + bool pack(data_buffer& buf) const { + if (!m_msg) { + return false; + } + + unsigned msg_size = m_msg->ByteSize(); + buf.resize(HEADER_SIZE + msg_size); + encode_header(buf, msg_size); + return m_msg->SerializeToArray(&buf[HEADER_SIZE], msg_size); + } + + unsigned decode_header(const data_buffer& buf) const { + if (buf.size() < HEADER_SIZE) { + return 0; + } + unsigned msg_size = 0; + for (unsigned i = 0; i < HEADER_SIZE; ++i) { + msg_size = msg_size * 256 + (static_cast(buf[i]) & 0xFF); + } + return msg_size; + } + + bool unpack(const data_buffer& buf) { + return m_msg->ParseFromArray(&buf[HEADER_SIZE], + static_cast(buf.size() - HEADER_SIZE)); + } +private: + void encode_header(data_buffer& buf, unsigned size) const { + assert(buf.size() >= HEADER_SIZE); + buf[0] = static_cast((size >> 24) & 0xFF); + buf[1] = static_cast((size >> 16) & 0xFF); + buf[2] = static_cast((size >> 8) & 0xFF); + buf[3] = static_cast(size & 0xFF); + } + + MessagePointer m_msg; +}; + +#endif /* QGS_MSG_WRAPPER_H */ diff --git a/QuoteGeneration/quote_wrapper/qgs/qgs_server.cpp b/QuoteGeneration/quote_wrapper/qgs/qgs_server.cpp new file mode 100644 index 00000000..5f161f6e --- /dev/null +++ b/QuoteGeneration/quote_wrapper/qgs/qgs_server.cpp @@ -0,0 +1,312 @@ +/* + * Copyright (C) 2011-2021 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 "qgs_log.h" +#include "qgs_server.h" +#include "qgs_msg_wrapper.h" +#include "qgs.message.pb.h" +#include "td_ql_logic.h" +#include "se_trace.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +using namespace std; +using boost::uint8_t; +using namespace qgs::message; +static const int QGS_TIMEOUT = 30; + +namespace intel { namespace sgx { namespace dcap { namespace qgs { + + + class QgsConnection : public boost::enable_shared_from_this + { + public: + using Pointer = boost::shared_ptr; + using RequestPointer = boost::shared_ptr; + using ResponsePointer = boost::shared_ptr; + using ConnectionSet = boost::unordered_set; + static Pointer create(boost::mutex& connection_mtx, + ConnectionSet& connections, + asio::thread_pool& pool, + asio::io_service& io_service) { + return Pointer(new QgsConnection(connection_mtx, connections, pool, + io_service)); + } + + gs::socket& get_socket() { + return m_socket; + } + + void start() { + m_timer.expires_from_now(timeout); + m_timer.async_wait([this](boost::system::error_code ec) { + if (!ec) { + QGS_LOG_ERROR("timeout\n"); + stop(); + } + }); + start_read_header(); + } + + void stop() { + boost::system::error_code ec; + QGS_LOG_INFO("About to shutdown and close socket\n"); + m_socket.shutdown(asio::socket_base::shutdown_both, ec); + m_socket.close(); + { + boost::lock_guard lock(m_connection_mtx); + m_connections.erase(shared_from_this()); + QGS_LOG_INFO("erased a connection, now [%d]\n", m_connections.size()); + } + } + + private: + boost::mutex& m_connection_mtx; + ConnectionSet& m_connections; + asio::thread_pool& m_pool; + gs::socket m_socket; + asio::deadline_timer m_timer; + vector m_readbuf; + QgsMsgWrapper m_packed_request; + + const boost::posix_time::time_duration timeout = + boost::posix_time::seconds(QGS_TIMEOUT); + + QgsConnection(boost::mutex &connection_mtx, + ConnectionSet &connections, + asio::thread_pool &pool, + asio::io_service &io_service) + : m_connection_mtx(connection_mtx), + m_connections(connections), + m_pool(pool), + m_socket(io_service), + m_timer(io_service), + m_packed_request(boost::shared_ptr(new Request())) { + } + + void handle_read_header(const boost::system::error_code& ec) { + std::ostringstream oss; + oss << ec.category().name() << ':' << ec.value(); + QGS_LOG_INFO("handle read header, status [%s]\n", + oss.str().c_str()); + if (!ec) { + QGS_LOG_INFO("Got header!\n"); + unsigned msg_len = m_packed_request.decode_header(m_readbuf); + QGS_LOG_INFO("body should be [%d] bytes!\n", msg_len); + start_read_body(msg_len); + } + } + + void handle_read_body(const boost::system::error_code& ec) { + std::ostringstream oss; + oss << ec.category().name() << ':' << ec.value(); + QGS_LOG_INFO("handle read body status [%s]\n", + oss.str().c_str()); + if (!ec) { + QGS_LOG_INFO("Got body!\n"); + handle_request(); + } + } + + void handle_request() { + if (m_packed_request.unpack(m_readbuf)) { + std::ostringstream oss; + oss << boost::this_thread::get_id(); + QGS_LOG_INFO("unpack message successfully in thread [%s]\n", + oss.str().c_str()); + RequestPointer req = m_packed_request.get_msg(); + asio::post(m_pool, [this, self = shared_from_this(), req] { + boost::system::error_code ec; + ResponsePointer resp = prepare_response(req); + + vector writebuf; + QgsMsgWrapper resp_msg(resp); + resp_msg.pack(writebuf); + std::ostringstream oss1; + oss1 << boost::this_thread::get_id(); + QGS_LOG_INFO("About to write response in thread [%s]\n", + oss1.str().c_str()); + asio::write(m_socket, asio::buffer(writebuf), ec); + m_timer.cancel(); + stop(); + }); + } + } + + void start_read_header() { + m_readbuf.resize(HEADER_SIZE); + asio::async_read(m_socket, asio::buffer(m_readbuf), + boost::bind(&QgsConnection::handle_read_header, + shared_from_this(), + asio::placeholders::error)); + } + + void start_read_body(unsigned msg_len) { + m_readbuf.resize(HEADER_SIZE + msg_len); + asio::mutable_buffers_1 buf = asio::buffer(&m_readbuf[HEADER_SIZE], + msg_len); + asio::async_read(m_socket, buf, + boost::bind(&QgsConnection::handle_read_body, + shared_from_this(), + asio::placeholders::error)); + } + + ResponsePointer prepare_response(RequestPointer req) { + ResponsePointer resp(new Response); + quote3_error_t quote3_ret = SGX_QL_SUCCESS; + + switch (req->type()) { + case Request::MsgCase::kGetQuoteRequest: + { + uint32_t size = 0; + vector quote_buf; + auto get_quote_resp = new Response::GetQuoteResponse(); + resp->set_type(Response::kGetQuoteResponse); + quote3_ret = td_init_quote(PPID_RSA3072_ENCRYPTED, false); + if (SGX_QL_SUCCESS != quote3_ret) { + get_quote_resp->set_error_code(1); + QGS_LOG_ERROR("td_init_quote return 0x%x\n", quote3_ret); + } + else if (SGX_QL_SUCCESS != (quote3_ret = td_get_quote_size(PPID_RSA3072_ENCRYPTED, &size))) { + get_quote_resp->set_error_code(1); + QGS_LOG_ERROR("td_get_quote_size return 0x%x\n", quote3_ret); + } else { + quote_buf.resize(size); + quote3_ret = td_get_quote((sgx_report2_t *)(req->getquoterequest().report().c_str()), + (sgx_quote4_t *)quote_buf.data(), size); + if (SGX_QL_SUCCESS != quote3_ret) { + get_quote_resp->set_error_code(1); + QGS_LOG_ERROR("td_get_quote return 0x%x\n", quote3_ret); + } else { + get_quote_resp->set_error_code(0); + get_quote_resp->set_quote(quote_buf.data(), size); + QGS_LOG_ERROR("td_get_quote return Success\n"); + } + } + resp->set_allocated_getquoteresponse(get_quote_resp); + QGS_LOG_INFO("byte length is: %d\n", resp->ByteSize()); + break; + } + default: + QGS_LOG_ERROR("Whoops, bad request!"); + break; + } + + return resp; + } + }; + + + struct QgsServer::QgsServerImpl + { + using vsock_acceptor = asio::basic_socket_acceptor; + boost::mutex connection_mtx; + boost::unordered_set> connections; + boost::asio::thread_pool pool; + QgsServerImpl(asio::io_service& in_io_service, gs::endpoint& ep) + : pool(4), acceptor(in_io_service, ep), io_service(in_io_service) { + start_accept(); + } + + void start_accept() + { + QgsConnection::Pointer new_connection = + QgsConnection::create(connection_mtx, connections, pool, + io_service); + + acceptor.async_accept(new_connection->get_socket(), + boost::bind(&QgsServerImpl::handle_accept, + this, new_connection, + asio::placeholders::error)); + } + + void handle_accept(QgsConnection::Pointer connection, + const boost::system::error_code& ec) { + if (!ec) { + { + boost::lock_guard lock(connection_mtx); + connections.insert(connection); + QGS_LOG_INFO("Added a new connection, now [%d]\n", connections.size()); + } + connection->start(); + start_accept(); + } + } + + void shutdown() { + QGS_LOG_INFO("About to close acceptor\n"); + acceptor.close(); + std::vector> connections_to_close; + int i = 0; + copy(connections.begin(), connections.end(), back_inserter(connections_to_close)); + for (auto& s : connections_to_close) { + i++; + s->stop(); + } + QGS_LOG_INFO("Stopped [%d] connections, about to clear connection list\n", i); + pool.join(); + QGS_LOG_INFO("Joined thread pool\n"); + io_service.stop(); + QGS_LOG_INFO("Stopped io_service\n"); + connections.clear(); + } + + private: + vsock_acceptor acceptor; + asio::io_service& io_service; + }; + + + QgsServer::QgsServer(asio::io_service& io_service, gs::endpoint& ep) + : d(new QgsServerImpl(io_service, ep)) { + } + + void QgsServer::shutdown() { + d->shutdown(); + } + + QgsServer::~QgsServer() { + } + +}}}} diff --git a/QuoteGeneration/quote_wrapper/qgs/qgs_server.h b/QuoteGeneration/quote_wrapper/qgs/qgs_server.h new file mode 100644 index 00000000..83f96b47 --- /dev/null +++ b/QuoteGeneration/quote_wrapper/qgs/qgs_server.h @@ -0,0 +1,59 @@ +/* + * Copyright (C) 2011-2021 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 QGS_SERVER_H +#define QGS_SERVER_H + +#include +#include + +namespace intel { namespace sgx { namespace dcap { namespace qgs { + + namespace asio = boost::asio; + using gs = asio::generic::stream_protocol; + + class QgsServer { + public: + QgsServer(asio::io_service& io_service, gs::endpoint& ep); + ~QgsServer(); + void shutdown(); + + private: + QgsServer(); + //void start_accept(); + + struct QgsServerImpl; + // d will be deleted in ~QgsServer(); + boost::scoped_ptr d; + }; +}}}} +#endif /* QGS_SERVER_H */ + diff --git a/QuoteGeneration/quote_wrapper/qgs/qgsd.conf b/QuoteGeneration/quote_wrapper/qgs/qgsd.conf new file mode 100644 index 00000000..1f876862 --- /dev/null +++ b/QuoteGeneration/quote_wrapper/qgs/qgsd.conf @@ -0,0 +1,26 @@ +description "Intel(R) TD Quoting Generation Service" + +start on runlevel [2345] +stop on runlevel [!2345] + +respawn +respawn limit 10 5 +normal exit 0 +umask 022 + +expect fork +console none +setuid "qgsd" + +env NAME="qgs" +env QGS_PATH=@qgs_folder@ +env DAEMON="$QGS_PATH/$NAME" + + +pre-start script + test -x $QGS_PATH/$NAME || { stop; exit 0; } +end script + + +env LD_LIBRARY_PATH=$QGS_PATH +exec $QGS_PATH/$NAME diff --git a/QuoteGeneration/quote_wrapper/qgs/qgsd.service b/QuoteGeneration/quote_wrapper/qgs/qgsd.service new file mode 100644 index 00000000..47364197 --- /dev/null +++ b/QuoteGeneration/quote_wrapper/qgs/qgsd.service @@ -0,0 +1,27 @@ +[Unit] +Description=Intel(R) TD Quoting Generation Service +After=syslog.target network.target auditd.service +After=remount-dev-exec.service +Wants=remount-dev-exec.service + +[Service] +User=qgsd +Type=forking +Environment=NAME=qgsd +Environment=LD_LIBRARY_PATH=@qgs_folder@ +WorkingDirectory=@qgs_folder@ +PermissionsStartOnly=true +ExecStart=@qgs_folder@/qgs +ExecStartPre=@qgs_folder@/linksgx.sh +InaccessibleDirectories=/home +ExecReload=/bin/kill -SIGHUP $MAINPID +Restart=on-failure +RestartSec=15s +DevicePolicy=closed +DeviceAllow=/dev/sgx rw +DeviceAllow=/dev/sgx/enclave rw +DeviceAllow=/dev/sgx/provision rw +DeviceAllow=/dev/sgx_enclave rw +DeviceAllow=/dev/sgx_provision rw +[Install] +WantedBy=multi-user.target diff --git a/QuoteGeneration/quote_wrapper/qgs/server_main.cpp b/QuoteGeneration/quote_wrapper/qgs/server_main.cpp new file mode 100644 index 00000000..5e498378 --- /dev/null +++ b/QuoteGeneration/quote_wrapper/qgs/server_main.cpp @@ -0,0 +1,192 @@ +/* + * Copyright (C) 2011-2021 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 "qgs_server.h" +#include "qgs_log.h" +#include +#include +#include + +#define QGS_CONFIG_FILE "/etc/qgs.conf" + +using namespace std; +using namespace intel::sgx::dcap::qgs; +volatile bool reload = false; +static QgsServer* server = NULL; + +void signal_handler(int sig) +{ + switch(sig) + { + case SIGTERM: + if (server) + { + reload = false; + server->shutdown(); + } + break; + case SIGHUP: + if (server) + { + reload = true; + server->shutdown(); + } + break; + default: + break; + } +} + + +int main(int argc, const char* argv[]) +{ + bool no_daemon = false; + unsigned long int port = 0; + char *endptr = NULL; + if (argc > 3) { + cout << "Usage: " << argv[0] << "[--no-daemon] [-p=port_number]" + << endl; + exit(1); + } + + for (int i = 1; i < argc; i++) + { + if (strcmp(argv[i], "--no-daemon") == 0) { + cout << "--no-daemon option found, will not run as a daemon" + << endl; + no_daemon = true; + continue; + } else if (strncmp(argv[i], "-p=", 3 ) == 0) { + if (strspn(argv[i] + 3, "0123456789") != strlen(argv[i] + 3)) { + cout << "Please input valid port number" << endl; + exit(1); + } + errno = 0; + port = strtoul(argv[i] + 3, &endptr, 10); + if (errno || strlen(endptr) || (port > UINT_MAX) ) { + cout << "Please input valid port number" << endl; + exit(1); + } + cout << "port number [" << port << "] found in cmdline" << endl; + continue; + } else { + cout << "Usage: " << argv[0] << "[--no-daemon] [-p=port_number]" + << endl; + exit(1); + } + } + + // Use the port number in QGS_CONFIG_FILE if no valid port number on + // command line + if (port == 0) { + ifstream config_file(QGS_CONFIG_FILE); + if (config_file.is_open()) { + string line; + while(getline(config_file, line)) { + line.erase(remove_if(line.begin(), line.end(), ::isspace), + line.end()); + if(line.empty() || line[0] == '#' ) { + continue; + } + auto delimiterPos = line.find("="); + if (delimiterPos == std::string::npos) { + continue; + } + auto name = line.substr(0, delimiterPos); + if (name.empty()) { + cout << "Wrong config format in " << QGS_CONFIG_FILE + << endl; + exit(1); + } + if( name.compare("port") == 0) { + errno = 0; + endptr = NULL; + port = strtoul(line.substr(delimiterPos + 1).c_str(), + &endptr, 10); + if (errno || strlen(endptr) || (port > UINT_MAX) ) { + cout << "Please input valid port number in " + << QGS_CONFIG_FILE << endl; + exit(1); + } + } + // ignore unrecognized configs. + } + } else { + cout << "Failed to open config file " << QGS_CONFIG_FILE << endl; + } + } + + if (port == 0) { + cout << "Please provide valid port number in cmdline or " + << QGS_CONFIG_FILE << endl; + exit(1); + } + + if(!no_daemon && daemon(0, 0) < 0) { + exit(1); + } + + QGS_LOG_INIT_EX(no_daemon); + signal(SIGCHLD, SIG_IGN); + signal(SIGPIPE, SIG_IGN); + signal(SIGHUP, signal_handler); + signal(SIGTERM, signal_handler); + QGS_LOG_INFO("Added signal handler\n"); + + try { + do { + reload = false; + asio::io_service io_service; + struct sockaddr_vm vm_addr = {}; + vm_addr.svm_family = AF_VSOCK; + vm_addr.svm_reserved1 = 0; + vm_addr.svm_port = port & UINT_MAX; + vm_addr.svm_cid = VMADDR_CID_ANY; + asio::generic::stream_protocol::endpoint ep(&vm_addr, sizeof(vm_addr)); + QGS_LOG_INFO("About to create QgsServer\n"); + server = new QgsServer(io_service, ep); + QGS_LOG_INFO("About to start main loop\n"); + io_service.run(); + QGS_LOG_INFO("Quit main loop\n"); + QgsServer *temp_server = server; + server = NULL; + QGS_LOG_INFO("Deleted QgsServer object\n"); + delete temp_server; + } while (reload == true); + } catch (std::exception &e) { + cerr << e.what() << endl; + exit(1); + } + + QGS_LOG_FINI(); + return 0; +} diff --git a/QuoteGeneration/quote_wrapper/quote/enclave/linux/Makefile b/QuoteGeneration/quote_wrapper/quote/enclave/linux/Makefile index fdadabb7..cee1385c 100644 --- a/QuoteGeneration/quote_wrapper/quote/enclave/linux/Makefile +++ b/QuoteGeneration/quote_wrapper/quote/enclave/linux/Makefile @@ -39,7 +39,6 @@ SONAME := $(AENAME).so QE3_VER:= $(shell awk '$$2 ~ /QE3_VERSION/ { print substr($$3, 2, length($$3) - 2); }' $(COMMON_DIR)/inc/internal/se_version.h) -CONFIG := config.xml TCRYPTO_LIB_NAME := sgx_tcrypto INCLUDE := -I$(SGX_SDK)/include \ diff --git a/QuoteGeneration/quote_wrapper/quote/enclave/linux/config.xml b/QuoteGeneration/quote_wrapper/quote/enclave/linux/config.xml index 9694e366..87a51d12 100644 --- a/QuoteGeneration/quote_wrapper/quote/enclave/linux/config.xml +++ b/QuoteGeneration/quote_wrapper/quote/enclave/linux/config.xml @@ -2,7 +2,7 @@ 1 1 0x1 - 7 + 8 1 1 0 diff --git a/QuoteGeneration/quote_wrapper/quote/enclave/quoting_enclave_3.cpp b/QuoteGeneration/quote_wrapper/quote/enclave/quoting_enclave_3.cpp index 159944b5..33bc9aae 100644 --- a/QuoteGeneration/quote_wrapper/quote/enclave/quoting_enclave_3.cpp +++ b/QuoteGeneration/quote_wrapper/quote/enclave/quoting_enclave_3.cpp @@ -362,7 +362,7 @@ static qe3_error_t get_att_key_based_from_seal_key(sgx_ec256_private_t *p_att_pr } ref_static_assert(sizeof(g_sgx_nistp256_r_m1) == sizeof(sgx_ec256_private_t)); /*Unmatched size*/ - // Calculate pce private key + // Calculate attest key if (sgx_calculate_ecdsa_priv_key((const unsigned char*)hash_drg_output, HASH_DRBG_OUT_LEN, (const unsigned char*)g_sgx_nistp256_r_m1, @@ -398,92 +398,6 @@ static qe3_error_t get_att_key_based_from_seal_key(sgx_ec256_private_t *p_att_pr return ret; } -/** - * The QE_ID is a platform ID that is not associated with a particular SVN but is dependent on the Quoting Enclave's - * (QE) MRSIGNER and its Seal Key. The QE_ID is designed to be dependent on the seal key which is dependent on the - * platform's OWNER_EPOCH value. The OWNER_EPOCH value is set by the platform owner in the BIOS configuration. If the - * BIOS's non-volatile memory (FLASH) is wiped, then the QE_ID will change even if generated by the same QE. This - * prevents the QE_ID from being a true HW ID which cannot be modified by the platform owner. - * - * 1) QE_ID-Seed = EGETKEY(KEYNAME=SEAL_KEY, - * KEY_POLICY=MRSIGNER, - * KEY_ID = 0, - * CPUSVN=0, - * ISVSVN = 0) - * 2) QE_ID = AES128-CMAC(QE_ID-Seed, 16 bytes below) - * - * Byte Position | Value - * 0 | 0x00 - * 1-9 | "QE_ID_DER" (ascii encoded) - * 10-13 | 0x00000000 - * 14-15 | 0x0080 (Big Endian) - * - * @param p_qe_id[Out] Pointer to the QE_ID. Must not be NULL. - * - * @return REFQE3_SUCCESS Successfully created the QE_ID. - * @return REFQE3_ERROR_INVALID_PARAMETER The QE_ID pointer is NULL. - * @return REFQE3_ERROR_CRYPTO Error in the crypto library functions ues to generate the key. - * @return REFQE3_ERROR_OUT_OF_MEMORY Heap memory was exhausted. - * - */ -static qe3_error_t get_qe_id_internal(sgx_key_128bit_t *p_qe_id) -{ - sgx_status_t sgx_status = SGX_SUCCESS; - qe3_error_t ret = REFQE3_SUCCESS; - sgx_key_128bit_t key_tmp; - sgx_key_request_t qe_id_key_req; - - // Defense-in-depth. This is only called internally so should never be NULL - if (NULL == p_qe_id) { - return REFQE3_ERROR_INVALID_PARAMETER; - } - - memset(&key_tmp, 0, sizeof(key_tmp)); - - // Set up the key request structure for Seal Key with both CPUSVN and ISVSVN set to 0 and KeyID set to 0 - memset(&qe_id_key_req, 0, sizeof(sgx_key_request_t)); - qe_id_key_req.key_name = SGX_KEYSELECT_SEAL; // Seal key - qe_id_key_req.key_policy = SGX_KEYPOLICY_MRSIGNER; - qe_id_key_req.attribute_mask.xfrm = 0; - qe_id_key_req.misc_mask = 0xFFFFFFFF; - qe_id_key_req.attribute_mask.flags = ~SGX_FLAGS_MODE64BIT; //set all bits except the SGX_FLAGS_MODE64BIT - sgx_status = sgx_get_key(&qe_id_key_req, &key_tmp); - if (SGX_SUCCESS != sgx_status) { - ret = REFQE3_ERROR_CRYPTO; - goto ret_point; - } - - uint8_t content[16]; - memset(&content, 0, sizeof(content)); - //1-10bytes: "QE_ID_DER"(ascii encoded) - memcpy(content + 1, QE_ID_STRING, 9); - //14-15bytes: 0x0080 (Big Endian) - content[14] = 0x00; - content[15] = 0x80; - - // Generate the mac as QE_ID - ref_static_assert(sizeof(sgx_cmac_128bit_key_t) == sizeof(sgx_key_128bit_t)); - ref_static_assert(sizeof(sgx_cmac_128bit_tag_t) == sizeof(*p_qe_id)); - if ((sgx_status = sgx_rijndael128_cmac_msg(reinterpret_cast(&key_tmp), - content, - sizeof(content), - reinterpret_cast(p_qe_id))) != SGX_SUCCESS) { - if (sgx_status == SGX_ERROR_OUT_OF_MEMORY) { - ret = REFQE3_ERROR_OUT_OF_MEMORY; - } - else { - ret = REFQE3_ERROR_CRYPTO; - } - } - else { - ret = REFQE3_SUCCESS; - } - -ret_point: - (void)memset_s(&key_tmp, sizeof(key_tmp), 0, sizeof(key_tmp)); //clear provisioning key in stack - return ret; -} - /** * An internal function used to verify the ECDSA Blob. It will verify the format of the blob and check the * authenticity using the seal key. If the TCB of the platform has increased since the last time the blob was sealed, @@ -670,7 +584,6 @@ static qe3_error_t verify_blob_internal(uint8_t *p_blob, * @return REFQE3_ERROR_INVALID_PARAMETER One of the inputted parameters in invalid. * @return REFQE3_ECDSABLOB_ERROR There is a problem with the inputted blob format of unsealing. * @return REFQE3_ERROR_UNEXPECTED There is a problem retrieving the current platform TCB or resealing of the BLOB. - * @return REFQE3_ECDSABLOB_ERROR There is a problem with the inputted blob format of unsealing. */ uint32_t verify_blob(uint8_t *p_blob, uint32_t blob_size, @@ -1167,12 +1080,6 @@ uint32_t gen_att_key(uint8_t *p_blob, goto ret_point; } - // Add QE_ID to the ECDSA Blob - ret = get_qe_id_internal(&plaintext_data.qe3_id); - if (REFQE3_SUCCESS != ret) { - goto ret_point; - } - plaintext_data.seal_blob_type = SGX_QL_SEAL_ECDSA_KEY_BLOB; plaintext_data.ecdsa_key_version = SGX_QL_ECDSA_KEY_BLOB_VERSION_0; // Call sgx_seal_data to generate the ECDSA Blob with the updated information @@ -1320,7 +1227,7 @@ uint32_t store_cert_data(ref_plaintext_ecdsa_data_sdk_t *p_plaintext_data, } // Compare the ECDSA_ID passed in matches the value in the existing ECDSA Blob. This should catch keys that haven't been generated before storing - if (0 != memcmp(&local_plaintext_data.ecdsa_id, &p_plaintext_data->qe3_report.body.report_data, sizeof(local_plaintext_data.ecdsa_id))) { //ECDSA_ID is the first 32bytes or REPORT.ReportData + if (0 != memcmp(&local_plaintext_data.ecdsa_id, &p_plaintext_data->qe_report.body.report_data, sizeof(local_plaintext_data.ecdsa_id))) { //ECDSA_ID is the first 32bytes or REPORT.ReportData ret = REFQE3_ERROR_INVALID_PARAMETER; goto ret_point; } @@ -1341,7 +1248,7 @@ uint32_t store_cert_data(ref_plaintext_ecdsa_data_sdk_t *p_plaintext_data, /* Store the current QE PSVN with the blob to indicate what the TCB was when sealed. */ memcpy(&local_plaintext_data.seal_cpu_svn, &report.body.cpu_svn, sizeof(local_plaintext_data.seal_cpu_svn)); - local_plaintext_data.seal_qe3_isv_svn = report.body.isv_svn; + local_plaintext_data.seal_qe_isv_svn = report.body.isv_svn; // For recertification, the PPID does not change. No need to process the PPID information again since it is // unchanged from the previous certification. @@ -1405,7 +1312,7 @@ uint32_t store_cert_data(ref_plaintext_ecdsa_data_sdk_t *p_plaintext_data, } } - local_plaintext_data.cert_qe3_isv_svn = report.body.isv_svn; + local_plaintext_data.cert_qe_isv_svn = report.body.isv_svn; // Copy in the PCE identity used to certify the ECDSA Attestation key memcpy(&local_plaintext_data.cert_cpu_svn, &p_plaintext_data->cert_cpu_svn, sizeof(local_plaintext_data.cert_cpu_svn)); @@ -1414,13 +1321,14 @@ uint32_t store_cert_data(ref_plaintext_ecdsa_data_sdk_t *p_plaintext_data, // Re-copy in the old certification data local_plaintext_data.signature_scheme = p_plaintext_data->signature_scheme; - memcpy(&local_plaintext_data.qe3_report, &p_plaintext_data->qe3_report, sizeof(local_plaintext_data.qe3_report)); - memcpy(&local_plaintext_data.qe3_report_cert_key_sig, &p_plaintext_data->qe3_report_cert_key_sig, sizeof(local_plaintext_data.qe3_report_cert_key_sig)); + memcpy(&local_plaintext_data.qe_report, &p_plaintext_data->qe_report, sizeof(local_plaintext_data.qe_report)); + memcpy(&local_plaintext_data.qe_report_cert_key_sig, &p_plaintext_data->qe_report_cert_key_sig, sizeof(local_plaintext_data.qe_report_cert_key_sig)); local_plaintext_data.certification_key_type = p_plaintext_data->certification_key_type; memcpy_s(&local_plaintext_data.pce_target_info, sizeof(local_plaintext_data.pce_target_info), &p_plaintext_data->pce_target_info, sizeof(p_plaintext_data->pce_target_info)); memcpy_s(&local_plaintext_data.raw_cpu_svn, sizeof(local_plaintext_data.raw_cpu_svn), &p_plaintext_data->raw_cpu_svn, sizeof(p_plaintext_data->raw_cpu_svn)); local_plaintext_data.raw_pce_info.pce_isv_svn = p_plaintext_data->raw_pce_info.pce_isv_svn; local_plaintext_data.raw_pce_info.pce_id = p_plaintext_data->raw_pce_info.pce_id; + memcpy_s(&local_plaintext_data.qe_id, sizeof(local_plaintext_data.qe_id), &p_plaintext_data->qe_id, sizeof(p_plaintext_data->qe_id)); // Call sgx_seal_data to generate the ECDSA Blob with the updated information sgx_status = sgx_seal_data(sizeof(local_plaintext_data), @@ -1540,7 +1448,6 @@ uint32_t gen_quote(uint8_t *p_blob, sgx_ql_ppid_rsa3072_encrypted_cert_info_t *p_cert_encrypted_ppid_info_data; sgx_sha_state_handle_t sha_quote_context = NULL; sgx_report_data_t qe_report_data; - sgx_key_128bit_t qe_id = { 0 }; sgx_ec256_public_t le_att_pub_key; uint8_t verify_result = SGX_EC_INVALID_SIGNATURE; @@ -1667,7 +1574,7 @@ uint32_t gen_quote(uint8_t *p_blob, } // Verify sizeof header.userdata is large enough - ref_static_assert(sizeof(qe_id) <= sizeof(p_quote->header.user_data)); + ref_static_assert(sizeof(plaintext.qe_id) <= sizeof(p_quote->header.user_data)); // Clear out the quote buffer sgx_lfence(); @@ -1689,12 +1596,7 @@ uint32_t gen_quote(uint8_t *p_blob, p_quote->header.att_key_type = SGX_QL_ALG_ECDSA_P256; p_quote->header.pce_svn = pce_isvsvn; // Both are little endian // Sizes of user_data and qe_id were checked above. If here, then sizes are OK without overflow. - ///todo: Verify that the QE_ID matches the value in the blob. - ret = get_qe_id_internal(&qe_id); - if (REFQE3_SUCCESS != ret) { - goto ret_point; - } - memcpy(&p_quote->header.user_data, &qe_id, sizeof(qe_id)); + memcpy(&p_quote->header.user_data, &plaintext.qe_id, sizeof(plaintext.qe_id)); // Copy in Intel's Vender ID memcpy(p_quote->header.vendor_id, g_vendor_id, 16); // Copy the incoming report into Quote body. @@ -1778,10 +1680,10 @@ uint32_t gen_quote(uint8_t *p_blob, memcpy(p_quote_sig->attest_pub_key, &plaintext.ecdsa_att_public_key, sizeof(p_quote_sig->attest_pub_key)); // Add the QE Report to the Quote sig data (the qe report when it was signed by the PCE!). - memcpy(&p_quote_sig->qe3_report, &plaintext.qe3_report.body, sizeof(p_quote_sig->qe3_report)); + memcpy(&p_quote_sig->qe_report, &plaintext.qe_report.body, sizeof(p_quote_sig->qe_report)); // Add the PCE signature - memcpy(p_quote_sig->qe3_report_sig, &plaintext.qe3_report_cert_key_sig, sizeof(p_quote_sig->qe3_report_sig)); + memcpy(p_quote_sig->qe_report_sig, &plaintext.qe_report_cert_key_sig, sizeof(p_quote_sig->qe_report_sig)); // Copy in the Authentication Data if (0 != p_auth_data->size) { diff --git a/QuoteGeneration/quote_wrapper/quote/enclave/win/config.xml b/QuoteGeneration/quote_wrapper/quote/enclave/win/config.xml index bd890737..a243d6db 100644 --- a/QuoteGeneration/quote_wrapper/quote/enclave/win/config.xml +++ b/QuoteGeneration/quote_wrapper/quote/enclave/win/config.xml @@ -2,7 +2,7 @@ 1 1 0x1 - 7 + 8 1 1 0 diff --git a/QuoteGeneration/quote_wrapper/quote/id_enclave/linux/config.xml b/QuoteGeneration/quote_wrapper/quote/id_enclave/linux/config.xml index b2780c0e..bc4a86a7 100644 --- a/QuoteGeneration/quote_wrapper/quote/id_enclave/linux/config.xml +++ b/QuoteGeneration/quote_wrapper/quote/id_enclave/linux/config.xml @@ -2,7 +2,7 @@ 1 1 0x1 - 2 + 3 1 1 0 diff --git a/QuoteGeneration/quote_wrapper/quote/id_enclave/win/config.xml b/QuoteGeneration/quote_wrapper/quote/id_enclave/win/config.xml new file mode 100644 index 00000000..45e81438 --- /dev/null +++ b/QuoteGeneration/quote_wrapper/quote/id_enclave/win/config.xml @@ -0,0 +1,12 @@ + + 1 + 1 + 0x1 + 3 + 1 + 1 + 0 + 0x1000 + 0x1000 + 1 + diff --git a/QuoteGeneration/quote_wrapper/quote/id_enclave/win/id_enclave.rc b/QuoteGeneration/quote_wrapper/quote/id_enclave/win/id_enclave.rc new file mode 100644 index 00000000..bde3efe0 Binary files /dev/null and b/QuoteGeneration/quote_wrapper/quote/id_enclave/win/id_enclave.rc differ diff --git a/QuoteGeneration/quote_wrapper/quote/id_enclave/win/id_enclave.vcxproj b/QuoteGeneration/quote_wrapper/quote/id_enclave/win/id_enclave.vcxproj new file mode 100644 index 00000000..6446a049 --- /dev/null +++ b/QuoteGeneration/quote_wrapper/quote/id_enclave/win/id_enclave.vcxproj @@ -0,0 +1,391 @@ + + + + + CVE-2020-0551-Load-Release + x64 + + + CVE-2020-0551-CF-Release + x64 + + + Debug + Win32 + + + Debug + x64 + + + Release + Win32 + + + Release + x64 + + + + 15.0 + {BE9799F0-84D2-4107-A5DB-A54E22F81F31} + Win32Proj + id_enclave + 10.0.18362.0 + id_enclave + + + + DynamicLibrary + true + v142 + Unicode + + + DynamicLibrary + false + v142 + true + Unicode + + + DynamicLibrary + true + v142 + Unicode + + + DynamicLibrary + false + v142 + true + Unicode + + + DynamicLibrary + false + v142 + true + Unicode + + + DynamicLibrary + false + v142 + true + Unicode + + + + + + + + + + + + + + + + + + + + + + + + + + + false + + + false + + + false + + + false + + + false + + + false + + + + NotUsing + Level4 + MaxSpeed + true + false + true + NDEBUG;ID_ENCLAVE_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) + true + $(SGXSDKInstallPath)\include;$(SGXSDKInstallPath)\include\tlibc;$(SGXSDKInstallPath)\include\libc++;.;..\..\..\inc;..\..\..\..\common\inc\internal;..\..\..\..\common\inc\internal\win;..\..\..\common\inc;..\..\..\..\pce_wrapper\inc;.. + true + true + true + false + false + + + Windows + true + true + true + $(SGXSDKInstallPath)\bin\$(Platform)\Release;$(SolutionDir)$(Platform)\Release\;..\..\..\..\$(Platform)\Release\ + true + sgx_tstdc.lib;sgx_tservice.lib;sgx_trts.lib;sgx_tcxx.lib;sgx_tcrypto.lib + true + true + true + /PDBALTPATH:id_enclave.pdb %(AdditionalOptions) + + + ..\..\..\common\inc\internal + + + + + + + + + NotUsing + Level4 + MaxSpeed + true + false + true + NDEBUG;ID_ENCLAVE_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) + true + $(SGXSDKInstallPath)\include;$(SGXSDKInstallPath)\include\tlibc;$(SGXSDKInstallPath)\include\libc++;.;..\..\..\inc;..\..\..\..\common\inc\internal;..\..\..\..\common\inc\internal\win;..\..\..\common\inc;..\..\..\..\pce_wrapper\inc;.. + true + true + true + false + false + /Qspectre-load-cf + + + Windows + true + true + true + $(SGXSDKInstallPath)\bin\$(Platform)\CVE-2020-0551-CF-Release;$(SolutionDir)$(Platform)\CVE-2020-0551-CF-Release\;..\..\..\..\$(Platform)\CVE-2020-0551-CF-Release\ + true + sgx_tstdc.lib;sgx_tservice.lib;sgx_trts.lib;sgx_tcxx.lib;sgx_tcrypto.lib + true + true + true + /PDBALTPATH:id_enclave.pdb %(AdditionalOptions) + + + ..\..\..\common\inc\internal + + + + + + + + + NotUsing + Level4 + MaxSpeed + true + false + true + NDEBUG;ID_ENCLAVE_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) + true + $(SGXSDKInstallPath)\include;$(SGXSDKInstallPath)\include\tlibc;$(SGXSDKInstallPath)\include\libc++;.;..\..\..\inc;..\..\..\..\common\inc\internal;..\..\..\..\common\inc\internal\win;..\..\..\common\inc;..\..\..\..\pce_wrapper\inc;.. + true + true + true + false + false + /Qspectre-load + + + Windows + true + true + true + $(SGXSDKInstallPath)\bin\$(Platform)\CVE-2020-0551-Load-Release;$(SolutionDir)$(Platform)\CVE-2020-0551-Load-Release\;..\..\..\..\$(Platform)\CVE-2020-0551-Load-Release\ + true + sgx_tstdc.lib;sgx_tservice.lib;sgx_trts.lib;sgx_tcxx.lib;sgx_tcrypto.lib + true + true + true + /PDBALTPATH:id_enclave.pdb %(AdditionalOptions) + + + ..\..\..\common\inc\internal + + + + + + + + + NotUsing + Level4 + Disabled + true + WIN32;_DEBUG;ID_ENCLAVE_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) + true + $(SGXSDKInstallPath)\include;$(SGXSDKInstallPath)\include\tlibc;$(SGXSDKInstallPath)\include\libc++;.;..\..\..\inc;..\..\..\..\common\inc\internal;..\..\..\..\common\inc\internal\win;..\..\..\common\inc;..\..\..\..\pce_wrapper\inc;.. + ProgramDatabase + false + true + true + true + false + Default + true + false + + + Windows + true + $(SGXSDKInstallPath)\bin\$(Platform)\Debug;$(SolutionDir)Debug\;..\..\..\..\Debug + true + sgx_tstdc.lib;sgx_tservice.lib;sgx_trts.lib;sgx_tcxx.lib;sgx_tcrypto.lib + true + true + true + + + ..\..\..\common\inc\internal + + + + + + + + + NotUsing + Level4 + Disabled + true + _DEBUG;ID_ENCLAVE_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) + true + $(SGXSDKInstallPath)\include;$(SGXSDKInstallPath)\include\tlibc;$(SGXSDKInstallPath)\include\libc++;.;..\..\..\inc;..\..\..\..\common\inc\internal;..\..\..\..\common\inc\internal\win;..\..\..\common\inc;..\..\..\..\pce_wrapper\inc;.. + ProgramDatabase + false + true + true + true + false + Default + true + false + + + Windows + true + $(SGXSDKInstallPath)\bin\$(Platform)\Debug;$(SolutionDir)$(Platform)\Debug\;..\..\..\..\$(Platform)\Debug\ + true + sgx_tstdc.lib;sgx_tservice.lib;sgx_trts.lib;sgx_tcxx.lib;sgx_tcrypto.lib + true + true + true + /PDBALTPATH:id_enclave.pdb %(AdditionalOptions) + + + + + + + ..\..\..\common\inc\internal + + + + + NotUsing + Level4 + MaxSpeed + true + false + true + WIN32;NDEBUG;ID_ENCLAVE_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) + true + $(SGXSDKInstallPath)\include;$(SGXSDKInstallPath)\include\tlibc;$(SGXSDKInstallPath)\include\libc++;.;..\..\..\inc;..\..\..\..\common\inc\internal;..\..\..\..\common\inc\internal\win;..\..\..\common\inc;..\..\..\..\pce_wrapper\inc;.. + true + true + true + false + false + + + Windows + true + true + true + $(SGXSDKInstallPath)\bin\$(Platform)\Release;$(SolutionDir)Release\;..\..\..\..\Release\ + true + sgx_tstdc.lib;sgx_tservice.lib;sgx_trts.lib;sgx_tcxx.lib;sgx_tcrypto.lib + true + true + + + ..\..\..\common\inc\internal + + + + + + + + + + + + "$(SGXSDKInstallPath)bin\win32\release\sgx_edger8r.exe" --trusted "%(FullPath)" --search-path "$(SGXSDKInstallPath)include" + Creating proxy/bridge routines + %(Filename)_t.h;%(Filename)_t.c;%(Outputs) + config.xml;%(AdditionalInputs) + "$(SGXSDKInstallPath)bin\win32\release\sgx_edger8r.exe" --trusted "%(FullPath)" --search-path "$(SGXSDKInstallPath)include" + Creating proxy/bridge routines + %(Filename)_t.h;%(Filename)_t.c;%(Outputs) + config.xml;%(AdditionalInputs) + "$(SGXSDKInstallPath)bin\win32\release\sgx_edger8r.exe" --trusted "%(FullPath)" --search-path "$(SGXSDKInstallPath)include" + Creating proxy/bridge routines + %(Filename)_t.h;%(Filename)_t.c;%(Outputs) + config_debug.xml;%(AdditionalInputs) + "$(SGXSDKInstallPath)bin\win32\release\sgx_edger8r.exe" --trusted "%(FullPath)" --search-path "$(SGXSDKInstallPath)include" + Creating proxy/bridge routines + %(Filename)_t.h;%(Filename)_t.c;%(Outputs) + config_debug.xml;%(AdditionalInputs) + "$(SGXSDKInstallPath)bin\win32\release\sgx_edger8r.exe" --trusted "%(FullPath)" --search-path "$(SGXSDKInstallPath)include" + Creating proxy/bridge routines + %(Filename)_t.h;%(Filename)_t.c;%(Outputs) + config.xml;%(AdditionalInputs) + "$(SGXSDKInstallPath)bin\win32\release\sgx_edger8r.exe" --trusted "%(FullPath)" --search-path "$(SGXSDKInstallPath)include" + Creating proxy/bridge routines + %(Filename)_t.h;%(Filename)_t.c;%(Outputs) + config.xml;%(AdditionalInputs) + + + + + ..\..\..\..\common\inc\internal + ..\..\..\..\common\inc\internal + ..\..\..\..\common\inc\internal + ..\..\..\..\common\inc\internal + ..\..\..\..\common\inc\internal + ..\..\..\..\common\inc\internal + + + + + + \ No newline at end of file diff --git a/QuoteGeneration/quote_wrapper/quote/id_enclave/win/id_enclave.vcxproj.filters b/QuoteGeneration/quote_wrapper/quote/id_enclave/win/id_enclave.vcxproj.filters new file mode 100644 index 00000000..28cf0acf --- /dev/null +++ b/QuoteGeneration/quote_wrapper/quote/id_enclave/win/id_enclave.vcxproj.filters @@ -0,0 +1,30 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hh;hpp;hxx;hm;inl;inc;ipp;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + Source Files + + + + + Resource Files + + + + + + \ No newline at end of file diff --git a/QuoteGeneration/quote_wrapper/quote/id_enclave/win/resource.h b/QuoteGeneration/quote_wrapper/quote/id_enclave/win/resource.h new file mode 100644 index 00000000..45961b57 --- /dev/null +++ b/QuoteGeneration/quote_wrapper/quote/id_enclave/win/resource.h @@ -0,0 +1,15 @@ +//{{NO_DEPENDENCIES}} +// Microsoft Visual C++ generated include file. +// Used by qe3.rc +// + +// Next default values for new objects +// +#ifdef APSTUDIO_INVOKED +#ifndef APSTUDIO_READONLY_SYMBOLS +#define _APS_NEXT_RESOURCE_VALUE 101 +#define _APS_NEXT_COMMAND_VALUE 40001 +#define _APS_NEXT_CONTROL_VALUE 1001 +#define _APS_NEXT_SYMED_VALUE 101 +#endif +#endif diff --git a/QuoteGeneration/quote_wrapper/quote/id_enclave/win/targetver.h b/QuoteGeneration/quote_wrapper/quote/id_enclave/win/targetver.h new file mode 100644 index 00000000..87c0086d --- /dev/null +++ b/QuoteGeneration/quote_wrapper/quote/id_enclave/win/targetver.h @@ -0,0 +1,8 @@ +#pragma once + +// Including SDKDDKVer.h defines the highest available Windows platform. + +// If you wish to build your application for a previous Windows platform, include WinSDKVer.h and +// set the _WIN32_WINNT macro to the platform you wish to support before including SDKDDKVer.h. + +#include diff --git a/QuoteGeneration/quote_wrapper/quote/qe_logic.cpp b/QuoteGeneration/quote_wrapper/quote/qe_logic.cpp index e7f32db2..658ecc45 100644 --- a/QuoteGeneration/quote_wrapper/quote/qe_logic.cpp +++ b/QuoteGeneration/quote_wrapper/quote/qe_logic.cpp @@ -62,8 +62,8 @@ #include "se_trace.h" #include "qe3_u.h" +#include "id_enclave_u.h" #ifndef _MSC_VER - #include "id_enclave_u.h" #define QE3_ENCLAVE_NAME "libsgx_qe3.signed.so.1" #define QE3_ENCLAVE_NAME_LEGACY "libsgx_qe3.signed.so" #define ID_ENCLAVE_NAME "libsgx_id_enclave.signed.so.1" @@ -73,6 +73,7 @@ #define _T(x) (x) #else #define QE3_ENCLAVE_NAME _T("qe3.signed.dll") + #define ID_ENCLAVE_NAME _T("id_enclave.signed.dll") #define SGX_QL_QUOTE_CONFIG_LIB_FILE_NAME "dcap_quoteprov.dll" #endif #define ECDSA_BLOB_LABEL "ecdsa_data.blob" @@ -527,7 +528,7 @@ static quote3_error_t get_platform_quote_cert_data(sgx_ql_pck_cert_id_t *p_pck_c // use noinline here to aovid __builtin_return_address(0) returning an address outside libsgx_qe3_logic.so static bool #ifndef _MSC_VER -__attribute__ ((noinline)) +__attribute__ ((noinline)) #endif get_qe_path(const TCHAR *p_file_name, TCHAR *p_file_path, @@ -758,7 +759,6 @@ void unload_qe() } } -#ifndef _MSC_VER static quote3_error_t load_id_enclave(sgx_enclave_id_t* p_qe_eid) { quote3_error_t ret_val = SGX_QL_SUCCESS; @@ -831,6 +831,9 @@ static quote3_error_t load_id_enclave_get_id(sgx_key_128bit_t* p_id) goto CLEANUP; } + SE_TRACE(SE_TRACE_DEBUG, "QE_ID:\n"); + PRINT_BYTE_ARRAY(SE_TRACE_DEBUG, p_id, sizeof(sgx_key_128bit_t)); + CLEANUP: if (0 != id_enclave_eid) { sgx_destroy_enclave(id_enclave_eid); @@ -838,7 +841,6 @@ static quote3_error_t load_id_enclave_get_id(sgx_key_128bit_t* p_id) return ret_val; } -#endif /* This function output encrypted PPID which is encrypted with backend server's pub key * @@ -1150,7 +1152,7 @@ static quote3_error_t certify_key(uint8_t *p_ecdsa_blob, SE_TRACE(SE_TRACE_DEBUG, "\npce_cert_psvn.isv_svn = 0x%04x.\n", p_plaintext_data->cert_pce_info.pce_isv_svn); pce_error = sgx_pce_sign_report(&p_plaintext_data->cert_pce_info.pce_isv_svn, &p_plaintext_data->cert_cpu_svn, - &p_plaintext_data->qe3_report, + &p_plaintext_data->qe_report, (uint8_t*)&pce_sig, sizeof(pce_sig), &sig_out_size); @@ -1161,7 +1163,7 @@ static quote3_error_t certify_key(uint8_t *p_ecdsa_blob, } // Update the signature data and the report that was signed. - if(0 != memcpy_s(&p_plaintext_data->qe3_report_cert_key_sig, sizeof(p_plaintext_data->qe3_report_cert_key_sig), &pce_sig, sizeof(pce_sig))) { + if(0 != memcpy_s(&p_plaintext_data->qe_report_cert_key_sig, sizeof(p_plaintext_data->qe_report_cert_key_sig), &pce_sig, sizeof(pce_sig))) { refqt_ret = SGX_QL_ERROR_UNEXPECTED; goto CLEANUP; } @@ -1438,7 +1440,7 @@ quote3_error_t ECDSA256Quote::ecdsa_init_quote(sgx_ql_cert_key_type_t certificat } //QE's TCB has increased, (a decrease would cause a blob verification failure) then catch it here and generate a //new key - if((qe3_report_body.isv_svn > p_seal_data_plain_text->cert_qe3_isv_svn) || + if((qe3_report_body.isv_svn > p_seal_data_plain_text->cert_qe_isv_svn) || (0 != memcmp(&p_seal_data_plain_text->raw_cpu_svn, &qe3_report_body.cpu_svn, sizeof(p_seal_data_plain_text->raw_cpu_svn)))) { SE_TRACE(SE_TRACE_ERROR, "Platform TCB has increased, Requested certificaiton_key_type doesn't match existing blob's type, Gen and certify new key.\n"); gen_new_key = true; @@ -1464,7 +1466,6 @@ quote3_error_t ECDSA256Quote::ecdsa_init_quote(sgx_ql_cert_key_type_t certificat goto CLEANUP; } -#ifndef _MSC_VER if (NULL == g_ql_global_data.m_qe_id) { @@ -1480,7 +1481,6 @@ quote3_error_t ECDSA256Quote::ecdsa_init_quote(sgx_ql_cert_key_type_t certificat goto CLEANUP; } } -#endif // Determine if the raw-TCB has changed since the blob was last generated or the platform library // has a new TCBm. If the raw-TCB was downgraded, the ECDSA blob will not be accessible and fail @@ -1496,13 +1496,8 @@ quote3_error_t ECDSA256Quote::ecdsa_init_quote(sgx_ql_cert_key_type_t certificat // sgx_ql_get_quote_config(). If it is not available or the API returns SGX_QL_NO_PLATFORM_CERT_DATA, then use // the platform's raw TCB to certify the key. cert_data_size = 0; -#ifndef _MSC_VER pck_cert_id.p_qe3_id = (uint8_t*)g_ql_global_data.m_qe_id; pck_cert_id.qe3_id_size = sizeof(*g_ql_global_data.m_qe_id); -#else - pck_cert_id.p_qe3_id = (uint8_t*)&p_seal_data_plain_text->qe3_id; - pck_cert_id.qe3_id_size = sizeof(p_seal_data_plain_text->qe3_id); -#endif pck_cert_id.p_platform_cpu_svn = &qe3_report_body.cpu_svn; pck_cert_id.p_platform_pce_isv_svn = &pce_isv_svn; pck_cert_id.p_encrypted_ppid = encrypted_ppid; @@ -1543,18 +1538,18 @@ quote3_error_t ECDSA256Quote::ecdsa_init_quote(sgx_ql_cert_key_type_t certificat plaintext_data.raw_pce_info.pce_isv_svn = pce_isv_svn; plaintext_data.raw_pce_info.pce_id = p_seal_data_plain_text->cert_pce_info.pce_id; // For recertification, pull out out the certification data from the blob that doesn't need to change. - if(0 != memcpy_s(&plaintext_data.qe3_report, sizeof(plaintext_data.qe3_report), - &p_seal_data_plain_text->qe3_report, sizeof(p_seal_data_plain_text->qe3_report))) { + if(0 != memcpy_s(&plaintext_data.qe_report, sizeof(plaintext_data.qe_report), + &p_seal_data_plain_text->qe_report, sizeof(p_seal_data_plain_text->qe_report))) { refqt_ret = SGX_QL_ERROR_UNEXPECTED; goto CLEANUP; } -#ifndef _MSC_VER - if (0 != memcpy_s(&plaintext_data.qe3_id, sizeof(plaintext_data.qe3_id), + + if (0 != memcpy_s(&plaintext_data.qe_id, sizeof(plaintext_data.qe_id), g_ql_global_data.m_qe_id, sizeof(*g_ql_global_data.m_qe_id))) { refqt_ret = SGX_QL_ERROR_UNEXPECTED; goto CLEANUP; } -#endif + plaintext_data.signature_scheme = p_seal_data_plain_text->signature_scheme; ///todo: Not likely that the signature scheme changed but may want to re-get from PCE. It is just more involved. if(0 != memcpy_s(&plaintext_data.pce_target_info, sizeof(plaintext_data.pce_target_info), &pce_target_info, sizeof(pce_target_info))) { @@ -1596,18 +1591,18 @@ quote3_error_t ECDSA256Quote::ecdsa_init_quote(sgx_ql_cert_key_type_t certificat plaintext_data.raw_pce_info.pce_isv_svn = pce_isv_svn; plaintext_data.raw_pce_info.pce_id = p_seal_data_plain_text->cert_pce_info.pce_id; // For recertification, pull out out the certification data from the blob that doesn't need to change. - if(0 != memcpy_s(&plaintext_data.qe3_report, sizeof(plaintext_data.qe3_report), - &p_seal_data_plain_text->qe3_report, sizeof(p_seal_data_plain_text->qe3_report))){ + if(0 != memcpy_s(&plaintext_data.qe_report, sizeof(plaintext_data.qe_report), + &p_seal_data_plain_text->qe_report, sizeof(p_seal_data_plain_text->qe_report))){ refqt_ret = SGX_QL_ERROR_UNEXPECTED; goto CLEANUP; } -#ifndef _MSC_VER - if (0 != memcpy_s(&plaintext_data.qe3_id, sizeof(plaintext_data.qe3_id), + + if (0 != memcpy_s(&plaintext_data.qe_id, sizeof(plaintext_data.qe_id), g_ql_global_data.m_qe_id, sizeof(*g_ql_global_data.m_qe_id))) { refqt_ret = SGX_QL_ERROR_UNEXPECTED; goto CLEANUP; } -#endif + plaintext_data.signature_scheme = p_seal_data_plain_text->signature_scheme; ///todo: Not likely that the signature scheme changed but may want to re-get from PCE. It is just more involved. if(0 != memcpy_s(&plaintext_data.pce_target_info, sizeof(plaintext_data.pce_target_info), &pce_target_info, sizeof(pce_target_info))) { @@ -1677,7 +1672,7 @@ quote3_error_t ECDSA256Quote::ecdsa_init_quote(sgx_ql_cert_key_type_t certificat refqt_ret = SGX_QL_ERROR_UNEXPECTED; goto CLEANUP; } -#ifndef _MSC_VER + if (NULL == g_ql_global_data.m_qe_id) { @@ -1693,20 +1688,14 @@ quote3_error_t ECDSA256Quote::ecdsa_init_quote(sgx_ql_cert_key_type_t certificat goto CLEANUP; } } -#endif + // Certify the key // Get the certification data from the platform, if available p_sealed_ecdsa = reinterpret_cast(g_ql_global_data.m_ecdsa_blob); - p_seal_data_plain_text = reinterpret_cast(g_ql_global_data.m_ecdsa_blob + sizeof(sgx_sealed_data_t) + p_sealed_ecdsa->plain_text_offset); cert_data_size = 0; memset(&plaintext_data, 0, sizeof(plaintext_data)); -#ifndef _MSC_VER pck_cert_id.p_qe3_id = (uint8_t*)g_ql_global_data.m_qe_id; pck_cert_id.qe3_id_size = sizeof(*g_ql_global_data.m_qe_id); -#else - pck_cert_id.p_qe3_id = (uint8_t*)&p_seal_data_plain_text->qe3_id; - pck_cert_id.qe3_id_size = sizeof(p_seal_data_plain_text->qe3_id); -#endif pck_cert_id.p_platform_cpu_svn = &qe3_report.body.cpu_svn; pck_cert_id.p_platform_pce_isv_svn = &g_ql_global_data.m_pce_info.pce_isv_svn; pck_cert_id.p_encrypted_ppid = encrypted_ppid; @@ -1747,11 +1736,16 @@ quote3_error_t ECDSA256Quote::ecdsa_init_quote(sgx_ql_cert_key_type_t certificat } plaintext_data.raw_pce_info.pce_isv_svn = g_ql_global_data.m_pce_info.pce_isv_svn; plaintext_data.raw_pce_info.pce_id = g_ql_global_data.m_pce_info.pce_id; - if(0 != memcpy_s(&plaintext_data.qe3_report, sizeof(plaintext_data.qe3_report), + if(0 != memcpy_s(&plaintext_data.qe_report, sizeof(plaintext_data.qe_report), &qe3_report, sizeof(qe3_report))) { refqt_ret = SGX_QL_ERROR_UNEXPECTED; goto CLEANUP; } + if (0 != memcpy_s(&plaintext_data.qe_id, sizeof(plaintext_data.qe_id), + g_ql_global_data.m_qe_id, sizeof(*g_ql_global_data.m_qe_id))) { + refqt_ret = SGX_QL_ERROR_UNEXPECTED; + goto CLEANUP; + } plaintext_data.signature_scheme = PCE_NIST_P256_ECDSA_SHA256; if(0 != memcpy_s(&plaintext_data.pce_target_info, sizeof(plaintext_data.pce_target_info), &pce_target_info, sizeof(pce_target_info))) { @@ -1770,8 +1764,6 @@ quote3_error_t ECDSA256Quote::ecdsa_init_quote(sgx_ql_cert_key_type_t certificat SE_TRACE(SE_TRACE_DEBUG, "Failed to cerify key.\n"); goto CLEANUP; } - SE_TRACE(SE_TRACE_DEBUG, "QE3_ID:\n"); - PRINT_BYTE_ARRAY(SE_TRACE_DEBUG, &p_seal_data_plain_text->qe3_id, sizeof(p_seal_data_plain_text->qe3_id)); SE_TRACE(SE_TRACE_DEBUG, "Generated and certified a new key. ECDSA_ID:\n"); PRINT_BYTE_ARRAY(SE_TRACE_DEBUG, &qe3_report.body.report_data, sizeof(sgx_sha256_hash_t)); @@ -1952,8 +1944,8 @@ quote3_error_t ECDSA256Quote::ecdsa_get_quote_size(sgx_ql_cert_key_type_t certif p_sealed_ecdsa = reinterpret_cast(g_ql_global_data.m_ecdsa_blob); p_seal_data_plain_text = reinterpret_cast(g_ql_global_data.m_ecdsa_blob + sizeof(sgx_sealed_data_t) + p_sealed_ecdsa->plain_text_offset); cert_data_size = 0; - pck_cert_id.p_qe3_id = (uint8_t*)&p_seal_data_plain_text->qe3_id; - pck_cert_id.qe3_id_size = sizeof(p_seal_data_plain_text->qe3_id); + pck_cert_id.p_qe3_id = (uint8_t*)&p_seal_data_plain_text->qe_id; + pck_cert_id.qe3_id_size = sizeof(p_seal_data_plain_text->qe_id); pck_cert_id.p_platform_cpu_svn = &qe3_report_body.cpu_svn; pck_cert_id.p_platform_pce_isv_svn = &pce_isv_svn; pck_cert_id.p_encrypted_ppid = NULL; @@ -2197,8 +2189,8 @@ quote3_error_t ECDSA256Quote::ecdsa_get_quote(const sgx_report_t *p_app_report, p_sealed_ecdsa = reinterpret_cast(g_ql_global_data.m_ecdsa_blob); p_seal_data_plain_text = reinterpret_cast(g_ql_global_data.m_ecdsa_blob + sizeof(sgx_sealed_data_t) + p_sealed_ecdsa->plain_text_offset); cert_data_size = 0; - pck_cert_id.p_qe3_id = (uint8_t*)&p_seal_data_plain_text->qe3_id; - pck_cert_id.qe3_id_size = sizeof(p_seal_data_plain_text->qe3_id); + pck_cert_id.p_qe3_id = (uint8_t*)&p_seal_data_plain_text->qe_id; + pck_cert_id.qe3_id_size = sizeof(p_seal_data_plain_text->qe_id); pck_cert_id.p_platform_cpu_svn = &qe3_report_body.cpu_svn; pck_cert_id.p_platform_pce_isv_svn = &cur_pce_isv_svn; pck_cert_id.p_encrypted_ppid = NULL; @@ -2536,4 +2528,3 @@ quote3_error_t ECDSA256Quote::get_quote(const sgx_report_t *p_app_report, return(ret_val); } - diff --git a/QuoteGeneration/quote_wrapper/quote/win/qe3_core_wrapper_static.vcxproj b/QuoteGeneration/quote_wrapper/quote/win/qe3_core_wrapper_static.vcxproj index 61c754c1..27a1c236 100644 --- a/QuoteGeneration/quote_wrapper/quote/win/qe3_core_wrapper_static.vcxproj +++ b/QuoteGeneration/quote_wrapper/quote/win/qe3_core_wrapper_static.vcxproj @@ -110,7 +110,8 @@ true - "$(SGXSDKInstallPath)\bin\win32\Release\sgx_edger8r.exe" ..\enclave\qe3.edl --search-path ..\..\..\external\sgxssl\Windows\package\include;..\..\..\common\inc --untrusted + "$(SGXSDKInstallPath)\bin\win32\Release\sgx_edger8r.exe" ..\enclave\qe3.edl --search-path ..\..\..\common\inc --untrusted +"$(SGXSDKInstallPath)\bin\win32\Release\sgx_edger8r.exe" ..\id_enclave\id_enclave.edl --search-path ..\..\..\common\inc --untrusted true @@ -143,7 +144,8 @@ true - "$(SGXSDKInstallPath)\bin\win32\Release\sgx_edger8r.exe" ..\enclave\qe3.edl --search-path ..\..\..\external\sgxssl\Windows\package\include;..\..\..\common\inc --untrusted + "$(SGXSDKInstallPath)\bin\win32\Release\sgx_edger8r.exe" ..\enclave\qe3.edl --search-path ..\..\..\common\inc --untrusted +"$(SGXSDKInstallPath)\bin\win32\Release\sgx_edger8r.exe" ..\id_enclave\id_enclave.edl --search-path ..\..\..\common\inc --untrusted sgx_urts.lib;sgx_pce_wrapper_static.lib;%(AdditionalDependencies) @@ -186,7 +188,8 @@ true - "$(SGXSDKInstallPath)\bin\win32\Release\sgx_edger8r.exe" ..\enclave\qe3.edl --search-path ..\..\..\common\inc --untrusted + "$(SGXSDKInstallPath)\bin\win32\Release\sgx_edger8r.exe" ..\enclave\qe3.edl --search-path ..\..\..\common\inc --untrusted +"$(SGXSDKInstallPath)\bin\win32\Release\sgx_edger8r.exe" ..\id_enclave\id_enclave.edl --search-path ..\..\..\common\inc --untrusted @@ -215,7 +218,8 @@ true - "$(SGXSDKInstallPath)\bin\win32\Release\sgx_edger8r.exe" ..\enclave\qe3.edl --search-path ..\..\..\common\inc --untrusted + "$(SGXSDKInstallPath)\bin\win32\Release\sgx_edger8r.exe" ..\enclave\qe3.edl --search-path ..\..\..\common\inc --untrusted +"$(SGXSDKInstallPath)\bin\win32\Release\sgx_edger8r.exe" ..\id_enclave\id_enclave.edl --search-path ..\..\..\common\inc --untrusted sgx_urts.lib;sgx_pce_wrapper_static.lib;%(AdditionalDependencies) @@ -227,11 +231,13 @@ + + @@ -265,6 +271,9 @@ $(ProjectDir)%(Filename)_u.h;$(ProjectDir)%(Filename)_u.c;%(Outputs) + + + diff --git a/QuoteGeneration/quote_wrapper/quote/win/qe3_core_wrapper_static.vcxproj.filters b/QuoteGeneration/quote_wrapper/quote/win/qe3_core_wrapper_static.vcxproj.filters index 5fcbc917..a155441f 100644 --- a/QuoteGeneration/quote_wrapper/quote/win/qe3_core_wrapper_static.vcxproj.filters +++ b/QuoteGeneration/quote_wrapper/quote/win/qe3_core_wrapper_static.vcxproj.filters @@ -26,6 +26,9 @@ Header Files + + Generated Files + @@ -37,10 +40,18 @@ Generated Files + + Generated Files + Source Files + + + Source Files + + \ No newline at end of file diff --git a/QuoteGeneration/quote_wrapper/tdx_attest/Makefile.sample b/QuoteGeneration/quote_wrapper/tdx_attest/Makefile.sample new file mode 100644 index 00000000..6d40b0f4 --- /dev/null +++ b/QuoteGeneration/quote_wrapper/tdx_attest/Makefile.sample @@ -0,0 +1,42 @@ +# +# Copyright (C) 2011-2019 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. +# +# +ifdef DEBUG + CFLAGS = -O0 -ggdb +else + CFLAGS = -O2 +endif + +test_tdx_attest: test_tdx_attest.c + $(CC) $(CFLAGS) $^ -l:libtdx_attest.so.1 -o $@ + +clean: + rm -rf ./test_tdx_attest + diff --git a/QuoteGeneration/quote_wrapper/tdx_attest/linux/Makefile b/QuoteGeneration/quote_wrapper/tdx_attest/linux/Makefile new file mode 100644 index 00000000..b06d426f --- /dev/null +++ b/QuoteGeneration/quote_wrapper/tdx_attest/linux/Makefile @@ -0,0 +1,85 @@ +# +# Copyright (C) 2011-2021 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. +# +# + +######## Basic Settings ######## +TOP_DIR = ../../.. +include $(TOP_DIR)/buildenv.mk + +######## Tdx_Attest Settings ######## +Protobuf_CFLAGS = `pkg-config --cflags libprotobuf-c` +Protobuf_LFLAGS = `pkg-config --libs libprotobuf-c` + +Tdx_Attest_C_Files := ../tdx_attest.c + +Tdx_Attest_Include_Paths := -I./ + +Tdx_Attest_C_Flags := $(CFLAGS) -g -MMD -fPIC -Wno-attributes $(Tdx_Attest_Include_Paths) + +LDUFLAGS := $(COMMON_LDFLAGS) +LDUFLAGS += -Wl,--version-script=tdx_attest.lds -Wl,--gc-sections -g + + +Tdx_Attest_C_Objects := $(Tdx_Attest_C_Files:.c=.o) +Tdx_Attest_C_Depends := $(Tdx_Attest_C_Files:.c=.d) + +Tdx_Attest_Name := libtdx_attest.so +-include $(Tdx_Attest_C_Depends) + +.PHONY: all test_app +all: install_lib + +install_lib: $(Tdx_Attest_Name) | $(BUILD_DIR) + @$(CP) $(Tdx_Attest_Name) $| + +######## Tdx_Attest Objects ######## +$(Tdx_Attest_Name): qgs.message.pb-c.o $(Tdx_Attest_C_Objects) + $(CC) $^ -shared -shared -Wl,-soname=$@.$(SGX_MAJOR_VER) $(Protobuf_LFLAGS) $(LDUFLAGS) -o $@ + @echo "LINK => $@" + +$(Tdx_Attest_C_Objects): %.o: qgs.message.pb-c.o %.c + $(CC) $(Tdx_Attest_C_Flags) -c $(Tdx_Attest_C_Files) -o $@ + +qgs.message.pb-c.o: ../../qgs/qgs.message.proto + protoc --c_out=. --proto_path=../../ ../../qgs/qgs.message.proto + $(CC) -c qgs/qgs.message.pb-c.c -I. $(Protobuf_CFLAGS) $(Tdx_Attest_C_Flags) + +test_app: $(Tdx_Attest_Name) ../test_tdx_attest.c ../tdx_attest.h + $(CC) -I. -L./linux ../test_tdx_attest.c -L. -ltdx_attest -g -o $@ + +$(BUILD_DIR): + @$(MKDIR) $@ + +.PHONY: clean + +clean: + @rm -rf $(Tdx_Attest_Name) $(Tdx_Attest_C_Objects) $(Tdx_Attest_C_Depends) qgs.message.pb-c.o ./qgs test_app + + diff --git a/QuoteGeneration/quote_wrapper/tdx_attest/linux/tdx_attest.lds b/QuoteGeneration/quote_wrapper/tdx_attest/linux/tdx_attest.lds new file mode 100644 index 00000000..7e5958a0 --- /dev/null +++ b/QuoteGeneration/quote_wrapper/tdx_attest/linux/tdx_attest.lds @@ -0,0 +1,10 @@ +{ +global: + tdx_att_get_quote; + tdx_att_free_quote; + tdx_att_get_report; + tdx_att_extend; + tdx_att_get_supported_att_key_ids; +local: + *; +}; diff --git a/QuoteGeneration/quote_wrapper/tdx_attest/tdx_attest.c b/QuoteGeneration/quote_wrapper/tdx_attest/tdx_attest.c new file mode 100644 index 00000000..24183b55 --- /dev/null +++ b/QuoteGeneration/quote_wrapper/tdx_attest/tdx_attest.c @@ -0,0 +1,494 @@ +/* + * Copyright (C) 2011-2021 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 "qgs/qgs.message.pb-c.h" +#include +#include +#include "tdx_attest.h" + +#include +#include +#include +#include +#include +#include +#include +#include +// For strtoul +#include +#include +#include + +#define TDX_ATTEST_DEV_PATH "/dev/tdx-attest" +#define CFG_FILE_PATH "/etc/tdx-attest.conf" +//TODO: Should include kernel header +#define TDX_CMD_GET_TDREPORT _IOWR('T', 0x01, __u64) +#define TDX_CMD_EXTEND_RTMR _IOR('T', 0x04, __u64) +#define TDX_CMD_GET_EXTEND_SIZE _IOR('T', 0x05, __u64) +#define TDX_CMD_GEN_QUOTE _IOR('T', 0x02, __u64) + +#ifdef DEBUG +#define TDX_TRACE \ + do { \ + fprintf(stderr, "\n[%s:%d] ", __FILE__, __LINE__); \ + perror(NULL); \ + }while(0) +#else +#define TDX_TRACE +#endif + +#pragma pack(push, 1) +// It's a 4*4K byte structure +typedef struct _get_quote_blob_t +{ + // Following fields are used for transport layer, LE + uint64_t version; + uint64_t status; + uint32_t in_len; + uint32_t out_len; + // Following fields are consumed by QGS and this library + uint8_t trans_len[4]; // BE + uint8_t p_buf[4 * 4 * 1024 - 28]; +} get_quote_blob_t; + +typedef struct _get_quote_ioctl_arg_t +{ + void *p_blob; + size_t len; +} get_quote_ioctl_arg_t; +#pragma pack(pop) + +static const unsigned HEADER_SIZE = 4; +static const tdx_uuid_t g_intel_tdqe_uuid = {TDX_SGX_ECDSA_ATTESTATION_ID}; + +static unsigned int get_vsock_port(void) +{ + FILE *p_config_fd = NULL; + char *p_line = NULL; + char *p = NULL; + size_t line_len = 0; + long long_num = 0; + unsigned int port = 0; + + p_config_fd = fopen(CFG_FILE_PATH, "r"); + if (NULL == p_config_fd) { + TDX_TRACE; + return 0; + } + while(-1 != getline(&p_line, &line_len, p_config_fd)) { + char temp[11] = {0}; + int number = 0; + int ret = sscanf(p_line, " %10[#]", temp); + if (ret == 1) { + continue; + } + /* leading or trailing white space are ignored, white space around '=' + are also ignored. The number should no longer than 10 characters. + Trailing non-whitespace are not allowed. */ + ret = sscanf(p_line, " port = %10[0-9] %n", temp, &number); + /* Make sure number is positive then make the cast. It's not likely to + have a negtive value, just a defense-in-depth. The cast is used to + suppress the -Wsign-compare warning. */ + if (ret == 1 && number > 0 && ((size_t)number < line_len) + && !p_line[number]) { + errno = 0; + long_num = strtol(temp, &p, 10); + if (p == temp) { + TDX_TRACE; + port = 0; + break; + } + + // make sure that no range error occurred + if (errno == ERANGE || long_num > UINT_MAX) { + TDX_TRACE; + port = 0; + break; + } + + // range is ok, so we can convert to int + port = (unsigned int)long_num & 0xFFFFFFFF; + #ifdef DBUG + fprintf(stdout, "\nGet the vsock port number [%u]\n", port); + #endif + break; + } + } + + /* p_line is allocated by sscanf */ + free(p_line); + fclose(p_config_fd); + + return port; +} + +static tdx_attest_error_t get_tdx_report( + int devfd, + const tdx_report_data_t *p_tdx_report_data, + tdx_report_t *p_tdx_report) +{ + if (-1 == devfd) { + return TDX_ATTEST_ERROR_UNEXPECTED; + } + if (!p_tdx_report) { + fprintf(stderr, "\nNeed to input TDX report."); + return TDX_ATTEST_ERROR_INVALID_PARAMETER; + } + + uint8_t tdx_report[TDX_REPORT_SIZE] = {0}; + if (p_tdx_report_data) { + memcpy(tdx_report, p_tdx_report_data->d, sizeof(p_tdx_report_data->d)); + } + + if (-1 == ioctl(devfd, TDX_CMD_GET_TDREPORT, tdx_report)) { + TDX_TRACE; + return TDX_ATTEST_ERROR_REPORT_FAILURE; + } + memcpy(p_tdx_report->d, tdx_report, sizeof(p_tdx_report->d)); + return TDX_ATTEST_SUCCESS; +} + +tdx_attest_error_t tdx_att_get_quote( + const tdx_report_data_t *p_tdx_report_data, + const tdx_uuid_t *p_att_key_id_list, + uint32_t list_size, + tdx_uuid_t *p_att_key_id, + uint8_t **pp_quote, + uint32_t *p_quote_size, + uint32_t flags) +{ + int s = -1; + int devfd = -1; + int use_tdvmcall = 1; + uint32_t quote_size = 0; + uint32_t recieved_bytes = 0; + uint32_t in_msg_size = 0; + unsigned int vsock_port = 0; + tdx_attest_error_t ret = TDX_ATTEST_ERROR_UNEXPECTED; + get_quote_blob_t *p_get_quote_blob = NULL; + tdx_report_t tdx_report; + uint32_t msg_size = 0; + Qgs__Message__Response *resp; + Qgs__Message__Request request = QGS__MESSAGE__REQUEST__INIT; + Qgs__Message__Request__GetQuoteRequest get_quote_request = + QGS__MESSAGE__REQUEST__GET_QUOTE_REQUEST__INIT; + + if ((!p_att_key_id_list && list_size) || + (p_att_key_id_list && !list_size)) { + ret = TDX_ATTEST_ERROR_INVALID_PARAMETER; + goto ret_point; + } + if (!pp_quote) { + ret = TDX_ATTEST_ERROR_INVALID_PARAMETER; + goto ret_point; + } + if (flags) { + //TODO: I think we need to have a runtime version to make this flag usable. + ret = TDX_ATTEST_ERROR_INVALID_PARAMETER; + goto ret_point; + } + + // Currently only intel TDQE are supported + if (1 < list_size) { + ret = TDX_ATTEST_ERROR_INVALID_PARAMETER; + } + if (p_att_key_id_list && memcmp(p_att_key_id_list, &g_intel_tdqe_uuid, + sizeof(g_intel_tdqe_uuid))) { + ret = TDX_ATTEST_ERROR_INVALID_PARAMETER; + } + *pp_quote = NULL; + memset(&tdx_report, 0, sizeof(tdx_report)); + p_get_quote_blob = (get_quote_blob_t *)malloc(sizeof(get_quote_blob_t)); + if (!p_get_quote_blob) { + ret = TDX_ATTEST_ERROR_OUT_OF_MEMORY; + goto ret_point; + } + + devfd = open(TDX_ATTEST_DEV_PATH, O_RDWR | O_SYNC); + if (-1 == devfd) { + TDX_TRACE; + ret = TDX_ATTEST_ERROR_DEVICE_FAILURE; + goto ret_point; + } + + ret = get_tdx_report(devfd, p_tdx_report_data, &tdx_report); + if (TDX_ATTEST_SUCCESS != ret) { + goto ret_point; + } + + request.type = QGS__MESSAGE__REQUEST__MSG_GET_QUOTE_REQUEST; + get_quote_request.report.len = sizeof(tdx_report.d); + get_quote_request.report.data = tdx_report.d; + request.msg_case = QGS__MESSAGE__REQUEST__MSG_GET_QUOTE_REQUEST; + request.getquoterequest = &get_quote_request; + + // Add the size header + msg_size = (uint32_t)qgs__message__request__get_packed_size(&request); + p_get_quote_blob->trans_len[0] = (uint8_t)((msg_size >> 24) & 0xFF); + p_get_quote_blob->trans_len[1] = (uint8_t)((msg_size >> 16) & 0xFF); + p_get_quote_blob->trans_len[2] = (uint8_t)((msg_size >> 8) & 0xFF); + p_get_quote_blob->trans_len[3] = (uint8_t)(msg_size & 0xFF); + + // Serialization + qgs__message__request__pack(&request, p_get_quote_blob->p_buf); + + do { + vsock_port = get_vsock_port(); + if (!vsock_port) { + syslog(LOG_INFO, "libtdx_attest: fallback to tdvmcall mode."); + break; + } + s = socket(AF_VSOCK, SOCK_STREAM, 0); + if (-1 == s) { + syslog(LOG_INFO, "libtdx_attest: fallback to tdvmcall mode."); + break; + } + struct sockaddr_vm vm_addr; + memset(&vm_addr, 0, sizeof(vm_addr)); + vm_addr.svm_family = AF_VSOCK; + vm_addr.svm_reserved1 = 0; + vm_addr.svm_port = vsock_port; + vm_addr.svm_cid = VMADDR_CID_HOST; + if (connect(s, (struct sockaddr *)&vm_addr, sizeof(vm_addr))) { + syslog(LOG_INFO, "libtdx_attest: fallback to tdvmcall mode."); + break; + } + + // Write to socket + if (HEADER_SIZE + msg_size != send(s, p_get_quote_blob->trans_len, + HEADER_SIZE + msg_size, 0)) { + TDX_TRACE; + ret = TDX_ATTEST_ERROR_VSOCK_FAILURE; + goto ret_point; + } + + // Read the response size header + if (HEADER_SIZE != recv(s, p_get_quote_blob->trans_len, + HEADER_SIZE, 0)) { + TDX_TRACE; + ret = TDX_ATTEST_ERROR_VSOCK_FAILURE; + goto ret_point; + } + + // decode the size + for (unsigned i = 0; i < HEADER_SIZE; ++i) { + in_msg_size = in_msg_size * 256 + + ((p_get_quote_blob->trans_len[i]) & 0xFF); + } + + // prepare the buffer and read the reply body + #ifdef DEBUG + fprintf(stdout, "\nReply message body is %u bytes", in_msg_size); + #endif + + if (sizeof(p_get_quote_blob->p_buf) < in_msg_size) + { + #ifdef DEBUG + fprintf(stdout, "\nReply message body is too big"); + #endif + ret = TDX_ATTEST_ERROR_UNEXPECTED; + goto ret_point; + } + while( recieved_bytes < in_msg_size) { + int recv_ret = (int)recv(s, p_get_quote_blob->p_buf + recieved_bytes, + in_msg_size - recieved_bytes, 0); + if (recv_ret < 0) { + ret = TDX_ATTEST_ERROR_VSOCK_FAILURE; + goto ret_point; + } + recieved_bytes += (uint32_t)recv_ret; + } + #ifdef DEBUG + fprintf(stdout, "\nGet %u bytes response from vsock", recieved_bytes); + #endif + use_tdvmcall = 0; + } while (0); + + if (use_tdvmcall) { + int ioctl_ret = 0; + get_quote_ioctl_arg_t arg; + p_get_quote_blob->version = 1; + p_get_quote_blob->status = 0; + p_get_quote_blob->in_len = HEADER_SIZE + msg_size; + p_get_quote_blob->out_len = (uint32_t)(sizeof(*p_get_quote_blob) - 24); + arg.p_blob = p_get_quote_blob; + arg.len = sizeof(*p_get_quote_blob); + + ioctl_ret = ioctl(devfd, TDX_CMD_GEN_QUOTE, &arg); + if (EBUSY == ioctl_ret) { + TDX_TRACE; + ret = TDX_ATTEST_ERROR_BUSY; + goto ret_point; + } else if (ioctl_ret) { + TDX_TRACE; + ret = TDX_ATTEST_ERROR_QUOTE_FAILURE; + goto ret_point; + } + if (p_get_quote_blob->status + || p_get_quote_blob->out_len <= HEADER_SIZE) { + TDX_TRACE; + ret = TDX_ATTEST_ERROR_UNEXPECTED; + goto ret_point; + } + + //in_msg_size is the size of serialized response, remove 4bytes header + //TODO: Decode the HEAD and compare it with out_len as defense-in-depth + in_msg_size = p_get_quote_blob->out_len - HEADER_SIZE; + #ifdef DEBUG + fprintf(stdout, "\nGet %u bytes response from tdvmcall", in_msg_size); + #endif + } + + resp = qgs__message__response__unpack( + NULL, in_msg_size, p_get_quote_blob->p_buf); + if (!resp) { + ret = TDX_ATTEST_ERROR_UNEXPECTED; + goto ret_point; + } + + switch (resp->type) + { + case QGS__MESSAGE__RESPONSE__MSG_GET_QUOTE_RESPONSE: + if (resp->getquoteresponse->error_code != 0) { + ret = TDX_ATTEST_ERROR_UNEXPECTED; + goto ret_point; + } + quote_size = (uint32_t)resp->getquoteresponse->quote.len; + *pp_quote = malloc(quote_size); + if (!*pp_quote) { + ret = TDX_ATTEST_ERROR_OUT_OF_MEMORY; + goto ret_point; + } + memcpy(*pp_quote, resp->getquoteresponse->quote.data, quote_size); + if (p_quote_size) { + *p_quote_size = quote_size; + } + if (p_att_key_id) { + *p_att_key_id = g_intel_tdqe_uuid; + } + break; + default: + ret = TDX_ATTEST_ERROR_UNEXPECTED; + } + +ret_point: + if (s >= 0) { + close(s); + } + if (-1 != devfd) { + close(devfd); + } + free(p_get_quote_blob); + + return ret; +} + +tdx_attest_error_t tdx_att_free_quote( + uint8_t *p_quote) +{ + free(p_quote); + return TDX_ATTEST_SUCCESS; +} + +tdx_attest_error_t tdx_att_get_report( + const tdx_report_data_t *p_tdx_report_data, + tdx_report_t *p_tdx_report) +{ + int devfd; + tdx_attest_error_t ret = TDX_ATTEST_SUCCESS; + + devfd = open(TDX_ATTEST_DEV_PATH, O_RDWR | O_SYNC); + if (-1 == devfd) { + TDX_TRACE; + return TDX_ATTEST_ERROR_DEVICE_FAILURE; + } + + ret = get_tdx_report(devfd, p_tdx_report_data, p_tdx_report); + + close(devfd); + return ret; +} + +tdx_attest_error_t tdx_att_get_supported_att_key_ids( + tdx_uuid_t *p_att_key_id_list, + uint32_t *p_list_size) +{ + if (!p_list_size) { + return TDX_ATTEST_ERROR_INVALID_PARAMETER; + } + if (p_att_key_id_list && !*p_list_size) { + return TDX_ATTEST_ERROR_INVALID_PARAMETER; + } + if (!p_att_key_id_list && *p_list_size) { + return TDX_ATTEST_ERROR_INVALID_PARAMETER; + } + if (p_att_key_id_list) { + p_att_key_id_list[0] = g_intel_tdqe_uuid; + } + *p_list_size = 1; + return TDX_ATTEST_SUCCESS; +} + +tdx_attest_error_t tdx_att_extend( + const tdx_rtmr_event_t *p_rtmr_event) +{ + int devfd = -1; + uint64_t extend_data_size = 0; + if (!p_rtmr_event || p_rtmr_event->version != 1) { + return TDX_ATTEST_ERROR_INVALID_PARAMETER; + } + if (p_rtmr_event->event_data_size) { + return TDX_ATTEST_ERROR_NOT_SUPPORTED; + } + + devfd = open(TDX_ATTEST_DEV_PATH, O_RDWR | O_SYNC); + if (-1 == devfd) { + TDX_TRACE; + return TDX_ATTEST_ERROR_DEVICE_FAILURE; + } + + if (-1 == ioctl(devfd, TDX_CMD_GET_EXTEND_SIZE, &extend_data_size)) { + TDX_TRACE; + close(devfd); + return TDX_ATTEST_ERROR_EXTEND_FAILURE; + } + assert(extend_data_size == sizeof(p_rtmr_event->extend_data)); + if (-1 == ioctl(devfd, TDX_CMD_EXTEND_RTMR, &p_rtmr_event->rtmr_index)) { + TDX_TRACE; + close(devfd); + if (EINVAL == errno) { + return TDX_ATTEST_ERROR_INVALID_RTMR_INDEX; + } + return TDX_ATTEST_ERROR_EXTEND_FAILURE; + } + close(devfd); + return TDX_ATTEST_SUCCESS; +} diff --git a/QuoteGeneration/quote_wrapper/tdx_attest/tdx_attest.h b/QuoteGeneration/quote_wrapper/tdx_attest/tdx_attest.h new file mode 100644 index 00000000..0c79cc67 --- /dev/null +++ b/QuoteGeneration/quote_wrapper/tdx_attest/tdx_attest.h @@ -0,0 +1,256 @@ +/* + * Copyright (C) 2011-2021 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: tdx_attest.h + * + * Description: API definitions for TDX Attestation library + * + */ +#ifndef _TDX_ATTEST_H_ +#define _TDX_ATTEST_H_ +#include + +typedef enum _tdx_attest_error_t { + TDX_ATTEST_SUCCESS = 0x0000, ///< Success + TDX_ATTEST_ERROR_MIN = 0x0001, ///< Indicate min error to allow better translation. + TDX_ATTEST_ERROR_UNEXPECTED = 0x0001, ///< Unexpected error + TDX_ATTEST_ERROR_INVALID_PARAMETER = 0x0002, ///< The parameter is incorrect + TDX_ATTEST_ERROR_OUT_OF_MEMORY = 0x0003, ///< Not enough memory is available to complete this operation + TDX_ATTEST_ERROR_VSOCK_FAILURE = 0x0004, ///< vsock related failure + TDX_ATTEST_ERROR_REPORT_FAILURE = 0x0005, ///< Failed to get the TD Report + TDX_ATTEST_ERROR_EXTEND_FAILURE = 0x0006, ///< Failed to extend rtmr + TDX_ATTEST_ERROR_NOT_SUPPORTED = 0x0007, ///< Request feature is not supported + TDX_ATTEST_ERROR_QUOTE_FAILURE = 0x0008, ///< Failed to get the TD Quote + TDX_ATTEST_ERROR_BUSY = 0x0009, ///< The device driver return busy + TDX_ATTEST_ERROR_DEVICE_FAILURE = 0x000a, ///< Failed to acess tdx attest device + TDX_ATTEST_ERROR_INVALID_RTMR_INDEX = 0x000b, ///< Only supported RTMR index is 2 and 3 + TDX_ATTEST_ERROR_MAX +} tdx_attest_error_t; + +#define TDX_UUID_SIZE 16 + +#pragma pack(push, 1) + +#define TDX_UUID_SIZE 16 +typedef struct tdx_uuid_t +{ + uint8_t d[TDX_UUID_SIZE]; +} tdx_uuid_t; + +#define TDX_SGX_ECDSA_ATTESTATION_ID \ +{ \ + 0xe8, 0x6c, 0x04, 0x6e, 0x8c, 0xc4, 0x4d, 0x95, \ + 0x81, 0x73, 0xfc, 0x43, 0xc1, 0xfa, 0x4f, 0x3f \ +} + +#define TDX_REPORT_DATA_SIZE 64 +typedef struct _tdx_report_data_t +{ + uint8_t d[TDX_REPORT_DATA_SIZE]; +} tdx_report_data_t; + +#define TDX_REPORT_SIZE 1024 +typedef struct _tdx_report_t +{ + uint8_t d[TDX_REPORT_SIZE]; +} tdx_report_t; + +typedef struct _tdx_rtmr_event_t { + uint32_t version; + uint64_t rtmr_index; + uint8_t extend_data[48]; + uint32_t event_type; + uint32_t event_data_size; + uint8_t event_data[]; +} tdx_rtmr_event_t; + +#pragma pack(pop) + +#if defined(__cplusplus) +extern "C" { +#endif + +/** + * @brief Request a Quote of the calling TD. + * + * The caller provides data intended to be cryptographically bound to the + * resulting Quote. (This data should not require confidentiality protection.) + * The caller also provides information about the type of Quote signing that + * should be used. + * + * In general, a given platform can create Quotes using + * different cryptographic algorithms or using different vendors’ code/enclaves. + * The att_key_id_list parameter is related to this. It is a list of key IDs + * supported by the eventual verifier of the Quote. How the caller of this + * function obtains this list is outside the scope of the R3AAL. + * + * A default key ID is supported and will be used when att_key_id_list == NULL. + * In this case, the default key ID is returned via the p_att_key_id parameter. + * + * When the function returns successfully, p_quote will point to a buffer + * containing the Quote. This buffer is allocated by the function. Use + * tdx_att_free_quote to free this buffer. + * + * @param p_tdx_report_data [in] Pointer to data that the caller/TD wants to + * cryptographically bind to the Quote, + * typically a hash. May be NULL, in which case, + * all zeros will be used for the Report data. + * @param att_key_id_list [in] List (array) of the attestation key IDs supported + * by the Quote verifier. The function compares the + * key IDs in att_key_id_list to the key IDs that + * the platform supports and uses the first match. + * May be NULL. If NULL, the API will use the + * platform’s default key ID. The uuid_t + * corresponding to the key ID that’s used is + * pointed to by p_att_key_id when the function + * returns unless p_att_key_id == NULL. + * @param list_size [in] Size of att_key_id_list in entries. + * @param p_att_key_id [out] The selected attestation key ID when the function + * returns. May be NULL indicating the platform’s + * default key ID + * @param pp_quote [out] Pointer to a pointer that the function will set equal + * to the address of the buffer containing the Quote. The + * function also allocates this buffer. Use + * tdx_att_free_quote to free this buffe + * @param p_quote_size [out] This function will place the size of the Quote, in + * bytes, in the uint32_t pointed to by the + * p_quote_size parameter. May be NULL. + * @param flags [in] Reserved, must be zero. + * @return TDX_ATTEST_SUCCESS: Successfully generated the Quote. + * @return TDX_ATTEST_ERROR_UNEXPECTED: An unexpected internal error occurred. + * @return TDX_ATTEST_ERROR_INVALID_PARAMETER: The parameter is incorrect + * @return TDX_ATTEST_ERROR_REPORT_FAILURE: Failed to get TD report. + * @return TDX_ATTEST_ERROR_VSOCK_FAILURE: Failed read/write in vsock mode + * @return TDX_ATTEST_ERROR_QUOTE_FAILURE: Failed to get quote from QGS + * @return TDX_ATTEST_UNSUPPORTED_ATT_KEY_ID: The platform Quoting + * infrastructure does not support any of the keys described in + * att_key_id_list. + * @return TDX_ATTEST_OUT_OF_MEMORY: Heap memory allocation error in library or + * enclave. + */ +tdx_attest_error_t tdx_att_get_quote( + const tdx_report_data_t *p_tdx_report_data, + const tdx_uuid_t att_key_id_list[], + uint32_t list_size, + tdx_uuid_t *p_att_key_id, + uint8_t **pp_quote, + uint32_t *p_quote_size, + uint32_t flags); + + +/** + * @brief Free the Quote buffer allocated by tdx_att_get_quote. + * + * @param p_quote [in] The value of *p_quote returned by tdx_att_get_quote. + * @return TDX_ATTEST_SUCCESS: Successfully freed the p_quote. + */ +tdx_attest_error_t tdx_att_free_quote( + uint8_t *p_quote); + +/** + * @brief Request a TDX Report of the calling TD. + * + * The caller provides data intended to be cryptographically bound to the + * resulting Report. + * + * @param p_tdx_report_data [in] Pointer to data that the caller/TD wants to + * cryptographically bind to the Quote, typically + * a hash. May be NULL, in which case, all zeros + * will be used for the Report data. + * @param p_tdx_report [out] Pointer to the buffer that will contain the + * generated TDX Report. Must not be NULL. + * @return TDX_ATTEST_SUCCESS: Successfully generated the Report. + * @return TDX_ATTEST_ERROR_INVALID_PARAMETER: p_tdx_report == NULL + * @return TDX_ATTEST_ERROR_REPORT_FAILURE: Failed to get TD report. + */ +tdx_attest_error_t tdx_att_get_report( + const tdx_report_data_t *p_tdx_report_data, + tdx_report_t* p_tdx_report); + + +/** + * @brief Extend one of the TDX runtime measurement registers (RTMRs). + * + * RTMR[rtmr_index] = SHA384(RTMR[rtmr_index] || extend_data) + * rtmr_index and extend_data are fields in the structure that is an input of + * this API. + * This API does not return either the new or old value of the specified RTMR. + * The tdx_att_get_report API may be used for this. + * The input to this API includes a description of the “extend data”. This is + * intended to facilitate reconstruction of the RTMR value. This, in turn, + * suggests maintenance of an event log by the callee. Currently, event_data is + * not supported. + * + * @param p_rtmr_event [in] Pointer to structure that contains the index of the + * RTMR to extend, the data with which to extend it and + * a description of the data. + * @return TDX_ATTEST_SUCCESS: Successfully extended the RTMR. + * @return TDX_ATTEST_ERROR_INVALID_PARAMETER: p_rtmr_event == NULL + * @return TDX_ATTEST_ERROR_UNEXPECTED: An unexpected internal error occurred. + * @return TDX_ATTEST_ERROR_EXTEND_FAILURE: Failed to extend data. + * @return TDX_ATTEST_ERROR_NOT_SUPPORTED: p_rtmr_event->event_data_size != 0 + */ +tdx_attest_error_t tdx_att_extend( + const tdx_rtmr_event_t *p_rtmr_event); + + +/** + * @brief Retrieve the list of attestation key IDs supported by the platform. + * + * Specify p_att_key_id_list = NULL to learn the number of entries in the list. + * + * @param p_att_key_id_list [out] List of the attestation key IDs that the + * platform supports. May be NULL. If NULL, the + * API will return the number of entries in the + * list in the uint32_t pointed to by p_list_size + * @param p_list_size [in/out] As input, pointer to a uint32_t specifying the + * size of p_att_key_id_list in entries. As output, + * this function will place the required size, in + * entries, in the uint32_t pointed to by the + * p_list_size parameter. If this value changes, the + * new value will be the required size + * @return TDX_ATTEST_SUCCESS: att_key_id_list populated and p_list_size points + * to a uint32_t that indicates the number of + * entries. + * @return TDX_ATTEST_ERROR_INVALID_PARAMETER: The parameter is incorrect + */ +tdx_attest_error_t tdx_att_get_supported_att_key_ids( + tdx_uuid_t *p_att_key_id_list, + uint32_t *p_list_size); +#if defined(__cplusplus) +} +#endif + + +#endif + diff --git a/QuoteGeneration/quote_wrapper/tdx_attest/test_tdx_attest.c b/QuoteGeneration/quote_wrapper/tdx_attest/test_tdx_attest.c new file mode 100644 index 00000000..56d29fa7 --- /dev/null +++ b/QuoteGeneration/quote_wrapper/tdx_attest/test_tdx_attest.c @@ -0,0 +1,112 @@ +/* + * Copyright (C) 2011-2021 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 +#include "tdx_attest.h" + +#define devname "/dev/tdx-attest" + +#define HEX_DUMP_SIZE 16 +#define MAX_ROW_SIZE 70 + +static void print_hex_dump(const char *title, const char *prefix_str, + const uint8_t *buf, int len) +{ + const uint8_t *ptr = buf; + int i, rowsize = HEX_DUMP_SIZE; + + if (!len || !buf) + return; + + fprintf(stdout, "\t\t%s", title); + + for (i = 0; i < len; i++) { + if (!(i % rowsize)) + fprintf(stdout, "\n%s%.8x:", prefix_str, i); + if (ptr[i] <= 0x0f) + fprintf(stdout, " 0%x", ptr[i]); + else + fprintf(stdout, " %x", ptr[i]); + } + + fprintf(stdout, "\n"); +} + +void gen_report_data(uint8_t *reportdata) +{ + int i; + + srand(time(NULL)); + + for (i = 0; i < TDX_REPORT_DATA_SIZE; i++) + reportdata[i] = rand(); +} + +int main(int argc, char *argv[]) +{ + uint32_t quote_size = 0; + tdx_report_data_t report_data = {{0}}; + tdx_report_t tdx_report = {{0}}; + tdx_uuid_t selected_att_key_id = {0}; + uint8_t *p_quote_buf = NULL; + FILE *fptr = NULL; + + gen_report_data(report_data.d); + print_hex_dump("\n\t\tTDX report data\n", " ", report_data.d, sizeof(report_data.d)); + + if (TDX_ATTEST_SUCCESS != tdx_att_get_report(&report_data, &tdx_report)) { + fprintf(stderr, "\nFailed to get the report\n"); + return 1; + } + print_hex_dump("\n\t\tTDX report\n", " ", tdx_report.d, sizeof(tdx_report.d)); + + if (TDX_ATTEST_SUCCESS != tdx_att_get_quote(&report_data, NULL, 0, &selected_att_key_id, + &p_quote_buf, "e_size, 0)) { + fprintf(stderr, "\nFailed to get the quote\n"); + return 1; + } + print_hex_dump("\n\t\tTDX quote data\n", " ", p_quote_buf, quote_size); + + fprintf(stdout, "\nSuccessfully get the TD Quote\n"); + fptr = fopen("quote.dat","wb"); + if( fptr ) + { + fwrite(p_quote_buf, quote_size, 1, fptr); + fclose(fptr); + } + fprintf(stdout, "\nWrote TD Quote to quote.dat\n"); + + tdx_att_free_quote(p_quote_buf); + return 0; +} diff --git a/QuoteGeneration/quote_wrapper/tdx_quote/enclave/linux/Makefile b/QuoteGeneration/quote_wrapper/tdx_quote/enclave/linux/Makefile new file mode 100644 index 00000000..d9a60053 --- /dev/null +++ b/QuoteGeneration/quote_wrapper/tdx_quote/enclave/linux/Makefile @@ -0,0 +1,89 @@ +# +# Copyright (C) 2011-2021 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. +# +# + + +TOP_DIR := ../../../.. +MITIGATION-CVE-2020-0551 := LOAD +include $(TOP_DIR)/ae/buildenv.mk + +AENAME := tdqe +SONAME := $(AENAME).so + +TDQE_VER := $(shell awk '$$2 ~ /TDQE_VERSION/ { print substr($$3, 2, length($$3) - 2); }' $(COMMON_DIR)/inc/internal/se_version.h) + +TCRYPTO_LIB_NAME := sgx_tcrypto + +INCLUDE := -I$(SGX_SDK)/include \ + -I$(SGX_SDK)/include/tlibc \ + -I$(SGX_SDK)/include/libcxx \ + -I$(COMMON_DIR)/inc/internal \ + -I$(COMMON_DIR)/inc/internal/linux \ + -I$(TOP_DIR)/ae/inc/internal \ + -I../../inc \ + -I../../../common/inc \ + -I../../../../pce_wrapper/inc \ + -I.. \ + -I. + +EXTERNAL_LIB = $(EXTERNAL_LIB_NO_CRYPTO) -lsgx_tcxx -l$(TCRYPTO_LIB_NAME) + +vpath %.cpp .. . +SRC := quoting_enclave_tdqe.cpp + +OBJ := $(SRC:.cpp=.o) +OBJS := $(sort $(OBJ) version.o) + +.PHONY: all +all: $(SONAME) + +$(SONAME): $(OBJS) + $(CXX) $(CXXFLAGS) -o $@ $(OBJS) -nostdlib -nodefaultlibs -nostartfiles -Wl,-soname=libsgx_${AENAME}.signed.so.$(call SPLIT_VERSION,$(TDQE_VER),1) $(LDTFLAGS) -fno-exceptions -fno-rtti + $(STRIP) --strip-unneeded --remove-section=.comment --remove-section=.note $@ + +quoting_enclave_tdqe.o: $(AENAME)_t.c + +%.o:%.cpp + $(CXX) $(CXXFLAGS) $(INCLUDE) $(DEFINES) -fno-exceptions -c $< -o $@ + +$(AENAME)_t.c: ../$(AENAME).edl + @$(SGX_EDGER8R) --trusted $< + +.PHONY: clean +clean: + @$(RM) *.o + @$(RM) *.so + @$(RM) *.map + @$(RM) *_t.* + +.PHONY: rebuild +rebuild: + $(MAKE) clean + $(MAKE) all diff --git a/QuoteGeneration/quote_wrapper/tdx_quote/enclave/linux/config.xml b/QuoteGeneration/quote_wrapper/tdx_quote/enclave/linux/config.xml new file mode 100644 index 00000000..ba4c703c --- /dev/null +++ b/QuoteGeneration/quote_wrapper/tdx_quote/enclave/linux/config.xml @@ -0,0 +1,13 @@ + + 1 + 1 + 0x2 + 4 + 1 + 1 + 0 + 0x44000 + 0x44000 + 0x24000 + 1 + diff --git a/QuoteGeneration/quote_wrapper/tdx_quote/enclave/linux/enclave.lds b/QuoteGeneration/quote_wrapper/tdx_quote/enclave/linux/enclave.lds new file mode 100644 index 00000000..a345878c --- /dev/null +++ b/QuoteGeneration/quote_wrapper/tdx_quote/enclave/linux/enclave.lds @@ -0,0 +1,10 @@ +{ + global: + g_global_data_sim; + g_global_data; + enclave_entry; + g_peak_heap_used; + local: + *; +}; + diff --git a/QuoteGeneration/quote_wrapper/tdx_quote/enclave/quoting_enclave_tdqe.cpp b/QuoteGeneration/quote_wrapper/tdx_quote/enclave/quoting_enclave_tdqe.cpp new file mode 100644 index 00000000..2e6e74f7 --- /dev/null +++ b/QuoteGeneration/quote_wrapper/tdx_quote/enclave/quoting_enclave_tdqe.cpp @@ -0,0 +1,1649 @@ +/* + * Copyright (C) 2011-2021 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: quoting_enclave_tdqe.cpp + * + * Description: The implementation of the + * reference ECDSA Quoting enclave + * interfaces. + * + */ + +#include +#include +#include + +#include "sgx_quote.h" +#include "sgx_quote_4.h" +#include "sgx_tseal.h" +#include "sgx_utils.h" +#include "tdqe_t.c" +#include "sgx_tcrypto.h" +#include "sgx_trts.h" + +#include "quoting_enclave_tdqe.h" +#include "user_types.h" +#include "sgx_pce.h" +#include "sgx_lfence.h" + +#define REF_N_SIZE_IN_BYTES 384 +#define REF_E_SIZE_IN_BYTES 4 +#define REF_D_SIZE_IN_BYTES 384 +#define REF_P_SIZE_IN_BYTES 192 +#define REF_Q_SIZE_IN_BYTES 192 +#define REF_DMP1_SIZE_IN_BYTES 192 +#define REF_DMQ1_SIZE_IN_BYTES 192 +#define REF_IQMP_SIZE_IN_BYTES 192 + +#define REF_N_SIZE_IN_UINT REF_N_SIZE_IN_BYTES/sizeof(unsigned int) +#define REF_E_SIZE_IN_UINT REF_E_SIZE_IN_BYTES/sizeof(unsigned int) +#define REF_D_SIZE_IN_UINT REF_D_SIZE_IN_BYTES/sizeof(unsigned int) +#define REF_P_SIZE_IN_UINT REF_P_SIZE_IN_BYTES/sizeof(unsigned int) +#define REF_Q_SIZE_IN_UINT REF_Q_SIZE_IN_BYTES/sizeof(unsigned int) +#define REF_DMP1_SIZE_IN_UINT REF_DMP1_SIZE_IN_BYTES/sizeof(unsigned int) +#define REF_DMQ1_SIZE_IN_UINT REF_DMQ1_SIZE_IN_BYTES/sizeof(unsigned int) +#define REF_IQMP_SIZE_IN_UINT REF_IQMP_SIZE_IN_BYTES/sizeof(unsigned int) + +static const uint8_t g_vendor_id[16] = +{ 0x93,0x9A,0x72,0x33,0xF7,0x9C,0x4C,0xA9,0x94,0x0A,0x0D,0xB3,0x95,0x7F,0x06,0x07 }; + +static const uint8_t g_ref_pubkey_e_be[REF_E_SIZE_IN_BYTES] = { 0x00,0x01,0x00,0x01 }; +static const uint8_t g_ref_pubkey_n_be[REF_N_SIZE_IN_BYTES] = { + 0xd3, 0x96, 0xf9, 0x43, 0x43, 0x11, 0x00, 0x1c, 0x69, 0x44, 0x9c, + 0x3b, 0xfd, 0xee, 0x8f, 0x38, 0xcd, 0x95, 0xcd, 0xad, 0x74, 0x09, + 0x7c, 0x87, 0xf1, 0xa7, 0x65, 0x02, 0x4c, 0x87, 0xc1, 0x57, 0x30, + 0xa5, 0xc9, 0xa6, 0xa4, 0xcc, 0xf9, 0x1d, 0x62, 0x18, 0x1e, 0x00, + 0xa6, 0x74, 0x27, 0x58, 0x59, 0xca, 0x1b, 0x1d, 0xf5, 0x31, 0x0e, + 0xf2, 0xd5, 0xe1, 0x79, 0x37, 0x39, 0x94, 0x3d, 0x3d, 0xe2, 0x50, + 0x93, 0x12, 0xd6, 0x03, 0xe5, 0x19, 0x3a, 0x48, 0xf0, 0xae, 0x0c, + 0x37, 0xee, 0xe0, 0x57, 0x27, 0xbd, 0xec, 0x17, 0x1b, 0x0f, 0x39, + 0x86, 0x06, 0x54, 0x20, 0x74, 0x84, 0x34, 0xbe, 0x34, 0xfa, 0x71, + 0x6f, 0xa1, 0xf5, 0x4c, 0x9a, 0x52, 0x0f, 0xc4, 0xbc, 0x2d, 0x7a, + 0x2e, 0x17, 0xe3, 0x5d, 0xa2, 0x0e, 0xca, 0x39, 0x07, 0x98, 0xa9, + 0x05, 0x1a, 0x34, 0xfb, 0x8f, 0x60, 0x9c, 0x3a, 0x1e, 0x26, 0x30, + 0x0b, 0xf3, 0xf3, 0x49, 0x40, 0xd9, 0xf7, 0x5d, 0xcb, 0xd1, 0xbf, + 0x57, 0x8d, 0xe5, 0x2d, 0xce, 0x98, 0x57, 0x35, 0xf1, 0x93, 0xc3, + 0x19, 0x2e, 0x80, 0x55, 0x37, 0xab, 0x8d, 0x64, 0x08, 0xda, 0xe6, + 0xdd, 0x64, 0xb4, 0x62, 0x83, 0x8d, 0x43, 0xaa, 0xd2, 0x7b, 0xc2, + 0x63, 0xaa, 0x97, 0xde, 0xed, 0x09, 0x92, 0xd6, 0x88, 0x56, 0x86, + 0xcd, 0x08, 0x23, 0x03, 0x27, 0x9a, 0x78, 0x7c, 0xf4, 0x36, 0x12, + 0xf5, 0xb1, 0xe6, 0x1d, 0x54, 0xab, 0x88, 0x69, 0xff, 0x18, 0x4f, + 0xdc, 0x87, 0xee, 0x34, 0xa6, 0x68, 0xb1, 0x81, 0x67, 0xb6, 0xce, + 0x0a, 0x70, 0x14, 0xbc, 0xb3, 0xe1, 0x8d, 0x76, 0x1c, 0x73, 0xde, + 0x00, 0xab, 0x41, 0xca, 0x40, 0x51, 0x53, 0x63, 0x04, 0xc3, 0x63, + 0x0b, 0xca, 0x62, 0xda, 0xaa, 0x9c, 0xe5, 0x01, 0xb7, 0xc0, 0x0f, + 0x7e, 0x0b, 0xb0, 0xbe, 0xe9, 0xf8, 0x0d, 0xb3, 0xb6, 0x64, 0xfd, + 0xcd, 0x95, 0x17, 0x9c, 0x57, 0x8e, 0xec, 0xc4, 0xac, 0x8b, 0x36, + 0x01, 0x5e, 0x4c, 0x6d, 0x1e, 0x21, 0x49, 0xa0, 0x1d, 0xde, 0x04, + 0x39, 0x6b, 0x34, 0x68, 0x44, 0xea, 0x06, 0x76, 0xe0, 0x8d, 0x1f, + 0xa2, 0xc0, 0x26, 0x05, 0xcc, 0x91, 0xbe, 0xa3, 0x17, 0xc8, 0x75, + 0x46, 0x85, 0x10, 0x39, 0x16, 0x50, 0x8e, 0x02, 0x43, 0x98, 0x31, + 0x70, 0x69, 0xd8, 0x34, 0x71, 0x82, 0xe7, 0x48, 0x26, 0xcd, 0xc1, + 0x82, 0xd3, 0xeb, 0x6f, 0xe9, 0x58, 0xe7, 0x06, 0x77, 0x10, 0x1f, + 0xdf, 0x49, 0x76, 0x30, 0xa7, 0x68, 0x42, 0xb0, 0x16, 0xd7, 0xda, + 0x92, 0x75, 0xd5, 0x7f, 0x2e, 0x75, 0x43, 0xac, 0x83, 0xb0, 0x1f, + 0xc3, 0x90, 0x19, 0xce, 0xaa, 0x94, 0xd0, 0x2e, 0x5a, 0x6c, 0x13, + 0x72, 0xe7, 0xa6, 0xb5, 0xc0, 0x45, 0x81, 0xe3, 0x53, 0x27 +}; + +const uint32_t g_sgx_nistp256_r_m1[] = {//hard-coded value for n-1 where n is order of the ECC group used + 0xFC632550, 0xF3B9CAC2, 0xA7179E84, 0xBCE6FAAD, 0xFFFFFFFF, 0xFFFFFFFF, + 0x00000000, 0xFFFFFFFF }; + +#define HASH_DRBG_OUT_LEN 40 //320 bits +static const char QE_ATT_STRING[] = "TDX_QE_DER"; + +#define MAX_CERT_DATA_SIZE (4098*3) +#define MIN_CERT_DATA_SIZE (500) + +static bool is_verify_report2_available() { + sgx_report2_mac_struct_t dummy_report_mac_struct; + memset(&dummy_report_mac_struct, 0, sizeof(dummy_report_mac_struct)); + dummy_report_mac_struct.report_type.type = TEE_REPORT2_TYPE; + dummy_report_mac_struct.report_type.subtype = TEE_REPORT2_SUBTYPE; + dummy_report_mac_struct.report_type.version = TEE_REPORT2_VERSION; + if (SGX_ERROR_FEATURE_NOT_SUPPORTED == + sgx_verify_report2(&dummy_report_mac_struct)) { + return false; + } + return true; +} + +/** + * Generates the attestation key based on the TDQE's seal key at the current raw TCB. The attestation key will change + * when the platform TCB (CPUSVN and TDQE ISVSVN) changes. The attestation key can be 'refreshed' for key hygeine by + * inputting a differnt key_id. + * (///todo: The current wrappers don't allow modification of key_id). + * + * Derivation: + * 1) Sealing Key = EGETKEY(KEYNAME = SEAL_KEY, + * KEY_POLICY =MRSIGNER, + * KEY_ID = 0, Current CPUSVN, + * Current ISVSVN) + * 2) Block 1 = AES-CMAC(Sealing Key, QE ATT string with Counter = 0x01) + * 3) Block 2 = AES-CMAC(Sealing Key, QE ATT string with Counter = 0x02) + * 4) Block 3 = AES-CMAC(Sealing Key, QE ATT string with Counter = 0x03) + * 5) TDQE ATT Seed = most significant 320 bits of (Block 1 || Block 2 || Block 3). + * 6) TDQE ATT key pair ir is generated d using NIST SP 186-4 4 section B 4.1 "Key Pair Generation Using Extra Random + * Bits." AE ATT Seed are used for the random bits. + * + * QE ATT String: + * Byte Position | Value + * 0 | Counter (See Description) + * 1-10 | "TDX_QE_DER" (ascii encoded) + * 11-13 | 0x000000 + * 14-15 | 0x0140 (Big Endian) + * + * @param p_att_priv_key[Out] Pointer to the returned value of tha attestion key private key. Must not be NULL. + * @param p_att_pub_key[Out] Pointer to the returned value of tha attestion key public key. Must not be NULL. + * @param p_req_key_id[In] Pointer to the key_id to use when generating the attestation key. + * + * @return TDQE_SUCCESS Successfully created the key and the private and public keys are returned. + * @return TDQE_ERROR_INVALID_PARAMETER One of the inputted parameter is NULL + * @return TDQE_ERROR_OUT_OF_MEMORY Heap memory was exhausted. + * @return TDQE_ERROR_CRYPTO Error in the crypto library functions ues to generate the key. + * @return TDQE_ERROR_UNEXPECTED Unexpected internal error. + */ +static tdqe_error_t get_att_key_based_from_seal_key(sgx_ec256_private_t *p_att_priv_key, + sgx_ec256_public_t *p_att_pub_key, + const sgx_key_id_t *p_req_key_id) +{ + + sgx_status_t sgx_status = SGX_SUCCESS; + + sgx_key_request_t att_priv_key_seed_req; + //sgx_key_128bit_t key_tmp; + // + // securely align seed + // + sgx::custom_alignment_aligned okey_tmp; + sgx_key_128bit_t* pkey_tmp = &okey_tmp.v; + + uint8_t content[16]; + sgx_cmac_128bit_tag_t block; + sgx_report_t tdqe_report; + uint8_t hash_drg_output[HASH_DRBG_OUT_LEN]; + uint32_t i; + tdqe_error_t ret = TDQE_ERROR_CRYPTO; + + // Defense-in-depth. This function is only called internally so should never be NULL + if ((NULL == p_att_priv_key) || + (NULL == p_att_pub_key) || + (NULL == p_req_key_id)) { + return TDQE_ERROR_INVALID_PARAMETER; + } + + memset(&content, 0, sizeof(content)); + memset(&block, 0, sizeof(block)); + memset(pkey_tmp, 0, sizeof(*pkey_tmp)); + //1-10bytes: "TDX_QE_DER"(ascii encoded) + memcpy(content + 1, QE_ATT_STRING, 10); + //14-15bytes: 0x0140 (Big Endian) + content[14] = 0x01; + content[15] = 0x40; + + // Get PSVN from self report + sgx_status = sgx_create_report(NULL, NULL, &tdqe_report); + if (SGX_SUCCESS != sgx_status) { + if (SGX_ERROR_OUT_OF_MEMORY == sgx_status) { + ret = TDQE_ERROR_OUT_OF_MEMORY; + } + else { + ret = TDQE_ERROR_UNEXPECTED; + } + goto ret_point; + } + + // Set up the key request structure. + memset(&att_priv_key_seed_req, 0, sizeof(sgx_key_request_t)); + memcpy(&att_priv_key_seed_req.cpu_svn, &tdqe_report.body.cpu_svn, sizeof(att_priv_key_seed_req.cpu_svn)); + memcpy(&att_priv_key_seed_req.isv_svn, &tdqe_report.body.isv_svn, sizeof(att_priv_key_seed_req.isv_svn)); + memcpy(&att_priv_key_seed_req.key_id, p_req_key_id, sizeof(att_priv_key_seed_req.key_id)); + att_priv_key_seed_req.key_name = SGX_KEYSELECT_SEAL; // Seal key + att_priv_key_seed_req.key_policy = SGX_KEYPOLICY_MRSIGNER; + att_priv_key_seed_req.attribute_mask.xfrm = 0; + att_priv_key_seed_req.misc_mask = 0xFFFFFFFF; + att_priv_key_seed_req.attribute_mask.flags = ~SGX_FLAGS_MODE64BIT; //set all bits except the SGX_FLAGS_MODE64BIT + sgx_status = sgx_get_key(&att_priv_key_seed_req, pkey_tmp); + if (SGX_SUCCESS != sgx_status) + { + ret = TDQE_ERROR_CRYPTO; + goto ret_point; + } + + ref_static_assert(sizeof(sgx_cmac_128bit_key_t) == sizeof(sgx_key_128bit_t)); + ref_static_assert(2 * sizeof(sgx_cmac_128bit_tag_t) <= HASH_DRBG_OUT_LEN && 3 * sizeof(sgx_cmac_128bit_tag_t) >= HASH_DRBG_OUT_LEN); + + //Block 1 = AES-CMAC(Seal Key, QE ATT string with Counter = 0x01) + content[0] = 0x01; + if ((sgx_status = sgx_rijndael128_cmac_msg(reinterpret_cast(*pkey_tmp), + content, + sizeof(content), + &block)) != SGX_SUCCESS) { + if (sgx_status == SGX_ERROR_OUT_OF_MEMORY) { + ret = TDQE_ERROR_OUT_OF_MEMORY; + } + else { + ret = TDQE_ERROR_CRYPTO; + } + goto ret_point; + } + memcpy(hash_drg_output, block, sizeof(sgx_cmac_128bit_tag_t)); + + //Block 2 = AES-CMAC(Seal Key, QE ATT string with Counter = 0x02) + content[0] = 0x02; + if ((sgx_status = sgx_rijndael128_cmac_msg(reinterpret_cast(*pkey_tmp), + content, + sizeof(content), + &block)) != SGX_SUCCESS) { + if (sgx_status == SGX_ERROR_OUT_OF_MEMORY) { + ret = TDQE_ERROR_OUT_OF_MEMORY; + } + else { + ret = TDQE_ERROR_CRYPTO; + } + goto ret_point; + } + memcpy(hash_drg_output + sizeof(sgx_cmac_128bit_tag_t), block, sizeof(sgx_cmac_128bit_tag_t)); + + //Block 3 = AES-CMAC(Seal Key, QE ATT string with Counter = 0x03) + content[0] = 0x03; + if ((sgx_status = sgx_rijndael128_cmac_msg(reinterpret_cast(*pkey_tmp), + content, + sizeof(content), + &block)) != SGX_SUCCESS) { + if (sgx_status == SGX_ERROR_OUT_OF_MEMORY) { + ret = TDQE_ERROR_OUT_OF_MEMORY; + } + else { + ret = TDQE_ERROR_CRYPTO; + } + goto ret_point; + } + //ECDSA Att Seed = most significant 320 bits of (Block 1 || Block 2 || Block 3). + memcpy(hash_drg_output + 2 * sizeof(sgx_cmac_128bit_tag_t), block, sizeof(hash_drg_output) - 2 * sizeof(sgx_cmac_128bit_tag_t)); + + for (i = 0; i < sizeof(hash_drg_output) / 2; i++) {//big endian to little endian + hash_drg_output[i] ^= hash_drg_output[sizeof(hash_drg_output) - 1 - i]; + hash_drg_output[sizeof(hash_drg_output) - 1 - i] ^= hash_drg_output[i]; + hash_drg_output[i] ^= hash_drg_output[sizeof(hash_drg_output) - 1 - i]; + } + ref_static_assert(sizeof(g_sgx_nistp256_r_m1) == sizeof(sgx_ec256_private_t)); /*Unmatched size*/ + + // Calculate attest key + if (sgx_calculate_ecdsa_priv_key((const unsigned char*)hash_drg_output, + sizeof(hash_drg_output), + (const unsigned char*)g_sgx_nistp256_r_m1, + sizeof(g_sgx_nistp256_r_m1), + (unsigned char*)p_att_priv_key, + sizeof(sgx_ec256_private_t)) != SGX_SUCCESS) { + ret = TDQE_ERROR_CRYPTO; + goto ret_point; + } + + if (sgx_ecc256_calculate_pub_from_priv(p_att_priv_key, p_att_pub_key) != SGX_SUCCESS) { + ret = TDQE_ERROR_CRYPTO; + goto ret_point; + } + + //little endian to big endian + SWAP_ENDIAN_32B(p_att_pub_key->gx); + SWAP_ENDIAN_32B(p_att_pub_key->gy); + + ret = TDQE_SUCCESS; + +ret_point: + //clear and free objects + // + (void)memset_s(pkey_tmp, sizeof(*pkey_tmp), 0, sizeof(*pkey_tmp)); + (void)memset_s(&hash_drg_output, sizeof(hash_drg_output), 0, sizeof(hash_drg_output)); + (void)memset_s(&block, sizeof(block), 0, sizeof(block)); + if (ret != TDQE_SUCCESS) { + (void)memset_s(p_att_priv_key, sizeof(sgx_ec256_private_t), 0, sizeof(sgx_ec256_private_t)); //clear private key in stack + (void)memset_s(p_att_pub_key, sizeof(ref_ec256_public_t), 0, sizeof(ref_ec256_public_t)); //clear public key in stack + } + + return ret; +} + +/** + * An internal function used to verify the ECDSA Blob. It will verify the format of the blob and check the + * authenticity using the seal key. If the TCB of the platform has increased since the last time the blob was sealed, + * it will be resealed to the new TCB and the p_is_resealed will be set to TRUE. It will also optionally return the pub + * key id and the encrypted data from the seal data if requested by the caller. + * + * @param p_blob Pointer to the inputted ECDSA sealed blob to + * be checked and unsealed. + * @param blob_size Size in bytes of the ECDSA blob. + * @param p_is_resealed + * Pointer to return whether the blob was resealed to a new TCB. + * @param p_plaintext_ecdsa_data + * Pointer to the buffer that will contain the plaintext portion of the sealed blob. This must not be + * null. + * @param p_pub_key_id + * Optional pointer to the buffer to contain the ECDSA key ID stored in the blob. If not NULL, it will + * contain the ECDSA ID of the key in th blob upon returning. + * @param p_report_body If non-NULL, it will contain the a non-targetted QE REPORT without any REPORT.ReportData. + * @param pub_key_id_size + * Size in bytes of the buffer pointed to by p_pub_key_id. Ignored if p_pub_key_id is NULL but if not + * NULL, it must be large enough to hold a SHA256 hash. + * @param p_secret_ecdsa_data Optional pointer to a buffer that will contains the decrypted secret data + * in the sealed blob. + * + * @return TDQE_SUCCESS ECDSA The blob verification passed and the p_secret_data will contain the decypted sealed + * secret data. + * @return TDQE_ECDSABLOB_ERROR There is a problem with the inputted blob format or unsealing failed. + * @return TDQE_ERROR_UNEXPECTED There is a problem retrieving the current platform TCB or resealing of the BLOB. + * @return TDQE_ERROR_OUT_OF_MEMORY Heap memory was exhausted. + */ +static tdqe_error_t verify_blob_internal(uint8_t *p_blob, + uint32_t blob_size, + uint8_t *p_is_resealed, + ref_plaintext_ecdsa_data_sdk_t *p_plaintext_ecdsa_data, + sgx_report_body_t *p_report_body, + uint8_t *p_pub_key_id, + uint32_t pub_key_id_size, + ref_ciphertext_ecdsa_data_sdk_t *p_secret_ecdsa_data) +{ + sgx_status_t sgx_status = SGX_SUCCESS; + tdqe_error_t ret = TDQE_SUCCESS; + uint8_t resealed = FALSE; + //ref_ciphertext_ecdsa_data_sdk_t local_secret_ecdsa_data; + // + // securely align attestation key + // + sgx::custom_alignment_alignedecdsa_private_key)> osecret_ecdsa_data; + ref_ciphertext_ecdsa_data_sdk_t* plocal_secret_ecdsa_data = &osecret_ecdsa_data.v; + + uint32_t plaintext_length; + uint32_t decryptedtext_length = sizeof(*plocal_secret_ecdsa_data); + sgx_sealed_data_t *p_ecdsa_blob = (sgx_sealed_data_t *)p_blob; + uint8_t local_ecdsa_blob[SGX_QL_TRUSTED_ECDSA_BLOB_SIZE_SDK] = { 0 }; + sgx_report_t report; + + if ((NULL == p_plaintext_ecdsa_data) || + (NULL == p_is_resealed) || + (NULL == p_blob)) { + return(TDQE_ERROR_INVALID_PARAMETER); + } + + if (SGX_QL_TRUSTED_ECDSA_BLOB_SIZE_SDK != blob_size) { + return(TDQE_ECDSABLOB_ERROR); + } + if (NULL != p_pub_key_id) { + if (pub_key_id_size < sizeof(sgx_sha256_hash_t)) { + return(TDQE_ERROR_INVALID_PARAMETER); + } + } + if (sgx_get_encrypt_txt_len(p_ecdsa_blob) != sizeof(ref_ciphertext_ecdsa_data_sdk_t)) { + return(TDQE_ECDSABLOB_ERROR); + } + plaintext_length = sgx_get_add_mac_txt_len(p_ecdsa_blob); + if (plaintext_length != sizeof(ref_plaintext_ecdsa_data_sdk_t)) { + return(TDQE_ECDSABLOB_ERROR); + } + + memset(plocal_secret_ecdsa_data, 0, sizeof(*plocal_secret_ecdsa_data)); + memset(p_plaintext_ecdsa_data, 0, sizeof(*p_plaintext_ecdsa_data)); + + sgx_status = sgx_unseal_data(p_ecdsa_blob, + (uint8_t *)p_plaintext_ecdsa_data, + &plaintext_length, + (uint8_t *)plocal_secret_ecdsa_data, + &decryptedtext_length); + if (SGX_SUCCESS != sgx_status) { + // The blob has been corrupted or the platform TCB has been downgraded. + ret = TDQE_ECDSABLOB_ERROR; + goto ret_point; + } + + if ((p_plaintext_ecdsa_data->seal_blob_type != SGX_QL_SEAL_ECDSA_KEY_BLOB) + || (p_plaintext_ecdsa_data->ecdsa_key_version != SGX_QL_ECDSA_KEY_BLOB_VERSION_0)) { + ret = TDQE_ECDSABLOB_ERROR; + goto ret_point; + } + + if (decryptedtext_length != sizeof(ref_ciphertext_ecdsa_data_sdk_t) + || plaintext_length != sizeof(ref_plaintext_ecdsa_data_sdk_t)) { + ret = TDQE_ECDSABLOB_ERROR; + goto ret_point; + } + + /* Create report to get current cpu_svn and isv_svn. */ + memset(&report, 0, sizeof(report)); + sgx_status = sgx_create_report(NULL, NULL, &report); + if (SGX_SUCCESS != sgx_status) { + if (SGX_ERROR_OUT_OF_MEMORY == sgx_status) { + ret = TDQE_ERROR_OUT_OF_MEMORY; + } + else { + ret = TDQE_ERROR_UNEXPECTED; + } + goto ret_point; + } + + if (NULL != p_report_body) { + memcpy(p_report_body, &report.body, sizeof(*p_report_body)); + } + + // Update the Key Blob using the SEAL Key for the current TCB if the TCB is + // upgraded after the Key Blob is generated. Here memcmp cpu_svn might be + // different even though they're actually the same, but for defense in depth we + // will keep this comparison here. + if ((memcmp(&report.body.cpu_svn, &p_ecdsa_blob->key_request.cpu_svn, sizeof(report.body.cpu_svn))) || + (report.body.isv_svn != p_ecdsa_blob->key_request.isv_svn)) { + sgx_status = sgx_seal_data(sizeof(*p_plaintext_ecdsa_data), + (uint8_t*)p_plaintext_ecdsa_data, + sizeof(*plocal_secret_ecdsa_data), + (uint8_t*)plocal_secret_ecdsa_data, + SGX_QL_TRUSTED_ECDSA_BLOB_SIZE_SDK, + (sgx_sealed_data_t *)local_ecdsa_blob); + if (SGX_SUCCESS != sgx_status) { + if (SGX_ERROR_OUT_OF_MEMORY == sgx_status) { + ret = TDQE_ERROR_OUT_OF_MEMORY; + } + else { + ret = TDQE_ERROR_UNEXPECTED; + } + goto ret_point; + } + memcpy(p_ecdsa_blob, local_ecdsa_blob, blob_size); + resealed = TRUE; + } + + if (NULL != p_pub_key_id) { + memcpy(p_pub_key_id, &p_plaintext_ecdsa_data->ecdsa_id, sizeof(p_plaintext_ecdsa_data->ecdsa_id)); + } + if (NULL != p_secret_ecdsa_data) { + memcpy(p_secret_ecdsa_data, plocal_secret_ecdsa_data, sizeof(*p_secret_ecdsa_data)); + } + +ret_point: + + // Clear the output buffer to make sure nothing leaks. + memset_s(plocal_secret_ecdsa_data, sizeof(*plocal_secret_ecdsa_data), 0, sizeof(*plocal_secret_ecdsa_data)); + if (TDQE_SUCCESS == ret) { + *p_is_resealed = resealed; + } + return ret; +} + +/** + * An external function exposed through the EDL to verify the ECDSA Blob. It will verify the format of the blob and + * check the authenticity using the seal key. If the TCB of the platform has increased since the last time the blob was + * sealed, it will be resealed to the new TCB and the p_is_resealed will be set to TRUE. It will also optionally return + * the pub key id. + * + * @param p_blob [In, Out] Pointer to the ECDSA Blob. Must not be NULL and the full buffer must be inside the + * enclave's memory space. If the blob was resealed, upon return, the p_blob will point to the resealed + * blob and the caller should save it. + * @param blob_size [In] Size in bytes of the ECDSA blob buffer pointed to by p_blob. + * @param p_is_resealed [In, Out] Pointer to flag that will be updated to true if the inputted blob is resealed. This + * will happen when the platform TCB has been increased since it was last sealed. Must not be + * NULL. + * @param p_report_body + * @param pub_key_id_size [In] Size in bytes of the optional p_pub_key_id. If p_pub_key_id is NULL, pub_key_id_size + * must be zero. The size must be large enough to contain a SHA256 hash. + * @param p_pub_key_id [In, Out] Optional pointer to contain the ECDSA attestation public keys ID. If not null, the + * full buffer must inside the enclave's memory space. + * + * @return TDQE_SUCCESS ECDSA The blob verification passed. + * @return TDQE_ERROR_INVALID_PLATFORM + * @return TDQE_ERROR_OUT_OF_MEMORY Heap memory was exhausted. + * @return TDQE_ERROR_INVALID_PARAMETER One of the inputted parameters in invalid. + * @return TDQE_ECDSABLOB_ERROR There is a problem with the inputted blob format of unsealing. + * @return TDQE_ERROR_UNEXPECTED There is a problem retrieving the current platform TCB or resealing of the BLOB. + */ +uint32_t verify_blob(uint8_t *p_blob, + uint32_t blob_size, + uint8_t *p_is_resealed, + sgx_report_body_t *p_report_body, + uint32_t pub_key_id_size, + uint8_t *p_pub_key_id) +{ + ref_plaintext_ecdsa_data_sdk_t plain_text; + + if (!is_verify_report2_available()) { + return (TDQE_ERROR_INVALID_PLATFORM); + } + // Actually, some cases here will be checked with code generated by + // edger8r. Here we just want to defend in depth. + if (NULL == p_blob || NULL == p_is_resealed) { + return(TDQE_ERROR_INVALID_PARAMETER); + } + + if (SGX_QL_TRUSTED_ECDSA_BLOB_SIZE_SDK != blob_size) { + return(TDQE_ERROR_INVALID_PARAMETER); + } + + if (!sgx_is_within_enclave(p_blob, blob_size)) { + return(TDQE_ERROR_INVALID_PARAMETER); + } + + if ((pub_key_id_size != 0 && NULL == p_pub_key_id) || + (pub_key_id_size == 0 && NULL != p_pub_key_id)) { + return(TDQE_ERROR_INVALID_PARAMETER); + } + + if (NULL != p_pub_key_id) { + if (pub_key_id_size < sizeof(sgx_sha256_hash_t)) { + return(TDQE_ERROR_INVALID_PARAMETER); + } + if (!sgx_is_within_enclave(p_pub_key_id, pub_key_id_size)) { + return(TDQE_ERROR_INVALID_PARAMETER); + } + } + if (NULL != p_report_body) { + if (!sgx_is_within_enclave(p_report_body, sizeof(*p_report_body))) { + return(TDQE_ERROR_INVALID_PARAMETER); + } + } + + return((uint32_t)random_stack_advance(verify_blob_internal,p_blob, + blob_size, + p_is_resealed, + &plain_text, + p_report_body, + p_pub_key_id, + pub_key_id_size, + (ref_ciphertext_ecdsa_data_sdk_t*) NULL)); +} + +/** + * External function exposed through the EDL used to return the TDQE report and the PPID encryption key required to get + * the PCE identity information. The PCE requires that the PPID be encrypted with a public key. The reference supports + * 1 type of certification data: + * 1. PPID_RSA3072_ENCRYPTED. + * If PPID_CLEARTEXT was supported, the QE will generate an RSA3072 key pair and store both the public and private parts + * in the enclave's global memory. Reference Note: This requires that this function be called before the + * store_cert_data() function in order to properly decrypt the PPID returned by the PCE and store it in the blob. This + * function does not take the blob as input so the QE stores it in global memory. If the QE is unloaded between this + * function and the store_cert_data(), the ephemeral private key will be lost and the decryption of PPID in + * store_cert_data() will fail. For a production version of the QE, the private key should be stored in the blob to keep + * the QE stateless. The platform software may consider storing the encryption public key if it intends to recertify + * (request PCE to re-sign at a higher TCB) without calling the QE to re-generate an encryption key and a new QE REPORT. + * + * For PPID_RSA3072_ENCRYPTED, the QE will use the hardcoded public key owned by the quote verifier and store the PPID + * encrypted by this RSA key in the ECDSA blob. + * + * + * NOTE: This is an optional function. If the other cert_key_types are used, the TDQE does not need to generate an + * ephemeral PPID encryption key. + * + * @param p_pce_target_info + * [In] Pointer to the target_info buffer of the PCE. It must not be NULL and the full target info + * buffer must reside in the enclave's memory space. + * @param p_tdqe_report + * [In, Out] Pointer to the QE report buffer targeting the PCE. It must not be NULL and full report + * buffer must reside in the enclave's memory space. + * @param crypto_suite + * [In] Indicates the crypto algorithm to use to encrypt the PPID. Currently, only RSA3072 keys are + * supported. This is the type of key this function will generate. + * @param cert_key_type + * [In] Indicates whether to use the hard-coded public key or generate a new one. This option allows + * the reference to demonstrate creating an encryption key on-demand or to use the hard-coded value. + * Using the hard-coded value typically means the PPID is to remain private on the platform. Must be + * PPID_RSA3072_ENCRYPTED. + * + * @param key_size [In] The size in bytes of the supplied p_public_key buffer. Currently, it must be equal to the size + * of an RSA3072 public key. 4 byte 'e' and 256 byte 'n'. + * @param p_public_key + * [In, Out] Pointer to the buffer that will contain the public key used to encrypt the PPID. It must + * not be NULL and the buffer must reside within the enclave's memory space. + * + * @return TDQE_SUCCESS Function successfully generated or retrieved the encryption key and generated a REPORT + * targeting the PCE. + * @return TDQE_ERROR_INVALID_PLATFORM + * @return TDQE_ERROR_INVALID_PARAMETER Invalid parameter. + * @return TDQE_ERROR_UNEXPECTED An internal error occurred. + */ +uint32_t get_pce_encrypt_key(const sgx_target_info_t* p_pce_target_info, + sgx_report_t* p_tdqe_report, + uint8_t crypto_suite, + uint16_t cert_key_type, + uint32_t key_size, + uint8_t* p_public_key) +{ + tdqe_error_t ret = TDQE_SUCCESS; + sgx_status_t sgx_status = SGX_SUCCESS; + sgx_report_data_t report_data = { 0 }; + sgx_sha_state_handle_t sha_handle = NULL; + pce_rsaoaep_3072_encrypt_pub_key_t* p_rsa_pub_key; + + if (!is_verify_report2_available()) { + return (TDQE_ERROR_INVALID_PLATFORM); + } + if (p_pce_target_info == NULL || !sgx_is_within_enclave(p_pce_target_info, sizeof(*p_pce_target_info))) { + return(TDQE_ERROR_INVALID_PARAMETER); + } + + if (p_public_key == NULL || !sgx_is_within_enclave(p_public_key, key_size)) { + return(TDQE_ERROR_INVALID_PARAMETER); + } + + if (p_tdqe_report == NULL || !sgx_is_within_enclave(p_tdqe_report, sizeof(*p_tdqe_report))) { + return(TDQE_ERROR_INVALID_PARAMETER); + } + + if (crypto_suite != PCE_ALG_RSA_OAEP_3072) { + return(TDQE_ERROR_INVALID_PARAMETER); + } + + if (key_size != sizeof(*p_rsa_pub_key)) { + return(TDQE_ERROR_INVALID_PARAMETER); + } + // Only PPID_RSA3072_ENCRYPTED is supported when using production mode PCE. + if (PPID_RSA3072_ENCRYPTED != cert_key_type) { + return(TDQE_ERROR_INVALID_PARAMETER); + } + + if ((p_pce_target_info->attributes.flags & SGX_FLAGS_PROVISION_KEY) != SGX_FLAGS_PROVISION_KEY || + (p_pce_target_info->attributes.flags & SGX_FLAGS_DEBUG) != 0) + { + //PCE must have access to provisioning key + //Can't be debug PCE + return(TDQE_ERROR_INVALID_PARAMETER); + } + + p_rsa_pub_key = (pce_rsaoaep_3072_encrypt_pub_key_t*)p_public_key; + memcpy(p_rsa_pub_key->e, g_ref_pubkey_e_be, sizeof(p_rsa_pub_key->e)); + memcpy(p_rsa_pub_key->n, g_ref_pubkey_n_be, sizeof(p_rsa_pub_key->n)); + + // report_data = SHA256(crypto_suite||rsa_pub_key)||0-padding + do { + sgx_status = sgx_sha256_init(&sha_handle); + if (SGX_SUCCESS != sgx_status) + break; + + sgx_status = sgx_sha256_update(&crypto_suite, + sizeof(uint8_t), + sha_handle); + if (SGX_SUCCESS != sgx_status) + break; + //(MOD followed by e) + sgx_status = sgx_sha256_update(p_rsa_pub_key->n, + sizeof(p_rsa_pub_key->n), + sha_handle); + if (SGX_SUCCESS != sgx_status) + break; + sgx_status = sgx_sha256_update(p_rsa_pub_key->e, + sizeof(p_rsa_pub_key->e), + sha_handle); + if (SGX_SUCCESS != sgx_status) + break; + sgx_status = sgx_sha256_get_hash(sha_handle, + reinterpret_cast(&report_data)); + } while (0); + if (SGX_SUCCESS != sgx_status) { + ret = TDQE_ERROR_UNEXPECTED; + goto ret_point; + } + + sgx_status = sgx_create_report(p_pce_target_info, &report_data, p_tdqe_report); + if (SGX_SUCCESS != sgx_status) { + if (SGX_ERROR_OUT_OF_MEMORY == sgx_status) { + ret = TDQE_ERROR_OUT_OF_MEMORY; + } + else { + ret = TDQE_ERROR_UNEXPECTED; + } + goto ret_point; + } + +ret_point: + // Clear critical output data on error + if (TDQE_SUCCESS != ret) { + memset_s(p_tdqe_report, sizeof(*p_tdqe_report), 0, sizeof(*p_tdqe_report)); + } + if (sha_handle != NULL) { + sgx_sha256_close(sha_handle); + } + + return(ret); +} + +/** + * External function exposed through the EDL to generate the ECDSA attestation key. The generated key will be stored in + * the ECDSA blob passed in to the function. The public part of the key is MAC'd and the private key is encrypted and + * MAC'd with the QE sealing key. First the attestation key is generated and its + * SHA256(public_key||authendication_data) is added to the returned QE REPORT.report_data. The caller can then send the + * report to the PCE to be certified. Once certified, the certification data is given back to this enclave + * (store_cert_data()) to be sealed along with the attestation key in this fucntion. This function must be called + * before the store_cert_data() function unless the store_cert_data() function is only called to re-certify an existing + * key already in an existing ECDSA blob. If the store_cert_data() function is called without first generating the key, + * the ECDSA blob verification will fail or the quote signatures will not match PCE certified attestation keys. + * + * Any data in the p_blob will be overwritten when this fuction is called. + * + * @param p_blob [In, Out] Pointer to the ECDSA Blob. Must not be NULL and the full buffer must be inside the + * enclave's memory space. If the blob was resealed, upon return, the p_blob will point to the + * resealed blob and the caller should save it.[in, out] Pointer to the ECDSA Blob. + * @param blob_size [In] Size in bytes of the ECDSA blob buffer pointed to by p_blob. + * @param p_pce_target_info + * [In] Pointer to the target_info of the PCE. It must not be NULL and must reside in the enclave's memory + * space. + * @param p_tdqe_report + * [In, Out] Pointer to the outputted QE report targeting the PCE. The Report's ReportData will contain + * the SHA256 hash of the ECDSA public key. The hash is generated using the big endian formatted ECDSA + * public key. SHA256(X||Y) where both X and Y are in Big Endian format. + * @param p_authentication_data + * [In] Optional pointer to the extra authentication data provided by the caller. This data will be + * included in the quote and signed by the ECDSA attestation. If provided the + * authentication_data_size must not be zero and the full buffer must reside inside the enclave's + * memory space. + * @param authentication_data_size + * [In] The size in bytes of the data pointed to by p_authentication_data. If this value must be zero + * if the p_authentication_data pointer is NULL and it must be non-zero of it is not NULL. + * + * @return TDQE_SUCCESS The attestation keys was successfully generated. The blob will have the ECDSA key and be + * sealed. The QE Report targeting the PCE is returned with the ReportData containing the hash + * of the ECDSA attestation** public key and authentication data. + * @return TDQE_ERROR_INVALID_PLATFORM + * @return TDQE_ERROR_INVALID_PARAMETER + * @return TDQE_ERROR_OUT_OF_MEMORY + * @return TDQE_ERROR_ATT_KEY_GEN + * @return TDQE_ERROR_UNEXPECTED + */ +uint32_t gen_att_key(uint8_t *p_blob, + uint32_t blob_size, + const sgx_target_info_t *p_pce_target_info, + sgx_report_t *p_tdqe_report, + uint8_t *p_authentication_data, + uint32_t authentication_data_size) +{ + tdqe_error_t ret = TDQE_SUCCESS; + sgx_status_t sgx_status = SGX_SUCCESS; + sgx_sha_state_handle_t sha_handle = NULL; + sgx_report_data_t report_data = { 0 }; + ref_plaintext_ecdsa_data_sdk_t plaintext_data; + + if (!is_verify_report2_available()) { + return (TDQE_ERROR_INVALID_PLATFORM); + } + // + // provide extra protection for attestation key by + // randomizing its address and securely aligning it + // + using cciphertext_data = randomly_placed_object< + sgx::custom_alignment_aligned< + ref_ciphertext_ecdsa_data_sdk_t, + alignof(ref_ciphertext_ecdsa_data_sdk_t), + __builtin_offsetof(ref_ciphertext_ecdsa_data_sdk_t, ecdsa_private_key), + sizeof(((ref_ciphertext_ecdsa_data_sdk_t*)0)->ecdsa_private_key)>>; + // + // instance of randomly_placed_object + // + cciphertext_data ociphertext_data_buf; + // + // pointer to instance of custom_alignment_aligned + // + auto* ociphertext_data = ociphertext_data_buf.instantiate_object(); + + ref_ciphertext_ecdsa_data_sdk_t* pciphertext_data = &ociphertext_data->v; + + sgx_key_id_t req_key_id = { 0 }; + + if ((NULL == p_blob) || + (NULL == p_pce_target_info) || + (NULL == p_tdqe_report)) + return(TDQE_ERROR_INVALID_PARAMETER); + + if (SGX_QL_TRUSTED_ECDSA_BLOB_SIZE_SDK != blob_size) { + return(TDQE_ERROR_INVALID_PARAMETER); + } + + // Check whether p_blob is copied into EPC. If we want to reduce the + // memory usage, maybe we can leave the p_blob outside EPC. + if (!sgx_is_within_enclave(p_blob, blob_size)) { + return(TDQE_ERROR_INVALID_PARAMETER); + } + + if (!sgx_is_within_enclave(p_pce_target_info, sizeof(*p_pce_target_info))) { + return(TDQE_ERROR_INVALID_PARAMETER); + } + + if (!sgx_is_within_enclave(p_tdqe_report, sizeof(*p_tdqe_report))) { + return(TDQE_ERROR_INVALID_PARAMETER); + } + + if ((p_pce_target_info->attributes.flags & SGX_FLAGS_PROVISION_KEY) != + SGX_FLAGS_PROVISION_KEY || (p_pce_target_info->attributes.flags & SGX_FLAGS_DEBUG) != 0) + { + //PCE must have access to provisioning key + //Can't be debug PCE + return(TDQE_ERROR_INVALID_PARAMETER); + } + + // ECDSA quotes supports 'authentication_data' that will be signed by the PCE's PCK along with the ECDSA Attestation key + if ((0 != authentication_data_size) && (NULL == p_authentication_data)) { + return(TDQE_ERROR_INVALID_PARAMETER); + } + if ((0 == authentication_data_size) && (NULL != p_authentication_data)) { + return(TDQE_ERROR_INVALID_PARAMETER); + } + if (p_authentication_data) { + if (!sgx_is_within_enclave(p_authentication_data, authentication_data_size)) { + return(TDQE_ERROR_INVALID_PARAMETER); + } + ///todo: The intention is to allow this data to be truly variable. This check forces it to be a fixed size. + //Make ake the necessary changes to fully support a variable size in the future. + if (REF_ECDSDA_AUTHENTICATION_DATA_SIZE != authentication_data_size) { + return(TDQE_ERROR_INVALID_PARAMETER); + } + } + + memset(&plaintext_data, 0, sizeof(plaintext_data)); + + if (UINT16_MAX < authentication_data_size) { + return(TDQE_ERROR_INVALID_PARAMETER); + } + plaintext_data.authentication_data_size = (uint16_t)authentication_data_size; + if (p_authentication_data) { + sgx_lfence(); + memcpy(plaintext_data.authentication_data, p_authentication_data, sizeof(plaintext_data.authentication_data)); + } + + ret = random_stack_advance(get_att_key_based_from_seal_key,&pciphertext_data->ecdsa_private_key, + &plaintext_data.ecdsa_att_public_key, + &req_key_id); + if (TDQE_SUCCESS != ret) { + if (TDQE_ERROR_CRYPTO == ret) { + ret = TDQE_ERROR_ATT_KEY_GEN; + } + goto ret_point; + } + // Public key is returned in big endian format. Store public key and generate the hash using big + // endian format. + // The Private key is returned in little endian format. Store the private key is little endian + // as the signing algorithm is uses little endian format. + + do { + sgx_status = sgx_sha256_init(&sha_handle); + if (SGX_SUCCESS != sgx_status) { + break; + } + + sgx_status = sgx_sha256_update((uint8_t*)&plaintext_data.ecdsa_att_public_key, + sizeof(plaintext_data.ecdsa_att_public_key), + sha_handle); + if (SGX_SUCCESS != sgx_status) { + break; + } + + sgx_status = sgx_sha256_update((uint8_t*)plaintext_data.authentication_data, + sizeof(plaintext_data.authentication_data), + sha_handle); + if (SGX_SUCCESS != sgx_status) { + break; + } + + sgx_status = sgx_sha256_get_hash(sha_handle, + reinterpret_cast(&plaintext_data.ecdsa_id)); + if (SGX_SUCCESS != sgx_status) { + break; + } + + } while (0); + if (SGX_SUCCESS != sgx_status) { + ret = TDQE_ERROR_UNEXPECTED; + goto ret_point; + } + ref_static_assert(sizeof(plaintext_data.ecdsa_id) <= sizeof(report_data)); + memcpy(&report_data, &plaintext_data.ecdsa_id, sizeof(plaintext_data.ecdsa_id)); + + sgx_status = sgx_create_report(p_pce_target_info, &report_data, p_tdqe_report); + if (SGX_SUCCESS != sgx_status) { + if (SGX_ERROR_OUT_OF_MEMORY == sgx_status) { + ret = TDQE_ERROR_OUT_OF_MEMORY; + } + else { + ret = TDQE_ERROR_UNEXPECTED; + } + goto ret_point; + } + + plaintext_data.seal_blob_type = SGX_QL_SEAL_ECDSA_KEY_BLOB; + plaintext_data.ecdsa_key_version = SGX_QL_ECDSA_KEY_BLOB_VERSION_0; + // Call sgx_seal_data to generate the ECDSA Blob with the updated information + sgx_status = sgx_seal_data(sizeof(plaintext_data), + reinterpret_cast(&plaintext_data), //plaintext as AAD + sizeof(*pciphertext_data), + reinterpret_cast(pciphertext_data), //ciphertext data to SEAL + blob_size, + (sgx_sealed_data_t*)p_blob); + if (SGX_SUCCESS != sgx_status) { + ret = TDQE_ERROR_UNEXPECTED; + goto ret_point; + } + +ret_point: + // Clear output data on error + if (TDQE_SUCCESS != ret) { + (void)memset_s(p_tdqe_report, sizeof(*p_tdqe_report), 0, sizeof(*p_tdqe_report)); + } + + if (NULL != sha_handle) { + sgx_sha256_close(sha_handle); + } + + // Clear out any sensitive data from the stack before returning. + memset_s(pciphertext_data, sizeof(*pciphertext_data), 0, sizeof(*pciphertext_data)); + return(ret); +} + +/** + * External function exposed through the EDL used to store the ECDSA blob with all of the certification data from the + * PCE along with the ECDSA attestation key. It must be called after retrieving the PCE identity information, generating + * the ECDSA attestation key pair, and getting the PCE to certify the ECDSA attestation key. Once the ECDSA blob has been + * stored with all of the requisite information, quote generation can take place. + * + * @param p_plaintext_data + * [In] Pointer to the plaintext data to store in the blob. Most of the plaintext values are populated + * by the calling code. It must not be NULL and the full plaintext buffer must reside in the enclave's + * memory space. + * @param cert_key_type + * [In] Indicates the type of certification data used in the quote. Only PPID_RSA3072 is supported. If + * PPID_CLEARTEXT was supported, the PPID will be decrypted by the RSA private before sealing + * (encrypted) it in the ECDSA blob with the seal key. Otherwise, the encrypted PPID is left + * encrypted by the RSA key and the sealed (encrypted) by the seal key. + * @param p_encrypted_ppid + * [In] Pointer to the encrypted PPID as generated by the PCE. + * @param encrypted_ppid_size + * [In] Size of the enrypted PPID. + * @param p_blob [In, Out] Pointer the buffer that will contain the sealed ECDSA blob. For recertification, it will + * contain a valid ECDSA blob that will be unsealed to extract the secret data and then be resealed + * with the new certification data. Otherwise, the contents of the p_blob buffer will be overwritten + * with the new certification data and new secret data. It must not be NULL and the buffer must reside + * in the enclave's memory space. + * @param blob_size [In] Size in bytes of the p_blob buffer. Must be equal to SGX_QL_TRUSTED_ECDSA_BLOB_SIZE_SDK. + * + * @return TDQE_SUCCESS + * @return TDQE_ERROR_INVALID_PLATFORM + * @return TDQE_ERROR_INVALID_PARAMETER + * @return TDQE_ERROR_UNEXPECTED + * @return TDQE_ERROR_OUT_OF_MEMORY + * @return TDQE_ERROR_CRYPTO + * @return TDQE_ECDSABLOB_ERROR + */ +uint32_t store_cert_data(ref_plaintext_ecdsa_data_sdk_t *p_plaintext_data, + sgx_ql_cert_key_type_t cert_key_type, + uint8_t *p_encrypted_ppid, + uint32_t encrypted_ppid_size, + uint8_t *p_blob, + uint32_t blob_size) +{ + tdqe_error_t ret = TDQE_SUCCESS; + sgx_status_t sgx_status = SGX_SUCCESS; + + if (!is_verify_report2_available()) { + return (TDQE_ERROR_INVALID_PLATFORM); + } + // + // provide extra protection for attestation key by + // randomizing its address and securely aligning it + // + using cciphertext_data = randomly_placed_object< + sgx::custom_alignment_aligned< + ref_ciphertext_ecdsa_data_sdk_t, + alignof(ref_ciphertext_ecdsa_data_sdk_t), + __builtin_offsetof(ref_ciphertext_ecdsa_data_sdk_t, ecdsa_private_key), + sizeof(((ref_ciphertext_ecdsa_data_sdk_t*)0)->ecdsa_private_key)>>; + // + // instance of randomly_placed_object + // + cciphertext_data ociphertext_data_buf; + // + // pointer to instance of custom_alignment_aligned + // + auto* ociphertext_data = ociphertext_data_buf.instantiate_object(); + ref_ciphertext_ecdsa_data_sdk_t* pciphertext_data = &ociphertext_data->v; + + ref_plaintext_ecdsa_data_sdk_t local_plaintext_data; + uint8_t is_resealed; + + if ((NULL == p_blob) || + (NULL == p_plaintext_data)) { + return(TDQE_ERROR_INVALID_PARAMETER); + } + if (blob_size != SGX_QL_TRUSTED_ECDSA_BLOB_SIZE_SDK) { + return(TDQE_ERROR_INVALID_PARAMETER); + } + /* Check whether p_blob is copied into EPC. If we want to reduce the + memory usage, maybe we can leave the p_blob outside EPC. */ + if (!sgx_is_within_enclave(p_blob, blob_size)) { + return(TDQE_ERROR_INVALID_PARAMETER); + } + + if (NULL != p_encrypted_ppid) { + if ((!sgx_is_within_enclave(p_encrypted_ppid, REF_RSA_OAEP_3072_MOD_SIZE)) || + (REF_RSA_OAEP_3072_MOD_SIZE != encrypted_ppid_size)) { + return(TDQE_ERROR_INVALID_PARAMETER); + } + } + + if (!sgx_is_within_enclave(p_plaintext_data, sizeof(*p_plaintext_data))) { + return(TDQE_ERROR_INVALID_PARAMETER); + } + + // Only 3072 encrypted PPID is supported post alpha. + if (PPID_RSA3072_ENCRYPTED != cert_key_type) { + return(TDQE_ERROR_INVALID_PARAMETER); + } + + // Verify ECDSA p_blob + ret = random_stack_advance(verify_blob_internal,p_blob, + blob_size, + &is_resealed, + &local_plaintext_data, + (sgx_report_body_t*) NULL, + (uint8_t*) NULL, + 0, + pciphertext_data); + if (TDQE_SUCCESS != ret) { + goto ret_point; + } + + // Compare the ECDSA_ID passed in matches the value in the existing ECDSA Blob. This should catch keys that haven't been generated before storing + if (0 != memcmp(&local_plaintext_data.ecdsa_id, &p_plaintext_data->qe_report.body.report_data, sizeof(local_plaintext_data.ecdsa_id))) { //ECDSA_ID is the first 32bytes of REPORT.ReportData + ret = TDQE_ERROR_INVALID_PARAMETER; + goto ret_point; + } + + /* Create report to get current cpu_svn and isv_svn. */ + sgx_report_t report; + memset(&report, 0, sizeof(report)); + sgx_status = sgx_create_report(NULL, NULL, &report); + if (SGX_SUCCESS != sgx_status) { + if (SGX_ERROR_OUT_OF_MEMORY == sgx_status) { + ret = TDQE_ERROR_OUT_OF_MEMORY; + } + else { + ret = TDQE_ERROR_UNEXPECTED; + } + goto ret_point; + } + + /* Store the current QE PSVN with the blob to indicate what the TCB was when sealed. */ + memcpy(&local_plaintext_data.seal_cpu_svn, &report.body.cpu_svn, sizeof(local_plaintext_data.seal_cpu_svn)); + local_plaintext_data.seal_qe_isv_svn = report.body.isv_svn; + + // For recertification, the PPID does not change. No need to process the PPID information again since it is + // unchanged from the previous certification. + // PPID_CLEARTEXT is not supported. Parameter check above will not allow this cert_key_type. + if (NULL != p_encrypted_ppid) { + pciphertext_data->is_clear_ppid = 0; // Specifies that ciphertext part of the blob contains the ciphertext PPID instead of the cleartext PPID + pciphertext_data->encrypted_ppid_data.crypto_suite = PCE_ALG_RSA_OAEP_3072; + pciphertext_data->encrypted_ppid_data.encrypted_ppid_buf_size = encrypted_ppid_size; + memcpy(pciphertext_data->encrypted_ppid_data.encrypted_ppid, p_encrypted_ppid, encrypted_ppid_size); //encrypted_ppid_size checked above. + } + + local_plaintext_data.cert_qe_isv_svn = report.body.isv_svn; + + // Copy in the PCE identity used to certify the ECDSA Attestation key + memcpy(&local_plaintext_data.cert_cpu_svn, &p_plaintext_data->cert_cpu_svn, sizeof(local_plaintext_data.cert_cpu_svn)); + local_plaintext_data.cert_pce_info.pce_isv_svn = p_plaintext_data->cert_pce_info.pce_isv_svn; + local_plaintext_data.cert_pce_info.pce_id = p_plaintext_data->cert_pce_info.pce_id; + + // Re-copy in the old certification data + local_plaintext_data.signature_scheme = p_plaintext_data->signature_scheme; + memcpy(&local_plaintext_data.qe_report, &p_plaintext_data->qe_report, sizeof(local_plaintext_data.qe_report)); + memcpy(&local_plaintext_data.qe_report_cert_key_sig, &p_plaintext_data->qe_report_cert_key_sig, sizeof(local_plaintext_data.qe_report_cert_key_sig)); + local_plaintext_data.certification_key_type = p_plaintext_data->certification_key_type; + memcpy_s(&local_plaintext_data.pce_target_info, sizeof(local_plaintext_data.pce_target_info), &p_plaintext_data->pce_target_info, sizeof(p_plaintext_data->pce_target_info)); + memcpy_s(&local_plaintext_data.raw_cpu_svn, sizeof(local_plaintext_data.raw_cpu_svn), &p_plaintext_data->raw_cpu_svn, sizeof(p_plaintext_data->raw_cpu_svn)); + local_plaintext_data.raw_pce_info.pce_isv_svn = p_plaintext_data->raw_pce_info.pce_isv_svn; + local_plaintext_data.raw_pce_info.pce_id = p_plaintext_data->raw_pce_info.pce_id; + memcpy_s(&local_plaintext_data.qe_id, sizeof(local_plaintext_data.qe_id), &p_plaintext_data->qe_id, sizeof(p_plaintext_data->qe_id)); + + // Call sgx_seal_data to generate the ECDSA Blob with the updated information + sgx_status = sgx_seal_data(sizeof(local_plaintext_data), + reinterpret_cast(&local_plaintext_data), //plaintext as AAD + sizeof(*pciphertext_data), + reinterpret_cast(pciphertext_data), //ciphertext data to SEAL + blob_size, + (sgx_sealed_data_t*)p_blob); + if (SGX_SUCCESS != sgx_status) { + ret = TDQE_ERROR_UNEXPECTED; + goto ret_point; + } + +ret_point: + memset_s(pciphertext_data, sizeof(*pciphertext_data), 0, sizeof(*pciphertext_data)); + return(ret); +} + +/** + * External function exposed through the EDL used to generate a quote. It will take the TD report requesting a + * quote. It also takes the ECDSA blob that contains the private attestation key and the PCE certification data. + * The other inputs are the data required to fill out the quote structure. The application enclave's report will + * verified and signed with the ECDSA attestation private key and will return the resulting quote in the provided + * buffer. The caller can also optionally request that this enclave generate a report targeting the requesting + * enclave along with a nonce. If requested, the resulting QE report will be returned with the QE_Report.ReportData + * equal to the nonce. This allows the requesting enclave to verify the Quote was generated by a valid QE. + * + * @param p_blob [In, Out] Pointer to the ECDSA Blob. Must not be NULL and the full buffer must be inside the + * enclave's memory space. If the blob was resealed, upon return, the p_blob will point to the + * resealed blob and the caller should save it.[in, out] Pointer to the ECDSA Blob. + * @param blob_size [In] Size in bytes of the ECDSA blob buffer pointed to by p_blob. + * @param p_td_report + * [In] The TD report. It must be generated in a Trust Domain on this physical platform. + * @param p_nonce [In] Optional pointer to a nonce. This nonce will be used when the caller requests this enclave to + * generate a report. The resulting report's report_data field will contain the SHA256(nonce||quote). + * If the p_nonce is NULL, then the p_qe_report must be NULL. IF the p_nonce is not NULL, then the + * p_qe_report must not be NULL. If provided, the buffer must reside in the enclave's memory space. + * @param p_app_enclave_target_info [in] The application enclave's target info. + * @param p_qe_report_out + * [In, Out] Optional pointer to this enclave's report targeting the requesting enclave. The resulting + * report's report_data field will contain the SHA256(nonce||quote). If the p_nonce is NULL, then the + * p_qe_report must be NULL. IF the p_nonce is not NULL, then the p_qe_report must not be NULL. If + * provided, the buffer must reside in the enclave's memory space. + * @param p_quote_buf [out] Pointer to the output buffer for quote. + * @param quote_size [in] The size of buffer pointed to by p_quote, in bytes. It must be at least the value returned by + the ref_get_quote_size() API. + * @param p_certification_data [In] The optional cert_data, it can be NULL. + * @param cert_data_size [in] The size of buffer pointed to by p_certification_data, in bytes. If p_certification_data is NULL, it should + be 0. + + * @return TDQE_SUCCESS + * @return TDQE_ERROR_INVALID_PLATFORM + * @return TDQE_ERROR_INVALID_PARAMETER + * @return TDQE_ECDSABLOB_ERROR + * @return TDQE_ERROR_UNEXPECTED + * @return TDQE_ERROR_INVALID_REPORT + * @return TDQE_ERROR_OUT_OF_MEMORY + */ +uint32_t gen_quote(uint8_t *p_blob, + uint32_t blob_size, + const sgx_report2_t *p_td_report, + const sgx_quote_nonce_t *p_nonce, + const sgx_target_info_t *p_app_enclave_target_info, + sgx_report_t *p_qe_report_out, + uint8_t *p_quote_buf, + uint32_t quote_size, + const uint8_t * p_certification_data, + uint32_t cert_data_size) +{ + tdqe_error_t ret = TDQE_SUCCESS; + sgx_quote4_t *p_quote; + sgx_ecdsa_sig_data_v4_t *p_quote_sig; + sgx_ql_certification_data_t *p_qe_report_cert_header; + sgx_qe_report_certification_data_t *p_qe_report_cert_data; + uint8_t is_resealed = 0; + uint32_t sign_size = 0; + sgx_status_t sgx_status = SGX_SUCCESS; + sgx_report_t qe_report; + size_t required_buffer_size = 0; + ref_plaintext_ecdsa_data_sdk_t plaintext; + + if (!is_verify_report2_available()) { + return (TDQE_ERROR_INVALID_PLATFORM); + } + // + // provide extra protection for attestation key by + // randomizing its address and securely aligning it + // + using cciphertext = randomly_placed_object< + sgx::custom_alignment_aligned< + ref_ciphertext_ecdsa_data_sdk_t, + alignof(ref_ciphertext_ecdsa_data_sdk_t), + __builtin_offsetof(ref_ciphertext_ecdsa_data_sdk_t, ecdsa_private_key), + sizeof(((ref_ciphertext_ecdsa_data_sdk_t*)0)->ecdsa_private_key)>>; + // + // instance of randomly_placed_object + // + cciphertext ociphertext_buf; + // + // pointer to instance of custom_alignment_aligned + // + auto* ociphertext = ociphertext_buf.instantiate_object(); + ref_ciphertext_ecdsa_data_sdk_t* pciphertext = &ociphertext->v; + + sgx_sha384_hash_t hash384_buf = {0}; + sgx_ecc_state_handle_t handle = NULL; + sgx_ql_auth_data_t *p_auth_data; + sgx_ql_certification_data_t *p_certification_data_output; + sgx_ql_ppid_rsa3072_encrypted_cert_info_t *p_cert_encrypted_ppid_info_data; + sgx_sha_state_handle_t sha_quote_context = NULL; + sgx_report_data_t qe_report_data; + tee_tcb_info_t* p_tee_tcb_info; + tee_info_t* p_tee_info; + sgx_ec256_public_t le_att_pub_key; + uint8_t verify_result = SGX_EC_INVALID_SIGNATURE; + + memset(&plaintext, 0, sizeof(plaintext)); + + // Actually, some cases here will be checked with code generated by + // edger8r. Here we just want to defend in depth. + if ((NULL == p_blob) || + (NULL == p_td_report) || + (NULL == p_quote_buf) || + (!quote_size)) { + return(TDQE_ERROR_INVALID_PARAMETER); + } + if (SGX_QL_TRUSTED_ECDSA_BLOB_SIZE_SDK != blob_size) { + return(TDQE_ERROR_INVALID_PARAMETER); + } + // All these 3 parameters should be all NULL or all not NULL. + if (!((NULL == p_nonce) && (NULL == p_app_enclave_target_info) && (NULL == p_qe_report_out)) + && !((NULL != p_nonce) && (NULL != p_app_enclave_target_info) && (NULL != p_qe_report_out))) { + return(TDQE_ERROR_INVALID_PARAMETER); + } + if (NULL != p_certification_data) + { + sgx_ql_certification_data_t * p_input_certification_data_header = (sgx_ql_certification_data_t *)p_certification_data; + if (PPID_CLEARTEXT > p_input_certification_data_header->cert_key_type + || QL_CERT_KEY_TYPE_MAX < p_input_certification_data_header->cert_key_type) { + return(TDQE_ERROR_INVALID_PARAMETER); + } + if (MAX_CERT_DATA_SIZE < p_input_certification_data_header->size) { + return(TDQE_ERROR_INVALID_PARAMETER); + } + if (sizeof(sgx_ql_certification_data_t) + p_input_certification_data_header->size != cert_data_size) { + return(TDQE_ERROR_INVALID_PARAMETER); + } + } + if (NULL == p_certification_data && cert_data_size !=0) { + return(TDQE_ERROR_INVALID_PARAMETER); + } + + + // The ECDSA Quote is not so large that it needs to be outside the enclave. Verify the full buffer is within + // the EPC. To reduce the ECDSA QE, it can be moved outside the epc. + if (!sgx_is_within_enclave(p_quote_buf, quote_size)) { + return(TDQE_ERROR_INVALID_PARAMETER); + } + + /* Check whether p_blob is copied into EPC. If we want to reduce the + memory usage, maybe we can leave the p_blob outside EPC. */ + if (!sgx_is_within_enclave(p_blob, blob_size)) { + return(TDQE_ERROR_INVALID_PARAMETER); + } + if (!sgx_is_within_enclave(p_td_report, sizeof(*p_td_report))) { + return(TDQE_ERROR_INVALID_PARAMETER); + } + + if (NULL != p_certification_data) { + if (!sgx_is_within_enclave(p_certification_data, cert_data_size)) { + return(TDQE_ERROR_INVALID_PARAMETER); + } + } + + // If the code reaches here, if p_nonce is NULL, then p_qe_report will be + // NULL also. So we only check p_nonce here. + if (p_nonce) { + // Actually Edger8r will alloc the buffer within EPC, this is just kind + // of defense in depth. + if (!sgx_is_within_enclave(p_nonce, sizeof(*p_nonce))) { + return(TDQE_ERROR_INVALID_PARAMETER); + } + if (!sgx_is_within_enclave(p_qe_report_out, sizeof(*p_qe_report_out))) { + return(TDQE_ERROR_INVALID_PARAMETER); + } + if (!sgx_is_within_enclave(p_app_enclave_target_info, sizeof(*p_app_enclave_target_info))) { + return(TDQE_ERROR_INVALID_PARAMETER); + } + } + + ref_static_assert(sizeof(tee_tcb_info_t) == sizeof(p_td_report->tee_tcb_info)); + p_tee_tcb_info = (tee_tcb_info_t*)p_td_report->tee_tcb_info; + if (p_tee_tcb_info->valid[0] != 0xFF || p_tee_tcb_info->valid[1] != 1) { + return(TDQE_REPORT_FORMAT_NOT_SUPPORTED); + } + for (size_t i = 2; i < sizeof(p_tee_tcb_info->valid); i++) { + if (p_tee_tcb_info->valid[i]) { + return(TDQE_REPORT_FORMAT_NOT_SUPPORTED); + } + } + + ref_static_assert(sizeof(tee_info_t) == sizeof(p_td_report->tee_info)); + p_tee_info = (tee_info_t*)p_td_report->tee_info; + for (int i = 0; i < TD_INFO_RESERVED_BYTES; i++) { + if (p_tee_info->reserved[i]) { + return(TDQE_REPORT_FORMAT_NOT_SUPPORTED); + } + } + + // Verify the input report. + sgx_status = sgx_verify_report2(&p_td_report->report_mac_struct); + if (SGX_SUCCESS != sgx_status) { + if (SGX_ERROR_INVALID_PARAMETER == sgx_status) { + return(TDQE_REPORT_FORMAT_NOT_SUPPORTED); + } + else { + return(TDQE_ERROR_INVALID_REPORT); + } + } + + // tee tcb info hash + sgx_status = sgx_sha384_msg((uint8_t *)(&(p_td_report->tee_tcb_info)), sizeof(p_td_report->tee_tcb_info), &hash384_buf); + if (SGX_SUCCESS != sgx_status) { + ret = TDQE_ERROR_UNEXPECTED; + goto ret_point; + } + + //verify the tee tcb hash data data is SHA384(tee tcb info) + if(memcmp(&hash384_buf, &p_td_report->report_mac_struct.tee_tcb_info_hash, sizeof(p_td_report->report_mac_struct.tee_tcb_info_hash))!=0){ + ret = TDQE_ERROR_INVALID_HASH; + goto ret_point; + } + + memset(&hash384_buf, 0x00, sizeof(hash384_buf)); + + // td info hash + sgx_status = sgx_sha384_msg((uint8_t *)(&(p_td_report->tee_info)), sizeof(p_td_report->tee_info), &hash384_buf); + if (SGX_SUCCESS != sgx_status) { + ret = TDQE_ERROR_UNEXPECTED; + goto ret_point; + } + + //verify the td info hash data data is SHA384(td info) + if(memcmp(&hash384_buf, &p_td_report->report_mac_struct.tee_info_hash, sizeof(p_td_report->report_mac_struct.tee_info_hash))!=0){ + ret = TDQE_ERROR_INVALID_HASH; + goto ret_point; + } + + // Verify ECDSA p_blob and create the context + ret = random_stack_advance(verify_blob_internal,p_blob, + blob_size, + &is_resealed, + &plaintext, + (sgx_report_body_t*) NULL, + (uint8_t*) NULL, + 0, + pciphertext); + if (TDQE_SUCCESS != ret) { + goto ret_point; + } + + sign_size = sizeof(sgx_ecdsa_sig_data_v4_t) + // ECDSA sig data structure + sizeof(sgx_ql_auth_data_t) + + sizeof(sgx_ql_certification_data_t) + // We added sgx_qe_report_certification_data_t in version 4 + sizeof(sgx_qe_report_certification_data_t) + + sizeof(sgx_ql_certification_data_t); + if (1 == pciphertext->is_clear_ppid) { + ret = TDQE_ERROR_INVALID_PARAMETER; + goto ret_point; + } + else { + if (!p_certification_data) { + sign_size += (uint32_t)sizeof(sgx_ql_ppid_rsa3072_encrypted_cert_info_t); // RSA3072_Enc_PPID, PCE PSVN and PCE_ID + } + else { + sign_size += ((sgx_ql_certification_data_t *)p_certification_data)->size; + } + } + /* Check for overflow before adding in the variable size of authentication data. */ + if ((UINT32_MAX - sign_size - sizeof(sgx_quote4_t)) < plaintext.authentication_data_size) { + ret = TDQE_ERROR_INVALID_PARAMETER; + goto ret_point; + } + sign_size += plaintext.authentication_data_size; // Authentication data + + required_buffer_size = sizeof(sgx_quote4_t) + sign_size; + + // Make sure the buffer size is big enough. + if (quote_size < required_buffer_size) { + ret = TDQE_ERROR_INVALID_PARAMETER; + goto ret_point; + } + + // Verify sizeof header.userdata is large enough + ref_static_assert(sizeof(plaintext.qe_id) <= sizeof(p_quote->header.user_data)); + + // Clear out the quote buffer + sgx_lfence(); + memset(p_quote_buf, 0, required_buffer_size); + // Set up the component quote structure pointers to point to the correct place within the inputted quote buffer. + p_quote = (sgx_quote4_t *)p_quote_buf; + p_quote->signature_data_len = sign_size; + p_quote_sig = (sgx_ecdsa_sig_data_v4_t*)(p_quote->signature_data); + + p_qe_report_cert_header = ((sgx_ql_certification_data_t *)(p_quote_sig->certification_data)); + p_qe_report_cert_data = (sgx_qe_report_certification_data_t *)(p_qe_report_cert_header->certification_data); + p_qe_report_cert_header->cert_key_type = ECDSA_SIG_AUX_DATA; + + //p_auth_data = (sgx_ql_auth_data_t*)(p_quote_sig->auth_certification_data); + p_auth_data = (sgx_ql_auth_data_t *)(p_quote_sig->certification_data + sizeof(sgx_ql_certification_data_t) + sizeof(sgx_qe_report_certification_data_t)); + p_auth_data->size = (uint16_t)plaintext.authentication_data_size; + + // write initial size for p_qe_report_cert_header->size, will add remain part later. + p_qe_report_cert_header->size = (uint32_t)(sizeof(sgx_qe_report_certification_data_t) + sizeof(sgx_ql_auth_data_t) + + p_auth_data->size + sizeof(sgx_ql_certification_data_t)); + + //Note: This is potentially dangerous pointer math using an untrusted input size. The 'required_buffer_size' check + //above verifies that the size will not put the calculated address and certification data outside of the inputted + //p_quote + quote_size memory. + p_certification_data_output = (sgx_ql_certification_data_t*)((uint8_t*)p_auth_data + sizeof(*p_auth_data) + p_auth_data->size); + + // Populate the quote buffer. + // Set up the header. + p_quote->header.version = QE_QUOTE_VERSION; + p_quote->header.att_key_type = SGX_QL_ALG_ECDSA_P256; + p_quote->header.tee_type = 0x81; // TEE for this attestation, little endian 0x81 means TDX + // Sizes of user_data and qe_id were checked above. If here, then sizes are OK without overflow. + + // Copy in QE_ID from blob + memcpy(&p_quote->header.user_data, &plaintext.qe_id, sizeof(plaintext.qe_id)); + // Copy in Intel's Vender ID + memcpy(p_quote->header.vendor_id, g_vendor_id, sizeof(g_vendor_id)); + // Fill the td report body. + memset(&(p_quote->report_body), 0, sizeof(p_quote->report_body)); + + memcpy(&(p_quote->report_body.tee_tcb_svn), &(p_tee_tcb_info->tee_tcb_svn), sizeof(p_quote->report_body.tee_tcb_svn)); + memcpy(&(p_quote->report_body.mr_seam), &(p_tee_tcb_info->mr_seam), sizeof(p_quote->report_body.mr_seam)); + + memcpy(&(p_quote->report_body.td_attributes), &(p_tee_info->attributes), sizeof(p_quote->report_body.td_attributes)); + memcpy(&(p_quote->report_body.xfam), &(p_tee_info->xfam), sizeof(p_quote->report_body.xfam)); + memcpy(&(p_quote->report_body.mr_td), &(p_tee_info->mr_td), sizeof(p_quote->report_body.mr_td)); + memcpy(&(p_quote->report_body.mr_config_id), &(p_tee_info->mr_config_id), sizeof(p_quote->report_body.mr_config_id)); + memcpy(&(p_quote->report_body.mr_owner), &(p_tee_info->mr_owner), sizeof(p_quote->report_body.mr_owner)); + memcpy(&(p_quote->report_body.mr_owner_config), &(p_tee_info->mr_owner_config), sizeof(p_quote->report_body.mr_owner_config)); + memcpy(p_quote->report_body.rt_mr, p_tee_info->rt_mr, sizeof(p_quote->report_body.rt_mr)); + memcpy(&(p_quote->report_body.report_data), &(p_td_report->report_mac_struct.report_data), sizeof(p_quote->report_body.report_data)); + + memset(&qe_report_data, 0, sizeof(qe_report_data)); + sgx_status = sgx_create_report(NULL, &qe_report_data, &qe_report); + if (SGX_SUCCESS != sgx_status) { + if (SGX_ERROR_OUT_OF_MEMORY == sgx_status) { + ret = TDQE_ERROR_OUT_OF_MEMORY; + } + else { + ret = TDQE_ERROR_UNEXPECTED; + } + goto ret_point; + } + // Generate the quote signature. + sgx_status = sgx_ecc256_open_context(&handle); + if (SGX_ERROR_OUT_OF_MEMORY == sgx_status) { + ret = TDQE_ERROR_OUT_OF_MEMORY; + goto ret_point; + } + else if (SGX_SUCCESS != sgx_status) { + ret = TDQE_ERROR_UNEXPECTED; + goto ret_point; + } + // Sign everything in the quote except the signature_data_len. This allows the quote certification information to change + // to contain the actual PCK cert after initially only carring the PPID+PCEID+TCB without making the quote invalid. + sgx_status = sgx_ecdsa_sign(reinterpret_cast(p_quote), + sizeof(*p_quote) - sizeof(p_quote->signature_data_len), + &pciphertext->ecdsa_private_key, + reinterpret_cast(p_quote_sig->sig), + handle); + if (SGX_ERROR_OUT_OF_MEMORY == sgx_status) { + ret = TDQE_ERROR_OUT_OF_MEMORY; + goto ret_point; + } + else if (SGX_SUCCESS != sgx_status) { + ret = TDQE_ERROR_UNEXPECTED; + goto ret_point; + } + + memcpy(&le_att_pub_key, &plaintext.ecdsa_att_public_key, sizeof(le_att_pub_key)); + //big endian to little endian + SWAP_ENDIAN_32B(le_att_pub_key.gx); + SWAP_ENDIAN_32B(le_att_pub_key.gy); + + // the signature verify code here is for FI (fault injection) mitigation. + sgx_status = sgx_ecdsa_verify(reinterpret_cast(p_quote), + sizeof(*p_quote) - sizeof(p_quote->signature_data_len), + &le_att_pub_key, + reinterpret_cast(p_quote_sig->sig), + &verify_result, + handle); + if (SGX_SUCCESS != sgx_status || SGX_EC_VALID != verify_result) { + if (SGX_SUCCESS != sgx_read_rand((unsigned char*)p_quote_sig->sig, + sizeof(sgx_ec256_signature_t))) + memset(p_quote_sig->sig, 0, sizeof(sgx_ec256_signature_t)); + ret = TDQE_ERROR_UNEXPECTED; + goto ret_point; + } + + // Swap signature x and y from little endian used in sgx_crypto to big endian used in quote byte order + { + size_t i; + uint8_t swap; + for (i = 0; i < 32 / 2; i++) { + swap = p_quote_sig->sig[i]; + p_quote_sig->sig[i] = p_quote_sig->sig[32 - 1 - i]; + p_quote_sig->sig[32 - 1 - i] = swap; + } + for (i = 0; i < 32 / 2; i++) { + swap = p_quote_sig->sig[32 + i]; + p_quote_sig->sig[32 + i] = p_quote_sig->sig[64 - 1 - i]; + p_quote_sig->sig[64 - 1 - i] = swap; + } + } + // Add the public part of the ECDSA key to the quote sig data. Store it in Big Endian + memcpy(p_quote_sig->attest_pub_key, &plaintext.ecdsa_att_public_key, sizeof(p_quote_sig->attest_pub_key)); + + // Add the QE Report to the Quote QE report certification data (the qe report when it was signed by the PCE!). + memcpy(&(p_qe_report_cert_data->qe_report), &plaintext.qe_report.body, sizeof(p_qe_report_cert_data->qe_report)); + + // Add the PCE signature + memcpy(p_qe_report_cert_data->qe_report_sig, &plaintext.qe_report_cert_key_sig, sizeof(p_qe_report_cert_data->qe_report_sig)); + + // Copy in the Authentication Data + if (0 != p_auth_data->size) { + memcpy(p_auth_data->auth_data, plaintext.authentication_data, p_auth_data->size); + } + + if (NULL == p_certification_data) { + p_cert_encrypted_ppid_info_data = (sgx_ql_ppid_rsa3072_encrypted_cert_info_t *)p_certification_data_output->certification_data; + // Prepare the the certification data. PPID_RSA3072_ENCRYPTED = Encrypted_PPID + PCE_TCB + PCEID is supported by the referecne. + p_certification_data_output->cert_key_type = PPID_RSA3072_ENCRYPTED; + p_certification_data_output->size = sizeof(sgx_ql_ppid_rsa3072_encrypted_cert_info_t); + // Get the cert_info_data from the ECDSA blob. + memcpy(p_cert_encrypted_ppid_info_data->enc_ppid, pciphertext->encrypted_ppid_data.encrypted_ppid, sizeof(p_cert_encrypted_ppid_info_data->enc_ppid)); + p_cert_encrypted_ppid_info_data->pce_info = plaintext.cert_pce_info; + memcpy(&p_cert_encrypted_ppid_info_data->cpu_svn, &plaintext.cert_cpu_svn, sizeof(p_cert_encrypted_ppid_info_data->cpu_svn)); + + // update p_qe_report_cert_header->size + p_qe_report_cert_header->size = p_qe_report_cert_header->size + p_certification_data_output->size; + } + else { + sgx_ql_certification_data_t * p_input_certification_data_header = (sgx_ql_certification_data_t *)p_certification_data; + p_certification_data_output->cert_key_type = p_input_certification_data_header->cert_key_type; + p_certification_data_output->size = p_input_certification_data_header->size; + // Get the cert_info_data from the ECDSA blob. + if (0 != memcpy_s(p_certification_data_output->certification_data, p_certification_data_output->size, + &p_input_certification_data_header->certification_data, p_input_certification_data_header->size)) { + ret = TDQE_ERROR_UNEXPECTED; + goto ret_point; + } + + // update p_qe_report_cert_header->size + p_qe_report_cert_header->size = p_qe_report_cert_header->size + p_certification_data_output->size; + } + + // Get the QE's report if requested. + ///todo: It is possible that the untrusted code can change the certification data of the quote (including the + //the signature_length. We may need to modify the quote hash generation to skip the modifiable values!! + if (NULL != p_nonce) { + ref_static_assert(sizeof(qe_report_data) >= sizeof(sgx_sha256_hash_t)); + + sgx_status = sgx_sha256_init(&sha_quote_context); + if (SGX_SUCCESS != sgx_status) { + ret = TDQE_ERROR_UNEXPECTED; + goto ret_point; + } + + memset(&qe_report_data, 0, sizeof(qe_report_data)); + // Update hash for nonce. + sgx_status = sgx_sha256_update((uint8_t *)const_cast(p_nonce), + (uint32_t)sizeof(*p_nonce), + sha_quote_context); + if (SGX_SUCCESS != sgx_status) { + ret = TDQE_ERROR_UNEXPECTED; + goto ret_point; + } + // Update hash with the quote. + sgx_status = sgx_sha256_update(p_quote_buf, + (uint32_t)required_buffer_size, + sha_quote_context); + if (SGX_SUCCESS != sgx_status) { + ret = TDQE_ERROR_UNEXPECTED; + goto ret_point; + } + sgx_status = sgx_sha256_get_hash(sha_quote_context, + (sgx_sha256_hash_t *)&qe_report_data); + if (SGX_SUCCESS != sgx_status) { + ret = TDQE_ERROR_UNEXPECTED; + goto ret_point; + } + ///todo: Evaluate the requirements on the format of target_info structure. + sgx_status = sgx_create_report(p_app_enclave_target_info, &qe_report_data, &qe_report); + if (SGX_SUCCESS != sgx_status) { + if (SGX_ERROR_OUT_OF_MEMORY == sgx_status) { + ret = TDQE_ERROR_OUT_OF_MEMORY; + } + else { + ret = TDQE_UNABLE_TO_GENERATE_QE_REPORT; + } + goto ret_point; + } + if (NULL != p_qe_report_out) { + memcpy(p_qe_report_out, &qe_report, sizeof(*p_qe_report_out)); + } + } + +ret_point: + // Clear out any senstive data. + memset_s(pciphertext, sizeof(*pciphertext), 0, sizeof(*pciphertext)); + if (handle != NULL) { + sgx_ecc256_close_context(handle); + } + if (sha_quote_context != NULL) { + sgx_sha256_close(sha_quote_context); + } + + return(ret); +} + diff --git a/QuoteGeneration/quote_wrapper/tdx_quote/enclave/quoting_enclave_tdqe.h b/QuoteGeneration/quote_wrapper/tdx_quote/enclave/quoting_enclave_tdqe.h new file mode 100644 index 00000000..c1765343 --- /dev/null +++ b/QuoteGeneration/quote_wrapper/tdx_quote/enclave/quoting_enclave_tdqe.h @@ -0,0 +1,114 @@ +/* + * Copyright (C) 2011-2021 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: quoting_enclave_tdqe.h + * + * Description: Definitions and prototypes + * for the sample application's quoteing + * enclave. + * + */ + +#ifndef _QUOTING_ENCLAVE_TDQE_H_ +#define _QUOTING_ENCLAVE_TDQE_H_ + +#include +#include + +#include "user_types.h" +#include "ecdsa_quote.h" +#include "sgx_tcrypto.h" + +#define QE_QUOTE_VERSION 4 ///< Version of the quote structure that supports ECDSA (and EPID). It is a generic form of the Quote. + +#define TDQE_MK_ERROR(x) (0x00010000|(x)) + +/** Possible errors generated by the TDQE */ +typedef enum _tdqe_error_t { + TDQE_SUCCESS = 0x0000, + TDQE_ERROR_UNEXPECTED = TDQE_MK_ERROR(0x0001), ///< Unexpected error. + TDQE_ERROR_INVALID_PARAMETER = TDQE_MK_ERROR(0x0002), ///< The parameter is incorrect. + TDQE_ERROR_OUT_OF_MEMORY = TDQE_MK_ERROR(0x0003), ///< Not enough memory is available to complete this operation. + TDQE_ECDSABLOB_ERROR = TDQE_MK_ERROR(0x0004), ///< There was a problem with verifying the ECDSA Blob. + TDQE_ERROR_CRYPTO = TDQE_MK_ERROR(0x0005), ///< An error occurred in the encryption library. + TDQE_ERROR_ATT_KEY_GEN = TDQE_MK_ERROR(0x0006), ///< Error generating the ECDSA Attestation key pair. + TDQE_ERROR_WRONG_STATE = TDQE_MK_ERROR(0x0007), ///< Key generation and certification flow is stateful. ECALL order is incorrect. + TDQE_ERROR_INVALID_REPORT = TDQE_MK_ERROR(0x0008), ///< The TD report is invalid + TDQE_UNABLE_TO_GENERATE_QE_REPORT = TDQE_MK_ERROR(0x0009), ///< The QE was unable to generate its own report targeting the application enclave. + TDQE_ERROR_INVALID_HASH = TDQE_MK_ERROR(0x000A), ///< The tee_tcb_info_hash or tee_tcb_info_hash is invalid. + TDQE_ERROR_INVALID_PLATFORM = TDQE_MK_ERROR(0x000B), ///< This QE cannot be used on this platform + TDQE_REPORT_FORMAT_NOT_SUPPORTED = TDQE_MK_ERROR(0x000C), ///< This TD report is not compatible with this QE +} tdqe_error_t; + +#pragma pack(push, 1) + +/** Structure definition of the RSA key used to decrypt the PCE's PPID */ +typedef struct _pce_rsaoaep_2048_encrypt_pub_key_t { + uint8_t n[REF_RSA_OAEP_2048_MOD_SIZE]; ///< RSA 2048 public modulus + uint8_t e[REF_RSA_OAEP_2048_EXP_SIZE]; ///< RSA 2048 public exponent +} pce_rsaoaep_2048_encrypt_pub_key_t; + +/** Structure definition of the RSA key used to decrypt the PCE's PPID */ +typedef struct _pce_rsaoaep_3072_encrypt_pub_key_t { + uint8_t n[REF_RSA_OAEP_3072_MOD_SIZE]; ///< RSA 3072 public modulus + uint8_t e[REF_RSA_OAEP_3072_EXP_SIZE]; ///< RSA 3072 public exponent +} pce_rsaoaep_3072_encrypt_pub_key_t; + +/** Structure used when storing the encrypted PPID from the PCE in the ECDSA Blob. */ +typedef struct _ref_encrypted_ppid_t { + uint8_t crypto_suite; ///< Encryption crypto algorithm used to encrypt the PPID + uint32_t encrypted_ppid_buf_size; ///< The size of the buffer holding the encrypted PPID + uint8_t encrypted_ppid[REF_RSA_OAEP_3072_MOD_SIZE]; ///< The buffer containing the encrypted PPID. Worst case size is 3072 +}ref_encrypted_ppid_t; + +/** Used to store the ciphertext data of the ECDSA key and the certification data in a sealed blob. This portion of the blob is +* authenticated and encrypted. +* The contents vary depending on the certification key type (sgx_cert_key_type_t) */ +typedef struct _ref_ciphertext_ecdsa_data_sdk_t { + sgx_ec256_private_t ecdsa_private_key; ///< ECDSA private key stored in little endian + uint8_t is_clear_ppid; ///< Indicates whether the PPID is stored in the clear or encrypted + union { + uint8_t ppid[16]; ///< PPID if stored in the clear. + ref_encrypted_ppid_t encrypted_ppid_data; ///< Encrypted PPID data + }; +}ref_ciphertext_ecdsa_data_sdk_t; + +#pragma pack(pop) + +#if defined(__cplusplus) +extern "C" { +#endif + +#if defined(__cplusplus) +} +#endif + +#endif /* !_QUOTING_ENCLAVE_TDQE_H_ */ diff --git a/QuoteGeneration/quote_wrapper/tdx_quote/enclave/tdqe.edl b/QuoteGeneration/quote_wrapper/tdx_quote/enclave/tdqe.edl new file mode 100644 index 00000000..502c444b --- /dev/null +++ b/QuoteGeneration/quote_wrapper/tdx_quote/enclave/tdqe.edl @@ -0,0 +1,79 @@ +/* + * Copyright (C) 2011-2021 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. + * + */ + +enclave { +include "sgx_report.h" +include "sgx_quote.h" +include "sgx_quote_4.h" +include "user_types.h" +include "ecdsa_quote.h" + +trusted { + public uint32_t get_pce_encrypt_key([in]const sgx_target_info_t *pce_target_info, + [out] sgx_report_t *p_qe_report, + uint8_t crypto_suite, + uint16_t cert_key_type, + uint32_t key_size, + [out, size=key_size] uint8_t *p_public_key); + + public uint32_t gen_att_key([size = blob_size, in, out] uint8_t *p_blob, + uint32_t blob_size, + [in]const sgx_target_info_t *p_pce_target_info, + [out] sgx_report_t *qe_report, + [in, size = authentication_data_size] uint8_t* p_authentication_data, + uint32_t authentication_data_size); + + public uint32_t verify_blob([size = blob_size, in, out] uint8_t *p_blob, + uint32_t blob_size, + [out] uint8_t *p_is_resealed, + [out] sgx_report_body_t *p_report, + uint32_t pub_key_id_size, + [out, size=pub_key_id_size] uint8_t *p_pub_key_id); + + public uint32_t store_cert_data([in]ref_plaintext_ecdsa_data_sdk_t *p_plaintext_data, + sgx_ql_cert_key_type_t certification_key_type, + [in, size = encrypted_ppid_size] uint8_t* p_encrypted_ppid, + uint32_t encrypted_ppid_size, + [in, out, size = blob_size] uint8_t *p_blob, + uint32_t blob_size); + + public uint32_t gen_quote([size = blob_size, in, out] uint8_t *p_blob, + uint32_t blob_size, + [in] const sgx_report2_t *p_app_report, + [in] const sgx_quote_nonce_t *p_nonce, + [in] const sgx_target_info_t *p_app_enclave_target_info, + [out] sgx_report_t *p_qe_report, + [size = quote_size, in, out] uint8_t *p_quote, + uint32_t quote_size, + [in, size = cert_data_size] const uint8_t * p_cert_data, + uint32_t cert_data_size); + }; +}; diff --git a/QuoteGeneration/quote_wrapper/tdx_quote/enclave/win/config.xml b/QuoteGeneration/quote_wrapper/tdx_quote/enclave/win/config.xml new file mode 100644 index 00000000..feb17f38 --- /dev/null +++ b/QuoteGeneration/quote_wrapper/tdx_quote/enclave/win/config.xml @@ -0,0 +1,14 @@ + + 1 + 1 + 0x2 + + 0 + 1 + 1 + 0 + + 0x44000 + 0x24000 + 1 + diff --git a/QuoteGeneration/quote_wrapper/tdx_quote/enclave/win/config_debug.xml b/QuoteGeneration/quote_wrapper/tdx_quote/enclave/win/config_debug.xml new file mode 100644 index 00000000..75aed689 --- /dev/null +++ b/QuoteGeneration/quote_wrapper/tdx_quote/enclave/win/config_debug.xml @@ -0,0 +1,14 @@ + + 1 + 1 + 0x2 + + 0 + 1 + 1 + 0 + + 0x84000 + 0x84000 + 0 + diff --git a/QuoteGeneration/quote_wrapper/tdx_quote/enclave/win/resource.h b/QuoteGeneration/quote_wrapper/tdx_quote/enclave/win/resource.h new file mode 100644 index 00000000..a0689159 --- /dev/null +++ b/QuoteGeneration/quote_wrapper/tdx_quote/enclave/win/resource.h @@ -0,0 +1,15 @@ +//{{NO_DEPENDENCIES}} +// Microsoft Visual C++ generated include file. +// Used by tdqe.rc +// + +// Next default values for new objects +// +#ifdef APSTUDIO_INVOKED +#ifndef APSTUDIO_READONLY_SYMBOLS +#define _APS_NEXT_RESOURCE_VALUE 101 +#define _APS_NEXT_COMMAND_VALUE 40001 +#define _APS_NEXT_CONTROL_VALUE 1001 +#define _APS_NEXT_SYMED_VALUE 101 +#endif +#endif diff --git a/QuoteGeneration/quote_wrapper/tdx_quote/enclave/win/targetver.h b/QuoteGeneration/quote_wrapper/tdx_quote/enclave/win/targetver.h new file mode 100644 index 00000000..87c0086d --- /dev/null +++ b/QuoteGeneration/quote_wrapper/tdx_quote/enclave/win/targetver.h @@ -0,0 +1,8 @@ +#pragma once + +// Including SDKDDKVer.h defines the highest available Windows platform. + +// If you wish to build your application for a previous Windows platform, include WinSDKVer.h and +// set the _WIN32_WINNT macro to the platform you wish to support before including SDKDDKVer.h. + +#include diff --git a/QuoteGeneration/quote_wrapper/tdx_quote/enclave/win/tdqe.filters b/QuoteGeneration/quote_wrapper/tdx_quote/enclave/win/tdqe.filters new file mode 100644 index 00000000..0df16778 --- /dev/null +++ b/QuoteGeneration/quote_wrapper/tdx_quote/enclave/win/tdqe.filters @@ -0,0 +1,35 @@ + + + + + {56109D74-043A-4F3B-9376-D16FB3A9CCA0} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {B6F108D3-1D67-4538-8802-355C7ECBB0FC} + h;hh;hpp;hxx;hm;inl;inc;ipp;xsd + + + {B2FF4453-4E0F-4568-A59D-3221ADB8AC12} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + Header Files + + + + + Source Files + + + + + + + + Resource Files + + + diff --git a/QuoteGeneration/quote_wrapper/tdx_quote/enclave/win/tdqe.rc b/QuoteGeneration/quote_wrapper/tdx_quote/enclave/win/tdqe.rc new file mode 100644 index 00000000..e23a476b Binary files /dev/null and b/QuoteGeneration/quote_wrapper/tdx_quote/enclave/win/tdqe.rc differ diff --git a/QuoteGeneration/quote_wrapper/tdx_quote/enclave/win/tdqe.vcxproj b/QuoteGeneration/quote_wrapper/tdx_quote/enclave/win/tdqe.vcxproj new file mode 100644 index 00000000..019d872a --- /dev/null +++ b/QuoteGeneration/quote_wrapper/tdx_quote/enclave/win/tdqe.vcxproj @@ -0,0 +1,393 @@ + + + + + CVE-2020-0551-Load-Release + x64 + + + CVE-2020-0551-CF-Release + x64 + + + Debug + Win32 + + + Debug + x64 + + + Release + Win32 + + + Release + x64 + + + + 15.0 + {FA74E16C-93BA-4722-8B06-434F57C0E6D0} + Win32Proj + tdqe + 10.0.18362.0 + tdqe + + + + DynamicLibrary + true + v142 + Unicode + + + DynamicLibrary + false + v142 + true + Unicode + + + DynamicLibrary + true + v142 + Unicode + + + DynamicLibrary + false + v142 + true + Unicode + + + DynamicLibrary + false + v142 + true + Unicode + + + DynamicLibrary + false + v142 + true + Unicode + + + + + + + + + + + + + + + + + + + + + + + + + + + false + false + + + false + false + + + false + false + + + false + false + + + false + false + + + false + false + + + + NotUsing + Level4 + MaxSpeed + true + false + true + NDEBUG;TDQE_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) + true + $(SGXSDKInstallPath)\include;$(SGXSDKInstallPath)\include\tlibc;$(SGXSDKInstallPath)\include\libc++;.;..\..\inc;..\..\..\..\common\inc\internal;..\..\..\..\common\inc\internal\win;..\..\..\common\inc;..\..\..\..\pce_wrapper\inc;.. + true + true + true + false + false + + + Windows + true + true + true + $(SGXSDKInstallPath)\bin\$(Platform)\Release;$(SolutionDir)$(Platform)\Release\;..\..\..\..\$(Platform)\Release\ + true + sgx_tstdc.lib;sgx_tservice.lib;sgx_trts.lib;sgx_tcxx.lib;sgx_tcrypto.lib + true + true + true + /PDBALTPATH:tdqe.pdb %(AdditionalOptions) + + + ..\..\..\common\inc\internal + + + "$(SGXSDKInstallPath)\bin\win32\Release\sgx_edger8r.exe" ..\tdqe.edl --trusted + + + + + + + + + NotUsing + Level4 + MaxSpeed + true + false + true + NDEBUG;TDQE_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) + true + $(SGXSDKInstallPath)\include;$(SGXSDKInstallPath)\include\tlibc;$(SGXSDKInstallPath)\include\libc++;.;..\..\inc;..\..\..\..\common\inc\internal;..\..\..\..\common\inc\internal\win;..\..\..\common\inc;..\..\..\..\pce_wrapper\inc;.. + true + true + true + false + false + /Qspectre-load-cf + + + Windows + true + true + true + $(SGXSDKInstallPath)\bin\$(Platform)\CVE-2020-0551-CF-Release;$(SolutionDir)$(Platform)\CVE-2020-0551-CF-Release\;..\..\..\..\$(Platform)\CVE-2020-0551-CF-Release\ + true + sgx_tstdc.lib;sgx_tservice.lib;sgx_trts.lib;sgx_tcxx.lib;sgx_tcrypto.lib + true + true + true + /PDBALTPATH:tdqe.pdb %(AdditionalOptions) + + + ..\..\..\common\inc\internal + + + "$(SGXSDKInstallPath)\bin\win32\Release\sgx_edger8r.exe" ..\tdqe.edl --trusted + + + + + + + + + NotUsing + Level4 + MaxSpeed + true + false + true + NDEBUG;TDQE_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) + true + $(SGXSDKInstallPath)\include;$(SGXSDKInstallPath)\include\tlibc;$(SGXSDKInstallPath)\include\libc++;.;..\..\inc;..\..\..\..\common\inc\internal;..\..\..\..\common\inc\internal\win;..\..\..\common\inc;..\..\..\..\pce_wrapper\inc;.. + true + true + true + false + false + /Qspectre-load + + + Windows + true + true + true + $(SGXSDKInstallPath)\bin\$(Platform)\CVE-2020-0551-Load-Release;$(SolutionDir)$(Platform)\CVE-2020-0551-Load-Release\;..\..\..\..\$(Platform)\CVE-2020-0551-Load-Release\ + true + sgx_tstdc.lib;sgx_tservice.lib;sgx_trts.lib;sgx_tcxx.lib;sgx_tcrypto.lib + true + true + true + /PDBALTPATH:tdqe.pdb %(AdditionalOptions) + + + ..\..\..\common\inc\internal + + + "$(SGXSDKInstallPath)\bin\win32\Release\sgx_edger8r.exe" ..\tdqe.edl --trusted + + + + + + + + + NotUsing + Level4 + Disabled + true + WIN32;_DEBUG;TDQE_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) + true + $(SGXSDKInstallPath)\include;$(SGXSDKInstallPath)\include\tlibc;$(SGXSDKInstallPath)\include\libc++;.;..\..\inc;..\..\..\..\common\inc\internal;..\..\..\..\common\inc\internal\win;..\..\..\common\inc;..\..\..\..\pce_wrapper\inc;.. + ProgramDatabase + false + true + true + true + false + Default + true + false + + + Windows + true + $(SGXSDKInstallPath)\bin\$(Platform)\Debug;$(SolutionDir)Debug\;..\..\..\..\Debug + true + sgx_tstdc.lib;sgx_tservice.lib;sgx_trts.lib;sgx_tcxx.lib;sgx_tcrypto.lib + true + true + true + + + "$(SGXSDKInstallPath)\bin\win32\Release\sgx_edger8r.exe" ..\tdqe.edl --trusted + + + ..\..\..\common\inc\internal + + + + + + + + + NotUsing + Level4 + Disabled + true + _DEBUG;TDQE_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) + true + $(SGXSDKInstallPath)\include;$(SGXSDKInstallPath)\include\tlibc;$(SGXSDKInstallPath)\include\libc++;.;..\..\inc;..\..\..\..\common\inc\internal;..\..\..\..\common\inc\internal\win;..\..\..\common\inc;..\..\..\..\pce_wrapper\inc;.. + ProgramDatabase + false + true + true + true + false + Default + true + false + + + Windows + true + $(SGXSDKInstallPath)\bin\$(Platform)\Debug;$(SolutionDir)$(Platform)\Debug\;..\..\..\..\$(Platform)\Debug\ + true + sgx_tstdc.lib;sgx_tservice.lib;sgx_trts.lib;sgx_tcxx.lib;sgx_tcrypto.lib + true + true + true + /PDBALTPATH:tdqe.pdb %(AdditionalOptions) + + + "$(SGXSDKInstallPath)\bin\win32\Release\sgx_edger8r.exe" ..\tdqe.edl --trusted + + + + + + + ..\..\..\common\inc\internal + + + + + NotUsing + Level4 + MaxSpeed + true + false + true + WIN32;NDEBUG;TDQE_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) + true + $(SGXSDKInstallPath)\include;$(SGXSDKInstallPath)\include\tlibc;$(SGXSDKInstallPath)\include\libc++;.;..\..\inc;..\..\..\..\common\inc\internal;..\..\..\..\common\inc\internal\win;..\..\..\common\inc;..\..\..\..\pce_wrapper\inc;.. + true + true + true + false + false + + + Windows + true + true + true + $(SGXSDKInstallPath)\bin\$(Platform)\Release;$(SolutionDir)Release\;..\..\..\..\Release\ + true + sgx_tstdc.lib;sgx_tservice.lib;sgx_trts.lib;sgx_tcxx.lib;sgx_tcrypto.lib + true + true + + + ..\..\..\common\inc\internal + + + "$(SGXSDKInstallPath)\bin\win32\Release\sgx_edger8r.exe" ..\tdqe.edl --trusted + + + + + + + + + + + + + + + + + + ..\..\..\..\common\inc\internal + ..\..\..\..\common\inc\internal + ..\..\..\..\common\inc\internal + ..\..\..\..\common\inc\internal + ..\..\..\..\common\inc\internal + ..\..\..\..\common\inc\internal + + + + + + \ No newline at end of file diff --git a/QuoteGeneration/quote_wrapper/tdx_quote/linux/Makefile b/QuoteGeneration/quote_wrapper/tdx_quote/linux/Makefile new file mode 100644 index 00000000..722c7b8b --- /dev/null +++ b/QuoteGeneration/quote_wrapper/tdx_quote/linux/Makefile @@ -0,0 +1,130 @@ +# +# Copyright (C) 2011-2021 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 Settings ######## +TOP_DIR = ../../.. +include $(TOP_DIR)/buildenv.mk + +TDQE_WRAPPER_VER:= $(shell awk '$$2 ~ /TDQE_WRAPPER_VERSION/ { print substr($$3, 2, length($$3) - 2); }' \ + $(COMMON_DIR)/inc/internal/se_version.h) + +PCE_Library_Dir := $(TOP_DIR)/pce_wrapper/linux +PCE_Library := $(PCE_Library_Dir)/libsgx_pce_logic.so + +TDQE_Dir := ../enclave/linux +TDQE_Signed_Name := $(TDQE_Dir)/libsgx_tdqe.signed.so + +ID_ENCLAVE_Dir := ../../quote/id_enclave/linux +ID_ENCLAVE_Signed_Name := $(ID_ENCLAVE_Dir)/libsgx_id_enclave.signed.so + +######## Quote Settings ######## + + +vpath %.c $(COMMON_DIR)/src +Quote_C_Files := tdqe_u.c id_enclave_u.c se_thread.c se_trace.c +Quote_Cpp_Files := $(wildcard ../*.cpp) + +Quote_Include_Paths := -I$(SGX_SDK)/include -I../../common/inc -I./ \ + -I../enclave -I$(TOP_DIR)/pce_wrapper/inc \ + -I$(COMMON_DIR)/inc/internal \ + -I$(COMMON_DIR)/inc/internal/linux + +Quote_C_Flags := $(CFLAGS) -g -MMD -fPIC -Wno-attributes $(Quote_Include_Paths) + +Quote_Cpp_Flags := $(CXXFLAGS) -g -MMD -fPIC -Wno-attributes $(Quote_Include_Paths) +Quote_Link_Flags := $(COMMON_LDFLAGS) -g -L$(ROOT_DIR)/build/linux \ + -L$(PCE_Library_Dir) -lsgx_pce_logic -L$(SGX_SDK)/lib64 \ + -lsgx_urts -lpthread -ldl + +Quote_Link_Flags += -Wl,--version-script=td_ql_logic.lds -Wl,--gc-sections + +Quote_C_Objects := $(Quote_C_Files:.c=.o) +Quote_C_Depends := $(Quote_C_Files:.c=.d) +Quote_Cpp_Objects := $(Quote_Cpp_Files:.cpp=.o) +Quote_Cpp_Depends := $(Quote_Cpp_Files:.cpp=.d) + +Quote_Name := libsgx_tdx_logic.so +Quote_Soname := $(Quote_Name).$(call SPLIT_VERSION,$(TDQE_WRAPPER_VER),1) + +-include $(Quote_C_Depends) +-include $(Quote_Cpp_Depends) + +.PHONY: all +all: install_lib + +install_lib: $(Quote_Name) | $(BUILD_DIR) + @$(CP) $(Quote_Name) $| + @ln -fs $(Quote_Name) $(BUILD_DIR)/$(Quote_Soname) + +######## Quote Objects ######## + +tdqe_u.c: $(SGX_EDGER8R) ../enclave/tdqe.edl + $(SGX_EDGER8R) --untrusted ../enclave/tdqe.edl --search-path ../enclave + @echo "GEN => $@" + +id_enclave_u.c: $(SGX_EDGER8R) ../../quote/id_enclave/id_enclave.edl + $(SGX_EDGER8R) --untrusted ../../quote/id_enclave/id_enclave.edl + @echo "GEN => $@" + +%.o: %.c + @$(CC) $(Quote_C_Flags) -c $< -o $@ + @echo "CC <= $<" + +$(Quote_Cpp_Objects): %.o: %.cpp + $(CXX) $(Quote_Cpp_Flags) -c $< -o $@ + @echo "CXX <= $<" + +$(Quote_Name): $(Quote_C_Objects) $(Quote_Cpp_Objects) $(PCE_Library) + $(CXX) $(Quote_C_Objects) $(Quote_Cpp_Objects) -shared $(Quote_Link_Flags) \ + -Wl,-soname=$(Quote_Soname) -o $@ + @echo "LINK => $@" + +$(PCE_Library): force_look + @make -C $(PCE_Library_Dir) + +$(TDQE_Signed_Name): force_look + @make -C $(TDQE_Dir) + +$(ID_ENCLAVE_Signed_Name): force_look + @make -C $(ID_ENCLAVE_Dir) + +force_look: + true + +.PHONY: clean + +clean: + @rm -f .config_* $(Quote_Name) $(Quote_C_Objects) $(Quote_Cpp_Objects) \ + tdqe_u.* id_enclave_u.* + @make -C $(PCE_Library_Dir) clean + @make -C $(TDQE_Dir) clean + @make -C $(ID_ENCLAVE_Dir) clean + diff --git a/QuoteGeneration/quote_wrapper/tdx_quote/linux/td_ql_logic.lds b/QuoteGeneration/quote_wrapper/tdx_quote/linux/td_ql_logic.lds new file mode 100644 index 00000000..294285cd --- /dev/null +++ b/QuoteGeneration/quote_wrapper/tdx_quote/linux/td_ql_logic.lds @@ -0,0 +1,12 @@ +{ +global: + td_set_enclave_load_policy; + td_set_qe_path; + td_set_qpl_path; + td_init_quote; + td_get_quote_size; + td_get_quote; + get_qpl_handle; +local: + *; +}; diff --git a/QuoteGeneration/quote_wrapper/tdx_quote/td_ql_logic.cpp b/QuoteGeneration/quote_wrapper/tdx_quote/td_ql_logic.cpp new file mode 100644 index 00000000..f03f1246 --- /dev/null +++ b/QuoteGeneration/quote_wrapper/tdx_quote/td_ql_logic.cpp @@ -0,0 +1,2497 @@ +/* + * Copyright (C) 2011-2021 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: td_ql_logic.cpp + * + * Description: This is the implementation of the quoting class that will support + * the reference ECDSA-P256 quoting class used by an application requiring quote + * generation. These are the untrusted functions of the reference code. It will + * call the trusted functions in the ECDSA-P256 quoting enclave. + * + */ +#include +#include +#include +#ifndef _MSC_VER + #include + #include +#else +#include +#include +#endif + +#include "sgx_urts.h" +#include "td_ql_logic.h" +#include "user_types.h" +#include "tdqe_u.h" +#include "id_enclave_u.h" +#include "ecdsa_quote.h" +#include "se_thread.h" +#include "quoting_enclave_tdqe.h" + +#ifndef _MSC_VER + #define TDQE_ENCLAVE_NAME "libsgx_tdqe.signed.so.1" + #define ID_ENCLAVE_NAME "libsgx_id_enclave.signed.so.1" + #define SGX_QL_QUOTE_CONFIG_LIB_FILE_NAME "libdcap_quoteprov.so.1" + #define SGX_QL_QUOTE_CONFIG_LIB_FILE_NAME_LEGACY "libdcap_quoteprov.so" + #define TCHAR char + #define _T(x) (x) +#else + #define TDQE_ENCLAVE_NAME _T("tdqe.signed.dll") + #define ID_ENCLAVE_NAME _T("id_enclave.signed.dll") + #define SGX_QL_QUOTE_CONFIG_LIB_FILE_NAME "dcap_quoteprov.dll" +#endif +#define ECDSA_BLOB_LABEL "tdqe_data.blob" + + +#define MAX_PATH 260 +#define MAX_CERT_DATA_SIZE (4098*3) +#define MIN_CERT_DATA_SIZE (500) // Chosen to be large enough to contain the native cert data types. + + +typedef quote3_error_t (*sgx_get_quote_config_func_t)(const sgx_ql_pck_cert_id_t *p_pck_cert_id, + sgx_ql_config_t **pp_quote_config); + +typedef quote3_error_t (*sgx_free_quote_config_func_t)(sgx_ql_config_t *p_quote_config); + +typedef quote3_error_t (*sgx_write_persistent_data_func_t)(const uint8_t *p_buf, + uint32_t buf_size, + const char *p_label); + +typedef quote3_error_t (*sgx_read_persistent_data_func_t)(const uint8_t *p_buf, + uint32_t *p_buf_size, + const char *p_label); +#ifndef _MSC_VER +static inline errno_t memcpy_s(void *dest, size_t numberOfElements, const void *src, size_t count) +{ + if(0 == count) + return -1; + if(NULL == dest) + return -1; + if ((src == NULL) || (numberOfElements < count)) { + memset(dest, 0, numberOfElements); + return -1; + } + + memcpy(dest, src, count); + return 0; +} +#define strcpy_s(dst, dstsize, src) strncpy(dst, src, dstsize) +#endif + + +/** + * Since the error code space of the PCE library is not unique from SGX SDK error space, need to explicitly + * translate the errors here instead of in the final high level error scrubbing function. + * + * @param pce_error Error return by the pce library API. + * + * @return SGX_QL_SUCCESS + * @return SGX_QL_OUT_OF_EPC + * @return SGX_QL_INTERFACE_UNAVAILABLE + * @return SGX_QL_ERROR_UNEXPECTED + * @return SGX_QL_KEY_CERTIFCATION_ERROR + * + */ +static quote3_error_t translate_pce_errors(sgx_pce_error_t pce_error) +{ + quote3_error_t ret_val = SGX_QL_ERROR_UNEXPECTED; + + switch(pce_error) { + + case SGX_PCE_SUCCESS: + ret_val = SGX_QL_SUCCESS; + break; + + case SGX_PCE_OUT_OF_EPC: + ret_val = SGX_QL_OUT_OF_EPC; + break; + + case SGX_PCE_INTERFACE_UNAVAILABLE: + ret_val = SGX_QL_INTERFACE_UNAVAILABLE; + break; + + case SGX_PCE_INVALID_TCB: + ret_val = SGX_QL_KEY_CERTIFCATION_ERROR; + break; + + case SGX_PCE_INVALID_PRIVILEGE: // Indicates that the QE does not have the prov key bit set. Unexpected for a production release. + ret_val = SGX_QL_ERROR_INVALID_PRIVILEGE; + break; + + case SGX_PCE_UNEXPECTED: + case SGX_PCE_INVALID_PARAMETER: // Inputs to the PCE are generated by the QE library. Don't expect input errors. + case SGX_PCE_INVALID_REPORT: // Indicates that the QE.REPORT is invalid. This unexpected. + case SGX_PCE_CRYPTO_ERROR: // Indicates that the QE.REPORT.ReportData is invalid. This unexpected. + ret_val = SGX_QL_ERROR_UNEXPECTED; + break; + + default: + ret_val = SGX_QL_ERROR_UNEXPECTED; + break; + } + + return(ret_val); +} + +/** + * Used to keep track of the TDQE's load status. Allows for + * thread safe updating of the load policy and the storage of + * target information of the QE when the policy is + * persistent mode. Also contains the global ecdsa_blob and + * provides thread safe access to the blob. + */ +struct ql_global_data{ + se_mutex_t m_enclave_load_mutex; + se_mutex_t m_ecdsa_blob_mutex; + + sgx_ql_request_policy_t m_load_policy; + sgx_enclave_id_t m_eid; + sgx_misc_attribute_t m_attributes; + sgx_launch_token_t m_launch_token; + uint8_t m_ecdsa_blob[SGX_QL_TRUSTED_ECDSA_BLOB_SIZE_SDK]; + uint8_t *m_pencryptedppid; + sgx_pce_info_t m_pce_info; + sgx_key_128bit_t* m_qe_id; + void *m_qpl_handle; + char tdqe_path[MAX_PATH]; + char qpl_path[MAX_PATH]; + + ql_global_data(): + m_load_policy(SGX_QL_DEFAULT), + m_eid(0), + m_pencryptedppid(NULL), + m_qe_id(NULL), + m_qpl_handle(NULL) + { + se_mutex_init(&m_enclave_load_mutex); + se_mutex_init(&m_ecdsa_blob_mutex); + memset(&m_attributes, 0, sizeof(m_attributes)); + memset(&m_launch_token, 0, sizeof(m_launch_token)); + memset(m_ecdsa_blob, 0, sizeof(m_ecdsa_blob)); + memset(&m_pce_info, 0, sizeof(m_pce_info)); + memset(tdqe_path, 0, sizeof(tdqe_path)); + memset(qpl_path, 0, sizeof(qpl_path)); + } + ql_global_data(const ql_global_data&); + ql_global_data& operator=(const ql_global_data&); + ~ql_global_data(){ + if (m_eid!=0) sgx_destroy_enclave(m_eid); + se_mutex_destroy(&m_enclave_load_mutex); + se_mutex_destroy(&m_ecdsa_blob_mutex); + if (m_pencryptedppid) + { + free(m_pencryptedppid); + m_pencryptedppid = NULL; + } + if (m_qe_id) + { + free(m_qe_id); + m_qe_id = NULL; + } +#ifndef _MSC_VER + if (m_qpl_handle) + { + dlclose(m_qpl_handle); + m_qpl_handle = NULL; + } +#endif + } +}; + +static ql_global_data g_ql_global_data; + +#ifndef _MSC_VER +void * get_qpl_handle() +{ + if (!g_ql_global_data.m_qpl_handle) { + void * handle = NULL; + if (g_ql_global_data.qpl_path[0]) { + handle = dlopen(g_ql_global_data.qpl_path, RTLD_LAZY); + if (NULL == handle) { + SE_PROD_LOG("Cannot open Quote Provider Library %s\n", g_ql_global_data.qpl_path); + } + } + else { + handle = dlopen(SGX_QL_QUOTE_CONFIG_LIB_FILE_NAME, RTLD_LAZY); + if (NULL == handle) + { + ///TODO: + // This is a temporary solution to make sure the legacy library without a version suffix can be loaded. + // We shall remove this when we have a major version change later and drop the backward compatible + // support for old lib name. + handle = dlopen(SGX_QL_QUOTE_CONFIG_LIB_FILE_NAME_LEGACY, RTLD_LAZY); + if (NULL == handle) { + SE_PROD_LOG("Cannot open Quote Provider Library %s and %s\n", SGX_QL_QUOTE_CONFIG_LIB_FILE_NAME, + SGX_QL_QUOTE_CONFIG_LIB_FILE_NAME_LEGACY); + } + } + } + g_ql_global_data.m_qpl_handle = handle; + } + return g_ql_global_data.m_qpl_handle; +} +#endif + + +/** + * Wrapper function for retrieving the PCK Certificate data from the platform's Quote Provider Library. + * + * @param p_pck_cert_id Pointer to the platorm identification data. Must not be NULL. + * @param p_cert_cpu_svn Returned CPUSVN of the PCK cert. Must not be NULL. + * @param p_cert_isv_svn Returned CPUSVN of the PCK cert. Must not be NULL. + * @param p_cert_data_size Pointer to the size in bytes of the cert data. Must not be NULL. If p_cert_data is NULL, + * then this function will return the size of the bufffer to allocate. If p_cert_data is not + * NULL, then the p_cert_data_size points the number of bytes in the p_cert_data buffer and it + * must not be 0. + * @param p_cert_data Pointer ot the buffer to containt the cert data. Can be NULL. If NULL, the required buffer size + * will be returned in p_cert_data_size. + * + * @return SGX_QL_SUCCESS + * @return SGX_QL_ERROR_INVALID_PARAMETER + * @return SGX_QL_PLATFORM_LIB_UNAVAILABLE + * @return SGX_QL_NO_PLATFORM_CERT_DATA + */ +static quote3_error_t get_platform_quote_cert_data(sgx_ql_pck_cert_id_t *p_pck_cert_id, + sgx_cpu_svn_t *p_cert_cpu_svn, + sgx_isv_svn_t *p_cert_pce_isv_svn, + uint32_t *p_cert_data_size, + uint8_t *p_cert_data) +{ + quote3_error_t ret_val = SGX_QL_PLATFORM_LIB_UNAVAILABLE; + sgx_get_quote_config_func_t p_sgx_get_quote_config = NULL; + sgx_free_quote_config_func_t p_sgx_free_quote_config = NULL; + sgx_ql_config_t *p_pck_cert_config = NULL; + + #ifndef _MSC_VER + void *handle = NULL; + char *error1 = NULL; + char *error2 = NULL; + #else + HINSTANCE handle; + #endif + + if((NULL == p_pck_cert_id) || + (NULL == p_cert_cpu_svn) || + (NULL == p_cert_pce_isv_svn) || + (NULL == p_cert_data_size)) { + return SGX_QL_ERROR_INVALID_PARAMETER; + } + if((NULL != p_cert_data) && (0 == *p_cert_data_size)) { + return SGX_QL_ERROR_INVALID_PARAMETER; + } + + #ifndef _MSC_VER + handle = get_qpl_handle(); + if (handle) { + p_sgx_get_quote_config = (sgx_get_quote_config_func_t)dlsym(handle, "sgx_ql_get_quote_config"); + error1 = dlerror(); + p_sgx_free_quote_config = (sgx_free_quote_config_func_t)dlsym(handle, "sgx_ql_free_quote_config"); + error2 = dlerror(); + + if ((NULL == error1) && + (NULL != p_sgx_get_quote_config) && + (NULL == error2) && + (NULL != p_sgx_free_quote_config)){ + SE_TRACE(SE_TRACE_DEBUG, "Found the sgx_ql_get_quote_config and sgx_ql_free_quote_config API.\n"); + SE_TRACE(SE_TRACE_DEBUG, "Request the Quote Config data.\n"); + ret_val = p_sgx_get_quote_config(p_pck_cert_id, &p_pck_cert_config); + if (SGX_QL_SUCCESS != ret_val) { + SE_PROD_LOG("Error returned from the p_sgx_get_quote_config API. 0x%04x\n", ret_val); + goto CLEANUP; + } + if(NULL == p_pck_cert_config) { + ret_val = SGX_QL_NO_PLATFORM_CERT_DATA; + SE_PROD_LOG("p_sgx_get_quote_config returned NULL for p_pck_cert_config.\n"); + goto CLEANUP; + } + if(p_pck_cert_config->version != SGX_QL_CONFIG_VERSION_1) { + SE_PROD_LOG("p_sgx_get_quote_config returned incompatible pck_cert_config version.\n"); + ret_val = SGX_QL_NO_PLATFORM_CERT_DATA; + goto CLEANUP; + } + if(0 != memcpy_s(p_cert_cpu_svn, sizeof(*p_cert_cpu_svn), &p_pck_cert_config->cert_cpu_svn, sizeof(p_pck_cert_config->cert_cpu_svn))) { + ret_val = SGX_QL_ERROR_UNEXPECTED; + goto CLEANUP; + } + *p_cert_pce_isv_svn = p_pck_cert_config->cert_pce_isv_svn; + if(NULL == p_cert_data) { + // The caller only needs the TCBm and/or the required buffer size. + // Return the required buffer size. + *p_cert_data_size = p_pck_cert_config->cert_data_size; + } + else { + // The caller wants the TCBm and the required buffer size. + if(*p_cert_data_size < p_pck_cert_config->cert_data_size) { + // The buffer passed in to this API is not large enouge to contain the provider library's returned cert data. + // This shouldn't happen since the passed in value should be the result of calling this function + // with the inputted p_cert_data equal to NULL just befor this caller. + SE_PROD_LOG("sgx_ql_get_quote_config returned a cert_data_size too large to fit in inputted buffer.\n"); + ret_val = SGX_QL_ERROR_INVALID_PARAMETER; + goto CLEANUP; + } + if(NULL == p_pck_cert_config->p_cert_data) { + SE_PROD_LOG("sgx_ql_get_quote_config returned NULL for p_cert_data.\n"); + ret_val = SGX_QL_NO_PLATFORM_CERT_DATA; + goto CLEANUP; + } + // Copy the returned cert data + if(0 != memcpy_s(p_cert_data, *p_cert_data_size, p_pck_cert_config->p_cert_data, p_pck_cert_config->cert_data_size)) { + ret_val = SGX_QL_ERROR_UNEXPECTED; + goto CLEANUP; + } + // Return the number of bytes copied. + *p_cert_data_size = p_pck_cert_config->cert_data_size; + } + } else { + SE_PROD_LOG("Couldn't find 'sgx_ql_get_quote_config()' and 'sgx_ql_free_quote_config()' in the platform library. %s\n", dlerror()); + } + } else { + SE_PROD_LOG("Couldn't find the platform library. %s\n", dlerror()); + } + + CLEANUP: + if(NULL != p_sgx_free_quote_config){ + if(NULL != p_pck_cert_config) { + p_sgx_free_quote_config(p_pck_cert_config); + } + } + #else + handle = LoadLibrary(TEXT(SGX_QL_QUOTE_CONFIG_LIB_FILE_NAME)); + if (handle != NULL) { + SE_TRACE(SE_TRACE_DEBUG, "Found the Quote's dependent library. %s.\n", SGX_QL_QUOTE_CONFIG_LIB_FILE_NAME); + p_sgx_get_quote_config = (sgx_get_quote_config_func_t)GetProcAddress(handle, "sgx_ql_get_quote_config"); + p_sgx_free_quote_config = (sgx_free_quote_config_func_t)GetProcAddress(handle, "sgx_ql_free_quote_config"); + if ((NULL != p_sgx_get_quote_config) && + (NULL != p_sgx_free_quote_config)){ + SE_TRACE(SE_TRACE_DEBUG, "Found the sgx_ql_get_quote_config and sgx_ql_free_quote_config API.\n"); + SE_TRACE(SE_TRACE_DEBUG, "Request the Quote Config data.\n"); + ret_val = p_sgx_get_quote_config(p_pck_cert_id, &p_pck_cert_config); + if (SGX_QL_SUCCESS != ret_val) { + SE_TRACE(SE_TRACE_ERROR, "Error returned from the p_sgx_get_quote_config API. 0x%04x\n", ret_val); + goto CLEANUP; + } + if (NULL == p_pck_cert_config) { + ret_val = SGX_QL_NO_PLATFORM_CERT_DATA; + SE_TRACE(SE_TRACE_ERROR, "p_sgx_get_quote_config returned NULL for p_pck_cert_config.\n"); + goto CLEANUP; + } + if (p_pck_cert_config->version != SGX_QL_CONFIG_VERSION_1) { + SE_TRACE(SE_TRACE_ERROR, "p_sgx_get_quote_config returned incompatible pck_cert_config version.\n"); + ret_val = SGX_QL_NO_PLATFORM_CERT_DATA; + goto CLEANUP; + } + if (0 != memcpy_s(p_cert_cpu_svn, sizeof(*p_cert_cpu_svn), &p_pck_cert_config->cert_cpu_svn, sizeof(p_pck_cert_config->cert_cpu_svn))) { + ret_val = SGX_QL_ERROR_UNEXPECTED; + goto CLEANUP; + } + *p_cert_pce_isv_svn = p_pck_cert_config->cert_pce_isv_svn; + if (NULL == p_cert_data) { + // The caller only needs the TCBm and/or the required buffer size. + // Return the required buffer size. + *p_cert_data_size = p_pck_cert_config->cert_data_size; + } + else { + // The caller wants the TCBm and the required buffer size. + if (*p_cert_data_size < p_pck_cert_config->cert_data_size) { + // The buffer passed in to this API is not large enouge to contain the provider library's returned cert data. + // This shouldn't happen since the passed in value should be the result of calling this function + // with the inputted p_cert_data equal to NULL just befor this caller. + SE_TRACE(SE_TRACE_ERROR, "sgx_ql_get_quote_config returned a cert_data_size too large to fit in inputted buffer.\n"); + ret_val = SGX_QL_ERROR_INVALID_PARAMETER; + goto CLEANUP; + } + if (NULL == p_pck_cert_config->p_cert_data) { + SE_TRACE(SE_TRACE_ERROR, "sgx_ql_get_quote_config returned NULL for p_cert_data.\n"); + ret_val = SGX_QL_NO_PLATFORM_CERT_DATA; + goto CLEANUP; + } + // Copy the returned cert data + if (0 != memcpy_s(p_cert_data, *p_cert_data_size, p_pck_cert_config->p_cert_data, p_pck_cert_config->cert_data_size)) { + ret_val = SGX_QL_ERROR_UNEXPECTED; + goto CLEANUP; + } + // Return the number of bytes copied. + *p_cert_data_size = p_pck_cert_config->cert_data_size; + } + } + else { + SE_TRACE(SE_TRACE_WARNING, "Couldn't find 'sgx_ql_get_quote_config()' and 'sgx_ql_free_quote_config()' in the platform library.\n"); + } + } + else { + SE_TRACE(SE_TRACE_DEBUG, "Couldn't find the platform library. %s\n"); + } + CLEANUP: + if (NULL != p_sgx_free_quote_config) { + if (NULL != p_pck_cert_config) { + p_sgx_free_quote_config(p_pck_cert_config); + } + } + if (NULL != handle) { + FreeLibrary(handle); + } + #endif + + return(ret_val); +} + +/** + * + * @param q_file_name + * @param p_file_path + * @param buf_size + * + * @return + */ +static bool get_qe_path(const TCHAR *p_file_name, + TCHAR *p_file_path, + size_t buf_size) +{ + if(!p_file_name || !p_file_path) { + return false; + } + +#ifndef _MSC_VER + Dl_info dl_info; + if(g_ql_global_data.tdqe_path[0]) + { + strncpy(p_file_path, g_ql_global_data.tdqe_path, buf_size -1); + p_file_path[buf_size - 1] = '\0'; //null terminate the string + return true; + } + else if(0 != dladdr(__builtin_return_address(0), &dl_info) && + NULL != dl_info.dli_fname) + { + if(strnlen(dl_info.dli_fname,buf_size)>=buf_size) { + return false; + } + (void)strncpy(p_file_path,dl_info.dli_fname,buf_size); + p_file_path[buf_size - 1] = '\0'; //null terminate the string + } + else //not a dynamic executable + { + ssize_t i = readlink( "/proc/self/exe", p_file_path, buf_size ); + if (i == -1) + return false; + p_file_path[i] = '\0'; + } + + char* p_last_slash = strrchr(p_file_path, '/' ); + if ( p_last_slash != NULL ) { + p_last_slash++; //increment beyond the last slash + *p_last_slash = '\0'; //null terminate the string + } + else { + p_file_path[0] = '\0'; + } + + if(strnlen(p_file_path,buf_size)+strnlen(p_file_name,buf_size)+sizeof(char)>buf_size) { + return false; + } + (void)strncat(p_file_path,p_file_name, strnlen(p_file_name,buf_size)); +#else + HMODULE hModule = NULL; +#ifndef AESM_ECDSA_BUNDLE + if (!GetModuleHandleEx(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS, _T(__FUNCTION__), &hModule)) + return false; +#endif + DWORD path_length = GetModuleFileName(hModule, p_file_path, static_cast(buf_size)); + if (path_length == 0) + return false; + if (path_length == buf_size) + return false; + + TCHAR *p_last_slash = _tcsrchr(p_file_path, _T('\\')); + if (p_last_slash != NULL) + { + p_last_slash++; + *p_last_slash = _T('\0'); + } + else + return false; + if (_tcsnlen(p_file_name, MAX_PATH) + _tcsnlen(p_file_path, MAX_PATH) + sizeof(TCHAR) > buf_size) + return false; + if (_tcscat_s(p_file_path, buf_size, p_file_name)) + return false; +#endif + return true; +} + + +/** + * + * @param p_qe_eid + * @param p_qe_attributes + * @param p_launch_token + * + * @return SGX_QL_SUCCESS + * @return SGX_QL_ENCLAVE_LOAD_ERROR + * @return SGX_QL_ERROR_UNEXPECTED + * @return SGX_QL_OUT_OF_EPC + * @return SGX_ERROR_ENCLAVE_FILE_ACCESS The QE file cannot be found or accessed. + * @return SGX_ERROR_OUT_OF_MEMORY + * @return SGX_ERROR_INVALID_ENCLAVE Enclave file parser failed. + * @return SGX_ERROR_UNDEFINED_SYMBOL Enclave not statically built. + * @return SGX_ERROR_MODE_INCOMPATIBLE Enclave linked with the incorrect tRTS library (simulation) + * @return SGX_ERROR_PCL_NOT_ENCRYPTED Invalid protected code loader state. + * @return SGX_ERROR_PCL_ENCRYPTED Invalid protected code loader state. + * @return SGX_ERROR_INVALID_METADATA Enclave meta data is invalid. + * @return SGX_ERROR_ENCLAVE_LOST Power transition caused the enclave to be unloaded. + * @return SGX_ERROR_MEMORY_MAP_CONFLICT Error loading the enclave. + * @return SGX_ERROR_INVALID_VERSION Metadata version is unsupported. + * @return SGX_ERROR_NO_DEVICE SGX not enabled on platform. + * @return SGX_ERROR_INVALID_ATTRIBUTE Invalid encave attribute. + * @return SGX_ERROR_NDEBUG_ENCLAVE Enlcave properties disallows launching in debug mode. + * @return SGX_ERROR_INVALID_MISC Invalid Misc. attribute setting. + * @return SGX_ERROR_UNEXPECTED + * @return SE_ERROR_INVALID_LAUNCH_TOKEN A debug LE is trying to launch a production QE. + * @return SGX_ERROR_INVALID_SIGNATURE + * @return SE_ERROR_INVALID_MEASUREMENT + * @return SGX_ERROR_DEVICE_BUSY + * @return SE_ERROR_INVALID_ISVSVNLE + * @return SGX_ERROR_INVALID_ENCLAVE_ID + */ + +static quote3_error_t load_qe(sgx_enclave_id_t *p_qe_eid, + sgx_misc_attribute_t *p_qe_attributes, + sgx_launch_token_t *p_launch_token) +{ + quote3_error_t ret_val = SGX_QL_SUCCESS; + sgx_status_t sgx_status = SGX_SUCCESS; + int launch_token_updated = 0; + TCHAR qe_enclave_path[MAX_PATH] = _T(""); + + memset(p_launch_token, 0, sizeof(*p_launch_token)); + + int rc = se_mutex_lock(&g_ql_global_data.m_enclave_load_mutex); + if (0 == rc) { + SE_TRACE(SE_TRACE_ERROR, "Failed to lock mutex\n"); + return SGX_QL_ENCLAVE_LOAD_ERROR; + } + + // Load the TDQE + if (g_ql_global_data.m_eid == 0) { + if (!get_qe_path(TDQE_ENCLAVE_NAME, qe_enclave_path, MAX_PATH)) { + SE_TRACE(SE_TRACE_ERROR, "Couldn't find QE file.\n"); + ret_val = SGX_QL_ENCLAVE_LOAD_ERROR; + goto CLEANUP; + } + SE_TRACE(SE_TRACE_DEBUG, "Call sgx_create_enclave for QE. %s\n", qe_enclave_path); + sgx_status = sgx_create_enclave(qe_enclave_path, + 0, + p_launch_token, + &launch_token_updated, + p_qe_eid, + p_qe_attributes); + if (SGX_SUCCESS != sgx_status) { + SE_PROD_LOG("Error, call sgx_create_enclave QE fail [%s], SGXError:%04x.\n", __FUNCTION__, sgx_status); + if (sgx_status == SGX_ERROR_OUT_OF_EPC) { + ret_val = SGX_QL_OUT_OF_EPC; + } + else { + ret_val = (quote3_error_t)sgx_status; + } + goto CLEANUP; + } + g_ql_global_data.m_eid = *p_qe_eid; + if(0 != memcpy_s(&g_ql_global_data.m_launch_token, sizeof(g_ql_global_data.m_launch_token), + p_launch_token, sizeof(*p_launch_token))) { + ret_val = SGX_QL_ERROR_UNEXPECTED; + goto CLEANUP; + } + g_ql_global_data.m_attributes = *p_qe_attributes; + } else { + SE_TRACE(SE_TRACE_DEBUG, "QE already loaded. %d\n", g_ql_global_data.m_eid); + *p_qe_eid = g_ql_global_data.m_eid; + if(0 != memcpy_s(p_launch_token, sizeof(*p_launch_token), + &g_ql_global_data.m_launch_token, sizeof(g_ql_global_data.m_launch_token))) { + ret_val = SGX_QL_ERROR_UNEXPECTED; + goto CLEANUP; + } + *p_qe_attributes = g_ql_global_data.m_attributes; + } + + CLEANUP: + rc = se_mutex_unlock(&g_ql_global_data.m_enclave_load_mutex); + if (0 == rc) { + SE_TRACE(SE_TRACE_ERROR, "Failed to unlock mutex.\n"); + ret_val = SGX_QL_ERROR_UNEXPECTED; + } + + return ret_val; +} + +/** + * + * @return + */ +static void unload_qe() +{ + + int rc = se_mutex_lock(&g_ql_global_data.m_enclave_load_mutex); + if (0 == rc) { + SE_TRACE(SE_TRACE_ERROR, "Failed to lock mutex\n"); + return; + } + + // Unload the QE enclave + if ((0 != g_ql_global_data.m_eid) && + (g_ql_global_data.m_load_policy != SGX_QL_PERSISTENT)) { + SE_TRACE(SE_TRACE_DEBUG, "Unload QE enclave 0X%lX\n", g_ql_global_data.m_eid); + sgx_destroy_enclave(g_ql_global_data.m_eid); + g_ql_global_data.m_eid = 0; + } + + rc = se_mutex_unlock(&g_ql_global_data.m_enclave_load_mutex); + if (0 == rc) { + SE_TRACE(SE_TRACE_ERROR, "Failed to unlock mutex\n"); + } +} + + +static quote3_error_t load_id_enclave(sgx_enclave_id_t* p_qe_eid) +{ + quote3_error_t ret_val = SGX_QL_SUCCESS; + sgx_status_t sgx_status = SGX_SUCCESS; + int launch_token_updated = 0; + TCHAR id_enclave_path[MAX_PATH] = _T(""); + + sgx_launch_token_t launch_token = { 0 }; + + int rc = se_mutex_lock(&g_ql_global_data.m_enclave_load_mutex); + if (0 == rc) { + SE_TRACE(SE_TRACE_ERROR, "Failed to lock mutex\n"); + return SGX_QL_ENCLAVE_LOAD_ERROR; + } + + // Load the ID ENCLAVE + if (!get_qe_path(ID_ENCLAVE_NAME, id_enclave_path, MAX_PATH)) { + SE_TRACE(SE_TRACE_ERROR, "Couldn't find ID_ENCLAVE file.\n"); + ret_val = SGX_QL_ENCLAVE_LOAD_ERROR; + goto CLEANUP; + } + SE_TRACE(SE_TRACE_DEBUG, "Call sgx_create_enclave for ID_ENCLAVE. %s\n", id_enclave_path); + sgx_status = sgx_create_enclave(id_enclave_path, + 0, + &launch_token, + &launch_token_updated, + p_qe_eid, + NULL); + if (SGX_SUCCESS != sgx_status) { + SE_PROD_LOG("Error, call sgx_create_enclave ID_ENCLAVE fail [%s], SGXError:%04x.\n", __FUNCTION__, sgx_status); + if (sgx_status == SGX_ERROR_OUT_OF_EPC) { + ret_val = SGX_QL_OUT_OF_EPC; + } + else { + ret_val = (quote3_error_t)sgx_status; + } + goto CLEANUP; + } +CLEANUP: + rc = se_mutex_unlock(&g_ql_global_data.m_enclave_load_mutex); + if (0 == rc) { + SE_TRACE(SE_TRACE_ERROR, "Failed to unlock mutex.\n"); + ret_val = SGX_QL_ERROR_UNEXPECTED; + } + + return ret_val; +} + +static quote3_error_t load_id_enclave_get_id(sgx_key_128bit_t* p_id) +{ + quote3_error_t ret_val = SGX_QL_SUCCESS; + sgx_status_t sgx_status = SGX_SUCCESS; + sgx_status_t ecall_ret = SGX_SUCCESS; + sgx_enclave_id_t id_enclave_eid = 0; + ret_val = load_id_enclave(&id_enclave_eid); + if (ret_val != SGX_QL_SUCCESS) + { + return ret_val; + } + sgx_status = ide_get_id(id_enclave_eid, &ecall_ret, p_id); + if (SGX_SUCCESS != sgx_status) { + SE_PROD_LOG("Failed call into the ID_ENCLAVE. 0x%04x.\n", sgx_status); + ret_val = (quote3_error_t)sgx_status; + goto CLEANUP; + } + + if (SGX_SUCCESS != ecall_ret) { + SE_TRACE(SE_TRACE_ERROR, "Failed to get QE_ID. 0x%04x.\n", ecall_ret); + ret_val = (quote3_error_t)ecall_ret; + goto CLEANUP; + } + +CLEANUP: + if (0 != id_enclave_eid) { + sgx_destroy_enclave(id_enclave_eid); + } + + return ret_val; +} + +/* This function output encrypted PPID which is encrypted with backend server's pub key + * + * note: this function is called in lock area of global ecdsa blob mutex + */ +static quote3_error_t getencryptedppid(sgx_target_info_t& pce_target_info, uint8_t *p_buf, uint32_t buf_size) +{ + tdqe_error_t tdqe_error = TDQE_ERROR_UNEXPECTED; + sgx_status_t sgx_status = SGX_SUCCESS; + sgx_pce_error_t pce_error; + sgx_report_t tdqe_report; + uint32_t enc_key_size = REF_RSA_OAEP_3072_MOD_SIZE + REF_RSA_OAEP_3072_EXP_SIZE; + uint8_t enc_public_key[REF_RSA_OAEP_3072_MOD_SIZE + REF_RSA_OAEP_3072_EXP_SIZE]; + uint8_t encrypted_ppid[REF_RSA_OAEP_3072_MOD_SIZE]; + uint32_t encrypted_ppid_ret_size; + sgx_pce_info_t pce_info; + uint8_t signature_scheme; + + if (!p_buf || buf_size < REF_RSA_OAEP_3072_MOD_SIZE) + return SGX_QL_ERROR_INVALID_PARAMETER; + + if (g_ql_global_data.m_pencryptedppid) + { + memcpy_s(p_buf, buf_size, g_ql_global_data.m_pencryptedppid, REF_RSA_OAEP_3072_MOD_SIZE); + return SGX_QL_SUCCESS; + } + + sgx_status = get_pce_encrypt_key(g_ql_global_data.m_eid, + (uint32_t*)&tdqe_error, + &pce_target_info, + &tdqe_report, + PCE_ALG_RSA_OAEP_3072, + PPID_RSA3072_ENCRYPTED, + enc_key_size, + enc_public_key); + if (SGX_SUCCESS != sgx_status) { + SE_TRACE(SE_TRACE_ERROR, "Failed call into the TDQE. 0x%04x.\n", sgx_status); + return (quote3_error_t)sgx_status; + } + + if (TDQE_SUCCESS != tdqe_error) { + SE_TRACE(SE_TRACE_ERROR, "Failed to generated PCE encryption key.\n"); + return (quote3_error_t)tdqe_error; + } + + pce_error = sgx_get_pce_info(&tdqe_report, + enc_public_key, + enc_key_size, + PCE_ALG_RSA_OAEP_3072, + encrypted_ppid, + REF_RSA_OAEP_3072_MOD_SIZE, + &encrypted_ppid_ret_size, + &pce_info.pce_isv_svn, + &pce_info.pce_id, + &signature_scheme); + if (SGX_PCE_SUCCESS != pce_error) { + SE_TRACE(SE_TRACE_ERROR, "Failed to get PCE info, 0x%04x.\n", pce_error); + return translate_pce_errors(pce_error); + } + + if (signature_scheme != PCE_NIST_P256_ECDSA_SHA256) { + SE_TRACE(SE_TRACE_ERROR, "PCE returned incorrect signature scheme.\n"); + return SGX_QL_ERROR_INVALID_PCE_SIG_SCHEME; + } + + if (encrypted_ppid_ret_size != REF_RSA_OAEP_3072_MOD_SIZE) { + SE_TRACE(SE_TRACE_ERROR, "PCE returned unexpected returned encrypted PPID size.\n"); + return SGX_QL_ERROR_UNEXPECTED; + } + + g_ql_global_data.m_pencryptedppid = (uint8_t *)malloc(sizeof(uint8_t) * REF_RSA_OAEP_3072_MOD_SIZE); + if (!g_ql_global_data.m_pencryptedppid) { + SE_TRACE(SE_TRACE_ERROR, "Fail to allocate memory.\n"); + return SGX_QL_ERROR_OUT_OF_MEMORY; + } + + if (0 != memcpy_s(g_ql_global_data.m_pencryptedppid, REF_RSA_OAEP_3072_MOD_SIZE, encrypted_ppid, REF_RSA_OAEP_3072_MOD_SIZE) || + 0 != memcpy_s(p_buf, buf_size, g_ql_global_data.m_pencryptedppid, REF_RSA_OAEP_3072_MOD_SIZE) || + 0 != memcpy_s(&g_ql_global_data.m_pce_info, sizeof(g_ql_global_data.m_pce_info), &pce_info, sizeof (pce_info))) { + SE_TRACE(SE_TRACE_ERROR, "Fail to copy memory.\n"); + return SGX_QL_ERROR_UNEXPECTED; + } + + return SGX_QL_SUCCESS; +} + +/** + * This function is used to write the ECDSA data blob. + * + * @param p_buf Points to the buffer to be written to disk. Must not be NULL. + * @param buf_size Size in bytes pointed to by p_buf. Must be no larger than MAX_PATH. + * @param p_label String of the label for the data to be stored. Must not be NULL. + * + * @return SGX_QE_PLATFORM_LIB_UNAVAILABLE + * @return SGX_QL_ERROR_UNEXPECTED + * @return SGX_QL_ERROR_INVALID_PARAMETER + * @return SGX_QL_FILE_ACCESS_ERROR + * @return SGX_QL_SUCCESS + */ +static quote3_error_t write_persistent_data(const uint8_t *p_buf, + uint32_t buf_size, + const char *p_label) +{ + quote3_error_t ret_val = SGX_QL_PLATFORM_LIB_UNAVAILABLE; + sgx_write_persistent_data_func_t p_sgx_qe_write_persistent_data; + #ifndef _MSC_VER + void *handle; + char *error; + #else + HINSTANCE handle; + #endif + + if((NULL == p_buf) || + (0 == buf_size)|| + (NULL == p_label)) { + return(SGX_QL_ERROR_INVALID_PARAMETER); + } + + #ifndef _MSC_VER + handle = get_qpl_handle(); + if (handle) { + p_sgx_qe_write_persistent_data = (sgx_write_persistent_data_func_t)dlsym(handle, "sgx_ql_write_persistent_data"); + if ((error = dlerror()) == NULL && + NULL != p_sgx_qe_write_persistent_data) { + SE_TRACE(SE_TRACE_DEBUG, "Found the sgx_ql_write_persistent_data API.\n"); + ret_val = p_sgx_qe_write_persistent_data(p_buf, + buf_size, + p_label); + if (SGX_QL_SUCCESS != ret_val) { + SE_PROD_LOG("Error returned from the sgx_ql_write_persistent_data API. 0x%04x\n", ret_val); + } + } else { + SE_TRACE(SE_TRACE_WARNING, "Couldn't find 'sgx_ql_write_persistent_data()' in the platform library. %s\n", dlerror()); + } + } else { + SE_PROD_LOG("Couldn't find the platform library. %s\n", dlerror()); + } + #else + handle = LoadLibrary(TEXT(SGX_QL_QUOTE_CONFIG_LIB_FILE_NAME)); + if (handle != NULL) { + SE_TRACE(SE_TRACE_DEBUG, "Found the Quote's dependent library. %s.\n", SGX_QL_QUOTE_CONFIG_LIB_FILE_NAME); + p_sgx_qe_write_persistent_data = (sgx_write_persistent_data_func_t)GetProcAddress(handle, "sgx_ql_write_persistent_data"); + if (NULL != p_sgx_qe_write_persistent_data) { + SE_TRACE(SE_TRACE_DEBUG, "Found the sgx_ql_write_persistent_data API.\n"); + ret_val = p_sgx_qe_write_persistent_data(p_buf, + buf_size, + p_label); + if (SGX_QL_SUCCESS != ret_val) { + SE_TRACE(SE_TRACE_ERROR, "Error returned from the sgx_ql_write_persistent_data API. 0x%04x\n", ret_val); + } + } + else { + SE_TRACE(SE_TRACE_WARNING, "Couldn't find 'sgx_ql_write_persistent_data()' in the platform library. %s\n"); + } + FreeLibrary(handle); + } + else { + SE_TRACE(SE_TRACE_DEBUG, "Couldn't find the platform library. %s\n"); + } + #endif + + //CLEANUP: + return(ret_val); +} + +/** + * This function is used to read the ECDSA data blob. + * + * @param p_buf Points to the buffer to be written to disk. Must not be NULL. + * @param p_buf_size Size in bytes pointed to by p_buf. Must not be NULL. + * @param p_label String of the label for the data to be stored. Must not be NULL. + * + * @return SGX_QL_SUCCESS + * @return SGX_QE_PLATFORM_LIB_UNAVAILABLE + * @return SGX_QL_ERROR_UNEXPECTED + * @return SGX_QL_ERROR_INVALID_PARAMETER + * @return SGX_QL_FILE_ACCESS_ERROR + */ +static quote3_error_t read_persistent_data(uint8_t *p_buf, + uint32_t *p_buf_size, + const char *p_label) +{ + quote3_error_t ret_val = SGX_QL_PLATFORM_LIB_UNAVAILABLE; + sgx_read_persistent_data_func_t p_sgx_qe_read_persistent_data; + + #ifndef _MSC_VER + void *handle; + char *error; + #else + HINSTANCE handle; + #endif + + if((NULL == p_buf) || + (NULL == p_buf_size)|| + (NULL == p_label)) { + return(SGX_QL_ERROR_INVALID_PARAMETER); + } + + #ifndef _MSC_VER + handle = get_qpl_handle(); + if (handle) { + p_sgx_qe_read_persistent_data = (sgx_read_persistent_data_func_t)dlsym(handle, "sgx_ql_read_persistent_data"); + if ((error = dlerror()) == NULL && + NULL != p_sgx_qe_read_persistent_data) { + SE_TRACE(SE_TRACE_DEBUG, "Found the sgx_qe_read_persistent_data API.\n"); + ret_val = p_sgx_qe_read_persistent_data(p_buf, + p_buf_size, + p_label); + if (SGX_QL_SUCCESS != ret_val) { + SE_PROD_LOG("Error returned from the sgx_ql_read_persistent_data API. 0x%04x\n", ret_val); + } + } else { + SE_TRACE(SE_TRACE_WARNING, "Couldn't find 'sgx_ql_read_persistent_data()' in the platform library. %s\n", dlerror()); + } + } else { + SE_PROD_LOG("Couldn't find the platform library. %s\n", dlerror()); + } + #else + handle = LoadLibrary(TEXT(SGX_QL_QUOTE_CONFIG_LIB_FILE_NAME)); + if (handle != NULL) { + SE_TRACE(SE_TRACE_DEBUG, "Found the Quote's dependent library. %s.\n", SGX_QL_QUOTE_CONFIG_LIB_FILE_NAME); + p_sgx_qe_read_persistent_data = (sgx_read_persistent_data_func_t)GetProcAddress(handle, "sgx_ql_read_persistent_data"); + if (NULL != p_sgx_qe_read_persistent_data) { + SE_TRACE(SE_TRACE_DEBUG, "Found the sgx_ql_read_persistent_data API.\n"); + ret_val = p_sgx_qe_read_persistent_data(p_buf, + p_buf_size, + p_label); + if (SGX_QL_SUCCESS != ret_val) { + SE_TRACE(SE_TRACE_ERROR, "Error returned from the sgx_ql_read_persistent_data API. 0x%04x\n", ret_val); + } + } + else { + SE_TRACE(SE_TRACE_WARNING, "Couldn't find 'sgx_ql_write_persistent_data()' in the platform library. %s\n"); + } + FreeLibrary(handle); + } + else { + SE_TRACE(SE_TRACE_DEBUG, "Couldn't find the platform library. %s\n"); + } + + #endif + + //CLEANUP: + return(ret_val); +} + +/** + * + * @param p_ecdsa_blob + * @param p_plaintext_data + * @param p_encrypted_ppid + * @param encrypted_ppid_size + * @param certification_key_type + * @param p_tdqe_eid + * + * @return SGX_QL_SUCCESS + * @return SGX_QL_ERROR_INVALID_PARAMETER + * @return errors from PCE translator from sgx_pce_sign_report() + * @return ecall errors + * @return errors from TDQE's store_cert_data() + * + */ +static quote3_error_t certify_key(uint8_t *p_ecdsa_blob, + ref_plaintext_ecdsa_data_sdk_t* p_plaintext_data, + uint8_t *p_encrypted_ppid, + uint32_t encrypted_ppid_size, + sgx_ql_cert_key_type_t certification_key_type, + sgx_enclave_id_t *p_tdqe_eid) +{ + quote3_error_t refqt_ret = SGX_QL_ERROR_UNEXPECTED; + sgx_status_t sgx_status = SGX_SUCCESS; + tdqe_error_t tdqe_error = TDQE_ERROR_UNEXPECTED; + sgx_pce_error_t pce_error; + sgx_ec256_signature_t pce_sig; + uint32_t sig_out_size; + + // Verify inputs + if((NULL == p_ecdsa_blob) || + (NULL == p_plaintext_data) || + (NULL == p_tdqe_eid)) { + return(SGX_QL_ERROR_INVALID_PARAMETER); + } + + if(NULL != p_encrypted_ppid) { + if(encrypted_ppid_size != REF_RSA_OAEP_3072_MOD_SIZE) { + return(SGX_QL_ERROR_INVALID_PARAMETER); + } + } + + if (PPID_RSA3072_ENCRYPTED != certification_key_type) { + return(SGX_QL_ERROR_INVALID_PARAMETER); + } + + SE_TRACE(SE_TRACE_DEBUG, "Certify Key.\n"); + // Set the TCB to the value you want to use when certifying the key. + // For the reference, use the CPUSNV and PCEISVSVN that matches the test PCK. CPUSVN = 00000000010100000000000000000000, PCE ISVSVN = 0000 + // For E3's, there will not be a PCK Cert for every CPUSVN+PCE ISVNSVN combination. The platform will need to know which values to use. + // For E5's, the PCK Cert can be requested on demand and use the CPUSVN+PCE ISVSVN of the current platform. + // + SE_TRACE(SE_TRACE_DEBUG, "pce_cert_psvn.cpusvn:\n"); + PRINT_BYTE_ARRAY(SE_TRACE_DEBUG, &p_plaintext_data->cert_cpu_svn, sizeof(p_plaintext_data->cert_cpu_svn)); + SE_TRACE(SE_TRACE_DEBUG, "\npce_cert_psvn.isv_svn = 0x%04x.\n", p_plaintext_data->cert_pce_info.pce_isv_svn); + pce_error = sgx_pce_sign_report(&p_plaintext_data->cert_pce_info.pce_isv_svn, + &p_plaintext_data->cert_cpu_svn, + &p_plaintext_data->qe_report, + (uint8_t*)&pce_sig, + sizeof(pce_sig), + &sig_out_size); + if (SGX_PCE_SUCCESS != pce_error) { + SE_TRACE(SE_TRACE_ERROR, "Failed to certify the attestation key. PCE Error = 0x%04x.\n", pce_error); + refqt_ret = translate_pce_errors(pce_error); + goto CLEANUP; + } + + // Update the signature data and the report that was signed. + if(0 != memcpy_s(&p_plaintext_data->qe_report_cert_key_sig, sizeof(p_plaintext_data->qe_report_cert_key_sig), &pce_sig, sizeof(pce_sig))) { + refqt_ret = SGX_QL_ERROR_UNEXPECTED; + goto CLEANUP; + } + // Update the ECDSA key blob with certification data + SE_TRACE(SE_TRACE_DEBUG, "Update ECDSA blob with cert data.\n"); + sgx_status = store_cert_data(*p_tdqe_eid, + (uint32_t*)&tdqe_error, + p_plaintext_data, + certification_key_type, + p_encrypted_ppid, + encrypted_ppid_size, + p_ecdsa_blob, + SGX_QL_TRUSTED_ECDSA_BLOB_SIZE_SDK); + if (SGX_SUCCESS != sgx_status) { + SE_TRACE(SE_TRACE_ERROR, "Failed call into the TDQE. 0x%04x\n", sgx_status); + // /todo: May want to retry on SGX_ERROR_ENCLAVE_LOST caused by power transition + refqt_ret = (quote3_error_t)sgx_status; + goto CLEANUP; + } + if (TDQE_SUCCESS != tdqe_error) { + SE_TRACE(SE_TRACE_ERROR, "Failed to generate ECDSA blob. 0x%04x.\n", tdqe_error); + refqt_ret = (quote3_error_t)tdqe_error; + goto CLEANUP; + } else { + SE_TRACE(SE_TRACE_DEBUG, "Certification done. Store updated ECDSA blob to disk.\n"); + refqt_ret = write_persistent_data(p_ecdsa_blob, + SGX_QL_TRUSTED_ECDSA_BLOB_SIZE_SDK, + ECDSA_BLOB_LABEL); + if (refqt_ret != SGX_QL_SUCCESS) { + // This should not be a critical failure but a warning. The ECDSA key is still in memory. + SE_TRACE(SE_TRACE_WARNING, "Warning, unable to store resealed ECDSA blob to persistent storage.\n"); + SE_TRACE(SE_TRACE_DEBUG, "File storage is not required for the QE_Library. Library will use ECDSA Blob cached in memory.\n"); + refqt_ret = SGX_QL_SUCCESS; + } + } + + CLEANUP: + return(refqt_ret); +} + + +/** + * This is the ECDSA-P256 specific init quote code. The generic quote interfaces have been converted/reduced to the ECDSA specific inputs. + * The method will generate a new key and certify it when needed. + * /todo: Add support to re-certify when the key exists but its certification is out of date. + * /todo: Add the ability to specify additional certification data such as the CPU_SVN and PCE_SVN information when requesting a PCE signature + * to support E3 platforms. + * + * @param certification_key_type + * @param qe_target_info + * @param refresh_att_key + * @param pub_key_id + * + * @return SGX_QL_SUCCESS + * @return SGX_QL_ERROR_INVALID_PARAMETER + * @return SGX_PCE_INVALID_PARAMETER->SGX_QL_ERROR_UNEXPECTED + * @return SGX_PCE_INTERFACE_UNAVAILABLE->SGX_QL_INTERFACE_UNAVAILABLE + * @return SGX_PCE_OUT_OF_EPC->SGX_QL_OUT_OF_EPC + * @return Errors from load_qe() + * @return Errors from failed ecall (need to handle at least ENCLAVE_LOST) + * @return TDQE_ERROR_INVALID_PLATFORM + * @return TDQE_ERROR_INVALID_PARAMETER + * @return TDQE_ERROR_CRYPTO Error generating the PPID Encryption key. + * @return TDQE_ERROR_UNEXPECTED + * @return SGX_PCE_INVALID_REPORT QE.REPORT verification failed.->SGX_QL_ERROR_UNEXPECTED + * @return SGX_PCE_CRYPTO_ERROR QE.REPORT.ReportData hash compare failed.-> SGX_QL_ERROR_UNEXPECTED + * @return SGX_PCE_INVALID_PRIVILEGE QE doesn't have the prov bit set.-> SGX_QL_ERROR_UNEXPECTED (for produciton + * release. + * @return SGX_PCE_UNEXPECTED->SGX_QL_ERROR_UNEXPECTED + * @return SGX_QL_ERROR_INVALID_PCE_SIG_SCHEME PCE used and unexpected/unsupported signature scheme. + * @return SGX_QL_ERROR_UNEXPECTED + * @return TDQE_ERROR_ATT_KEY_GEN Error generated the attestaion key. + * @return TDQE_ERROR_CRYPTO Error generating QE_ID. + * @return TDQE_ERROR_OUT_OF_MEMORY + * @return SGX_ERROR_UNEXPECTED (from Seal) + * @return SGX_ERROR_INVALID_PARAMETER (from Seal) + * @return SGX_ERROR_OUT_OF_MEMORY (create report) + * @return TDQE_ERROR_CRYPTO Error decrypting PPID (only for cert_key_type = PPID_CLEARTEXT) + * @return TDQE_ECDSABLOB_ERROR (probably should be unexpected since the blob was either generated during this call + * or was already verified once. + * + */ +static quote3_error_t ecdsa_init_quote(sgx_ql_cert_key_type_t certification_key_type, + sgx_target_info_t *p_qe_target_info, + bool refresh_att_key, + ref_sha256_hash_t *p_pub_key_id) +{ + quote3_error_t refqt_ret = SGX_QL_SUCCESS; + sgx_status_t sgx_status = SGX_SUCCESS; + sgx_enclave_id_t tdqe_eid = 0; + sgx_launch_token_t launch_token = {0}; + tdqe_error_t tdqe_error = TDQE_ERROR_UNEXPECTED; + uint8_t resealed = 0; + ref_sha256_hash_t blob_ecdsa_id; + sgx_target_info_t pce_target_info; + sgx_isv_svn_t pce_isv_svn; + sgx_misc_attribute_t tdqe_attributes; + //int enclave_lost_retry_time = 1; + bool gen_new_key = false; + sgx_psvn_t pce_cert_psvn; + sgx_ql_pck_cert_id_t pck_cert_id; + sgx_pce_error_t pce_error; + sgx_report_body_t tdqe_report_body; + uint32_t cert_data_size; + sgx_sealed_data_t *p_sealed_ecdsa; + ref_plaintext_ecdsa_data_sdk_t plaintext_data; + ref_plaintext_ecdsa_data_sdk_t *p_seal_data_plain_text; + uint8_t encrypted_ppid[REF_RSA_OAEP_3072_MOD_SIZE]; + int blob_mutex_rc = 0; + + // Verify inputs + if (PPID_RSA3072_ENCRYPTED != certification_key_type) { + SE_TRACE(SE_TRACE_ERROR, "Invalid certification key type.\n"); + return(SGX_QL_ERROR_INVALID_PARAMETER); + } + + if (NULL == p_qe_target_info) { + SE_TRACE(SE_TRACE_ERROR, "Invalid qe target info.\n"); + return(SGX_QL_ERROR_INVALID_PARAMETER); + } + + // Get PCE Target Info + SE_TRACE(SE_TRACE_DEBUG, "Call sgx_pce_get_target().\n"); + pce_error = sgx_pce_get_target(&pce_target_info, &pce_isv_svn); + if (SGX_PCE_SUCCESS != pce_error) { + SE_TRACE(SE_TRACE_ERROR, "Error, call sgx_pce_get_target [%s], pce_error:%04x.\n", __FUNCTION__, pce_error); + refqt_ret = translate_pce_errors(pce_error); + goto CLEANUP; + } + + // Load the QE enclave + SE_TRACE(SE_TRACE_DEBUG, "Call Load the QE.\n"); + refqt_ret = load_qe(&tdqe_eid, + &tdqe_attributes, + &launch_token); + if (SGX_QL_SUCCESS != refqt_ret) + { + goto CLEANUP; + + } + + // Compose the target_info from the attributes returned by sgx_create_enclave and mr_enclave from qe report. + memset(p_qe_target_info, 0, sizeof(sgx_target_info_t)); + if(0 != memcpy_s(&p_qe_target_info->attributes, sizeof(p_qe_target_info->attributes), + &tdqe_attributes.secs_attr, sizeof(tdqe_attributes.secs_attr))) { + refqt_ret = SGX_QL_ERROR_UNEXPECTED; + goto CLEANUP; + } + if(0 != memcpy_s(&p_qe_target_info->misc_select, sizeof(p_qe_target_info->misc_select), + &tdqe_attributes.misc_select, sizeof(tdqe_attributes.misc_select))) { + refqt_ret = SGX_QL_ERROR_UNEXPECTED; + goto CLEANUP; + } + + blob_mutex_rc = se_mutex_lock(&g_ql_global_data.m_ecdsa_blob_mutex); + if (0 == blob_mutex_rc) { + SE_TRACE(SE_TRACE_ERROR, "Failed to lock mutex\n"); + goto CLEANUP; + } + + // If the caller has requested a new key, then force the generation of the new key regardless if the ECDSA blob exists. Otherwise, + // check to see if the ECDSA blob exists and is valid. + do { + if (true == refresh_att_key) { + SE_TRACE(SE_TRACE_DEBUG, "Caller requests a new ECDSA Key.\n"); + gen_new_key = true; + break; + } + uint32_t blob_size_read = sizeof(g_ql_global_data.m_ecdsa_blob); + // Get ECDSA Blob if exists + SE_TRACE(SE_TRACE_DEBUG, "Read ECDSA blob.\n"); + refqt_ret = read_persistent_data((uint8_t*)g_ql_global_data.m_ecdsa_blob, + &blob_size_read, + ECDSA_BLOB_LABEL); + if (SGX_QL_SUCCESS != refqt_ret) { + // Ignore errors since persistent storage is not required. Blob in memory may still be OK so continue to try to verify the cached blob. + SE_TRACE(SE_TRACE_WARNING, "ECDSA Blob doesn't exist is persistent storage. Try to use the cached version.\n"); + refqt_ret = SGX_QL_SUCCESS; + } + else if (blob_size_read != sizeof(g_ql_global_data.m_ecdsa_blob)) { + // If the blob was successfully read from persistent storage, verify its size. + SE_TRACE(SE_TRACE_ERROR, "Invalid ECDSA Blob file size. blob_size_read = %uld, sizeof(g_ecdsa_blob) = %uld. Since caller requested use any key, generate a new key.\n", blob_size_read, (uint32_t)sizeof(g_ql_global_data.m_ecdsa_blob)); + gen_new_key = true; + break; + } + memset(&tdqe_report_body, 0, sizeof(tdqe_report_body)); + // Verify the cached blob. + sgx_status = verify_blob(tdqe_eid, + (uint32_t*)&tdqe_error, + (uint8_t*)g_ql_global_data.m_ecdsa_blob, + sizeof(g_ql_global_data.m_ecdsa_blob), + &resealed, + &tdqe_report_body, + sizeof(blob_ecdsa_id), + (uint8_t*)&blob_ecdsa_id); + if (SGX_SUCCESS != sgx_status) { + SE_TRACE(SE_TRACE_ERROR, "Failed call into the TDQE. 0x%04x\n", sgx_status); + ///todo: May want to retry on SGX_ERROR_ENCLAVE_LOST caused by power transition or return a differnet error + refqt_ret = (quote3_error_t)sgx_status; + goto CLEANUP; + } + if (TDQE_SUCCESS != tdqe_error) { + SE_TRACE(SE_TRACE_DEBUG, "Invalid ECDSA Blob verificaton. 0x%04x, generate a new key.\n", tdqe_error); + gen_new_key = true; + break; + } + SE_TRACE(SE_TRACE_DEBUG, "Successfully verified ECDSA Blob.\n"); + p_qe_target_info->mr_enclave = tdqe_report_body.mr_enclave; + if (resealed) { + SE_TRACE(SE_TRACE_DEBUG, "ECDSA Blob was resealed. Store it disk.\n"); + refqt_ret = write_persistent_data((uint8_t*)g_ql_global_data.m_ecdsa_blob, + sizeof(g_ql_global_data.m_ecdsa_blob), + ECDSA_BLOB_LABEL); + if (refqt_ret != SGX_QL_SUCCESS) { + // Don't need to error since the blob is still good in memory. + ///todo: What is the best way to notify the requester that the blob was not stored to disk? + SE_TRACE(SE_TRACE_WARNING, "Warning, unable to store resealed ECDSA blob to persistent storage.\n"); + SE_TRACE(SE_TRACE_DEBUG, "File storage is not required for the QE_Library. Library will use ECDSA Blob cached in memory.\n"); + refqt_ret = SGX_QL_SUCCESS; + } + } + + p_sealed_ecdsa = reinterpret_cast(g_ql_global_data.m_ecdsa_blob); + p_seal_data_plain_text = reinterpret_cast(g_ql_global_data.m_ecdsa_blob + sizeof(sgx_sealed_data_t) + p_sealed_ecdsa->plain_text_offset); + // Check to see if the requested certification type matches the type in the blob. + if(p_seal_data_plain_text->certification_key_type != certification_key_type) { + SE_TRACE(SE_TRACE_ERROR, "Requested certificaiton_key_type doesn't match existing blob's type, Gen and certify new key.\n"); + gen_new_key = true; + break; + } + //QE's TCB has increased, (a decrease would cause a blob verification failure) then catch it here and generate a + //new key + if((tdqe_report_body.isv_svn > p_seal_data_plain_text->cert_qe_isv_svn) || + (0 != memcmp(&p_seal_data_plain_text->raw_cpu_svn, &tdqe_report_body.cpu_svn, sizeof(p_seal_data_plain_text->raw_cpu_svn)))) { + SE_TRACE(SE_TRACE_ERROR, "Platform TCB has increased, Requested certificaiton_key_type doesn't match existing blob's type, Gen and certify new key.\n"); + gen_new_key = true; + break; + } + ///todo: Probably don't need this check. PCE target info changes shouldn't require re-certification unless there is OwnerID changes. + //but is safe since it will just uneccessarily cause key regeneration and recertificaiton. + if(0 != memcmp(&p_seal_data_plain_text->pce_target_info, &pce_target_info, sizeof(p_seal_data_plain_text->pce_target_info))) { + SE_TRACE(SE_TRACE_DEBUG, "Recertification is not available since PCE TargetInfo changed. Gen and certify new key.\n"); + gen_new_key = true; + break; + } + if(0 != memcpy_s(p_pub_key_id, sizeof(*p_pub_key_id), &blob_ecdsa_id, sizeof(blob_ecdsa_id))) { + refqt_ret = SGX_QL_ERROR_UNEXPECTED; + goto CLEANUP; + } + SE_TRACE(SE_TRACE_DEBUG, "Using ECDSA_ID from ECDSA Blob. ECDSA_ID:\n"); + PRINT_BYTE_ARRAY(SE_TRACE_DEBUG, (uint8_t *)&blob_ecdsa_id, sizeof(blob_ecdsa_id)); + SE_TRACE(SE_TRACE_DEBUG, "\n"); + + if (SGX_QL_SUCCESS != (refqt_ret = getencryptedppid(pce_target_info, encrypted_ppid, REF_RSA_OAEP_3072_MOD_SIZE))){ + SE_TRACE(SE_TRACE_DEBUG, "Fail to retrieve encrypted PPID.\n"); + goto CLEANUP; + } + + + if (NULL == g_ql_global_data.m_qe_id) + { + + g_ql_global_data.m_qe_id = (sgx_key_128bit_t*)malloc(sizeof(sgx_key_128bit_t)); + if (!g_ql_global_data.m_qe_id) { + SE_TRACE(SE_TRACE_ERROR, "Fail to allocate memory.\n"); + refqt_ret = SGX_QL_ERROR_OUT_OF_MEMORY; + goto CLEANUP; + } + + refqt_ret = load_id_enclave_get_id(g_ql_global_data.m_qe_id); + if (SGX_QL_SUCCESS != refqt_ret) { + goto CLEANUP; + } + } + + // Determine if the raw-TCB has changed since the blob was last generated or the platform library + // has a new TCBm. If the raw-TCB was downgraded, the ECDSA blob will not be accessible and fail + // above. + // For key recertification, the attestation owner doesn't need to generate a new attestation key but + // it does need the attestation key to get recertified by the PCE. This can happen due to a TCB + // Recovery that requires the att key to be certified due to a higher PCE ISVSVN. If the CPUSVN changes + // both a new attestation key will be generated and it will get recertified. Recertification without a new + // attestation key can also happen when the resulting TCBm from the call to sgx_get_quote_config() differs from + // the value used to certify existing attestation key. + + // Get the TCB the PCE should use to ceritfy the attestaion key. Find and call the platform software's + // sgx_ql_get_quote_config(). If it is not available or the API returns SGX_QL_NO_PLATFORM_CERT_DATA, then use + // the platform's raw TCB to certify the key. + cert_data_size = 0; + pck_cert_id.p_qe3_id = (uint8_t*)g_ql_global_data.m_qe_id; + pck_cert_id.qe3_id_size = sizeof(*g_ql_global_data.m_qe_id); + pck_cert_id.p_platform_cpu_svn = &tdqe_report_body.cpu_svn; + pck_cert_id.p_platform_pce_isv_svn = &pce_isv_svn; + pck_cert_id.p_encrypted_ppid = encrypted_ppid; + pck_cert_id.encrypted_ppid_size = REF_RSA_OAEP_3072_MOD_SIZE; + pck_cert_id.crypto_suite = PCE_ALG_RSA_OAEP_3072; + pck_cert_id.pce_id = p_seal_data_plain_text->cert_pce_info.pce_id; + refqt_ret = get_platform_quote_cert_data(&pck_cert_id, + &pce_cert_psvn.cpu_svn, + &pce_cert_psvn.isv_svn, + &cert_data_size, + NULL); + if (refqt_ret != SGX_QL_SUCCESS) { + if (refqt_ret != SGX_QL_PLATFORM_LIB_UNAVAILABLE) { + // The dependent library was found but it returned an error + goto CLEANUP; + } + refqt_ret = SGX_QL_SUCCESS; + if(pce_isv_svn > p_seal_data_plain_text->cert_pce_info.pce_isv_svn) { + SE_TRACE(SE_TRACE_DEBUG, "Using raw-PCE_ISVSVN to certify the key and it has increased. Recertify.\n"); + + // Use the raw TCB of the platform and the EncPPID certification type + pce_cert_psvn.cpu_svn = tdqe_report_body.cpu_svn; + pce_cert_psvn.isv_svn = pce_isv_svn; + // Set up the certification data to update the blob with. + memset(&plaintext_data, 0, sizeof(plaintext_data)); + if(0 != memcpy_s(&plaintext_data.cert_cpu_svn, sizeof(plaintext_data.cert_cpu_svn), + &pce_cert_psvn.cpu_svn, sizeof(pce_cert_psvn.cpu_svn))) { + refqt_ret = SGX_QL_ERROR_UNEXPECTED; + goto CLEANUP; + } + plaintext_data.cert_pce_info.pce_isv_svn = pce_cert_psvn.isv_svn; + plaintext_data.cert_pce_info.pce_id = p_seal_data_plain_text->cert_pce_info.pce_id; + if(0 != memcpy_s(&plaintext_data.raw_cpu_svn, sizeof(plaintext_data.raw_cpu_svn), + &tdqe_report_body.cpu_svn, sizeof(tdqe_report_body.cpu_svn))) { + refqt_ret = SGX_QL_ERROR_UNEXPECTED; + goto CLEANUP; + } + plaintext_data.raw_pce_info.pce_isv_svn = pce_isv_svn; + plaintext_data.raw_pce_info.pce_id = p_seal_data_plain_text->cert_pce_info.pce_id; + // For recertification, pull out out the certification data from the blob that doesn't need to change. + if(0 != memcpy_s(&plaintext_data.qe_report, sizeof(plaintext_data.qe_report), + &p_seal_data_plain_text->qe_report, sizeof(p_seal_data_plain_text->qe_report))) { + refqt_ret = SGX_QL_ERROR_UNEXPECTED; + goto CLEANUP; + } + if (0 != memcpy_s(&plaintext_data.qe_id, sizeof(plaintext_data.qe_id), + g_ql_global_data.m_qe_id, sizeof(*g_ql_global_data.m_qe_id))) { + refqt_ret = SGX_QL_ERROR_UNEXPECTED; + goto CLEANUP; + } + plaintext_data.signature_scheme = p_seal_data_plain_text->signature_scheme; ///todo: Not likely that the signature scheme changed but may want to re-get from PCE. It is just more involved. + if(0 != memcpy_s(&plaintext_data.pce_target_info, sizeof(plaintext_data.pce_target_info), + &pce_target_info, sizeof(pce_target_info))) { + refqt_ret = SGX_QL_ERROR_UNEXPECTED; + goto CLEANUP; + } + plaintext_data.certification_key_type = certification_key_type; //Cert key request it checked if it changed above. If changed, recertification is not allowed. + refqt_ret = certify_key(g_ql_global_data.m_ecdsa_blob, + &plaintext_data, + NULL, + 0, + certification_key_type, + &tdqe_eid); + } + } + else { + // Check if the returned certification TCB is different than the TCB used to certify the key in the + // ECDSA blob. If it hasn't changed then continue to use the cert data in the blob. Otherwise, need to + // do recertify using the new data. + if((pce_cert_psvn.isv_svn != p_seal_data_plain_text->cert_pce_info.pce_isv_svn) || + (0 != memcmp(&pce_cert_psvn.cpu_svn, &p_seal_data_plain_text->cert_cpu_svn, sizeof(pce_cert_psvn.cpu_svn)))) + { + SE_TRACE(SE_TRACE_DEBUG, "The Cert TCB value returned by the platform library is different than the value used to certify the key. Recertify.\n"); + + // Set up the certification data to update the blob with. + memset(&plaintext_data, 0, sizeof(plaintext_data)); + if(0 != memcpy_s(&plaintext_data.cert_cpu_svn, sizeof(plaintext_data.cert_cpu_svn), + &pce_cert_psvn.cpu_svn, sizeof(pce_cert_psvn.cpu_svn))) { + refqt_ret = SGX_QL_ERROR_UNEXPECTED; + goto CLEANUP; + } + plaintext_data.cert_pce_info.pce_isv_svn = pce_cert_psvn.isv_svn; + plaintext_data.cert_pce_info.pce_id = p_seal_data_plain_text->cert_pce_info.pce_id; + if(0 != memcpy_s(&plaintext_data.raw_cpu_svn, sizeof(plaintext_data.raw_cpu_svn), + &tdqe_report_body.cpu_svn, sizeof(tdqe_report_body.cpu_svn))) { + refqt_ret = SGX_QL_ERROR_UNEXPECTED; + goto CLEANUP; + } + plaintext_data.raw_pce_info.pce_isv_svn = pce_isv_svn; + plaintext_data.raw_pce_info.pce_id = p_seal_data_plain_text->cert_pce_info.pce_id; + // For recertification, pull out out the certification data from the blob that doesn't need to change. + if(0 != memcpy_s(&plaintext_data.qe_report, sizeof(plaintext_data.qe_report), + &p_seal_data_plain_text->qe_report, sizeof(p_seal_data_plain_text->qe_report))){ + refqt_ret = SGX_QL_ERROR_UNEXPECTED; + goto CLEANUP; + } + if (0 != memcpy_s(&plaintext_data.qe_id, sizeof(plaintext_data.qe_id), + g_ql_global_data.m_qe_id, sizeof(*g_ql_global_data.m_qe_id))) { + refqt_ret = SGX_QL_ERROR_UNEXPECTED; + goto CLEANUP; + } + plaintext_data.signature_scheme = p_seal_data_plain_text->signature_scheme; ///todo: Not likely that the signature scheme changed but may want to re-get from PCE. It is just more involved. + if(0 != memcpy_s(&plaintext_data.pce_target_info, sizeof(plaintext_data.pce_target_info), + &pce_target_info, sizeof(pce_target_info))) { + refqt_ret = SGX_QL_ERROR_UNEXPECTED; + goto CLEANUP; + } + plaintext_data.certification_key_type = certification_key_type; //Cert key request it checked if it changed above. If changed, recertification is not allowed. + refqt_ret = certify_key(g_ql_global_data.m_ecdsa_blob, + &plaintext_data, + NULL, + 0, + certification_key_type, + &tdqe_eid); + } + } + } while (0); + + if (true == gen_new_key) { + sgx_report_t tdqe_report; + + // Authentication data is added to by the QE owner and will be 'signed' by the certification key. It's use is dependent of the owner. + // Just use a fixed value for the reference. + uint8_t authentication_data[REF_ECDSDA_AUTHENTICATION_DATA_SIZE] = + {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f, + 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f}; + + SE_TRACE(SE_TRACE_DEBUG, "Generate and certify a new ECDSA attestation key\n"); + if (PPID_RSA3072_ENCRYPTED == certification_key_type) { + if (SGX_QL_SUCCESS != (refqt_ret = getencryptedppid(pce_target_info, encrypted_ppid, REF_RSA_OAEP_3072_MOD_SIZE))) { + SE_TRACE(SE_TRACE_DEBUG, "Fail to retrieve encrypted PPID.\n"); + goto CLEANUP; + } + } else { + SE_TRACE(SE_TRACE_ERROR, "certification_key_type not supported.\n"); + refqt_ret = SGX_QL_ERROR_INVALID_PARAMETER; + goto CLEANUP; + } + // Generate the ECDSA key + SE_TRACE(SE_TRACE_DEBUG, "Get ATT Key.\n"); + sgx_status = gen_att_key(tdqe_eid, + (uint32_t*)&tdqe_error, + g_ql_global_data.m_ecdsa_blob, + SGX_QL_TRUSTED_ECDSA_BLOB_SIZE_SDK, + &pce_target_info, + &tdqe_report, + &authentication_data[0], + sizeof(authentication_data)); + if (SGX_SUCCESS != sgx_status) { + SE_TRACE(SE_TRACE_ERROR, "Failed call into the TDQE. 0x%04x.\n", sgx_status); + // /todo: May want to retry on SGX_ERROR_ENCLAVE_LOST caused by power transition + refqt_ret = (quote3_error_t)sgx_status; + goto CLEANUP; + } + if (TDQE_SUCCESS != tdqe_error) { + SE_TRACE(SE_TRACE_ERROR, "Failed to generate attestation key. 0x%04x\n", tdqe_error); + refqt_ret = (quote3_error_t)tdqe_error; + goto CLEANUP; + } + + if(0 != memcpy_s(&p_qe_target_info->mr_enclave, sizeof(p_qe_target_info->mr_enclave), + &tdqe_report.body.mr_enclave, sizeof(tdqe_report.body.mr_enclave))) { + refqt_ret = SGX_QL_ERROR_UNEXPECTED; + goto CLEANUP; + } + + if (NULL == g_ql_global_data.m_qe_id) + { + + g_ql_global_data.m_qe_id = (sgx_key_128bit_t*)malloc(sizeof(sgx_key_128bit_t)); + if (!g_ql_global_data.m_qe_id) { + SE_TRACE(SE_TRACE_ERROR, "Fail to allocate memory.\n"); + refqt_ret = SGX_QL_ERROR_OUT_OF_MEMORY; + goto CLEANUP; + } + + refqt_ret = load_id_enclave_get_id(g_ql_global_data.m_qe_id); + if (SGX_QL_SUCCESS != refqt_ret) { + goto CLEANUP; + } + } + + // Certify the key + // Get the certification data from the platform, if available + p_sealed_ecdsa = reinterpret_cast(g_ql_global_data.m_ecdsa_blob); + p_seal_data_plain_text = reinterpret_cast(g_ql_global_data.m_ecdsa_blob + sizeof(sgx_sealed_data_t) + p_sealed_ecdsa->plain_text_offset); + cert_data_size = 0; + memset(&plaintext_data, 0, sizeof(plaintext_data)); + pck_cert_id.p_qe3_id = (uint8_t*)g_ql_global_data.m_qe_id; + pck_cert_id.qe3_id_size = sizeof(*g_ql_global_data.m_qe_id); + pck_cert_id.p_platform_cpu_svn = &tdqe_report.body.cpu_svn; + pck_cert_id.p_platform_pce_isv_svn = &g_ql_global_data.m_pce_info.pce_isv_svn; + pck_cert_id.p_encrypted_ppid = encrypted_ppid; + pck_cert_id.encrypted_ppid_size = REF_RSA_OAEP_3072_MOD_SIZE; + pck_cert_id.crypto_suite = PCE_ALG_RSA_OAEP_3072; + pck_cert_id.pce_id = g_ql_global_data.m_pce_info.pce_id; + refqt_ret = get_platform_quote_cert_data(&pck_cert_id, + &pce_cert_psvn.cpu_svn, + &pce_cert_psvn.isv_svn, + &cert_data_size, + NULL); + if (refqt_ret != SGX_QL_SUCCESS) { + if (refqt_ret != SGX_QL_PLATFORM_LIB_UNAVAILABLE) { + // The dependent library was found but it returned an error + goto CLEANUP; + } + SE_TRACE(SE_TRACE_DEBUG, "Platform Quote Config callback is not available, use the platform's raw TCB.\n"); + refqt_ret = SGX_QL_SUCCESS; + // Use the raw TCB of the platform and the EncPPID certification type + pce_cert_psvn.cpu_svn = tdqe_report.body.cpu_svn; + pce_cert_psvn.isv_svn = pce_isv_svn; + } + + // Set up the certification data and update the ECDSA Blob. + // The TDQE will verify these plaintext parameters, add some more plaintext values, add the secret values and + // generate a sealed blob. + if(0 != memcpy_s(&plaintext_data.cert_cpu_svn, sizeof(plaintext_data.cert_cpu_svn), + &pce_cert_psvn.cpu_svn, sizeof(pce_cert_psvn.cpu_svn))) { + refqt_ret = SGX_QL_ERROR_UNEXPECTED; + goto CLEANUP; + } + plaintext_data.cert_pce_info.pce_isv_svn = pce_cert_psvn.isv_svn; + plaintext_data.cert_pce_info.pce_id = 0; + if(0 != memcpy_s(&plaintext_data.raw_cpu_svn, sizeof(plaintext_data.raw_cpu_svn), + &tdqe_report.body.cpu_svn, sizeof(tdqe_report.body.cpu_svn))) { + refqt_ret = SGX_QL_ERROR_UNEXPECTED; + goto CLEANUP; + } + plaintext_data.raw_pce_info.pce_isv_svn = g_ql_global_data.m_pce_info.pce_isv_svn; + plaintext_data.raw_pce_info.pce_id = g_ql_global_data.m_pce_info.pce_id; + if(0 != memcpy_s(&plaintext_data.qe_report, sizeof(plaintext_data.qe_report), + &tdqe_report, sizeof(tdqe_report))) { + refqt_ret = SGX_QL_ERROR_UNEXPECTED; + goto CLEANUP; + } + if (0 != memcpy_s(&plaintext_data.qe_id, sizeof(plaintext_data.qe_id), + g_ql_global_data.m_qe_id, sizeof(*g_ql_global_data.m_qe_id))) { + refqt_ret = SGX_QL_ERROR_UNEXPECTED; + goto CLEANUP; + } + plaintext_data.signature_scheme = PCE_NIST_P256_ECDSA_SHA256; + if(0 != memcpy_s(&plaintext_data.pce_target_info, sizeof(plaintext_data.pce_target_info), + &pce_target_info, sizeof(pce_target_info))) { + refqt_ret = SGX_QL_ERROR_UNEXPECTED; + goto CLEANUP; + } + plaintext_data.certification_key_type = certification_key_type; + refqt_ret = certify_key(g_ql_global_data.m_ecdsa_blob, + &plaintext_data, + encrypted_ppid, + REF_RSA_OAEP_3072_MOD_SIZE, + certification_key_type, + &tdqe_eid); + if (SGX_QL_SUCCESS != refqt_ret) { + SE_TRACE(SE_TRACE_DEBUG, "Failed to cerify key.\n"); + goto CLEANUP; + } + SE_TRACE(SE_TRACE_DEBUG, "TDQE_ID:\n"); + PRINT_BYTE_ARRAY(SE_TRACE_DEBUG, &p_seal_data_plain_text->qe_id, sizeof(p_seal_data_plain_text->qe_id)); + + SE_TRACE(SE_TRACE_DEBUG, "Generated and certified a new key. ECDSA_ID:\n"); + PRINT_BYTE_ARRAY(SE_TRACE_DEBUG, &tdqe_report.body.report_data, sizeof(sgx_sha256_hash_t)); + // Write the ECDSA_ID to the output buffer + if(0 != memcpy_s(p_pub_key_id, sizeof(*p_pub_key_id), &tdqe_report.body.report_data, sizeof(*p_pub_key_id))) { + refqt_ret = SGX_QL_ERROR_UNEXPECTED; + goto CLEANUP; + } + } + + CLEANUP: + if(0 != blob_mutex_rc ) { + blob_mutex_rc = se_mutex_unlock(&g_ql_global_data.m_ecdsa_blob_mutex); + if (0 == blob_mutex_rc) + { + SE_TRACE(SE_TRACE_ERROR, "Failed to unlock mutex"); + return SGX_QL_ERROR_UNEXPECTED; + } + } + + unload_qe(); + + return(refqt_ret); +} + +/** +* This is the ECDSA-P256 specific init quote code. The generic quote interfaces have been converted/reduced to the ECDSA specific inputs. +* The method will return the required quote buffer size dependent on the certification key type. +* +* @param certification_key_type +* @param p_quote_size +* +* @return SGX_QL_SUCCESS +* @return SGX_QL_ERROR_INVALID_PARAMETER +* @return Errors from load_qe() +* @return Errors from an ecall +* @return SGX_QL_ATT_KEY_NOT_INITIALIZED The Attestaion key has not been generated, certified or requires +* recertification yet. Need to call InitQuote first/again to get attestaion key regenerated/receritifed. +* @return SGX_QL_ATT_KEY_CERT_DATA_INVALID Quote certification data from the platform library is invalid. +* +*/ +static quote3_error_t ecdsa_get_quote_size(sgx_ql_cert_key_type_t certification_key_type, + uint32_t* p_quote_size) +{ + + quote3_error_t refqt_ret = SGX_QL_SUCCESS; + sgx_status_t sgx_status = SGX_SUCCESS; + tdqe_error_t tdqe_error = TDQE_ERROR_UNEXPECTED; + uint32_t cert_data_size; + sgx_sealed_data_t *p_sealed_ecdsa; + ref_plaintext_ecdsa_data_sdk_t *p_seal_data_plain_text; + sgx_report_body_t tdqe_report_body; + sgx_pce_error_t pce_error; + sgx_target_info_t pce_target_info; + sgx_isv_svn_t pce_isv_svn; + sgx_psvn_t pce_cert_psvn; + sgx_enclave_id_t tdqe_eid = 0; + sgx_launch_token_t launch_token = {0}; + sgx_misc_attribute_t tdqe_attributes; + uint8_t resealed = 0; + sgx_ql_pck_cert_id_t pck_cert_id; + uint32_t blob_size_read; + int blob_mutex_rc = 0; + + // Verify inputs + // Only RSA-3072-OAEP Encrypted PPID certification type in the reference. + if (PPID_RSA3072_ENCRYPTED != certification_key_type) { + SE_TRACE(SE_TRACE_ERROR, "Invalid certification key type."); + return(SGX_QL_ERROR_INVALID_PARAMETER); + } + + if (NULL == p_quote_size) { + SE_TRACE(SE_TRACE_ERROR, "p_quote_size is NULL."); + return(SGX_QL_ERROR_INVALID_PARAMETER); + } + + SE_TRACE(SE_TRACE_DEBUG, "sizeof(sgx_quote4_t) = %d.\n", (unsigned int)sizeof(sgx_quote4_t)); + SE_TRACE(SE_TRACE_DEBUG, "(2 * sizeof(sgx_ec256_signature_t)) = %d.\n", (unsigned int)(2 * sizeof(sgx_ec256_signature_t))); + SE_TRACE(SE_TRACE_DEBUG, "sizeof(sgx_ec256_public_t) = %d.\n", (unsigned int)sizeof(sgx_ec256_public_t)); + SE_TRACE(SE_TRACE_DEBUG, "sizeof(uint16_t) = %d.\n", (unsigned int)sizeof(uint16_t)); + SE_TRACE(SE_TRACE_DEBUG, "sizeof(uint32_t) = %d.\n", (unsigned int)sizeof(uint32_t)); + SE_TRACE(SE_TRACE_DEBUG, "sizeof(uint32_t) = %d.\n", (unsigned int)sizeof(uint32_t)); + SE_TRACE(SE_TRACE_DEBUG, "authentication_data_size = %d.\n", (unsigned int)REF_ECDSDA_AUTHENTICATION_DATA_SIZE); + SE_TRACE(SE_TRACE_DEBUG, "sizeof(ref_ppid_rsa3072_encrypted_cert_info_t) = %d.\n", (unsigned int)sizeof(sgx_ql_ppid_rsa3072_encrypted_cert_info_t)); + + // Get PCE Target Info + pce_error = sgx_pce_get_target(&pce_target_info, &pce_isv_svn); + if (SGX_PCE_SUCCESS != pce_error) { + SE_TRACE(SE_TRACE_ERROR, "Error, call sgx_pce_get_target [%s], pce_error:%04x.\n", __FUNCTION__, pce_error); + refqt_ret = translate_pce_errors(pce_error); + goto CLEANUP; + } + + // Load the TDQE + SE_TRACE(SE_TRACE_DEBUG, "Call Load the QE.\n"); + refqt_ret = load_qe(&tdqe_eid, + &tdqe_attributes, + &launch_token); + if (SGX_QL_SUCCESS != refqt_ret) + { + goto CLEANUP; + + } + + blob_mutex_rc = se_mutex_lock(&g_ql_global_data.m_ecdsa_blob_mutex); + if (0 == blob_mutex_rc) { + SE_TRACE(SE_TRACE_ERROR, "Failed to lock mutex\n"); + goto CLEANUP; + } + + blob_size_read = sizeof(g_ql_global_data.m_ecdsa_blob); + // Get ECDSA Blob if exists + SE_TRACE(SE_TRACE_DEBUG, "Read ECDSA blob from persistent storage.\n"); + refqt_ret = read_persistent_data((uint8_t*)g_ql_global_data.m_ecdsa_blob, + &blob_size_read, + ECDSA_BLOB_LABEL); + if (SGX_QL_SUCCESS != refqt_ret) { + // Ignore errors since persistent storage is not required. Blob in memory may still be OK and continue to try to verify the cached blob. + SE_TRACE(SE_TRACE_WARNING, "ECDSA Blob doesn't exist is persistent storage. Try to use the cached version.\n"); + refqt_ret = SGX_QL_SUCCESS; + } + else if (blob_size_read != sizeof(g_ql_global_data.m_ecdsa_blob)) { + // If the blob was successfully read from persistent storage, verify its size. + SE_TRACE(SE_TRACE_ERROR, "Invalid ECDSA Blob file size. blob_size_read = %uld, sizeof(g_ecdsa_blob) = %uld. Since caller requested use any key, generate a new key.\n", blob_size_read, (uint32_t)sizeof(g_ql_global_data.m_ecdsa_blob)); + refqt_ret = SGX_QL_ATT_KEY_NOT_INITIALIZED; + goto CLEANUP; + } + memset(&tdqe_report_body, 0, sizeof(tdqe_report_body)); + // If exists, verify blob. + sgx_status = verify_blob(tdqe_eid, + (uint32_t*)&tdqe_error, + (uint8_t*)g_ql_global_data.m_ecdsa_blob, + sizeof(g_ql_global_data.m_ecdsa_blob), + &resealed, + &tdqe_report_body, + 0, + NULL); + if (SGX_SUCCESS != sgx_status) { + SE_TRACE(SE_TRACE_ERROR, "Failed call into the TDQE. 0x%04x\n", sgx_status); + ///todo: May want to retry on SGX_ERROR_ENCLAVE_LOST caused by power transition or return a different error + refqt_ret = (quote3_error_t)sgx_status; + goto CLEANUP; + } + if (TDQE_SUCCESS != tdqe_error) { + SE_TRACE(SE_TRACE_ERROR, "Invalid ECDSA Blob verificaton. 0x%04x, generate a new key.\n", tdqe_error); + ///todo: Do we want to force the caller to generate the attestation key again when the ECDSA blob fails? + // May want to add logic to the DCAP wrappers to automatically call init_quote on this failure. + refqt_ret = SGX_QL_ATT_KEY_NOT_INITIALIZED; + goto CLEANUP; + } + if (resealed) { + SE_TRACE(SE_TRACE_DEBUG, "ECDSA Blob was resealed. Store it disk.\n"); + refqt_ret = write_persistent_data((uint8_t*)g_ql_global_data.m_ecdsa_blob, + sizeof(g_ql_global_data.m_ecdsa_blob), + ECDSA_BLOB_LABEL); + + if (refqt_ret != SGX_QL_SUCCESS) { + // Don't need to error since the blob is still good in memory. + // /todo: What is the best way to notify the requester that the blob was not stored? + SE_TRACE(SE_TRACE_WARNING, "Warning, unable to store resealed ECDSA blob to persistent storage.\n"); + SE_TRACE(SE_TRACE_DEBUG, "File storage is not required for the QE_Library. Library will use ECDSA Blob cached in memory.\n"); + refqt_ret = SGX_QL_SUCCESS; + } + } + SE_TRACE(SE_TRACE_DEBUG, "Successfully verified ECDSA Blob.\n"); + + p_sealed_ecdsa = reinterpret_cast(g_ql_global_data.m_ecdsa_blob); + p_seal_data_plain_text = reinterpret_cast(g_ql_global_data.m_ecdsa_blob + sizeof(sgx_sealed_data_t) + p_sealed_ecdsa->plain_text_offset); + cert_data_size = 0; + pck_cert_id.p_qe3_id = (uint8_t*)&p_seal_data_plain_text->qe_id; + pck_cert_id.qe3_id_size = sizeof(p_seal_data_plain_text->qe_id); + pck_cert_id.p_platform_cpu_svn = &tdqe_report_body.cpu_svn; + pck_cert_id.p_platform_pce_isv_svn = &pce_isv_svn; + pck_cert_id.p_encrypted_ppid = NULL; + pck_cert_id.encrypted_ppid_size = 0; + pck_cert_id.crypto_suite = PCE_ALG_RSA_OAEP_3072; + pck_cert_id.pce_id = p_seal_data_plain_text->cert_pce_info.pce_id; + refqt_ret = get_platform_quote_cert_data(&pck_cert_id, + &pce_cert_psvn.cpu_svn, + &pce_cert_psvn.isv_svn, + &cert_data_size, + NULL); + // Use the default certification data when there is no data from platform library. + if (refqt_ret != SGX_QL_SUCCESS) { + if (refqt_ret != SGX_QL_PLATFORM_LIB_UNAVAILABLE) { + // The dependent library was found but it returned an error + goto CLEANUP; + } + + *p_quote_size = sizeof(sgx_quote4_t) + // quote body + sizeof(sgx_ecdsa_sig_data_v4_t) + + sizeof(sgx_ql_auth_data_t) + + REF_ECDSDA_AUTHENTICATION_DATA_SIZE + // Authentication data + sizeof(sgx_ql_certification_data_t) + + sizeof(sgx_ql_certification_data_t) + + sizeof(sgx_qe_report_certification_data_t) + + sizeof(sgx_ql_ppid_rsa3072_encrypted_cert_info_t); // RSA3072_ENC_PPID + PCE CPUSVN + PCE ISVSNV + PCEID + refqt_ret = SGX_QL_SUCCESS; + } + else { + // Verify that the cert_data_size is reasonable. + if((cert_data_size > MAX_CERT_DATA_SIZE) || + (cert_data_size < MIN_CERT_DATA_SIZE)) { + refqt_ret = SGX_QL_ATT_KEY_CERT_DATA_INVALID; + goto CLEANUP; + } + //Check to make sure that the TCBm of from the platform library matches the Cert TCB in the ECDSA blob. + if((0 != memcmp(&p_seal_data_plain_text->cert_cpu_svn, &pce_cert_psvn.cpu_svn, sizeof(p_seal_data_plain_text->cert_cpu_svn))) || + (p_seal_data_plain_text->cert_pce_info.pce_isv_svn != pce_cert_psvn.isv_svn)) { + SE_TRACE(SE_TRACE_ERROR, "TCBm in ECDSA blob doesn't match the value returned by the platform lib. %d and %d\n", p_seal_data_plain_text->cert_pce_info.pce_isv_svn, pce_cert_psvn.isv_svn); + + refqt_ret = SGX_QL_ATT_KEY_NOT_INITIALIZED; + goto CLEANUP; + } + // Overflow will not occur since the cer_data_size is limited above + *p_quote_size = (uint32_t)(sizeof(sgx_quote4_t) + // quote body + sizeof(sgx_ecdsa_sig_data_v4_t) + + sizeof(sgx_ql_auth_data_t) + + REF_ECDSDA_AUTHENTICATION_DATA_SIZE + // Authentication data + sizeof(sgx_ql_certification_data_t) + + sizeof(sgx_ql_certification_data_t) + + sizeof(sgx_qe_report_certification_data_t) + + cert_data_size); // certification data size returned by get_platform_quote_cert_data() + } + + CLEANUP: + if(0 != blob_mutex_rc ) { + blob_mutex_rc = se_mutex_unlock(&g_ql_global_data.m_ecdsa_blob_mutex); + if (0 == blob_mutex_rc) { + SE_TRACE(SE_TRACE_ERROR, "Failed to unlock mutex"); + refqt_ret = SGX_QL_ERROR_UNEXPECTED; + } + } + + unload_qe(); + + return(refqt_ret); +} + +/** +* This is the ECDSA-P256 specific get quote code. The generic quote interfaces have been converted/reduced to the ECDSA +* specific inputs. The method will return the quote dependent on the certification key type. +* +* @param certification_key_type +* @param p_app_report +* @param p_quote +* @param quote_size +* +* @return SGX_QL_SUCCESS +* @return Return codes from load_qe. +* @return SGX_QL_ATT_KEY_NOT_INITIALIZED The Attestaion key has not been generated, certified or requires +* recertification yet. Need to call InitQuote first/again to get attestaion key regenerated/receritifed. +* @return ///todo: List out ecall errors. + * @return SGX_QL_ATT_KEY_CERT_DATA_INVALID Quote certification data from the platform library is invalid. +* @return SGX_QL_ERROR_OUT_OF_MEMORY +* @return TDQE_ERROR_INVALID_PLATFORM +* @return TDQE_ERROR_INVALID_PARAMETER +* @return TDQE_ERROR_INVALID_REPORT +* @return TDQE_ECDSABLOB_ERROR Attestation key is invalid. Needs to be regenerated/recertified. +* @return TDQE_ERROR_UNEXPECTED +* @return TDQE_ERROR_CRYPTO +* @return TDQE_ERROR_OUT_OF_MEMORY +* @return SGX_ERROR_INVALID_PARAMETER +*/ +static quote3_error_t ecdsa_get_quote(const sgx_report2_t *p_app_report, + sgx_quote4_t *p_quote, + uint32_t quote_size) +{ + quote3_error_t refqt_ret = SGX_QL_SUCCESS; + sgx_status_t sgx_status = SGX_SUCCESS; + sgx_launch_token_t launch_token = {0}; + sgx_misc_attribute_t tdqe_attributes; + sgx_enclave_id_t tdqe_eid = 0; + tdqe_error_t tdqe_error = TDQE_ERROR_UNEXPECTED; + uint8_t resealed = 0; + uint32_t blob_size_read = sizeof(g_ql_global_data.m_ecdsa_blob); + sgx_sha256_hash_t blob_ecdsa_id; + sgx_isv_svn_t cur_pce_isv_svn = {0}; + sgx_target_info_t pce_target_info; + sgx_pce_error_t pce_error; + uint32_t cert_data_size; + sgx_ql_pck_cert_id_t pck_cert_id; + sgx_sealed_data_t *p_sealed_ecdsa; + ref_plaintext_ecdsa_data_sdk_t *p_seal_data_plain_text; + sgx_report_body_t tdqe_report_body; + sgx_ql_certification_data_t *p_certification_data = NULL; + sgx_psvn_t pce_cert_psvn; + int blob_mutex_rc = 0; + + //Verify inputs + if (NULL == p_app_report || + NULL == p_quote) { + SE_TRACE(SE_TRACE_ERROR, "Invalid input pointer.\n"); + return(SGX_QL_ERROR_INVALID_PARAMETER); + } + + // Load the TDQE + memset(&launch_token, 0, sizeof(sgx_launch_token_t)); + SE_TRACE(SE_TRACE_DEBUG, "Load the TDQE. %s\n", TDQE_ENCLAVE_NAME); + // Load the QE enclave + refqt_ret = load_qe(&tdqe_eid, + &tdqe_attributes, + &launch_token); + if (SGX_QL_SUCCESS != refqt_ret) + { + goto CLEANUP; + } + + blob_mutex_rc = se_mutex_lock(&g_ql_global_data.m_ecdsa_blob_mutex); + if (0 == blob_mutex_rc) { + SE_TRACE(SE_TRACE_ERROR, "Failed to lock mutex\n"); + goto CLEANUP; + } + + SE_TRACE(SE_TRACE_DEBUG, "Read and verify ecdsa blob\n"); + blob_size_read = sizeof(g_ql_global_data.m_ecdsa_blob); + // Get ECDSA Blob if exists + SE_TRACE(SE_TRACE_DEBUG, "Read ECDSA blob.\n"); + refqt_ret = read_persistent_data((uint8_t*)g_ql_global_data.m_ecdsa_blob, + &blob_size_read, + ECDSA_BLOB_LABEL); + if (SGX_QL_SUCCESS != refqt_ret) { + // Ignore errors since persistent storage is not required. Blob in memory may still be OK and continue to try to verify the cached blob. + ///todo: May want to have a library configuration option that requires persistent storage. Then treat the + //failures accordingly + SE_TRACE(SE_TRACE_WARNING, "ECDSA Blob doesn't exist is persistent storage. Try to use the cached version.\n"); + refqt_ret = SGX_QL_SUCCESS; + } + else if (blob_size_read != sizeof(g_ql_global_data.m_ecdsa_blob)) { + // If the blob was successfully read from persistent storage, verify its size. + SE_TRACE(SE_TRACE_ERROR, "Invalid ECDSA Blob file size. blob_size_read = %uld, sizeof(g_ecdsa_blob) = %uld. Since caller requested use any key, generate a new key.\n", blob_size_read, (uint32_t)sizeof(g_ql_global_data.m_ecdsa_blob)); + refqt_ret = SGX_QL_ATT_KEY_NOT_INITIALIZED; + goto CLEANUP; + } + memset(&tdqe_report_body, 0, sizeof(tdqe_report_body)); + // If exists, verify blob. + SE_TRACE(SE_TRACE_DEBUG, "Verify blob\n"); + sgx_status = verify_blob(tdqe_eid, + (uint32_t*)&tdqe_error, + (uint8_t*)g_ql_global_data.m_ecdsa_blob, + sizeof(g_ql_global_data.m_ecdsa_blob), + &resealed, + &tdqe_report_body, + sizeof(blob_ecdsa_id), + (uint8_t*)&blob_ecdsa_id); + if (SGX_SUCCESS != sgx_status) { + SE_TRACE(SE_TRACE_ERROR, "Failed call into the TDQE. 0x%04x\n", sgx_status); + // /todo: May want to retry on SGX_ERROR_ENCLAVE_LOST caused by power transition or return a differnent error. + refqt_ret = (quote3_error_t)sgx_status; + goto CLEANUP; + } + if (TDQE_SUCCESS != tdqe_error) { + SE_TRACE(SE_TRACE_ERROR, "Invalid ECDSA Blob verification. 0x%04x\n", tdqe_error); + refqt_ret = SGX_QL_ATT_KEY_NOT_INITIALIZED; + goto CLEANUP; + } + if (resealed) { + SE_TRACE(SE_TRACE_DEBUG, "ECDSA Blob was resealed. Store it.\n"); + refqt_ret = write_persistent_data((uint8_t*)g_ql_global_data.m_ecdsa_blob, + sizeof(g_ql_global_data.m_ecdsa_blob), + ECDSA_BLOB_LABEL); + + if (refqt_ret != SGX_QL_SUCCESS) { + // Don't need to error since the blob is still good in memory. + ///todo: What is the best way to notify the requester that the blob was not stored? + SE_TRACE(SE_TRACE_WARNING, "Warning, unable to store resealed ECDSA blob to persistent storage.\n"); + SE_TRACE(SE_TRACE_DEBUG, "File storage is not required for the QE_Library. Library will use ECDSA Blob cached in memory.\n"); + refqt_ret = SGX_QL_SUCCESS; + } + } + SE_TRACE(SE_TRACE_DEBUG, "Using ECDSA_ID:\n"); + PRINT_BYTE_ARRAY(SE_TRACE_DEBUG, (uint8_t *)&blob_ecdsa_id, sizeof(blob_ecdsa_id)); + + // Call into the PCE to get the current platform's PCE ISVSVN + pce_error = sgx_pce_get_target(&pce_target_info, + &cur_pce_isv_svn); + if (SGX_PCE_SUCCESS != pce_error) { + SE_TRACE(SE_TRACE_ERROR, "Error in call to sgx_pce_get_target(). 0x%04x\n", pce_error); + refqt_ret = translate_pce_errors(pce_error); + goto CLEANUP; + } + + // See if we can get the certification data from the platform library. + p_sealed_ecdsa = reinterpret_cast(g_ql_global_data.m_ecdsa_blob); + p_seal_data_plain_text = reinterpret_cast(g_ql_global_data.m_ecdsa_blob + sizeof(sgx_sealed_data_t) + p_sealed_ecdsa->plain_text_offset); + cert_data_size = 0; + pck_cert_id.p_qe3_id = (uint8_t*)&p_seal_data_plain_text->qe_id; + pck_cert_id.qe3_id_size = sizeof(p_seal_data_plain_text->qe_id); + pck_cert_id.p_platform_cpu_svn = &tdqe_report_body.cpu_svn; + pck_cert_id.p_platform_pce_isv_svn = &cur_pce_isv_svn; + pck_cert_id.p_encrypted_ppid = NULL; + pck_cert_id.encrypted_ppid_size = 0; + pck_cert_id.crypto_suite = PCE_ALG_RSA_OAEP_3072; + pck_cert_id.pce_id = p_seal_data_plain_text->cert_pce_info.pce_id; + refqt_ret = get_platform_quote_cert_data(&pck_cert_id, + &pce_cert_psvn.cpu_svn, + &pce_cert_psvn.isv_svn, + &cert_data_size, + NULL); + if (refqt_ret == SGX_QL_SUCCESS) { + // Verify that the cert_data_size is reasonable. + if((cert_data_size > MAX_CERT_DATA_SIZE) || + (cert_data_size < MIN_CERT_DATA_SIZE)) { + refqt_ret = SGX_QL_ATT_KEY_CERT_DATA_INVALID; + goto CLEANUP; + } + // malloc the buffer to get the cert data and call again + p_certification_data = (sgx_ql_certification_data_t *)malloc(sizeof(*p_certification_data) + cert_data_size); + if(NULL == p_certification_data) { + refqt_ret = SGX_QL_ERROR_OUT_OF_MEMORY; + goto CLEANUP; + + } + memset(p_certification_data, 0, sizeof(*p_certification_data)); + refqt_ret = get_platform_quote_cert_data(&pck_cert_id, + &pce_cert_psvn.cpu_svn, + &pce_cert_psvn.isv_svn, + &cert_data_size, + p_certification_data->certification_data); + if (refqt_ret != SGX_QL_SUCCESS) { + // Really shouldn't fail here if we passed the first call. + refqt_ret = SGX_QL_ERROR_UNEXPECTED; + goto CLEANUP; + } + //Check to make sure that the TCBm of from the platform library matches the Cert TCB in the ECDSA blob. + if((0 != memcmp(&p_seal_data_plain_text->cert_cpu_svn, &pce_cert_psvn.cpu_svn, sizeof(p_seal_data_plain_text->cert_cpu_svn))) || + (p_seal_data_plain_text->cert_pce_info.pce_isv_svn != pce_cert_psvn.isv_svn)) { + SE_TRACE(SE_TRACE_ERROR, "TCBm in ECDSA blob doesn't match the value returned by the platform lib. %d and %d\n", p_seal_data_plain_text->cert_pce_info.pce_isv_svn, pce_cert_psvn.isv_svn); + refqt_ret = SGX_QL_ATT_KEY_NOT_INITIALIZED; + goto CLEANUP; + } + //Verify that the size of the quote is large enough to accomodate the cert data returned from the platform library + if(quote_size < (sizeof(sgx_quote4_t) + + sizeof(sgx_ecdsa_sig_data_v4_t) + + sizeof(sgx_ql_auth_data_t) + + REF_ECDSDA_AUTHENTICATION_DATA_SIZE + + sizeof(sgx_ql_certification_data_t) + + sizeof(sgx_ql_certification_data_t) + + sizeof(sgx_qe_report_certification_data_t) + + cert_data_size)) { + refqt_ret = SGX_QL_ERROR_INVALID_PARAMETER; + goto CLEANUP; + } + p_certification_data->cert_key_type = PCK_CERT_CHAIN; + p_certification_data->size = cert_data_size; + } + else + { + if (refqt_ret != SGX_QL_PLATFORM_LIB_UNAVAILABLE) { + // The dependent library was found but it returned an error + goto CLEANUP; + } + // Generate the quote with ECDSA blob's cert data. It is possible that the ECDSA blob's data contains the mapped + // TCB of a previously successful call to the platform lib API. In that case, this flow will not generate + // the signature based on the raw-TCB. This would be an 'unexpected' error flow since it is expected that if + // the library was available before it should be available now. + // + // This is the normal flow when there is no provider library. + refqt_ret = SGX_QL_SUCCESS; + } + + SE_TRACE(SE_TRACE_DEBUG, "Call TDQE gen_quote\n"); + sgx_status = gen_quote(tdqe_eid, + (uint32_t*)&tdqe_error, + (uint8_t*)g_ql_global_data.m_ecdsa_blob, + (uint32_t)sizeof(g_ql_global_data.m_ecdsa_blob), + p_app_report, + NULL, + NULL, + NULL, + (uint8_t*)p_quote, + quote_size, + (uint8_t*)p_certification_data, + p_certification_data ? (uint32_t)(sizeof(*p_certification_data) + cert_data_size) : 0); + if (SGX_SUCCESS != sgx_status) { + SE_TRACE(SE_TRACE_ERROR, "Failed call into the TDQE. 0x%04x\n", sgx_status); + ///todo: May want to retry on SGX_ERROR_ENCLAVE_LOST caused by power transition + refqt_ret = (quote3_error_t)sgx_status; + goto CLEANUP; + } + if (TDQE_SUCCESS != tdqe_error) { + SE_TRACE(SE_TRACE_ERROR, "Gen Quote failed. 0x%04x\n", tdqe_error); + refqt_ret = (quote3_error_t)tdqe_error; + goto CLEANUP; + } + SE_TRACE(SE_TRACE_DEBUG, "Get quote success\n"); + + CLEANUP: + if(NULL != p_certification_data) { + free(p_certification_data); + } + + if(0 != blob_mutex_rc ) { + blob_mutex_rc = se_mutex_unlock(&g_ql_global_data.m_ecdsa_blob_mutex); + if (0 == blob_mutex_rc) { + SE_TRACE(SE_TRACE_ERROR, "Failed to unlock mutex"); + refqt_ret = SGX_QL_ERROR_UNEXPECTED; + } + } + + unload_qe(); + + return(refqt_ret); +} + +/** + * Set the load policy of TD QE and pce + * @param policy + * + * @return SGX_QL_SUCCESS + * @return SGX_QL_ERROR_UNEXPECTED + * + */ +quote3_error_t td_set_enclave_load_policy(sgx_ql_request_policy_t policy) +{ + quote3_error_t refqt_ret = SGX_QL_ERROR_UNEXPECTED; + sgx_pce_error_t pce_error; + int rc = 0; + + rc = se_mutex_lock(&g_ql_global_data.m_enclave_load_mutex); + if (0 == rc) { + SE_TRACE(SE_TRACE_ERROR, "Failed to lock mutex\n"); + refqt_ret = SGX_QL_ERROR_UNEXPECTED; + goto CLEANUP; + } + + g_ql_global_data.m_load_policy = policy; + refqt_ret = SGX_QL_SUCCESS; + + rc = se_mutex_unlock(&g_ql_global_data.m_enclave_load_mutex); + if (0 == rc) { + SE_TRACE(SE_TRACE_ERROR, "Failed to unlock mutex.\n"); + refqt_ret = SGX_QL_ERROR_UNEXPECTED; + } + pce_error = sgx_set_pce_enclave_load_policy(policy); + if (SGX_PCE_SUCCESS != pce_error) { + refqt_ret = translate_pce_errors(pce_error); + goto CLEANUP; + } + + CLEANUP: + + // Unload the qe if the policy was changed to ephemeral and the enclave is loaded. + unload_qe(); + + return(refqt_ret); +} + +/** + * Set the full path of TD QE + * + * @param p_path The full path of the TD QE + * + * @return SGX_QL_SUCCESS + * @return SGX_QL_ERROR_INVALID_PARAMETER + * + */ +quote3_error_t td_set_qe_path(const char* p_path) +{ + size_t len = 0; + if (NULL == p_path) { + return SGX_QL_ERROR_INVALID_PARAMETER; + } + len = strnlen(p_path, sizeof(g_ql_global_data.tdqe_path)); + // Make sure there is enough space for the '\0', + // after this line len <= sizeof(g_ql_global_data.tdqe_path) - 1 + if(len > sizeof(g_ql_global_data.tdqe_path) - 1) + return SGX_QL_ERROR_INVALID_PARAMETER; +#ifndef _MSC_VER + strncpy(g_ql_global_data.tdqe_path, p_path, sizeof(g_ql_global_data.tdqe_path) - 1); +#else + strncpy_s(g_ql_global_data.tdqe_path, sizeof(g_ql_global_data.tdqe_path), p_path, sizeof(g_ql_global_data.tdqe_path)); +#endif + g_ql_global_data.tdqe_path[len] = '\0'; + return SGX_QL_SUCCESS; +} + +/** + * Set the full path of QPL + * + * @param p_path The full path of the QPL + * + * @return SGX_QL_SUCCESS + * @return SGX_QL_ERROR_INVALID_PARAMETER + * + */ +quote3_error_t td_set_qpl_path(const char* p_path) +{ + size_t len = 0; + if (NULL == p_path) { + return SGX_QL_ERROR_INVALID_PARAMETER; + } + len = strnlen(p_path, sizeof(g_ql_global_data.qpl_path)); + // Make sure there is enough space for the '\0', + // after this line len <= sizeof(g_ql_global_data.qpl_path) - 1 + if(len > sizeof(g_ql_global_data.qpl_path) - 1) + return SGX_QL_ERROR_INVALID_PARAMETER; +#ifndef _MSC_VER + strncpy(g_ql_global_data.qpl_path, p_path, sizeof(g_ql_global_data.qpl_path) - 1); +#else + strncpy_s(g_ql_global_data.qpl_path, sizeof(g_ql_global_data.qpl_path), p_path, sizeof(g_ql_global_data.qpl_path)); +#endif + g_ql_global_data.qpl_path[len] = '\0'; + return SGX_QL_SUCCESS; +} + +quote3_error_t td_init_quote(sgx_ql_cert_key_type_t certification_key_type, + bool refresh_att_key) +{ + sgx_status_t sgx_status = SGX_SUCCESS; + tdqe_error_t tdqe_error = TDQE_SUCCESS; + quote3_error_t ret_val = SGX_QL_SUCCESS; + sgx_target_info_t tdqe_target_info; + ref_sha256_hash_t hash = {0}; + + memset(&tdqe_target_info, 0, sizeof(tdqe_target_info)); + ret_val = ecdsa_init_quote(certification_key_type, &tdqe_target_info, refresh_att_key, &hash); + if(SGX_QL_SUCCESS != ret_val) { + if((ret_val < SGX_QL_ERROR_MIN) || + (ret_val > SGX_QL_ERROR_MAX)) + { + sgx_status = (sgx_status_t)ret_val; + tdqe_error = (tdqe_error_t)ret_val; + + // Translate TDQE errors + switch(tdqe_error) + { + case TDQE_ERROR_INVALID_PARAMETER: + ret_val = SGX_QL_ERROR_INVALID_PARAMETER; + break; + + case TDQE_ERROR_OUT_OF_MEMORY: + ret_val = SGX_QL_ERROR_OUT_OF_MEMORY; + break; + + case TDQE_ERROR_UNEXPECTED: + case TDQE_ERROR_CRYPTO: // Error generating the QE_ID (or decypting PPID not supported in release). Unexpected error. + case TDQE_ERROR_ATT_KEY_GEN: // Error generating the ECDSA Attestation key. + case TDQE_ECDSABLOB_ERROR: // Should be unexpected since the blob was either generated or regenerated during this call + ret_val = SGX_QL_ERROR_UNEXPECTED; + break; + + default: + // Translate SDK errors + switch (sgx_status) + { + case SGX_ERROR_INVALID_PARAMETER: + ret_val = SGX_QL_ERROR_INVALID_PARAMETER; + break; + + case SGX_ERROR_OUT_OF_MEMORY: + ret_val = SGX_QL_ERROR_OUT_OF_MEMORY; + break; + + case SGX_ERROR_ENCLAVE_FILE_ACCESS: + ret_val = SGX_QL_ENCLAVE_LOAD_ERROR; + break; + + case SGX_ERROR_ENCLAVE_LOST: + ret_val = SGX_QL_ENCLAVE_LOST; + break; + + // Unexpected enclave loading errorsReturn codes from load_qe + case SGX_ERROR_INVALID_ENCLAVE: + case SGX_ERROR_UNDEFINED_SYMBOL: + case SGX_ERROR_MODE_INCOMPATIBLE: + case SGX_ERROR_INVALID_METADATA: + case SGX_ERROR_MEMORY_MAP_CONFLICT: + case SGX_ERROR_INVALID_VERSION: + case SGX_ERROR_INVALID_ATTRIBUTE: + case SGX_ERROR_NDEBUG_ENCLAVE: + case SGX_ERROR_INVALID_MISC: + //case SE_ERROR_INVALID_LAUNCH_TOKEN: ///todo: Internal error should be scrubbed before here. + case SGX_ERROR_DEVICE_BUSY: + case SGX_ERROR_NO_DEVICE: + case SGX_ERROR_INVALID_SIGNATURE: + //case SE_ERROR_INVALID_MEASUREMENT: ///todo: Internal error should be scrubbed before here. + //case SE_ERROR_INVALID_ISVSVNLE: ///todo: Internal error should be scrubbed before here. + case SGX_ERROR_INVALID_ENCLAVE_ID: + ret_val = SGX_QL_ENCLAVE_LOAD_ERROR; + break; + case SGX_ERROR_SERVICE_INVALID_PRIVILEGE: + ret_val = SGX_QL_ERROR_INVALID_PRIVILEGE; + break; + + case SGX_ERROR_UNEXPECTED: + ret_val = SGX_QL_ERROR_UNEXPECTED; + break; + + default: + ret_val = SGX_QL_ERROR_UNEXPECTED; + break; + } + break; + } + } + } + + return(ret_val); +} + + +quote3_error_t td_get_quote_size(sgx_ql_cert_key_type_t certification_key_type, + uint32_t *p_quote_size) +{ + sgx_status_t sgx_status = SGX_SUCCESS; + quote3_error_t ret_val = SGX_QL_SUCCESS; + + ret_val = ecdsa_get_quote_size(certification_key_type, p_quote_size); + if(SGX_QL_SUCCESS != ret_val) { + if((ret_val < SGX_QL_ERROR_MIN) || + (ret_val > SGX_QL_ERROR_MAX)) + { + sgx_status = (sgx_status_t)ret_val; + + // Translate SDK errors + switch(sgx_status) + { + case SGX_ERROR_OUT_OF_MEMORY: + ret_val = SGX_QL_ERROR_OUT_OF_MEMORY; + break; + + case SGX_ERROR_ENCLAVE_FILE_ACCESS: + ret_val = SGX_QL_ENCLAVE_LOAD_ERROR; + break; + + // Unexpected enclave loading errorsReturn codes from load_qe + case SGX_ERROR_INVALID_ENCLAVE: + case SGX_ERROR_UNDEFINED_SYMBOL: + case SGX_ERROR_MODE_INCOMPATIBLE: + case SGX_ERROR_INVALID_METADATA: + case SGX_ERROR_MEMORY_MAP_CONFLICT: + case SGX_ERROR_INVALID_VERSION: + case SGX_ERROR_INVALID_ATTRIBUTE: + case SGX_ERROR_NDEBUG_ENCLAVE: + case SGX_ERROR_INVALID_MISC: + //case SE_ERROR_INVALID_LAUNCH_TOKEN: ///todo: Internal error should be scrubbed before here. + case SGX_ERROR_DEVICE_BUSY: + case SGX_ERROR_NO_DEVICE: + case SGX_ERROR_INVALID_SIGNATURE: + //case SE_ERROR_INVALID_MEASUREMENT: ///todo: Internal error should be scrubbed before here. + //case SE_ERROR_INVALID_ISVSVNLE: ///todo: Internal error should be scrubbed before here. + case SGX_ERROR_INVALID_ENCLAVE_ID: + ret_val = SGX_QL_ENCLAVE_LOAD_ERROR; + break; + case SGX_ERROR_SERVICE_INVALID_PRIVILEGE: + ret_val = SGX_QL_ERROR_INVALID_PRIVILEGE; + break; + + case SGX_ERROR_ENCLAVE_LOST: + ret_val = SGX_QL_ENCLAVE_LOST; + break; + + case SGX_ERROR_UNEXPECTED: + ret_val = SGX_QL_ERROR_UNEXPECTED; + break; + + default: + ret_val = SGX_QL_ERROR_UNEXPECTED; + break; + } + } + } + + return(ret_val); +} + + +quote3_error_t td_get_quote( + const sgx_report2_t *p_app_report, + sgx_quote4_t *p_quote, + uint32_t quote_size) +{ + sgx_status_t sgx_status = SGX_SUCCESS; + tdqe_error_t tdqe_error = TDQE_SUCCESS; + quote3_error_t ret_val = SGX_QL_SUCCESS; + + ret_val = ecdsa_get_quote(p_app_report, p_quote, quote_size); + if(SGX_QL_SUCCESS != ret_val) { + if((ret_val < SGX_QL_ERROR_MIN) || + (ret_val > SGX_QL_ERROR_MAX)) + { + sgx_status = (sgx_status_t)ret_val; + tdqe_error = (tdqe_error_t)ret_val; + + // Translate TDQE errors + switch(tdqe_error) + { + case TDQE_ERROR_INVALID_PARAMETER: + ret_val = SGX_QL_ERROR_INVALID_PARAMETER; + break; + + case TDQE_ERROR_INVALID_REPORT: + ret_val = SGX_QL_INVALID_REPORT; + break; + + case TDQE_ERROR_CRYPTO: + // Error generating QE_ID. Shouldn't happen + ret_val = SGX_QL_ERROR_UNEXPECTED; + break; + + case TDQE_ERROR_OUT_OF_MEMORY: + ret_val = SGX_QL_ERROR_OUT_OF_MEMORY; + break; + + case TDQE_UNABLE_TO_GENERATE_QE_REPORT: + ret_val = SGX_QL_UNABLE_TO_GENERATE_QE_REPORT; + break; + + case TDQE_REPORT_FORMAT_NOT_SUPPORTED: + ret_val = SGX_QL_QE_REPORT_UNSUPPORTED_FORMAT; + break; + + default: + // Translate SDK errors + switch (sgx_status) + { + case SGX_ERROR_INVALID_PARAMETER: + ret_val = SGX_QL_ERROR_INVALID_PARAMETER; + break; + + case SGX_ERROR_ENCLAVE_FILE_ACCESS: + ret_val = SGX_QL_ENCLAVE_LOAD_ERROR; + break; + + case SGX_ERROR_OUT_OF_MEMORY: + ret_val = SGX_QL_ERROR_OUT_OF_MEMORY; + break; + + case SGX_ERROR_ENCLAVE_LOST: + ret_val = SGX_QL_ENCLAVE_LOST; + break; + + // Unexpected enclave loading errorsReturn codes from load_qe + case SGX_ERROR_INVALID_ENCLAVE: + case SGX_ERROR_UNDEFINED_SYMBOL: + case SGX_ERROR_MODE_INCOMPATIBLE: + case SGX_ERROR_INVALID_METADATA: + case SGX_ERROR_MEMORY_MAP_CONFLICT: + case SGX_ERROR_INVALID_VERSION: + case SGX_ERROR_INVALID_ATTRIBUTE: + case SGX_ERROR_NDEBUG_ENCLAVE: + case SGX_ERROR_INVALID_MISC: + //case SE_ERROR_INVALID_LAUNCH_TOKEN: ///todo: Internal error should be scrubbed before here. + case SGX_ERROR_DEVICE_BUSY: + case SGX_ERROR_NO_DEVICE: + case SGX_ERROR_INVALID_SIGNATURE: + //case SE_ERROR_INVALID_MEASUREMENT: ///todo: Internal error should be scrubbed before here. + //case SE_ERROR_INVALID_ISVSVNLE: ///todo: Internal error should be scrubbed before here. + case SGX_ERROR_INVALID_ENCLAVE_ID: + ret_val = SGX_QL_ENCLAVE_LOAD_ERROR; + break; + case SGX_ERROR_SERVICE_INVALID_PRIVILEGE: + ret_val = SGX_QL_ERROR_INVALID_PRIVILEGE; + break; + + case SGX_ERROR_UNEXPECTED: + ret_val = SGX_QL_ERROR_UNEXPECTED; + break; + + default: + ret_val = SGX_QL_ERROR_UNEXPECTED; + break; + } + break; + } + } + } + + return(ret_val); +} + diff --git a/QuoteGeneration/quote_wrapper/tdx_quote/td_ql_logic.h b/QuoteGeneration/quote_wrapper/tdx_quote/td_ql_logic.h new file mode 100644 index 00000000..84216239 --- /dev/null +++ b/QuoteGeneration/quote_wrapper/tdx_quote/td_ql_logic.h @@ -0,0 +1,64 @@ +/* + * Copyright (C) 2011-2021 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: td_ql_logic.h + * + * Description: API definitions for TD quote library + * + */ +#ifndef _TD_QL_LOGIC_H_ +#define _TD_QL_LOGIC_H_ +#include "sgx_ql_lib_common.h" +#include "sgx_quote_4.h" + +#if defined(__cplusplus) +extern "C" { +#endif +quote3_error_t td_set_enclave_load_policy(sgx_ql_request_policy_t policy); + +quote3_error_t td_init_quote(sgx_ql_cert_key_type_t certification_key_type, + bool refresh_att_key); +quote3_error_t td_get_quote_size(sgx_ql_cert_key_type_t certification_key_type, + uint32_t *p_quote_size); +quote3_error_t td_get_quote(const sgx_report2_t *p_app_report, + sgx_quote4_t *p_quote, + uint32_t quote_size); + +quote3_error_t td_set_qe_path(const char *p_path); +quote3_error_t td_set_qpl_path(const char *p_path); +void *get_qpl_handle(); +#if defined(__cplusplus) +} +#endif + + +#endif + diff --git a/QuoteGeneration/quote_wrapper/tdx_quote/win/dllmain.cpp b/QuoteGeneration/quote_wrapper/tdx_quote/win/dllmain.cpp new file mode 100644 index 00000000..160e1588 --- /dev/null +++ b/QuoteGeneration/quote_wrapper/tdx_quote/win/dllmain.cpp @@ -0,0 +1,22 @@ +// dllmain.cpp : Defines the entry point for the DLL application. +#include +#include "util.h" + +BOOL APIENTRY DllMain( HMODULE hModule, + DWORD ul_reason_for_call, + LPVOID lpReserved + ) +{ + UNUSED(hModule); + UNUSED(lpReserved); + switch (ul_reason_for_call) + { + case DLL_PROCESS_ATTACH: + case DLL_THREAD_ATTACH: + case DLL_THREAD_DETACH: + case DLL_PROCESS_DETACH: + break; + } + return TRUE; +} + diff --git a/QuoteGeneration/quote_wrapper/tdx_quote/win/framework.h b/QuoteGeneration/quote_wrapper/tdx_quote/win/framework.h new file mode 100644 index 00000000..54b83e94 --- /dev/null +++ b/QuoteGeneration/quote_wrapper/tdx_quote/win/framework.h @@ -0,0 +1,5 @@ +#pragma once + +#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers +// Windows Header Files +#include diff --git a/QuoteGeneration/quote_wrapper/tdx_quote/win/resource.h b/QuoteGeneration/quote_wrapper/tdx_quote/win/resource.h new file mode 100644 index 00000000..0c237bae --- /dev/null +++ b/QuoteGeneration/quote_wrapper/tdx_quote/win/resource.h @@ -0,0 +1,15 @@ +//{{NO_DEPENDENCIES}} +// Microsoft Visual C++ generated include file. +// Used by tdx_logic.rc +// + +// Next default values for new objects +// +#ifdef APSTUDIO_INVOKED +#ifndef APSTUDIO_READONLY_SYMBOLS +#define _APS_NEXT_RESOURCE_VALUE 101 +#define _APS_NEXT_COMMAND_VALUE 40001 +#define _APS_NEXT_CONTROL_VALUE 1001 +#define _APS_NEXT_SYMED_VALUE 101 +#endif +#endif diff --git a/QuoteGeneration/quote_wrapper/tdx_quote/win/tdx_logic.def b/QuoteGeneration/quote_wrapper/tdx_quote/win/tdx_logic.def new file mode 100644 index 00000000..8b49bc64 --- /dev/null +++ b/QuoteGeneration/quote_wrapper/tdx_quote/win/tdx_logic.def @@ -0,0 +1,9 @@ +LIBRARY "sgx_tdx_logic" + +EXPORTS + td_set_enclave_load_policy @1 + td_set_qe_path @2 + td_set_qpl_path @3 + td_init_quote @4 + td_get_quote_size @5 + td_get_quote @6 diff --git a/QuoteGeneration/quote_wrapper/tdx_quote/win/tdx_logic.rc b/QuoteGeneration/quote_wrapper/tdx_quote/win/tdx_logic.rc new file mode 100644 index 00000000..6bede01f Binary files /dev/null and b/QuoteGeneration/quote_wrapper/tdx_quote/win/tdx_logic.rc differ diff --git a/QuoteGeneration/quote_wrapper/tdx_quote/win/tdx_logic.vcxproj b/QuoteGeneration/quote_wrapper/tdx_quote/win/tdx_logic.vcxproj new file mode 100644 index 00000000..4507350d --- /dev/null +++ b/QuoteGeneration/quote_wrapper/tdx_quote/win/tdx_logic.vcxproj @@ -0,0 +1,256 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + + 16.0 + {DF76228C-AA18-41D2-ABF6-E340AE2B6591} + Win32Proj + tdxlogic + 10.0.18362.0 + + + + DynamicLibrary + true + v142 + Unicode + + + DynamicLibrary + false + v142 + true + Unicode + + + DynamicLibrary + true + v142 + Unicode + + + DynamicLibrary + false + v142 + true + Unicode + + + + + + + + + + + + + + + + + + + + + false + sgx_tdx_logic + + + true + sgx_tdx_logic + + + true + sgx_tdx_logic + + + false + sgx_tdx_logic + + + + NotUsing + Level4 + true + true + true + NDEBUG;TDXLOGIC_EXPORTS;_WINDOWS;_USRDLL;DISABLE_TRACE;%(PreprocessorDefinitions) + false + $(SGXSDKInstallPath)\include;.;..\inc;..\..\common\inc;..\enclave;..\..\..\pce_wrapper\inc;..\..\..\common\inc\internal;..\..\..\common\inc\internal\win;%(AdditionalIncludeDirectories) + true + true + MultiThreaded + + + Windows + true + true + true + true + tdx_logic.def + true + sgx_urts.lib;sgx_pce_wrapper_static.lib;%(AdditionalDependencies) + $(OutDir);$(SGXSDKInstallPath)bin\$(Platform)\$(Configuration) + + + "$(SGXSDKInstallPath)\bin\win32\Release\sgx_edger8r.exe" ..\enclave\tdqe.edl --search-path ..\..\..\common\inc --untrusted +"$(SGXSDKInstallPath)\bin\win32\Release\sgx_edger8r.exe" ..\..\quote\id_enclave\id_enclave.edl --search-path ..\..\..\common\inc --untrusted + + + "C:\Program Files (x86)\Windows Kits\10\bin\$(PlatformTarget)\apivalidator.exe" -driverpackagepath:"$(TargetPath)" -SupportedApiXmlFiles:"C:\Program Files (x86)\Windows Kits\10\build\universalDDIs\$(PlatformTarget)\UniversalDDIs.xml" -ModuleWhiteListXmlFiles:"C:\Program Files (x86)\Windows Kits\10\build\universalDDIs\$(PlatformTarget)\ModuleWhiteList.xml" >"$(OutDir)api_validator_log.txt" 2>&1 + + + + + NotUsing + Level4 + true + SE_DEBUG;_DEBUG;_WINDOWS;_USRDLL;TDXLOGIC_EXPORTS;WIN32;%(PreprocessorDefinitions) + false + $(SGXSDKInstallPath)\include;.;..\inc;..\..\common\inc;..\enclave;..\..\..\pce_wrapper\inc;..\..\..\common\inc\internal;..\..\..\common\inc\internal\win;%(AdditionalIncludeDirectories) + true + true + MultiThreadedDebug + + + Windows + true + true + tdx_logic.def + true + sgx_urts.lib;sgx_pce_wrapper_static.lib;%(AdditionalDependencies) + $(OutDir);$(SGXSDKInstallPath)bin\$(Platform)\$(Configuration) + + + "$(SGXSDKInstallPath)\bin\win32\Release\sgx_edger8r.exe" ..\enclave\tdqe.edl --search-path ..\..\..\common\inc --untrusted +"$(SGXSDKInstallPath)\bin\win32\Release\sgx_edger8r.exe" ..\..\quote\id_enclave\id_enclave.edl --search-path ..\..\..\common\inc --untrusted + + + + + NotUsing + Level4 + true + SE_DEBUG;_DEBUG;_WINDOWS;_USRDLL;TDXLOGIC_EXPORTS;%(PreprocessorDefinitions) + false + $(SGXSDKInstallPath)\include;.;..\inc;..\..\common\inc;..\enclave;..\..\..\pce_wrapper\inc;..\..\..\common\inc\internal;..\..\..\common\inc\internal\win;%(AdditionalIncludeDirectories) + true + true + MultiThreadedDebug + + + Windows + true + true + tdx_logic.def + true + sgx_urts.lib;sgx_pce_wrapper_static.lib;%(AdditionalDependencies) + $(OutDir);$(SGXSDKInstallPath)bin\$(Platform)\$(Configuration) + + + "$(SGXSDKInstallPath)\bin\win32\Release\sgx_edger8r.exe" ..\enclave\tdqe.edl --search-path ..\..\..\common\inc --untrusted +"$(SGXSDKInstallPath)\bin\win32\Release\sgx_edger8r.exe" ..\..\quote\id_enclave\id_enclave.edl --search-path ..\..\..\common\inc --untrusted + + + + + NotUsing + Level4 + true + true + true + NDEBUG;TDXLOGIC_EXPORTS;_WINDOWS;_USRDLL;DISABLE_TRACE;WIN32;%(PreprocessorDefinitions) + false + $(SGXSDKInstallPath)\include;.;..\inc;..\..\common\inc;..\enclave;..\..\..\pce_wrapper\inc;..\..\..\common\inc\internal;..\..\..\common\inc\internal\win;%(AdditionalIncludeDirectories) + true + true + MultiThreaded + + + Windows + true + true + true + true + tdx_logic.def + true + sgx_urts.lib;sgx_pce_wrapper_static.lib;%(AdditionalDependencies) + $(OutDir);$(SGXSDKInstallPath)bin\$(Platform)\$(Configuration) + + + "$(SGXSDKInstallPath)\bin\win32\Release\sgx_edger8r.exe" ..\enclave\tdqe.edl --search-path ..\..\..\common\inc --untrusted +"$(SGXSDKInstallPath)\bin\win32\Release\sgx_edger8r.exe" ..\..\quote\id_enclave\id_enclave.edl --search-path ..\..\..\common\inc --untrusted + + + "C:\Program Files (x86)\Windows Kits\10\bin\$(PlatformTarget)\apivalidator.exe" -driverpackagepath:"$(TargetPath)" -SupportedApiXmlFiles:"C:\Program Files (x86)\Windows Kits\10\build\universalDDIs\$(PlatformTarget)\UniversalDDIs.xml" -ModuleWhiteListXmlFiles:"C:\Program Files (x86)\Windows Kits\10\build\universalDDIs\$(PlatformTarget)\ModuleWhiteList.xml" >"$(OutDir)api_validator_log.txt" 2>&1 + + + + + + + + + + + + + + + + + + + + + + + + + + + ..\..\..\common\inc\internal + ..\..\..\common\inc\internal + ..\..\..\common\inc\internal + ..\..\..\common\inc\internal + + + + + Document + Creating untrusted proxy/bridge routines + Creating untrusted proxy/bridge routines + Creating untrusted proxy/bridge routines + Creating untrusted proxy/bridge routines + $(ProjectDir)%(Filename)_u.h;$(ProjectDir)%(Filename)_u.c;%(Outputs) + $(ProjectDir)%(Filename)_u.h;$(ProjectDir)%(Filename)_u.c;%(Outputs) + $(ProjectDir)%(Filename)_u.h;$(ProjectDir)%(Filename)_u.c;%(Outputs) + $(ProjectDir)%(Filename)_u.h;$(ProjectDir)%(Filename)_u.c;%(Outputs) + + + + + + + + + \ No newline at end of file diff --git a/QuoteGeneration/quote_wrapper/tdx_quote/win/tdx_logic.vcxproj.filters b/QuoteGeneration/quote_wrapper/tdx_quote/win/tdx_logic.vcxproj.filters new file mode 100644 index 00000000..a92883de --- /dev/null +++ b/QuoteGeneration/quote_wrapper/tdx_quote/win/tdx_logic.vcxproj.filters @@ -0,0 +1,64 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;c++;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + {004685B6-BAF2-4621-B736-E736B36FBA18} + + + + + Header Files + + + Generated Files + + + Header Files + + + Header Files + + + Generated Files + + + + + Source Files + + + Source Files + + + Generated Files + + + Generated Files + + + + + Resource Files + + + + + + + + Source Files + + + diff --git a/QuoteVerification/QVL/Src/AttestationLibrary/src/Verifiers/QuoteVerifier.cpp b/QuoteVerification/QVL/Src/AttestationLibrary/src/Verifiers/QuoteVerifier.cpp index 067d31b2..06d96f82 100644 --- a/QuoteVerification/QVL/Src/AttestationLibrary/src/Verifiers/QuoteVerifier.cpp +++ b/QuoteVerification/QVL/Src/AttestationLibrary/src/Verifiers/QuoteVerifier.cpp @@ -83,7 +83,7 @@ bool isTdxTcbHigherOrEqual(const dcap::quote::TDReport& tdReport, // but for TCB level to be considered higher it requires *EVERY* SVN to be higher or equal return true; } -const std::string& getMatchingTcbLevel(const dcap::parser::json::TcbInfo &tcbInfo, +const parser::json::TcbLevel& getMatchingTcbLevel(const dcap::parser::json::TcbInfo &tcbInfo, const dcap::parser::x509::PckCertificate &pckCert, const Quote "e) { @@ -100,12 +100,12 @@ const std::string& getMatchingTcbLevel(const dcap::parser::json::TcbInfo &tcbInf { if (isTdxTcbHigherOrEqual(quote.getTdReport(), tcb)) { - return tcb.getStatus(); + return tcb; } } else { - return tcb.getStatus(); + return tcb; } } } @@ -118,7 +118,15 @@ Status checkTcbLevel(const dcap::parser::json::TcbInfo& tcbInfoJson, const dcap: const Quote& quote) { /// 4.1.2.4.17.1 & 4.1.2.4.17.2 - const auto& tcbLevelStatus = getMatchingTcbLevel(tcbInfoJson, pckCert, quote); + const auto& tcbLevel = getMatchingTcbLevel(tcbInfoJson, pckCert, quote); + + if (tcbInfoJson.getVersion() >= 3 && tcbInfoJson.getId() == parser::json::TcbInfo::TDX_ID + && tcbLevel.getTdxTcbComponent(1).getSvn() != quote.getTdReport().teeTcbSvn[1]) + { + return STATUS_TCB_INFO_MISMATCH; + } + + const auto& tcbLevelStatus = tcbLevel.getStatus(); if (tcbLevelStatus == "OutOfDate") { @@ -386,6 +394,11 @@ Status QuoteVerifier::verify(const Quote& quote, /// 4.1.2.4.17 const auto tcbLevelStatus = checkTcbLevel(tcbInfoJson, pckCert, quote); + if (tcbLevelStatus == STATUS_TCB_INFO_MISMATCH) + { + return STATUS_TCB_INFO_MISMATCH; + } + if (enclaveIdentity) { return convergeTcbStatus(tcbLevelStatus, qeIdentityStatus); diff --git a/QuoteVerification/QVL/Src/AttestationLibrary/test/IntegrationTests/VerifyQuoteIT.cpp b/QuoteVerification/QVL/Src/AttestationLibrary/test/IntegrationTests/VerifyQuoteIT.cpp index 7b4b82a6..69a12eaa 100644 --- a/QuoteVerification/QVL/Src/AttestationLibrary/test/IntegrationTests/VerifyQuoteIT.cpp +++ b/QuoteVerification/QVL/Src/AttestationLibrary/test/IntegrationTests/VerifyQuoteIT.cpp @@ -105,6 +105,7 @@ struct VerifyQuoteIT : public Test string positiveTdxTcbInfoV3JsonBody; string positiveSgxTcbInfoV3JsonBody; string positiveQEIdentityV2JsonBody; + std::vector tdxTcbLevels; test::QuoteV3Generator::EnclaveReport enclaveReport; @@ -140,7 +141,7 @@ struct VerifyQuoteIT : public Test positiveSgxTcbInfoV3JsonBody = tcbInfoJsonV3Body("SGX", 3, issueDate, nextUpdate, fmspcStr, pceIdStr, 1, 1, sgxTcbLevels, false, tdxModule); - std::vector tdxTcbLevels; + tdxTcbLevels.push_back(TcbLevelV3{ getRandomTcbComponent(), getRandomTcbComponent(), @@ -605,7 +606,7 @@ TEST_F(VerifyQuoteIT, shouldReturnedStatusOKWhenVerifyTdxQuoteV4Successffuly) quoteV4Generator.getHeader().teeType = constants::TEE_TYPE_TDX; std::copy_n(tdxModule.mrsigner.begin(), tdxModule.mrsigner.size(), quoteV4Generator.getTdReport().mrSignerSeam.begin()); quoteV4Generator.getTdReport().seamAttributes.fill(0x00); - quoteV4Generator.getTdReport().teeTcbSvn = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,}; + quoteV4Generator.getTdReport().teeTcbSvn = {0xFF, tdxTcbLevels[0].tdxTcbComponents[1].svn, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,}; test::QuoteV4Generator::EnclaveReport qeReport{}; @@ -675,7 +676,7 @@ TEST_F(VerifyQuoteIT, shouldReturnedStatusTdxModuleMismatchWhenVerifyTdxQuoteV4W quoteV4Generator.getHeader().teeType = constants::TEE_TYPE_TDX; quoteV4Generator.getTdReport().mrSignerSeam.fill(0x01); quoteV4Generator.getTdReport().seamAttributes.fill(0x00); - quoteV4Generator.getTdReport().teeTcbSvn = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,}; + quoteV4Generator.getTdReport().teeTcbSvn = {0xFF, tdxTcbLevels[0].tdxTcbComponents[1].svn, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,}; test::QuoteV4Generator::EnclaveReport qeReport{}; @@ -739,7 +740,7 @@ TEST_F(VerifyQuoteIT, shouldReturnedStatusTdxModuleMismatchWhenVerifyTdxQuoteV4W quoteV4Generator.getHeader().teeType = constants::TEE_TYPE_TDX; quoteV4Generator.getTdReport().mrSignerSeam.fill(0x00); quoteV4Generator.getTdReport().seamAttributes.fill(0x01); - quoteV4Generator.getTdReport().teeTcbSvn = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,}; + quoteV4Generator.getTdReport().teeTcbSvn = {0xFF, tdxTcbLevels[0].tdxTcbComponents[1].svn, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,}; test::QuoteV4Generator::EnclaveReport qeReport{}; @@ -803,7 +804,7 @@ TEST_F(VerifyQuoteIT, shouldReturnedStatusOKWhenVerifyTdxQuoteV4WithoutQeIdentit quoteV4Generator.getHeader().teeType = constants::TEE_TYPE_TDX; std::copy_n(tdxModule.mrsigner.begin(), tdxModule.mrsigner.size(), quoteV4Generator.getTdReport().mrSignerSeam.begin()); quoteV4Generator.getTdReport().seamAttributes.fill(0x00); - quoteV4Generator.getTdReport().teeTcbSvn = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,}; + quoteV4Generator.getTdReport().teeTcbSvn = {0xFF, tdxTcbLevels[0].tdxTcbComponents[1].svn, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,}; test::QuoteV4Generator::EnclaveReport qeReport{}; diff --git a/QuoteVerification/QVL/Src/AttestationLibrary/test/UnitTests/QuoteV4VerifierUT.cpp b/QuoteVerification/QVL/Src/AttestationLibrary/test/UnitTests/QuoteV4VerifierUT.cpp index a9e66cb6..68b09344 100644 --- a/QuoteVerification/QVL/Src/AttestationLibrary/test/UnitTests/QuoteV4VerifierUT.cpp +++ b/QuoteVerification/QVL/Src/AttestationLibrary/test/UnitTests/QuoteV4VerifierUT.cpp @@ -276,7 +276,7 @@ TEST_F(QuoteV4VerifierUT, shouldVerifyTdxCorrectly) header.version = 4; header.teeType = dcap::constants::TEE_TYPE_TDX; auto tdReport = dcap::test::QuoteV4Generator::TDReport{}; - tdReport.teeTcbSvn = {0x50, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + tdReport.teeTcbSvn = {0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; gen.withTDReport(tdReport); gen.withHeader(header); @@ -294,6 +294,30 @@ TEST_F(QuoteV4VerifierUT, shouldVerifyTdxCorrectly) EXPECT_EQ(STATUS_OK, dcap::QuoteVerifier{}.verify(quote, pck, crl, tcbInfoJson, &enclaveIdentityV2, enclaveReportVerifier)); } +TEST_F(QuoteV4VerifierUT, shouldFailWithTcbInfoMismatchWhenTdxQuoteSvnDoesntMatchTcbInfo) +{ + auto header = dcap::test::QuoteV4Generator::QuoteHeader{}; + header.version = 4; + header.teeType = dcap::constants::TEE_TYPE_TDX; + auto tdReport = dcap::test::QuoteV4Generator::TDReport{}; + tdReport.teeTcbSvn = {0x50, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; + gen.withTDReport(tdReport); + gen.withHeader(header); + gen.getAuthData().ecdsaSignature.signature = signAndGetRaw(concat(gen.getHeader().bytes(), gen.getTdReport().bytes()), *privKey); + const auto quoteBin = gen.buildTdxQuote(); + + tcbs.insert(tcbs.begin(), dcap::parser::json::TcbLevel{"TDX", sgxTcbComponents, tdxTcbComponents, toUint16(pcesvn[1], pcesvn[0]), "UpToDate"}); + EXPECT_CALL(tcbInfoJson, getId()).WillRepeatedly(testing::Return("TDX")); + EXPECT_CALL(tcbInfoJson, getVersion()).WillRepeatedly(testing::Return(3)); + EXPECT_CALL(tcbInfoJson, getTcbLevels()).WillOnce(testing::ReturnRef(tcbs)); + EXPECT_CALL(enclaveIdentityV2, getID()).WillOnce(testing::Return(EnclaveID::TD_QE)); + + dcap::Quote quote; + ASSERT_TRUE(quote.parse(quoteBin)); + EXPECT_EQ(STATUS_TCB_INFO_MISMATCH, dcap::QuoteVerifier{}.verify(quote, pck, crl, tcbInfoJson, &enclaveIdentityV2, enclaveReportVerifier)); +} + TEST_F(QuoteV4VerifierUT, shouldVerifyTdxCorrectlyWhenTdReportSeamAttributesMaskedMatch) { auto header = dcap::test::QuoteV4Generator::QuoteHeader{}; @@ -301,7 +325,7 @@ TEST_F(QuoteV4VerifierUT, shouldVerifyTdxCorrectlyWhenTdReportSeamAttributesMask header.teeType = dcap::constants::TEE_TYPE_TDX; auto tdReport = dcap::test::QuoteV4Generator::TDReport{}; tdReport.seamAttributes = {0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; - tdReport.teeTcbSvn = {0x50, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + tdReport.teeTcbSvn = {0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; gen.withTDReport(tdReport); gen.withHeader(header); @@ -642,7 +666,7 @@ TEST_F(QuoteV4VerifierUT, shouldBackoffToLowerLevelBecauseTdReportTeeSvnIsOutOfD header.version = 4; header.teeType = dcap::constants::TEE_TYPE_TDX; auto tdReport = dcap::test::QuoteV4Generator::TDReport{}; - tdReport.teeTcbSvn = {0x50, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + tdReport.teeTcbSvn = {0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; gen.withTDReport(tdReport); gen.withHeader(header); @@ -668,13 +692,13 @@ TEST_F(QuoteV4VerifierUT, shouldBackoffToLowerLevelBecauseNoAllSvnsAreHigher) header.version = 4; header.teeType = dcap::constants::TEE_TYPE_TDX; auto tdReport = dcap::test::QuoteV4Generator::TDReport{}; - tdReport.teeTcbSvn = {0x50, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + tdReport.teeTcbSvn = {0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; gen.withTDReport(tdReport); gen.withHeader(header); gen.getAuthData().ecdsaSignature.signature = signAndGetRaw(concat(gen.getHeader().bytes(), gen.getTdReport().bytes()), *privKey); const auto quoteBin = gen.buildTdxQuote(); - std::vector tdxComponents = {0x50, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + std::vector tdxComponents = {0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 }; tcbs.insert(dcap::parser::json::TcbLevel{"TDX", sgxTcbComponents, tdxComponents, toUint16(pcesvn[1], pcesvn[0]), "UpToDate"}); tcbs.insert(dcap::parser::json::TcbLevel{"TDX", sgxTcbComponents, tdxTcbComponents, toUint16(pcesvn[1], pcesvn[0]), "OutOfDate"}); diff --git a/QuoteVerification/QVL/Src/CMakeLists.txt b/QuoteVerification/QVL/Src/CMakeLists.txt index ffb20a06..8656ee0b 100644 --- a/QuoteVerification/QVL/Src/CMakeLists.txt +++ b/QuoteVerification/QVL/Src/CMakeLists.txt @@ -151,7 +151,7 @@ set(HUNTER_STATUS_DEBUG OFF) #set to 'ON' to see debug hunter logs option(HUNTER_NO_TOOLCHAIN_ID_RECALCULATION "No Toolchain-ID recalculation" ON) option(HUNTER_KEEP_PACKAGE_SOURCES "Keep third party sources" ON) -include("ThirdParty/hunter/HunterGate.cmake") +include("${CMAKE_CURRENT_LIST_DIR}/ThirdParty/hunter/HunterGate.cmake") HunterGate( URL "https://github.com/cpp-pm/hunter/archive/v0.23.316.tar.gz" SHA1 "167a33c4cc398504826a1a3014ef66f9ccc35db3" @@ -348,6 +348,8 @@ if (BUILD_TESTS) if (CMAKE_BUILD_TYPE STREQUAL "Coverage") if(UNIX) + include(ProcessorCount) + ProcessorCount(N) set(COVFILE "${CMAKE_SOURCE_DIR}/sgx.cov") add_custom_target(cov_on @@ -366,7 +368,7 @@ if (BUILD_TESTS) COMMAND ${BULLSEYE_COV_XML} -f${COVFILE} -o${PROJECT_SOURCE_DIR}/code-coverage-report/coverage.xml --no-banner) add_custom_target(code-coverage - COMMAND COVFILE=${COVFILE} ${CMAKE_MAKE_PROGRAM} -C ${QVL_BUILD_DIR} -j1 cov_on runTests cov_off cov_html cov_xml) + COMMAND COVFILE=${COVFILE} $(MAKE) -j${N} -C ${QVL_BUILD_DIR} cov_on runTests cov_off cov_html cov_xml) else() message(FATAL_ERROR "Coverage build is only supported on Linux") endif() diff --git a/QuoteVerification/QvE/AttestationLibrary/AttestationLibrary.vcxproj b/QuoteVerification/QvE/AttestationLibrary/AttestationLibrary.vcxproj index 90fa17c1..fa6f021e 100644 --- a/QuoteVerification/QvE/AttestationLibrary/AttestationLibrary.vcxproj +++ b/QuoteVerification/QvE/AttestationLibrary/AttestationLibrary.vcxproj @@ -254,11 +254,13 @@ Level4 $(ProjectDir)..\..\QVL/Src/;$(ProjectDir)..\..\package\include;$(ProjectDir)..\..\QVL/Src/ThirdParty/rapidjson/include;$(ProjectDir)..\..\QVL/Src/AttestationCommons/include;$(ProjectDir)..\..\QVL/Src/AttestationCommons/include/Utils;$(ProjectDir)..\..\QVL/Src/AttestationLibrary/include;$(ProjectDir)..\..\QVL/Src/AttestationLibrary/src;$(ProjectDir)..\..\QVL/Src/AttestationParsers/include/;..\Include;$(ProjectDir)..\..\../QuoteGeneration/common/inc/internal;$(ProjectDir)..\..\../QuoteGeneration/quote_wrapper/common/inc;$(SGXSDKInstallPath)include;$(SGXSDKInstallPath)include\tlibc;$(SGXSDKInstallPath)include\libc++;$(SGXSDKInstallPath)include\epid;$(VCToolsInstallDir)\include;$(ProjectDir)..\..\QvE\Enclave;%(AdditionalIncludeDirectories) true - SGX_TRUSTED;_WINDOWS;_ATTESTATIONLIBRARY_EXPORTS + NDEBUG;SGX_TRUSTED;_WINDOWS;_ATTESTATIONLIBRARY_EXPORTS;OPENSSL_NO_FILENAMES true Guard 4101 /d2FH4- %(AdditionalOptions) + false + ProgramDatabase sgx_trts.lib;sgx_tstdc.lib;sgx_tservice.lib;sgx_tcxx.lib;sgx_tcrypto.lib @@ -268,6 +270,9 @@ + + /PDBALTPATH:AttestationLibrary.pdb %(AdditionalOptions) + diff --git a/QuoteVerification/QvE/AttestationParsers/AttestationParsers.vcxproj b/QuoteVerification/QvE/AttestationParsers/AttestationParsers.vcxproj index 45331d84..46247743 100644 --- a/QuoteVerification/QvE/AttestationParsers/AttestationParsers.vcxproj +++ b/QuoteVerification/QvE/AttestationParsers/AttestationParsers.vcxproj @@ -254,11 +254,13 @@ Level4 $(ProjectDir)..\..\QVL/Src/;$(ProjectDir)..\..\package\include;$(ProjectDir)..\..\QVL/Src/ThirdParty/rapidjson/include;$(ProjectDir)..\..\QVL/Src/AttestationCommons/include;$(ProjectDir)..\..\QVL/Src/AttestationCommons/include/Utils;$(ProjectDir)..\..\QVL/Src/AttestationParsers/include/;$(ProjectDir)..\..\QVL/Src/AttestationParsers/src;$(ProjectDir)..\..\QVL/Src/AttestationLibrary/include/;..\Include;$(ProjectDir)..\..\../QuoteGeneration/quote_wrapper/common/inc;$(ProjectDir)..\..\../QuoteGeneration/common/inc/internal;$(SGXSDKInstallPath)include;$(SGXSDKInstallPath)include\tlibc;$(SGXSDKInstallPath)include\libc++;$(SGXSDKInstallPath)include\epid;$(VCToolsInstallDir)\include;$(ProjectDir)..\..\QvE\Enclave;%(AdditionalIncludeDirectories) true - SGX_TRUSTED;_WINDOWS + NDEBUG;SGX_TRUSTED;_WINDOWS;OPENSSL_NO_FILENAMES Guard true 4101 /d2FH4- %(AdditionalOptions) + false + ProgramDatabase sgx_trts.lib;sgx_tstdc.lib;sgx_tservice.lib;sgx_tcxx.lib;sgx_tcrypto.lib @@ -268,6 +270,9 @@ + + /PDBALTPATH:AttestationParsers.pdb %(AdditionalOptions) + diff --git a/QuoteVerification/QvE/Enclave/linux/config.xml b/QuoteVerification/QvE/Enclave/linux/config.xml index 435d3b3b..db73d2cb 100644 --- a/QuoteVerification/QvE/Enclave/linux/config.xml +++ b/QuoteVerification/QvE/Enclave/linux/config.xml @@ -1,7 +1,7 @@ 1 0x2 - 5 + 6 1 1 diff --git a/QuoteVerification/QvE/Enclave/qve.vcxproj b/QuoteVerification/QvE/Enclave/qve.vcxproj index 6003c05f..774a91f9 100644 --- a/QuoteVerification/QvE/Enclave/qve.vcxproj +++ b/QuoteVerification/QvE/Enclave/qve.vcxproj @@ -412,8 +412,10 @@ true true Guard - ATTESTATIONLIBRARY_STATIC;SGX_TRUSTED;_WINDOWS;_WINDLL;%(PreprocessorDefinitions) + NDEBUG;ATTESTATIONLIBRARY_STATIC;SGX_TRUSTED;_WINDOWS;_WINDLL;%(PreprocessorDefinitions) /d2FH4- %(AdditionalOptions) + false + ProgramDatabase sgx_trts.lib;sgx_tstdc.lib;sgx_tservice.lib;sgx_tcxx.lib;sgx_tcrypto.lib;AttestationParsers.lib;AttestationLibrary.lib;libsgx_tsgxssl.lib;libsgx_tsgxssl_crypto.lib @@ -427,6 +429,7 @@ true true true + /PDBALTPATH:qve.pdb %(AdditionalOptions) "$(SGXSDKInstallPath)bin\x64\release\sgx_sign.exe" sign -key "qve_test_key.pem" -enclave "$(OutDir)qve.dll" -out "$(OutDir)qve.signed.dll" -config "win\config.xml" @@ -530,4 +533,4 @@ - + \ No newline at end of file diff --git a/QuoteVerification/QvE/Enclave/win/config.xml b/QuoteVerification/QvE/Enclave/win/config.xml index 823e0ecf..2c67a958 100644 --- a/QuoteVerification/QvE/Enclave/win/config.xml +++ b/QuoteVerification/QvE/Enclave/win/config.xml @@ -1,11 +1,11 @@ 1 0x2 - 5 + 6 1 1 0x44000 0x80000 1 - \ No newline at end of file + diff --git a/QuoteVerification/dcap_quoteverify/AttestationLibrary_untrusted/AttestationLibrary_untrusted.vcxproj b/QuoteVerification/dcap_quoteverify/AttestationLibrary_untrusted/AttestationLibrary_untrusted.vcxproj index d88a5a30..d4fbfd5c 100644 --- a/QuoteVerification/dcap_quoteverify/AttestationLibrary_untrusted/AttestationLibrary_untrusted.vcxproj +++ b/QuoteVerification/dcap_quoteverify/AttestationLibrary_untrusted/AttestationLibrary_untrusted.vcxproj @@ -131,10 +131,12 @@ Level4 $(ProjectDir)..\..\QVL/Src/;$(ProjectDir)..\..\QVL/Src/ThirdParty/rapidjson/include;$(ProjectDir)..\..\QVL/Src/AttestationCommons/include;$(ProjectDir)..\..\QVL/Src/AttestationCommons/include/Utils;$(ProjectDir)..\..\QVL/Src/AttestationLibrary/include/;$(ProjectDir)..\..\QVL/Src/AttestationLibrary/src;$(ProjectDir)..\..\QVL/Src/AttestationParsers/include/;..\Include;$(ProjectDir)..\..\../QuoteGeneration/common/inc/internal;$(ProjectDir)..\..\../QuoteGeneration/quote_wrapper/common/inc;$(VCToolsInstallDir)\include;$(ProjectDir)..\..\QvE\Include;$(SolutionDir)prebuilt\openssl\inc;%(AdditionalIncludeDirectories) true - _WINDOWS;_ATTESTATIONLIBRARY_EXPORTS + NDEBUG;_WINDOWS;_ATTESTATIONLIBRARY_EXPORTS;OPENSSL_NO_FILENAMES true Guard 4101 + false + ProgramDatabase sgx_trts.lib;sgx_tstdc.lib;sgx_tservice.lib;sgx_tcxx.lib;sgx_tcrypto.lib @@ -153,6 +155,7 @@ + /PDBALTPATH:AttestationLibrary.pdb %(AdditionalOptions) diff --git a/QuoteVerification/dcap_quoteverify/AttestationParsers_untrusted/AttestationParsers_untrusted.vcxproj b/QuoteVerification/dcap_quoteverify/AttestationParsers_untrusted/AttestationParsers_untrusted.vcxproj index 8de8bd16..3645ffba 100644 --- a/QuoteVerification/dcap_quoteverify/AttestationParsers_untrusted/AttestationParsers_untrusted.vcxproj +++ b/QuoteVerification/dcap_quoteverify/AttestationParsers_untrusted/AttestationParsers_untrusted.vcxproj @@ -128,10 +128,12 @@ Level4 $(ProjectDir)..\..\QVL/Src/;$(ProjectDir)..\..\QVL/Src/ThirdParty/rapidjson/include;$(ProjectDir)..\..\QVL/Src/AttestationCommons/include;$(ProjectDir)..\..\QVL/Src/AttestationCommons/include/Utils;$(ProjectDir)..\..\QVL/Src/AttestationParsers/include/;$(ProjectDir)..\..\QVL/Src/AttestationParsers/src;$(ProjectDir)..\..\QVL/Src/AttestationLibrary/include/;..\Include;$(ProjectDir)..\..\../QuoteGeneration/quote_wrapper/common/inc;$(ProjectDir)..\..\../QuoteGeneration/common/inc/internal;$(VCToolsInstallDir)\include;$(SolutionDir)prebuilt\openssl\inc;%(AdditionalIncludeDirectories) true - _WINDOWS; + NDEBUG;_WINDOWS;OPENSSL_NO_FILENAMES Guard true 4101 + false + ProgramDatabase sgx_trts.lib;sgx_tstdc.lib;sgx_tservice.lib;sgx_tcxx.lib;sgx_tcrypto.lib @@ -148,6 +150,7 @@ + /PDBALTPATH:AttestationParsers.pdb %(AdditionalOptions) diff --git a/QuoteVerification/dcap_quoteverify/inc/sgx_dcap_qv_internal.h b/QuoteVerification/dcap_quoteverify/inc/sgx_dcap_qv_internal.h index af0c740b..c647458d 100644 --- a/QuoteVerification/dcap_quoteverify/inc/sgx_dcap_qv_internal.h +++ b/QuoteVerification/dcap_quoteverify/inc/sgx_dcap_qv_internal.h @@ -71,7 +71,7 @@ quote3_error_t sgx_qvl_get_quote_supplemental_data_version( uint32_t *p_version); - quote3_error_t qvl_get_fmspc_ca_from_quote(const uint8_t* p_quote, uint32_t quote_size, +quote3_error_t qvl_get_fmspc_ca_from_quote(const uint8_t* p_quote, uint32_t quote_size, unsigned char* p_fmsp_from_quote, uint32_t fmsp_from_quote_size, unsigned char* p_ca_from_quote, uint32_t ca_from_quote_size); diff --git a/QuoteVerification/dcap_quoteverify/sgx-dcap-quoteverify-rs/.gitignore b/QuoteVerification/dcap_quoteverify/sgx-dcap-quoteverify-rs/.gitignore new file mode 100644 index 00000000..96ef6c0b --- /dev/null +++ b/QuoteVerification/dcap_quoteverify/sgx-dcap-quoteverify-rs/.gitignore @@ -0,0 +1,2 @@ +/target +Cargo.lock diff --git a/QuoteVerification/dcap_quoteverify/sgx-dcap-quoteverify-rs/Cargo.toml b/QuoteVerification/dcap_quoteverify/sgx-dcap-quoteverify-rs/Cargo.toml new file mode 100644 index 00000000..b7e3d6a0 --- /dev/null +++ b/QuoteVerification/dcap_quoteverify/sgx-dcap-quoteverify-rs/Cargo.toml @@ -0,0 +1,9 @@ +[package] +name = "sgx-dcap-quoteverify-rs" +version = "0.1.0" +edition = "2018" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +sgx-dcap-quoteverify-sys = { version = "0.1.0", path = "../sgx-dcap-quoteverify-sys" } diff --git a/QuoteVerification/dcap_quoteverify/sgx-dcap-quoteverify-rs/src/lib.rs b/QuoteVerification/dcap_quoteverify/sgx-dcap-quoteverify-rs/src/lib.rs new file mode 100644 index 00000000..286140a2 --- /dev/null +++ b/QuoteVerification/dcap_quoteverify/sgx-dcap-quoteverify-rs/src/lib.rs @@ -0,0 +1,302 @@ +/* + * Copyright (C) 2011-2021 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. + * + */ +//! Intel(R) Software Guard Extensions Data Center Attestation Primitives (Intel(R) SGX DCAP) +//! Rust wrapper for Quote Verification Library +//! ================================================ +//! +//! This is a safe wrapper for **sgx-dcap-quoteverify-sys**. + +use std::ffi::CString; +use sgx_dcap_quoteverify_sys as qvl_sys; + +pub use qvl_sys::quote3_error_t; +pub use qvl_sys::sgx_ql_request_policy_t; +pub use qvl_sys::sgx_ql_qv_supplemental_t; +pub use qvl_sys::sgx_ql_qve_collateral_t; +pub use qvl_sys::tdx_ql_qve_collateral_t; +pub use qvl_sys::sgx_ql_qv_result_t; +pub use qvl_sys::sgx_ql_qe_report_info_t; +pub use qvl_sys::sgx_qv_path_type_t; + + +/// When the Quoting Verification Library is linked to a process, it needs to know the proper enclave loading policy. +/// The library may be linked with a long lived process, such as a service, where it can load the enclaves and leave +/// them loaded (persistent). This better ensures that the enclaves will be available upon quote requests and not subject +/// to EPC limitations if loaded on demand. However, if the Quoting library is linked with an application process, there +/// may be many applications with the Quoting library and a better utilization of EPC is to load and unloaded the quoting +/// enclaves on demand (ephemeral). The library will be shipped with a default policy of loading enclaves and leaving +/// them loaded until the library is unloaded (PERSISTENT). If the policy is set to EPHEMERAL, then the QE and PCE will +/// be loaded and unloaded on-demand. If either enclave is already loaded when the policy is change to EPHEMERAL, the +/// enclaves will be unloaded before returning. +/// +/// # Param +/// - **policy**\ +/// Sets the requested enclave loading policy to either *SGX_QL_PERSISTENT*, *SGX_QL_EPHEMERAL* +/// or *SGX_QL_DEFAULT*. +/// +/// # Return +/// - ***SGX_QL_SUCCESS***\ +/// Successfully set the enclave loading policy for the quoting library's enclaves.\ +/// - ***SGX_QL_UNSUPPORTED_LOADING_POLICY***\ +/// The selected policy is not support by the quoting library.\ +/// - ***SGX_QL_ERROR_UNEXPECTED***\ +/// Unexpected internal error. +/// +/// # Examples +/// ``` +/// use sgx_dcap_quoteverify_rs::*; +/// +/// let policy = sgx_ql_request_policy_t::SGX_QL_DEFAULT; +/// let ret = sgx_qv_set_enclave_load_policy(policy); +/// +/// assert_eq!(ret, quote3_error_t::SGX_QL_SUCCESS); +/// ``` +pub fn sgx_qv_set_enclave_load_policy(policy: sgx_ql_request_policy_t) -> quote3_error_t { + unsafe {qvl_sys::sgx_qv_set_enclave_load_policy(policy)} +} + +/// Get SGX supplemental data required size. +/// +/// # Param +/// - **p_data_size\[OUT\]**\ +/// Pointer to hold the size of the buffer in bytes required to contain all of the supplemental data. +/// +/// # Return +/// Status code of the operation, one of: +/// - *SGX_QL_SUCCESS* +/// - *SGX_QL_ERROR_INVALID_PARAMETER* +/// - *SGX_QL_ERROR_QVL_QVE_MISMATCH* +/// - *SGX_QL_ENCLAVE_LOAD_ERROR* +/// +/// # Examples +/// ``` +/// use sgx_dcap_quoteverify_rs::*; +/// +/// let mut data_size: u32 = 0; +/// let ret = sgx_qv_get_quote_supplemental_data_size(&mut data_size); +/// +/// assert_eq!(ret, quote3_error_t::SGX_QL_SUCCESS); +/// assert_eq!(data_size, std::mem::size_of::() as u32); +/// ``` +pub fn sgx_qv_get_quote_supplemental_data_size(p_data_size: &mut u32) -> quote3_error_t { + unsafe {qvl_sys::sgx_qv_get_quote_supplemental_data_size(p_data_size as *mut u32)} +} + +/// Perform SGX ECDSA quote verification. +/// +/// # Param +/// - **quote\[IN\]**\ +/// SGX Quote, presented as u8 vector. +/// - **p_quote_collateral\[IN\]**\ +/// This is a pointer to the Quote Certification Collateral provided by the caller. +/// - **expiration_check_date\[IN\]**\ +/// This is the date that the QvE will use to determine if any of the inputted collateral have expired. +/// - **p_collateral_expiration_status\[OUT\]**\ +/// Address of the outputted expiration status. This input must not be NULL. +/// - **p_quote_verification_result\[OUT\]**\ +/// Address of the outputted quote verification result. +/// - **p_qve_report_info\[IN/OUT\]**\ +/// This parameter can be used in 2 ways.\ +/// - If p_qve_report_info is NOT None, the API will use Intel QvE to perform quote verification, and QvE will generate a report using the target_info in sgx_ql_qe_report_info_t structure.\ +/// - if p_qve_report_info is None, the API will use QVL library to perform quote verification, not that the results can not be cryptographically authenticated in this mode. +/// - **supplemental_data_size\[IN\]**\ +/// Size of the buffer pointed to by p_quote (in bytes). +/// - **p_supplemental_data\[OUT\]**\ +/// The parameter is optional. If it is None, supplemental_data_size must be 0. +/// +/// # Return +/// Status code of the operation, one of: +/// - *SGX_QL_SUCCESS* +/// - *SGX_QL_ERROR_INVALID_PARAMETER* +/// - *SGX_QL_QUOTE_FORMAT_UNSUPPORTED* +/// - *SGX_QL_QUOTE_CERTIFICATION_DATA_UNSUPPORTED* +/// - *SGX_QL_UNABLE_TO_GENERATE_REPORT* +/// - *SGX_QL_CRL_UNSUPPORTED_FORMAT* +/// - *SGX_QL_ERROR_UNEXPECTED* +/// +pub fn sgx_qv_verify_quote( + quote: &[u8], + p_quote_collateral: Option<&sgx_ql_qve_collateral_t>, + expiration_check_date: i64, + p_collateral_expiration_status: &mut u32, + p_quote_verification_result: &mut sgx_ql_qv_result_t, + p_qve_report_info: Option<&mut sgx_ql_qe_report_info_t>, + supplemental_data_size: u32, + p_supplemental_data: Option<&mut sgx_ql_qv_supplemental_t> +) -> quote3_error_t { + + // Match Option types to raw pointers + // + let p_quote_collateral = match p_quote_collateral { + Some(p) => p as *const sgx_ql_qve_collateral_t, + None => std::ptr::null(), + }; + let p_qve_report_info = match p_qve_report_info { + Some(p) => p as *mut sgx_ql_qe_report_info_t, + None => std::ptr::null_mut(), + }; + let p_supplemental_data = match p_supplemental_data { + Some(p) => p as *mut sgx_ql_qv_supplemental_t as *mut u8, + None => std::ptr::null_mut(), + }; + + unsafe { + qvl_sys::sgx_qv_verify_quote( + quote.as_ptr(), + quote.len() as u32, + p_quote_collateral, + expiration_check_date, + p_collateral_expiration_status as *mut u32, + p_quote_verification_result as *mut sgx_ql_qv_result_t, + p_qve_report_info, + supplemental_data_size, + p_supplemental_data) + } +} + +/// Get TDX supplemental data required size. +/// +/// # Param +/// - **p_data_size\[OUT\]**\ +/// Pointer to hold the size of the buffer in bytes required to contain all of the supplemental data. +/// +/// # Return +/// Status code of the operation, one of: +/// - *SGX_QL_SUCCESS* +/// - *SGX_QL_ERROR_INVALID_PARAMETER* +/// - *SGX_QL_ERROR_QVL_QVE_MISMATCH* +/// - *SGX_QL_ENCLAVE_LOAD_ERROR* +/// +/// # Examples +/// ``` +/// use sgx_dcap_quoteverify_rs::*; +/// +/// let mut data_size: u32 = 0; +/// let ret = tdx_qv_get_quote_supplemental_data_size(&mut data_size); +/// +/// assert_eq!(ret, quote3_error_t::SGX_QL_SUCCESS); +/// assert_eq!(data_size, std::mem::size_of::() as u32); +/// ``` +pub fn tdx_qv_get_quote_supplemental_data_size(p_data_size: &mut u32) -> quote3_error_t { + unsafe {qvl_sys::tdx_qv_get_quote_supplemental_data_size(p_data_size as *mut u32)} +} + +/// Perform TDX ECDSA quote verification. +/// +/// # Param +/// - **quote\[IN\]**\ +/// TDX Quote, presented as u8 vector. +/// - **p_quote_collateral\[IN\]**\ +/// This is a pointer to the Quote Certification Collateral provided by the caller. +/// - **expiration_check_date\[IN\]**\ +/// This is the date that the QvE will use to determine if any of the inputted collateral have expired. +/// - **p_collateral_expiration_status\[OUT\]**\ +/// Address of the outputted expiration status. This input must not be NULL. +/// - **p_quote_verification_result\[OUT\]**\ +/// Address of the outputted quote verification result. +/// - **p_qve_report_info\[IN/OUT\]**\ +/// This parameter can be used in 2 ways.\ +/// - If p_qve_report_info is NOT None, the API will use Intel QvE to perform quote verification, and QvE will generate a report using the target_info in sgx_ql_qe_report_info_t structure.\ +/// - if p_qve_report_info is None, the API will use QVL library to perform quote verification, not that the results can not be cryptographically authenticated in this mode. +/// - **supplemental_data_size\[IN\]**\ +/// Size of the buffer pointed to by p_quote (in bytes). +/// - **p_supplemental_data\[OUT\]**\ +/// The parameter is optional. If it is None, supplemental_data_size must be 0. +/// +/// # Return +/// Status code of the operation, one of: +/// - *SGX_QL_SUCCESS* +/// - *SGX_QL_ERROR_INVALID_PARAMETER* +/// - *SGX_QL_QUOTE_FORMAT_UNSUPPORTED* +/// - *SGX_QL_QUOTE_CERTIFICATION_DATA_UNSUPPORTED* +/// - *SGX_QL_UNABLE_TO_GENERATE_REPORT* +/// - *SGX_QL_CRL_UNSUPPORTED_FORMAT* +/// - *SGX_QL_ERROR_UNEXPECTED* +/// +pub fn tdx_qv_verify_quote( + quote: &[u8], + p_quote_collateral: Option<&tdx_ql_qve_collateral_t>, + expiration_check_date: i64, + p_collateral_expiration_status: &mut u32, + p_quote_verification_result: &mut sgx_ql_qv_result_t, + p_qve_report_info: Option<&mut sgx_ql_qe_report_info_t>, + supplemental_data_size: u32, + p_supplemental_data: Option<&mut sgx_ql_qv_supplemental_t> +) -> quote3_error_t { + + // Match Option types to raw pointers + // + let p_quote_collateral = match p_quote_collateral { + Some(p) => p as *const tdx_ql_qve_collateral_t, + None => std::ptr::null(), + }; + let p_qve_report_info = match p_qve_report_info { + Some(p) => p as *mut sgx_ql_qe_report_info_t, + None => std::ptr::null_mut(), + }; + let p_supplemental_data = match p_supplemental_data { + Some(p) => p as *mut sgx_ql_qv_supplemental_t as *mut u8, + None => std::ptr::null_mut(), + }; + + unsafe { + qvl_sys::tdx_qv_verify_quote( + quote.as_ptr(), + quote.len() as u32, + p_quote_collateral, + expiration_check_date, + p_collateral_expiration_status as *mut u32, + p_quote_verification_result as *mut sgx_ql_qv_result_t, + p_qve_report_info, + supplemental_data_size, + p_supplemental_data) + } +} + +/// Set the full path of QVE and QPL library. +/// The function takes the enum and the corresponding full path. +/// +/// # Param +/// - **path_type**\ +/// The type of binary being passed in. +/// - **p_path**\ +/// It should be a valid full path. +/// +/// # Return +/// - ***SGX_QL_SUCCESS***\ +/// Successfully set the full path. +/// - ***SGX_QL_ERROR_INVALID_PARAMETER***\ +/// p_path is not a valid full path or the path is too long. +/// +#[cfg(target_os = "linux")] +pub fn sgx_qv_set_path(path_type: sgx_qv_path_type_t, p_path: CString) -> quote3_error_t { + unsafe {qvl_sys::sgx_qv_set_path(path_type, p_path.as_ptr())} +} diff --git a/QuoteVerification/dcap_quoteverify/sgx-dcap-quoteverify-sys/.gitignore b/QuoteVerification/dcap_quoteverify/sgx-dcap-quoteverify-sys/.gitignore new file mode 100644 index 00000000..96ef6c0b --- /dev/null +++ b/QuoteVerification/dcap_quoteverify/sgx-dcap-quoteverify-sys/.gitignore @@ -0,0 +1,2 @@ +/target +Cargo.lock diff --git a/QuoteVerification/dcap_quoteverify/sgx-dcap-quoteverify-sys/Cargo.toml b/QuoteVerification/dcap_quoteverify/sgx-dcap-quoteverify-sys/Cargo.toml new file mode 100644 index 00000000..0621853e --- /dev/null +++ b/QuoteVerification/dcap_quoteverify/sgx-dcap-quoteverify-sys/Cargo.toml @@ -0,0 +1,12 @@ +[package] +name = "sgx-dcap-quoteverify-sys" +version = "0.1.0" +edition = "2018" +links = "sgx_dcap_quoteverify" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] + +[build-dependencies] +bindgen = "0.59.1" diff --git a/QuoteVerification/dcap_quoteverify/sgx-dcap-quoteverify-sys/bindings.h b/QuoteVerification/dcap_quoteverify/sgx-dcap-quoteverify-sys/bindings.h new file mode 100644 index 00000000..a655b8ae --- /dev/null +++ b/QuoteVerification/dcap_quoteverify/sgx-dcap-quoteverify-sys/bindings.h @@ -0,0 +1,32 @@ +/* + * Copyright (C) 2011-2021 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_dcap_quoteverify.h" \ No newline at end of file diff --git a/QuoteVerification/dcap_quoteverify/sgx-dcap-quoteverify-sys/build.rs b/QuoteVerification/dcap_quoteverify/sgx-dcap-quoteverify-sys/build.rs new file mode 100644 index 00000000..9380ff0e --- /dev/null +++ b/QuoteVerification/dcap_quoteverify/sgx-dcap-quoteverify-sys/build.rs @@ -0,0 +1,89 @@ +/* + * Copyright (C) 2011-2021 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. + * + */ + +use bindgen; + +use std::env; +use std::path::PathBuf; + +fn main() { + // Tell cargo to tell rustc to link the system + // sgx-dcap-quoteverify shared library. + println!("cargo:rustc-link-lib=sgx_dcap_quoteverify"); + + // Tell cargo to invalidate the built crate whenever the wrapper changes + println!("cargo:rerun-if-changed=bindings.h"); + + // Set sdk to search path if SGX_SDK is in environment variable + let mut sdk_inc = String::from("-I"); + match env::var("SGX_SDK") { + Ok(val) => { + sdk_inc.push_str(&val); + sdk_inc.push_str("/include/"); + }, + _ => (), + } + + // The bindgen::Builder is the main entry point + // to bindgen, and lets you build up options for + // the resulting bindings. + let bindings = bindgen::Builder::default() + // The input header we would like to generate + // bindings for. + .header("bindings.h") + // Include search path + .clang_arg(sdk_inc) + // Convert C enum to Rust enum + .rustified_enum("_quote3_error_t") + .rustified_enum("_sgx_ql_request_policy") + .rustified_enum("_sgx_ql_qv_result_t") + .rustified_enum("sgx_qv_path_type_t") + // Disable debug trait for packed C structures + .no_debug("_quote_t") + .no_debug("_sgx_ql_auth_data_t") + .no_debug("_sgx_ql_certification_data_t") + .no_debug("_sgx_ql_ecdsa_sig_data_t") + .no_debug("_sgx_quote3_t") + .no_debug("_sgx_ql_att_key_id_param_t") + // Tell cargo to invalidate the built crate whenever any of the + // included header files changed. + .parse_callbacks(Box::new(bindgen::CargoCallbacks)) + // Finish the builder and generate the bindings. + .generate() + // Unwrap the Result and panic on failure. + .expect("Unable to generate bindings"); + + // Write the bindings to the $OUT_DIR/bindings.rs file. + let out_path = PathBuf::from(env::var("OUT_DIR").unwrap()); + bindings + .write_to_file(out_path.join("bindings.rs")) + .expect("Couldn't write bindings!"); +} diff --git a/QuoteVerification/dcap_quoteverify/sgx-dcap-quoteverify-sys/src/lib.rs b/QuoteVerification/dcap_quoteverify/sgx-dcap-quoteverify-sys/src/lib.rs new file mode 100644 index 00000000..9d81d5bd --- /dev/null +++ b/QuoteVerification/dcap_quoteverify/sgx-dcap-quoteverify-sys/src/lib.rs @@ -0,0 +1,52 @@ +/* + * Copyright (C) 2011-2021 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. + * + */ +//! Intel(R) Software Guard Extensions Data Center Attestation Primitives (Intel(R) SGX DCAP) +//! Rust raw FFI bindings for Quote Verification Library +//! ================================================ +//! +//! Please install the following prerequisite: +//! * Intel(R) SGX DCAP Driver +//! * Intel(R) SGX SDK +//! * Intel(R) SGX DCAP Packages +//! * Intel(R) SGX DCAP PCCS (Provisioning Certificate Caching Service) +//! +//! *Please refer to [SGX DCAP Linux installation guide]( +//! https://download.01.org/intel-sgx/sgx-dcap/#version#/linux/docs/Intel_SGX_SW_Installation_Guide_for_Linux.pdf) +//! to install above dependencies.* +//! +//! *Note that you need to change **\#version\#** to actual version number in URL, such as 1.4.*\ +//! *Note that you need to install **libsgx-dcap-quote-verify-dev** and **clang** for this package.* + +#![allow(non_upper_case_globals)] +#![allow(non_camel_case_types)] +#![allow(non_snake_case)] + +include!(concat!(env!("OUT_DIR"), "/bindings.rs")); diff --git a/QuoteVerification/dcap_tvl/sgx_dcap_tvl.cpp b/QuoteVerification/dcap_tvl/sgx_dcap_tvl.cpp index db3a4a1e..4d4282a0 100644 --- a/QuoteVerification/dcap_tvl/sgx_dcap_tvl.cpp +++ b/QuoteVerification/dcap_tvl/sgx_dcap_tvl.cpp @@ -45,7 +45,7 @@ #define SGX_ERR_BREAK(x) {if (x != SGX_SUCCESS) break;} //Hardcode Intel signed QvE Identity below -//You can get such info from latest QvE Identity JSON file +//You can get such info from QvE Identity JSON file //e.g. Get the QvE Identity JSON file from //https://api.trustedservices.intel.com/sgx/certification/v3/qve/identity // @@ -60,9 +60,8 @@ const std::string QVE_MRSIGNER = "8C4F5775D796503E96137F77C68A829A0056AC8DED7014 const sgx_prod_id_t QVE_PRODID = 2; -//Defense in depth, threshold must be greater or equal to least QvE ISV SVN -const sgx_isv_svn_t LEAST_QVE_ISVSVN = 5; - +//Defense in depth, QvE ISV SVN in report must be greater or equal to hardcode QvE ISV SVN +const sgx_isv_svn_t LEAST_QVE_ISVSVN = 6; quote3_error_t sgx_tvl_verify_qve_report_and_identity( const uint8_t *p_quote, @@ -96,13 +95,6 @@ quote3_error_t sgx_tvl_verify_qve_report_and_identity( } } - //Defense in depth, threshold must be greater or equal to 5 - // - if (qve_isvsvn_threshold < LEAST_QVE_ISVSVN) - return SGX_QL_QVE_OUT_OF_DATE; - - - const sgx_report_t *p_qve_report = &(p_qve_report_info->qe_report); do { @@ -227,8 +219,15 @@ quote3_error_t sgx_tvl_verify_qve_report_and_identity( break; } + //Check QvE ISV SVN in QvE report meets the minimum requires SVN when the TVL was built. + // + if (p_qve_report->body.isv_svn < LEAST_QVE_ISVSVN) { + ret = SGX_QL_QVE_OUT_OF_DATE; + break; + } - //Check QvE ISV SVN in QvE report + //Check if there has been a TCB Recovery on the QVE used to verify the report. + //Warning: The function may return erroneous result if QvE ISV SVN has been modified maliciously. // if (p_qve_report->body.isv_svn < qve_isvsvn_threshold) { ret = SGX_QL_QVE_OUT_OF_DATE; diff --git a/QuoteVerification/dcap_tvl/sgx_dcap_tvl.edl b/QuoteVerification/dcap_tvl/sgx_dcap_tvl.edl index 507d5bd6..2d94cf63 100644 --- a/QuoteVerification/dcap_tvl/sgx_dcap_tvl.edl +++ b/QuoteVerification/dcap_tvl/sgx_dcap_tvl.edl @@ -48,7 +48,9 @@ enclave { * @param quote_verification_result[IN] - The output of API "sgx_qv_verify_quote" about quote verification result * @param p_supplemental_data[IN] - The output of API "sgx_qv_verify_quote", the pointer to supplemental data * @param supplemental_data_size[IN] - Size of the buffer pointed to by p_quote (in bytes) - * @param qve_isvsvn_threshold [IN] - The threshold of QvE ISVSVN, the ISVSVN of QvE used to verify quote must be greater or equal to this threshold. You can get latest QvE ISVSVN in QvE Identity (JSON) from Intel PCS. + * @param qve_isvsvn_threshold [IN] - The threshold of QvE ISVSVN, the ISVSVN of QvE used to verify quote must be greater or equal to this threshold. + * @You can get latest QvE ISVSVN from QvE configuration file (Github) or QvE Identity (JSON) from Intel PCS. + * @Warning: The function may return erroneous result if QvE ISV SVN has been modified maliciously. * * @return Status code of the operation, one of: * - SGX_QL_SUCCESS diff --git a/QuoteVerification/dcap_tvl/sgx_dcap_tvl.h b/QuoteVerification/dcap_tvl/sgx_dcap_tvl.h index f6101220..9e72690f 100644 --- a/QuoteVerification/dcap_tvl/sgx_dcap_tvl.h +++ b/QuoteVerification/dcap_tvl/sgx_dcap_tvl.h @@ -64,7 +64,9 @@ extern "C" { * @param quote_verification_result[IN] - The output of API "sgx_qv_verify_quote" about quote verification result * @param p_supplemental_data[IN] - The output of API "sgx_qv_verify_quote", the pointer to supplemental data * @param supplemental_data_size[IN] - Size of the buffer pointed to by p_quote (in bytes) - * @param qve_isvsvn_threshold [IN] - The threshold of QvE ISVSVN, the ISVSVN of QvE used to verify quote must be greater or equal to this threshold. You can get latest QvE ISVSVN in QvE Identity (JSON) from Intel PCS. + * @param qve_isvsvn_threshold [IN] - The threshold of QvE ISVSVN, the ISVSVN of QvE used to verify quote must be greater or equal to this threshold. + * @You can get latest QvE ISVSVN from QvE configuration file (Github) or QvE Identity (JSON) from Intel PCS. + * @Warning: The function may return erroneous result if QvE ISV SVN has been modified maliciously. * * @return Status code of the operation, one of: * - SGX_QL_SUCCESS diff --git a/QuoteVerification/prepare_sgxssl.cmd b/QuoteVerification/prepare_sgxssl.cmd index 1849410e..68863205 100644 --- a/QuoteVerification/prepare_sgxssl.cmd +++ b/QuoteVerification/prepare_sgxssl.cmd @@ -1,6 +1,6 @@ Rem -Rem Copyright (C) 2011-2021 Intel Corporation. All rights reserved. +Rem Copyright (C) 2011-2022 Intel Corporation. All rights reserved. Rem Rem Redistribution and use in source and binary forms, with or without Rem modification, are permitted provided that the following conditions @@ -39,17 +39,17 @@ set top_dir=%~dp0 set sgxssl_dir=%top_dir%\sgxssl set openssl_out_dir=%sgxssl_dir%\openssl_source -set openssl_ver_name=openssl-1.1.1m +set openssl_ver_name=openssl-1.1.1o set sgxssl_github_archive=https://github.com/intel/intel-sgx-ssl/archive -set sgxssl_ver_name=win_2.15_1.1.1m_update +set sgxssl_ver_name=win_2.16_1.1.1o set sgxssl_ver=%sgxssl_ver_name% set build_script=%sgxssl_dir%\Windows\build_package.cmd set server_url_path=https://www.openssl.org/source/ set full_openssl_url=%server_url_path%/%openssl_ver_name%.tar.gz -set sgxssl_chksum=C9177D23AB221429EC1BDE38D2118C69FBE612018B6EA9900D22C1DD9596A2E6 -set openssl_chksum=F89199BE8B23CA45FC7CB9F1D8D3EE67312318286AD030F5316ACA6462DB6C96 +set sgxssl_chksum=E25CF02BF48FA279CFCB6B134ACB0A1FB04B84F680B40F32EF03AFF7368BE1E6 +set openssl_chksum=9384A2B0570DD80358841464677115DF785EDB941C71211F75076D72FE6B438F if not exist %sgxssl_dir% ( diff --git a/QuoteVerification/prepare_sgxssl.sh b/QuoteVerification/prepare_sgxssl.sh index 83676abf..a0685adc 100755 --- a/QuoteVerification/prepare_sgxssl.sh +++ b/QuoteVerification/prepare_sgxssl.sh @@ -34,16 +34,16 @@ ARG1=${1:-build} top_dir="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" sgxssl_dir=$top_dir/sgxssl openssl_out_dir=$sgxssl_dir/openssl_source -openssl_ver_name=openssl-1.1.1m +openssl_ver_name=openssl-1.1.1o sgxssl_github_archive=https://github.com/01org/intel-sgx-ssl/archive -sgxssl_file_name=lin_2.16_1.1.1m_update +sgxssl_file_name=lin_2.17_1.1.1o build_script=$sgxssl_dir/Linux/build_openssl.sh server_url_path=https://www.openssl.org/source/ full_openssl_url=$server_url_path/$openssl_ver_name.tar.gz full_openssl_url_old=$server_url_path/old/1.1.1/$openssl_ver_name.tar.gz -sgxssl_chksum=46d3e6113da446f0fb250d9ca3b73f06b4fbc4e8f552c98f5de0865ee38caffc -openssl_chksum=f89199be8b23ca45fc7cb9f1d8d3ee67312318286ad030f5316aca6462db6c96 +sgxssl_chksum=f0ed7bd37b45fd2350ec835a9c56b5590554e13b94471a38d3379054448a6d4b +openssl_chksum=9384a2b0570dd80358841464677115df785edb941c71211f75076d72fe6b438f rm -f check_sum_sgxssl.txt check_sum_openssl.txt if [ ! -f $build_script ]; then wget $sgxssl_github_archive/$sgxssl_file_name.zip -P $sgxssl_dir/ || exit 1 diff --git a/SGX_DCAP.sln b/SGX_DCAP.sln index 68108a32..5bfc67b9 100644 --- a/SGX_DCAP.sln +++ b/SGX_DCAP.sln @@ -66,6 +66,12 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "AttestationLibrary_untruste {D3FBC2A5-18F3-4073-ABD9-74612E17A0C3} = {D3FBC2A5-18F3-4073-ABD9-74612E17A0C3} EndProjectSection EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "id_enclave", "QuoteGeneration\quote_wrapper\quote\id_enclave\win\id_enclave.vcxproj", "{BE9799F0-84D2-4107-A5DB-A54E22F81F31}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "tdqe", "QuoteGeneration\quote_wrapper\tdx_quote\enclave\win\tdqe.vcxproj", "{FA74E16C-93BA-4722-8B06-434F57C0E6D0}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "tdx_logic", "QuoteGeneration\quote_wrapper\tdx_quote\win\tdx_logic.vcxproj", "{DF76228C-AA18-41D2-ABF6-E340AE2B6591}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution CVE-2020-0551-CF-Release|x64 = CVE-2020-0551-CF-Release|x64 @@ -354,6 +360,62 @@ Global {D860F500-9B86-43AC-AAF3-51173AC75B25}.Simulation|x64.Build.0 = Release|x64 {D860F500-9B86-43AC-AAF3-51173AC75B25}.Simulation|x86.ActiveCfg = Release|Win32 {D860F500-9B86-43AC-AAF3-51173AC75B25}.Simulation|x86.Build.0 = Release|Win32 + {BE9799F0-84D2-4107-A5DB-A54E22F81F31}.CVE-2020-0551-CF-Release|x64.ActiveCfg = CVE-2020-0551-CF-Release|x64 + {BE9799F0-84D2-4107-A5DB-A54E22F81F31}.CVE-2020-0551-CF-Release|x64.Build.0 = CVE-2020-0551-CF-Release|x64 + {BE9799F0-84D2-4107-A5DB-A54E22F81F31}.CVE-2020-0551-CF-Release|x86.ActiveCfg = CVE-2020-0551-CF-Release|x64 + {BE9799F0-84D2-4107-A5DB-A54E22F81F31}.CVE-2020-0551-Load-Release|x64.ActiveCfg = CVE-2020-0551-Load-Release|x64 + {BE9799F0-84D2-4107-A5DB-A54E22F81F31}.CVE-2020-0551-Load-Release|x64.Build.0 = CVE-2020-0551-Load-Release|x64 + {BE9799F0-84D2-4107-A5DB-A54E22F81F31}.CVE-2020-0551-Load-Release|x86.ActiveCfg = CVE-2020-0551-Load-Release|x64 + {BE9799F0-84D2-4107-A5DB-A54E22F81F31}.Debug|x64.ActiveCfg = Debug|x64 + {BE9799F0-84D2-4107-A5DB-A54E22F81F31}.Debug|x64.Build.0 = Debug|x64 + {BE9799F0-84D2-4107-A5DB-A54E22F81F31}.Debug|x86.ActiveCfg = Debug|Win32 + {BE9799F0-84D2-4107-A5DB-A54E22F81F31}.Debug|x86.Build.0 = Debug|Win32 + {BE9799F0-84D2-4107-A5DB-A54E22F81F31}.Release|x64.ActiveCfg = Release|x64 + {BE9799F0-84D2-4107-A5DB-A54E22F81F31}.Release|x64.Build.0 = Release|x64 + {BE9799F0-84D2-4107-A5DB-A54E22F81F31}.Release|x86.ActiveCfg = Release|Win32 + {BE9799F0-84D2-4107-A5DB-A54E22F81F31}.Release|x86.Build.0 = Release|Win32 + {BE9799F0-84D2-4107-A5DB-A54E22F81F31}.Simulation|x64.ActiveCfg = Release|x64 + {BE9799F0-84D2-4107-A5DB-A54E22F81F31}.Simulation|x64.Build.0 = Release|x64 + {BE9799F0-84D2-4107-A5DB-A54E22F81F31}.Simulation|x86.ActiveCfg = Release|Win32 + {BE9799F0-84D2-4107-A5DB-A54E22F81F31}.Simulation|x86.Build.0 = Release|Win32 + {FA74E16C-93BA-4722-8B06-434F57C0E6D0}.CVE-2020-0551-CF-Release|x64.ActiveCfg = CVE-2020-0551-CF-Release|x64 + {FA74E16C-93BA-4722-8B06-434F57C0E6D0}.CVE-2020-0551-CF-Release|x64.Build.0 = CVE-2020-0551-CF-Release|x64 + {FA74E16C-93BA-4722-8B06-434F57C0E6D0}.CVE-2020-0551-CF-Release|x86.ActiveCfg = CVE-2020-0551-CF-Release|x64 + {FA74E16C-93BA-4722-8B06-434F57C0E6D0}.CVE-2020-0551-Load-Release|x64.ActiveCfg = CVE-2020-0551-Load-Release|x64 + {FA74E16C-93BA-4722-8B06-434F57C0E6D0}.CVE-2020-0551-Load-Release|x64.Build.0 = CVE-2020-0551-Load-Release|x64 + {FA74E16C-93BA-4722-8B06-434F57C0E6D0}.CVE-2020-0551-Load-Release|x86.ActiveCfg = CVE-2020-0551-Load-Release|x64 + {FA74E16C-93BA-4722-8B06-434F57C0E6D0}.Debug|x64.ActiveCfg = Debug|x64 + {FA74E16C-93BA-4722-8B06-434F57C0E6D0}.Debug|x64.Build.0 = Debug|x64 + {FA74E16C-93BA-4722-8B06-434F57C0E6D0}.Debug|x86.ActiveCfg = Debug|Win32 + {FA74E16C-93BA-4722-8B06-434F57C0E6D0}.Debug|x86.Build.0 = Debug|Win32 + {FA74E16C-93BA-4722-8B06-434F57C0E6D0}.Release|x64.ActiveCfg = Release|x64 + {FA74E16C-93BA-4722-8B06-434F57C0E6D0}.Release|x64.Build.0 = Release|x64 + {FA74E16C-93BA-4722-8B06-434F57C0E6D0}.Release|x86.ActiveCfg = Release|Win32 + {FA74E16C-93BA-4722-8B06-434F57C0E6D0}.Release|x86.Build.0 = Release|Win32 + {FA74E16C-93BA-4722-8B06-434F57C0E6D0}.Simulation|x64.ActiveCfg = Release|x64 + {FA74E16C-93BA-4722-8B06-434F57C0E6D0}.Simulation|x64.Build.0 = Release|x64 + {FA74E16C-93BA-4722-8B06-434F57C0E6D0}.Simulation|x86.ActiveCfg = Release|Win32 + {FA74E16C-93BA-4722-8B06-434F57C0E6D0}.Simulation|x86.Build.0 = Release|Win32 + {DF76228C-AA18-41D2-ABF6-E340AE2B6591}.CVE-2020-0551-CF-Release|x64.ActiveCfg = Release|x64 + {DF76228C-AA18-41D2-ABF6-E340AE2B6591}.CVE-2020-0551-CF-Release|x64.Build.0 = Release|x64 + {DF76228C-AA18-41D2-ABF6-E340AE2B6591}.CVE-2020-0551-CF-Release|x86.ActiveCfg = Release|Win32 + {DF76228C-AA18-41D2-ABF6-E340AE2B6591}.CVE-2020-0551-CF-Release|x86.Build.0 = Release|Win32 + {DF76228C-AA18-41D2-ABF6-E340AE2B6591}.CVE-2020-0551-Load-Release|x64.ActiveCfg = Release|x64 + {DF76228C-AA18-41D2-ABF6-E340AE2B6591}.CVE-2020-0551-Load-Release|x64.Build.0 = Release|x64 + {DF76228C-AA18-41D2-ABF6-E340AE2B6591}.CVE-2020-0551-Load-Release|x86.ActiveCfg = Release|Win32 + {DF76228C-AA18-41D2-ABF6-E340AE2B6591}.CVE-2020-0551-Load-Release|x86.Build.0 = Release|Win32 + {DF76228C-AA18-41D2-ABF6-E340AE2B6591}.Debug|x64.ActiveCfg = Debug|x64 + {DF76228C-AA18-41D2-ABF6-E340AE2B6591}.Debug|x64.Build.0 = Debug|x64 + {DF76228C-AA18-41D2-ABF6-E340AE2B6591}.Debug|x86.ActiveCfg = Debug|Win32 + {DF76228C-AA18-41D2-ABF6-E340AE2B6591}.Debug|x86.Build.0 = Debug|Win32 + {DF76228C-AA18-41D2-ABF6-E340AE2B6591}.Release|x64.ActiveCfg = Release|x64 + {DF76228C-AA18-41D2-ABF6-E340AE2B6591}.Release|x64.Build.0 = Release|x64 + {DF76228C-AA18-41D2-ABF6-E340AE2B6591}.Release|x86.ActiveCfg = Release|Win32 + {DF76228C-AA18-41D2-ABF6-E340AE2B6591}.Release|x86.Build.0 = Release|Win32 + {DF76228C-AA18-41D2-ABF6-E340AE2B6591}.Simulation|x64.ActiveCfg = Release|x64 + {DF76228C-AA18-41D2-ABF6-E340AE2B6591}.Simulation|x64.Build.0 = Release|x64 + {DF76228C-AA18-41D2-ABF6-E340AE2B6591}.Simulation|x86.ActiveCfg = Release|Win32 + {DF76228C-AA18-41D2-ABF6-E340AE2B6591}.Simulation|x86.Build.0 = Release|Win32 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/SampleCode/QuoteGenerationSample/Makefile b/SampleCode/QuoteGenerationSample/Makefile index 2709662c..1758d9a3 100644 --- a/SampleCode/QuoteGenerationSample/Makefile +++ b/SampleCode/QuoteGenerationSample/Makefile @@ -35,6 +35,8 @@ SGX_DEBUG ?= 0 SGX_SDK ?= /opt/intel/sgxsdk SGX_MODE ?= HW SGX_ARCH ?= x64 +OUT_OF_PROC ?= 0 + SGX_COMMON_CFLAGS := -m64 SGX_LIBRARY_PATH := $(SGX_SDK)/lib64 @@ -51,7 +53,7 @@ endif DCAP_Library_Name := sgx_dcap_ql Urts_Library_Name := sgx_urts -Uae_Library_Name := sgx_quote_ex +Quote_ex_Library_Name := sgx_quote_ex App_Cpp_Files := App/App.cpp App_Include_Paths := -I$(SGX_SDK)/include -I../../QuoteGeneration/quote_wrapper/common/inc @@ -69,7 +71,10 @@ endif App_Cpp_Flags := $(App_C_Flags) -std=c++11 -App_Link_Flags := $(SGX_COMMON_CFLAGS) -l$(DCAP_Library_Name) -l$(Urts_Library_Name) -l$(Uae_Library_Name) -ldl -lpthread +App_Link_Flags := $(SGX_COMMON_CFLAGS) -l$(DCAP_Library_Name) -l$(Urts_Library_Name) -ldl -lpthread +ifeq ($(OUT_OF_PROC),1) + App_Link_Flags += -l$(Quote_ex_Library_Name) +endif App_Cpp_Objects := $(App_Cpp_Files:.cpp=.o) diff --git a/SampleCode/QuoteGenerationSample/README.md b/SampleCode/QuoteGenerationSample/README.md index 6bd5386b..f29e9b9a 100644 --- a/SampleCode/QuoteGenerationSample/README.md +++ b/SampleCode/QuoteGenerationSample/README.md @@ -20,6 +20,7 @@ Prerequisite: * Intel(R) SGX SDK * Intel(R) SGX DCAP Packages * Intel(R) SGX DCAP PCCS (Provisioning Certificate Caching Service) +* If you want to use "out-of-process" quote generation, you need to install quote-ex package in Intel(R) SGX PSW Packages *Please refer to SGX DCAP Linux installation guide "https://download.01.org/intel-sgx/sgx-dcap/#version#/linux/docs/Intel_SGX_DCAP_Linux_SW_Installation_Guide.pdf" to install above dependencies*
*Note that you need to change **\#version\#** to actual version number in URL, such as 1.4.* @@ -45,16 +46,21 @@ Details please refer to driver [README](https://github.com/intel/SGXDataCenterAt *Note that you need to install libsgx-quote-ex-dev package and all its dependencies and recommends in order to build and run this sample. Or you can remove the `-l$(Uae_Library_Name)` in Makefile. ``` - Release build: + "in-porc" Release build: $ make Or Debug build: $ make SGX_DEBUG=1 Run application in "in-proc" mode: $ ./app + + "out-of-proc" Release build: + $ make OUT_OF_PROC=1 + Or Debug build: + $ make SGX_DEBUG=1 OUT_OF_PROC=1 Run application in "out-of-proc" mode: $ SGX_AESM_ADDR=1 ./app ``` - +**Note**: Our libdcap_quoteprov.so is not built with Intel(R) Control Flow Enforcement Technology(CET) feature. If the sample is built with CET feature(it can be enabled by the compiler's default setting) and it is running on a CET enabled platform, you may encounter such an error message(or something similar): "Couldn't find the platform library. rebuild shared object with SHSTK support enabled". It means the system glibc enforces that a CET-enabled application can't load a non-CET shared library. You need to rebuild the sample by adding -fcf-protection=none option explicitly to disable CET. ## Windows Supported operating systems: diff --git a/SampleCode/QuoteVerificationSample/App/App.cpp b/SampleCode/QuoteVerificationSample/App/App.cpp index 19353dae..ce3d06b2 100644 --- a/SampleCode/QuoteVerificationSample/App/App.cpp +++ b/SampleCode/QuoteVerificationSample/App/App.cpp @@ -144,6 +144,14 @@ int ecdsa_quote_verification(vector quote, bool use_qve) if (dcap_ret == SGX_QL_SUCCESS && supplemental_data_size == sizeof(sgx_ql_qv_supplemental_t)) { printf("\tInfo: sgx_qv_get_quote_supplemental_data_size successfully returned.\n"); p_supplemental_data = (uint8_t*)malloc(supplemental_data_size); + if (p_supplemental_data != NULL) { + memset(p_supplemental_data, 0, sizeof(supplemental_data_size)); + } + //Just print error in sample + // + else { + printf("\tError: Cannot allocate memory for supplemental data.\n"); + } } else { if (dcap_ret != SGX_QL_SUCCESS) @@ -182,11 +190,14 @@ int ecdsa_quote_verification(vector quote, bool use_qve) // Threshold of QvE ISV SVN. The ISV SVN of QvE used to verify quote must be greater or equal to this threshold - // e.g. You can get latest QvE ISVSVN in QvE Identity JSON file from + // e.g. You can check latest QvE ISVSVN from QvE configuration file on Github + // https://github.com/intel/SGXDataCenterAttestationPrimitives/blob/master/QuoteVerification/QvE/Enclave/linux/config.xml#L4 + // or you can get latest QvE ISVSVN in QvE Identity JSON file from // https://api.trustedservices.intel.com/sgx/certification/v3/qve/identity // Make sure you are using trusted & latest QvE ISV SVN as threshold + // Warning: The function may return erroneous result if QvE ISV SVN has been modified maliciously. // - sgx_isv_svn_t qve_isvsvn_threshold = 5; + sgx_isv_svn_t qve_isvsvn_threshold = 6; //call sgx_dcap_tvl API in SampleISVEnclave to verify QvE's report and identity // @@ -267,6 +278,14 @@ int ecdsa_quote_verification(vector quote, bool use_qve) if (dcap_ret == SGX_QL_SUCCESS && supplemental_data_size == sizeof(sgx_ql_qv_supplemental_t)) { printf("\tInfo: sgx_qv_get_quote_supplemental_data_size successfully returned.\n"); p_supplemental_data = (uint8_t*)malloc(supplemental_data_size); + if (p_supplemental_data != NULL) { + memset(p_supplemental_data, 0, sizeof(supplemental_data_size)); + } + //Just print error in sample + // + else { + printf("\tError: Cannot allocate memory for supplemental data.\n"); + } } else { if (dcap_ret != SGX_QL_SUCCESS) @@ -351,6 +370,10 @@ int ecdsa_quote_verification(vector quote, bool use_qve) } + if (p_supplemental_data) { + free(p_supplemental_data); + } + if (eid) { sgx_destroy_enclave(eid); } diff --git a/SampleCode/QuoteVerificationSample/README.md b/SampleCode/QuoteVerificationSample/README.md index 15968a1f..072314f0 100644 --- a/SampleCode/QuoteVerificationSample/README.md +++ b/SampleCode/QuoteVerificationSample/README.md @@ -40,7 +40,7 @@ Prerequisite: $ make SGX_DEBUG=1 $ ./app -quote ``` - +**Note**: Our libdcap_quoteprov.so is not built with Intel(R) Control Flow Enforcement Technology(CET) feature. If the sample is built with CET feature(it can be enabled by the compiler's default setting) and it is running on a CET enabled platform, you may encounter such an error message(or something similar): "Couldn't find the platform library. rebuild shared object with SHSTK support enabled". It means the system glibc enforces that a CET-enabled application can't load a non-CET shared library. You need to rebuild the sample by adding -fcf-protection=none option explicitly to disable CET. ## Windows Supported operating systems: diff --git a/SampleCode/RustQuoteVerificationSample/.gitignore b/SampleCode/RustQuoteVerificationSample/.gitignore new file mode 100644 index 00000000..96ef6c0b --- /dev/null +++ b/SampleCode/RustQuoteVerificationSample/.gitignore @@ -0,0 +1,2 @@ +/target +Cargo.lock diff --git a/SampleCode/RustQuoteVerificationSample/Cargo.toml b/SampleCode/RustQuoteVerificationSample/Cargo.toml new file mode 100644 index 00000000..5131d88b --- /dev/null +++ b/SampleCode/RustQuoteVerificationSample/Cargo.toml @@ -0,0 +1,11 @@ +[package] +name = "app" +version = "0.1.0" +edition = "2018" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +sgx-dcap-quoteverify-rs = { path = "../../QuoteVerification/dcap_quoteverify/sgx-dcap-quoteverify-rs"} +sgx-dcap-quoteverify-sys = { path = "../../QuoteVerification/dcap_quoteverify/sgx-dcap-quoteverify-sys"} +clap = "2.34" diff --git a/SampleCode/RustQuoteVerificationSample/README.md b/SampleCode/RustQuoteVerificationSample/README.md new file mode 100644 index 00000000..c8751f94 --- /dev/null +++ b/SampleCode/RustQuoteVerificationSample/README.md @@ -0,0 +1,72 @@ +Intel(R) Software Guard Extensions Data Center Attestation Primitives (Intel(R) SGX DCAP) Rust Quote Verification SampleCode +================================================ + +## Linux +Supported operating systems: +* Ubuntu* 18.04 LTS Desktop 64bits +* Ubuntu* 18.04 LTS Server 64bits +* Ubuntu* 20.04 LTS Server 64bits +* Red Hat Enterprise Linux Server release 8.2 64bits +* CentOS 8.2 64bits + +Requirements: +* make +* gcc +* g++ +* bash shell +* clang +* Rust and Cargo + +Prerequisite: +* Intel(R) SGX DCAP Driver +* Intel(R) SGX SDK +* Intel(R) SGX DCAP Packages +* Intel(R) SGX DCAP PCCS (Provisioning Certificate Caching Service) + +*Please refer to SGX DCAP Linux installation guide "https://download.01.org/intel-sgx/sgx-dcap/#version#/linux/docs/Intel_SGX_DCAP_Linux_SW_Installation_Guide.pdf" to install above dependencies*
+*Note that you need to change **\#version\#** to actual version number in URL, such as 1.4.*
+*Note that you need to install **libsgx-dcap-quote-verify-dev** for this package.* + +1. Generate an ECDSA quote with certification data of type 5 using *QuoteGenerationSample* +``` + $ cd ../QuoteGenerationSample/ + $ make + $ ./app +``` + +2. Build and run *RustQuoteVerificationSample* to verify a given quote + + Trusted quote verification is processed inside the Intel(R) QvE. In this sample, we borrowed enclave from [QuoteVerificationSample](../QuoteVerificationSample) to perform quote verification. + + Go to *QuoteVerificationSample* and build *enclave.signed.so*. + ``` + $ cd ../QuoteVerificationSample/ + $ make SGX_DEBUG=1 + ``` + + Go back to *RustQuoteVerificationSample* and build static library for *Enclave_u.o*. + ``` + $ cd ../RustQuoteVerificationSample/ + $ ar rs libenclave_untrusted.a ../QuoteVerificationSample/App/Enclave_u.o + ``` + + + Build the and run with default quote path: + ``` + $ cargo build + $ ./target/debug/app + ``` + + Or run with specified quote path: + + ``` + $ ./target/debug/app --quote + ``` + You can also combine building and running with a single Cargo command: + ``` + $ cargo run + ``` + and to specify quote path: + ``` + $ cargo run -- --quote + ``` diff --git a/SampleCode/RustQuoteVerificationSample/build.rs b/SampleCode/RustQuoteVerificationSample/build.rs new file mode 100644 index 00000000..c721f649 --- /dev/null +++ b/SampleCode/RustQuoteVerificationSample/build.rs @@ -0,0 +1,34 @@ +/* + * Copyright (C) 2011-2021 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. + * + */ + +fn main() { + println!(r"cargo:rustc-link-search=."); +} \ No newline at end of file diff --git a/SampleCode/RustQuoteVerificationSample/src/main.rs b/SampleCode/RustQuoteVerificationSample/src/main.rs new file mode 100644 index 00000000..eb1b61ab --- /dev/null +++ b/SampleCode/RustQuoteVerificationSample/src/main.rs @@ -0,0 +1,342 @@ +/* + * Copyright (C) 2011-2021 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. + * + */ + +use clap::{Arg, App}; +use std::mem::size_of; +use std::convert::TryInto; +use std::time::SystemTime; + +use sgx_dcap_quoteverify_rs as qvl; +use sgx_dcap_quoteverify_sys as qvl_sys; + + +#[cfg(debug_assertions)] +const SGX_DEBUG_FLAG: i32 = 1; +#[cfg(not(debug_assertions))] +const SGX_DEBUG_FLAG: i32 = 0; + +const SAMPLE_ISV_ENCLAVE: &str = "../QuoteVerificationSample/enclave.signed.so\0"; +const DEFAULT_QUOTE: &str = "../QuoteGenerationSample/quote.dat"; + + +// C library bindings + +#[link(name = "sgx_urts")] +extern { + fn sgx_create_enclave(file_name: *const u8, + debug: i32, + launch_token: *mut [u8; 1024usize], + launch_token_updated: *mut i32, + enclave_id: *mut u64, + misc_attr: *mut qvl_sys::sgx_misc_attribute_t) -> u32; + fn sgx_destroy_enclave(enclave_id: u64) -> u32; +} + +#[link(name = "enclave_untrusted")] +extern { + fn ecall_get_target_info(eid: u64, retval: *mut u32, target_info: *mut qvl_sys::sgx_target_info_t) -> u32; + fn sgx_tvl_verify_qve_report_and_identity(eid: u64, retval: *mut qvl::quote3_error_t, + p_quote: *const u8, quote_size: u32, + p_qve_report_info: *const qvl::sgx_ql_qe_report_info_t, + expiration_check_date: i64, + collateral_expiration_status: u32, + quote_verification_result: qvl::sgx_ql_qv_result_t, + p_supplemental_data: *const u8, + supplemental_data_size: u32, + qve_isvsvn_threshold: qvl_sys::sgx_isv_svn_t) -> u32; +} + + +/// Quote verification with QvE/QVL +/// +/// # Param +/// - **quote**\ +/// ECDSA quote buffer. +/// - **use_qve**\ +/// Set quote verification mode.\ +/// - If true, quote verification will be performed by Intel QvE. +/// - If false, quote verification will be performed by untrusted QVL. +/// +fn ecdsa_quote_verification(quote: &[u8], use_qve: bool) { + + let mut supplemental_data_size = 0u32; // mem::zeroed() is safe as long as the struct doesn't have zero-invalid types, like pointers + let mut supplemental_data: qvl::sgx_ql_qv_supplemental_t = unsafe { std::mem::zeroed() }; + let mut quote_verification_result = qvl::sgx_ql_qv_result_t::SGX_QL_QV_RESULT_UNSPECIFIED; + let mut qve_report_info: qvl::sgx_ql_qe_report_info_t = unsafe { std::mem::zeroed() }; + let rand_nonce = "59jslk201fgjmm;\0"; + let mut collateral_expiration_status = 1u32; + + let mut updated = 0i32; + let mut verify_qveid_ret = qvl::quote3_error_t::SGX_QL_ERROR_UNEXPECTED; + let mut eid: u64 = 0; + let mut token = [0u8; 1024usize]; + + if use_qve { + + // Trusted quote verification + + // set nonce + // + qve_report_info.nonce.rand.copy_from_slice(rand_nonce.as_bytes()); + + // get target info of SampleISVEnclave. QvE will target the generated report to this enclave. + // + let sgx_ret = unsafe { sgx_create_enclave(SAMPLE_ISV_ENCLAVE.as_ptr(), SGX_DEBUG_FLAG, + &mut token as *mut [u8; 1024usize], + &mut updated as *mut i32, + &mut eid as *mut u64, + std::ptr::null_mut()) }; + if sgx_ret != 0 { + println!("\tError: Can't load SampleISVEnclave: {:#04x}", sgx_ret); + return; + } + let mut get_target_info_ret = 1u32; + let sgx_ret = unsafe { ecall_get_target_info(eid, &mut get_target_info_ret as *mut u32, + &mut qve_report_info.app_enclave_target_info as *mut qvl_sys::sgx_target_info_t) }; + if sgx_ret != 0 || get_target_info_ret != 0 { + println!("\tError in sgx_get_target_info. {:#04x}", get_target_info_ret); + } else { + println!("\tInfo: get target info successfully returned."); + } + + // call DCAP quote verify library to set QvE loading policy + // + let dcap_ret = qvl::sgx_qv_set_enclave_load_policy(qvl::sgx_ql_request_policy_t::SGX_QL_DEFAULT); + if qvl::quote3_error_t::SGX_QL_SUCCESS == dcap_ret { + println!("\tInfo: sgx_qv_set_enclave_load_policy successfully returned."); + } else { + println!("\tError: sgx_qv_set_enclave_load_policy failed: {:#04x}", dcap_ret as u32); + } + + // call DCAP quote verify library to get supplemental data size + // + let dcap_ret = qvl::sgx_qv_get_quote_supplemental_data_size(&mut supplemental_data_size); + if qvl::quote3_error_t::SGX_QL_SUCCESS == dcap_ret && std::mem::size_of::() as u32 == supplemental_data_size { + println!("\tInfo: sgx_qv_get_quote_supplemental_data_size successfully returned."); + } else { + if dcap_ret != qvl::quote3_error_t::SGX_QL_SUCCESS { + println!("\tError: sgx_qv_get_quote_supplemental_data_size failed: {:#04x}", dcap_ret as u32); + } + if supplemental_data_size != size_of::().try_into().unwrap() { + println!("\tWarning: Quote supplemental data size is different between DCAP QVL and QvE, please make sure you installed DCAP QVL and QvE from same release."); + } + supplemental_data_size = 0u32; + } + + // set current time. This is only for sample purposes, in production mode a trusted time should be used. + // + let current_time: i64 = SystemTime::now().duration_since(SystemTime::UNIX_EPOCH).unwrap().as_secs().try_into().unwrap(); + + let p_supplemental_data = match supplemental_data_size { + 0 => None, + _ => Some(&mut supplemental_data), + }; + + + // call DCAP quote verify library for quote verification + // here you can choose 'trusted' or 'untrusted' quote verification by specifying parameter '&qve_report_info' + // if '&qve_report_info' is NOT NULL, this API will call Intel QvE to verify quote + // if '&qve_report_info' is NULL, this API will call 'untrusted quote verify lib' to verify quote, this mode doesn't rely on SGX capable system, but the results can not be cryptographically authenticated + let dcap_ret = qvl::sgx_qv_verify_quote( + quote, + None, + current_time, + &mut collateral_expiration_status, + &mut quote_verification_result, + Some(&mut qve_report_info), + supplemental_data_size, + p_supplemental_data); + if qvl::quote3_error_t::SGX_QL_SUCCESS == dcap_ret { + println!("\tInfo: App: sgx_qv_verify_quote successfully returned."); + } else { + println!("\tError: App: sgx_qv_verify_quote failed: {:#04x}", dcap_ret as u32); + } + + + // Threshold of QvE ISV SVN. The ISV SVN of QvE used to verify quote must be greater or equal to this threshold + // e.g. You can get latest QvE ISVSVN in QvE Identity JSON file from + // https://api.trustedservices.intel.com/sgx/certification/v2/qve/identity + // Make sure you are using trusted & latest QvE ISV SVN as threshold + // + let qve_isvsvn_threshold: qvl_sys::sgx_isv_svn_t = 5; + + let p_supplemental_data = match supplemental_data_size { + 0 => std::ptr::null(), + _ => &supplemental_data as *const qvl::sgx_ql_qv_supplemental_t as *const u8, + }; + + // call sgx_dcap_tvl API in SampleISVEnclave to verify QvE's report and identity + // + let sgx_ret = unsafe { sgx_tvl_verify_qve_report_and_identity(eid, &mut verify_qveid_ret as *mut qvl::quote3_error_t, + quote.as_ptr(), quote.len() as u32, + &qve_report_info as *const qvl::sgx_ql_qe_report_info_t, + current_time, + collateral_expiration_status, + quote_verification_result, + p_supplemental_data, + supplemental_data_size, + qve_isvsvn_threshold) }; + if sgx_ret != 0 || verify_qveid_ret != qvl::quote3_error_t::SGX_QL_SUCCESS { + println!("\tError: Ecall: Verify QvE report and identity failed. {:#04x}", verify_qveid_ret as u32); + } else { + println!("\tInfo: Ecall: Verify QvE report and identity successfully returned.") + } + + unsafe { sgx_destroy_enclave(eid) }; + + } else { + + // Untrusted quote verification + + // call DCAP quote verify library to get supplemental data size + // + let dcap_ret = qvl::sgx_qv_get_quote_supplemental_data_size(&mut supplemental_data_size); + if qvl::quote3_error_t::SGX_QL_SUCCESS == dcap_ret && std::mem::size_of::() as u32 == supplemental_data_size { + println!("\tInfo: sgx_qv_get_quote_supplemental_data_size successfully returned."); + } else { + if dcap_ret != qvl::quote3_error_t::SGX_QL_SUCCESS { + println!("\tError: sgx_qv_get_quote_supplemental_data_size failed: {:#04x}", dcap_ret as u32); + } + if supplemental_data_size != size_of::().try_into().unwrap() { + println!("\tWarning: Quote supplemental data size is different between DCAP QVL and QvE, please make sure you installed DCAP QVL and QvE from same release."); + } + supplemental_data_size = 0u32; + } + + // set current time. This is only for sample purposes, in production mode a trusted time should be used. + // + let current_time: i64 = SystemTime::now().duration_since(SystemTime::UNIX_EPOCH).unwrap().as_secs().try_into().unwrap(); + + let p_supplemental_data = match supplemental_data_size { + 0 => None, + _ => Some(&mut supplemental_data), + }; + + + // call DCAP quote verify library for quote verification + // here you can choose 'trusted' or 'untrusted' quote verification by specifying parameter '&qve_report_info' + // if '&qve_report_info' is NOT NULL, this API will call Intel QvE to verify quote + // if '&qve_report_info' is NULL, this API will call 'untrusted quote verify lib' to verify quote, this mode doesn't rely on SGX capable system, but the results can not be cryptographically authenticated + let dcap_ret = qvl::sgx_qv_verify_quote( + quote, + None, + current_time, + &mut collateral_expiration_status, + &mut quote_verification_result, + None, + supplemental_data_size, + p_supplemental_data); + if qvl::quote3_error_t::SGX_QL_SUCCESS == dcap_ret { + println!("\tInfo: App: sgx_qv_verify_quote successfully returned."); + } else { + println!("\tError: App: sgx_qv_verify_quote failed: {:#04x}", dcap_ret as u32); + } + + } + + // check verification result + // + match quote_verification_result { + qvl::sgx_ql_qv_result_t::SGX_QL_QV_RESULT_OK => { + // check verification collateral expiration status + // this value should be considered in your own attestation/verification policy + // + if 0u32 == collateral_expiration_status { + println!("\tInfo: App: Verification completed successfully."); + } else { + println!("\tWarning: App: Verification completed, but collateral is out of date based on 'expiration_check_date' you provided."); + } + }, + qvl::sgx_ql_qv_result_t::SGX_QL_QV_RESULT_CONFIG_NEEDED | + qvl::sgx_ql_qv_result_t::SGX_QL_QV_RESULT_OUT_OF_DATE | + qvl::sgx_ql_qv_result_t::SGX_QL_QV_RESULT_OUT_OF_DATE_CONFIG_NEEDED | + qvl::sgx_ql_qv_result_t::SGX_QL_QV_RESULT_SW_HARDENING_NEEDED | + qvl::sgx_ql_qv_result_t::SGX_QL_QV_RESULT_CONFIG_AND_SW_HARDENING_NEEDED => { + println!("\tWarning: App: Verification completed with Non-terminal result: {:x}", quote_verification_result as u32); + }, + qvl::sgx_ql_qv_result_t::SGX_QL_QV_RESULT_INVALID_SIGNATURE | + qvl::sgx_ql_qv_result_t::SGX_QL_QV_RESULT_REVOKED | + qvl::sgx_ql_qv_result_t::SGX_QL_QV_RESULT_UNSPECIFIED | _ => { + println!("\tError: App: Verification completed with Terminal result: {:x}", quote_verification_result as u32); + }, + } + + // check supplemental data if necessary + // + if supplemental_data_size > 0 { + + // you can check supplemental data based on your own attestation/verification policy + // here we only print supplemental data version for demo usage + // + println!("\tInfo: Supplemental data version: {}", supplemental_data.version); + } +} + + +fn main() { + // Specify quote path from command line arguments + // + let matches = App::new("Rust Quote Verification Sample App:") + .version("1.0") + .arg(Arg::with_name("quote_path") + .long("quote") + .value_name("FILE") + .help(format!("Specify quote path, default is {}", DEFAULT_QUOTE).as_str())) + .get_matches(); + let quote_path = matches.value_of("quote_path").unwrap_or(DEFAULT_QUOTE); + + //read quote from file + // + let quote = std::fs::read(quote_path).expect("Unable to read quote file"); + + println!("Info: ECDSA quote path: {}", quote_path); + + + // We demonstrate two different types of quote verification + // a. Trusted quote verification - quote will be verified by Intel QvE + // b. Untrusted quote verification - quote will be verified by untrusted QVL (Quote Verification Library) + // this mode doesn't rely on SGX capable system, but the results can not be cryptographically authenticated + // + + // Trusted quote verification, ignore error checking + // + println!("\nTrusted quote verification:"); + ecdsa_quote_verification("e, true); + + println!("\n==========================================="); + + // Unrusted quote verification, ignore error checking + // + println!("\nUntrusted quote verification:"); + ecdsa_quote_verification("e, false); + + println!(); +} diff --git a/SampleCode/TDQuoteVerificationSample/App/App.cpp b/SampleCode/TDQuoteVerificationSample/App/App.cpp new file mode 100644 index 00000000..27126514 --- /dev/null +++ b/SampleCode/TDQuoteVerificationSample/App/App.cpp @@ -0,0 +1,409 @@ +/* + * Copyright (C) 2011-2021 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 +#include +#include "sgx_urts.h" +#include +#ifdef TRUSTED_VERIFY +#include +#include "Enclave_u.h" +#endif +#include "sgx_ql_quote.h" +#include "sgx_dcap_quoteverify.h" + +#ifndef _MSC_VER + +#define SAMPLE_ISV_ENCLAVE "enclave.signed.so" +#define DEFAULT_QUOTE "../tdx-quote-generation-sample/quote.dat" + +#else + +#define SAMPLE_ISV_ENCLAVE "enclave.signed.dll" +#define DEFAULT_QUOTE "..\\..\\..\\TDQuoteGenerationSample\\x64\\Debug\\quote.dat" + +#define strncpy strncpy_s +#endif + + + +using namespace std; + + +vector readBinaryContent(const string& filePath) +{ + ifstream file(filePath, ios::binary); + if (!file.is_open()) + { + printf("Error: Unable to open quote file %s\n", filePath.c_str()); + return {}; + } + + file.seekg(0, ios_base::end); + streampos fileSize = file.tellg(); + + file.seekg(0, ios_base::beg); + vector retVal(fileSize); + file.read(reinterpret_cast(retVal.data()), fileSize); + file.close(); + return retVal; +} +#define PATHSIZE 0x418U + + +/** + * @param quote - ECDSA quote buffer + * @param use_qve - Set quote verification mode + * If true, quote verification will be performed by Intel QvE + * If false, quote verification will be performed by untrusted QVL + */ + +int ecdsa_quote_verification(vector quote, bool use_qve) +{ + int ret = 0; + time_t current_time = 0; + uint32_t supplemental_data_size = 0; + uint8_t *p_supplemental_data = NULL; + quote3_error_t dcap_ret = SGX_QL_ERROR_UNEXPECTED; + sgx_ql_qv_result_t quote_verification_result = SGX_QL_QV_RESULT_UNSPECIFIED; + uint32_t collateral_expiration_status = 1; + + +#ifdef TRUSTED_VERIFY + sgx_status_t sgx_ret = SGX_SUCCESS; + unsigned char rand_nonce[16] = "59jslk201fgjmm;"; + sgx_ql_qe_report_info_t qve_report_info; + sgx_launch_token_t token = { 0 }; + + int updated = 0; + quote3_error_t verify_qveid_ret = SGX_QL_ERROR_UNEXPECTED; + sgx_enclave_id_t eid = 0; + // Trusted quote verification + if (use_qve) { + + //set nonce + // + memcpy(qve_report_info.nonce.rand, rand_nonce, sizeof(rand_nonce)); + + //get target info of SampleISVEnclave. QvE will target the generated report to this enclave. + // + sgx_ret = sgx_create_enclave(SAMPLE_ISV_ENCLAVE, SGX_DEBUG_FLAG, &token, &updated, &eid, NULL); + if (sgx_ret != SGX_SUCCESS) { + printf("\tError: Failed to load Enclave, please make sure the environment is SGX capable(N.B SGX is not supported inside TD).\n"); + return -1; + } + sgx_status_t get_target_info_ret; + sgx_ret = ecall_get_target_info(eid, &get_target_info_ret, &qve_report_info.app_enclave_target_info); + if (sgx_ret != SGX_SUCCESS || get_target_info_ret != SGX_SUCCESS) { + printf("\tError in sgx_get_target_info. 0x%04x\n", get_target_info_ret); + } + else { + printf("\tInfo: get target info successfully returned.\n"); + } + + //call DCAP quote verify library to set QvE loading policy + // + dcap_ret = sgx_qv_set_enclave_load_policy(SGX_QL_DEFAULT); + if (dcap_ret == SGX_QL_SUCCESS) { + printf("\tInfo: sgx_qv_set_enclave_load_policy successfully returned.\n"); + } + else { + printf("\tError: sgx_qv_set_enclave_load_policy failed: 0x%04x\n", dcap_ret); + } + + + //call DCAP quote verify library to get supplemental data size + // + dcap_ret = tdx_qv_get_quote_supplemental_data_size(&supplemental_data_size); + if (dcap_ret == SGX_QL_SUCCESS) { + printf("\tInfo: tdx_qv_get_quote_supplemental_data_size successfully returned.\n"); + p_supplemental_data = (uint8_t*)malloc(supplemental_data_size); + if (p_supplemental_data != NULL) { + memset(p_supplemental_data, 0, sizeof(supplemental_data_size)); + } + //Just print error in sample + // + else { + printf("\tError: Cannot allocate memory for supplemental data.\n"); + } + } + else { + printf("\tError: tdx_qv_get_quote_supplemental_data_size failed: 0x%04x\n", dcap_ret); + supplemental_data_size = 0; + } + + //set current time. This is only for sample purposes, in production mode a trusted time should be used. + // + current_time = time(NULL); + + + //call DCAP quote verify library for quote verification + //here you can choose 'trusted' or 'untrusted' quote verification by specifying parameter '&qve_report_info' + //if '&qve_report_info' is NOT NULL, this API will call Intel QvE to verify quote + //if '&qve_report_info' is NULL, this API will call 'untrusted quote verify lib' to verify quote, this mode doesn't rely on SGX capable system, but the results can not be cryptographically authenticated + dcap_ret = tdx_qv_verify_quote( + quote.data(), (uint32_t)quote.size(), + NULL, + current_time, + &collateral_expiration_status, + "e_verification_result, + &qve_report_info, + supplemental_data_size, + p_supplemental_data); + if (dcap_ret == SGX_QL_SUCCESS) { + printf("\tInfo: App: tdx_qv_verify_quote successfully returned.\n"); + } else { + printf("\tError: App: tdx_qv_verify_quote failed: 0x%04x\n", dcap_ret); + } + + + // Threshold of QvE ISV SVN. The ISV SVN of QvE used to verify quote must be greater or equal to this threshold + // e.g. You can get latest QvE ISVSVN in QvE Identity JSON file from + // https://api.trustedservices.intel.com/sgx/certification/v4/qve/identity + // Make sure you are using trusted & latest QvE ISV SVN as threshold + // + sgx_isv_svn_t qve_isvsvn_threshold = 5; + + //call sgx_dcap_tvl API in SampleISVEnclave to verify QvE's report and identity + // + sgx_ret = sgx_tvl_verify_qve_report_and_identity(eid, + &verify_qveid_ret, + quote.data(), + (uint32_t) quote.size(), + &qve_report_info, + current_time, + collateral_expiration_status, + quote_verification_result, + p_supplemental_data, + supplemental_data_size, + qve_isvsvn_threshold); + + if (sgx_ret != SGX_SUCCESS || verify_qveid_ret != SGX_QL_SUCCESS) { + printf("\tError: Ecall: Verify QvE report and identity failed. 0x%04x\n", verify_qveid_ret); + } + else { + printf("\tInfo: Ecall: Verify QvE report and identity successfully returned.\n"); + } + + //check verification result + // + switch (quote_verification_result) + { + case SGX_QL_QV_RESULT_OK: + //check verification collateral expiration status + //this value should be considered in your own attestation/verification policy + // + if (collateral_expiration_status == 0) { + printf("\tInfo: App: Verification completed successfully.\n"); + ret = 0; + } + else { + printf("\tWarning: App: Verification completed, but collateral is out of date based on 'expiration_check_date' you provided.\n"); + ret = 1; + } + break; + case SGX_QL_QV_RESULT_CONFIG_NEEDED: + case SGX_QL_QV_RESULT_OUT_OF_DATE: + case SGX_QL_QV_RESULT_OUT_OF_DATE_CONFIG_NEEDED: + case SGX_QL_QV_RESULT_SW_HARDENING_NEEDED: + case SGX_QL_QV_RESULT_CONFIG_AND_SW_HARDENING_NEEDED: + printf("\tWarning: App: Verification completed with Non-terminal result: %x\n", quote_verification_result); + ret = 1; + break; + case SGX_QL_QV_RESULT_INVALID_SIGNATURE: + case SGX_QL_QV_RESULT_REVOKED: + case SGX_QL_QV_RESULT_UNSPECIFIED: + default: + printf("\tError: App: Verification completed with Terminal result: %x\n", quote_verification_result); + ret = -1; + break; + } + } + + + + // Untrusted quote verification + else { +#endif + //call DCAP quote verify library to get supplemental data size + // + (void)(use_qve); + dcap_ret = tdx_qv_get_quote_supplemental_data_size(&supplemental_data_size); + if (dcap_ret == SGX_QL_SUCCESS && supplemental_data_size == sizeof(sgx_ql_qv_supplemental_t)) { + printf("\tInfo: tdx_qv_get_quote_supplemental_data_size successfully returned.\n"); + p_supplemental_data = (uint8_t*)malloc(supplemental_data_size); + if (p_supplemental_data != NULL) { + memset(p_supplemental_data, 0, sizeof(supplemental_data_size)); + } + //Just print error in sample + // + else { + printf("\tError: Cannot allocate memory for supplemental data.\n"); + } + } + else { + printf("\tError: tdx_qv_get_quote_supplemental_data_size failed: 0x%04x\n", dcap_ret); + supplemental_data_size = 0; + } + + //set current time. This is only for sample purposes, in production mode a trusted time should be used. + // + current_time = time(NULL); + + + //call DCAP quote verify library for quote verification + dcap_ret = tdx_qv_verify_quote( + quote.data(), (uint32_t)quote.size(), + NULL, + current_time, + &collateral_expiration_status, + "e_verification_result, + NULL, + supplemental_data_size, + p_supplemental_data); + if (dcap_ret == SGX_QL_SUCCESS) { + printf("\tInfo: App: tdx_qv_verify_quote successfully returned.\n"); + } + else { + printf("\tError: App: tdx_qv_verify_quote failed: 0x%04x\n", dcap_ret); + } + + //check verification result + switch (quote_verification_result) + { + case SGX_QL_QV_RESULT_OK: + //check verification collateral expiration status + //this value should be considered in your own attestation/verification policy + // + if (collateral_expiration_status == 0) { + printf("\tInfo: App: Verification completed successfully.\n"); + ret = 0; + } + else { + printf("\tWarning: App: Verification completed, but collateral is out of date based on 'expiration_check_date' you provided.\n"); + ret = 1; + } + break; + case SGX_QL_QV_RESULT_CONFIG_NEEDED: + case SGX_QL_QV_RESULT_OUT_OF_DATE: + case SGX_QL_QV_RESULT_OUT_OF_DATE_CONFIG_NEEDED: + case SGX_QL_QV_RESULT_SW_HARDENING_NEEDED: + case SGX_QL_QV_RESULT_CONFIG_AND_SW_HARDENING_NEEDED: + printf("\tWarning: App: Verification completed with Non-terminal result: %x\n", quote_verification_result); + ret = 1; + break; + case SGX_QL_QV_RESULT_INVALID_SIGNATURE: + case SGX_QL_QV_RESULT_REVOKED: + case SGX_QL_QV_RESULT_UNSPECIFIED: + default: + printf("\tError: App: Verification completed with Terminal result: %x\n", quote_verification_result); + ret = -1; + break; + } + +#ifdef TRUSTED_VERIFY + } + + + if (eid) { + sgx_destroy_enclave(eid); + } +#endif + + if (p_supplemental_data) { + free(p_supplemental_data); + } + + return ret; +} + + +void usage() +{ + printf("\nUsage:\n"); + printf("\tPlease specify quote path, e.g. \"./app -quote \"\n"); + printf("\tDefault quote path is %s when no command line args\n\n", DEFAULT_QUOTE); +} + + +/* Application entry */ +int main(int argc, char *argv[]) +{ + vector quote; + + char quote_path[PATHSIZE] = { '\0' }; + + //Just for sample use, better to change solid command line args solution in production env + if (argc != 1 && argc != 3) { + usage(); + return 0; + } + + if (argv[1] && argv[2]) { + if (!strcmp(argv[1], "-quote")) { + strncpy(quote_path, argv[2], PATHSIZE-1); + quote_path[PATHSIZE-1]= '\0'; + } + } + + if (*quote_path == '\0') { + strncpy(quote_path, DEFAULT_QUOTE, PATHSIZE-1); + quote_path[PATHSIZE-1]= '\0'; + } + + //read quote from file + quote = readBinaryContent(quote_path); + if (quote.empty()) { + usage(); + return -1; + } + + printf("Info: ECDSA quote path: %s\n", quote_path); +#ifdef TRUSTED_VERIFY + // Trusted quote verification, ignore error checking + printf("\nTrusted quote verification:\n"); + ecdsa_quote_verification(quote, true); + + printf("\n===========================================\n"); +#endif + + + // quote verification, ignore error checking + printf("\nUntrusted quote verification:\n"); + ecdsa_quote_verification(quote, false); + + printf("\n"); + + return 0; +} diff --git a/SampleCode/TDQuoteVerificationSample/Enclave/Enclave.config.xml b/SampleCode/TDQuoteVerificationSample/Enclave/Enclave.config.xml new file mode 100644 index 00000000..e94c9bc5 --- /dev/null +++ b/SampleCode/TDQuoteVerificationSample/Enclave/Enclave.config.xml @@ -0,0 +1,12 @@ + + 0 + 0 + 0x40000 + 0x100000 + 10 + 1 + + 0 + 0 + 0xFFFFFFFF + diff --git a/SampleCode/TDQuoteVerificationSample/Enclave/Enclave.cpp b/SampleCode/TDQuoteVerificationSample/Enclave/Enclave.cpp new file mode 100644 index 00000000..29fad8d4 --- /dev/null +++ b/SampleCode/TDQuoteVerificationSample/Enclave/Enclave.cpp @@ -0,0 +1,41 @@ +/* + * Copyright (C) 2011-2021 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 "Enclave_t.h" /* print_string */ +#include +#include /* vsnprintf */ +#include +#include "sgx_utils.h" + + +sgx_status_t ecall_get_target_info(sgx_target_info_t* target_info) { + return sgx_self_target(target_info); +} diff --git a/SampleCode/TDQuoteVerificationSample/Enclave/Enclave.edl b/SampleCode/TDQuoteVerificationSample/Enclave/Enclave.edl new file mode 100644 index 00000000..059f143d --- /dev/null +++ b/SampleCode/TDQuoteVerificationSample/Enclave/Enclave.edl @@ -0,0 +1,52 @@ +/* + * Copyright (C) 2011-2021 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. + * + */ + +/* Enclave.edl - Top EDL file. */ + +enclave { + + from "sgx_tstdc.edl" import *; + from "sgx_dcap_tvl.edl" import *; + + /* Import ECALL/OCALL from sub-directory EDLs. + * [from]: specifies the location of EDL file. + * [import]: specifies the functions to import, + * [*]: implies to import all functions. + */ + + + trusted { + + public sgx_status_t ecall_get_target_info([out] sgx_target_info_t* target_info); + + }; + +}; diff --git a/SampleCode/TDQuoteVerificationSample/Enclave/Enclave.lds b/SampleCode/TDQuoteVerificationSample/Enclave/Enclave.lds new file mode 100644 index 00000000..f5f35d5b --- /dev/null +++ b/SampleCode/TDQuoteVerificationSample/Enclave/Enclave.lds @@ -0,0 +1,10 @@ +enclave.so +{ + global: + g_global_data_sim; + g_global_data; + enclave_entry; + g_peak_heap_used; + local: + *; +}; diff --git a/SampleCode/TDQuoteVerificationSample/Enclave/Enclave_private_sample.pem b/SampleCode/TDQuoteVerificationSample/Enclave/Enclave_private_sample.pem new file mode 100644 index 00000000..529d07be --- /dev/null +++ b/SampleCode/TDQuoteVerificationSample/Enclave/Enclave_private_sample.pem @@ -0,0 +1,39 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIG4gIBAAKCAYEAroOogvsj/fZDZY8XFdkl6dJmky0lRvnWMmpeH41Bla6U1qLZ +AmZuyIF+mQC/cgojIsrBMzBxb1kKqzATF4+XwPwgKz7fmiddmHyYz2WDJfAjIveJ +ZjdMjM4+EytGlkkJ52T8V8ds0/L2qKexJ+NBLxkeQLfV8n1mIk7zX7jguwbCG1Pr +nEMdJ3Sew20vnje+RsngAzdPChoJpVsWi/K7cettX/tbnre1DL02GXc5qJoQYk7b +3zkmhz31TgFrd9VVtmUGyFXAysuSAb3EN+5VnHGr0xKkeg8utErea2FNtNIgua8H +ONfm9Eiyaav1SVKzPHlyqLtcdxH3I8Wg7yqMsaprZ1n5A1v/levxnL8+It02KseD +5HqV4rf/cImSlCt3lpRg8U5E1pyFQ2IVEC/XTDMiI3c+AR+w2jSRB3Bwn9zJtFlW +KHG3m1xGI4ck+Lci1JvWWLXQagQSPtZTsubxTQNx1gsgZhgv1JHVZMdbVlAbbRMC +1nSuJNl7KPAS/VfzAgEDAoIBgHRXxaynbVP5gkO0ug6Qw/E27wzIw4SmjsxG6Wpe +K7kfDeRskKxESdsA/xCrKkwGwhcx1iIgS5+Qscd1Yg+1D9X9asd/P7waPmWoZd+Z +AhlKwhdPsO7PiF3e1AzHhGQwsUTt/Y/aSI1MpHBvy2/s1h9mFCslOUxTmWw0oj/Q +ldIEgWeNR72CE2+jFIJIyml6ftnb6qzPiga8Bm48ubKh0kvySOqnkmnPzgh+JBD6 +JnBmtZbfPT97bwTT+N6rnPqOOApvfHPf15kWI8yDbprG1l4OCUaIUH1AszxLd826 +5IPM+8gINLRDP1MA6azECPjTyHXhtnSIBZCyWSVkc05vYmNXYUNiXWMajcxW9M02 +wKzFELO8NCEAkaTPxwo4SCyIjUxiK1LbQ9h8PSy4c1+gGP4LAMR8xqP4QKg6zdu9 +osUGG/xRe/uufgTBFkcjqBHtK5L5VI0jeNIUAgW/6iNbYXjBMJ0GfauLs+g1VsOm +WfdgXzsb9DYdMa0OXXHypmV4GwKBwQDUwQj8RKJ6c8cT4vcWCoJvJF00+RFL+P3i +Gx2DLERxRrDa8AVGfqaCjsR+3vLgG8V/py+z+dxZYSqeB80Qeo6PDITcRKoeAYh9 +xlT3LJOS+k1cJcEmlbbO2IjLkTmzSwa80fWexKu8/Xv6vv15gpqYl1ngYoqJM3pd +vzmTIOi7MKSZ0WmEQavrZj8zK4endE3v0eAEeQ55j1GImbypSf7Idh7wOXtjZ7WD +Dg6yWDrri+AP/L3gClMj8wsAxMV4ZR8CgcEA0fzDHkFa6raVOxWnObmRoDhAtE0a +cjUj976NM5yyfdf2MrKy4/RhdTiPZ6b08/lBC/+xRfV3xKVGzacm6QjqjZrUpgHC +0LKiZaMtccCJjLtPwQd0jGQEnKfMFaPsnhOc5y8qVkCzVOSthY5qhz0XNotHHFmJ +gffVgB0iqrMTvSL7IA2yqqpOqNRlhaYhNl8TiFP3gIeMtVa9rZy31JPgT2uJ+kfo +gV7sdTPEjPWZd7OshGxWpT6QfVDj/T9T7L6tAoHBAI3WBf2DFvxNL2KXT2QHAZ9t +k3imC4f7U+wSE6zILaDZyzygA4RUbwG0gv8/TJVn2P/Eynf76DuWHGlaiLWnCbSz +Az2DHBQBBaku409zDQym3j1ugMRjzzSQWzJg0SIyBH3hTmnYcn3+Uqcp/lEBvGW6 +O+rsXFt3pukqJmIV8HzLGGaLm62BHUeZf3dyWm+i3p/hQAL7Xvu04QW70xuGqdr5 +afV7p5eaeQIJXyGQJ0eylV/90+qxjMKiB1XYg6WYvwKBwQCL/ddpgOdHJGN8uRom +e7Zq0Csi3hGheMKlKbN3vcxT5U7MdyHtTZZOJbTvxKNNUNYH/8uD+PqDGNneb29G +BfGzvI3EASyLIcGZF3OhKwZd0jUrWk2y7Vhob91jwp2+t73vdMbkKyI4mHOuXvGv +fg95si9oO7EBT+Oqvhccd2J+F1IVXncccYnF4u5ZGWt5lLewN/pVr7MjjykeaHqN +t+rfnQam2psA6fL4zS2zTmZPzR2tnY8Y1GBTi0Ko1OKd1HMCgcAb5cB/7/AQlhP9 +yQa04PLH9ygQkKKptZp7dy5WcWRx0K/hAHRoi2aw1wZqfm7VBNu2SLcs90kCCCxp +6C5sfJi6b8NpNbIPC+sc9wsFr7pGo9SFzQ78UlcWYK2Gu2FxlMjonhka5hvo4zvg +WxlpXKEkaFt3gLd92m/dMqBrHfafH7VwOJY2zT3WIpjwuk0ZzmRg5p0pG/svVQEH +NZmwRwlopysbR69B/n1nefJ84UO50fLh5s5Zr3gBRwbWNZyzhXk= +-----END RSA PRIVATE KEY----- diff --git a/SampleCode/TDQuoteVerificationSample/Makefile b/SampleCode/TDQuoteVerificationSample/Makefile new file mode 100644 index 00000000..3b7ba806 --- /dev/null +++ b/SampleCode/TDQuoteVerificationSample/Makefile @@ -0,0 +1,267 @@ +# +# Copyright (C) 2011-2021 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 Settings ######## + +SGX_SDK ?= /opt/intel/sgxsdk +SGX_MODE ?= HW +SGX_ARCH ?= x64 +DEBUG ?= 0 +UNTRUSTED_VERIFY ?= 0 + +# Don't support 32bit in this sample +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 + +ifeq ($(DEBUG), 1) +ifeq ($(SGX_PRERELEASE), 1) +$(error Cannot set DEBUG and SGX_PRERELEASE at the same time!!) +endif +endif + +ifeq ($(DEBUG), 1) + SGX_COMMON_FLAGS += -O0 -g3 -ggdb +else + SGX_COMMON_FLAGS += -O2 +endif + +SGX_COMMON_FLAGS += -DSGX_TRUSTED -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) + Urts_Library_Name := sgx_urts_sim +else + Urts_Library_Name := sgx_urts +endif + +App_Cpp_Files := App/App.cpp +App_Include_Paths := -IApp + +ifeq ($(UNTRUSTED_VERIFY), 0) +App_Include_Paths += -I$(SGX_SDK)/include +endif + + +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 ($(DEBUG), 1) + App_C_Flags += -DDEBUG -UNDEBUG -UEDEBUG +else ifeq ($(SGX_PRERELEASE), 1) + App_C_Flags += -DNDEBUG -DEDEBUG -UDEBUG +else + App_C_Flags += -DNDEBUG -UEDEBUG -UDEBUG +endif + +App_Cpp_Flags := $(App_C_Flags) +App_Link_Flags := -L$(SGX_LIBRARY_PATH) -lsgx_dcap_quoteverify -l$(Urts_Library_Name) -lpthread -ldl + + +App_Cpp_Objects := $(App_Cpp_Files:.cpp=.o) + +App_Name := app + +######## Enclave Settings ######## + +ifneq ($(SGX_MODE), HW) + Trts_Library_Name := sgx_trts_sim + Service_Library_Name := sgx_tservice_sim +else + Trts_Library_Name := sgx_trts + Service_Library_Name := sgx_tservice +endif +Crypto_Library_Name := sgx_tcrypto +DCAP_DIR ?= ../../ +DCAP_QG_DIR ?= $(DCAP_DIR)/QuoteGeneration/ + +Enclave_Cpp_Files := Enclave/Enclave.cpp +Enclave_Include_Paths := -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 += -fstack-protector +else + Enclave_C_Flags += -fstack-protector-strong +endif + +Enclave_Cpp_Flags := $(Enclave_C_Flags) -nostdinc++ + +# Enable the security flags +Enclave_Security_Link_Flags := -Wl,-z,relro,-z,now,-z,noexecstack + +# 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, +# so that the whole content of trts is included in the enclave. +# 2. For other libraries, you just need to pull the required symbols. +# 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 := $(Enclave_Security_Link_Flags) -fPIC \ + -Wl,--no-undefined -nostdlib -nodefaultlibs -nostartfiles -L$(SGX_LIBRARY_PATH) \ + -Wl,--whole-archive -lsgx_dcap_tvl -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 \ + -Wl,-pie,-eenclave_entry -Wl,--export-dynamic \ + -Wl,--defsym,__ImageBase=0 -Wl,--gc-sections \ + -Wl,--version-script=Enclave/Enclave.lds + +Enclave_Cpp_Objects := $(sort $(Enclave_Cpp_Files:.cpp=.o)) + +Enclave_Name := enclave.so +Signed_Enclave_Name := enclave.signed.so +Enclave_Config_File := Enclave/Enclave.config.xml + +ifeq ($(SGX_MODE), HW) +ifeq ($(DEBUG), 1) + Build_Mode = HW_DEBUG +else ifeq ($(SGX_PRERELEASE), 1) + Build_Mode = HW_PRERELEASE +else + Build_Mode = HW_RELEASE +endif +else +ifeq ($(DEBUG), 1) + Build_Mode = SIM_DEBUG +else ifeq ($(SGX_PRERELEASE), 1) + Build_Mode = SIM_PRERELEASE +else + Build_Mode = SIM_RELEASE +endif +endif + + +.PHONY: all target +ifeq ($(UNTRUSTED_VERIFY), 0) +all: .config_$(Build_Mode)_$(SGX_ARCH) + @$(MAKE) target + +ifeq ($(Build_Mode), HW_RELEASE) +target: $(App_Name) $(Enclave_Name) + @echo "The project has been built in release hardware mode." + @echo "Please sign the $(Enclave_Name) first with your signing key before you run the $(App_Name) to launch and access the enclave." + @echo "To sign the enclave use the command:" + @echo " $(SGX_ENCLAVE_SIGNER) sign -key -enclave $(Enclave_Name) -out <$(Signed_Enclave_Name)> -config $(Enclave_Config_File)" + @echo "You can also sign the enclave using an external signing tool." + @echo "To build the project in simulation mode set SGX_MODE=SIM. To build the project in prerelease mode set SGX_PRERELEASE=1 and SGX_MODE=HW." + + +else +target: $(App_Name) $(Signed_Enclave_Name) +ifeq ($(Build_Mode), HW_DEBUG) + @echo "The project has been built in debug hardware mode." +else ifeq ($(Build_Mode), SIM_DEBUG) + @echo "The project has been built in debug simulation mode." +else ifeq ($(Build_Mode), HW_PRERELEASE) + @echo "The project has been built in pre-release hardware mode." +else ifeq ($(Build_Mode), SIM_PRERELEASE) + @echo "The project has been built in pre-release simulation mode." +else + @echo "The project has been built in release simulation mode." +endif + +endif + + +.config_$(Build_Mode)_$(SGX_ARCH): + @rm -f .config_* $(App_Name) $(Enclave_Name) $(Signed_Enclave_Name) $(App_Cpp_Objects) App/Enclave_u.* $(Enclave_Cpp_Objects) Enclave/Enclave_t.* + @touch .config_$(Build_Mode)_$(SGX_ARCH) + +######## App Objects ######## + +App/Enclave_u.h: $(SGX_EDGER8R) Enclave/Enclave.edl + @cd App && $(SGX_EDGER8R) --untrusted ../Enclave/Enclave.edl --search-path ../Enclave --search-path $(SGX_SDK)/include + @echo "GEN => $@" + +App/Enclave_u.c: App/Enclave_u.h + +App/Enclave_u.o: App/Enclave_u.c + @$(CC) $(SGX_COMMON_CFLAGS) $(App_C_Flags) -c $< -o $@ + @echo "CC <= $<" + +App/%.o: App/%.cpp App/Enclave_u.h + @$(CXX) $(SGX_COMMON_CXXFLAGS) $(App_Cpp_Flags) -c $< -o $@ -DTRUSTED_VERIFY + @echo "CXX <= $<" + +$(App_Name): App/Enclave_u.o $(App_Cpp_Objects) + @$(CXX) $^ -o $@ $(App_Link_Flags) + @echo "LINK => $@" + +######## Enclave Objects ######## + +Enclave/Enclave_t.h: $(SGX_EDGER8R) Enclave/Enclave.edl + @cd Enclave && $(SGX_EDGER8R) --trusted ../Enclave/Enclave.edl --search-path ../Enclave --search-path $(SGX_SDK)/include + @echo "GEN => $@" + +Enclave/Enclave_t.c: Enclave/Enclave_t.h + +Enclave/Enclave_t.o: Enclave/Enclave_t.c + @$(CC) $(SGX_COMMON_CFLAGS) $(Enclave_C_Flags) -c $< -o $@ + @echo "CC <= $<" + +Enclave/%.o: Enclave/%.cpp Enclave/Enclave_t.h + @$(CXX) $(SGX_COMMON_CXXFLAGS) $(Enclave_Cpp_Flags) -c $< -o $@ + @echo "CXX <= $<" + +$(Enclave_Name): Enclave/Enclave_t.o $(Enclave_Cpp_Objects) + $(CXX) $^ -o $@ $(Enclave_Link_Flags) + echo "LINK => $@" + +$(Signed_Enclave_Name): $(Enclave_Name) + @$(SGX_ENCLAVE_SIGNER) sign -key Enclave/Enclave_private_sample.pem -enclave $(Enclave_Name) -out $@ -config $(Enclave_Config_File) + @echo "SIGN => $@" +else +all: + @$(MAKE) target +target: $(App_Name) +App/%.o: App/%.cpp + $(CXX) $(SGX_COMMON_CXXFLAGS) $(App_Cpp_Flags) -c $< -o $@ -UTRUSTED_VERIFY + @echo "CXX <= $<" + +$(App_Name): $(App_Cpp_Objects) + @$(CXX) $^ -o $@ $(App_Link_Flags) + @echo "LINK => $@" +endif + +.PHONY: clean + +clean: + @rm -f .config_* $(App_Name) $(Enclave_Name) $(Signed_Enclave_Name) $(App_Cpp_Objects) App/*_u.* $(Enclave_Cpp_Objects) Enclave/Enclave_t.* diff --git a/SampleCode/TDQuoteVerificationSample/README.md b/SampleCode/TDQuoteVerificationSample/README.md new file mode 100644 index 00000000..baf0b873 --- /dev/null +++ b/SampleCode/TDQuoteVerificationSample/README.md @@ -0,0 +1,44 @@ +Intel(R) Software Guard Extensions Data Center Attestation Primitives (Intel(R) SGX DCAP) Quote Verification SampleCode +================================================ + +## Linux +Supported operating systems: +* CentOS 8.3 64bits + +Requirements: +* make +* gcc +* g++ +* bash shell + +Prerequisite: +* Installed Intel(R) TDX DCAP Verfication Packages +* Installed Intel(R) Quote Generation Service Packages +* Installed Intel(R) SGX DCAP PCCS (Provisioning Certificate Caching Service) +* Intel(R) SGX DCAP Packages(only needed in trusted mode of quote verification) +If want verified quote in trusted mode +* Intel(R) SGX SDK + +*Please refer to SGX DCAP Linux installation guide "https://download.01.org/intel-sgx/sgx-dcap/#version#/linux/docs/Intel_SGX_DCAP_Linux_SW_Installation_Guide.pdf" to install above dependencies*
+*Note that you need to change **\#version\#** to actual version number in URL, such as 1.11.* + + +1. Generate an ECDSA quote with certification data of type 5 using this Quote Generation Sample Code +``` + $ cd /opt/intel/tdx-quote-generation-sample + $ make + $ ./test_tdx_attest +``` + +2. Build and run TD-based Quote Verification Sample to verify a given quote +``` + Untrusted mode build: + $ make UNTRUSTED_VERIFY=1 + Trused & Untrusted mode debug build: + $ make DEBUG=1 + $ ./app -quote
[default=../tdx-quote-generation-sample/quote.dat]> + Trused & Untrusted mode Release build: + $ make `#You need to sign ISV enclave with your own key in this mode` + $ ./app -quote [default=../tdx-quote-generation-sample/quote.dat]> +``` +**Note**: Our libdcap_quoteprov.so is not built with Intel(R) Control Flow Enforcement Technology(CET) feature. If the sample is built with CET feature(it can be enabled by the compiler's default setting) and it is running on a CET enabled platform, you may encounter such an error message(or something similar): "Couldn't find the platform library. rebuild shared object with SHSTK support enabled". It means the system glibc enforces that a CET-enabled application can't load a non-CET shared library. You need to rebuild the sample by adding -fcf-protection=none option explicitly to disable CET. diff --git a/driver/win/FLCMSR/FLCMSR.vcxproj b/driver/win/FLCMSR/FLCMSR.vcxproj index ad360281..5f209e18 100644 --- a/driver/win/FLCMSR/FLCMSR.vcxproj +++ b/driver/win/FLCMSR/FLCMSR.vcxproj @@ -73,11 +73,13 @@ true sgx_lc_msr true + true DbgengKernelDebugger sgx_lc_msr true + true diff --git a/driver/win/WinLe/WinLe.vcxproj b/driver/win/WinLe/WinLe.vcxproj index 59941fae..53a045a0 100644 --- a/driver/win/WinLe/WinLe.vcxproj +++ b/driver/win/WinLe/WinLe.vcxproj @@ -74,6 +74,7 @@ True 133563 + true DbgengKernelDebugger @@ -85,6 +86,7 @@ True 133563 + true diff --git a/driver/win/WinLeProxyUMDF/WinLeProxyUMDF.vcxproj b/driver/win/WinLeProxyUMDF/WinLeProxyUMDF.vcxproj index b2caa9ef..5574131c 100644 --- a/driver/win/WinLeProxyUMDF/WinLeProxyUMDF.vcxproj +++ b/driver/win/WinLeProxyUMDF/WinLeProxyUMDF.vcxproj @@ -82,12 +82,14 @@ $(IncludePath) $(LibraryPath) sgx_lc + true DbgengRemoteDebugger $(IncludePath) $(LibraryPath) sgx_lc + true diff --git a/prebuilt/openssl/inc/openssl/engine.h b/prebuilt/openssl/inc/openssl/engine.h index 0780f0fb..d707eaeb 100644 --- a/prebuilt/openssl/inc/openssl/engine.h +++ b/prebuilt/openssl/inc/openssl/engine.h @@ -1,5 +1,5 @@ /* - * Copyright 2000-2018 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2000-2022 The OpenSSL Project Authors. All Rights Reserved. * Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved * * Licensed under the OpenSSL license (the "License"). You may not use @@ -722,6 +722,7 @@ typedef int (*dynamic_bind_engine) (ENGINE *e, const char *id, CRYPTO_set_mem_functions(fns->mem_fns.malloc_fn, \ fns->mem_fns.realloc_fn, \ fns->mem_fns.free_fn); \ + OPENSSL_init_crypto(OPENSSL_INIT_NO_ATEXIT, NULL); \ skip_cbs: \ if (!fn(e, id)) return 0; \ return 1; } diff --git a/prebuilt/openssl/inc/openssl/obj_mac.h b/prebuilt/openssl/inc/openssl/obj_mac.h index eb812ed1..53516a06 100644 --- a/prebuilt/openssl/inc/openssl/obj_mac.h +++ b/prebuilt/openssl/inc/openssl/obj_mac.h @@ -2,7 +2,7 @@ * WARNING: do not edit! * Generated by crypto/objects/objects.pl * - * Copyright 2000-2021 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2000-2022 The OpenSSL Project Authors. All Rights Reserved. * Licensed under the OpenSSL license (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy * in the file LICENSE in the source distribution or at diff --git a/prebuilt/openssl/inc/openssl/opensslconf.h b/prebuilt/openssl/inc/openssl/opensslconf.h index afea9cee..1398dd7b 100644 --- a/prebuilt/openssl/inc/openssl/opensslconf.h +++ b/prebuilt/openssl/inc/openssl/opensslconf.h @@ -1,6 +1,6 @@ /* * WARNING: do not edit! - * Generated by makefile from include\openssl\opensslconf.h.in + * Generated by Makefile from include/openssl/opensslconf.h.in * * Copyright 2016-2020 The OpenSSL Project Authors. All Rights Reserved. * @@ -24,9 +24,6 @@ extern "C" { * OpenSSL was configured with the following options: */ -#ifndef OPENSSL_SYS_WIN64A -# define OPENSSL_SYS_WIN64A 1 -#endif #ifndef OPENSSL_NO_ARIA # define OPENSSL_NO_ARIA #endif @@ -102,6 +99,9 @@ extern "C" { #ifndef OPENSSL_NO_ASAN # define OPENSSL_NO_ASAN #endif +#ifndef OPENSSL_NO_ASM +# define OPENSSL_NO_ASM +#endif #ifndef OPENSSL_NO_AUTOERRINIT # define OPENSSL_NO_AUTOERRINIT #endif @@ -261,7 +261,7 @@ extern "C" { #undef OPENSSL_UNISTD #define OPENSSL_UNISTD -#define OPENSSL_EXPORT_VAR_AS_FUNCTION +#undef OPENSSL_EXPORT_VAR_AS_FUNCTION /* * The following are cipher-specific, but are part of the public API. @@ -269,8 +269,8 @@ extern "C" { #if !defined(OPENSSL_SYS_UEFI) # undef BN_LLONG /* Only one for the following should be defined */ -# undef SIXTY_FOUR_BIT_LONG -# define SIXTY_FOUR_BIT +# define SIXTY_FOUR_BIT_LONG +# undef SIXTY_FOUR_BIT # undef THIRTY_TWO_BIT #endif diff --git a/prebuilt/openssl/inc/openssl/opensslv.h b/prebuilt/openssl/inc/openssl/opensslv.h index 261d7cb3..bd9dc920 100644 --- a/prebuilt/openssl/inc/openssl/opensslv.h +++ b/prebuilt/openssl/inc/openssl/opensslv.h @@ -1,5 +1,5 @@ /* - * Copyright 1999-2021 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1999-2022 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the OpenSSL license (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -39,8 +39,8 @@ extern "C" { * (Prior to 0.9.5a beta1, a different scheme was used: MMNNFFRBB for * major minor fix final patch/beta) */ -# define OPENSSL_VERSION_NUMBER 0x101010dfL -# define OPENSSL_VERSION_TEXT "OpenSSL 1.1.1m 14 Dec 2021" +# define OPENSSL_VERSION_NUMBER 0x101010ffL +# define OPENSSL_VERSION_TEXT "OpenSSL 1.1.1o 3 May 2022" /*- * The macros below are to be used for shared library (.so, .dll, ...) diff --git a/prebuilt/openssl/lib/linux64/libcrypto.a b/prebuilt/openssl/lib/linux64/libcrypto.a index db5ca94b..d8b79489 100644 Binary files a/prebuilt/openssl/lib/linux64/libcrypto.a and b/prebuilt/openssl/lib/linux64/libcrypto.a differ diff --git a/prebuilt/openssl/lib/win64/libcrypto.lib b/prebuilt/openssl/lib/win64/libcrypto.lib index 5a5182d1..0d274c0f 100644 Binary files a/prebuilt/openssl/lib/win64/libcrypto.lib and b/prebuilt/openssl/lib/win64/libcrypto.lib differ diff --git a/tools/PCKCertSelection/PCKSelectionSample/main.cpp b/tools/PCKCertSelection/PCKSelectionSample/main.cpp index 24f7ec77..3550b89f 100644 --- a/tools/PCKCertSelection/PCKSelectionSample/main.cpp +++ b/tools/PCKCertSelection/PCKSelectionSample/main.cpp @@ -49,8 +49,8 @@ const string SAMPLE_DIR = "../SampleData/"; #else const string SAMPLE_DIR = "..\\..\\SampleData\\"; #endif -const string CERT_FILES[] = { "pck2.pem", "pck1.pem", "pck0.pem" }; -const string TCB_FILE = "tcb_info.json"; +const string CERT_FILES[] = { "pck6_sample.pem", "pck5_sample.pem", "pck4_sample.pem", "pck3_sample.pem", "pck2_sample.pem", "pck1_sample.pem", "pck0_sample.pem" }; +const string TCB_FILE = "tcb_info_4.json"; /** * read file (certificate PEM or JSON) into std::string @@ -97,9 +97,10 @@ int main ( void ) // trick to keep PCKs strings alive vector < string > strs; vector < const char* > pcks; + uint32_t cert_count = sizeof(CERT_FILES)/ sizeof(CERT_FILES[0]); // read sample PCK Certs from PEM files to strings array - for ( size_t i = 0; i < 3; i++ ) + for ( size_t i = 0; i < cert_count; i++ ) { string pem; path = SAMPLE_DIR + CERT_FILES[i]; @@ -118,11 +119,11 @@ int main ( void ) cpu_svn_t plat_svn = { 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }; uint16_t plat_pcesvn = 6; uint16_t plat_pceid = 0; - uint32_t best_index = 0; + uint32_t best_index = 6; // call PCK Cert Selection library with sample data input - cout << "Call with PCESVN (6), CPUSVN { 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }, expecting success with index 1\n"; - pck_cert_selection_res_t res = pck_cert_select ( &plat_svn, plat_pcesvn, plat_pceid, tcb.c_str (), pcks.data (), 3, &best_index ); + cout << "Call with PCESVN (6), CPUSVN { 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }, expecting success with index 6\n"; + pck_cert_selection_res_t res = pck_cert_select ( &plat_svn, plat_pcesvn, plat_pceid, tcb.c_str (), pcks.data (), cert_count, &best_index ); if ( res == PCK_CERT_SELECT_SUCCESS ) { cout << "Best PCK is: " << best_index << "\n"; @@ -136,8 +137,8 @@ int main ( void ) // change platform TCB raw data and call PCK Cert Selection library again, sample data is same plat_svn = { 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0 }; plat_pcesvn = 4; - cout << "Call with PCESVN (4), CPUSVN { 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0 }, expecting success with index 0\n"; - res = pck_cert_select ( &plat_svn, plat_pcesvn, plat_pceid, tcb.c_str (), pcks.data (), 3, &best_index ); + cout << "Call with PCESVN (4), CPUSVN { 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0 }, expecting success with index 4\n"; + res = pck_cert_select ( &plat_svn, plat_pcesvn, plat_pceid, tcb.c_str (), pcks.data (), cert_count, &best_index ); if ( res == PCK_CERT_SELECT_SUCCESS ) { cout << "Best PCK is: " << best_index << "\n"; @@ -152,7 +153,7 @@ int main ( void ) plat_svn = { 0 }; plat_pcesvn = 1; cout << "Call with PCESVN (1), CPUSVN { 0 }, expecting fail not found (error 12)\n"; - res = pck_cert_select ( &plat_svn, plat_pcesvn, plat_pceid, tcb.c_str (), pcks.data (), 3, &best_index ); + res = pck_cert_select ( &plat_svn, plat_pcesvn, plat_pceid, tcb.c_str (), pcks.data (), cert_count, &best_index ); if ( res == PCK_CERT_SELECT_SUCCESS ) { cout << " Success index: " << res << ", exit\n"; @@ -162,10 +163,26 @@ int main ( void ) { cout << "Error returned: " << res << "\n"; } + // platform TCB raw data, CPUSVN and PCESVN + plat_svn = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1 }; + plat_pcesvn = 7; + + // call PCK Cert Selection library with sample data input + cout << "Call with PCESVN (7), CPUSVN { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1 }, expecting success with index 6\n"; + res = pck_cert_select ( &plat_svn, plat_pcesvn, plat_pceid, tcb.c_str (), pcks.data (), cert_count, &best_index ); + if ( res == PCK_CERT_SELECT_SUCCESS ) + { + cout << "Best PCK is: " << best_index << "\n"; + } + else + { + cout << "Unexpected Error returned: " << res << ", exit\n"; + return 1; + } cout << "Below test case to get the hw config ID" << endl; - // check the + // check the hw config plat_svn = { 0, 1, 2, 3, 4, 5, 19, 7, 8, 9, 0, 0, 0, 0, 0, 0 }; plat_pcesvn = 4; uint32_t configuration_id = 0; diff --git a/tools/PCKCertSelection/SampleData/pck0.pem b/tools/PCKCertSelection/SampleData/pck0_sample.pem similarity index 100% rename from tools/PCKCertSelection/SampleData/pck0.pem rename to tools/PCKCertSelection/SampleData/pck0_sample.pem diff --git a/tools/PCKCertSelection/SampleData/pck1.pem b/tools/PCKCertSelection/SampleData/pck1_sample.pem similarity index 100% rename from tools/PCKCertSelection/SampleData/pck1.pem rename to tools/PCKCertSelection/SampleData/pck1_sample.pem diff --git a/tools/PCKCertSelection/SampleData/pck2.pem b/tools/PCKCertSelection/SampleData/pck2_sample.pem similarity index 100% rename from tools/PCKCertSelection/SampleData/pck2.pem rename to tools/PCKCertSelection/SampleData/pck2_sample.pem diff --git a/tools/PCKCertSelection/SampleData/pck3_sample.pem b/tools/PCKCertSelection/SampleData/pck3_sample.pem new file mode 100644 index 00000000..c5759d68 --- /dev/null +++ b/tools/PCKCertSelection/SampleData/pck3_sample.pem @@ -0,0 +1,27 @@ +-----BEGIN CERTIFICATE----- +MIIEoDCCBCegAwIBAgIUE8T6Xg4z7Uj7poHEHHSOnSIZArowCgYIKoZIzj0EAwIw +cDEiMCAGA1UEAwwZSW50ZWwgU0dYIFBDSyBDZXJ0aWZpY2F0ZTEaMBgGA1UECgwR +SW50ZWwgQ29ycG9yYXRpb24xFDASBgNVBAcMC1NhbnRhIENsYXJhMQswCQYDVQQI +DAJDQTELMAkGA1UEBhMCVVMwHhcNMjEwMjIyMTAzNTU2WhcNMjIwMjIyMTAzNTU2 +WjBwMSIwIAYDVQQDDBlJbnRlbCBTR1ggUENLIENlcnRpZmljYXRlMRowGAYDVQQK +DBFJbnRlbCBDb3Jwb3JhdGlvbjEUMBIGA1UEBwwLU2FudGEgQ2xhcmExCzAJBgNV +BAgMAkNBMQswCQYDVQQGEwJVUzB2MBAGByqGSM49AgEGBSuBBAAiA2IABGRGsHFp +LX67vmd4MDSTFawgcVtGCIH9oTkzciNOA2o7VvLe0++4dF9sTByHNGvV6OBt9wSX +rnfbktNl9zkcSHGiHPQyQW3yDpBFt7iLclIdqR0wdll7cwIjtYPpsk4IVqOCAoAw +ggJ8MAkGA1UdIwQCMAAwWAYDVR0fBFEwTzBNoEugSYZHaHR0cHM6Ly9jZXJ0aWZp +Y2F0ZXMudHJ1c3RlZHNlcnZpY2VzLmludGVsLmNvbS9JbnRlbFNHWFBDS1Byb2Nl +c3Nvci5jcmwwHQYDVR0OBBYEFH0Z+IE+Rmz6bttmwa/iaH600AXfMA4GA1UdDwEB +/wQEAwIGwDAMBgNVHRMBAf8EAjAAMIIB1gYJKoZIhvhNAQ0BAQH/BIIBxDCCAcAw +HgYKKoZIhvhNAQ0BAQQQE24AAAAAAAAAAAAAAAAAADCCAWMGCiqGSIb4TQENAQIw +ggFTMBAGCyqGSIb4TQENAQIBAgEBMBAGCyqGSIb4TQENAQICAgEBMBAGCyqGSIb4 +TQENAQIDAgEBMBAGCyqGSIb4TQENAQIEAgEBMBAGCyqGSIb4TQENAQIFAgEBMBAG +CyqGSIb4TQENAQIGAgEBMBAGCyqGSIb4TQENAQIHAgEBMBAGCyqGSIb4TQENAQII +AgEBMBAGCyqGSIb4TQENAQIJAgEBMBAGCyqGSIb4TQENAQIKAgEBMBAGCyqGSIb4 +TQENAQILAgEBMBAGCyqGSIb4TQENAQIMAgEAMBAGCyqGSIb4TQENAQINAgEAMBAG +CyqGSIb4TQENAQIOAgEAMBAGCyqGSIb4TQENAQIPAgEAMBAGCyqGSIb4TQENAQIQ +AgEAMBAGCyqGSIb4TQENAQIRAgEEMB8GCyqGSIb4TQENAQISBBABAQEBAQEBAQEB +AQAAAAAAMBAGCiqGSIb4TQENAQMEAgAAMBQGCiqGSIb4TQENAQQEBgBwfwAAADAP +BgoqhkiG+E0BDQEFCgEAMAoGCCqGSM49BAMCA2cAMGQCMFqbdE6Z3XgRZO75W69+ +zqPGZS4J6YBwlCwOgSjd9CE4owLoU4kKvg0ceJsHf99XaQIwQ/HiDdy/vc2l1jkK +c6Y4jyp68UbJI0hHi6Qdq5ithg2shq4rAQY2eK9eL6HkJmRH +-----END CERTIFICATE----- diff --git a/tools/PCKCertSelection/SampleData/pck4_sample.pem b/tools/PCKCertSelection/SampleData/pck4_sample.pem new file mode 100644 index 00000000..5c20fb7a --- /dev/null +++ b/tools/PCKCertSelection/SampleData/pck4_sample.pem @@ -0,0 +1,27 @@ +-----BEGIN CERTIFICATE----- +MIIEoTCCBCegAwIBAgIUQxKHanzfgX7U2S9/CGBCsQjUKKUwCgYIKoZIzj0EAwIw +cDEiMCAGA1UEAwwZSW50ZWwgU0dYIFBDSyBDZXJ0aWZpY2F0ZTEaMBgGA1UECgwR +SW50ZWwgQ29ycG9yYXRpb24xFDASBgNVBAcMC1NhbnRhIENsYXJhMQswCQYDVQQI +DAJDQTELMAkGA1UEBhMCVVMwHhcNMjEwMjIyMTAzNTUxWhcNMjIwMjIyMTAzNTUx +WjBwMSIwIAYDVQQDDBlJbnRlbCBTR1ggUENLIENlcnRpZmljYXRlMRowGAYDVQQK +DBFJbnRlbCBDb3Jwb3JhdGlvbjEUMBIGA1UEBwwLU2FudGEgQ2xhcmExCzAJBgNV +BAgMAkNBMQswCQYDVQQGEwJVUzB2MBAGByqGSM49AgEGBSuBBAAiA2IABGRGsHFp +LX67vmd4MDSTFawgcVtGCIH9oTkzciNOA2o7VvLe0++4dF9sTByHNGvV6OBt9wSX +rnfbktNl9zkcSHGiHPQyQW3yDpBFt7iLclIdqR0wdll7cwIjtYPpsk4IVqOCAoAw +ggJ8MAkGA1UdIwQCMAAwWAYDVR0fBFEwTzBNoEugSYZHaHR0cHM6Ly9jZXJ0aWZp +Y2F0ZXMudHJ1c3RlZHNlcnZpY2VzLmludGVsLmNvbS9JbnRlbFNHWFBDS1Byb2Nl +c3Nvci5jcmwwHQYDVR0OBBYEFH0Z+IE+Rmz6bttmwa/iaH600AXfMA4GA1UdDwEB +/wQEAwIGwDAMBgNVHRMBAf8EAjAAMIIB1gYJKoZIhvhNAQ0BAQH/BIIBxDCCAcAw +HgYKKoZIhvhNAQ0BAQQQE24AAAAAAAAAAAAAAAAAADCCAWMGCiqGSIb4TQENAQIw +ggFTMBAGCyqGSIb4TQENAQIBAgEBMBAGCyqGSIb4TQENAQICAgEBMBAGCyqGSIb4 +TQENAQIDAgEBMBAGCyqGSIb4TQENAQIEAgEBMBAGCyqGSIb4TQENAQIFAgEBMBAG +CyqGSIb4TQENAQIGAgEBMBAGCyqGSIb4TQENAQIHAgEBMBAGCyqGSIb4TQENAQII +AgEBMBAGCyqGSIb4TQENAQIJAgEBMBAGCyqGSIb4TQENAQIKAgEBMBAGCyqGSIb4 +TQENAQILAgEBMBAGCyqGSIb4TQENAQIMAgEBMBAGCyqGSIb4TQENAQINAgEBMBAG +CyqGSIb4TQENAQIOAgEBMBAGCyqGSIb4TQENAQIPAgEBMBAGCyqGSIb4TQENAQIQ +AgEBMBAGCyqGSIb4TQENAQIRAgEHMB8GCyqGSIb4TQENAQISBBABAQEBAQEBAQEB +AQEBAQEBMBAGCiqGSIb4TQENAQMEAgAAMBQGCiqGSIb4TQENAQQEBgBwfwAAADAP +BgoqhkiG+E0BDQEFCgEAMAoGCCqGSM49BAMCA2gAMGUCMBgPQxZlKmqmD9r8jgpE +h4cWXy2RVuTE6zAQvk8kE/G7S1DLC/OlpP2sBfxwaPl8/wIxAI16zxBSyFjdEoKb +bAihxv36Z7mAT9MmBz3h59Opug/ibQ5tOoQ9h6/7uwuRxZ0yCg== +-----END CERTIFICATE----- diff --git a/tools/PCKCertSelection/SampleData/pck5_sample.pem b/tools/PCKCertSelection/SampleData/pck5_sample.pem new file mode 100644 index 00000000..d9f93aea --- /dev/null +++ b/tools/PCKCertSelection/SampleData/pck5_sample.pem @@ -0,0 +1,27 @@ +-----BEGIN CERTIFICATE----- +MIIEoTCCBCegAwIBAgIUOL1Th6SQCNqpHI5B09+15UItniwwCgYIKoZIzj0EAwIw +cDEiMCAGA1UEAwwZSW50ZWwgU0dYIFBDSyBDZXJ0aWZpY2F0ZTEaMBgGA1UECgwR +SW50ZWwgQ29ycG9yYXRpb24xFDASBgNVBAcMC1NhbnRhIENsYXJhMQswCQYDVQQI +DAJDQTELMAkGA1UEBhMCVVMwHhcNMjEwMjIyMTAzNTQ2WhcNMjIwMjIyMTAzNTQ2 +WjBwMSIwIAYDVQQDDBlJbnRlbCBTR1ggUENLIENlcnRpZmljYXRlMRowGAYDVQQK +DBFJbnRlbCBDb3Jwb3JhdGlvbjEUMBIGA1UEBwwLU2FudGEgQ2xhcmExCzAJBgNV +BAgMAkNBMQswCQYDVQQGEwJVUzB2MBAGByqGSM49AgEGBSuBBAAiA2IABGRGsHFp +LX67vmd4MDSTFawgcVtGCIH9oTkzciNOA2o7VvLe0++4dF9sTByHNGvV6OBt9wSX +rnfbktNl9zkcSHGiHPQyQW3yDpBFt7iLclIdqR0wdll7cwIjtYPpsk4IVqOCAoAw +ggJ8MAkGA1UdIwQCMAAwWAYDVR0fBFEwTzBNoEugSYZHaHR0cHM6Ly9jZXJ0aWZp +Y2F0ZXMudHJ1c3RlZHNlcnZpY2VzLmludGVsLmNvbS9JbnRlbFNHWFBDS1Byb2Nl +c3Nvci5jcmwwHQYDVR0OBBYEFH0Z+IE+Rmz6bttmwa/iaH600AXfMA4GA1UdDwEB +/wQEAwIGwDAMBgNVHRMBAf8EAjAAMIIB1gYJKoZIhvhNAQ0BAQH/BIIBxDCCAcAw +HgYKKoZIhvhNAQ0BAQQQE24AAAAAAAAAAAAAAAAAADCCAWMGCiqGSIb4TQENAQIw +ggFTMBAGCyqGSIb4TQENAQIBAgEBMBAGCyqGSIb4TQENAQICAgEBMBAGCyqGSIb4 +TQENAQIDAgEBMBAGCyqGSIb4TQENAQIEAgEBMBAGCyqGSIb4TQENAQIFAgEBMBAG +CyqGSIb4TQENAQIGAgEBMBAGCyqGSIb4TQENAQIHAgEBMBAGCyqGSIb4TQENAQII +AgEBMBAGCyqGSIb4TQENAQIJAgEBMBAGCyqGSIb4TQENAQIKAgEBMBAGCyqGSIb4 +TQENAQILAgEBMBAGCyqGSIb4TQENAQIMAgEBMBAGCyqGSIb4TQENAQINAgEBMBAG +CyqGSIb4TQENAQIOAgEBMBAGCyqGSIb4TQENAQIPAgEAMBAGCyqGSIb4TQENAQIQ +AgEAMBAGCyqGSIb4TQENAQIRAgEIMB8GCyqGSIb4TQENAQISBBABAQEBAQEBAQEB +AQEBAQAAMBAGCiqGSIb4TQENAQMEAgAAMBQGCiqGSIb4TQENAQQEBgBwfwAAADAP +BgoqhkiG+E0BDQEFCgEAMAoGCCqGSM49BAMCA2gAMGUCMDb2U7Hin0HUUXSiLCh1 +cIuhdEJSC59xblO2KtwPCd1j/NBdXlijNybQjfyHX7YiNQIxAKW4r9/d4WNe9ZDN +W5dik0pQwsPJBS6HdtZwoYNwFqEiQ8MM1sHAAivHA3HPYxOpHA== +-----END CERTIFICATE----- diff --git a/tools/PCKCertSelection/SampleData/pck6_sample.pem b/tools/PCKCertSelection/SampleData/pck6_sample.pem new file mode 100644 index 00000000..508aab06 --- /dev/null +++ b/tools/PCKCertSelection/SampleData/pck6_sample.pem @@ -0,0 +1,27 @@ +-----BEGIN CERTIFICATE----- +MIIEoTCCBCegAwIBAgIUFAKiXaO5ip3GFvMjNoNWaR9+OjMwCgYIKoZIzj0EAwIw +cDEiMCAGA1UEAwwZSW50ZWwgU0dYIFBDSyBDZXJ0aWZpY2F0ZTEaMBgGA1UECgwR +SW50ZWwgQ29ycG9yYXRpb24xFDASBgNVBAcMC1NhbnRhIENsYXJhMQswCQYDVQQI +DAJDQTELMAkGA1UEBhMCVVMwHhcNMjEwMjIyMTAzNTQwWhcNMjIwMjIyMTAzNTQw +WjBwMSIwIAYDVQQDDBlJbnRlbCBTR1ggUENLIENlcnRpZmljYXRlMRowGAYDVQQK +DBFJbnRlbCBDb3Jwb3JhdGlvbjEUMBIGA1UEBwwLU2FudGEgQ2xhcmExCzAJBgNV +BAgMAkNBMQswCQYDVQQGEwJVUzB2MBAGByqGSM49AgEGBSuBBAAiA2IABGRGsHFp +LX67vmd4MDSTFawgcVtGCIH9oTkzciNOA2o7VvLe0++4dF9sTByHNGvV6OBt9wSX +rnfbktNl9zkcSHGiHPQyQW3yDpBFt7iLclIdqR0wdll7cwIjtYPpsk4IVqOCAoAw +ggJ8MAkGA1UdIwQCMAAwWAYDVR0fBFEwTzBNoEugSYZHaHR0cHM6Ly9jZXJ0aWZp +Y2F0ZXMudHJ1c3RlZHNlcnZpY2VzLmludGVsLmNvbS9JbnRlbFNHWFBDS1Byb2Nl +c3Nvci5jcmwwHQYDVR0OBBYEFH0Z+IE+Rmz6bttmwa/iaH600AXfMA4GA1UdDwEB +/wQEAwIGwDAMBgNVHRMBAf8EAjAAMIIB1gYJKoZIhvhNAQ0BAQH/BIIBxDCCAcAw +HgYKKoZIhvhNAQ0BAQQQE24AAAAAAAAAAAAAAAAAADCCAWMGCiqGSIb4TQENAQIw +ggFTMBAGCyqGSIb4TQENAQIBAgEBMBAGCyqGSIb4TQENAQICAgEBMBAGCyqGSIb4 +TQENAQIDAgEBMBAGCyqGSIb4TQENAQIEAgEBMBAGCyqGSIb4TQENAQIFAgEBMBAG +CyqGSIb4TQENAQIGAgEBMBAGCyqGSIb4TQENAQIHAgEBMBAGCyqGSIb4TQENAQII +AgEBMBAGCyqGSIb4TQENAQIJAgEBMBAGCyqGSIb4TQENAQIKAgEBMBAGCyqGSIb4 +TQENAQILAgEBMBAGCyqGSIb4TQENAQIMAgEBMBAGCyqGSIb4TQENAQINAgEAMBAG +CyqGSIb4TQENAQIOAgEAMBAGCyqGSIb4TQENAQIPAgEAMBAGCyqGSIb4TQENAQIQ +AgEAMBAGCyqGSIb4TQENAQIRAgEFMB8GCyqGSIb4TQENAQISBBABAQEBAQEBAQEB +AQEAAAAAMBAGCiqGSIb4TQENAQMEAgAAMBQGCiqGSIb4TQENAQQEBgBwfwAAADAP +BgoqhkiG+E0BDQEFCgEAMAoGCCqGSM49BAMCA2gAMGUCMBDvtnCA56/aNFFYY9NV +kzgdifL0P1Enp8WrvETrO+oFRd6Jp/SdWj2iuqjlZguY9gIxAOMRBiWyvigq/tcr +xUbrh34DXpa3t6Bb5ExotjV3yW0jTQfxcG4kveYAVugBiKMlEw== +-----END CERTIFICATE----- diff --git a/tools/PCKCertSelection/SampleData/tcb_info.json b/tools/PCKCertSelection/SampleData/tcb_info.json index a4429eb0..faa38cd4 100644 --- a/tools/PCKCertSelection/SampleData/tcb_info.json +++ b/tools/PCKCertSelection/SampleData/tcb_info.json @@ -1,175 +1,106 @@ { - "signature": "24f15870f33c63d9ad6c765ec23c011a01011497fcdec32fc0fa211a256ade7027f7b0a1aa11f02c38b01684925919bb68962b7f6d7e14096b5e6987384401b4", - "tcbInfo": { - "fmspc": "00707f000000", - "issueDate": "2021-07-05T17:20:02Z", - "nextUpdate": "2021-08-04T17:20:02Z", - "pceId": "0000", - "tcbEvaluationDataNumber": 11, - "tcbLevels": [ - { - "tcb": { - "pcesvn": 11, - "sgxtcbcomp01svn": 4, - "sgxtcbcomp02svn": 4, - "sgxtcbcomp03svn": 4, - "sgxtcbcomp04svn": 4, - "sgxtcbcomp05svn": 4, - "sgxtcbcomp06svn": 4, - "sgxtcbcomp07svn": 4, - "sgxtcbcomp08svn": 4, - "sgxtcbcomp09svn": 4, - "sgxtcbcomp10svn": 4, - "sgxtcbcomp11svn": 4, - "sgxtcbcomp12svn": 4, - "sgxtcbcomp13svn": 0, - "sgxtcbcomp14svn": 0, - "sgxtcbcomp15svn": 0, - "sgxtcbcomp16svn": 0 - }, - "tcbDate": "2021-06-09T00:00:00Z", - "tcbStatus": "UpToDate" - }, - { - "tcb": { - "pcesvn": 10, - "sgxtcbcomp01svn": 3, - "sgxtcbcomp02svn": 3, - "sgxtcbcomp03svn": 3, - "sgxtcbcomp04svn": 3, - "sgxtcbcomp05svn": 3, - "sgxtcbcomp06svn": 3, - "sgxtcbcomp07svn": 3, - "sgxtcbcomp08svn": 3, - "sgxtcbcomp09svn": 3, - "sgxtcbcomp10svn": 0, - "sgxtcbcomp11svn": 0, - "sgxtcbcomp12svn": 0, - "sgxtcbcomp13svn": 0, - "sgxtcbcomp14svn": 0, - "sgxtcbcomp15svn": 0, - "sgxtcbcomp16svn": 0 - }, - "tcbDate": "2020-11-11T00:00:00Z", - "tcbStatus": "OutOfDate" - }, - { - "tcb": { - "pcesvn": 9, - "sgxtcbcomp01svn": 2, - "sgxtcbcomp02svn": 2, - "sgxtcbcomp03svn": 2, - "sgxtcbcomp04svn": 2, - "sgxtcbcomp05svn": 0, - "sgxtcbcomp06svn": 0, - "sgxtcbcomp07svn": 0, - "sgxtcbcomp08svn": 0, - "sgxtcbcomp09svn": 0, - "sgxtcbcomp10svn": 0, - "sgxtcbcomp11svn": 0, - "sgxtcbcomp12svn": 0, - "sgxtcbcomp13svn": 0, - "sgxtcbcomp14svn": 0, - "sgxtcbcomp15svn": 0, - "sgxtcbcomp16svn": 0 - }, - "tcbDate": "2020-06-10T00:00:00Z", - "tcbStatus": "OutOfDate" - }, - { - "tcb": { - "pcesvn": 7, - "sgxtcbcomp01svn": 2, - "sgxtcbcomp02svn": 2, - "sgxtcbcomp03svn": 0, - "sgxtcbcomp04svn": 0, - "sgxtcbcomp05svn": 0, - "sgxtcbcomp06svn": 0, - "sgxtcbcomp07svn": 0, - "sgxtcbcomp08svn": 0, - "sgxtcbcomp09svn": 0, - "sgxtcbcomp10svn": 0, - "sgxtcbcomp11svn": 0, - "sgxtcbcomp12svn": 0, - "sgxtcbcomp13svn": 0, - "sgxtcbcomp14svn": 0, - "sgxtcbcomp15svn": 0, - "sgxtcbcomp16svn": 0 - }, - "tcbDate": "2019-05-15T00:00:00Z", - "tcbStatus": "OutOfDate" - }, - { - "tcb": { - "pcesvn": 6, - "sgxtcbcomp01svn": 2, - "sgxtcbcomp02svn": 2, - "sgxtcbcomp03svn": 0, - "sgxtcbcomp04svn": 0, - "sgxtcbcomp05svn": 0, - "sgxtcbcomp06svn": 0, - "sgxtcbcomp07svn": 0, - "sgxtcbcomp08svn": 0, - "sgxtcbcomp09svn": 0, - "sgxtcbcomp10svn": 0, - "sgxtcbcomp11svn": 0, - "sgxtcbcomp12svn": 0, - "sgxtcbcomp13svn": 0, - "sgxtcbcomp14svn": 0, - "sgxtcbcomp15svn": 0, - "sgxtcbcomp16svn": 0 - }, - "tcbDate": "2018-08-15T00:00:00Z", - "tcbStatus": "OutOfDate" - }, - { - "tcb": { - "pcesvn": 5, - "sgxtcbcomp01svn": 1, - "sgxtcbcomp02svn": 1, - "sgxtcbcomp03svn": 0, - "sgxtcbcomp04svn": 0, - "sgxtcbcomp05svn": 0, - "sgxtcbcomp06svn": 0, - "sgxtcbcomp07svn": 0, - "sgxtcbcomp08svn": 0, - "sgxtcbcomp09svn": 0, - "sgxtcbcomp10svn": 0, - "sgxtcbcomp11svn": 0, - "sgxtcbcomp12svn": 0, - "sgxtcbcomp13svn": 0, - "sgxtcbcomp14svn": 0, - "sgxtcbcomp15svn": 0, - "sgxtcbcomp16svn": 0 - }, - "tcbDate": "2018-01-04T00:00:00Z", - "tcbStatus": "OutOfDate" - }, - { - "tcb": { - "pcesvn": 4, - "sgxtcbcomp01svn": 0, - "sgxtcbcomp02svn": 0, - "sgxtcbcomp03svn": 0, - "sgxtcbcomp04svn": 0, - "sgxtcbcomp05svn": 0, - "sgxtcbcomp06svn": 0, - "sgxtcbcomp07svn": 0, - "sgxtcbcomp08svn": 0, - "sgxtcbcomp09svn": 0, - "sgxtcbcomp10svn": 0, - "sgxtcbcomp11svn": 0, - "sgxtcbcomp12svn": 0, - "sgxtcbcomp13svn": 0, - "sgxtcbcomp14svn": 0, - "sgxtcbcomp15svn": 0, - "sgxtcbcomp16svn": 0 - }, - "tcbDate": "2017-07-26T00:00:00Z", - "tcbStatus": "OutOfDate" - } - ], - "tcbType": 0, - "version": 2 - } -} + "tcbInfo": + { + "version":1, + "issueDate":"2018-07-23T14:35:49Z", + "nextUpdate":"2018-07-30T14:35:49Z", + "fmspc":"00707f000000", + "pceId":"0000", + "tcbLevels": + [ + { + "tcb": + { + "sgxtcbcomp01svn":1, + "sgxtcbcomp02svn":1, + "sgxtcbcomp03svn":1, + "sgxtcbcomp04svn":1, + "sgxtcbcomp05svn":1, + "sgxtcbcomp06svn":1, + "sgxtcbcomp07svn":1, + "sgxtcbcomp08svn":1, + "sgxtcbcomp09svn":1, + "sgxtcbcomp10svn":1, + "sgxtcbcomp11svn":1, + "sgxtcbcomp12svn":1, + "sgxtcbcomp13svn":0, + "sgxtcbcomp14svn":0, + "sgxtcbcomp15svn":0, + "sgxtcbcomp16svn":0, + "pcesvn":5 + }, + "status":"UpToDate" + }, + { + "tcb": + { + "sgxtcbcomp01svn":1, + "sgxtcbcomp02svn":1, + "sgxtcbcomp03svn":1, + "sgxtcbcomp04svn":1, + "sgxtcbcomp05svn":1, + "sgxtcbcomp06svn":1, + "sgxtcbcomp07svn":1, + "sgxtcbcomp08svn":1, + "sgxtcbcomp09svn":0, + "sgxtcbcomp10svn":0, + "sgxtcbcomp11svn":0, + "sgxtcbcomp12svn":0, + "sgxtcbcomp13svn":0, + "sgxtcbcomp14svn":0, + "sgxtcbcomp15svn":0, + "sgxtcbcomp16svn":0, + "pcesvn":4 + }, + "status":"OutOfDate" + }, + { + "tcb": + { + "sgxtcbcomp01svn":1, + "sgxtcbcomp02svn":1, + "sgxtcbcomp03svn":1, + "sgxtcbcomp04svn":1, + "sgxtcbcomp05svn":0, + "sgxtcbcomp06svn":0, + "sgxtcbcomp07svn":0, + "sgxtcbcomp08svn":0, + "sgxtcbcomp09svn":0, + "sgxtcbcomp10svn":0, + "sgxtcbcomp11svn":0, + "sgxtcbcomp12svn":0, + "sgxtcbcomp13svn":0, + "sgxtcbcomp14svn":0, + "sgxtcbcomp15svn":0, + "sgxtcbcomp16svn":0, + "pcesvn":3 + }, + "status":"ConfigurationNeeded" + }, + { + "tcb": + { + "sgxtcbcomp01svn":0, + "sgxtcbcomp02svn":0, + "sgxtcbcomp03svn":0, + "sgxtcbcomp04svn":0, + "sgxtcbcomp05svn":0, + "sgxtcbcomp06svn":0, + "sgxtcbcomp07svn":0, + "sgxtcbcomp08svn":0, + "sgxtcbcomp09svn":0, + "sgxtcbcomp10svn":0, + "sgxtcbcomp11svn":0, + "sgxtcbcomp12svn":0, + "sgxtcbcomp13svn":0, + "sgxtcbcomp14svn":0, + "sgxtcbcomp15svn":0, + "sgxtcbcomp16svn":0, + "pcesvn":2 + }, + "status":"Revoked" + } + ] + }, + "signature":"43cc4895a9b1035ef4c5aa0290913a31c1825d192ecbe0ef4854c603f2dede023665cd622f25825bbae1f8f8dc6e1286cdee499c8a40fc76d689dd2a3329a1c1" +} \ No newline at end of file diff --git a/tools/PCKCertSelection/SampleData/tcb_info_4.json b/tools/PCKCertSelection/SampleData/tcb_info_4.json new file mode 100644 index 00000000..a67bc30c --- /dev/null +++ b/tools/PCKCertSelection/SampleData/tcb_info_4.json @@ -0,0 +1,1270 @@ +{ + "tcbInfo": + { + "id":"SGX", + "version":3, + "issueDate":"2018-07-23T14:35:49Z", + "nextUpdate":"2018-07-30T14:35:49Z", + "fmspc":"00707f000000", + "pceId":"0000", + "tcbType":0, + "tcbEvaluationDataNumber":0, + "tcbLevels": + [ + { + "tcb": + { + "sgxtcbcomponents": + [ + { + "svn":1, + "category":"ucode", + "type":"Late Patch" + }, + { + "svn":1, + "category":"ucode", + "type":"Late Patch" + }, + { + "svn":1, + "category":"ucode", + "type":"Late Patch" + }, + { + "svn":1, + "category":"ucode", + "type":"Late Patch" + }, + { + "svn":1, + "category":"ucode", + "type":"Late Patch" + }, + { + "svn":1, + "category":"ucode", + "type":"Late Patch" + }, + { + "svn":1, + "category":"ucode", + "type":"Late Patch" + }, + { + "svn":1, + "category":"ucode", + "type":"Late Patch" + }, + { + "svn":1, + "category":"ucode", + "type":"Late Patch" + }, + { + "svn":1, + "category":"ucode", + "type":"Late Patch" + }, + { + "svn":1, + "category":"ucode", + "type":"Late Patch" + }, + { + "svn":1, + "category":"ucode", + "type":"Late Patch" + }, + { + "svn":1, + "category":"ucode", + "type":"Late Patch" + }, + { + "svn":1, + "category":"ucode", + "type":"Late Patch" + }, + { + "svn":0, + "category":"SW", + "type":"Late Patch" + }, + { + "svn":0, + "category":"BIOS", + "type":"Patch@Reset" + } + ], + "pcesvn":7, + "tdxtcbcomponents": + [ + { + "svn":1, + "category":"ucode", + "type":"Late Patch" + }, + { + "svn":1, + "category":"ucode", + "type":"Late Patch" + }, + { + "svn":1, + "category":"ucode", + "type":"Late Patch" + }, + { + "svn":1, + "category":"ucode", + "type":"Late Patch" + }, + { + "svn":1, + "category":"ucode", + "type":"Late Patch" + }, + { + "svn":1, + "category":"ucode", + "type":"Late Patch" + }, + { + "svn":1, + "category":"ucode", + "type":"Late Patch" + }, + { + "svn":1, + "category":"ucode", + "type":"Late Patch" + }, + { + "svn":1, + "category":"ucode", + "type":"Late Patch" + }, + { + "svn":1, + "category":"ucode", + "type":"Late Patch" + }, + { + "svn":1, + "category":"ucode", + "type":"Late Patch" + }, + { + "svn":1, + "category":"ucode", + "type":"Late Patch" + }, + { + "svn":1, + "category":"ucode", + "type":"Late Patch" + }, + { + "svn":1, + "category":"ucode", + "type":"Late Patch" + }, + { + "svn":0, + "category":"SW", + "type":"Late Patch" + }, + { + "svn":0, + "category":"BIOS", + "type":"Patch@Reset" + } + ] + }, + "tcbDate":"2020-02-05T14:35:49Z", + "tcbStatus":"UpToDate", + "AdvisoryIDs": + [ + "INTEL-SA-00079", + "INTEL-SA-00076" + ] + }, + { + "tcb": + { + "sgxtcbcomponents": + [ + { + "svn":1, + "category":"ucode", + "type":"Late Patch" + }, + { + "svn":1, + "category":"ucode", + "type":"Late Patch" + }, + { + "svn":1, + "category":"ucode", + "type":"Late Patch" + }, + { + "svn":1, + "category":"ucode", + "type":"Late Patch" + }, + { + "svn":1, + "category":"ucode", + "type":"Late Patch" + }, + { + "svn":1, + "category":"ucode", + "type":"Late Patch" + }, + { + "svn":1, + "category":"ucode", + "type":"Late Patch" + }, + { + "svn":1, + "category":"ucode", + "type":"Late Patch" + }, + { + "svn":1, + "category":"ucode", + "type":"Late Patch" + }, + { + "svn":1, + "category":"ucode", + "type":"Late Patch" + }, + { + "svn":1, + "category":"ucode", + "type":"Late Patch" + }, + { + "svn":1, + "category":"ucode", + "type":"Late Patch" + }, + { + "svn":0, + "category":"ucode", + "type":"Late Patch" + }, + { + "svn":0, + "category":"ucode", + "type":"Late Patch" + }, + { + "svn":0, + "category":"SW", + "type":"Late Patch" + }, + { + "svn":0, + "category":"BIOS", + "type":"Patch@Reset" + } + ], + "pcesvn":6, + "tdxtcbcomponents": + [ + { + "svn":1, + "category":"ucode", + "type":"Late Patch" + }, + { + "svn":1, + "category":"ucode", + "type":"Late Patch" + }, + { + "svn":1, + "category":"ucode", + "type":"Late Patch" + }, + { + "svn":1, + "category":"ucode", + "type":"Late Patch" + }, + { + "svn":1, + "category":"ucode", + "type":"Late Patch" + }, + { + "svn":1, + "category":"ucode", + "type":"Late Patch" + }, + { + "svn":1, + "category":"ucode", + "type":"Late Patch" + }, + { + "svn":1, + "category":"ucode", + "type":"Late Patch" + }, + { + "svn":1, + "category":"ucode", + "type":"Late Patch" + }, + { + "svn":1, + "category":"ucode", + "type":"Late Patch" + }, + { + "svn":1, + "category":"ucode", + "type":"Late Patch" + }, + { + "svn":1, + "category":"ucode", + "type":"Late Patch" + }, + { + "svn":0, + "category":"ucode", + "type":"Late Patch" + }, + { + "svn":0, + "category":"ucode", + "type":"Late Patch" + }, + { + "svn":0, + "category":"SW", + "type":"Late Patch" + }, + { + "svn":0, + "category":"BIOS", + "type":"Patch@Reset" + } + ] + }, + "tcbDate":"2020-02-05T14:35:49Z", + "tcbStatus":"SWHardeningNeeded", + "AdvisoryIDs": + [ + "INTEL-SA-00079", + "INTEL-SA-00076" + ] + }, + { + "tcb": + { + "sgxtcbcomponents": + [ + { + "svn":1, + "category":"ucode", + "type":"Late Patch" + }, + { + "svn":1, + "category":"ucode", + "type":"Late Patch" + }, + { + "svn":1, + "category":"ucode", + "type":"Late Patch" + }, + { + "svn":1, + "category":"ucode", + "type":"Late Patch" + }, + { + "svn":1, + "category":"ucode", + "type":"Late Patch" + }, + { + "svn":1, + "category":"ucode", + "type":"Late Patch" + }, + { + "svn":1, + "category":"ucode", + "type":"Late Patch" + }, + { + "svn":1, + "category":"ucode", + "type":"Late Patch" + }, + { + "svn":1, + "category":"ucode", + "type":"Late Patch" + }, + { + "svn":1, + "category":"ucode", + "type":"Late Patch" + }, + { + "svn":0, + "category":"ucode", + "type":"Late Patch" + }, + { + "svn":0, + "category":"ucode", + "type":"Late Patch" + }, + { + "svn":0, + "category":"ucode", + "type":"Late Patch" + }, + { + "svn":0, + "category":"ucode", + "type":"Late Patch" + }, + { + "svn":0, + "category":"SW", + "type":"Late Patch" + }, + { + "svn":0, + "category":"BIOS", + "type":"Patch@Reset" + } + ], + "pcesvn":5, + "tdxtcbcomponents": + [ + { + "svn":1, + "category":"ucode", + "type":"Late Patch" + }, + { + "svn":1, + "category":"ucode", + "type":"Late Patch" + }, + { + "svn":1, + "category":"ucode", + "type":"Late Patch" + }, + { + "svn":1, + "category":"ucode", + "type":"Late Patch" + }, + { + "svn":1, + "category":"ucode", + "type":"Late Patch" + }, + { + "svn":1, + "category":"ucode", + "type":"Late Patch" + }, + { + "svn":1, + "category":"ucode", + "type":"Late Patch" + }, + { + "svn":1, + "category":"ucode", + "type":"Late Patch" + }, + { + "svn":1, + "category":"ucode", + "type":"Late Patch" + }, + { + "svn":1, + "category":"ucode", + "type":"Late Patch" + }, + { + "svn":0, + "category":"ucode", + "type":"Late Patch" + }, + { + "svn":0, + "category":"ucode", + "type":"Late Patch" + }, + { + "svn":0, + "category":"ucode", + "type":"Late Patch" + }, + { + "svn":0, + "category":"ucode", + "type":"Late Patch" + }, + { + "svn":0, + "category":"SW", + "type":"Late Patch" + }, + { + "svn":0, + "category":"BIOS", + "type":"Patch@Reset" + } + ] + }, + "tcbDate":"2020-02-05T14:35:49Z", + "tcbStatus":"ConfigurationNeeded", + "AdvisoryIDs": + [ + "INTEL-SA-00079", + "INTEL-SA-00076" + ] + }, + { + "tcb": + { + "sgxtcbcomponents": + [ + { + "svn":1, + "category":"ucode", + "type":"Late Patch" + }, + { + "svn":1, + "category":"ucode", + "type":"Late Patch" + }, + { + "svn":1, + "category":"ucode", + "type":"Late Patch" + }, + { + "svn":1, + "category":"ucode", + "type":"Late Patch" + }, + { + "svn":1, + "category":"ucode", + "type":"Late Patch" + }, + { + "svn":1, + "category":"ucode", + "type":"Late Patch" + }, + { + "svn":1, + "category":"ucode", + "type":"Late Patch" + }, + { + "svn":1, + "category":"ucode", + "type":"Late Patch" + }, + { + "svn":0, + "category":"ucode", + "type":"Late Patch" + }, + { + "svn":0, + "category":"ucode", + "type":"Late Patch" + }, + { + "svn":0, + "category":"ucode", + "type":"Late Patch" + }, + { + "svn":0, + "category":"ucode", + "type":"Late Patch" + }, + { + "svn":0, + "category":"ucode", + "type":"Late Patch" + }, + { + "svn":0, + "category":"ucode", + "type":"Late Patch" + }, + { + "svn":0, + "category":"SW", + "type":"Late Patch" + }, + { + "svn":0, + "category":"BIOS", + "type":"Patch@Reset" + } + ], + "pcesvn":4, + "tdxtcbcomponents": + [ + { + "svn":1, + "category":"ucode", + "type":"Late Patch" + }, + { + "svn":1, + "category":"ucode", + "type":"Late Patch" + }, + { + "svn":1, + "category":"ucode", + "type":"Late Patch" + }, + { + "svn":1, + "category":"ucode", + "type":"Late Patch" + }, + { + "svn":1, + "category":"ucode", + "type":"Late Patch" + }, + { + "svn":1, + "category":"ucode", + "type":"Late Patch" + }, + { + "svn":1, + "category":"ucode", + "type":"Late Patch" + }, + { + "svn":1, + "category":"ucode", + "type":"Late Patch" + }, + { + "svn":0, + "category":"ucode", + "type":"Late Patch" + }, + { + "svn":0, + "category":"ucode", + "type":"Late Patch" + }, + { + "svn":0, + "category":"ucode", + "type":"Late Patch" + }, + { + "svn":0, + "category":"ucode", + "type":"Late Patch" + }, + { + "svn":0, + "category":"ucode", + "type":"Late Patch" + }, + { + "svn":0, + "category":"ucode", + "type":"Late Patch" + }, + { + "svn":0, + "category":"SW", + "type":"Late Patch" + }, + { + "svn":0, + "category":"BIOS", + "type":"Patch@Reset" + } + ] + }, + "tcbDate":"2020-02-05T14:35:49Z", + "tcbStatus":"ConfigurationAndSWHardeningNeeded", + "AdvisoryIDs": + [ + "INTEL-SA-00079", + "INTEL-SA-00076" + ] + }, + { + "tcb": + { + "sgxtcbcomponents": + [ + { + "svn":1, + "category":"ucode", + "type":"Late Patch" + }, + { + "svn":1, + "category":"ucode", + "type":"Late Patch" + }, + { + "svn":1, + "category":"ucode", + "type":"Late Patch" + }, + { + "svn":1, + "category":"ucode", + "type":"Late Patch" + }, + { + "svn":1, + "category":"ucode", + "type":"Late Patch" + }, + { + "svn":1, + "category":"ucode", + "type":"Late Patch" + }, + { + "svn":0, + "category":"ucode", + "type":"Late Patch" + }, + { + "svn":0, + "category":"ucode", + "type":"Late Patch" + }, + { + "svn":0, + "category":"ucode", + "type":"Late Patch" + }, + { + "svn":0, + "category":"ucode", + "type":"Late Patch" + }, + { + "svn":0, + "category":"ucode", + "type":"Late Patch" + }, + { + "svn":0, + "category":"ucode", + "type":"Late Patch" + }, + { + "svn":0, + "category":"ucode", + "type":"Late Patch" + }, + { + "svn":0, + "category":"ucode", + "type":"Late Patch" + }, + { + "svn":0, + "category":"SW", + "type":"Late Patch" + }, + { + "svn":0, + "category":"BIOS", + "type":"Patch@Reset" + } + ], + "pcesvn":3, + "tdxtcbcomponents": + [ + { + "svn":1, + "category":"ucode", + "type":"Late Patch" + }, + { + "svn":1, + "category":"ucode", + "type":"Late Patch" + }, + { + "svn":1, + "category":"ucode", + "type":"Late Patch" + }, + { + "svn":1, + "category":"ucode", + "type":"Late Patch" + }, + { + "svn":1, + "category":"ucode", + "type":"Late Patch" + }, + { + "svn":1, + "category":"ucode", + "type":"Late Patch" + }, + { + "svn":0, + "category":"ucode", + "type":"Late Patch" + }, + { + "svn":0, + "category":"ucode", + "type":"Late Patch" + }, + { + "svn":0, + "category":"ucode", + "type":"Late Patch" + }, + { + "svn":0, + "category":"ucode", + "type":"Late Patch" + }, + { + "svn":0, + "category":"ucode", + "type":"Late Patch" + }, + { + "svn":0, + "category":"ucode", + "type":"Late Patch" + }, + { + "svn":0, + "category":"ucode", + "type":"Late Patch" + }, + { + "svn":0, + "category":"ucode", + "type":"Late Patch" + }, + { + "svn":0, + "category":"SW", + "type":"Late Patch" + }, + { + "svn":0, + "category":"BIOS", + "type":"Patch@Reset" + } + ] + }, + "tcbDate":"2020-02-05T14:35:49Z", + "tcbStatus":"OutOfDate", + "AdvisoryIDs": + [ + "INTEL-SA-00079", + "INTEL-SA-00076" + ] + }, + { + "tcb": + { + "sgxtcbcomponents": + [ + { + "svn":1, + "category":"ucode", + "type":"Late Patch" + }, + { + "svn":1, + "category":"ucode", + "type":"Late Patch" + }, + { + "svn":1, + "category":"ucode", + "type":"Late Patch" + }, + { + "svn":1, + "category":"ucode", + "type":"Late Patch" + }, + { + "svn":0, + "category":"ucode", + "type":"Late Patch" + }, + { + "svn":0, + "category":"ucode", + "type":"Late Patch" + }, + { + "svn":0, + "category":"ucode", + "type":"Late Patch" + }, + { + "svn":0, + "category":"ucode", + "type":"Late Patch" + }, + { + "svn":0, + "category":"ucode", + "type":"Late Patch" + }, + { + "svn":0, + "category":"ucode", + "type":"Late Patch" + }, + { + "svn":0, + "category":"ucode", + "type":"Late Patch" + }, + { + "svn":0, + "category":"ucode", + "type":"Late Patch" + }, + { + "svn":0, + "category":"ucode", + "type":"Late Patch" + }, + { + "svn":0, + "category":"ucode", + "type":"Late Patch" + }, + { + "svn":0, + "category":"SW", + "type":"Late Patch" + }, + { + "svn":0, + "category":"BIOS", + "type":"Patch@Reset" + } + ], + "pcesvn":2, + "tdxtcbcomponents": + [ + { + "svn":1, + "category":"ucode", + "type":"Late Patch" + }, + { + "svn":1, + "category":"ucode", + "type":"Late Patch" + }, + { + "svn":1, + "category":"ucode", + "type":"Late Patch" + }, + { + "svn":1, + "category":"ucode", + "type":"Late Patch" + }, + { + "svn":0, + "category":"ucode", + "type":"Late Patch" + }, + { + "svn":0, + "category":"ucode", + "type":"Late Patch" + }, + { + "svn":0, + "category":"ucode", + "type":"Late Patch" + }, + { + "svn":0, + "category":"ucode", + "type":"Late Patch" + }, + { + "svn":0, + "category":"ucode", + "type":"Late Patch" + }, + { + "svn":0, + "category":"ucode", + "type":"Late Patch" + }, + { + "svn":0, + "category":"ucode", + "type":"Late Patch" + }, + { + "svn":0, + "category":"ucode", + "type":"Late Patch" + }, + { + "svn":0, + "category":"ucode", + "type":"Late Patch" + }, + { + "svn":0, + "category":"ucode", + "type":"Late Patch" + }, + { + "svn":0, + "category":"SW", + "type":"Late Patch" + }, + { + "svn":0, + "category":"BIOS", + "type":"Patch@Reset" + } + ] + }, + "tcbDate":"2020-02-05T14:35:49Z", + "tcbStatus":"OutOfDateConfigurationNeeded", + "AdvisoryIDs": + [ + "INTEL-SA-00079", + "INTEL-SA-00076" + ] + }, + { + "tcb": + { + "sgxtcbcomponents": + [ + { + "svn":0, + "category":"ucode", + "type":"Late Patch" + }, + { + "svn":0, + "category":"ucode", + "type":"Late Patch" + }, + { + "svn":0, + "category":"ucode", + "type":"Late Patch" + }, + { + "svn":0, + "category":"ucode", + "type":"Late Patch" + }, + { + "svn":0, + "category":"ucode", + "type":"Late Patch" + }, + { + "svn":0, + "category":"ucode", + "type":"Late Patch" + }, + { + "svn":0, + "category":"ucode", + "type":"Late Patch" + }, + { + "svn":0, + "category":"ucode", + "type":"Late Patch" + }, + { + "svn":0, + "category":"ucode", + "type":"Late Patch" + }, + { + "svn":0, + "category":"ucode", + "type":"Late Patch" + }, + { + "svn":0, + "category":"ucode", + "type":"Late Patch" + }, + { + "svn":0, + "category":"ucode", + "type":"Late Patch" + }, + { + "svn":0, + "category":"ucode", + "type":"Late Patch" + }, + { + "svn":0, + "category":"ucode", + "type":"Late Patch" + }, + { + "svn":0, + "category":"ucode", + "type":"Late Patch" + }, + { + "svn":0, + "category":"BIOS", + "type":"Patch@Reset" + } + ], + "pcesvn":1, + "tdxtcbcomponents": + [ + { + "svn":0, + "category":"ucode", + "type":"Late Patch" + }, + { + "svn":0, + "category":"ucode", + "type":"Late Patch" + }, + { + "svn":0, + "category":"ucode", + "type":"Late Patch" + }, + { + "svn":0, + "category":"ucode", + "type":"Late Patch" + }, + { + "svn":0, + "category":"ucode", + "type":"Late Patch" + }, + { + "svn":0, + "category":"ucode", + "type":"Late Patch" + }, + { + "svn":0, + "category":"ucode", + "type":"Late Patch" + }, + { + "svn":0, + "category":"ucode", + "type":"Late Patch" + }, + { + "svn":0, + "category":"ucode", + "type":"Late Patch" + }, + { + "svn":0, + "category":"ucode", + "type":"Late Patch" + }, + { + "svn":0, + "category":"ucode", + "type":"Late Patch" + }, + { + "svn":0, + "category":"ucode", + "type":"Late Patch" + }, + { + "svn":0, + "category":"ucode", + "type":"Late Patch" + }, + { + "svn":0, + "category":"ucode", + "type":"Late Patch" + }, + { + "svn":0, + "category":"ucode", + "type":"Late Patch" + }, + { + "svn":0, + "category":"BIOS", + "type":"Patch@Reset" + } + ] + }, + "tcbDate":"2020-02-05T14:35:49Z", + "tcbStatus":"Revoked", + "AdvisoryIDs": + [ + "INTEL-SA-00079", + "INTEL-SA-00076" + ] + } + ] + }, + "signature":"43cc4895a9b1035ef4c5aa0290913a31c1825d192ecbe0ef4854c603f2dede023665cd622f25825bbae1f8f8dc6e1286cdee499c8a40fc76d689dd2a3329a1c1" +} diff --git a/tools/PCKRetrievalTool/App/linux/network_wrapper.cpp b/tools/PCKRetrievalTool/App/linux/network_wrapper.cpp index 226d4762..c730a795 100644 --- a/tools/PCKRetrievalTool/App/linux/network_wrapper.cpp +++ b/tools/PCKRetrievalTool/App/linux/network_wrapper.cpp @@ -205,7 +205,7 @@ static bool process_configuration_setting(const char *config_file_name, string& url = value; } else { - url = server_url_string + "/sgx/certification/v3/platforms"; + url = server_url_string + "/sgx/certification/v4/platforms"; } } else if (name.compare("USE_SECURE_CERT") == 0) { diff --git a/tools/PCKRetrievalTool/App/utility.cpp b/tools/PCKRetrievalTool/App/utility.cpp index 0704b92c..a4033263 100644 --- a/tools/PCKRetrievalTool/App/utility.cpp +++ b/tools/PCKRetrievalTool/App/utility.cpp @@ -273,7 +273,7 @@ bool load_enclave(const char* enclave_name, sgx_enclave_id_t* p_eid) p_eid, NULL); if (SGX_SUCCESS != sgx_status) { - printf("Error, call sgx_create_enclave: fail [%s], SGXError:%04x.\n", __FUNCTION__, sgx_status); + printf("Error, call sgx_create_enclave: fail [%s], SGXError:%04x.\n",__FUNCTION__, sgx_status); ret = false; } @@ -629,47 +629,47 @@ int collect_data(uint8_t **pp_data_buffer) bool load_flag = get_urts_library_handle(); if(false == load_flag) {// can't find urts shared library to load enclave ret = -1; - goto CLEANUP; + goto CLEANUP; } load_flag = load_enclave(ID_ENCLAVE_NAME, &id_enclave_eid); if(false == load_flag) { // can't load id_enclave. ret = -1; - goto CLEANUP; + goto CLEANUP; } sgx_status = ide_get_id(id_enclave_eid, &ecall_ret, &platform_id); if (SGX_SUCCESS != sgx_status) { fprintf(stderr, "Failed to call into the ID_ENCLAVE:get_qe_id. 0x%04x.\n", sgx_status); ret = -1; - goto CLEANUP; + goto CLEANUP; } if (SGX_SUCCESS != ecall_ret) { fprintf(stderr, "Failed to get QE_ID. 0x%04x.\n", ecall_ret); ret = -1; - goto CLEANUP; + goto CLEANUP; } load_flag = load_enclave(PCE_ENCLAVE_NAME, &pce_enclave_eid); if(false == load_flag) { // can't load pce enclave. ret = -1; - goto CLEANUP; + goto CLEANUP; } p_sgx_get_target_info = (sgx_get_target_info_func_t)FINDFUNCTIONSYM(sgx_urts_handle, "sgx_get_target_info"); if (p_sgx_get_target_info == NULL) { printf("ERROR: Can't find the function sgx_get_target_info in sgx_urts library.\n"); ret = -1; - goto CLEANUP; + goto CLEANUP; } sgx_status = p_sgx_get_target_info(pce_enclave_eid, &pce_target_info); if (SGX_SUCCESS != sgx_status) { fprintf(stderr, "Failed to get pce target info. The error code is: 0x%04x.\n", sgx_status); ret = -1; - goto CLEANUP; + goto CLEANUP; } sgx_status = ide_get_pce_encrypt_key(id_enclave_eid, @@ -683,13 +683,13 @@ int collect_data(uint8_t **pp_data_buffer) if (SGX_SUCCESS != sgx_status) { fprintf(stderr, "Failed to call into the ID_ENCLAVE: get_report_and_pce_encrypt_key. The error code is: 0x%04x.\n", sgx_status); ret = -1; - goto CLEANUP; + goto CLEANUP; } if (SGX_SUCCESS != ecall_ret) { fprintf(stderr, "Failed to generate PCE encryption key. The error code is: 0x%04x.\n", ecall_ret); ret = -1; - goto CLEANUP; + goto CLEANUP; } sgx_status = get_pc_info(pce_enclave_eid, @@ -706,24 +706,24 @@ int collect_data(uint8_t **pp_data_buffer) if (SGX_SUCCESS != sgx_status) { fprintf(stderr, "Failed to call into PCE enclave: get_pc_info. The error code is: 0x%04x.\n", sgx_status); ret = -1; - goto CLEANUP; + goto CLEANUP; } if (SGX_SUCCESS != ecall_ret) { fprintf(stderr, "Failed to get PCE info. The error code is: 0x%04x.\n", ecall_ret); ret = -1; - goto CLEANUP; + goto CLEANUP; } if (signature_scheme != PCE_NIST_P256_ECDSA_SHA256) { fprintf(stderr, "PCE returned incorrect signature scheme.\n"); ret = -1; - goto CLEANUP; + goto CLEANUP; } if (encrypted_ppid_ret_size != ENCRYPTED_PPID_LENGTH) { fprintf(stderr, "PCE returned unexpected returned encrypted PPID size.\n"); ret = -1; - goto CLEANUP; + goto CLEANUP; } buffer_size = ENCRYPTED_PPID_LENGTH + CPU_SVN_LENGTH + ISV_SVN_LENGTH + PCE_ID_LENGTH + DEFAULT_PLATFORM_ID_LENGTH; @@ -732,7 +732,7 @@ int collect_data(uint8_t **pp_data_buffer) if (NULL == *pp_data_buffer) { fprintf(stderr,"Couldn't allocate data buffer\n"); ret = -1; - goto CLEANUP; + goto CLEANUP; } memset(*pp_data_buffer, 0, buffer_size); p_temp = *pp_data_buffer; diff --git a/tools/PCKRetrievalTool/App/win/network_wrapper.cpp b/tools/PCKRetrievalTool/App/win/network_wrapper.cpp index b77483b9..4bea6c42 100644 --- a/tools/PCKRetrievalTool/App/win/network_wrapper.cpp +++ b/tools/PCKRetrievalTool/App/win/network_wrapper.cpp @@ -118,7 +118,7 @@ static bool process_configuration_setting(const char *config_file_name, string& url = value; } else { - url = server_url_string + "/sgx/certification/v3/platforms"; + url = server_url_string + "/sgx/certification/v4/platforms"; } } else if (name.compare("USE_SECURE_CERT") == 0) { diff --git a/tools/PCKRetrievalTool/README.build b/tools/PCKRetrievalTool/README.build index 34bbec18..9cb7722e 100644 --- a/tools/PCKRetrievalTool/README.build +++ b/tools/PCKRetrievalTool/README.build @@ -8,8 +8,6 @@ Intel(R) Software Guard Extensions Data Center Attestation Primitives (Intel(R) For Linux version: - Install prebuilt Intel(R) SGX SDK and urts Installer, you can download it from [01.org](https://01.org/intel-software-guard-extensions/downloads) a. sgx_linux_x64_sdk_${version}.bin -- Build QuoteGeneration - a. please refer "How to build" section in the QuoteGeneration's README - Just run the command: make diff --git a/tools/PCKRetrievalTool/ThirdPartyLicenseIndex.txt b/tools/PCKRetrievalTool/ThirdPartyLicenseIndex.txt new file mode 100644 index 00000000..312890ab --- /dev/null +++ b/tools/PCKRetrievalTool/ThirdPartyLicenseIndex.txt @@ -0,0 +1,971 @@ +Intel® Software Guard Extensions PCKID Retrieval Tool +Third Party Components Attributions + + +The following are licenses for third party software that was used to develop the Intel product, Intel® Software Guard Extensions PCKID Retrieval Tool. These licenses are listed due to attribution requirements in these license agreements. For the avoidance of doubt, Intel® Software Guard Extensions is solely governed by the terms and conditions of the End User License Agreement that accompanies Intel® Software Guard Extensions PCKID Retrieval Tool and the third party licenses identified in the ThirdPartyLicenseIndex.txt that accompanies Intel® Software Guard Extensions PCKID Retrieval Tool. + + +OpenBSD* +http://openbsd.org/ + +OpenBSD* Copyright Policy + +• Goal + Copyright law is complex, OpenBSD* policy is simple - OpenBSD strives to maintain the spirit of the original Berkeley Unix copyrights. + OpenBSD can exist as it does today because of the example set by the Computer Systems Research Group at Berkeley and the battles which they and others fought to create a relatively un-encumbered Unix source distribution. + The ability of a freely redistributable "Berkeley" Unix to move forward on a competitive basis with other operating systems depends on the willingness of the various development groups to exchange code amongst themselves and with other projects. Understanding the legal issues surrounding copyright is fundamental to the ability to exchange and re-distribute code, while honoring the spirit of the copyright and concept of attribution is fundamental to promoting the cooperation of the people involved. +• The Berkeley* Copyright + The Berkeley* copyright poses no restrictions on private or commercial use of the software and imposes only simple and uniform requirements for maintaining copyright notices in redistributed versions and crediting the originator of the material only in advertising. + For instance: + * Copyright (c) 1982, 1986, 1990, 1991, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University 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 REGENTS 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 REGENTS 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. + * + Berkeley rescinded the 3rd term (the advertising term) on 22 July 1999. Verbatim copies of the Berkeley license in the OpenBSD tree have that term removed. In addition, many 3rd-party BSD-style licenses consist solely of the first two terms. + Because the OpenBSD copyright imposes no conditions beyond those imposed by the Berkeley copyright, OpenBSD can hope to share the same wide distribution and applicability as the Berkeley distributions. It follows however, that OpenBSD cannot include material which includes copyrights which are more restrictive than the Berkeley copyright, or must relegate this material to a secondary status, i.e. OpenBSD as a whole is freely redistributable, but some optional components may not be. +• Copyright Law + While the overall subject of copyright law is far beyond the scope of this document, some basics are in order. Under the current copyright law, copyrights are implicit in the creation of a new work and reside with the creator, unless otherwise assigned. In general the copyright applies only to the new work, not the material the work was derived from, nor those portions of the derivative material included in the new work. + Copyright law admits to three general categories of works: + Original Work + A new work that is not derived from an existing work. + Derivative Work + Work that is derived from, includes or amends existing works. + Compilations + A work that is a compilation of existing new and derivative works. + The fundamental concept is that there is primacy of the copyright, that is a copyright of a derivative work does not affect the rights held by the owner of the copyright of the original work, rather only the part added. Likewise the copyright of a compilation does not affect the rights of the owner of the included works, only the compilation as an entity. + It is vitally important to understand that copyrights are broad protections as defined by national and international copyright law. The "copyright notices" usually included in source files are not copyrights, but rather notices that a party asserts that they hold copyright to the material or to part of the material. Typically these notices are associated with license terms which grant permissions subject to copyright law and with disclaimers that state the position of the copyright holder/distributor with respect to liability surrounding use of the material. +• Permissions - the flip side + Because copyrights arise from the creation of a work, rather than through a registration process, there needs to be a practical way to extend permission to use a work beyond what might be allowed by "fair use" provisions of the copyright laws. + This permission typically takes the form of a "release" or "license" included in the work, which grants the additional uses beyond those granted by copyright law, usually subject to a variety of conditions. At one extreme sits "public domain" where the originator asserts that he imposes no restrictions on use of the material, at the other restrictive clauses that actually grant no additional rights or impose restrictive, discriminatory or impractical conditions on use of the work. + Again, an important point to note is that the release and conditions can only apply to the portion of the work that was originated by the copyright holder - the holder of a copyright on a derivative work can neither grant additional permissions for use of the original work, nor impose more restrictive conditions for use of that work. + Because copyright arises from the creation of a work and not the text or a registration process, removing or altering a copyright notice or associated release terms has no bearing on the existence of the copyright, rather all that is accomplished is to cast doubt upon whatever rights the person making the modifications had to use the material in the first place. Likewise, adding terms and conditions in conflict with the original terms and conditions does not supersede them, rather it casts doubts on the rights of the person making the amendments to use the material and creates confusion as to whether anyone can use the amended version or derivatives thereof. + Finally, releases are generally binding on the material that they are distributed with. This means that if the originator of a work distributes that work with a release granting certain permissions, those permissions apply as stated, without discrimination, to all persons legitimately possessing a copy of the work. That means that having granted a permission, the copyright holder can not retroactively say that an individual or class of individuals are no longer granted those permissions. Likewise should the copyright holder decide to "go commercial" he can not revoke permissions already granted for the use of the work as distributed, though he may impose more restrictive permissions in his future distributions of that work. +• Specific Cases +This section attempts to summarize the position of OpenBSD relative to some commonly encountered copyrights. +Berkeley* +The Berkeley copyright is the model for the OpenBSD copyright. It retains the rights of the copyright holder, while imposing minimal conditions on the use of the copyrighted material. Material with Berkeley copyrights, or copyrights closely adhering to the Berkeley model can generally be included in OpenBSD. +AT&T* +As part of its settlement with AT&T*, Berkeley included an AT&T copyright notice on some of the files in 4.4BSD lite and lite2. The terms of this license are identical to the standard Berkeley license. +Additionally, OpenBSD includes some other AT&T code with non-restrictive copyrights, such as the reference implementation of awk. +Caldera* +Caldera* (now known as the SCO group) is the current owner of the Unix code copyrights. On 23 January 2002, the original Unix code (versions 1 through seven, including 32V) was freed by Caldera. This code is now available under a 4-term BSD-style license. As a result, it is now possible to incorporate real Unix code into OpenBSD (though this code is quite old and generally requires significant changes to bring it up to date). +DEC*, Sun*, other manufacturers/software houses. +In general OpenBSD does not include material copyrighted by manufacturers or software houses. Material may be included where the copyright owner has granted general permission for reuse without conditions, with terms similar to the Berkeley copyright, or where the material is the product of an employee and the employer's copyright notice effectively releases any rights they might have to the work. +Carnegie-Mellon* (CMU, Mach) +The Carnegie-Mellon copyright is similar to the Berkeley copyright, except that it requests that derivative works be made available to Carnegie-Mellon. Because this is only a request and not a condition, such material can still be included in OpenBSD. It should be noted that existing versions of Mach are still subject to AT&T copyrights, which prevents the general distribution of Mach sources. +Apache* +The original Apache* copyright is similar to the Berkeley copyright, except that it stipulates that products derived from the code may not have "Apache" in their name. The purpose of this clause is to avoid a situation in which another party releases a modified version of the code named in such a way to make users think that it is the "official" version. This is not an issue with OpenBSD because OpenBSD is a Compilation, and not a Derived Work. Source code published under version 2 of the Apache license cannot be included into OpenBSD. As a consequence, OpenBSD now maintains its own version of Apache based on version 1.3.29. The OpenBSD version includes many enhancements and bugfixes. +ISC* +The ISC* copyright is functionally equivalent to a two-term BSD copyright with language removed that is made unnecessary by the Berne convention. This is the preferred license for new code incorporated into OpenBSD. A sample license is included in the source tree as /usr/src/share/misc/license.template. +GNU* General Public License, GPL, LGPL, copyleft, etc. +The GNU* Public License and licenses modeled on it impose the restriction that source code must be distributed or made available for all works that are derivatives of the GNU copyrighted code. +While this may be a noble strategy in terms of software sharing, it is a condition that is typically unacceptable for commercial use of software. As a consequence, software bound by the GPL terms can not be included in the kernel or "runtime" of OpenBSD, though software subject to GPL terms may be included as development tools or as part of the system that are "optional" as long as such use does not result in OpenBSD as a whole becoming subject to the GPL terms. +As an example, GCC and other GNU tools are included in the OpenBSD tool chain. However, it is quite possible to distribute a system for many applications without a tool chain, or the distributor can choose to include a tool chain as an optional bundle which conforms to the GPL terms. +NetBSD* +Much of OpenBSD is originally based on and evolved from NetBSD*, since some of the OpenBSD developers were involved in the NetBSD project. The general NetBSD license terms are compatible with the Berkeley license and permit such use. Material subject only to the general NetBSD license can generally be included in OpenBSD. +In the past, NetBSD has included material copyrighted by individuals who have imposed license conditions beyond that of the general NetBSD license, but granted the NetBSD Foundation license to distribute the material. Such material can not be included in OpenBSD as long as the conditions imposed are at odds with the OpenBSD license terms or releases from those terms are offered on a discriminatory basis. +FreeBSD* +Most of FreeBSD* is also based on Berkeley licensed material or includes copyright notices based on the Berkeley model. Such material can be included in OpenBSD, while those parts that are subject to GPL or various individual copyright terms that are at odds with the OpenBSD license can not be included in OpenBSD. +Linux* +Most of Linux* is subject to GPL style licensing terms and therefore can not be included in OpenBSD. Individual components may be eligible, subject to the terms of the originator's copyright notices. Note that Linux "distributions" may also be subject to additional copyright claims of the distributing organization, either as a compilation or on material included that is not part of the Linux core. +X*, XFree86*, X.Org* +X*, X.Org* or XFree86* are not parts of OpenBSD, rather X.Org and parts of XFree86 3.3.6 are distributed with many OpenBSD ports as a convenience to the user, subject to applicable license terms. +Shareware, Charityware, Freeware, etc. +Most "shareware" copyright notices impose conditions for redistribution, use or visibility that are at conflict with the OpenBSD project goals. Review on a case-by-case basis is required as to whether the wording of the conditions is acceptable in terms of conditions being requested vs. demanded and whether the spirit of the conditions is compatible with goals of the OpenBSD project. +Public Domain +While material that is truly entered into the "Public Domain" can be included in OpenBSD, review is required on a case by case basis. Frequently the "public domain" assertion is made by someone who does not really hold all rights under Copyright law to grant that status or there are a variety of conditions imposed on use. For a work to be truly in the "Public Domain" all rights are abandoned and the material is offered without restrictions. + + +FreeBSD* +http://www.freebsd.org/ + +The FreeBSD* Copyright +Copyright 1992-2013 The FreeBSD Project. All rights reserved. +Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: +1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. +2. 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. +THIS SOFTWARE IS PROVIDED BY THE FREEBSD PROJECT ``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 FREEBSD PROJECT 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. +The views and conclusions contained in the software and documentation are those of the authors and should not be interpreted as representing official policies, either expressed or implied, of the FreeBSD Project. + + +NetBSD* +http://www.netbsd.org/ + +/*- + * Copyright (c) 2008 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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. + */ +________________________________________ +For complete copyright and licensing terms, see: http://www.netbsd.org/about/redistribution.html + + +SQLite* + +http://sqlite.org/ + +SQLite* Copyright + +All of the code and documentation in SQLite has been dedicated to the public domain by the authors. All code authors, and representatives of the companies they work for, have signed affidavits dedicating their contributions to the public domain and originals of those signed affidavits are stored in a firesafe at the main offices of Hwaci. Anyone is free to copy, modify, publish, use, compile, sell, or distribute the original SQLite code, either in source code form or as a compiled binary, for any purpose, commercial or non-commercial, and by any means. +The previous paragraph applies to the deliverable code and documentation in SQLite - those parts of the SQLite library that you actually bundle and ship with a larger application. Some scripts used as part of the build process (for example the "configure" scripts generated by autoconf) might fall under other open-source licenses. Nothing from these build scripts ever reaches the final deliverable SQLite library, however, and so the licenses associated with those scripts should not be a factor in assessing your rights to copy and use the SQLite library. +All of the deliverable code in SQLite has been written from scratch. No code has been taken from other projects or from the open internet. Every line of code can be traced back to its original author, and all of those authors have public domain dedications on file. So the SQLite code base is clean and is uncontaminated with licensed code from other projects. + + + +Dlmalloc* +Public domain +http://g.oswego.edu/dl/html/malloc.html + +CC0 1.0 Universal + +CREATIVE COMMONS CORPORATION IS NOT A LAW FIRM AND DOES NOT PROVIDE LEGAL SERVICES. DISTRIBUTION OF THIS DOCUMENT DOES NOT CREATE AN ATTORNEY-CLIENT RELATIONSHIP. CREATIVE COMMONS PROVIDES THIS INFORMATION ON AN "AS-IS" BASIS. CREATIVE COMMONS MAKES NO WARRANTIES REGARDING THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS PROVIDED HEREUNDER, AND DISCLAIMS LIABILITY FOR DAMAGES RESULTING FROM THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS PROVIDED HEREUNDER. +Statement of Purpose +The laws of most jurisdictions throughout the world automatically confer exclusive Copyright and Related Rights (defined below) upon the creator and subsequent owner(s) (each and all, an "owner") of an original work of authorship and/or a database (each, a "Work"). +Certain owners wish to permanently relinquish those rights to a Work for the purpose of contributing to a commons of creative, cultural and scientific works ("Commons") that the public can reliably and without fear of later claims of infringement build upon, modify, incorporate in other works, reuse and redistribute as freely as possible in any form whatsoever and for any purposes, including without limitation commercial purposes. These owners may contribute to the Commons to promote the ideal of a free culture and the further production of creative, cultural and scientific works, or to gain reputation or greater distribution for their Work in part through the use and efforts of others. +For these and/or other purposes and motivations, and without any expectation of additional consideration or compensation, the person associating CC0 with a Work (the "Affirmer"), to the extent that he or she is an owner of Copyright and Related Rights in the Work, voluntarily elects to apply CC0 to the Work and publicly distribute the Work under its terms, with knowledge of his or her Copyright and Related Rights in the Work and the meaning and intended legal effect of CC0 on those rights. +1. Copyright and Related Rights. A Work made available under CC0 may be protected by copyright and related or neighboring rights ("Copyright and Related Rights"). Copyright and Related Rights include, but are not limited to, the following: +i. the right to reproduce, adapt, distribute, perform, display, communicate, and translate a Work; +ii. moral rights retained by the original author(s) and/or performer(s); +iii. publicity and privacy rights pertaining to a person's image or likeness depicted in a Work; +iv. rights protecting against unfair competition in regards to a Work, subject to the limitations in paragraph 4(a), below; +v. rights protecting the extraction, dissemination, use and reuse of data in a Work; +vi. database rights (such as those arising under Directive 96/9/EC of the European Parliament and of the Council of 11 March 1996 on the legal protection of databases, and under any national implementation thereof, including any amended or successor version of such directive); and +vii. other similar, equivalent or corresponding rights throughout the world based on applicable law or treaty, and any national implementations thereof. +2. Waiver. To the greatest extent permitted by, but not in contravention of, applicable law, Affirmer hereby overtly, fully, permanently, irrevocably and unconditionally waives, abandons, and surrenders all of Affirmer's Copyright and Related Rights and associated claims and causes of action, whether now known or unknown (including existing as well as future claims and causes of action), in the Work (i) in all territories worldwide, (ii) for the maximum duration provided by applicable law or treaty (including future time extensions), (iii) in any current or future medium and for any number of copies, and (iv) for any purpose whatsoever, including without limitation commercial, advertising or promotional purposes (the "Waiver"). Affirmer makes the Waiver for the benefit of each member of the public at large and to the detriment of Affirmer's heirs and successors, fully intending that such Waiver shall not be subject to revocation, rescission, cancellation, termination, or any other legal or equitable action to disrupt the quiet enjoyment of the Work by the public as contemplated by Affirmer's express Statement of Purpose. +3. Public License Fallback. Should any part of the Waiver for any reason be judged legally invalid or ineffective under applicable law, then the Waiver shall be preserved to the maximum extent permitted taking into account Affirmer's express Statement of Purpose. In addition, to the extent the Waiver is so judged Affirmer hereby grants to each affected person a royalty-free, non transferable, non sublicensable, non exclusive, irrevocable and unconditional license to exercise Affirmer's Copyright and Related Rights in the Work (i) in all territories worldwide, (ii) for the maximum duration provided by applicable law or treaty (including future time extensions), (iii) in any current or future medium and for any number of copies, and (iv) for any purpose whatsoever, including without limitation commercial, advertising or promotional purposes (the "License"). The License shall be deemed effective as of the date CC0 was applied by Affirmer to the Work. Should any part of the License for any reason be judged legally invalid or ineffective under applicable law, such partial invalidity or ineffectiveness shall not invalidate the remainder of the License, and in such case Affirmer hereby affirms that he or she will not (i) exercise any of his or her remaining Copyright and Related Rights in the Work or (ii) assert any associated claims and causes of action with respect to the Work, in either case contrary to Affirmer's express Statement of Purpose. +4. Limitations and Disclaimers. +a. No trademark or patent rights held by Affirmer are waived, abandoned, surrendered, licensed or otherwise affected by this document. +b. Affirmer offers the Work as-is and makes no representations or warranties of any kind concerning the Work, express, implied, statutory or otherwise, including without limitation warranties of title, merchantability, fitness for a particular purpose, non infringement, or the absence of latent or other defects, accuracy, or the present or absence of errors, whether or not discoverable, all to the greatest extent permissible under applicable law. +c. Affirmer disclaims responsibility for clearing rights of other persons that may apply to the Work or any use thereof, including without limitation any person's Copyright and Related Rights in the Work. Further, Affirmer disclaims responsibility for obtaining any necessary consents, permissions or other rights required for any use of the Work. +d. Affirmer understands and acknowledges that Creative Commons is not a party to this document and has no duty or obligation with respect to this CC0 or use of the Work. + + + +STLPort* +http://stlport.org/ + +License Agreement +Boris Fomitchev grants Licensee a non-exclusive, non-transferable, royalty-free license to use STLport* and its documentation without fee. + +By downloading, using, or copying STLport or any portion thereof, Licensee agrees to abide by the intellectual property laws and all other applicable laws of the United States of America, and to all of the terms and conditions of this Agreement. + +Licensee shall maintain the following copyright and permission notices on STLport sources and its documentation unchanged : +Copyright 1999,2000 Boris Fomitchev + +This material is provided "as is", with absolutely no warranty expressed or implied. Any use is at your own risk. +Permission to use or copy this software for any purpose is hereby granted without fee, provided the above notices are retained on all copies. Permission to modify the code and to distribute modified code is granted, provided the above notices are retained, and a notice that the code was modified is included with the above copyright notice. +The Licensee may distribute binaries compiled with STLport (whether original or modified) without any royalties or restrictions. +The Licensee may distribute original or modified STLport sources, provided that: +• The conditions indicated in the above permission notice are met; +• The following copyright notices are retained when present, and conditions provided in accompanying permission notices are met : +Copyright 1994 Hewlett-Packard Company +Copyright 1996,97 Silicon Graphics Computer Systems, Inc. +Copyright 1997 Moscow Center for SPARC Technology. +Permission to use, copy, modify, distribute and sell this software and its documentation for any purpose is hereby granted without fee, provided that the above copyright notice appear in all copies and that both that copyright notice and this permission notice appear in supporting documentation. Hewlett-Packard Company makes no representations about the suitability of this software for any purpose. It is provided "as is" without express or implied warranty. +Permission to use, copy, modify, distribute and sell this software and its documentation for any purpose is hereby granted without fee, provided that the above copyright notice appear in all copies and that both that copyright notice and this permission notice appear in supporting documentation. Silicon Graphics makes no representations about the suitability of this software for any purpose. It is provided "as is" without express or implied warranty. +Permission to use, copy, modify, distribute and sell this software and its documentation for any purpose is hereby granted without fee, provided that the above copyright notice appear in all copies and that both that copyright notice and this permission notice appear in supporting documentation. Moscow Center for SPARC Technology makes no representations about the suitability of this software for any purpose. It is provided "as is" without express or implied warranty. + + + +TinyXML* 2 +https://github.com/leethomason/tinyxml2 + + +The zlib/libpng License +This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions: +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. + + +OpenSSL* + +http://www.openssl.org/ + + LICENSE ISSUES + ============== + + The OpenSSL* toolkit stays under a dual license, i.e. both the conditions of + the OpenSSL License and the original SSLeay license apply to the toolkit. + See below for the actual license texts. Actually both licenses are BSD-style + Open Source licenses. In case of any license issues related to OpenSSL + please contact openssl-core@openssl.org. + + OpenSSL License + --------------- + +/* ==================================================================== + * Copyright (c) 1998-2011 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. 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. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED 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 OpenSSL PROJECT OR + * ITS 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 product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + + Original SSLeay* License + ----------------------- + +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``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 AUTHOR 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. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +Pintool* +http://software.intel.com/sites/landingpage/pintool/downloads/pin-2.11-49306-msvc10-ia32_intel64-windows.zip +Intel Pre-Release License Agreement for Pre-Release Software + +IMPORTANT - READ BEFORE COPYING, INSTALLING OR USING. + +Do not copy, install, or use the "Materials" provided under this +license agreement ("Agreement"), until you have carefully read the +following terms and conditions. By copying, installing, or otherwise +using the Materials, you agree to be bound by the terms of this +Agreement. If you do not agree to the terms of this Agreement, do not +copy, install, or use the Materials. + +Pre-Release License Agreement for Pre-Release Software + +1. PRE-RELEASE: The Materials are pre-release code, which may not be +fully functional and which Intel may substantially modify in producing +any final version. Intel can provide no assurance that it will ever +produce or make generally available a final version. + +2. LICENSE DEFINITIONS: + +A. "Materials" are defined as the software, documentation, license key +codes and other materials, including any updates and upgrade thereto, +for the applicable pre-release software (which may be found at +http://whatif.intel.com/), that are provided to you under this +Agreement. + +3. LICENSE GRANT: + +A. Subject to all of the terms and conditions of this Agreement, Intel +Corporation ("Intel") grants to you a non-exclusive, non-assignable +copyright license to make only the minimum number of copies of the +Materials reasonably necessary for your internal testing and +development of your products. + +B. Subject to all of the terms and conditions of this Agreement, Intel +grants to you a non-exclusive, non-assignable copyright license to +modify the Materials that are provided in source code (human readable) +form. + +C. If the Materials include the file named “redist.txt”, then subject to +all of the terms and conditions of this Agreement and any specific +restrictions which may appear in the “redist.txt” file, Intel grants to +you a non-exclusive, non-assignable copyright license to redistribute +the files (unmodified or modified by you) listed in the “redist.txt” +file only as part of the application you develop with the Materials. + +4. LICENSE RESTRICTIONS: + +A. You may not reverse-assemble, reverse-compile, or otherwise reverse-engineer any software provided solely in binary form. + +B. You may not distribute any portion of Materials, whether in source or binary form, to any third party, except as specified in this Agreement. + +5. COPYRIGHT: Title to the Materials and all copies thereof remain +with Intel or its suppliers. The Materials are copyrighted and are +protected by United States copyright laws and international treaty +provisions. You will not remove any copyright notice from the +Materials. You agree to prevent any unauthorized copying of the +Materials. Except as expressly provided herein, Intel does not grant +any express or implied right to you under Intel patents, copyrights, +trademarks, or trade secret information. Subject to Intel’s ownership +of the Materials, all right, title and interest in and to your +modifications shall belong to you. + +6. REPLACEMENTS: The Materials are provided "AS IS" without warranty +of any kind. If the media on which the Materials are furnished are +found to be defective in material or workmanship under normal use for +a period of ninety (90) days from the date of receipt, Intel's entire +liability and your exclusive remedy shall be the replacement of the +media. This offer is void if the media defect results from accident, +abuse, or misapplication. + +7. LIMITATION OF LIABILITY: THE ABOVE REPLACEMENT PROVISION IS THE +ONLY WARRANTY OF ANY KIND. INTEL OFFERS NO OTHER WARRANTY EITHER +EXPRESS OR IMPLIED INCLUDING THOSE OF MERCHANTABILITY, NONINFRINGEMENT +OF THIRD- PARTY INTELLECTUAL PROPERTY OR FITNESS FOR A PARTICULAR +PURPOSE. NEITHER INTEL NOR ITS SUPPLIERS SHALL BE LIABLE FOR ANY +DAMAGES WHATSOEVER (INCLUDING, WITHOUT LIMITATION, DAMAGES FOR LOSS OF +BUSINESS PROFITS, BUSINESS INTERRUPTION, LOSS OF BUSINESS INFORMATION, +OR OTHER LOSS) ARISING OUT OF THE USE OF OR INABILITY TO USE THE +SOFTWARE, EVEN IF INTEL HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH +DAMAGES. BECAUSE SOME JURISDICTIONS PROHIBIT THE EXCLUSION OR +LIMITATION OF LIABILITY FOR CONSEQUENTIAL OR INCIDENTAL DAMAGES, THE +ABOVE LIMITATION MAY NOT APPLY TO YOU. + +8. UNAUTHORIZED USE: THE MATERIALS ARE NOT DESIGNED, INTENDED, OR +AUTHORIZED FOR USE IN ANY TYPE OF SYSTEM OR APPLICATION IN WHICH THE +FAILURE OF THE MATERIALS COULD CREATE A SITUATION WHERE PERSONAL +INJURY OR DEATH MAY OCCUR (E.G MEDICAL SYSTEMS, LIFE SUSTAINING OR +LIFE SAVING SYSTEMS). Should the buyer purchase or use the Materials +for any such unintended or unauthorized use, the buyer shall indemnify +and hold Intel and its officers, subsidiaries and affiliates harmless +against all claims, costs, damages, and expenses, and reasonable +attorney fees arising out of, directly or indirectly, any claim of +product liability, personal injury or death associated with such +unintended or unauthorized use, even if such claim alleges that Intel +was negligent regarding the design or manufacture of the part. + +9. USER SUBMISSIONS: You agree that any material, information or other +communication, including all data, images, sounds, text, and other +things embodied therein, you transmit or post to an Intel website or +provide to Intel under this Agreement will be considered +non-confidential ("Communications"). Intel will have no +confidentiality obligations with respect to the Communications. You +agree that Intel and its designees will be free to copy, modify, +create derivative works, publicly display, disclose, distribute, +license and sublicense through multiple tiers of distribution and +licensees, incorporate and otherwise use the Communications, including +derivative works thereto, for any and all commercial or non-commercial +purposes. + +10. TERMINATION OF THIS LICENSE: The term of this Agreement will +commence on the date this Agreement is accepted by You and will +continue until terminated. This Agreement will terminate without +notice on the last day of the pre-release period, which is specified +elsewhere in the Materials, or upon the commercial release of the +Materials. Intel may terminate this Agreement at any time, with or +without cause, with written notice to you. Upon termination, you will +immediately destroy the Materials or return all copies of the +Materials to Intel along with any copies you have made. + +11. U.S. GOVERNMENT RESTRICTED RIGHTS: The Materials are provided with +"RESTRICTED RIGHTS". Use, duplication or disclosure by the Government +is subject to restrictions set forth in FAR52.227-14 and +DFAR252.227-7013 et seq. or its successor. Use of the Materials by +the Government constitutes acknowledgment of Intel's rights in them. + +12. EXPORT RESTRICTED RIGHTS: This software is subject to the U.S. +Export Administration Regulations and other U.S. law, and may not be +exported or re-exported to certain countries (Burma, Cuba, Iran, North +Korea, Sudan, and Syria) or to persons or entities prohibited from +receiving U.S. exports (including Denied Parties, Specially Designated +Nationals, and entities on the Bureau of Export Administration Entity +List or involved with missile technology or nuclear, chemical or +biological weapons). + +13. APPLICABLE LAWS: Any claim arising under or relating to this +Agreement shall be governed by the internal substantive laws of the +State of Delaware or federal courts located in Delaware, without +regard to principles of conflict of laws. You may not export the +Materials in violation of applicable export laws. + +* Other names and brands may be claimed as the property of others + + +DRNG* +https://software.intel.com/en-us/articles/the-drng-library-and-manual + +Intel Sample Source Code License + +This license governs use of the accompanying software. By installing or +copying all or any part of the software components in this package, you +(“you” or “Licensee”) agree to the terms of this agreement. Do +not install or copy the software until you have carefully read and +agreed to the following terms and conditions. If you do not agree to the +terms of this agreement, promptly return the software to Intel +Corporation (“Intel”). + +1. Definitions: + +A. “Materials" are defined as the software (including the +Redistributables and Sample Source as defined herein), documentation, +and other materials, including any updates and upgrade thereto, that are +provided to you under this Agreement. + +B. "Redistributables" are the files listed in the "redist.txt" file that +is included in the Materials or are otherwise clearly identified as +redistributable files by Intel. + +C. “Sample Source” is the source code file(s) that: (i) +demonstrate(s) certain functions for particular purposes; (ii) are +identified as sample source code; and (iii) are provided hereunder in +source code form. + +D. “Intel’s Licensed Patent Claims” means those claims of +Intel’s patents that (a) are infringed by the Sample Source or +Redistributables, alone and not in combination, in their unmodified +form, as furnished by Intel to Licensee and (b) Intel has the right to +license. + +2. License Grant: Subject to all of the terms and conditions of this +Agreement: + +A. Intel grants to you a non-exclusive, non-assignable, copyright +license to use the Material for your internal development purposes only. + +B. Intel grants to you a non-exclusive, non-assignable copyright license +to reproduce the Sample Source, prepare derivative works of the Sample +Source and distribute the Sample Source or any derivative works thereof +that you create, as part of the product or application you develop using +the Materials. + +C. Intel grants to you a non-exclusive, non-assignable copyright license +to distribute the Redistributables, or any portions thereof, as part of +the product or application you develop using the Materials. + +D. Intel grants Licensee a non-transferable, non-exclusive, worldwide, +non-sublicenseable license under Intel’s Licensed Patent Claims to +make, use, sell, and import the Sample Source and the Redistributables. + +3. Conditions and Limitations: + +A. This license does not grant you any rights to use Intel’s name, +logo or trademarks. + +B. Title to the Materials and all copies thereof remain with Intel. The +Materials are copyrighted and are protected by United States copyright +laws. You will not remove any copyright notice from the Materials. You +agree to prevent any unauthorized copying of the Materials. Except as +expressly provided herein, Intel does not grant any express or implied +right to you under Intel patents, copyrights, trademarks, or trade +secret information. + +C. You may NOT: (i) use or copy the Materials except as provided in this +Agreement; (ii) rent or lease the Materials to any third party; (iii) +assign this Agreement or transfer the Materials without the express +written consent of Intel; (iv) modify, adapt, or translate the Materials +in whole or in part except as provided in this Agreement; (v) reverse +engineer, decompile, or disassemble the Materials not provided to you in +source code form; or (vii) distribute, sublicense or transfer the source +code form of any components of the Materials and derivatives thereof to +any third party except as provided in this Agreement. + +D. Platform Limitation - The licenses granted in section 2 extend only +to the software or derivative works that you create that run directly on +a Microsoft Windows operating system product, Microsoft run-time +technology (such as the .NET Framework or Silverlight), or Microsoft +application platform (such as Microsoft Office or Microsoft Dynamics). + +4. No Warranty: + +THE MATERIALS ARE PROVIDED “AS IS”. INTEL DISCLAIMS ALL EXPRESS OR +IMPLIED WARRANTIES WITH RESPECT TO THEM, INCLUDING ANY IMPLIED +WARRANTIES OF MERCHANTABILITY, NON-INFRINGEMENT, AND FITNESS FOR ANY +PARTICULAR PURPOSE. + +5. LIMITATION OF LIABILITY: NEITHER INTEL NOR ITS SUPPLIERS SHALL BE +LIABLE FOR ANY DAMAGES WHATSOEVER (INCLUDING, WITHOUT LIMITATION, +DAMAGES FOR LOSS OF BUSINESS PROFITS, BUSINESS INTERRUPTION, LOSS OF +BUSINESS INFORMATION, OR OTHER LOSS) ARISING OUT OF THE USE OF OR +INABILITY TO USE THE SOFTWARE, EVEN IF INTEL HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. BECAUSE SOME JURISDICTIONS PROHIBIT THE +EXCLUSION OR LIMITATION OF LIABILITY FOR CONSEQUENTIAL OR INCIDENTAL +DAMAGES, THE ABOVE LIMITATION MAY NOT APPLY TO YOU. + +6. USER SUBMISSIONS: You agree that any material, information or other +communication, including all data, images, sounds, text, and other +things embodied therein, you transmit or post to an Intel website or +provide to Intel under this Agreement will be considered +non-confidential ("Communications"). Intel will have no confidentiality +obligations with respect to the Communications. You agree that Intel and +its designees will be free to copy, modify, create derivative works, +publicly display, disclose, distribute, license and sublicense through +multiple tiers of distribution and licensees, incorporate and otherwise +use the Communications, including derivative works thereto, for any and +all commercial or non-commercial purposes + +7. TERMINATION OF THIS LICENSE: This Agreement becomes effective on the +date you accept this Agreement and will continue until terminated as +provided for in this Agreement. Intel may terminate this license at any +time if you are in breach of any of its terms and conditions. Upon +termination, you will immediately return to Intel or destroy the +Materials and all copies thereof. + +8. U.S. GOVERNMENT RESTRICTED RIGHTS: The Materials are provided with +"RESTRICTED RIGHTS". Use, duplication or disclosure by the Government is +subject to restrictions set forth in FAR52.227-14 and DFAR252.227-7013 +et seq. or its successor. Use of the Materials by the Government +constitutes acknowledgment of Intel's rights in them. + +9. APPLICABLE LAWS: Any claim arising under or relating to this +Agreement shall be governed by the internal substantive laws of the +State of Delaware, without regard to principles of conflict of laws. You +may not export the Materials in violation of applicable export laws. + + + + + + + + + + + +LLVM* + +http://llvm.org/ + +============================================================================== +LLVM Release License +============================================================================== +University of Illinois/NCSA +Open Source License + +Copyright (c) 2003-2016 University of Illinois at Urbana-Champaign. +All rights reserved. + +Developed by: + + LLVM Team + + University of Illinois at Urbana-Champaign + + http://llvm.org + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal with +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies +of the Software, and to permit persons to whom the Software is furnished to do +so, subject to the following conditions: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimers. + + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimers in the + documentation and/or other materials provided with the distribution. + + * Neither the names of the LLVM Team, University of Illinois at + Urbana-Champaign, nor the names of its contributors may be used to + endorse or promote products derived from this Software without specific + prior written permission. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE +SOFTWARE. + +============================================================================== +Copyrights and Licenses for Third Party Software Distributed with LLVM: +============================================================================== +The LLVM software contains code written by third parties. Such software will +have its own individual LICENSE.TXT file in the directory in which it appears. +This file will describe the copyrights, license, and restrictions which apply +to that code. + +The disclaimer of warranty in the University of Illinois Open Source License +applies to all code in the LLVM Distribution, and nothing in any of the +other licenses gives permission to use the names of the LLVM Team or the +University of Illinois to endorse or promote products derived from this +Software. + +The following pieces of software have additional or alternate copyrights, +licenses, and/or restrictions: + +Program Directory +------- --------- +Autoconf llvm/autoconf + llvm/projects/ModuleMaker/autoconf +Google Test llvm/utils/unittest/googletest +OpenBSD regex llvm/lib/Support/{reg*, COPYRIGHT.regex} +pyyaml tests llvm/test/YAMLParser/{*.data, LICENSE.TXT} +ARM contributions llvm/lib/Target/ARM/LICENSE.TXT +md5 contributions llvm/lib/Support/MD5.cpp llvm/include/llvm/Support/MD5.h + + + + + + +ITTNotify* + +Dual BSD/GPLv2 license + + GPL LICENSE SUMMARY + + Copyright (c) 2005-2014 Intel Corporation. All rights reserved. + + This program is free software; you can redistribute it and/or modify + it under the terms of version 2 of the GNU General Public License as + published by the Free Software Foundation. + + This program is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + The full GNU General Public License is included in this distribution + in the file called LICENSE.GPL. + + Contact Information: + http://software.intel.com/en-us/articles/intel-vtune-amplifier-xe/ + + BSD LICENSE + + Copyright (c) 2005-2014 Intel Corporation. All rights reserved. + 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. + + + + +WiX Toolset* + +http://wixtoolset.org/ + +WiX Toolset License +The WiX toolset is released under the Microsoft Reciprocal License (MS-RL). A reciprocal license is used to ensure that others who build on the effort of the WiX community give back to the WiX community. Specifically the license requires that fixes and improvements to the WiX toolset must be published using the same license. +Sometimes the reciprocal license is incorrectly interpreted to also apply to bundles, packages, and custom actions built using the WiX toolset. The Outercurve Foundation has previously provided this statement below to clarify which now the .NET Foundation reaffirms: +The WiX toolset (WiX) is licensed under the Microsoft Reciprocal License (MS-RL). The MS-RL governs the distribution of the software licensed under it, as well as derivative works, and incorporates the definition of a derivative work provided in U.S. copyright law. OuterCurve Foundation (and the .NET Foundation) does not view the installer packages generated by WiX as falling within the definition of a derivative work, merely because they are produced using WiX. Thus, the installer packages generated by WiX will normally fall outside the scope of the MS-RL, and any of your source code, binaries, libraries, routines or other software components that are incorporated in installer packages generated by WiX can be governed by other licensing terms. +The full text of the MS-RL license is reproduced below. It can also be found in the LICENSE.TXT file included with the source code. +Microsoft Reciprocal License (MS-RL) +This license governs use of the accompanying software. If you use the software, you accept this license. If you do not accept the license, do not use the software. +1. Definitions +The terms "reproduce," "reproduction," "derivative works," and "distribution" have the same meaning here as under U.S. copyright law. +A "contribution" is the original software, or any additions or changes to the software. +A "contributor" is any person that distributes its contribution under this license. +"Licensed patents" are a contributor's patent claims that read directly on its contribution. +2. Grant of Rights +(A) Copyright Grant- Subject to the terms of this license, including the license conditions and limitations in section 3, each contributor grants you a non-exclusive, worldwide, royalty-free copyright license to reproduce its contribution, prepare derivative works of its contribution, and distribute its contribution or any derivative works that you create. +(B) Patent Grant- Subject to the terms of this license, including the license conditions and limitations in section 3, each contributor grants you a non-exclusive, worldwide, royalty-free license under its licensed patents to make, have made, use, sell, offer for sale, import, and/or otherwise dispose of its contribution in the software or derivative works of the contribution in the software. +3. Conditions and Limitations +(A) Reciprocal Grants- For any file you distribute that contains code from the software (in source code or binary format), you must provide recipients the source code to that file along with a copy of this license, which license will govern that file. You may license other files that are entirely your own work and do not contain code from the software under any terms you choose. +(B) No Trademark License- This license does not grant you rights to use any contributors' name, logo, or trademarks. +(C) If you bring a patent claim against any contributor over patents that you claim are infringed by the software, your patent license from such contributor to the software ends automatically. +(D) If you distribute any portion of the software, you must retain all copyright, patent, trademark, and attribution notices that are present in the software. +(E) If you distribute any portion of the software in source code form, you may do so only under this license by including a complete copy of this license with your distribution. If you distribute any portion of the software in compiled or object code form, you may only do so under a license that complies with this license. +(F) The software is licensed "as-is." You bear the risk of using it. The contributors give no express warranties, guarantees or conditions. You may have additional consumer rights under your local laws which this license cannot change. To the extent permitted under your local laws, the contributors exclude the implied warranties of merchantability, fitness for a particular purpose and non-infringement. + + + +Microsoft/Windows-universal-samples +https://github.com/Microsoft/Windows-universal-samples +Microsoft/Windows-universal-samples is licensed under the MIT License +https://opensource.org/licenses/MIT +A short and simple permissive license with conditions only requiring preservation of copyright and license notices. Licensed works, modifications, and larger works may be distributed under different terms and without source code. + +The MIT License (MIT) + +Copyright (c) Microsoft Corporation + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + +ChakraCore + +https://github.com/Microsoft/ChakraCore + +The MIT License (MIT) + +Copyright (c) Microsoft Corporation +All rights reserved. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + +FsLexYacc + +https://fsprojects.github.io/FsLexYacc/ + +Apache License + +Version 2.0, January 2004 +http://www.apache.org/licenses/ + +TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + +1. Definitions. + +"License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. + +"Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. + +"Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. + +"You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. + +"Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. + +"Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. + +"Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). + +"Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. + +"Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." + +"Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. + +2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. + +3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. + +4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: + + 1. You must give any other recipients of the Work or Derivative Works a copy of this License; and + + 2. You must cause any modified files to carry prominent notices stating that You changed the files; and + + 3. You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and + + 4. If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. + +You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. + +5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. + +6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. + +7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. + +8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. + +9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. + +See FAQ for answers to frequently asked questions about this license. + + +The "inih" library is distributed under the New BSD license: + +Copyright (c) 2009, Ben Hoyt +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 Ben Hoyt 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 BEN HOYT ''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 BEN HOYT 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. + + + +Legal Information + +No license (express or implied, by estoppel or otherwise) to any intellectual property rights is granted by this document. +Intel disclaims all express and implied warranties, including without limitation, the +implied warranties of merchantability, fitness for a particular purpose, and noninfringement, as well as any warranty arising from course of performance, course of dealing, or usage in trade. +This document contains information on products, services and/or processes in +development. All information provided here is subject to change without notice. +Contact your Intel representative to obtain the latest forecast, schedule, specifications and roadmaps. +The products and services described may contain defects or errors known as errata +which may cause deviations from published specifications. Current characterized +errata are available on request. +Intel technologies features and benefits depend on system configuration and may +require enabled hardware, software or service activation. Learn more at Intel.com, or +from the OEM or retailer. +Copies of documents which have an order number and are referenced in this document may be obtained by calling 1-800-548-4725 or by visiting www.intel.com/design/literature.htm. +Intel, the Intel logo, Xeon, and Xeon Phi are trademarks of Intel Corporation in the +U.S. and/or other countries. + +Optimization Notice +Intel's compilers may or may not optimize to the same degree for non-Intel microprocessors for optimizations that are not unique to Intel microprocessors. These optimizations include SSE2, SSE3, and SSSE3 instruction sets and other optimizations. Intel does not guarantee the availability, functionality, or effectiveness of any optimization on microprocessors not manufactured by Intel. Microprocessor-dependent optimizations in this product are intended for use with Intel microprocessors. Certain optimizations not specific to Intel microarchitecture are reserved for Intel microprocessors. Please refer to the applicable product User and Reference Guides for more information regarding the specific instruction sets covered by this notice. + +Notice revision #20110804 +* Other names and brands may be claimed as the property of others. + Copyright 2014-2019 Intel Corporation. +This software and the related documents are Intel copyrighted materials, and your use of them is governed by the express license under which they were provided to you (License). Unless the License provides otherwise, you may not use, modify, copy, publish, distribute, disclose or transmit this software or the related documents without Intel's prior written permission. This software and the related documents are provided as is, with no express or implied warranties, other than those that are expressly stated in the License. + + diff --git a/tools/PCKRetrievalTool/installer/deb/sgx-pck-id-retrieval-tool/sgx-pck-id-retrieval-tool-1.0/debian/control b/tools/PCKRetrievalTool/installer/deb/sgx-pck-id-retrieval-tool/sgx-pck-id-retrieval-tool-1.0/debian/control index 39395d44..b3e2fe86 100644 --- a/tools/PCKRetrievalTool/installer/deb/sgx-pck-id-retrieval-tool/sgx-pck-id-retrieval-tool-1.0/debian/control +++ b/tools/PCKRetrievalTool/installer/deb/sgx-pck-id-retrieval-tool/sgx-pck-id-retrieval-tool-1.0/debian/control @@ -9,6 +9,6 @@ Homepage: https://github.com/intel/SGXDataCenterAttestationPrimitives Package: sgx-pck-id-retrieval-tool Architecture: amd64 Depends: ${shlibs:Depends}, ${misc:Depends} -Recommends: libsgx-urts (>= 2.13), libsgx-ae-pce (>= @dep_version@),libsgx-ae-id-enclave (>=@dep_version@), libsgx-ra-uefi (>= @dep_version@) +Recommends: libsgx-urts (>= 2.17), libsgx-ae-pce (>= @dep_version@),libsgx-ae-id-enclave (>=@dep_version@), libsgx-ra-uefi (>= @dep_version@) Description: Intel(R) Software Guard Extensions: this tool is used to collect the platform information to retrieve the PCK certs from PCS(Provisioning Certification Server) diff --git a/tools/PCKRetrievalTool/installer/rpm/sgx-pck-id-retrieval-tool/sgx-pck-id-retrieval-tool.spec b/tools/PCKRetrievalTool/installer/rpm/sgx-pck-id-retrieval-tool/sgx-pck-id-retrieval-tool.spec index a5bf45d8..53bf720a 100644 --- a/tools/PCKRetrievalTool/installer/rpm/sgx-pck-id-retrieval-tool/sgx-pck-id-retrieval-tool.spec +++ b/tools/PCKRetrievalTool/installer/rpm/sgx-pck-id-retrieval-tool/sgx-pck-id-retrieval-tool.spec @@ -37,7 +37,7 @@ Version: @version@ Release: 1%{?dist} Summary: Intel(R) Software Guard Extensions:this tool is used to collect the platform information to retrieve the PCK certs from PCS(Provisioning Certification Server) Group: Development/System -Recommends: libsgx-urts >= 2.13, libsgx-ae-pce >= %{version}-%{release}, libsgx-ae-id-enclave >= %{version}-%{release},libsgx-ra-uefi >= %{version}-%{release} +Recommends: libsgx-urts >= 2.17, libsgx-ae-pce >= %{version}-%{release}, libsgx-ae-id-enclave >= %{version}-%{release},libsgx-ra-uefi >= %{version}-%{release} License: BSD License URL: https://github.com/intel/SGXDataCenterAttestationPrimitives diff --git a/tools/PCKRetrievalTool/network_setting.conf b/tools/PCKRetrievalTool/network_setting.conf index afa2f732..cb3e52b7 100644 --- a/tools/PCKRetrievalTool/network_setting.conf +++ b/tools/PCKRetrievalTool/network_setting.conf @@ -1,9 +1,9 @@ # ############################################################# # PCCS server address -# support V2 version PCCS -#PCCS_URL=https://localhost:8081/sgx/certification/v2/platforms # support V3 version PCCS #PCCS_URL=https://localhost:8081/sgx/certification/v3/platforms +# support V4 version PCCS +#PCCS_URL=https://localhost:8081/sgx/certification/v4/platforms # To accept insecure HTTPS cert, set this option to FALSE #USE_SECURE_CERT=TRUE ############################################################### diff --git a/tools/PccsAdminTool/License.txt b/tools/PccsAdminTool/License.txt new file mode 100644 index 00000000..49fbc89b --- /dev/null +++ b/tools/PccsAdminTool/License.txt @@ -0,0 +1,77 @@ +BSD License + +Copyright (C) 2011-2021 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. + + +============================================================== + +pce.signed.dll, qve.signed.dll and qe3.signed.dll, libsgx_pce.signed.so, +libsgx_qve.signed.so and libsgx_qe3.signed.so are licensed as Intel +redistributable binary firmware and other blobs. + + +Copyright (c) Intel Corporation. + +Redistribution. Redistribution and use in binary form, without +modification, are permitted provided that the following conditions are +met: + +* Redistributions must reproduce the above copyright notice 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 suppliers + may be used to endorse or promote products derived from this software + without specific prior written permission. +* No reverse engineering, decompilation, or disassembly of this software + is permitted. + +Limited patent license. Intel Corporation grants a world-wide, +royalty-free, non-exclusive license under patents it now or hereafter +owns or controls to make, have made, use, import, offer to sell and +sell ("Utilize") this software, but solely to the extent that any +such patent is necessary to Utilize the software alone, or in +combination with an operating system licensed under an approved Open +Source license as listed by the Open Source Initiative at +http://opensource.org/licenses. The patent license shall not apply to +any other combinations which include this software. No hardware per +se is licensed hereunder. + +DISCLAIMER. 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. + diff --git a/tools/PccsAdminTool/lib/intelsgx/pcs.py b/tools/PccsAdminTool/lib/intelsgx/pcs.py index ef7dbf3c..cb9e65f9 100644 --- a/tools/PccsAdminTool/lib/intelsgx/pcs.py +++ b/tools/PccsAdminTool/lib/intelsgx/pcs.py @@ -40,6 +40,8 @@ def api_version(self): def _geturl(self, func, type='sgx'): if type == 'sgx': return urllib.parse.urljoin(self.BaseUrl, func) + elif type == 'tdx': + return urllib.parse.urljoin(self.BaseUrl.replace('/sgx/', '/tdx/'), func) else: raise Exception('Internal error!') @@ -596,7 +598,10 @@ def get_tcb_info(self, fmspc, type, dec=None): def get_enclave_identity(self, name, dec=None): self.clear_errors() - url= self._geturl(name + '/identity', 'sgx') + if name == 'tdqe': + url= self._geturl('qe/identity', 'tdx') + else: + url= self._geturl(name + '/identity', 'sgx') response= self._get_request(url, False) if response.status_code != 200: diff --git a/tools/PccsAdminTool/pccsadmin.py b/tools/PccsAdminTool/pccsadmin.py index 2bcfee0e..d31b5afc 100755 --- a/tools/PccsAdminTool/pccsadmin.py +++ b/tools/PccsAdminTool/pccsadmin.py @@ -21,7 +21,7 @@ def main(): # subparser for get parser_get = subparsers.add_parser('get', formatter_class=argparse.RawTextHelpFormatter) # add optional arguments for get - parser_get.add_argument("-u", "--url", help="The URL of the PCCS's GET platforms API; default: https://localhost:8081/sgx/certification/v3/platforms") + parser_get.add_argument("-u", "--url", help="The URL of the PCCS's GET platforms API; default: https://localhost:8081/sgx/certification/v4/platforms") parser_get.add_argument("-o", "--output_file", help="The output file name for platform list; default: platform_list.json") parser_get.add_argument("-s", "--source", help= "reg - Get platforms from registration table.(default)\n" @@ -32,14 +32,14 @@ def main(): # subparser for put parser_put = subparsers.add_parser('put') # add optional arguments for put - parser_put.add_argument("-u", "--url", help="The URL of the PCCS's PUT collateral API; default: https://localhost:8081/sgx/certification/v3/platformcollateral") + parser_put.add_argument("-u", "--url", help="The URL of the PCCS's PUT collateral API; default: https://localhost:8081/sgx/certification/v4/platformcollateral") parser_put.add_argument("-i", "--input_file", help="The input file name for platform collaterals; default: platform_collaterals.json") parser_put.set_defaults(func=pccs_put) # subparser for fetch parser_fetch = subparsers.add_parser('fetch') # add optional arguments for fetch - parser_fetch.add_argument("-u", "--url", help="The URL of the Intel PCS service; default: https://api.trustedservices.intel.com/sgx/certification/v3/") + parser_fetch.add_argument("-u", "--url", help="The URL of the Intel PCS service; default: https://api.trustedservices.intel.com/sgx/certification/v4/") parser_fetch.add_argument("-i", "--input_file", help="The input file name for platform list; default: platform_list.json") parser_fetch.add_argument("-o", "--output_file", help="The output file name for platform collaterals; default: platform_collaterals.json") parser_fetch.set_defaults(func=pcs_fetch) @@ -54,7 +54,7 @@ def main(): # subparser for refresh parser_refresh = subparsers.add_parser('refresh') # add optional arguments for refresh - parser_refresh.add_argument("-u", "--url", help="The URL of the PCCS's refresh API; default: https://localhost:8081/sgx/certification/v3/refresh") + parser_refresh.add_argument("-u", "--url", help="The URL of the PCCS's refresh API; default: https://localhost:8081/sgx/certification/v4/refresh") parser_refresh.add_argument("-f", "--fmspc", help="Only refresh certificates for specified FMSPCs. Format: [FMSPC1, FMSPC2, ..., FMSPCn]") parser_refresh.set_defaults(func=pccs_refresh) @@ -80,7 +80,7 @@ def is_file_writable(filename): def pccs_get(args): try : - url = "https://localhost:8081/sgx/certification/v3/platforms" + url = "https://localhost:8081/sgx/certification/v4/platforms" if args.url: url = args.url output_file = "platform_list.json" @@ -115,7 +115,7 @@ def pccs_get(args): def pccs_put(args): try : - url = "https://localhost:8081/sgx/certification/v3/platformcollateral" + url = "https://localhost:8081/sgx/certification/v4/platformcollateral" if args.url: url = args.url input_file = "platform_collaterals.json" @@ -148,7 +148,7 @@ def pccs_put(args): print(e) def get_api_version_from_url(url): - version = 3 + version = 4 regex = re.compile('/v[1-9][0-9]*/') match = regex.search(url) if match is not None: @@ -159,8 +159,8 @@ def get_api_version_from_url(url): def pcs_fetch(args): try : - url = 'https://api.trustedservices.intel.com/sgx/certification/v3/' - ApiVersion = 3 + url = 'https://api.trustedservices.intel.com/sgx/certification/v4/' + ApiVersion = 4 if args.url: url = args.url @@ -192,11 +192,13 @@ def pcs_fetch(args): output_json={} output_json["platforms"] = plaformlist output_json["collaterals"] = { + "version" : ApiVersion, "pck_certs" : [], "tcbinfos" : [], "pckcacrl" : { }, "qeidentity" : "", + "tdqeidentity" : "", "qveidentity" : "", "certificates" : { PCS.HDR_PCK_Certificate_Issuer_Chain: {}, @@ -235,7 +237,7 @@ def pcs_fetch(args): # set pck-certificate-issuer-chain ca = sgxext.get_ca() if ca is None: - print("Wrong certificate format!") + print("Wrong PCK certificate format!") return pckchain = output_json["collaterals"]["certificates"][PCS.HDR_PCK_Certificate_Issuer_Chain] @@ -277,10 +279,18 @@ def pcs_fetch(args): sgx_tcbinfo = pcsclient.get_tcb_info(fmspc, 'sgx', 'ascii') tcbinfoJson = {"fmspc" : fmspc} if sgx_tcbinfo != None: - tcbinfoJson['tcbinfo'] = json.loads(sgx_tcbinfo[0]) + if ApiVersion >= 4: + tcbinfoJson['sgx_tcbinfo'] = json.loads(sgx_tcbinfo[0]) + else: + tcbinfoJson['tcbinfo'] = json.loads(sgx_tcbinfo[0]) else: print("Failed to get SGXtcbinfo for FMSPC:%s" %(fmspc)) return + # TDX tcbinfo is optional + if ApiVersion >= 4: + tdx_tcbinfo = pcsclient.get_tcb_info(fmspc, 'tdx', 'ascii') + if tdx_tcbinfo != None: + tcbinfoJson['tdx_tcbinfo'] = json.loads(tdx_tcbinfo[0]) output_json["collaterals"]["tcbinfos"].append(tcbinfoJson) if output_json["collaterals"]["certificates"][PCS.HDR_TCB_INFO_ISSUER_CHAIN] == '': output_json["collaterals"]["certificates"][PCS.HDR_TCB_INFO_ISSUER_CHAIN] = sgx_tcbinfo[1] @@ -307,6 +317,14 @@ def pcs_fetch(args): output_json["collaterals"]["qeidentity"] = qe_identity[0] output_json["collaterals"]["certificates"][PCS.HDR_Enclave_Identity_Issuer_Chain] = qe_identity[1] + # output.collaterals.tdqeidentity (Api Version >= 4) + if ApiVersion >= 4: + tdqe_identity = pcsclient.get_enclave_identity('tdqe', 'ascii') + if tdqe_identity == None: + print("Failed to get TDQE identity") + return + output_json["collaterals"]["tdqeidentity"] = tdqe_identity[0] + # output.collaterals.qveidentity qve_identity = pcsclient.get_enclave_identity('qve', 'ascii') if qve_identity == None: @@ -363,7 +381,7 @@ def pcs_collect(args): def pccs_refresh(args): try : - url = "https://localhost:8081/sgx/certification/v3/refresh" + url = "https://localhost:8081/sgx/certification/v4/refresh" if args.url: url = args.url fmspc = None diff --git a/tools/SGXPlatformRegistration/inf/inf_build.cmd b/tools/SGXPlatformRegistration/inf/inf_build.cmd index 9a448d07..bcb0abfe 100644 --- a/tools/SGXPlatformRegistration/inf/inf_build.cmd +++ b/tools/SGXPlatformRegistration/inf/inf_build.cmd @@ -62,7 +62,7 @@ IF /I "%ERRORLEVEL%" NEQ "0" ( ) echo: echo ========= Creating The Catalog File ============== -%INF2CAT% /driver:%DST_DIR% /os:10_x64 /VERBOSE +%INF2CAT% /driver:%DST_DIR% /os:10_x64 /uselocaltime /VERBOSE IF /I "%ERRORLEVEL%" NEQ "0" ( goto exit )