├── .clang-dirs ├── .clang-format ├── .gitignore ├── .gitmodules ├── CMakeLists.txt ├── CONTRIBUTING.md ├── LICENSE ├── README.md ├── SECURITY.md ├── THIRD-PARTY-NOTICES ├── build.sh ├── cmake ├── FindGRPC.cmake ├── FindProtobuf.cmake └── FindSGX.cmake ├── deployment ├── .gitignore ├── bin │ ├── start_aesm.sh │ └── start_service.sh ├── certs │ └── .gitignore ├── conf │ └── kubetee.json ├── create_image.sh ├── dockerfile │ └── Dockerfile └── run_image.sh ├── dockerbuild.sh ├── docs └── tff.jpg ├── enclave_samples ├── CMakeLists.txt ├── protobuf_functions │ ├── CMakeLists.txt │ ├── app │ │ ├── app.cpp │ │ └── app.h │ └── enclave │ │ ├── enclave.config.xml │ │ ├── enclave.cpp │ │ ├── enclave.edl │ │ ├── enclave.h │ │ ├── enclave.lds │ │ └── enclave_private.pem └── remote_attestation │ ├── CMakeLists.txt │ ├── app │ ├── app.cpp │ └── app.h │ └── enclave │ ├── enclave.config.xml │ ├── enclave.cpp │ ├── enclave.edl │ ├── enclave.h │ ├── enclave.lds │ └── enclave_private.pem ├── enclave_service ├── CMakeLists.txt ├── client │ └── untrusted_enclave_service_client_main.cpp ├── proto │ └── enclave_service.proto ├── server │ └── untrusted_enclave_service_server_main.cpp ├── trusted │ ├── enclave.config.xml │ ├── enclave_private.pem │ ├── enclave_service.edl │ ├── enclave_service.lds │ └── trusted_enclave_service.cpp └── untrusted │ ├── untrusted_enclave_service_client.cpp │ ├── untrusted_enclave_service_client.h │ ├── untrusted_enclave_service_server.cpp │ └── untrusted_enclave_service_server.h ├── proto └── kubetee.proto ├── sdk ├── CMakeLists.txt ├── common │ ├── aes.cpp │ ├── bytes.cpp │ ├── challenger.cpp │ ├── envelope.cpp │ └── rsa.cpp ├── edl │ ├── .gitignore │ ├── common_utils.edl │ ├── kubetee.edl │ └── remote_attestation.edl ├── include │ └── tee │ │ ├── common │ │ ├── aes.h │ │ ├── bytes.h │ │ ├── challenger.h │ │ ├── envelope.h │ │ ├── error.h │ │ ├── log.h │ │ ├── protobuf.h │ │ ├── rsa.h │ │ ├── scope.h │ │ ├── table.h │ │ └── type.h │ │ ├── trusted │ │ ├── trusted_instance.h │ │ ├── trusted_pbcall.h │ │ ├── trusted_pbfunctions.h │ │ └── utils │ │ │ └── trusted_seal.h │ │ └── untrusted │ │ ├── enclave │ │ └── untrusted_enclave.h │ │ ├── ra │ │ ├── untrusted_challenger.h │ │ └── untrusted_ias.h │ │ ├── untrusted_config.h │ │ ├── untrusted_pbcall.h │ │ └── utils │ │ ├── untrusted_fs.h │ │ └── untrusted_json.h ├── trusted │ ├── CMakeLists.txt │ ├── ra │ │ └── trusted_ra.cpp │ ├── trusted_instance.cpp │ ├── trusted_pbcall.cpp │ ├── trusted_pbfunctions.cpp │ └── utils │ │ ├── trusted_crypto.cpp │ │ ├── trusted_log.cpp │ │ └── trusted_seal.cpp └── untrusted │ ├── CMakeLists.txt │ ├── challenger │ ├── CMakeLists.txt │ ├── untrusted_challenger.cpp │ └── untrusted_challenger_config.h │ ├── enclave │ └── untrusted_enclave.cpp │ ├── ra │ └── untrusted_ias.cpp │ ├── untrusted_pbcall.cpp │ └── utils │ ├── untrusted_fs.cpp │ ├── untrusted_json.cpp │ ├── untrusted_json_internal.h │ └── untrusted_log.cpp └── tools ├── clang_format.sh ├── cpplint.py ├── cpplint_all.sh ├── dockerenv.sh ├── dump_enclave_info.sh └── gencert /.clang-dirs: -------------------------------------------------------------------------------- 1 | sdk 2 | enclave_samples 3 | enclave_service 4 | tests 5 | -------------------------------------------------------------------------------- /.clang-format: -------------------------------------------------------------------------------- 1 | Language: Cpp 2 | BasedOnStyle: Google 3 | 4 | PointerAlignment: Left 5 | DerivePointerAlignment: false 6 | 7 | AllowShortFunctionsOnASingleLine: Empty 8 | 9 | #--- 10 | #Language: Cpp 11 | ## BasedOnStyle: Google 12 | #AccessModifierOffset: -1 13 | #AlignAfterOpenBracket: Align 14 | #AlignConsecutiveAssignments: false 15 | #AlignConsecutiveDeclarations: false 16 | #AlignEscapedNewlines: Left 17 | #AlignOperands: true 18 | #AlignTrailingComments: true 19 | #AllowAllParametersOfDeclarationOnNextLine: true 20 | #AllowShortBlocksOnASingleLine: false 21 | #AllowShortCaseLabelsOnASingleLine: false 22 | #AllowShortFunctionsOnASingleLine: All 23 | #AllowShortIfStatementsOnASingleLine: true 24 | #AllowShortLoopsOnASingleLine: true 25 | #AlwaysBreakAfterDefinitionReturnType: None 26 | #AlwaysBreakAfterReturnType: None 27 | #AlwaysBreakBeforeMultilineStrings: true 28 | #AlwaysBreakTemplateDeclarations: Yes 29 | #BinPackArguments: true 30 | #BinPackParameters: true 31 | #BraceWrapping: 32 | # AfterClass: false 33 | # AfterControlStatement: false 34 | # AfterEnum: false 35 | # AfterFunction: false 36 | # AfterNamespace: false 37 | # AfterObjCDeclaration: false 38 | # AfterStruct: false 39 | # AfterUnion: false 40 | # AfterExternBlock: false 41 | # BeforeCatch: false 42 | # BeforeElse: false 43 | # IndentBraces: false 44 | # SplitEmptyFunction: true 45 | # SplitEmptyRecord: true 46 | # SplitEmptyNamespace: true 47 | #BreakBeforeBinaryOperators: None 48 | #BreakBeforeBraces: Attach 49 | #BreakBeforeInheritanceComma: false 50 | #BreakInheritanceList: BeforeColon 51 | #BreakBeforeTernaryOperators: true 52 | #BreakConstructorInitializersBeforeComma: false 53 | #BreakConstructorInitializers: BeforeColon 54 | #BreakAfterJavaFieldAnnotations: false 55 | #BreakStringLiterals: true 56 | #ColumnLimit: 80 57 | #CommentPragmas: '^ IWYU pragma:' 58 | #CompactNamespaces: false 59 | #ConstructorInitializerAllOnOneLineOrOnePerLine: true 60 | #ConstructorInitializerIndentWidth: 4 61 | #ContinuationIndentWidth: 4 62 | #Cpp11BracedListStyle: true 63 | #DerivePointerAlignment: true 64 | #DisableFormat: false 65 | #ExperimentalAutoDetectBinPacking: false 66 | #FixNamespaceComments: true 67 | #ForEachMacros: 68 | # - foreach 69 | # - Q_FOREACH 70 | # - BOOST_FOREACH 71 | #IncludeBlocks: Preserve 72 | #IncludeCategories: 73 | # - Regex: '^' 74 | # Priority: 2 75 | # - Regex: '^<.*\.h>' 76 | # Priority: 1 77 | # - Regex: '^<.*' 78 | # Priority: 2 79 | # - Regex: '.*' 80 | # Priority: 3 81 | #IncludeIsMainRegex: '([-_](test|unittest))?$' 82 | #IndentCaseLabels: true 83 | #IndentPPDirectives: None 84 | #IndentWidth: 2 85 | #IndentWrappedFunctionNames: false 86 | #JavaScriptQuotes: Leave 87 | #JavaScriptWrapImports: true 88 | #KeepEmptyLinesAtTheStartOfBlocks: false 89 | #MacroBlockBegin: '' 90 | #MacroBlockEnd: '' 91 | #MaxEmptyLinesToKeep: 1 92 | #NamespaceIndentation: None 93 | #ObjCBinPackProtocolList: Never 94 | #ObjCBlockIndentWidth: 2 95 | #ObjCSpaceAfterProperty: false 96 | #ObjCSpaceBeforeProtocolList: true 97 | #PenaltyBreakAssignment: 2 98 | #PenaltyBreakBeforeFirstCallParameter: 1 99 | #PenaltyBreakComment: 300 100 | #PenaltyBreakFirstLessLess: 120 101 | #PenaltyBreakString: 1000 102 | #PenaltyBreakTemplateDeclaration: 10 103 | #PenaltyExcessCharacter: 1000000 104 | #PenaltyReturnTypeOnItsOwnLine: 200 105 | #PointerAlignment: Left 106 | #RawStringFormats: 107 | # - Language: Cpp 108 | # Delimiters: 109 | # - cc 110 | # - CC 111 | # - cpp 112 | # - Cpp 113 | # - CPP 114 | # - 'c++' 115 | # - 'C++' 116 | # CanonicalDelimiter: '' 117 | # BasedOnStyle: google 118 | # - Language: TextProto 119 | # Delimiters: 120 | # - pb 121 | # - PB 122 | # - proto 123 | # - PROTO 124 | # EnclosingFunctions: 125 | # - EqualsProto 126 | # - EquivToProto 127 | # - PARSE_PARTIAL_TEXT_PROTO 128 | # - PARSE_TEST_PROTO 129 | # - PARSE_TEXT_PROTO 130 | # - ParseTextOrDie 131 | # - ParseTextProtoOrDie 132 | # CanonicalDelimiter: '' 133 | # BasedOnStyle: google 134 | #ReflowComments: true 135 | #SortIncludes: true 136 | #SortUsingDeclarations: true 137 | #SpaceAfterCStyleCast: false 138 | #SpaceAfterTemplateKeyword: true 139 | #SpaceBeforeAssignmentOperators: true 140 | #SpaceBeforeCpp11BracedList: false 141 | #SpaceBeforeCtorInitializerColon: true 142 | #SpaceBeforeInheritanceColon: true 143 | #SpaceBeforeParens: ControlStatements 144 | #SpaceBeforeRangeBasedForLoopColon: true 145 | #SpaceInEmptyParentheses: false 146 | #SpacesBeforeTrailingComments: 2 147 | #SpacesInAngles: false 148 | #SpacesInContainerLiterals: true 149 | #SpacesInCStyleCastParentheses: false 150 | #SpacesInParentheses: false 151 | #SpacesInSquareBrackets: false 152 | #Standard: Auto 153 | #StatementMacros: 154 | # - Q_UNUSED 155 | # - QT_REQUIRE_VERSION 156 | #TabWidth: 8 157 | #UseTab: Never 158 | #... 159 | # 160 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | build 2 | release 3 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "third_party/protobuf-cpp"] 2 | path = third_party/protobuf-cpp 3 | url = https://github.com/SOFAEnclave/protobuf-sgx.git 4 | branch = v3.7.1 5 | [submodule "third_party/cppcodec"] 6 | path = third_party/cppcodec 7 | url = https://github.com/tplgy/cppcodec.git 8 | [submodule "third_party/rapidjson"] 9 | path = third_party/rapidjson 10 | url = https://github.com/Tencent/rapidjson.git 11 | -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.5) 2 | project(kubetee-tff) 3 | 4 | list(APPEND CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake) 5 | find_package(SGX REQUIRED) 6 | 7 | set(LIBRARY_OUTPUT_PATH ${CMAKE_BINARY_DIR}/out) 8 | set(EXECUTABLE_OUTPUT_PATH ${CMAKE_BINARY_DIR}/out) 9 | set(TEE_TOP_DIR ${CMAKE_SOURCE_DIR}) 10 | 11 | set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -pthread") 12 | if(SGX_HW STREQUAL "OFF") 13 | set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DSGX_SIM_MODE=true") 14 | else() 15 | set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DSGX_SIM_MODE=false") 16 | endif() 17 | if(SGX_MODE STREQUAL "Debug") 18 | set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O0 -g2 -DDEBUG -UNDEBUG -UEDEBUG") 19 | endif() 20 | if(WITHOUT_LOG STREQUAL "ON") 21 | set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DNOLOG") 22 | endif() 23 | 24 | add_subdirectory(third_party/protobuf-cpp/src/google/protobuf) 25 | add_subdirectory(sdk) 26 | add_subdirectory(enclave_service) 27 | 28 | if(BUILD_SAMPLES STREQUAL "ON") 29 | add_subdirectory(enclave_samples) 30 | endif() 31 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # How to Contribute 2 | 3 | We'd love to accept your patches and contributions to this project. There are just a few small guidelines you need to follow. 4 | 5 | #Contributor License Agreement 6 | 7 | Contributions to this project must be accompanied by a Contributor License Agreement. You (or your employer) retain the copyright to your contribution; this simply gives us permission to use and redistribute your contributions as part of the project. 8 | 9 | # Code reviews 10 | 11 | All submissions, including submissions by project members, require review. We use GitHub pull requests for this purpose. Consult GitHub Help for more information on using pull requests. 12 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # KubeTEE TFF 2 | 3 | KubeTEE TFF (Trusted Function Framework) is a Intel SGX partition model programming framework. 4 | KubeTEE TFF implements PbFunction that supports protobuf message data encapsulation. 5 | Developers can define Trusted-Function in the enclave (SGX application trusted part) or 6 | Untrusted-Function out of enclave, without caring about the underlying implementation details of SGX ECall/OCall. 7 | 8 | TFF also provides a enclave service example via gRPC. This example shows how a remote client can easily 9 | access the enclave via remote trusted-function call. 10 | 11 | ![KubeTEE TFF overview](docs/tff.jpg) 12 | 13 | 14 | # Quick Start 15 | 16 | The following steps show how to build and run the TFF based enclave service demo in dev mode. 17 | To release a formal product, you need more actions, for example, sign the enclave.so by the product key, 18 | set product IAS key and SPID in the configuration files, sign the configuration files, and so on. 19 | 20 | ## Update sub-modules 21 | 22 | KubeTEE TFF uses some [third party code](THIRD-PARTY-NOTICES), 23 | before you try the examples, please update the sub-modules firstly. 24 | 25 | ``` 26 | $ git submodule update --init --recursive 27 | ``` 28 | 29 | ## Build the source code in dev container 30 | 31 | ``` 32 | $ ./dockerbuild.sh [--build Debug|PreRelease|Release] 33 | ``` 34 | 35 | ## Create the Docker Image for Example Enclave Service 36 | 37 | Please set the enclave SPID and IAS access key in the configuration file "deployment/conf/kubetee.json". 38 | You can apply the IAS access key and SPID from [here](https://api.portal.trustedservices.intel.com/EPID-attestation) 39 | 40 | And you also need to generate the test certificates like this (for development and test only, should use formal certificates in product environment): 41 | 42 | ``` 43 | ./tools/gencert gentest ./deployment/certs/ 44 | ``` 45 | 46 | Then create the image with test certificates and configurations. 47 | 48 | ``` 49 | $ ./deployemnt/create_image.sh 50 | ``` 51 | 52 | ## Run the example enclave service docker image 53 | 54 | ``` 55 | $ ./deployemnt/run_image.sh 56 | ``` 57 | 58 | ## Deploy the service 59 | 60 | Before the service deployment, it is necessary to ensure that the SGX-Device-Plugin already 61 | exists in the Kubernetes cluster to provide SGX driver mounting and trusted memory allocation 62 | capabilities. 63 | For example, you can use Minikube to quickly deploy SGX-Device-Plugin and above example EnclaveService images. 64 | In addition, you can also create a confidential computing Kubernetes cluster based on 65 | [Alibaba Cloud Container Service for Kubernetes](https://www.aliyun.com/product/kubernetes). 66 | By default, SGX Driver and SGX-Device-Plugin are automatically installed on each node. 67 | Users only need to focus on application service development and deployment. 68 | 69 | 70 | ## Define and call the trusted function 71 | 72 | For example, add trusted PbFunctions in trusted code (enclave_samples/protobuf_functions/enclave/enclave.cpp) 73 | 74 | ``` 75 | TeeErrorCode SayHello(const std::string& req_str, std::string* res_str) { 76 | PbGenericRequest req; 77 | PbGenericResponse res; 78 | PB_PARSE(req, req_str); 79 | std::string welcome = "Welcome to enclave, "; 80 | res.add_result(welcome + req.argv()[0]); 81 | PB_SERIALIZE(res, res_str); 82 | return TEE_SUCCESS; 83 | } 84 | TeeErrorCode RegisterTrustedPbFunctionsEx() { 85 | ELOG_DEBUG("Register application trusted functions"); 86 | ADD_TRUSTED_PBCALL_FUNCTION(SayHello); 87 | return TEE_SUCCESS; 88 | } 89 | ``` 90 | 91 | Call the trusted function from untrusted code (enclave_samples/protobuf_functions/app/app.cpp) 92 | 93 | ``` 94 | /* Trusted Application*/ 95 | int SGX_CDECL main(void) { 96 | std::string enclave_name = "SampleEnclave"; 97 | EnclavesManager& em = EnclavesManager::GetInstance(); 98 | EnclaveInstance* enclave = em.CreateEnclave(enclave_name, ENCLAVE_FILENAME); 99 | if (!enclave) { 100 | printf("Fail to creates enclave %s: 0x%x", enclave_name.c_str()); 101 | return TEE_ERROR_CREATE_ENCLAVE; 102 | } 103 | // try to do something else before destroy enclave and exit 104 | PbGenericRequest req; 105 | PbGenericResponse res; 106 | req.add_argv("KubeTEE user"); 107 | enclave.TeeRun("SayHello", req, &res); 108 | printf("Function result: %s\n", res.result()[0].c_str()); 109 | return 0; 110 | } 111 | ``` 112 | 113 | 114 | # Contributing 115 | 116 | KubeTEE TFF is not final stable at this moment. We are considering add more product and Kubernetes related features later. 117 | Anyone is welcome to provide any form of contribution, please see CONTRIBUTING.md for details. 118 | 119 | 120 | # License 121 | 122 | KubeTEE TFF is released by Ant Group under Apache 2.0 License. 123 | Please see the copyright information [here](LICENSE) for detail. 124 | -------------------------------------------------------------------------------- /SECURITY.md: -------------------------------------------------------------------------------- 1 | # Security Policy 2 | 3 | ## Reporting a Vulnerability 4 | 5 | For any security vulnerabilities or other problems, please contact us by [email](mailto:SOFAEnclaveSecurity@list.alibaba-inc.com). 6 | -------------------------------------------------------------------------------- /THIRD-PARTY-NOTICES: -------------------------------------------------------------------------------- 1 | # Dependencies for KubeTEE TFF 2 | 3 | KubeTEE TFF uses some third party open source code, please refer to 4 | the project URL for their licenses in detail. 5 | 6 | If you find we have lost any dependency, please tell us by [email](SOFAEnclaveSecurity@list.alibaba-inc.com), 7 | and we will add it as soon as possible. 8 | 9 | 10 | ## Third-party source code: 11 | 12 | - [SGX CMake build](https://github.com/zhang-xin/SGX-CMake.git) 13 | - [openssl](https://www.openssl.org/source/openssl-1.1.1c.tar.gz) 14 | - [Intel SGX openssl](https://github.com/intel/intel-sgx-ssl.git) 15 | - [cppcodec for base64 encode/decode](https://github.com/tplgy/cppcodec.git) 16 | - [rapidjson as json parser](https://github.com/Tencent/rapidjson) 17 | - [libcurl as http client](https://github.com/curl/curl) 18 | - [protobuf](https://github.com/protocolbuffers/protobuf/releases/download/v3.7.1/protobuf-all-3.7.1.tar.gz) 19 | - [c-ares](https://c-ares.haxx.se/download/c-ares-1.14.0.tar.gz) 20 | - [grpc](https://github.com/grpc/grpc/archive/v1.19.1.tar.gz) 21 | - [Google cpplint.py](https://raw.githubusercontent.com/google/styleguide/gh-pages/cpplint/cpplint.py) 22 | 23 | 24 | ## Runtime dependencies 25 | 26 | - [Intel SGX Drivers](https://github.com/intel/linux-sgx-driver) (Installed in host machine) 27 | - [Intel SGX PSW(Platform Software)](https://github.com/intel/linux-sgx) (Already installed in [base image](https://hub.docker.com/repository/docker/antkubetee/kubetee-dev-ubuntu18.04-grpc-sgx-ssl)) 28 | - [protobuf-cpp-3.7.1](https://github.com/protocolbuffers/protobuf/releases/tag/v3.7.1) 29 | - docker 30 | 31 | 32 | ## Deployment dependencies 33 | If you want to deploy your enclave application or service as pods in Kubernetes, the following dependencies are also required. 34 | 35 | - Kubernetes 36 | - [SGX device plugin](https://github.com/AliyunContainerService/sgx-device-plugin) 37 | - minikube (To setup you Kubernetes cluster quickly) 38 | -------------------------------------------------------------------------------- /build.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | THISDIR="$(dirname $0)" 4 | BUILDDIR="$THISDIR/build" 5 | 6 | OPT_BUILD_MODE=PreRelease 7 | OPT_SGX_HW_MODE=HW 8 | OPT_VERBOSE=0 9 | OPT_WITHOUT_LOG=0 10 | OPT_WITH_SAMPLES=0 11 | 12 | 13 | EXIT_ERROR() { 14 | echo "$@" >&2 15 | exit 1 16 | } 17 | 18 | do_clean() { 19 | echo "remove $BUILDDIR ..." 20 | rm -rf $BUILDDIR 21 | } 22 | 23 | do_compile() { 24 | local sgx_build_mode=${1:-"Debug"} 25 | local sgx_hw_mode=${2:-"HW"} 26 | local sgx_hw="ON" 27 | local build_samples="OFF" 28 | local feature_la="OFF" 29 | local without_log="OFF" 30 | local verbose_opt="" 31 | 32 | [ "$sgx_hw_mode" != "HW" ] && sgx_hw="OFF" 33 | [ "$OPT_VERBOSE" -eq 1 ] && verbose_opt="VERBOSE=1" 34 | [ "$OPT_WITHOUT_LOG" -eq 1 ] && without_log="ON" 35 | [ "$OPT_WITH_SAMPLES" -eq 1 ] && build_samples="ON" 36 | 37 | mkdir -p $BUILDDIR && cd $BUILDDIR && \ 38 | cmake -DSGX_HW=$sgx_hw \ 39 | -DSGX_MODE=$sgx_build_mode \ 40 | -DBUILD_SAMPLES=$build_samples \ 41 | -DWITHOUT_LOG=$without_log \ 42 | ../ && \ 43 | make $verbose_opt -j$(nproc) 44 | } 45 | 46 | show_help() { 47 | cat < [...]) 16 | # 17 | # SRCS - variable to define with autogenerated source files 18 | # HDRS - variable to define with autogenerated header files 19 | # DEST - directory where the source files will be created 20 | # ARGN - .proto files 21 | # 22 | function(GRPC_GENERATE_CPP SRCS HDRS DEST) 23 | if(NOT ARGN) 24 | message(SEND_ERROR "Error: GRPC_GENERATE_CPP() called without any proto files") 25 | return() 26 | endif() 27 | 28 | if(GRPC_GENERATE_CPP_APPEND_PATH) 29 | # Create an include path for each file specified 30 | foreach(FIL ${ARGN}) 31 | get_filename_component(ABS_FIL ${FIL} ABSOLUTE) 32 | get_filename_component(ABS_PATH ${ABS_FIL} PATH) 33 | list(FIND _protobuf_include_path ${ABS_PATH} _contains_already) 34 | if(${_contains_already} EQUAL -1) 35 | list(APPEND _protobuf_include_path -I ${ABS_PATH}) 36 | endif() 37 | endforeach() 38 | else() 39 | set(_protobuf_include_path -I ${CMAKE_CURRENT_SOURCE_DIR}) 40 | endif() 41 | 42 | if(DEFINED PROTOBUF_IMPORT_DIRS) 43 | foreach(DIR ${PROTOBUF_IMPORT_DIRS}) 44 | get_filename_component(ABS_PATH ${DIR} ABSOLUTE) 45 | list(FIND _protobuf_include_path ${ABS_PATH} _contains_already) 46 | if(${_contains_already} EQUAL -1) 47 | list(APPEND _protobuf_include_path -I ${ABS_PATH}) 48 | endif() 49 | endforeach() 50 | endif() 51 | 52 | set(${SRCS}) 53 | set(${HDRS}) 54 | foreach(FIL ${ARGN}) 55 | get_filename_component(ABS_FIL ${FIL} ABSOLUTE) 56 | get_filename_component(FIL_WE ${FIL} NAME_WE) 57 | 58 | list(APPEND ${SRCS} "${DEST}/${FIL_WE}.grpc.pb.cc") 59 | list(APPEND ${HDRS} "${DEST}/${FIL_WE}.grpc.pb.h") 60 | 61 | add_custom_command( 62 | OUTPUT "${DEST}/${FIL_WE}.grpc.pb.cc" 63 | "${DEST}/${FIL_WE}.grpc.pb.h" 64 | COMMAND protobuf::protoc 65 | ARGS --grpc_out ${DEST} ${_protobuf_include_path} --plugin=protoc-gen-grpc=${GRPC_CPP_PLUGIN} ${ABS_FIL} 66 | DEPENDS ${ABS_FIL} protobuf::protoc gRPC::grpc_cpp_plugin 67 | COMMENT "Running C++ gRPC compiler on ${FIL}" 68 | VERBATIM ) 69 | endforeach() 70 | 71 | set_source_files_properties(${${SRCS}} ${${HDRS}} PROPERTIES GENERATED TRUE) 72 | set(${SRCS} ${${SRCS}} PARENT_SCOPE) 73 | set(${HDRS} ${${HDRS}} PARENT_SCOPE) 74 | endfunction() 75 | 76 | # By default have GRPC_GENERATE_CPP macro pass -I to protoc 77 | # for each directory where a proto file is referenced. 78 | if(NOT DEFINED GRPC_GENERATE_CPP_APPEND_PATH) 79 | set(GRPC_GENERATE_CPP_APPEND_PATH TRUE) 80 | endif() 81 | 82 | # Find gRPC include directory 83 | find_path(GRPC_INCLUDE_DIR grpc/grpc.h) 84 | mark_as_advanced(GRPC_INCLUDE_DIR) 85 | 86 | # Find gRPC library 87 | find_library(GRPC_LIBRARY NAMES grpc) 88 | mark_as_advanced(GRPC_LIBRARY) 89 | add_library(gRPC::grpc UNKNOWN IMPORTED) 90 | set_target_properties(gRPC::grpc PROPERTIES 91 | INTERFACE_INCLUDE_DIRECTORIES ${GRPC_INCLUDE_DIR} 92 | INTERFACE_LINK_LIBRARIES "-lpthread;-ldl" 93 | IMPORTED_LOCATION ${GRPC_LIBRARY} 94 | ) 95 | 96 | # Find gRPC C++ library 97 | find_library(GRPC_GRPC++_LIBRARY NAMES grpc++) 98 | mark_as_advanced(GRPC_GRPC++_LIBRARY) 99 | add_library(gRPC::grpc++ UNKNOWN IMPORTED) 100 | set_target_properties(gRPC::grpc++ PROPERTIES 101 | INTERFACE_INCLUDE_DIRECTORIES ${GRPC_INCLUDE_DIR} 102 | INTERFACE_LINK_LIBRARIES gRPC::grpc 103 | IMPORTED_LOCATION ${GRPC_GRPC++_LIBRARY} 104 | ) 105 | 106 | # Find gRPC C++ reflection library 107 | find_library(GRPC_GRPC++_REFLECTION_LIBRARY NAMES grpc++_reflection) 108 | mark_as_advanced(GRPC_GRPC++_REFLECTION_LIBRARY) 109 | add_library(gRPC::grpc++_reflection UNKNOWN IMPORTED) 110 | set_target_properties(gRPC::grpc++_reflection PROPERTIES 111 | INTERFACE_INCLUDE_DIRECTORIES ${GRPC_INCLUDE_DIR} 112 | INTERFACE_LINK_LIBRARIES gRPC::grpc++ 113 | IMPORTED_LOCATION ${GRPC_GRPC++_REFLECTION_LIBRARY} 114 | ) 115 | 116 | # Find gRPC CPP generator 117 | find_program(GRPC_CPP_PLUGIN NAMES grpc_cpp_plugin) 118 | mark_as_advanced(GRPC_CPP_PLUGIN) 119 | add_executable(gRPC::grpc_cpp_plugin IMPORTED) 120 | set_target_properties(gRPC::grpc_cpp_plugin PROPERTIES 121 | IMPORTED_LOCATION ${GRPC_CPP_PLUGIN} 122 | ) 123 | 124 | include(${CMAKE_ROOT}/Modules/FindPackageHandleStandardArgs.cmake) 125 | FIND_PACKAGE_HANDLE_STANDARD_ARGS(gRPC DEFAULT_MSG 126 | GRPC_LIBRARY GRPC_INCLUDE_DIR GRPC_GRPC++_REFLECTION_LIBRARY GRPC_CPP_PLUGIN) 127 | -------------------------------------------------------------------------------- /cmake/FindProtobuf.cmake: -------------------------------------------------------------------------------- 1 | # 2 | # Locate and configure the Google Protocol Buffers library 3 | # 4 | # Adds the following targets: 5 | # 6 | # protobuf::libprotobuf - Protobuf library 7 | # protobuf::libprotobuf-lite - Protobuf lite library 8 | # protobuf::libprotoc - Protobuf Protoc Library 9 | # protobuf::protoc - protoc executable 10 | # 11 | 12 | # 13 | # Generates C++ sources from the .proto files 14 | # 15 | # protobuf_generate_cpp ( [...]) 16 | # 17 | # SRCS - variable to define with autogenerated source files 18 | # HDRS - variable to define with autogenerated header files 19 | # DEST - directory where the source files will be created 20 | # ARGN - .proto files 21 | # 22 | function(PROTOBUF_GENERATE_CPP SRCS HDRS DEST) 23 | if(NOT ARGN) 24 | message(SEND_ERROR "Error: PROTOBUF_GENERATE_CPP() called without any proto files") 25 | return() 26 | endif() 27 | 28 | if(PROTOBUF_GENERATE_CPP_APPEND_PATH) 29 | # Create an include path for each file specified 30 | foreach(FIL ${ARGN}) 31 | get_filename_component(ABS_FIL ${FIL} ABSOLUTE) 32 | get_filename_component(ABS_PATH ${ABS_FIL} PATH) 33 | list(FIND _protobuf_include_path ${ABS_PATH} _contains_already) 34 | if(${_contains_already} EQUAL -1) 35 | list(APPEND _protobuf_include_path -I ${ABS_PATH}) 36 | endif() 37 | endforeach() 38 | else() 39 | set(_protobuf_include_path -I ${CMAKE_CURRENT_SOURCE_DIR}) 40 | endif() 41 | 42 | if(DEFINED PROTOBUF_IMPORT_DIRS) 43 | foreach(DIR ${PROTOBUF_IMPORT_DIRS}) 44 | get_filename_component(ABS_PATH ${DIR} ABSOLUTE) 45 | list(FIND _protobuf_include_path ${ABS_PATH} _contains_already) 46 | if(${_contains_already} EQUAL -1) 47 | list(APPEND _protobuf_include_path -I ${ABS_PATH}) 48 | endif() 49 | endforeach() 50 | endif() 51 | 52 | set(${SRCS}) 53 | set(${HDRS}) 54 | foreach(FIL ${ARGN}) 55 | get_filename_component(ABS_FIL ${FIL} ABSOLUTE) 56 | get_filename_component(FIL_WE ${FIL} NAME_WE) 57 | 58 | list(APPEND ${SRCS} "${DEST}/${FIL_WE}.pb.cc") 59 | list(APPEND ${HDRS} "${DEST}/${FIL_WE}.pb.h") 60 | 61 | add_custom_command( 62 | OUTPUT "${DEST}/${FIL_WE}.pb.cc" 63 | "${DEST}/${FIL_WE}.pb.h" 64 | COMMAND protobuf::protoc 65 | ARGS --cpp_out ${DEST} ${_protobuf_include_path} ${ABS_FIL} 66 | DEPENDS ${ABS_FIL} protobuf::protoc 67 | COMMENT "Running C++ protocol buffer compiler on ${FIL}" 68 | VERBATIM ) 69 | endforeach() 70 | 71 | set_source_files_properties(${${SRCS}} ${${HDRS}} PROPERTIES GENERATED TRUE) 72 | set(${SRCS} ${${SRCS}} PARENT_SCOPE) 73 | set(${HDRS} ${${HDRS}} PARENT_SCOPE) 74 | endfunction() 75 | 76 | # By default have PROTOBUF_GENERATE_CPP macro pass -I to protoc 77 | # for each directory where a proto file is referenced. 78 | if(NOT DEFINED PROTOBUF_GENERATE_CPP_APPEND_PATH) 79 | set(PROTOBUF_GENERATE_CPP_APPEND_PATH TRUE) 80 | endif() 81 | 82 | # Find the include directory 83 | find_path(PROTOBUF_INCLUDE_DIR google/protobuf/service.h) 84 | mark_as_advanced(PROTOBUF_INCLUDE_DIR) 85 | 86 | # The Protobuf library 87 | find_library(PROTOBUF_LIBRARY NAMES protobuf) 88 | mark_as_advanced(PROTOBUF_LIBRARY) 89 | add_library(protobuf::libprotobuf UNKNOWN IMPORTED) 90 | set_target_properties(protobuf::libprotobuf PROPERTIES 91 | INTERFACE_INCLUDE_DIRECTORIES ${PROTOBUF_INCLUDE_DIR} 92 | INTERFACE_LINK_LIBRARIES pthread 93 | IMPORTED_LOCATION ${PROTOBUF_LIBRARY} 94 | ) 95 | 96 | # The Protobuf lite library 97 | find_library(PROTOBUF_LITE_LIBRARY NAMES protobuf-lite) 98 | mark_as_advanced(PROTOBUF_LITE_LIBRARY) 99 | add_library(protobuf::libprotobuf-lite UNKNOWN IMPORTED) 100 | set_target_properties(protobuf::libprotobuf-lite PROPERTIES 101 | INTERFACE_INCLUDE_DIRECTORIES ${PROTOBUF_INCLUDE_DIR} 102 | INTERFACE_LINK_LIBRARIES pthread 103 | IMPORTED_LOCATION ${PROTOBUF_LITE_LIBRARY} 104 | ) 105 | 106 | # The Protobuf Protoc Library 107 | find_library(PROTOBUF_PROTOC_LIBRARY NAMES protoc) 108 | mark_as_advanced(PROTOBUF_PROTOC_LIBRARY) 109 | add_library(protobuf::libprotoc UNKNOWN IMPORTED) 110 | set_target_properties(protobuf::libprotoc PROPERTIES 111 | INTERFACE_INCLUDE_DIRECTORIES ${PROTOBUF_INCLUDE_DIR} 112 | INTERFACE_LINK_LIBRARIES protobuf::libprotobuf 113 | IMPORTED_LOCATION ${PROTOBUF_PROTOC_LIBRARY} 114 | ) 115 | 116 | # Find the protoc Executable 117 | find_program(PROTOBUF_PROTOC_EXECUTABLE NAMES protoc) 118 | mark_as_advanced(PROTOBUF_PROTOC_EXECUTABLE) 119 | add_executable(protobuf::protoc IMPORTED) 120 | set_target_properties(protobuf::protoc PROPERTIES 121 | IMPORTED_LOCATION ${PROTOBUF_PROTOC_EXECUTABLE} 122 | ) 123 | 124 | include(${CMAKE_ROOT}/Modules/FindPackageHandleStandardArgs.cmake) 125 | FIND_PACKAGE_HANDLE_STANDARD_ARGS(Protobuf DEFAULT_MSG 126 | PROTOBUF_LIBRARY PROTOBUF_INCLUDE_DIR PROTOBUF_PROTOC_EXECUTABLE) 127 | -------------------------------------------------------------------------------- /deployment/.gitignore: -------------------------------------------------------------------------------- 1 | buildout/* 2 | *.log 3 | -------------------------------------------------------------------------------- /deployment/bin/start_aesm.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # Start aesmd if it is not running 4 | if ! pgrep "aesm_service" > /dev/null ; then 5 | echo "Start aesmd service ..." 6 | LD_LIBRARY_PATH="/usr/local/lib:/opt/intel/sgxpsw/aesm:$LD_LIBRARY_PATH" \ 7 | /opt/intel/sgxpsw/aesm/aesm_service 8 | else 9 | echo "aesmd service is already started" 10 | fi 11 | 12 | sleep 5 # anyway, sleep a moment and then try to check 13 | for ((i=0;i<5;i++)) ; do 14 | if [ -e /dev/isgx -a -e /var/opt/aesmd/data/white_list_cert.bin ] ; then 15 | break 16 | else 17 | echo "Wait $i/5 seconds for isgx and white list file" 18 | sleep 1 19 | fi 20 | done 21 | -------------------------------------------------------------------------------- /deployment/bin/start_service.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # To make sure aesmd service is started 4 | /usr/bin/start_aesm.sh 5 | 6 | # To start the service 7 | ./enclave_service_server 8 | -------------------------------------------------------------------------------- /deployment/certs/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | -------------------------------------------------------------------------------- /deployment/conf/kubetee.json: -------------------------------------------------------------------------------- 1 | { 2 | "ias_url": "https://api.trustedservices.intel.com/sgx/dev/attestation/v4", 3 | "ias_access_key": "", 4 | "ias_response_cache": "disable", 5 | "ias_response_file": "", 6 | "enclave_user_data": "", 7 | "enclave_spid": "<32byte-SPID>", 8 | "enclave_identity_cache": "disable", 9 | "enclave_identity_file": "", 10 | "verify_mrenclave": "", 11 | "verify_prodid": "", 12 | "verify_min_svn": "", 13 | "verify_mrsigner": "83D719E77DEACA1470F6BAF62A4D774303C899DB69020F9C70EE1DFC08C7CE9E", 14 | "verify_spid": "<32byte-SPID>00000000000000000000000000000000", 15 | "verify_user_hash": "", 16 | "rpc_remote_server": "", 17 | "rpc_remote_port": "19666", 18 | "rpc_server": "", 19 | "rpc_port": "19668", 20 | "rpc_ca_path": "/etc/certs/ca.crt", 21 | "rpc_cert_path": "/etc/certs/test1.crt", 22 | "rpc_key_path": "/etc/certs/test1.key" 23 | } 24 | -------------------------------------------------------------------------------- /deployment/create_image.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | THISDIR="$(readlink -f $(dirname $0))" 4 | DOCKERFILE="${1:-${THISDIR}/dockerfile/Dockerfile}" 5 | IMAGENAME="${2:-kubetee-enclave-service:1.0}" 6 | #IMAGETAG="$(date +%F-%H%M%S)" 7 | 8 | if [ ! -f "$DOCKERFILE" ] ; then 9 | echo "Usage: $0 " 10 | exit 1 11 | fi 12 | 13 | cd $THISDIR 14 | BUILDOUTDIR="$THISDIR/buildout" 15 | echo "Copy release files to $BUILDOUTDIR" && \ 16 | mkdir -p $BUILDOUTDIR && \ 17 | rm -rf $BUILDOUTDIR/* && \ 18 | cp -r ../build/out/* $BUILDOUTDIR && \ 19 | rm -rf $BUILDOUTDIR/libenclave_service.so 20 | rm -rf $BUILDOUTDIR/identity.keypair* 21 | rm -rf $BUILDOUTDIR/ias_report.response* 22 | rm -rf $BUILDOUTDIR/*.a 23 | ls $BUILDOUTDIR 24 | 25 | if [ -e "$BUILDOUTDIR/enclave_service.signed.so" ] ; then 26 | echo "IMAGE: $IMAGENAME" 27 | sudo docker build -f ${DOCKERFILE} -t ${IMAGENAME} . && \ 28 | sudo docker images | grep "${IMAGENAME%:*}" 29 | else 30 | echo "There is no signed enclave named enclave_service.signed.so" 31 | echo "Please build the repository and sign the enclaves firstly!" 32 | exit 1 33 | fi 34 | -------------------------------------------------------------------------------- /deployment/dockerfile/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM antkubetee/kubetee-dev-ubuntu18.04-grpc-sgx-ssl:1.0 2 | 3 | LABEL maintainer="Junxian Xiao " 4 | 5 | ARG HOMEDIR=/root 6 | 7 | USER root 8 | COPY ./buildout/* ${HOMEDIR}/ 9 | COPY ./bin/*.sh /usr/bin/ 10 | COPY ./conf/* /etc/kubetee/ 11 | COPY ./certs/* /etc/certs/ 12 | 13 | #Start aesmd sever in start_service.sh 14 | #RUN echo '/usr/bin/start_aesm.sh' >> /etc/profile 15 | 16 | USER root 17 | WORKDIR ${HOMEDIR} 18 | CMD ["bash", "-c", "/usr/bin/start_service.sh"] 19 | -------------------------------------------------------------------------------- /deployment/run_image.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | SCRIPTNAME="$(basename $0)" 4 | THISDIR="$(dirname $(readlink -f $0))" 5 | 6 | IMAGE="${1:-kubetee-enclave-service:1.0}" 7 | CONTAINERNAME="${2:-kubetee-enclcave-service}" 8 | if [ -z "$IMAGE" ] ; then 9 | echo "Usage: $SCRIPTNAME [container-name]" 10 | exit 1 11 | fi 12 | 13 | # If Ctrl+C the container will not be removed 14 | # Register the handler to do clean up here. 15 | clean_up() { 16 | echo "Canceled and clean up ..." 17 | sudo docker ps -a | grep -q $CONTAINERNAME && \ 18 | sudo docker rm -f $CONTAINERNAME 19 | } 20 | trap clean_up SIGINT SIGQUIT SIGTERM 21 | 22 | # Start the application in container 23 | sudo docker run -t --rm \ 24 | --name $CONTAINERNAME \ 25 | --device=/dev/isgx \ 26 | --net=host \ 27 | --cap-add=SYS_PTRACE \ 28 | --security-opt seccomp=unconfined \ 29 | $IMAGE 30 | -------------------------------------------------------------------------------- /dockerbuild.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | SCRIPTNAME="$(basename $0)" 4 | THISDIR="$(dirname $(readlink -f $0))" 5 | BUILDDIR="$(pwd)" 6 | 7 | # Check the build directory 8 | if [ ! -e "$BUILDDIR/build.sh" ] ; then 9 | if [ -e "$THISDIR/build.sh" ] ; then 10 | BUILDDIR=$THISDIR 11 | else 12 | echo "Cannot find build script" 13 | exit 1 14 | fi 15 | fi 16 | 17 | # Print extra build options 18 | BUILDOPT="$@" 19 | echo "Build options: $BUILDOPT" 20 | 21 | REPONAME="$(basename $BUILDDIR)" 22 | IMAGE=antkubetee/kubetee-dev-ubuntu18.04-grpc-sgx-ssl:2.0 23 | CONTAINERNAME="kubetee-build-$REPONAME" 24 | 25 | echo "Build directory: $BUILDDIR" 26 | cd $BUILDDIR || exit 1 27 | sudo rm -rf ./build/* 28 | sudo docker run -t --rm \ 29 | --name $CONTAINERNAME \ 30 | --device=/dev/isgx \ 31 | --net=host \ 32 | -v $BUILDDIR:/root/$REPONAME \ 33 | -w /root/$REPONAME \ 34 | --cap-add=SYS_PTRACE \ 35 | --security-opt seccomp=unconfined \ 36 | $IMAGE \ 37 | bash -c "./build.sh $BUILDOPT" || exit 1 38 | -------------------------------------------------------------------------------- /docs/tff.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SOFAEnclave/trusted-function-framework/1c5ab9f5ca6453b71ef4da78b745022d60609fcf/docs/tff.jpg -------------------------------------------------------------------------------- /enclave_samples/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | list(APPEND CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake) 2 | find_package(SGX REQUIRED) 3 | 4 | add_subdirectory(protobuf_functions) 5 | add_subdirectory(remote_attestation) 6 | -------------------------------------------------------------------------------- /enclave_samples/protobuf_functions/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | find_package(Protobuf REQUIRED) 2 | set(TEE_PROTO_FILES 3 | ${TEE_TOP_DIR}/proto/kubetee.proto 4 | ) 5 | PROTOBUF_GENERATE_CPP( 6 | TEE_PROTO_SRCS 7 | TEE_PROTO_HDRS 8 | ${CMAKE_BINARY_DIR} 9 | ${TEE_PROTO_FILES} 10 | ) 11 | 12 | set(INC_EX ${TEE_TOP_DIR}/sdk/include) 13 | set(SGXSSL_LIB /opt/intel/sgxssl/lib64) 14 | set(SGXSSL_INC /opt/intel/sgxssl/include) 15 | set(EX_EDL_SEARCH_PATHS 16 | ${CMAKE_CURRENT_SOURCE_DIR}/enclave 17 | ${TEE_TOP_DIR}/sdk/edl 18 | ${SGXSSL_INC} 19 | ${INC_EX} 20 | ) 21 | set(E_SRCS 22 | ${TEE_PROTO_SRCS} 23 | ${CMAKE_CURRENT_SOURCE_DIR}/enclave/enclave.cpp 24 | ) 25 | set(LDS ${CMAKE_CURRENT_SOURCE_DIR}/enclave/enclave.lds) 26 | set(EDL ${CMAKE_CURRENT_SOURCE_DIR}/enclave/enclave.edl) 27 | set(KEY ${CMAKE_CURRENT_SOURCE_DIR}/enclave/enclave_private.pem) 28 | set(XML ${CMAKE_CURRENT_SOURCE_DIR}/enclave/enclave.config.xml) 29 | set(TLIBS tkubetee tprotobuf) 30 | include_directories( 31 | ${CMAKE_CURRENT_SOURCE_DIR} 32 | ${CMAKE_CURRENT_BINARY_DIR} 33 | ${CMAKE_BINARY_DIR} 34 | ${TEE_TOP_DIR}/sdk 35 | ${TEE_TOP_DIR}/third_party/protobuf-cpp/src/ 36 | ) 37 | 38 | set(SAMPLEENCLAVE enclave_protobuf_functions) 39 | add_enclave_library( 40 | ${SAMPLEENCLAVE} 41 | SRCS ${E_SRCS} 42 | TRUSTED_LIBS ${TLIBS} 43 | EDL ${EDL} 44 | EDL_SEARCH_PATHS ${EX_EDL_SEARCH_PATHS} 45 | LDSCRIPT ${LDS} 46 | ) 47 | enclave_sign( 48 | ${SAMPLEENCLAVE} 49 | KEY ${KEY} 50 | CONFIG ${XML} 51 | ) 52 | 53 | set(SAMPLEAPP sample_protobuf_functions) 54 | set(SRCS 55 | ${TEE_PROTO_SRCS} 56 | ${CMAKE_CURRENT_SOURCE_DIR}/app/app.cpp 57 | ) 58 | include_directories( 59 | ${CMAKE_CURRENT_SOURCE_DIR} 60 | ${CMAKE_CURRENT_BINARY_DIR} 61 | ${CMAKE_BINARY_DIR} 62 | ${TEE_TOP_DIR}/sdk 63 | ${TEE_TOP_DIR}/sdk/include 64 | ) 65 | add_untrusted_executable( 66 | ${SAMPLEAPP} 67 | SRCS ${SRCS} 68 | EDL ${EDL} 69 | EDL_SEARCH_PATHS ${EX_EDL_SEARCH_PATHS} 70 | ) 71 | target_link_libraries( 72 | ${SAMPLEAPP} 73 | -L${LIBRARY_OUTPUT_PATH} -L${SGX_LIBRARY_DIR} -L${SGXSSL_LIB} -L/usr/lib64 74 | -lprotobuf 75 | -Wl,--start-group -lukubetee -lchallenger -lsgx_usgxssl -lcrypto -Wl,--end-group 76 | -Wl,-rpath=.:/lib64:/usr/lib:/usr/local/lib 77 | ) 78 | add_dependencies(${SAMPLEAPP} ukubetee challenger) 79 | -------------------------------------------------------------------------------- /enclave_samples/protobuf_functions/app/app.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include "tee/untrusted/enclave/untrusted_enclave.h" 4 | #include "tee/untrusted/untrusted_pbcall.h" 5 | 6 | #include "./enclave_u.h" 7 | #include "./kubetee.pb.h" 8 | #include "app/app.h" 9 | 10 | #ifdef __cplusplus 11 | extern "C" { 12 | #endif 13 | 14 | TeeErrorCode PrintMessage(const std::string& req_str, std::string* res_str) { 15 | tee::PbGenericRequest req; 16 | tee::PbGenericResponse res; 17 | 18 | PB_PARSE(req, req_str); 19 | printf("PrintMessage: %s\n", req.argv()[0].c_str()); 20 | PB_SERIALIZE(res, res_str); 21 | 22 | return TEE_SUCCESS; 23 | } 24 | 25 | TeeErrorCode RegisterUntrustedPbFunctionsEx() { 26 | ELOG_DEBUG("Register application untrusted protobuf call funtions"); 27 | ADD_UNTRUSTED_PBCALL_FUNCTION(PrintMessage); 28 | return TEE_SUCCESS; 29 | } 30 | 31 | #ifdef __cplusplus 32 | } 33 | #endif 34 | 35 | int main(void) { 36 | TeeErrorCode ret = TEE_ERROR_GENERIC; 37 | 38 | // Create and initialize the enclave 39 | std::string enclave_name = "SamplePbCall"; 40 | EnclavesManager& em = EnclavesManager::GetInstance(); 41 | EnclaveInstance* enclave = em.CreateEnclave(enclave_name, ENCLAVE_FILENAME); 42 | if (!enclave) { 43 | printf("Fail to creates enclave %s", enclave_name.c_str()); 44 | return TEE_ERROR_CREATE_ENCLAVE; 45 | } 46 | 47 | // Try to do something else before destroy enclave and exit 48 | tee::PbGenericRequest req; 49 | tee::PbGenericResponse res; 50 | req.add_argv("Protobuf Call"); 51 | ret = enclave->TeeRun("SayHello", req, &res); 52 | if (ret != TEE_SUCCESS) { 53 | printf("Fail to run trusted function: SayHello\n"); 54 | return ret; 55 | } 56 | 57 | if (res.result().size()) { 58 | printf("%s\n", res.result()[0].c_str()); 59 | } 60 | 61 | // Destroy the enclave explicitly, this is optional. 62 | EnclavesManager::GetInstance().DestroyEnclave(enclave); 63 | 64 | return ret; 65 | } 66 | -------------------------------------------------------------------------------- /enclave_samples/protobuf_functions/app/app.h: -------------------------------------------------------------------------------- 1 | #ifndef ENCLAVE_SAMPLES_PROTOBUF_FUNCTIONS_APP_APP_H_ 2 | #define ENCLAVE_SAMPLES_PROTOBUF_FUNCTIONS_APP_APP_H_ 3 | 4 | #include "./sgx_eid.h" // sgx_enclave_id_t 5 | #include "./sgx_error.h" // sgx_status_t 6 | 7 | #define ENCLAVE_FILENAME "enclave_protobuf_functions.signed.so" 8 | 9 | #if defined(__cplusplus) 10 | extern "C" { 11 | #endif 12 | 13 | #if defined(__cplusplus) 14 | } 15 | #endif 16 | 17 | #endif // ENCLAVE_SAMPLES_PROTOBUF_FUNCTIONS_APP_APP_H_ 18 | -------------------------------------------------------------------------------- /enclave_samples/protobuf_functions/enclave/enclave.config.xml: -------------------------------------------------------------------------------- 1 | 2 | 1234 3 | 0001 4 | 0x40000 5 | 0x100000 6 | 10 7 | 1 8 | 9 | 0 10 | 0 11 | 0xFFFFFFFF 12 | 13 | -------------------------------------------------------------------------------- /enclave_samples/protobuf_functions/enclave/enclave.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include "tee/common/log.h" 4 | #include "tee/trusted/trusted_instance.h" 5 | #include "tee/trusted/trusted_pbcall.h" 6 | 7 | #include "./enclave_t.h" 8 | #include "./kubetee.pb.h" 9 | 10 | #include "enclave/enclave.h" 11 | 12 | #ifdef __cplusplus 13 | extern "C" { 14 | #endif 15 | 16 | TeeErrorCode SayHello(const std::string& req_str, std::string* res_str) { 17 | using tee::PbGenericRequest; 18 | using tee::PbGenericResponse; 19 | PbGenericRequest req; 20 | PbGenericResponse res; 21 | 22 | PB_PARSE(req, req_str); 23 | 24 | // Call untrusted pbcall function in trusted pbcall function 25 | PbGenericRequest ocall_req = req; 26 | PbGenericResponse ocall_res; 27 | TEE_CHECK_RETURN(tee::trusted::TeeInstance::GetInstance().ReeRun( 28 | "PrintMessage", ocall_req, &ocall_res)); 29 | 30 | std::string welcome = "Welcome to enclave, "; 31 | res.add_result(welcome + req.argv()[0]); 32 | PB_SERIALIZE(res, res_str); 33 | 34 | return TEE_SUCCESS; 35 | } 36 | 37 | TeeErrorCode RegisterTrustedPbFunctionsEx() { 38 | ELOG_DEBUG("Register application trusted protobuf call funtions"); 39 | ADD_TRUSTED_PBCALL_FUNCTION(SayHello); 40 | return TEE_SUCCESS; 41 | } 42 | 43 | #ifdef __cplusplus 44 | } 45 | #endif 46 | -------------------------------------------------------------------------------- /enclave_samples/protobuf_functions/enclave/enclave.edl: -------------------------------------------------------------------------------- 1 | /* Enclave.edl - Top EDL file. */ 2 | 3 | enclave { 4 | from "sgx_tsgxssl.edl" import *; 5 | from "kubetee.edl" import *; 6 | }; 7 | -------------------------------------------------------------------------------- /enclave_samples/protobuf_functions/enclave/enclave.h: -------------------------------------------------------------------------------- 1 | #ifndef ENCLAVE_SAMPLES_PROTOBUF_FUNCTIONS_ENCLAVE_ENCLAVE_H_ 2 | #define ENCLAVE_SAMPLES_PROTOBUF_FUNCTIONS_ENCLAVE_ENCLAVE_H_ 3 | 4 | #include 5 | #include 6 | 7 | #if defined(__cplusplus) 8 | extern "C" { 9 | #endif 10 | 11 | #if defined(__cplusplus) 12 | } 13 | #endif 14 | 15 | #endif // ENCLAVE_SAMPLES_PROTOBUF_FUNCTIONS_ENCLAVE_ENCLAVE_H_ 16 | -------------------------------------------------------------------------------- /enclave_samples/protobuf_functions/enclave/enclave.lds: -------------------------------------------------------------------------------- 1 | enclave.so 2 | { 3 | global: 4 | g_global_data_sim; 5 | g_global_data; 6 | enclave_entry; 7 | g_peak_heap_used; 8 | local: 9 | *; 10 | }; 11 | -------------------------------------------------------------------------------- /enclave_samples/protobuf_functions/enclave/enclave_private.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN RSA PRIVATE KEY----- 2 | MIIG4gIBAAKCAYEAroOogvsj/fZDZY8XFdkl6dJmky0lRvnWMmpeH41Bla6U1qLZ 3 | AmZuyIF+mQC/cgojIsrBMzBxb1kKqzATF4+XwPwgKz7fmiddmHyYz2WDJfAjIveJ 4 | ZjdMjM4+EytGlkkJ52T8V8ds0/L2qKexJ+NBLxkeQLfV8n1mIk7zX7jguwbCG1Pr 5 | nEMdJ3Sew20vnje+RsngAzdPChoJpVsWi/K7cettX/tbnre1DL02GXc5qJoQYk7b 6 | 3zkmhz31TgFrd9VVtmUGyFXAysuSAb3EN+5VnHGr0xKkeg8utErea2FNtNIgua8H 7 | ONfm9Eiyaav1SVKzPHlyqLtcdxH3I8Wg7yqMsaprZ1n5A1v/levxnL8+It02KseD 8 | 5HqV4rf/cImSlCt3lpRg8U5E1pyFQ2IVEC/XTDMiI3c+AR+w2jSRB3Bwn9zJtFlW 9 | KHG3m1xGI4ck+Lci1JvWWLXQagQSPtZTsubxTQNx1gsgZhgv1JHVZMdbVlAbbRMC 10 | 1nSuJNl7KPAS/VfzAgEDAoIBgHRXxaynbVP5gkO0ug6Qw/E27wzIw4SmjsxG6Wpe 11 | K7kfDeRskKxESdsA/xCrKkwGwhcx1iIgS5+Qscd1Yg+1D9X9asd/P7waPmWoZd+Z 12 | AhlKwhdPsO7PiF3e1AzHhGQwsUTt/Y/aSI1MpHBvy2/s1h9mFCslOUxTmWw0oj/Q 13 | ldIEgWeNR72CE2+jFIJIyml6ftnb6qzPiga8Bm48ubKh0kvySOqnkmnPzgh+JBD6 14 | JnBmtZbfPT97bwTT+N6rnPqOOApvfHPf15kWI8yDbprG1l4OCUaIUH1AszxLd826 15 | 5IPM+8gINLRDP1MA6azECPjTyHXhtnSIBZCyWSVkc05vYmNXYUNiXWMajcxW9M02 16 | wKzFELO8NCEAkaTPxwo4SCyIjUxiK1LbQ9h8PSy4c1+gGP4LAMR8xqP4QKg6zdu9 17 | osUGG/xRe/uufgTBFkcjqBHtK5L5VI0jeNIUAgW/6iNbYXjBMJ0GfauLs+g1VsOm 18 | WfdgXzsb9DYdMa0OXXHypmV4GwKBwQDUwQj8RKJ6c8cT4vcWCoJvJF00+RFL+P3i 19 | Gx2DLERxRrDa8AVGfqaCjsR+3vLgG8V/py+z+dxZYSqeB80Qeo6PDITcRKoeAYh9 20 | xlT3LJOS+k1cJcEmlbbO2IjLkTmzSwa80fWexKu8/Xv6vv15gpqYl1ngYoqJM3pd 21 | vzmTIOi7MKSZ0WmEQavrZj8zK4endE3v0eAEeQ55j1GImbypSf7Idh7wOXtjZ7WD 22 | Dg6yWDrri+AP/L3gClMj8wsAxMV4ZR8CgcEA0fzDHkFa6raVOxWnObmRoDhAtE0a 23 | cjUj976NM5yyfdf2MrKy4/RhdTiPZ6b08/lBC/+xRfV3xKVGzacm6QjqjZrUpgHC 24 | 0LKiZaMtccCJjLtPwQd0jGQEnKfMFaPsnhOc5y8qVkCzVOSthY5qhz0XNotHHFmJ 25 | gffVgB0iqrMTvSL7IA2yqqpOqNRlhaYhNl8TiFP3gIeMtVa9rZy31JPgT2uJ+kfo 26 | gV7sdTPEjPWZd7OshGxWpT6QfVDj/T9T7L6tAoHBAI3WBf2DFvxNL2KXT2QHAZ9t 27 | k3imC4f7U+wSE6zILaDZyzygA4RUbwG0gv8/TJVn2P/Eynf76DuWHGlaiLWnCbSz 28 | Az2DHBQBBaku409zDQym3j1ugMRjzzSQWzJg0SIyBH3hTmnYcn3+Uqcp/lEBvGW6 29 | O+rsXFt3pukqJmIV8HzLGGaLm62BHUeZf3dyWm+i3p/hQAL7Xvu04QW70xuGqdr5 30 | afV7p5eaeQIJXyGQJ0eylV/90+qxjMKiB1XYg6WYvwKBwQCL/ddpgOdHJGN8uRom 31 | e7Zq0Csi3hGheMKlKbN3vcxT5U7MdyHtTZZOJbTvxKNNUNYH/8uD+PqDGNneb29G 32 | BfGzvI3EASyLIcGZF3OhKwZd0jUrWk2y7Vhob91jwp2+t73vdMbkKyI4mHOuXvGv 33 | fg95si9oO7EBT+Oqvhccd2J+F1IVXncccYnF4u5ZGWt5lLewN/pVr7MjjykeaHqN 34 | t+rfnQam2psA6fL4zS2zTmZPzR2tnY8Y1GBTi0Ko1OKd1HMCgcAb5cB/7/AQlhP9 35 | yQa04PLH9ygQkKKptZp7dy5WcWRx0K/hAHRoi2aw1wZqfm7VBNu2SLcs90kCCCxp 36 | 6C5sfJi6b8NpNbIPC+sc9wsFr7pGo9SFzQ78UlcWYK2Gu2FxlMjonhka5hvo4zvg 37 | WxlpXKEkaFt3gLd92m/dMqBrHfafH7VwOJY2zT3WIpjwuk0ZzmRg5p0pG/svVQEH 38 | NZmwRwlopysbR69B/n1nefJ84UO50fLh5s5Zr3gBRwbWNZyzhXk= 39 | -----END RSA PRIVATE KEY----- 40 | -------------------------------------------------------------------------------- /enclave_samples/remote_attestation/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | find_package(Protobuf REQUIRED) 2 | set(TEE_PROTO_FILES 3 | ${TEE_TOP_DIR}/proto/kubetee.proto 4 | ) 5 | PROTOBUF_GENERATE_CPP( 6 | TEE_PROTO_SRCS 7 | TEE_PROTO_HDRS 8 | ${CMAKE_BINARY_DIR} 9 | ${TEE_PROTO_FILES} 10 | ) 11 | 12 | set(INC_EX ${TEE_TOP_DIR}/sdk/include) 13 | set(SGXSSL_LIB /opt/intel/sgxssl/lib64) 14 | set(SGXSSL_INC /opt/intel/sgxssl/include) 15 | set(EX_EDL_SEARCH_PATHS 16 | ${CMAKE_CURRENT_SOURCE_DIR}/enclave 17 | ${TEE_TOP_DIR}/sdk/edl 18 | ${SGXSSL_INC} 19 | ${INC_EX} 20 | ) 21 | set(E_SRCS 22 | ${TEE_PROTO_SRCS} 23 | ${CMAKE_CURRENT_SOURCE_DIR}/enclave/enclave.cpp 24 | ) 25 | set(LDS ${CMAKE_CURRENT_SOURCE_DIR}/enclave/enclave.lds) 26 | set(EDL ${CMAKE_CURRENT_SOURCE_DIR}/enclave/enclave.edl) 27 | set(KEY ${CMAKE_CURRENT_SOURCE_DIR}/enclave/enclave_private.pem) 28 | set(XML ${CMAKE_CURRENT_SOURCE_DIR}/enclave/enclave.config.xml) 29 | set(TLIBS tkubetee tprotobuf) 30 | include_directories( 31 | ${CMAKE_CURRENT_SOURCE_DIR} 32 | ${CMAKE_CURRENT_BINARY_DIR} 33 | ${CMAKE_BINARY_DIR} 34 | ${TEE_TOP_DIR}/sdk 35 | ${TEE_TOP_DIR}/third_party/protobuf-cpp/src/ 36 | ) 37 | 38 | set(SAMPLEENCLAVE enclave_remote_attestation) 39 | add_enclave_library( 40 | ${SAMPLEENCLAVE} 41 | SRCS ${E_SRCS} 42 | TRUSTED_LIBS ${TLIBS} 43 | EDL ${EDL} 44 | EDL_SEARCH_PATHS ${EX_EDL_SEARCH_PATHS} 45 | LDSCRIPT ${LDS} 46 | ) 47 | enclave_sign( 48 | ${SAMPLEENCLAVE} 49 | KEY ${KEY} 50 | CONFIG ${XML} 51 | ) 52 | 53 | set(SAMPLEAPP sample_remote_attestation) 54 | set(SRCS 55 | ${TEE_PROTO_SRCS} 56 | ${CMAKE_CURRENT_SOURCE_DIR}/app/app.cpp 57 | ) 58 | include_directories( 59 | ${CMAKE_CURRENT_SOURCE_DIR} 60 | ${CMAKE_CURRENT_BINARY_DIR} 61 | ${CMAKE_BINARY_DIR} 62 | ${TEE_TOP_DIR}/sdk 63 | ${TEE_TOP_DIR}/sdk/include 64 | ) 65 | add_untrusted_executable( 66 | ${SAMPLEAPP} 67 | SRCS ${SRCS} 68 | EDL ${EDL} 69 | EDL_SEARCH_PATHS ${EX_EDL_SEARCH_PATHS} 70 | ) 71 | target_link_libraries( 72 | ${SAMPLEAPP} 73 | -L${LIBRARY_OUTPUT_PATH} -L${SGX_LIBRARY_DIR} -L${SGXSSL_LIB} -L/usr/lib64 74 | -lprotobuf 75 | -Wl,--start-group -lukubetee -lchallenger -lsgx_usgxssl -lcrypto -Wl,--end-group 76 | -Wl,-rpath=.:/lib64:/usr/lib:/usr/local/lib 77 | ) 78 | add_dependencies(${SAMPLEAPP} ukubetee challenger) 79 | -------------------------------------------------------------------------------- /enclave_samples/remote_attestation/app/app.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include "./sgx_urts.h" 5 | 6 | #include "tee/untrusted/enclave/untrusted_enclave.h" 7 | #include "tee/untrusted/ra/untrusted_challenger.h" 8 | #include "tee/untrusted/ra/untrusted_ias.h" 9 | #include "tee/untrusted/untrusted_pbcall.h" 10 | 11 | #include "./enclave_u.h" 12 | #include "./kubetee.pb.h" 13 | #include "app/app.h" 14 | 15 | // OCall functions for this applicaiton 16 | void ocall_print_string(const char* str) { 17 | printf("%s", str); 18 | } 19 | 20 | int SGX_CDECL main(void) { 21 | // Step 1: Create and initialize the enclave 22 | std::string enclave_name = "SampleRemoteAttestation"; 23 | EnclaveInstance* enclave = EnclavesManager::GetInstance().CreateEnclave( 24 | enclave_name, ENCLAVE_FILENAME); 25 | if (!enclave) { 26 | printf("Fail to creates enclave %s", enclave_name.c_str()); 27 | return TEE_ERROR_CREATE_ENCLAVE; 28 | } 29 | 30 | // Step 2: Try to load cached report or create new quote and report 31 | TeeErrorCode ret = enclave->FetchIasReport(); 32 | if (ret != TEE_SUCCESS) { 33 | printf("Fail to get IAS report: 0x%x\n", ret); 34 | return ret; 35 | } 36 | 37 | // Step 3: If fetch new report successfully, then verify it. 38 | // Here, use the verify settings from configuration file 39 | ret = VerifyRaReport(enclave->GetPublicKey(), enclave->GetLocalIasReport()); 40 | printf("Verify RA report by config file settings: 0x%08x\n", ret); 41 | 42 | return ret; 43 | } 44 | -------------------------------------------------------------------------------- /enclave_samples/remote_attestation/app/app.h: -------------------------------------------------------------------------------- 1 | #ifndef ENCLAVE_SAMPLES_REMOTE_ATTESTATION_APP_APP_H_ 2 | #define ENCLAVE_SAMPLES_REMOTE_ATTESTATION_APP_APP_H_ 3 | 4 | #include 5 | #include 6 | 7 | #include "./sgx_eid.h" // sgx_enclave_id_t 8 | #include "./sgx_error.h" // sgx_status_t 9 | 10 | #ifndef TRUE 11 | #define TRUE 1 12 | #endif 13 | 14 | #ifndef FALSE 15 | #define FALSE 0 16 | #endif 17 | 18 | #define ENCLAVE_FILENAME "enclave_remote_attestation.signed.so" 19 | 20 | #if defined(__cplusplus) 21 | extern "C" { 22 | #endif 23 | 24 | #if defined(__cplusplus) 25 | } 26 | #endif 27 | 28 | #endif // ENCLAVE_SAMPLES_REMOTE_ATTESTATION_APP_APP_H_ 29 | -------------------------------------------------------------------------------- /enclave_samples/remote_attestation/enclave/enclave.config.xml: -------------------------------------------------------------------------------- 1 | 2 | 0 3 | 0 4 | 0x40000 5 | 0x100000 6 | 10 7 | 1 8 | 9 | 0 10 | 0 11 | 0xFFFFFFFF 12 | 13 | -------------------------------------------------------------------------------- /enclave_samples/remote_attestation/enclave/enclave.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include "./enclave_t.h" 4 | #include "enclave/enclave.h" 5 | 6 | #include "./kubetee.pb.h" 7 | 8 | void ecall_say_hello() { 9 | ocall_print_string("Welcome to enclave!\n"); 10 | } 11 | -------------------------------------------------------------------------------- /enclave_samples/remote_attestation/enclave/enclave.edl: -------------------------------------------------------------------------------- 1 | /* Enclave.edl - Top EDL file. */ 2 | 3 | enclave { 4 | from "sgx_tsgxssl.edl" import *; 5 | from "kubetee.edl" import *; 6 | 7 | trusted { 8 | public void ecall_say_hello(); 9 | }; 10 | 11 | untrusted { 12 | void ocall_print_string([in, string] const char *str); 13 | }; 14 | }; 15 | -------------------------------------------------------------------------------- /enclave_samples/remote_attestation/enclave/enclave.h: -------------------------------------------------------------------------------- 1 | #ifndef ENCLAVE_SAMPLES_REMOTE_ATTESTATION_ENCLAVE_ENCLAVE_H_ 2 | #define ENCLAVE_SAMPLES_REMOTE_ATTESTATION_ENCLAVE_ENCLAVE_H_ 3 | 4 | #include 5 | #include 6 | 7 | #if defined(__cplusplus) 8 | extern "C" { 9 | #endif 10 | 11 | #if defined(__cplusplus) 12 | } 13 | #endif 14 | 15 | #endif // ENCLAVE_SAMPLES_REMOTE_ATTESTATION_ENCLAVE_ENCLAVE_H_ 16 | -------------------------------------------------------------------------------- /enclave_samples/remote_attestation/enclave/enclave.lds: -------------------------------------------------------------------------------- 1 | enclave.so 2 | { 3 | global: 4 | g_global_data_sim; 5 | g_global_data; 6 | enclave_entry; 7 | g_peak_heap_used; 8 | local: 9 | *; 10 | }; 11 | -------------------------------------------------------------------------------- /enclave_samples/remote_attestation/enclave/enclave_private.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN RSA PRIVATE KEY----- 2 | MIIG4gIBAAKCAYEAroOogvsj/fZDZY8XFdkl6dJmky0lRvnWMmpeH41Bla6U1qLZ 3 | AmZuyIF+mQC/cgojIsrBMzBxb1kKqzATF4+XwPwgKz7fmiddmHyYz2WDJfAjIveJ 4 | ZjdMjM4+EytGlkkJ52T8V8ds0/L2qKexJ+NBLxkeQLfV8n1mIk7zX7jguwbCG1Pr 5 | nEMdJ3Sew20vnje+RsngAzdPChoJpVsWi/K7cettX/tbnre1DL02GXc5qJoQYk7b 6 | 3zkmhz31TgFrd9VVtmUGyFXAysuSAb3EN+5VnHGr0xKkeg8utErea2FNtNIgua8H 7 | ONfm9Eiyaav1SVKzPHlyqLtcdxH3I8Wg7yqMsaprZ1n5A1v/levxnL8+It02KseD 8 | 5HqV4rf/cImSlCt3lpRg8U5E1pyFQ2IVEC/XTDMiI3c+AR+w2jSRB3Bwn9zJtFlW 9 | KHG3m1xGI4ck+Lci1JvWWLXQagQSPtZTsubxTQNx1gsgZhgv1JHVZMdbVlAbbRMC 10 | 1nSuJNl7KPAS/VfzAgEDAoIBgHRXxaynbVP5gkO0ug6Qw/E27wzIw4SmjsxG6Wpe 11 | K7kfDeRskKxESdsA/xCrKkwGwhcx1iIgS5+Qscd1Yg+1D9X9asd/P7waPmWoZd+Z 12 | AhlKwhdPsO7PiF3e1AzHhGQwsUTt/Y/aSI1MpHBvy2/s1h9mFCslOUxTmWw0oj/Q 13 | ldIEgWeNR72CE2+jFIJIyml6ftnb6qzPiga8Bm48ubKh0kvySOqnkmnPzgh+JBD6 14 | JnBmtZbfPT97bwTT+N6rnPqOOApvfHPf15kWI8yDbprG1l4OCUaIUH1AszxLd826 15 | 5IPM+8gINLRDP1MA6azECPjTyHXhtnSIBZCyWSVkc05vYmNXYUNiXWMajcxW9M02 16 | wKzFELO8NCEAkaTPxwo4SCyIjUxiK1LbQ9h8PSy4c1+gGP4LAMR8xqP4QKg6zdu9 17 | osUGG/xRe/uufgTBFkcjqBHtK5L5VI0jeNIUAgW/6iNbYXjBMJ0GfauLs+g1VsOm 18 | WfdgXzsb9DYdMa0OXXHypmV4GwKBwQDUwQj8RKJ6c8cT4vcWCoJvJF00+RFL+P3i 19 | Gx2DLERxRrDa8AVGfqaCjsR+3vLgG8V/py+z+dxZYSqeB80Qeo6PDITcRKoeAYh9 20 | xlT3LJOS+k1cJcEmlbbO2IjLkTmzSwa80fWexKu8/Xv6vv15gpqYl1ngYoqJM3pd 21 | vzmTIOi7MKSZ0WmEQavrZj8zK4endE3v0eAEeQ55j1GImbypSf7Idh7wOXtjZ7WD 22 | Dg6yWDrri+AP/L3gClMj8wsAxMV4ZR8CgcEA0fzDHkFa6raVOxWnObmRoDhAtE0a 23 | cjUj976NM5yyfdf2MrKy4/RhdTiPZ6b08/lBC/+xRfV3xKVGzacm6QjqjZrUpgHC 24 | 0LKiZaMtccCJjLtPwQd0jGQEnKfMFaPsnhOc5y8qVkCzVOSthY5qhz0XNotHHFmJ 25 | gffVgB0iqrMTvSL7IA2yqqpOqNRlhaYhNl8TiFP3gIeMtVa9rZy31JPgT2uJ+kfo 26 | gV7sdTPEjPWZd7OshGxWpT6QfVDj/T9T7L6tAoHBAI3WBf2DFvxNL2KXT2QHAZ9t 27 | k3imC4f7U+wSE6zILaDZyzygA4RUbwG0gv8/TJVn2P/Eynf76DuWHGlaiLWnCbSz 28 | Az2DHBQBBaku409zDQym3j1ugMRjzzSQWzJg0SIyBH3hTmnYcn3+Uqcp/lEBvGW6 29 | O+rsXFt3pukqJmIV8HzLGGaLm62BHUeZf3dyWm+i3p/hQAL7Xvu04QW70xuGqdr5 30 | afV7p5eaeQIJXyGQJ0eylV/90+qxjMKiB1XYg6WYvwKBwQCL/ddpgOdHJGN8uRom 31 | e7Zq0Csi3hGheMKlKbN3vcxT5U7MdyHtTZZOJbTvxKNNUNYH/8uD+PqDGNneb29G 32 | BfGzvI3EASyLIcGZF3OhKwZd0jUrWk2y7Vhob91jwp2+t73vdMbkKyI4mHOuXvGv 33 | fg95si9oO7EBT+Oqvhccd2J+F1IVXncccYnF4u5ZGWt5lLewN/pVr7MjjykeaHqN 34 | t+rfnQam2psA6fL4zS2zTmZPzR2tnY8Y1GBTi0Ko1OKd1HMCgcAb5cB/7/AQlhP9 35 | yQa04PLH9ygQkKKptZp7dy5WcWRx0K/hAHRoi2aw1wZqfm7VBNu2SLcs90kCCCxp 36 | 6C5sfJi6b8NpNbIPC+sc9wsFr7pGo9SFzQ78UlcWYK2Gu2FxlMjonhka5hvo4zvg 37 | WxlpXKEkaFt3gLd92m/dMqBrHfafH7VwOJY2zT3WIpjwuk0ZzmRg5p0pG/svVQEH 38 | NZmwRwlopysbR69B/n1nefJ84UO50fLh5s5Zr3gBRwbWNZyzhXk= 39 | -----END RSA PRIVATE KEY----- 40 | -------------------------------------------------------------------------------- /enclave_service/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | set(SGXSSL_LIB /opt/intel/sgxssl/lib64) 2 | set(SGXSSL_INC /opt/intel/sgxssl/include) 3 | 4 | # Generate the protobuf and grpc source and header files 5 | find_package(Protobuf REQUIRED) 6 | find_package(GRPC REQUIRED) 7 | set(ES_PROTO_FILES 8 | ${TEE_TOP_DIR}/proto/kubetee.proto 9 | ${CMAKE_CURRENT_SOURCE_DIR}/proto/enclave_service.proto 10 | ) 11 | PROTOBUF_GENERATE_CPP( 12 | ES_PROTO_SRCS 13 | ES_PROTO_HDRS 14 | ${CMAKE_BINARY_DIR} 15 | ${ES_PROTO_FILES} 16 | ) 17 | GRPC_GENERATE_CPP( 18 | ES_GRPC_SRCS 19 | ES_GRPC_HDRS 20 | ${CMAKE_BINARY_DIR} 21 | ${ES_PROTO_FILES} 22 | ) 23 | 24 | set(ES_EDL ${CMAKE_CURRENT_SOURCE_DIR}/trusted/enclave_service.edl) 25 | set(EX_EDL_SEARCH_PATHS 26 | ${CMAKE_CURRENT_SOURCE_DIR}/trusted 27 | ${TEE_TOP_DIR}/sdk/edl 28 | ${TEE_TOP_DIR}/sdk/include 29 | ${SGXSSL_INC} 30 | ) 31 | 32 | # Generate the trusted targets 33 | file(GLOB ES_TRUSTED_SRCS ${CMAKE_CURRENT_SOURCE_DIR}/trusted/*.cpp) 34 | set(ES_LDS ${CMAKE_CURRENT_SOURCE_DIR}/trusted/enclave_service.lds) 35 | set(ES_KEY ${CMAKE_CURRENT_SOURCE_DIR}/trusted/enclave_private.pem) 36 | set(ES_XML ${CMAKE_CURRENT_SOURCE_DIR}/trusted/enclave.config.xml) 37 | set(ES_TLIBS tkubetee tprotobuf) 38 | set(ES_TSRCS 39 | ${ES_TRUSTED_SRCS} 40 | ${CMAKE_BINARY_DIR}/enclave_service.pb.cc 41 | ) 42 | include_directories( 43 | ${CMAKE_CURRENT_SOURCE_DIR} 44 | ${CMAKE_CURRENT_BINARY_DIR} 45 | ${CMAKE_BINARY_DIR} 46 | ${TEE_TOP_DIR}/sdk 47 | ${TEE_TOP_DIR}/sdk/include 48 | ${TEE_TOP_DIR}/third_party/protobuf-cpp/src/ 49 | ) 50 | 51 | set(ESENCLAVE enclave_service) 52 | add_enclave_library( 53 | ${ESENCLAVE} 54 | SRCS ${ES_TSRCS} 55 | TRUSTED_LIBS ${ES_TLIBS} 56 | EDL ${ES_EDL} 57 | EDL_SEARCH_PATHS ${EX_EDL_SEARCH_PATHS} 58 | LDSCRIPT ${ES_LDS} 59 | ) 60 | target_include_directories( 61 | ${ESENCLAVE} PRIVATE 62 | ${SGXSSL_INC} 63 | ) 64 | enclave_sign( 65 | ${ESENCLAVE} 66 | KEY ${ES_KEY} 67 | CONFIG ${ES_XML} 68 | ) 69 | 70 | # common untrusted files 71 | file(GLOB ES_CPPSRCS ${CMAKE_CURRENT_SOURCE_DIR}/untrusted/*.cpp) 72 | file(GLOB ES_SERVER_CPPSRCS ${CMAKE_CURRENT_SOURCE_DIR}/server/*.cpp) 73 | 74 | # Generate the untrusted targets 75 | set(ES_SERVER_USRCS ${ES_CPPSRCS} ${ES_SERVER_CPPSRCS} ${ES_PROTO_SRCS} ${ES_GRPC_SRCS}) 76 | include_directories( 77 | ${CMAKE_SOURCE_DIR} 78 | ${CMAKE_CURRENT_SOURCE_DIR} 79 | ${CMAKE_CURRENT_BINARY_DIR} 80 | ${CMAKE_BINARY_DIR} 81 | ${TEE_TOP_DIR}/sdk 82 | ${TEE_TOP_DIR}/sdk/include 83 | ${TEE_TOP_DIR}/third_party/rapidjson/include 84 | ) 85 | set(ES_SERVER_APP enclave_service_server) 86 | add_untrusted_executable( 87 | ${ES_SERVER_APP} 88 | SRCS ${ES_SERVER_USRCS} 89 | EDL ${ES_EDL} 90 | EDL_SEARCH_PATHS ${EX_EDL_SEARCH_PATHS} 91 | ) 92 | target_link_libraries( 93 | ${ES_SERVER_APP} 94 | -L${LIBRARY_OUTPUT_PATH} -L${SGX_LIBRARY_DIR} -L${SGXSSL_LIB} 95 | -L/usr/lib64 -L/usr/local/lib64 96 | -lprotobuf 97 | gRPC::grpc++_reflection 98 | -Wl,--start-group -lukubetee -lchallenger -lsgx_usgxssl -lcrypto -Wl,--end-group 99 | -Wl,-rpath=.:/lib64:/usr/lib:/usr/local/lib:/usr/local/lib64:${SGX_LIBRARY_DIR} 100 | ) 101 | add_dependencies(${ES_SERVER_APP} ukubetee challenger) 102 | 103 | # Generate the untrusted cli test targets 104 | file(GLOB ES_CLIENT_CPPSRCS ${CMAKE_CURRENT_SOURCE_DIR}/client/*.cpp) 105 | set(ES_CLIENT_USRCS ${ES_CPPSRCS} ${ES_CLIENT_CPPSRCS} ${ES_PROTO_SRCS} ${ES_GRPC_SRCS}) 106 | include_directories( 107 | ${CMAKE_SOURCE_DIR} 108 | ${CMAKE_CURRENT_SOURCE_DIR} 109 | ${CMAKE_CURRENT_BINARY_DIR} 110 | ${CMAKE_BINARY_DIR} 111 | ${TEE_TOP_DIR}/sdk 112 | ${TEE_TOP_DIR}/sdk/include 113 | ${TEE_TOP_DIR}/third_party/rapidjson/include 114 | ) 115 | set(ES_CLIENT_APP enclave_service_client) 116 | add_untrusted_executable( 117 | ${ES_CLIENT_APP} 118 | SRCS ${ES_CLIENT_USRCS} 119 | EDL ${ES_EDL} 120 | EDL_SEARCH_PATHS ${EX_EDL_SEARCH_PATHS} 121 | ) 122 | target_link_libraries( 123 | ${ES_CLIENT_APP} 124 | -L${LIBRARY_OUTPUT_PATH} -L${SGX_LIBRARY_DIR} -L${SGXSSL_LIB} 125 | -L/usr/lib64 -L/usr/local/lib64 126 | -lprotobuf 127 | gRPC::grpc++_reflection 128 | -Wl,--start-group -lukubetee -lchallenger -lsgx_usgxssl -lcrypto -Wl,--end-group 129 | -Wl,-rpath=.:/lib64:/usr/lib:/usr/local/lib:/usr/local/lib64:${SGX_LIBRARY_DIR} 130 | ) 131 | add_dependencies(${ES_CLIENT_APP} ukubetee challenger) 132 | -------------------------------------------------------------------------------- /enclave_service/client/untrusted_enclave_service_client_main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include "tee/common/log.h" 4 | #include "tee/untrusted/enclave/untrusted_enclave.h" 5 | 6 | #include "untrusted/untrusted_enclave_service_client.h" 7 | #include "untrusted/untrusted_enclave_service_server.h" 8 | 9 | #define ENCLAVE_FILENAME "enclave_service.signed.so" 10 | 11 | int SGX_CDECL main(int argc, char** argv) { 12 | if (argc < 3) { 13 | printf("Usage: %s [args ...]\n", argv[0]); 14 | return TEE_ERROR_PARAMETERS; 15 | } 16 | 17 | // Create and initialize the enclave 18 | std::string enclave_name = "EnclaveServiceClient"; 19 | EnclaveInstance* enclave = EnclavesManager::GetInstance().CreateEnclave( 20 | enclave_name, ENCLAVE_FILENAME); 21 | if (!enclave) { 22 | printf("Fail to create enclave\n"); 23 | return TEE_ERROR_CREATE_ENCLAVE; 24 | } 25 | 26 | // Call the remote trusted function 27 | tee::PbTeeRunRemoteRequest req; 28 | tee::PbTeeRunRemoteResponse res; 29 | req.set_function_name(argv[1]); 30 | for (int i = 2; i < argc; i++) { 31 | req.mutable_function_param()->add_argv(argv[i]); 32 | } 33 | 34 | tee::untrusted::EnclaveServiceClient es_client(enclave); 35 | TeeErrorCode ret = es_client.TeeRunRemote(&req, &res); 36 | if (res.result().result_size()) { 37 | printf("Result: %s\n", res.result().result()[0].c_str()); 38 | } 39 | 40 | return ret; 41 | } 42 | -------------------------------------------------------------------------------- /enclave_service/proto/enclave_service.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto2"; 2 | 3 | import "kubetee.proto"; 4 | 5 | package tee; 6 | 7 | service EnclaveService { 8 | rpc TeeRunRemote(PbTeeRunRemoteRequest) 9 | returns (PbTeeRunRemoteResponse) { 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /enclave_service/server/untrusted_enclave_service_server_main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include 4 | 5 | #include "tee/common/log.h" 6 | #include "tee/untrusted/enclave/untrusted_enclave.h" 7 | 8 | #include "untrusted/untrusted_enclave_service_server.h" 9 | 10 | #define ENCLAVE_FILENAME "enclave_service.signed.so" 11 | 12 | static EnclaveInstance* g_enclave = nullptr; 13 | 14 | void sig_handler(int signum) { 15 | if (signum == SIGINT) { 16 | EnclavesManager::GetInstance().DestroyEnclave(g_enclave); 17 | exit(signum); 18 | } 19 | } 20 | 21 | int SGX_CDECL main(void) { 22 | // Create and initialize the enclave 23 | std::string enclave_name = "EnclaveServiceServer"; 24 | g_enclave = EnclavesManager::GetInstance().CreateEnclave(enclave_name, 25 | ENCLAVE_FILENAME); 26 | if (!g_enclave) { 27 | return TEE_ERROR_CREATE_ENCLAVE; 28 | } 29 | 30 | signal(SIGINT, sig_handler); 31 | 32 | // Initialize the enclave service server 33 | tee::untrusted::EnclaveServiceServer es_server; 34 | TeeErrorCode ret = es_server.InitServer(g_enclave); 35 | if (ret != TEE_SUCCESS) { 36 | return ret; 37 | } 38 | 39 | // Run as enclave service server and wait for the sync requests 40 | return es_server.RunServer(); 41 | } 42 | -------------------------------------------------------------------------------- /enclave_service/trusted/enclave.config.xml: -------------------------------------------------------------------------------- 1 | 2 | 0 3 | 0 4 | 0x40000 5 | 0x100000 6 | 10 7 | 1 8 | 9 | 0 10 | 0 11 | 0xFFFFFFFF 12 | 13 | -------------------------------------------------------------------------------- /enclave_service/trusted/enclave_private.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN RSA PRIVATE KEY----- 2 | MIIG4gIBAAKCAYEAroOogvsj/fZDZY8XFdkl6dJmky0lRvnWMmpeH41Bla6U1qLZ 3 | AmZuyIF+mQC/cgojIsrBMzBxb1kKqzATF4+XwPwgKz7fmiddmHyYz2WDJfAjIveJ 4 | ZjdMjM4+EytGlkkJ52T8V8ds0/L2qKexJ+NBLxkeQLfV8n1mIk7zX7jguwbCG1Pr 5 | nEMdJ3Sew20vnje+RsngAzdPChoJpVsWi/K7cettX/tbnre1DL02GXc5qJoQYk7b 6 | 3zkmhz31TgFrd9VVtmUGyFXAysuSAb3EN+5VnHGr0xKkeg8utErea2FNtNIgua8H 7 | ONfm9Eiyaav1SVKzPHlyqLtcdxH3I8Wg7yqMsaprZ1n5A1v/levxnL8+It02KseD 8 | 5HqV4rf/cImSlCt3lpRg8U5E1pyFQ2IVEC/XTDMiI3c+AR+w2jSRB3Bwn9zJtFlW 9 | KHG3m1xGI4ck+Lci1JvWWLXQagQSPtZTsubxTQNx1gsgZhgv1JHVZMdbVlAbbRMC 10 | 1nSuJNl7KPAS/VfzAgEDAoIBgHRXxaynbVP5gkO0ug6Qw/E27wzIw4SmjsxG6Wpe 11 | K7kfDeRskKxESdsA/xCrKkwGwhcx1iIgS5+Qscd1Yg+1D9X9asd/P7waPmWoZd+Z 12 | AhlKwhdPsO7PiF3e1AzHhGQwsUTt/Y/aSI1MpHBvy2/s1h9mFCslOUxTmWw0oj/Q 13 | ldIEgWeNR72CE2+jFIJIyml6ftnb6qzPiga8Bm48ubKh0kvySOqnkmnPzgh+JBD6 14 | JnBmtZbfPT97bwTT+N6rnPqOOApvfHPf15kWI8yDbprG1l4OCUaIUH1AszxLd826 15 | 5IPM+8gINLRDP1MA6azECPjTyHXhtnSIBZCyWSVkc05vYmNXYUNiXWMajcxW9M02 16 | wKzFELO8NCEAkaTPxwo4SCyIjUxiK1LbQ9h8PSy4c1+gGP4LAMR8xqP4QKg6zdu9 17 | osUGG/xRe/uufgTBFkcjqBHtK5L5VI0jeNIUAgW/6iNbYXjBMJ0GfauLs+g1VsOm 18 | WfdgXzsb9DYdMa0OXXHypmV4GwKBwQDUwQj8RKJ6c8cT4vcWCoJvJF00+RFL+P3i 19 | Gx2DLERxRrDa8AVGfqaCjsR+3vLgG8V/py+z+dxZYSqeB80Qeo6PDITcRKoeAYh9 20 | xlT3LJOS+k1cJcEmlbbO2IjLkTmzSwa80fWexKu8/Xv6vv15gpqYl1ngYoqJM3pd 21 | vzmTIOi7MKSZ0WmEQavrZj8zK4endE3v0eAEeQ55j1GImbypSf7Idh7wOXtjZ7WD 22 | Dg6yWDrri+AP/L3gClMj8wsAxMV4ZR8CgcEA0fzDHkFa6raVOxWnObmRoDhAtE0a 23 | cjUj976NM5yyfdf2MrKy4/RhdTiPZ6b08/lBC/+xRfV3xKVGzacm6QjqjZrUpgHC 24 | 0LKiZaMtccCJjLtPwQd0jGQEnKfMFaPsnhOc5y8qVkCzVOSthY5qhz0XNotHHFmJ 25 | gffVgB0iqrMTvSL7IA2yqqpOqNRlhaYhNl8TiFP3gIeMtVa9rZy31JPgT2uJ+kfo 26 | gV7sdTPEjPWZd7OshGxWpT6QfVDj/T9T7L6tAoHBAI3WBf2DFvxNL2KXT2QHAZ9t 27 | k3imC4f7U+wSE6zILaDZyzygA4RUbwG0gv8/TJVn2P/Eynf76DuWHGlaiLWnCbSz 28 | Az2DHBQBBaku409zDQym3j1ugMRjzzSQWzJg0SIyBH3hTmnYcn3+Uqcp/lEBvGW6 29 | O+rsXFt3pukqJmIV8HzLGGaLm62BHUeZf3dyWm+i3p/hQAL7Xvu04QW70xuGqdr5 30 | afV7p5eaeQIJXyGQJ0eylV/90+qxjMKiB1XYg6WYvwKBwQCL/ddpgOdHJGN8uRom 31 | e7Zq0Csi3hGheMKlKbN3vcxT5U7MdyHtTZZOJbTvxKNNUNYH/8uD+PqDGNneb29G 32 | BfGzvI3EASyLIcGZF3OhKwZd0jUrWk2y7Vhob91jwp2+t73vdMbkKyI4mHOuXvGv 33 | fg95si9oO7EBT+Oqvhccd2J+F1IVXncccYnF4u5ZGWt5lLewN/pVr7MjjykeaHqN 34 | t+rfnQam2psA6fL4zS2zTmZPzR2tnY8Y1GBTi0Ko1OKd1HMCgcAb5cB/7/AQlhP9 35 | yQa04PLH9ygQkKKptZp7dy5WcWRx0K/hAHRoi2aw1wZqfm7VBNu2SLcs90kCCCxp 36 | 6C5sfJi6b8NpNbIPC+sc9wsFr7pGo9SFzQ78UlcWYK2Gu2FxlMjonhka5hvo4zvg 37 | WxlpXKEkaFt3gLd92m/dMqBrHfafH7VwOJY2zT3WIpjwuk0ZzmRg5p0pG/svVQEH 38 | NZmwRwlopysbR69B/n1nefJ84UO50fLh5s5Zr3gBRwbWNZyzhXk= 39 | -----END RSA PRIVATE KEY----- 40 | -------------------------------------------------------------------------------- /enclave_service/trusted/enclave_service.edl: -------------------------------------------------------------------------------- 1 | /* Enclave.edl - Top EDL file. */ 2 | 3 | enclave { 4 | from "sgx_tsgxssl.edl" import *; 5 | from "kubetee.edl" import *; 6 | }; 7 | -------------------------------------------------------------------------------- /enclave_service/trusted/enclave_service.lds: -------------------------------------------------------------------------------- 1 | enclave.so 2 | { 3 | global: 4 | g_global_data_sim; 5 | g_global_data; 6 | enclave_entry; 7 | g_peak_heap_used; 8 | local: 9 | *; 10 | }; 11 | -------------------------------------------------------------------------------- /enclave_service/trusted/trusted_enclave_service.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include "./sgx_trts.h" 5 | 6 | #include "tee/common/aes.h" 7 | #include "tee/common/bytes.h" 8 | #include "tee/common/challenger.h" 9 | #include "tee/common/envelope.h" 10 | #include "tee/common/error.h" 11 | #include "tee/common/log.h" 12 | #include "tee/common/rsa.h" 13 | #include "tee/common/type.h" 14 | #include "tee/trusted/trusted_pbcall.h" 15 | #include "tee/trusted/utils/trusted_seal.h" 16 | 17 | #include "./kubetee.pb.h" 18 | 19 | #include "./enclave_service_t.h" 20 | 21 | using tee::common::DigitalEnvelope; 22 | using tee::trusted::TeeInstance; 23 | 24 | #ifdef __cplusplus 25 | extern "C" { 26 | #endif 27 | 28 | /// \brief This is demo trusted PbFunction to simple return the SHA256 29 | /// 30 | /// To implement more complex PbFunctions, please refer to the header files 31 | /// in sdk/include/tee folder 32 | /// 33 | TeeErrorCode TeeGetSHA256(const std::string& req_str, std::string* res_str) { 34 | tee::PbGenericRequest req; 35 | tee::PbGenericResponse res; 36 | PB_PARSE(req, req_str); 37 | 38 | std::string data_str = req.argv()[0]; 39 | if (data_str.empty()) { 40 | ELOG_ERROR("Empty data for getting SHA256"); 41 | return TEE_ERROR_PARAMETERS; 42 | } 43 | 44 | tee::common::DataBytes data_bytes(data_str); 45 | res.add_result(data_bytes.ToSHA256().ToHexStr().GetStr()); 46 | ELOG_DEBUG("SHA256 result: %s", data_bytes.GetStr().c_str()); 47 | PB_SERIALIZE(res, res_str); 48 | return TEE_SUCCESS; 49 | } 50 | 51 | TeeErrorCode RegisterTrustedPbFunctionsEx() { 52 | ELOG_DEBUG("Register application trusted protobuf call functions"); 53 | ADD_TRUSTED_PBCALL_FUNCTION(TeeGetSHA256); 54 | return TEE_SUCCESS; 55 | } 56 | 57 | #ifdef __cplusplus 58 | } 59 | #endif 60 | -------------------------------------------------------------------------------- /enclave_service/untrusted/untrusted_enclave_service_client.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | #include "tee/common/error.h" 10 | #include "tee/common/log.h" 11 | #include "tee/common/type.h" 12 | #include "tee/untrusted/untrusted_config.h" 13 | #include "tee/untrusted/utils/untrusted_fs.h" 14 | 15 | #include "untrusted/untrusted_enclave_service_client.h" 16 | 17 | namespace tee { 18 | namespace untrusted { 19 | 20 | EnclaveServiceClient::EnclaveServiceClient(EnclaveInstance* enclave) { 21 | // Prepare the client stub based on secure channel 22 | std::string server = GET_CONF_STR(kConfRpcServer); 23 | std::string port = GET_CONF_STR(kConfRpcPort); 24 | std::string ca = GetFsString(GET_CONF_STR(kConfRpcCaPath)); 25 | std::string key = GetFsString(GET_CONF_STR(kConfRpcKeyPath)); 26 | std::string cert = GetFsString(GET_CONF_STR(kConfRpcCertPath)); 27 | std::string endpoint = server + ":" + port; 28 | stub_ = PrepareSecureStub(endpoint, ca, key, cert); 29 | 30 | // Initialize the enclave IAS report if it's not ready 31 | enclave_ = enclave; 32 | if (enclave_->GetLocalIasReport().b64_signature().empty()) { 33 | TEE_LOG_INFO("Fetch IAS report when initialize enclave service client"); 34 | enclave_->FetchIasReport(); 35 | } 36 | } 37 | 38 | bool EnclaveServiceClient::WaitForChannelReady( 39 | std::shared_ptr channel) { 40 | using std::chrono::system_clock; 41 | grpc_connectivity_state state; 42 | while ((state = channel->GetState(true)) != GRPC_CHANNEL_READY) { 43 | system_clock::time_point now = system_clock::now(); 44 | system_clock::time_point end = now + std::chrono::milliseconds(kTimeoutMs); 45 | if (!channel->WaitForStateChange(state, end)) { 46 | return false; 47 | } 48 | } 49 | return true; 50 | } 51 | 52 | std::unique_ptr EnclaveServiceClient::PrepareSecureStub( 53 | const std::string& ep, const std::string& ca, const std::string& key, 54 | const std::string& cert) { 55 | grpc::SslCredentialsOptions ssl_opts; 56 | ssl_opts.pem_root_certs = ca; 57 | ssl_opts.pem_private_key = key; 58 | ssl_opts.pem_cert_chain = cert; 59 | 60 | auto ssl_creds = grpc::SslCredentials(ssl_opts); 61 | auto channel_args = grpc::ChannelArguments(); 62 | 63 | // For our generated certificates CN. 64 | constexpr char kSelfSignedCN[] = "enclave-service"; 65 | channel_args.SetSslTargetNameOverride(kSelfSignedCN); 66 | 67 | // Return a channel using the credentials created in the previous step. 68 | auto channel = grpc::CreateCustomChannel(ep, ssl_creds, channel_args); 69 | 70 | if (!WaitForChannelReady(channel)) 71 | throw std::runtime_error("Secure channel not ready."); 72 | 73 | return EnclaveService::NewStub(channel); 74 | } 75 | 76 | TeeErrorCode EnclaveServiceClient::CheckStatusCode(const Status& status) { 77 | if (!status.ok()) { 78 | TEE_LOG_ERROR("Status Code: %d", status.error_code()); 79 | TEE_LOG_ERROR("Error Message: %s", status.error_message().c_str()); 80 | return TEE_ERROR_UNEXPECTED; 81 | } 82 | return TEE_SUCCESS; 83 | } 84 | 85 | TeeErrorCode EnclaveServiceClient::GetClientRaAuthentication( 86 | RaReportAuthentication* auth) { 87 | auth->mutable_ias_report()->CopyFrom(enclave_->GetLocalIasReport()); 88 | auth->set_public_key(enclave_->GetPublicKey()); 89 | return TEE_SUCCESS; 90 | } 91 | 92 | TeeErrorCode EnclaveServiceClient::TeeRunRemote( 93 | PbTeeRunRemoteRequest* request, PbTeeRunRemoteResponse* response) { 94 | ClientContext context; 95 | context.set_deadline(std::chrono::system_clock::now() + 96 | std::chrono::milliseconds(kTimeoutMs)); 97 | 98 | TEE_CHECK_RETURN(GetClientRaAuthentication(request->mutable_ra_auth())); 99 | Status status = stub_->TeeRunRemote(&context, *request, response); 100 | 101 | return CheckStatusCode(status); 102 | } 103 | 104 | } // namespace untrusted 105 | } // namespace tee 106 | -------------------------------------------------------------------------------- /enclave_service/untrusted/untrusted_enclave_service_client.h: -------------------------------------------------------------------------------- 1 | #ifndef ENCLAVE_SERVICE_UNTRUSTED_UNTRUSTED_ENCLAVE_SERVICE_CLIENT_H_ 2 | #define ENCLAVE_SERVICE_UNTRUSTED_UNTRUSTED_ENCLAVE_SERVICE_CLIENT_H_ 3 | 4 | #include 5 | 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | 12 | #include "tee/common/error.h" 13 | #include "tee/common/log.h" 14 | #include "tee/common/type.h" 15 | #include "tee/untrusted/enclave/untrusted_enclave.h" 16 | 17 | #include "./enclave_service.grpc.pb.h" 18 | #include "./enclave_service.pb.h" 19 | 20 | using grpc::Channel; 21 | using grpc::ClientContext; 22 | using grpc::Status; 23 | 24 | using tee::EnclaveService; 25 | using tee::IasReport; 26 | using tee::PbGenericRequest; 27 | using tee::PbGenericResponse; 28 | using tee::PbTeeRunRemoteRequest; 29 | using tee::PbTeeRunRemoteResponse; 30 | using tee::RaReportAuthentication; 31 | 32 | namespace tee { 33 | namespace untrusted { 34 | 35 | constexpr int kTimeoutMs = 4000; 36 | 37 | class EnclaveServiceClient { 38 | public: 39 | explicit EnclaveServiceClient(EnclaveInstance* enclave); 40 | ~EnclaveServiceClient() {} 41 | 42 | std::unique_ptr PrepareSecureStub( 43 | const std::string& ep, const std::string& ca, const std::string& key, 44 | const std::string& cert); 45 | 46 | TeeErrorCode TeeRunRemote(PbTeeRunRemoteRequest* request, 47 | PbTeeRunRemoteResponse* response); 48 | 49 | private: 50 | TeeErrorCode GetClientRaAuthentication(RaReportAuthentication* auth); 51 | bool WaitForChannelReady(std::shared_ptr channel); 52 | TeeErrorCode CheckStatusCode(const Status& status); 53 | 54 | EnclaveInstance* enclave_; 55 | std::unique_ptr stub_; 56 | }; 57 | 58 | } // namespace untrusted 59 | } // namespace tee 60 | 61 | #endif // ENCLAVE_SERVICE_UNTRUSTED_UNTRUSTED_ENCLAVE_SERVICE_CLIENT_H_ 62 | -------------------------------------------------------------------------------- /enclave_service/untrusted/untrusted_enclave_service_server.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #include "tee/common/aes.h" 6 | #include "tee/common/challenger.h" 7 | #include "tee/common/protobuf.h" 8 | #include "tee/common/rsa.h" 9 | 10 | #include "tee/untrusted/enclave/untrusted_enclave.h" 11 | #include "tee/untrusted/ra/untrusted_challenger.h" 12 | #include "tee/untrusted/ra/untrusted_ias.h" 13 | #include "tee/untrusted/untrusted_config.h" 14 | #include "tee/untrusted/untrusted_pbcall.h" 15 | #include "tee/untrusted/utils/untrusted_fs.h" 16 | #include "tee/untrusted/utils/untrusted_json.h" 17 | 18 | #include "untrusted/untrusted_enclave_service_client.h" 19 | #include "untrusted/untrusted_enclave_service_server.h" 20 | 21 | #include "./enclave_service_u.h" 22 | 23 | namespace tee { 24 | namespace untrusted { 25 | 26 | TeeErrorCode EnclaveServiceServerImpl::CheckRaAuthentication( 27 | const RaReportAuthentication& auth) { 28 | TEE_CHECK_RETURN(VerifyRaReport(auth.public_key(), auth.ias_report())); 29 | return TEE_SUCCESS; 30 | } 31 | 32 | TeeErrorCode EnclaveServiceServerImpl::GetServerRaAuthentication( 33 | RaReportAuthentication* auth) { 34 | auth->mutable_ias_report()->CopyFrom(enclave_->GetLocalIasReport()); 35 | auth->set_public_key(enclave_->GetPublicKey()); 36 | return TEE_SUCCESS; 37 | } 38 | 39 | Status EnclaveServiceServerImpl::TeeRunRemote( 40 | ServerContext* context, const PbTeeRunRemoteRequest* request, 41 | PbTeeRunRemoteResponse* response) { 42 | GRPC_INTERFACE_ENTER_DEBUG(); 43 | 44 | // Check the RA report or signature authentication 45 | if (CheckRaAuthentication(request->ra_auth()) != TEE_SUCCESS) { 46 | RETURN_ERROR("Fail to verify the authentication"); 47 | } 48 | 49 | // Call the trusted function 50 | TeeErrorCode ret = enclave_->TeeRun(request->function_name(), *request, 51 | response->mutable_result()); 52 | if (ret != TEE_SUCCESS) { 53 | RETURN_ERROR("Fail to run trusted function"); 54 | } 55 | 56 | // Prepare response with server's RA report and public key 57 | RaReportAuthentication* server_ra_auth = response->mutable_ra_auth(); 58 | if (GetServerRaAuthentication(server_ra_auth) != TEE_SUCCESS) { 59 | RETURN_ERROR("Fail to load server RA report"); 60 | } 61 | 62 | return Status::OK; 63 | } 64 | 65 | TeeErrorCode EnclaveServiceServerImpl::Initialize(EnclaveInstance* enclave) { 66 | enclave_ = enclave; 67 | 68 | // Check the server IAS report 69 | if (enclave_->GetLocalIasReport().b64_signature().empty()) { 70 | TEE_LOG_ERROR("Invalid server enclave identity public key"); 71 | return TEE_ERROR_ENCLAVE_NOTINITIALIZED; 72 | } 73 | 74 | // Check the server identity publick key 75 | if (enclave_->GetPublicKey().empty()) { 76 | TEE_LOG_ERROR("Invalid server enclave identity public key"); 77 | return TEE_ERROR_ENCLAVE_NOTINITIALIZED; 78 | } 79 | return TEE_SUCCESS; 80 | } 81 | 82 | TeeErrorCode EnclaveServiceServer::InitServer(EnclaveInstance* enclave) { 83 | // Set and check the enclave instance 84 | enclave_ = enclave; 85 | if (enclave_ == 0) { 86 | TEE_LOG_ERROR("Invalid enclave ID on which to run RPC server"); 87 | return TEE_ERROR_PARAMETERS; 88 | } 89 | 90 | // Load configurations 91 | rpc_port_ = GET_CONF_STR(kConfRpcPort); 92 | 93 | std::string cert = GET_CONF_STR(kConfRpcCertPath); 94 | std::string key = GET_CONF_STR(kConfRpcKeyPath); 95 | std::string ca = GET_CONF_STR(kConfRpcCaPath); 96 | 97 | TeeErrorCode ret = tee::untrusted::FsReadString(cert, &ssl_cert_); 98 | if (ret != TEE_SUCCESS) { 99 | TEE_LOG_ERROR("Fail to load ssl cert file: %s", cert.c_str()); 100 | return ret; 101 | } 102 | ret = tee::untrusted::FsReadString(key, &ssl_key_); 103 | if (ret != TEE_SUCCESS) { 104 | TEE_LOG_ERROR("Fail to load ssl key file: %s", key.c_str()); 105 | return ret; 106 | } 107 | ret = tee::untrusted::FsReadString(ca, &ssl_ca_); 108 | if (ret != TEE_SUCCESS) { 109 | TEE_LOG_ERROR("Fail to load ssl ca file: %s", ca.c_str()); 110 | return ret; 111 | } 112 | 113 | // Always generate new IAS report when start the service 114 | ret = enclave_->FetchIasReport(false); 115 | if (ret != TEE_SUCCESS) { 116 | TEE_LOG_ERROR("Fail to initialize the local RA report: 0x%x", ret); 117 | return ret; 118 | } 119 | 120 | // Try to initialize the rpc server implement instance. 121 | // Must before SyncIdentity because we will use the server ias_report 122 | // which is initialized in this process. 123 | ret = service_impl_.Initialize(enclave_); 124 | if (ret != TEE_SUCCESS) { 125 | TEE_LOG_ERROR("Fail to initialize the RPC server implement instance"); 126 | return ret; 127 | } 128 | 129 | return TEE_SUCCESS; 130 | } 131 | 132 | TeeErrorCode EnclaveServiceServer::RunServer() { 133 | // Listen on the given address with authentication mechanism. 134 | SslServerCredentialsOptions::PemKeyCertPair keycert{ssl_key_, ssl_cert_}; 135 | grpc::SslServerCredentialsOptions ssl_opts; 136 | ssl_opts.pem_root_certs = ssl_ca_; 137 | ssl_opts.pem_key_cert_pairs.push_back(keycert); 138 | ssl_opts.client_certificate_request = 139 | GRPC_SSL_REQUEST_AND_REQUIRE_CLIENT_CERTIFICATE_AND_VERIFY; 140 | 141 | ServerBuilder builder; 142 | std::string server_addr = "0.0.0.0:" + rpc_port_; 143 | builder.AddListeningPort(server_addr, grpc::SslServerCredentials(ssl_opts)); 144 | // Register "EnclaveServiceServerImpl" as the instance through which we'll 145 | // communicate with clients. In this case it corresponds to an 146 | // *synchronous* service. 147 | builder.RegisterService(&service_impl_); 148 | // Finally assemble the server. 149 | std::unique_ptr server(builder.BuildAndStart()); 150 | TEE_LOG_INFO("Server listening on %s", server_addr.c_str()); 151 | 152 | // Wait for the server to shutdown. Note that some other thread must be 153 | // responsible for shutting down the server for this call to ever return. 154 | server->Wait(); 155 | return TEE_SUCCESS; 156 | } 157 | 158 | } // namespace untrusted 159 | } // namespace tee 160 | -------------------------------------------------------------------------------- /enclave_service/untrusted/untrusted_enclave_service_server.h: -------------------------------------------------------------------------------- 1 | #ifndef ENCLAVE_SERVICE_UNTRUSTED_UNTRUSTED_ENCLAVE_SERVICE_SERVER_H_ 2 | #define ENCLAVE_SERVICE_UNTRUSTED_UNTRUSTED_ENCLAVE_SERVICE_SERVER_H_ 3 | 4 | #include 5 | 6 | #include "tee/common/error.h" 7 | #include "tee/common/type.h" 8 | #include "tee/untrusted/enclave/untrusted_enclave.h" 9 | 10 | #include "grpcpp/grpcpp.h" 11 | 12 | #include "./enclave_service.grpc.pb.h" 13 | #include "./enclave_service.pb.h" 14 | 15 | using grpc::Server; 16 | using grpc::ServerBuilder; 17 | using grpc::ServerContext; 18 | using grpc::SslServerCredentialsOptions; 19 | using grpc::Status; 20 | 21 | using tee::EnclaveService; 22 | 23 | #define RETURN_ERROR(msg) \ 24 | do { \ 25 | TEE_LOG_ERROR(msg); \ 26 | return Status(grpc::StatusCode::INTERNAL, msg); \ 27 | } while (0) 28 | 29 | #define GRPC_INTERFACE_ENTER_DEBUG() \ 30 | TEE_LOG_DEBUG("GRPC SERVER INTERFACE:%s", __FUNCTION__) 31 | 32 | namespace tee { 33 | namespace untrusted { 34 | 35 | class EnclaveServiceServerImpl final : public EnclaveService::Service { 36 | public: 37 | TeeErrorCode Initialize(EnclaveInstance* enclave); 38 | 39 | Status TeeRunRemote(ServerContext* context, 40 | const PbTeeRunRemoteRequest* request, 41 | PbTeeRunRemoteResponse* response); 42 | TeeErrorCode GetServerRaAuthentication(RaReportAuthentication* auth); 43 | 44 | private: 45 | TeeErrorCode CheckRaAuthentication(const RaReportAuthentication& auth); 46 | TeeErrorCode CheckSignatureAuthentication(const std::string& data, 47 | const std::string& signature); 48 | 49 | EnclaveInstance* enclave_; 50 | IasReport server_ias_report_; 51 | }; 52 | 53 | class EnclaveServiceServer { 54 | public: 55 | EnclaveServiceServer() : enclave_(nullptr) {} 56 | 57 | TeeErrorCode InitServer(EnclaveInstance* enclave); 58 | TeeErrorCode RunServer(); 59 | 60 | private: 61 | EnclaveServiceServerImpl service_impl_; 62 | EnclaveInstance* enclave_; 63 | std::string rpc_server_; 64 | std::string rpc_port_; 65 | std::string ssl_cert_; 66 | std::string ssl_key_; 67 | std::string ssl_ca_; 68 | }; 69 | 70 | } // namespace untrusted 71 | } // namespace tee 72 | 73 | #endif // ENCLAVE_SERVICE_UNTRUSTED_UNTRUSTED_ENCLAVE_SERVICE_SERVER_H_ 74 | -------------------------------------------------------------------------------- /proto/kubetee.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto2"; 2 | 3 | package tee; 4 | 5 | //////////////////////////////////////////////////////////////// 6 | /// Common Messages 7 | //////////////////////////////////////////////////////////////// 8 | 9 | message KeyPair { 10 | optional string public_key = 1; 11 | optional string private_key = 2; 12 | optional bytes aes_key = 3; 13 | } 14 | 15 | /// AES-GCM symmetric encryption/decryption data 16 | message SymmetricKeyEncrypted { 17 | optional bytes cipher = 1; 18 | optional bytes mac = 2; 19 | optional bytes aad = 3; 20 | optional bytes iv = 4; 21 | } 22 | 23 | /// Digital envelope encryption/decryption data 24 | message DigitalEnvelopeEncrypted { 25 | // symmetric cipher data 26 | optional SymmetricKeyEncrypted aes_cipher = 1; 27 | // RSA public encrypted symmetric key 28 | optional bytes encrypted_key = 2; 29 | // SHA256 hash value 30 | optional bytes plain_hash = 3; 31 | // RSA private key sign the above plain HASH value 32 | // The public key in RA report will verify this signature 33 | optional bytes plain_hash_sig = 4; 34 | } 35 | 36 | /// Store the IAS response data 37 | message IasReport { 38 | optional string b64_signature = 1; 39 | optional string signing_cert = 2; 40 | optional string advisory_url = 3; 41 | optional string advisory_ids = 4; 42 | optional string response_body = 5; 43 | optional string epid_pseudonym = 6; 44 | optional string quote_status = 7; 45 | optional string b16_platform_info_blob = 8; 46 | optional string b64_quote_body = 9; 47 | } 48 | 49 | /// Authentication by RA report 50 | message RaReportAuthentication { 51 | optional IasReport ias_report = 1; 52 | optional string public_key = 2; 53 | } 54 | 55 | /// Authentication by RSA private key signature 56 | message SignatureAuthentication { 57 | optional bytes signature = 1; 58 | optional bytes data = 2; 59 | } 60 | 61 | /// Enclave Information, which also used as enclave macch rule 62 | message EnclaveInformation { 63 | // Hex string enclave hash measurement 64 | optional string hex_mrenclave = 1; 65 | // Hex string enclave signer measurement 66 | optional string hex_mrsigner = 2; 67 | // Product ID 68 | optional string hex_prod_id = 3; 69 | // Minimal ISV SVN [optional] 70 | optional string hex_min_isvsvn = 4; 71 | // userdata 72 | optional string hex_user_data = 5; 73 | // 64 bytes spid 74 | optional string hex_spid = 6; 75 | } 76 | 77 | /// Enclave match rules are used when verify the RA report. 78 | /// For example, use mrsigner and prod_id to trust all the enclaves 79 | /// of this ProdID/MRSIGNER. And multi-rules are allowed. 80 | message EnclaveMatchRules { 81 | repeated EnclaveInformation entries = 1; 82 | } 83 | 84 | //////////////////////////////////////////////////////////////// 85 | /// PbFunction Messages 86 | //////////////////////////////////////////////////////////////// 87 | 88 | /// PbFunction call attributes 89 | message PbCallAttributes { 90 | optional int64 enclave_id = 1; 91 | optional string enclave_name = 2; 92 | optional string function_name = 3; 93 | } 94 | 95 | /// Define a default request type for PbFunctions 96 | message PbGenericRequest { 97 | repeated bytes argv = 1; 98 | } 99 | 100 | /// Define a default response type for PbFunctions 101 | message PbGenericResponse { 102 | repeated bytes result = 1; 103 | } 104 | 105 | /// Request for InitializeEnclave Trusted PbFunction 106 | message PbInitializeEnclaveRequest { 107 | optional int64 enclave_id = 1; 108 | optional string enclave_name = 2; 109 | // sealed KeyPair identity keys 110 | optional bytes sealed_identity = 3; 111 | optional bytes target_info = 4; 112 | optional bytes user_data = 5; 113 | optional string hex_spid = 6; 114 | } 115 | 116 | /// Response for InitializeEnclave Trusted PbFunction 117 | message PbInitializeEnclaveResponse { 118 | optional string enclave_public_key = 1; 119 | // only exists when new KeyPair identity keys are created 120 | optional bytes enclave_identity = 2; 121 | optional bytes enclave_report = 3; 122 | optional EnclaveInformation enclave_info = 4; 123 | } 124 | 125 | /// Request for remote trusted function call 126 | /// If the client is a enclave node, Ra report is used as authentication. 127 | /// If the client is a normal node, Signature is used as authentication. 128 | message PbTeeRunRemoteRequest { 129 | optional RaReportAuthentication ra_auth = 1; 130 | optional SignatureAuthentication sig_auth = 2; 131 | optional string function_name = 3; 132 | optional PbGenericRequest function_param = 4; 133 | } 134 | 135 | /// Response for remote trusted function call 136 | /// RaReportAuthentication should be verified before use the result. 137 | message PbTeeRunRemoteResponse { 138 | optional RaReportAuthentication ra_auth = 1; 139 | optional PbGenericResponse result = 2; 140 | } 141 | 142 | -------------------------------------------------------------------------------- /sdk/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | set(TOP_SRC_DIR ${CMAKE_CURRENT_SOURCE_DIR}) 2 | 3 | set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra") 4 | 5 | add_subdirectory(trusted) 6 | add_subdirectory(untrusted) 7 | add_subdirectory(untrusted/challenger) 8 | -------------------------------------------------------------------------------- /sdk/common/aes.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include "openssl/aes.h" 4 | #include "openssl/evp.h" 5 | 6 | #include "tee/common/aes.h" 7 | #include "tee/common/bytes.h" 8 | #include "tee/common/error.h" 9 | #include "tee/common/log.h" 10 | #include "tee/common/type.h" 11 | 12 | namespace tee { 13 | namespace common { 14 | 15 | // Reference here:https://wiki.openssl.org/ 16 | // index.php/EVP_Authenticated_Encryption_and_Decryption 17 | 18 | AesGcmCrypto::AesGcmCrypto() { 19 | DataBytes aes_rand_key; 20 | key_ = aes_rand_key.Randomize(kKeySize).GetStr(); 21 | } 22 | 23 | TeeErrorCode AesGcmCrypto::Encrypt(const std::string& plain, 24 | SymmetricKeyEncrypted* cipher) { 25 | if (key_.size() != kKeySize) { 26 | ELOG_ERROR("Invalid key, length = %ld", key_.size()); 27 | return TEE_ERROR_CRYPTO_AES_KEY_INVALID; 28 | } 29 | 30 | if (plain.empty()) { 31 | ELOG_ERROR("Empty plain data for AEC encryption"); 32 | return TEE_ERROR_PARAMETERS; 33 | } 34 | 35 | DataBytes aes_rand_iv; 36 | // If IV is not specified, generate rand bytes for it. 37 | if (cipher->iv().empty()) { 38 | if (aes_rand_iv.Randomize(kIvSize).empty()) { 39 | ELOG_ERROR("Fail to generate AES IV"); 40 | return TEE_ERROR_CRYPTO_AES_IV_GENERATE; 41 | } 42 | cipher->set_iv(aes_rand_iv.GetStr()); 43 | } else if (cipher->iv().size() != kIvSize) { 44 | ELOG_ERROR("Invalid IV length %ld", cipher->iv().size()); 45 | return TEE_ERROR_PARAMETERS; 46 | } 47 | 48 | // Start the AES encryption from here 49 | EVP_CIPHER_CTX* ctx = NULL; 50 | TeeErrorCode ret = TEE_ERROR_CRYPTO_AES_ENCRYPT; 51 | 52 | do { 53 | // Create the context and check 54 | if (!(ctx = EVP_CIPHER_CTX_new())) { 55 | ELOG_ERROR("Fail to create AES cipher context"); 56 | ret = TEE_ERROR_CRYPTO_AES_OUT_OF_MEMORY; 57 | break; 58 | } 59 | 60 | // Initialize encrypt, key and IV 61 | const uint8_t* key = RCAST(const uint8_t*, key_.data()); 62 | const uint8_t* iv = RCAST(const uint8_t*, cipher->iv().data()); 63 | if (!EVP_EncryptInit_ex(ctx, EVP_aes_256_gcm(), NULL, key, iv)) { 64 | ELOG_ERROR("Initialise encrypt, key and IV failed."); 65 | break; 66 | } 67 | 68 | // Provide AAD data if exist 69 | int len = 0; 70 | const uint8_t* aad = RCAST(const uint8_t*, cipher->aad().data()); 71 | const int aad_len = cipher->aad().size(); 72 | if (aad_len && !EVP_EncryptUpdate(ctx, NULL, &len, aad, aad_len)) { 73 | ELOG_ERROR("Provide AAD data failed."); 74 | break; 75 | } 76 | 77 | // Provide the message to be encrypted, and obtain the encrypted output. 78 | const uint8_t* src = RCAST(const uint8_t*, plain.data()); 79 | const int src_len = plain.size(); 80 | std::string* aes_cipher = cipher->mutable_cipher(); 81 | aes_cipher->resize(SCAST(size_t, src_len), '\0'); 82 | uint8_t* dst = RCAST(uint8_t*, CCAST(char*, aes_cipher->data())); 83 | if (!EVP_EncryptUpdate(ctx, dst, &len, src, src_len)) { 84 | ELOG_ERROR("Fail to obtain the encrypted output."); 85 | break; 86 | } 87 | if (len != src_len) { 88 | ELOG_ERROR("Unexpected AES encrypt cipher size"); 89 | break; 90 | } 91 | 92 | // Finalise the encryption. Normally ciphertext bytes may be written at 93 | // this stage, but this does not occur in GCM mode 94 | if (!EVP_EncryptFinal_ex(ctx, dst + len, &len)) { 95 | ELOG_ERROR("Finalise the encryption failed."); 96 | break; 97 | } 98 | if (len != 0) { 99 | ELOG_ERROR("Unexpected AES_GCM encrypt final length"); 100 | break; 101 | } 102 | 103 | // Get mac 104 | std::string* aes_mac = cipher->mutable_mac(); 105 | aes_mac->resize(SCAST(size_t, kMacSize), '\0'); 106 | uint8_t* mac = RCAST(uint8_t*, CCAST(char*, aes_mac->data())); 107 | if (!EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_GET_TAG, kMacSize, mac)) { 108 | ELOG_ERROR("Fail to get mac"); 109 | break; 110 | } 111 | 112 | ret = TEE_SUCCESS; 113 | } while (0); 114 | 115 | // Clean up and return 116 | if (ctx) { 117 | EVP_CIPHER_CTX_free(ctx); 118 | } 119 | return ret; 120 | } 121 | 122 | TeeErrorCode AesGcmCrypto::Decrypt(const SymmetricKeyEncrypted& cipher, 123 | std::string* plain) { 124 | // Check all input parameters 125 | if (key_.size() != kKeySize) { 126 | ELOG_ERROR("Invalid key, length = %ld", key_.size()); 127 | return TEE_ERROR_CRYPTO_AES_KEY_INVALID; 128 | } 129 | if (cipher.cipher().empty()) { 130 | ELOG_ERROR("Invalid AES decryption cipher data"); 131 | return TEE_ERROR_PARAMETERS; 132 | } 133 | if (cipher.iv().size() != kIvSize) { 134 | ELOG_ERROR("Invalid AES decryption IV size: %ld", cipher.iv().size()); 135 | return TEE_ERROR_PARAMETERS; 136 | } 137 | if (cipher.mac().size() != kMacSize) { 138 | ELOG_ERROR("Invalid AES decryption mac size: %ld", cipher.mac().size()); 139 | return TEE_ERROR_PARAMETERS; 140 | } 141 | 142 | // Begin the openssl AES decryption 143 | TeeErrorCode ret = TEE_ERROR_CRYPTO_AES_DECRYPT; 144 | EVP_CIPHER_CTX* ctx = NULL; 145 | 146 | do { 147 | // Create the context and check it 148 | if (!(ctx = EVP_CIPHER_CTX_new())) { 149 | ELOG_ERROR("Fail to create AES cipher context"); 150 | ret = TEE_ERROR_CRYPTO_AES_OUT_OF_MEMORY; 151 | break; 152 | } 153 | 154 | // Initialise decrypt, key and IV 155 | const uint8_t* key = RCAST(uint8_t*, CCAST(char*, key_.data())); 156 | const uint8_t* iv = RCAST(uint8_t*, CCAST(char*, cipher.iv().data())); 157 | if (!EVP_DecryptInit_ex(ctx, EVP_aes_256_gcm(), NULL, key, iv)) { 158 | ELOG_ERROR("Initialise decrypt, key and IV failed."); 159 | break; 160 | } 161 | 162 | // Provide AAD data if exist 163 | int len = 0; 164 | const uint8_t* aad = RCAST(uint8_t*, CCAST(char*, cipher.aad().data())); 165 | const int aad_len = SCAST(int, cipher.aad().size()); 166 | if (aad_len && !EVP_DecryptUpdate(ctx, NULL, &len, aad, aad_len)) { 167 | ELOG_ERROR("Provide AAD data failed."); 168 | break; 169 | } 170 | 171 | // Decrypt message, obtain the plain text output 172 | const uint8_t* src = RCAST(uint8_t*, CCAST(char*, cipher.cipher().data())); 173 | const int src_len = SCAST(int, cipher.cipher().size()); 174 | plain->resize(src_len, '\0'); 175 | uint8_t* dst = RCAST(uint8_t*, CCAST(char*, plain->data())); 176 | if (!EVP_DecryptUpdate(ctx, dst, &len, src, src_len)) { 177 | ELOG_ERROR("Fail to obtain the plain text output"); 178 | break; 179 | } 180 | if (len != src_len) { 181 | ELOG_ERROR("Unexpected AES decrypt plain text size"); 182 | break; 183 | } 184 | 185 | // Update expected mac value 186 | uint8_t* mac = RCAST(uint8_t*, CCAST(char*, cipher.mac().data())); 187 | const int mac_len = SCAST(int, cipher.mac().size()); 188 | if (!EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_TAG, mac_len, mac)) { 189 | ELOG_ERROR("Update expected mac value failed."); 190 | break; 191 | } 192 | 193 | // Finalise the decryption. A positive return value indicates success, 194 | // anything else is a failure - the plain text is not trustworthy. 195 | if (EVP_DecryptFinal_ex(ctx, dst + len, &len) <= 0) { 196 | ELOG_ERROR("Finalise the decryption failed."); 197 | break; 198 | } 199 | if (len != 0) { 200 | ELOG_ERROR("Unexpected AES_GCM decrypt final length"); 201 | break; 202 | } 203 | 204 | ret = TEE_SUCCESS; 205 | } while (0); 206 | 207 | // Clean up and return 208 | if (ctx != NULL) { 209 | EVP_CIPHER_CTX_free(ctx); 210 | } 211 | return ret; 212 | } 213 | 214 | } // namespace common 215 | } // namespace tee 216 | -------------------------------------------------------------------------------- /sdk/common/bytes.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | #include "cppcodec/base64_rfc4648.hpp" 7 | 8 | #include "openssl/err.h" 9 | #include "openssl/rand.h" 10 | #include "openssl/sha.h" 11 | 12 | #include "tee/common/bytes.h" 13 | #include "tee/common/error.h" 14 | #include "tee/common/log.h" 15 | #include "tee/common/type.h" 16 | 17 | namespace tee { 18 | namespace common { 19 | 20 | using base64 = cppcodec::base64_rfc4648; 21 | 22 | uint8_t DataBytes::Hex2Dec(const uint8_t hex) { 23 | if (('0' <= hex) && (hex <= '9')) { 24 | return hex - '0'; 25 | } else if (('a' <= hex) && (hex <= 'f')) { 26 | return hex - 'a' + 10; 27 | } else if (('A' <= hex) && (hex <= 'F')) { 28 | return hex - 'A' + 10; 29 | } else { 30 | // Otherwise return zero for none HEX character 31 | return 0; 32 | } 33 | } 34 | 35 | uint8_t DataBytes::Dec2Hex(const uint8_t dec) { 36 | static const char* hex_digits = "0123456789ABCDEF"; 37 | return hex_digits[dec & 0x0F]; 38 | } 39 | 40 | // Decode from hex string to bytes 41 | DataBytes& DataBytes::FromHexStr() { 42 | const size_t len = size() / 2; 43 | const uint8_t* pbuf = data(); 44 | std::vector dst(len); 45 | for (size_t i = 0; i < len; i++) { 46 | dst[i] = (Hex2Dec(pbuf[i * 2]) << 4) + (Hex2Dec(pbuf[i * 2 + 1])); 47 | } 48 | assign(dst.begin(), dst.end()); 49 | return *this; 50 | } 51 | 52 | // Encode from data bytes to hex string 53 | DataBytes& DataBytes::ToHexStr(bool inverted) { 54 | const size_t len = size(); 55 | const uint8_t* buf = data(); 56 | std::string dst(len * 2, '\0'); 57 | for (size_t i = 0; i < len; i++) { 58 | int j = inverted ? (len - 1 - i) : i; 59 | dst[i * 2] = Dec2Hex(buf[j] >> 4); 60 | dst[i * 2 + 1] = Dec2Hex(buf[j]); 61 | } 62 | assign(dst.begin(), dst.end()); 63 | return *this; 64 | } 65 | 66 | // Decode from base64 string to bytes 67 | DataBytes& DataBytes::FromBase64() { 68 | try { 69 | std::string b64_str(RCAST(const char*, data()), size()); 70 | std::vector b64_decoded = base64::decode(b64_str); 71 | assign(b64_decoded.begin(), b64_decoded.end()); 72 | } catch (std::exception& e) { 73 | TEE_LOG_ERROR("Fail to decode base64 string: %s", e.what()); 74 | SetErrorAndClear(TEE_ERROR_CRYPTO_BASE64); 75 | } 76 | return *this; 77 | } 78 | 79 | // Encode from bytes to base64 string 80 | DataBytes& DataBytes::ToBase64() { 81 | std::string b64_str = base64::encode(data(), size()); 82 | if (b64_str.empty()) { 83 | SetErrorAndClear(TEE_ERROR_CRYPTO_BASE64); 84 | } else { 85 | assign(b64_str.begin(), b64_str.end()); 86 | } 87 | return *this; 88 | } 89 | 90 | // From bytes to it's hash 91 | DataBytes& DataBytes::ToSHA256() { 92 | do { 93 | std::vector hash(SHA256_DIGEST_LENGTH, 0); 94 | SHA256_CTX sha256; 95 | if (!SHA256_Init(&sha256)) { 96 | ELOG_ERROR("Fail to do SHA256_Init"); 97 | SetErrorAndClear(TEE_ERROR_CRYPTO_SHA256); 98 | break; 99 | } 100 | if (!SHA256_Update(&sha256, data(), size())) { 101 | ELOG_ERROR("Fail to do SHA256_Update"); 102 | SetErrorAndClear(TEE_ERROR_CRYPTO_SHA256); 103 | break; 104 | } 105 | if (!SHA256_Final(hash.data(), &sha256)) { 106 | ELOG_ERROR("Fail to do SHA256_Final"); 107 | SetErrorAndClear(TEE_ERROR_CRYPTO_SHA256); 108 | break; 109 | } 110 | assign(hash.begin(), hash.end()); 111 | } while (0); 112 | 113 | return *this; 114 | } 115 | 116 | // Fill with random data of specified length 117 | DataBytes& DataBytes::Randomize(const size_t len) { 118 | resize(len); 119 | if (RAND_bytes(data(), size()) != OPENSSL_SUCCESS) { 120 | ELOG_ERROR("Fail to create random data bytes"); 121 | SetErrorAndClear(TEE_ERROR_CRYPTO_RAND); 122 | } 123 | return *this; 124 | } 125 | 126 | // Export bytes data to buffer 127 | DataBytes& DataBytes::Export(uint8_t* buf, size_t max_buf_len) { 128 | if (max_buf_len < size()) { 129 | // don't clear data if the output buffer is too small 130 | error_code_ = TEE_ERROR_SMALL_BUFFER; 131 | } else { 132 | std::copy(begin(), end(), buf); 133 | } 134 | return *this; 135 | } 136 | 137 | // Return the string format 138 | std::string DataBytes::GetStr() { 139 | return std::string(RCAST(const char*, data()), size()); 140 | } 141 | 142 | // Return the C string, from begin to first '\0'(maybe in middle of data) 143 | std::string DataBytes::GetCharStr() { 144 | if (size()) { // it's not empty and should have tail '\0' 145 | *rbegin() = 0; // In case that the string have no tail '\0' 146 | } 147 | return std::string(RCAST(const char*, data())); 148 | } 149 | 150 | // Return the Hex string of the SHA256 value of the data 151 | std::string DataBytes::SHA256HexStr(const unsigned char* data, 152 | const size_t size) { 153 | std::string hex_sha256; 154 | do { 155 | std::vector hash(SHA256_DIGEST_LENGTH, 0); 156 | SHA256_CTX sha256; 157 | if (!SHA256_Init(&sha256)) { 158 | ELOG_ERROR("Fail to do SHA256_Init"); 159 | break; 160 | } 161 | if (!SHA256_Update(&sha256, data, size)) { 162 | ELOG_ERROR("Fail to do SHA256_Update"); 163 | break; 164 | } 165 | if (!SHA256_Final(hash.data(), &sha256)) { 166 | ELOG_ERROR("Fail to do SHA256_Final"); 167 | break; 168 | } 169 | const size_t len = hash.size(); 170 | const uint8_t* buf = hash.data(); 171 | std::string dst(len * 2, '\0'); 172 | for (size_t i = 0; i < len; i++) { 173 | dst[i * 2] = Dec2Hex(buf[i] >> 4); 174 | dst[i * 2 + 1] = Dec2Hex(buf[i]); 175 | } 176 | hex_sha256.assign(dst); 177 | } while (0); 178 | 179 | return hex_sha256; 180 | } 181 | 182 | // Return the Hex string of the SHA256 value of the data 183 | std::string DataBytes::GetSHA256HexStr() { 184 | return SHA256HexStr(data(), size()); 185 | } 186 | 187 | // Compare to the memory buffer, return true when they are equal. 188 | bool DataBytes::Compare(const uint8_t* buf, size_t len) { 189 | if (len > size()) { 190 | ELOG_DEBUG("The buffer to be compared is longer"); 191 | return false; 192 | } 193 | return (memcmp(buf, data(), len) == 0) ? true : false; 194 | } 195 | 196 | // Compare to a string 197 | bool DataBytes::Compare(const std::string& str) { 198 | return Compare(RCAST(const uint8_t*, str.data()), str.length()); 199 | } 200 | 201 | // Compare to a vector 202 | bool DataBytes::Compare(const std::vector& vec) { 203 | return Compare(vec.data(), vec.size()); 204 | } 205 | 206 | } // namespace common 207 | } // namespace tee 208 | -------------------------------------------------------------------------------- /sdk/common/envelope.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include "openssl/err.h" 5 | #include "openssl/pem.h" 6 | #include "openssl/rand.h" 7 | #include "openssl/rsa.h" 8 | #include "openssl/sha.h" 9 | 10 | #include "tee/common/aes.h" 11 | #include "tee/common/bytes.h" 12 | #include "tee/common/error.h" 13 | #include "tee/common/log.h" 14 | #include "tee/common/rsa.h" 15 | #include "tee/common/type.h" 16 | 17 | #include "tee/common/envelope.h" 18 | 19 | namespace tee { 20 | namespace common { 21 | 22 | TeeErrorCode DigitalEnvelope::Encrypt(const std::string& public_key, 23 | const std::string& plain, 24 | DigitalEnvelopeEncrypted* envelope) { 25 | ELOG_DEBUG("Encrypt secret to digital envelope: %s", name_.c_str()); 26 | if (public_key.empty()) { 27 | ELOG_ERROR("RSA public key should not be empty."); 28 | return TEE_ERROR_PARAMETERS; 29 | } 30 | if (plain.empty()) { 31 | ELOG_ERROR("Input plain text should not be empty."); 32 | return TEE_ERROR_PARAMETERS; 33 | } 34 | 35 | // Set AAD to envelope name if it's not specified 36 | SymmetricKeyEncrypted* aes_cipher = envelope->mutable_aes_cipher(); 37 | if (!name_.empty() && aes_cipher->aad().empty()) { 38 | aes_cipher->set_aad(name_); 39 | } 40 | 41 | // Do AES encryption 42 | AesGcmCrypto aes; 43 | TEE_CHECK_RETURN(aes.Encrypt(plain, aes_cipher)); 44 | 45 | // Encrypt AES key by RSA public key 46 | tee::common::RsaCrypto rsa; 47 | TEE_CHECK_RETURN( 48 | rsa.Encrypt(public_key, aes.GetKey(), envelope->mutable_encrypted_key())); 49 | 50 | return TEE_SUCCESS; 51 | } 52 | 53 | TeeErrorCode DigitalEnvelope::Decrypt(const std::string& private_key, 54 | const DigitalEnvelopeEncrypted& envelope, 55 | std::string* plain) { 56 | ELOG_DEBUG("Decrypt secret in digital envelope: %s", name_.c_str()); 57 | if (private_key.empty()) { 58 | ELOG_ERROR("RSA private key should not be empty."); 59 | return TEE_ERROR_PARAMETERS; 60 | } 61 | 62 | // Decrypt the AES key by RSA private key 63 | std::string aes_key; 64 | tee::common::RsaCrypto rsa; 65 | TEE_CHECK_RETURN( 66 | rsa.Decrypt(private_key, envelope.encrypted_key(), &aes_key)); 67 | 68 | // Decrypt the secret data with AES key 69 | AesGcmCrypto aes(aes_key); 70 | TEE_CHECK_RETURN(aes.Decrypt(envelope.aes_cipher(), plain)); 71 | 72 | return TEE_SUCCESS; 73 | } 74 | 75 | TeeErrorCode DigitalEnvelope::Sign(const std::string& private_key, 76 | const std::string& plain, 77 | DigitalEnvelopeEncrypted* envelope) { 78 | ELOG_DEBUG("Sign the digital envelope: %s", name_.c_str()); 79 | 80 | // Set the HASH value 81 | std::string hash = DataBytes::SHA256HexStr( 82 | RCAST(uint8_t*, CCAST(char*, plain.data())), plain.size()); 83 | envelope->set_plain_hash(hash); 84 | ELOG_DEBUG("Hash of envelope plain: %s", hash.c_str()); 85 | 86 | // Sign and set the plain HASH value 87 | TEE_CHECK_RETURN( 88 | RsaCrypto::Sign(private_key, hash, envelope->mutable_plain_hash_sig())); 89 | 90 | return TEE_SUCCESS; 91 | } 92 | 93 | TeeErrorCode DigitalEnvelope::Verify(const std::string& public_key, 94 | const std::string& plain, 95 | const DigitalEnvelopeEncrypted& envelope) { 96 | ELOG_DEBUG("Verify the signature in digital envelope: %s", name_.c_str()); 97 | 98 | if (envelope.plain_hash().empty() || envelope.plain_hash_sig().empty()) { 99 | ELOG_ERROR("Empty hash or signature value"); 100 | return TEE_ERROR_PARAMETERS; 101 | } 102 | 103 | // Verify the HASH value 104 | std::string cal_hash = DataBytes::SHA256HexStr( 105 | RCAST(uint8_t*, CCAST(char*, plain.data())), plain.size()); 106 | if (envelope.plain_hash() != cal_hash) { 107 | ELOG_ERROR("Fail to compare the hash value"); 108 | ELOG_DEBUG("actual hash: %s", cal_hash.c_str()); 109 | ELOG_DEBUG("expected hash: %s", envelope.plain_hash().c_str()); 110 | return TEE_ERROR_UNEXPECTED; 111 | } 112 | 113 | // Verify the signature 114 | TEE_CHECK_RETURN( 115 | RsaCrypto::Verify(public_key, cal_hash, envelope.plain_hash_sig())); 116 | 117 | return TEE_SUCCESS; 118 | } 119 | 120 | } // namespace common 121 | } // namespace tee 122 | -------------------------------------------------------------------------------- /sdk/common/rsa.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include "openssl/err.h" 5 | #include "openssl/pem.h" 6 | #include "openssl/rand.h" 7 | #include "openssl/rsa.h" 8 | #include "openssl/sha.h" 9 | 10 | #include "tee/common/bytes.h" 11 | #include "tee/common/error.h" 12 | #include "tee/common/log.h" 13 | #include "tee/common/rsa.h" 14 | #include "tee/common/type.h" 15 | 16 | namespace tee { 17 | namespace common { 18 | 19 | TeeErrorCode RsaCrypto::GetKeyFromRSA(bool is_public_key, std::string* key, 20 | const RSA_ptr& rsa_ptr) { 21 | BIO_ptr bio(BIO_new(BIO_s_mem()), BIO_free_all); 22 | if (!bio) { 23 | ELOG_ERROR("Failed to new BIO"); 24 | return TEE_ERROR_UNEXPECTED; 25 | } 26 | 27 | int res = 0; 28 | if (is_public_key) { 29 | res = PEM_write_bio_RSAPublicKey(bio.get(), rsa_ptr.get()); 30 | } else { 31 | res = PEM_write_bio_RSAPrivateKey(bio.get(), rsa_ptr.get(), NULL, NULL, 0, 32 | 0, NULL); 33 | } 34 | if (!res) { 35 | ELOG_ERROR("Failed to write bio RSA Key"); 36 | return TEE_ERROR_UNEXPECTED; 37 | } 38 | 39 | int keylen = BIO_pending(bio.get()); 40 | DataBytes pem_str(keylen); 41 | if (!BIO_read(bio.get(), pem_str.data(), keylen)) { 42 | ELOG_ERROR("Failed to read BIO"); 43 | return TEE_ERROR_UNEXPECTED; 44 | } 45 | key->assign(RCAST(char*, pem_str.data()), keylen); 46 | return TEE_SUCCESS; 47 | } 48 | 49 | TeeErrorCode RsaCrypto::GetRSAFromKey(const bool is_public_key, 50 | const std::string& key, 51 | RSA_ptr* rsa_ptr) { 52 | void* pkey = RCAST(void*, CCAST(char*, key.c_str())); 53 | BIO_ptr bio(BIO_new_mem_buf(pkey, -1), BIO_free_all); 54 | if (!bio) { 55 | ELOG_ERROR("Failed to new BIO memory buffer"); 56 | return TEE_ERROR_UNEXPECTED; 57 | } 58 | 59 | RSA* rsa = NULL; 60 | if (is_public_key) { 61 | rsa = PEM_read_bio_RSAPublicKey(bio.get(), NULL, NULL, NULL); 62 | } else { 63 | rsa = PEM_read_bio_RSAPrivateKey(bio.get(), NULL, NULL, NULL); 64 | } 65 | rsa_ptr->reset(rsa); 66 | if (!rsa) { 67 | ELOG_ERROR("Failed to read PEM key"); 68 | return TEE_ERROR_UNEXPECTED; 69 | } 70 | 71 | return TEE_SUCCESS; 72 | } 73 | 74 | TeeErrorCode RsaCrypto::GenerateKeyPair(std::string* public_key, 75 | std::string* private_key) { 76 | uint64_t e = RSA_F4; 77 | BIGNUM_ptr exp(BN_new(), BN_free); 78 | if (!exp) { 79 | ELOG_ERROR("Failed to new big number"); 80 | return TEE_ERROR_UNEXPECTED; 81 | } 82 | if (!BN_set_word(exp.get(), e)) { 83 | ELOG_ERROR("Failed to set word"); 84 | return TEE_ERROR_UNEXPECTED; 85 | } 86 | 87 | RSA_ptr rsa_ptr(RSA_new(), RSA_free); 88 | if (!rsa_ptr) { 89 | ELOG_ERROR("Failed to new RSA"); 90 | return TEE_ERROR_UNEXPECTED; 91 | } 92 | if (!RSA_generate_key_ex(rsa_ptr.get(), kRSAKeySize, exp.get(), NULL)) { 93 | ELOG_ERROR("Failed to generate RSA key"); 94 | return TEE_ERROR_UNEXPECTED; 95 | } 96 | 97 | TeeErrorCode ret = GetKeyFromRSA(kIsPublicKey, public_key, rsa_ptr); 98 | if (ret != TEE_SUCCESS) { 99 | ELOG_ERROR_TRACE(); 100 | return ret; 101 | } 102 | ret = GetKeyFromRSA(kIsPrivateKey, private_key, rsa_ptr); 103 | if (ret != TEE_SUCCESS) { 104 | ELOG_ERROR_TRACE(); 105 | return ret; 106 | } 107 | 108 | return TEE_SUCCESS; 109 | } 110 | 111 | TeeErrorCode RsaCrypto::Encrypt(const std::string& public_key, 112 | const std::string& src, std::string* dst) { 113 | if (dst == NULL || public_key.empty() || src.empty()) { 114 | ELOG_ERROR("Invalid public key for RSA encrypt"); 115 | return TEE_ERROR_INVALID_PARAMETER; 116 | } 117 | 118 | dst->clear(); 119 | std::string buffer; 120 | size_t pos = 0; 121 | size_t length = src.length(); 122 | size_t step = GetMaxEncryptBufferSize(); 123 | TeeErrorCode ret = TEE_ERROR_INVALID_PARAMETER; 124 | while (pos < length) { 125 | size_t enc_len = (pos + step) <= length ? step : (length - pos); 126 | ret = RSAEncrypt(public_key, src.substr(pos, enc_len), &buffer); 127 | if (ret != TEE_SUCCESS) { 128 | ELOG_ERROR_TRACE(); 129 | break; 130 | } 131 | pos += step; 132 | dst->append(buffer); 133 | } 134 | return ret; 135 | } 136 | 137 | TeeErrorCode RsaCrypto::Decrypt(const std::string& private_key, 138 | const std::string& src, std::string* dst) { 139 | if (dst == NULL || private_key.empty() || src.empty() || 140 | src.length() % kRSAEncryptedTextLength != 0) { 141 | ELOG_ERROR("Invalid input, src length = %ld", src.length()); 142 | return TEE_ERROR_PARAMETERS; 143 | } 144 | 145 | dst->clear(); 146 | std::string buffer; 147 | size_t pos = 0; 148 | size_t length = src.length(); 149 | size_t step = GetDecryptBufferSize(); 150 | TeeErrorCode ret = TEE_ERROR_PARAMETERS; 151 | while (pos < length) { 152 | size_t dec_len = (pos + step) <= length ? step : (length - pos); 153 | ret = RSADecrypt(private_key, src.substr(pos, dec_len), &buffer); 154 | if (ret != TEE_SUCCESS) { 155 | ELOG_ERROR("Fail to do RSA decryption"); 156 | break; 157 | } 158 | pos += step; 159 | dst->append(buffer); 160 | } 161 | return ret; 162 | } 163 | 164 | TeeErrorCode RsaCrypto::Sign(const std::string& private_key, 165 | const std::string& msg, std::string* sigret) { 166 | if (sigret == NULL || private_key.empty() || msg.empty()) { 167 | ELOG_ERROR("Invalid private key for RSA sign"); 168 | return TEE_ERROR_INVALID_PARAMETER; 169 | } 170 | 171 | RSA_ptr rsa_ptr(NULL, RSA_free); 172 | TeeErrorCode ret = GetRSAFromKey(kIsPrivateKey, private_key, &rsa_ptr); 173 | if (ret != TEE_SUCCESS) { 174 | ELOG_ERROR_TRACE(); 175 | return ret; 176 | } 177 | 178 | DataBytes signature(RSA_size(rsa_ptr.get())); 179 | DataBytes msg_hash(msg); 180 | msg_hash.ToSHA256(); 181 | unsigned int sign_size = 0; 182 | int rsa_ret = RSA_sign(NID_sha256, msg_hash.data(), msg_hash.size(), 183 | signature.data(), &sign_size, rsa_ptr.get()); 184 | if (rsa_ret != OPENSSL_SUCCESS) { // RSA_sign() returns 1 on success 185 | ERR_load_crypto_strings(); 186 | char error_msg[kErrorBufferLength] = {}; 187 | ERR_error_string(ERR_get_error(), error_msg); 188 | ELOG_ERROR("Failed to do RSA sign: %s", error_msg); 189 | return TEE_ERROR_CRYPTO_RSA_SIGN; 190 | } 191 | sigret->assign(RCAST(char*, signature.data()), sign_size); 192 | return TEE_SUCCESS; 193 | } 194 | 195 | TeeErrorCode RsaCrypto::Verify(const std::string& public_key, 196 | const std::string& msg, 197 | const std::string& sigbuf) { 198 | if (public_key.empty() || msg.empty() || sigbuf.empty()) { 199 | ELOG_ERROR("Invalid public key for RSA verify"); 200 | return TEE_ERROR_PARAMETERS; 201 | } 202 | 203 | RSA_ptr rsa_ptr(NULL, RSA_free); 204 | // RSA_free() frees the RSA structure and its components. 205 | // The key is erased before the memory is returned to the system. 206 | // If rsa is a NULL pointer, no action occurs. 207 | TeeErrorCode ret = GetRSAFromKey(kIsPublicKey, public_key, &rsa_ptr); 208 | if (ret != TEE_SUCCESS) { 209 | return ret; 210 | } 211 | 212 | DataBytes msg_hash(msg); 213 | msg_hash.ToSHA256(); 214 | int rsa_ret = RSA_verify(NID_sha256, msg_hash.data(), msg_hash.size(), 215 | RCAST(const uint8_t*, sigbuf.data()), 216 | SCAST(uint32_t, sigbuf.length()), rsa_ptr.get()); 217 | if (rsa_ret != OPENSSL_SUCCESS) { 218 | ERR_load_crypto_strings(); 219 | char error_msg[kErrorBufferLength] = {}; 220 | ERR_error_string(ERR_get_error(), error_msg); 221 | ELOG_ERROR("Failed to do RSA verify: %s", error_msg); 222 | return TEE_ERROR_CRYPTO_RSA_VERIFY; 223 | } 224 | 225 | return TEE_SUCCESS; 226 | } 227 | 228 | TeeErrorCode RsaCrypto::RSAEncrypt(const std::string& public_key, 229 | const std::string& src, std::string* dst) { 230 | if (dst == NULL || public_key.empty() || src.empty() || 231 | src.length() > kRSAPlainTextLength) { 232 | ELOG_ERROR("Invalid public key for RSAEncrypt"); 233 | return TEE_ERROR_INVALID_PARAMETER; 234 | } 235 | 236 | RSA_ptr rsa_ptr(NULL, RSA_free); 237 | // RSA_free() frees the RSA structure and its components. 238 | // The key is erased before the memory is returned to the system. 239 | // If rsa is a NULL pointer, no action occurs. 240 | TeeErrorCode ret = GetRSAFromKey(kIsPublicKey, public_key, &rsa_ptr); 241 | if (ret != TEE_SUCCESS) { 242 | ELOG_ERROR_TRACE(); 243 | return ret; 244 | } 245 | 246 | DataBytes ctext(RSA_size(rsa_ptr.get())); 247 | int ctext_len = RSA_public_encrypt( 248 | SCAST(int, src.length()), RCAST(const unsigned char*, src.data()), 249 | ctext.data(), rsa_ptr.get(), kRSAPaddingScheme); 250 | if (ctext_len == -1) { 251 | ERR_load_crypto_strings(); 252 | char error_msg[kErrorBufferLength] = {}; 253 | ERR_error_string(ERR_get_error(), error_msg); 254 | ELOG_ERROR("Failed to do RSA decryption: %s", error_msg); 255 | return TEE_ERROR_CRYPTO_RSA_ENCRYPT; 256 | } 257 | dst->assign(RCAST(char*, ctext.data()), ctext.size()); 258 | return TEE_SUCCESS; 259 | } 260 | 261 | TeeErrorCode RsaCrypto::RSADecrypt(const std::string& private_key, 262 | const std::string& src, std::string* dst) { 263 | if (dst == NULL || private_key.empty() || src.empty() || 264 | src.length() != kRSAEncryptedTextLength) { 265 | ELOG_ERROR("Invalid private key for RSA decryption"); 266 | return TEE_ERROR_INVALID_PARAMETER; 267 | } 268 | 269 | RSA_ptr rsa_ptr(NULL, RSA_free); 270 | TeeErrorCode ret = GetRSAFromKey(kIsPrivateKey, private_key, &rsa_ptr); 271 | if (ret != TEE_SUCCESS) { 272 | ELOG_ERROR_TRACE(); 273 | return ret; 274 | } 275 | 276 | DataBytes ptext(RSA_size(rsa_ptr.get())); 277 | int ptext_len = RSA_private_decrypt( 278 | SCAST(int, src.length()), RCAST(const unsigned char*, src.data()), 279 | ptext.data(), rsa_ptr.get(), kRSAPaddingScheme); 280 | if (ptext_len == -1) { 281 | ERR_load_crypto_strings(); 282 | char error_msg[kErrorBufferLength] = {}; 283 | ERR_error_string(ERR_get_error(), error_msg); 284 | ELOG_ERROR("Failed to do RSA decryption: %s", error_msg); 285 | return TEE_ERROR_CRYPTO_RSA_DECRYPT; 286 | } 287 | ptext.resize(ptext_len); 288 | dst->assign(RCAST(char*, ptext.data()), ptext_len); 289 | return TEE_SUCCESS; 290 | } 291 | 292 | int RsaCrypto::GetDecryptBufferSize() { 293 | return kRSAEncryptedTextLength; 294 | } 295 | 296 | int RsaCrypto::GetMaxEncryptBufferSize() { 297 | return kRSAPlainTextLength; 298 | } 299 | 300 | } // namespace common 301 | } // namespace tee 302 | -------------------------------------------------------------------------------- /sdk/edl/.gitignore: -------------------------------------------------------------------------------- 1 | *_t.h 2 | *_t.c 3 | *_u.h 4 | *_u.c 5 | -------------------------------------------------------------------------------- /sdk/edl/common_utils.edl: -------------------------------------------------------------------------------- 1 | enclave { 2 | include "tee/common/error.h" 3 | include "sgx_urts.h" 4 | include "sgx_report.h" 5 | 6 | trusted { 7 | public TeeErrorCode ecall_GetRand( 8 | [out, size=len] uint8_t *rand, uint32_t len); 9 | }; 10 | 11 | untrusted { 12 | void ocall_PrintMessage( 13 | [in, string] const char *message); 14 | }; 15 | }; 16 | -------------------------------------------------------------------------------- /sdk/edl/kubetee.edl: -------------------------------------------------------------------------------- 1 | enclave { 2 | from "common_utils.edl" import *; 3 | from "remote_attestation.edl" import *; 4 | 5 | trusted { 6 | public TeeErrorCode ecall_TeeRun( 7 | [user_check] const char* attr_buf, size_t attr_len, 8 | [in,size=req_len] const char *req_buf, size_t req_len, 9 | [user_check] char** res_buf, [out]size_t* res_len); 10 | }; 11 | 12 | untrusted { 13 | TeeErrorCode ocall_UntrustedMemoryAlloc( 14 | size_t size, [user_check] char** buf); 15 | 16 | TeeErrorCode ocall_UntrustedMemoryFree( 17 | [in] char** buf); 18 | 19 | TeeErrorCode ocall_ReeRun( 20 | [in,size=attr_len] const char* attr_buf, size_t attr_len, 21 | [in,size=req_len] const char *req_buf, size_t req_len, 22 | [out] char** res_buf, [out]size_t* res_len); 23 | }; 24 | }; 25 | -------------------------------------------------------------------------------- /sdk/edl/remote_attestation.edl: -------------------------------------------------------------------------------- 1 | enclave { 2 | include "tee/common/error.h" 3 | include "sgx_urts.h" 4 | include "sgx_report.h" 5 | 6 | trusted { 7 | public TeeErrorCode ecall_RaVerifyReport( 8 | [in] sgx_target_info_t *target_info, 9 | [in] sgx_report_t *target_report); 10 | }; 11 | 12 | untrusted { 13 | }; 14 | }; 15 | -------------------------------------------------------------------------------- /sdk/include/tee/common/aes.h: -------------------------------------------------------------------------------- 1 | #ifndef SDK_INCLUDE_TEE_COMMON_AES_H_ 2 | #define SDK_INCLUDE_TEE_COMMON_AES_H_ 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | #include "tee/common/bytes.h" 9 | #include "tee/common/error.h" 10 | #include "tee/common/type.h" 11 | 12 | #include "./kubetee.pb.h" 13 | 14 | using tee::SymmetricKeyEncrypted; 15 | 16 | namespace tee { 17 | namespace common { 18 | 19 | class AesGcmCrypto { 20 | public: 21 | AesGcmCrypto(); // Generate random key if it's not specified 22 | explicit AesGcmCrypto(const std::string& key) : key_(key) {} 23 | explicit AesGcmCrypto(const char* key) : key_(key) {} 24 | 25 | // Encrypt the plain string to cipher in SymmetricKeyEncrypted format 26 | TeeErrorCode Encrypt(const std::string& plain, SymmetricKeyEncrypted* cipher); 27 | // Decrypt the cipher in SymmetricKeyEncrypted format to plain string 28 | TeeErrorCode Decrypt(const SymmetricKeyEncrypted& cipher, std::string* plain); 29 | 30 | std::string GetKey() { 31 | return key_; 32 | } 33 | 34 | static size_t get_iv_size() { 35 | return kIvSize; 36 | } 37 | 38 | static size_t get_mac_size() { 39 | return kMacSize; 40 | } 41 | 42 | static size_t get_key_size() { 43 | return kKeySize; 44 | } 45 | 46 | private: 47 | static const size_t kKeySize = 32; // AES256 48 | static const size_t kIvSize = 12; 49 | static const size_t kMacSize = 16; 50 | 51 | std::string key_; 52 | }; 53 | 54 | } // namespace common 55 | } // namespace tee 56 | 57 | #endif // SDK_INCLUDE_TEE_COMMON_AES_H_ 58 | -------------------------------------------------------------------------------- /sdk/include/tee/common/bytes.h: -------------------------------------------------------------------------------- 1 | #ifndef SDK_INCLUDE_TEE_COMMON_BYTES_H_ 2 | #define SDK_INCLUDE_TEE_COMMON_BYTES_H_ 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | #include "tee/common/error.h" 10 | #include "tee/common/type.h" 11 | 12 | namespace tee { 13 | namespace common { 14 | 15 | class DataBytes : public std::vector { 16 | public: 17 | // Constructor without any initialization 18 | DataBytes() {} 19 | 20 | // Constructor based on another vector 21 | explicit DataBytes(const std::vector& value) { 22 | std::vector::assign(value.begin(), value.end()); 23 | } 24 | 25 | // Constructor based on a normal string 26 | explicit DataBytes(const std::string& value) { 27 | std::vector::assign(value.begin(), value.end()); 28 | } 29 | 30 | // Constructor based on buffer end with '\' 31 | explicit DataBytes(const char* buf) { 32 | std::string temp(buf); 33 | std::vector::assign(temp.begin(), temp.end()); 34 | } 35 | 36 | // Constructor based on buffer and length 37 | DataBytes(const uint8_t* buf, size_t len) { 38 | std::string temp(RCAST(const char*, buf), len); 39 | std::vector::assign(temp.begin(), temp.end()); 40 | } 41 | 42 | // Constructor based on size of specified character 43 | DataBytes(const size_t size, uint8_t ch) { 44 | std::vector::assign(size, ch); 45 | } 46 | 47 | // Constructor based on zero initialized size 48 | explicit DataBytes(const size_t size) { 49 | std::vector::assign(size, 0); 50 | } 51 | 52 | // Update value from C string 53 | void SetValue(const char* value) { 54 | std::string temp = value; 55 | assign(temp.begin(), temp.end()); 56 | } 57 | 58 | // Update value from buffer and length 59 | void SetValue(const uint8_t* buf, const size_t len) { 60 | std::string temp(RCAST(const char*, buf), len); 61 | assign(temp.begin(), temp.end()); 62 | } 63 | 64 | // Update value from C++ string 65 | void SetValue(const std::string& value) { 66 | assign(value.begin(), value.end()); 67 | } 68 | 69 | // Update value from vector 70 | void SetValue(const std::vector& value) { 71 | assign(value.begin(), value.end()); 72 | } 73 | 74 | // From hex string to bytes 75 | DataBytes& FromHexStr(); 76 | 77 | // From bytes to hex string 78 | DataBytes& ToHexStr(bool inverted = false); 79 | 80 | // From base64 string to bytes 81 | DataBytes& FromBase64(); 82 | 83 | // From bytes to base64 string 84 | DataBytes& ToBase64(); 85 | 86 | // From bytes to SHA256 87 | DataBytes& ToSHA256(); 88 | 89 | // Fill with random data 90 | DataBytes& Randomize(const size_t len); 91 | 92 | // Export bytes data to buffer 93 | DataBytes& Export(uint8_t* buf, const size_t max_buf_len); 94 | 95 | // Return the string format 96 | std::string GetStr(); 97 | 98 | // Return the C format string, from begin to '\0' 99 | std::string GetCharStr(); 100 | 101 | // Get Hexstring SHA256 value of data 102 | static std::string SHA256HexStr(const unsigned char* data, const size_t size); 103 | 104 | // Get Hexstring SHA256 value of data 105 | std::string GetSHA256HexStr(); 106 | 107 | // Compare to other memeory instances 108 | bool Compare(const uint8_t* buf, size_t len); 109 | bool Compare(const std::string& str); 110 | bool Compare(const std::vector& vec); 111 | 112 | // For no return value statements; 113 | void Void() {} 114 | 115 | // Secure clear the content 116 | void SecureClear() { 117 | memset(data(), 0, size()); 118 | clear(); 119 | } 120 | 121 | // Return the final error code 122 | TeeErrorCode GetError() { 123 | if (empty() && (error_code_ == TEE_SUCCESS)) { 124 | return TEE_ERROR_UNEXPECTED; 125 | } 126 | return error_code_; 127 | } 128 | 129 | private: 130 | // internal methods for hex string 131 | static uint8_t Hex2Dec(const uint8_t hex); 132 | static uint8_t Dec2Hex(const uint8_t dec); 133 | 134 | // Set internal error code and clear all data by default. 135 | void inline SetErrorAndClear(TeeErrorCode error) { 136 | error_code_ = error; 137 | SecureClear(); 138 | } 139 | 140 | TeeErrorCode error_code_ = TEE_SUCCESS; 141 | }; 142 | 143 | } // namespace common 144 | } // namespace tee 145 | 146 | using DataBytes = tee::common::DataBytes; 147 | 148 | #endif // SDK_INCLUDE_TEE_COMMON_BYTES_H_ 149 | -------------------------------------------------------------------------------- /sdk/include/tee/common/challenger.h: -------------------------------------------------------------------------------- 1 | #ifndef SDK_INCLUDE_TEE_COMMON_CHALLENGER_H_ 2 | #define SDK_INCLUDE_TEE_COMMON_CHALLENGER_H_ 3 | 4 | #include 5 | #include 6 | 7 | #include "./sgx_quote.h" 8 | #include "./sgx_report.h" 9 | 10 | #include "tee/common/error.h" 11 | #include "tee/common/type.h" 12 | 13 | #include "./kubetee.pb.h" 14 | 15 | namespace tee { 16 | namespace common { 17 | 18 | class RaChallenger { 19 | public: 20 | RaChallenger(const std::string& public_key, 21 | const tee::EnclaveMatchRules& verify_rules); 22 | 23 | // Verify the IAS report by the public key and verify rules 24 | TeeErrorCode VerifyReport(const tee::IasReport& ias_report); 25 | 26 | // Get the enclave related information from IAS report 27 | static TeeErrorCode GetEnclaveInfo(const tee::IasReport& ias_report, 28 | tee::EnclaveInformation* info); 29 | 30 | private: 31 | // internal functions 32 | TeeErrorCode CheckReportSignature(const tee::IasReport& ias_report); 33 | TeeErrorCode CheckReportQuoteStatus(const tee::IasReport& ias_report); 34 | TeeErrorCode CheckReportQuote(const tee::IasReport& ias_report); 35 | 36 | // Check quote 37 | TeeErrorCode CheckQuoteSignType(sgx_quote_t* pquote); 38 | TeeErrorCode CheckQuoteSPID(sgx_quote_t* pquote); 39 | TeeErrorCode CheckQuoteReportBody(sgx_quote_t* pquote); 40 | 41 | // Check report body 42 | TeeErrorCode CheckReportBodyMRENCLAVE(sgx_report_body_t* report_body); 43 | TeeErrorCode CheckReportBodyMRSIGNER(sgx_report_body_t* report_body); 44 | TeeErrorCode CheckReportBodyAttributes(sgx_report_body_t* report_body); 45 | TeeErrorCode CheckReportBodyIsvProd(sgx_report_body_t* report_body); 46 | TeeErrorCode CheckReportBodyIsvSvn(sgx_report_body_t* report_body); 47 | TeeErrorCode CheckReportBodyUserData(sgx_report_body_t* report_body); 48 | 49 | const std::string public_key_; 50 | const tee::EnclaveMatchRules& rules_; 51 | tee::EnclaveInformation* enclave_ = nullptr; 52 | }; 53 | 54 | } // namespace common 55 | } // namespace tee 56 | 57 | #endif // SDK_INCLUDE_TEE_COMMON_CHALLENGER_H_ 58 | -------------------------------------------------------------------------------- /sdk/include/tee/common/envelope.h: -------------------------------------------------------------------------------- 1 | #ifndef SDK_INCLUDE_TEE_COMMON_ENVELOPE_H_ 2 | #define SDK_INCLUDE_TEE_COMMON_ENVELOPE_H_ 3 | 4 | #include 5 | #include 6 | 7 | #include "tee/common/aes.h" 8 | #include "tee/common/bytes.h" 9 | #include "tee/common/error.h" 10 | #include "tee/common/rsa.h" 11 | 12 | using tee::DigitalEnvelopeEncrypted; 13 | 14 | namespace tee { 15 | namespace common { 16 | 17 | class DigitalEnvelope { 18 | public: 19 | explicit DigitalEnvelope(const std::string& name) : name_(name) {} 20 | explicit DigitalEnvelope(const char* name) : name_(name) {} 21 | DigitalEnvelope() : name_("Enclave") {} // with default envelope name 22 | 23 | // Before decrypt, you need to prepare the plain text and public key 24 | // AES AAD and IV is optional. The default AAD is envelope name, and 25 | // the default IV is random number generated when do AES encryption. 26 | TeeErrorCode Encrypt(const std::string& public_key, const std::string& plain, 27 | DigitalEnvelopeEncrypted* envelope); 28 | 29 | // Before decrypt, you need to prepare the cipher envelope and private key 30 | TeeErrorCode Decrypt(const std::string& private_key, 31 | const DigitalEnvelopeEncrypted& envelope, 32 | std::string* plain); 33 | 34 | // Optional for add signature into the digital envelope 35 | TeeErrorCode Sign(const std::string& private_key, const std::string& plain, 36 | DigitalEnvelopeEncrypted* envelope); 37 | 38 | // Verify the signature in the digital envelope if it exits 39 | TeeErrorCode Verify(const std::string& public_key, const std::string& plain, 40 | const DigitalEnvelopeEncrypted& envelope); 41 | 42 | private: 43 | const std::string name_; 44 | }; 45 | 46 | } // namespace common 47 | } // namespace tee 48 | 49 | #endif // SDK_INCLUDE_TEE_COMMON_ENVELOPE_H_ 50 | -------------------------------------------------------------------------------- /sdk/include/tee/common/error.h: -------------------------------------------------------------------------------- 1 | #ifndef SDK_INCLUDE_TEE_COMMON_ERROR_H_ 2 | #define SDK_INCLUDE_TEE_COMMON_ERROR_H_ 3 | 4 | // clang-format off 5 | 6 | // For Openssl error code 7 | typedef enum { 8 | OPENSSL_ERROR = 0, 9 | OPENSSL_SUCCESS = 1, 10 | } OpensslErrorCode; 11 | 12 | // We want to use TeeErrorCode to include the error code from intel sdk and 13 | // also the ra sdk code, and to be compatible with the following changes 14 | // in future intel SDK version. So, we use unsigned int type here. 15 | typedef int TeeErrorCode; 16 | 17 | #define TEE_MK_ERROR(x) (0xFFFF0000&((x) << 16)) 18 | #define SGX_MK_ERROR(x) (0x00000000|(x)) 19 | 20 | // All SGX_MK_ERROR error code are from sgx_error.h, 21 | // we simple include it to return error code from intel sdk directly. 22 | #define TEE_SUCCESS SGX_MK_ERROR(0x0000) 23 | 24 | #define TEE_ERROR_UNEXPECTED SGX_MK_ERROR(0x0001) 25 | #define TEE_ERROR_INVALID_PARAMETER SGX_MK_ERROR(0x0002) 26 | #define TEE_ERROR_OUT_OF_MEMORY SGX_MK_ERROR(0x0003) 27 | #define TEE_ERROR_ENCLAVE_LOST SGX_MK_ERROR(0x0004) 28 | #define TEE_ERROR_INVALID_STATE SGX_MK_ERROR(0x0005) 29 | 30 | #define TEE_ERROR_INVALID_FUNCTION SGX_MK_ERROR(0x1001) 31 | #define TEE_ERROR_OUT_OF_TCS SGX_MK_ERROR(0x1003) 32 | #define TEE_ERROR_ENCLAVE_CRASHED SGX_MK_ERROR(0x1006) 33 | #define TEE_ERROR_ECALL_NOT_ALLOWED SGX_MK_ERROR(0x1007) 34 | #define TEE_ERROR_OCALL_NOT_ALLOWED SGX_MK_ERROR(0x1008) 35 | #define TEE_ERROR_STACK_OVERRUN SGX_MK_ERROR(0x1009) 36 | 37 | #define TEE_ERROR_UNDEFINED_SYMBOL SGX_MK_ERROR(0x2000) 38 | #define TEE_ERROR_INVALID_ENCLAVE SGX_MK_ERROR(0x2001) 39 | #define TEE_ERROR_INVALID_ENCLAVE_ID SGX_MK_ERROR(0x2002) 40 | #define TEE_ERROR_INVALID_SIGNATURE SGX_MK_ERROR(0x2003) 41 | #define TEE_ERROR_NDEBUG_ENCLAVE SGX_MK_ERROR(0x2004) 42 | #define TEE_ERROR_OUT_OF_EPC SGX_MK_ERROR(0x2005) 43 | #define TEE_ERROR_NO_DEVICE SGX_MK_ERROR(0x2006) 44 | #define TEE_ERROR_MEMORY_MAP_CONFLICT SGX_MK_ERROR(0x2007) 45 | #define TEE_ERROR_INVALID_METADATA SGX_MK_ERROR(0x2009) 46 | #define TEE_ERROR_DEVICE_BUSY SGX_MK_ERROR(0x200c) 47 | #define TEE_ERROR_INVALID_VERSION SGX_MK_ERROR(0x200d) 48 | #define TEE_ERROR_MODE_INCOMPATIBLE SGX_MK_ERROR(0x200e) 49 | #define TEE_ERROR_ENCLAVE_FILE_ACCESS SGX_MK_ERROR(0x200f) 50 | #define TEE_ERROR_INVALID_MISC SGX_MK_ERROR(0x2010) 51 | #define TEE_ERROR_INVALID_LAUNCH_TOKEN SGX_MK_ERROR(0x2011) 52 | 53 | #define TEE_ERROR_MAC_MISMATCH SGX_MK_ERROR(0x3001) 54 | #define TEE_ERROR_INVALID_ATTRIBUTE SGX_MK_ERROR(0x3002) 55 | #define TEE_ERROR_INVALID_CPUSVN SGX_MK_ERROR(0x3003) 56 | #define TEE_ERROR_INVALID_ISVSVN SGX_MK_ERROR(0x3004) 57 | #define TEE_ERROR_INVALID_KEYNAME SGX_MK_ERROR(0x3005) 58 | 59 | #define TEE_ERROR_SERVICE_UNAVAILABLE SGX_MK_ERROR(0x4001) 60 | #define TEE_ERROR_SERVICE_TIMEOUT SGX_MK_ERROR(0x4002) 61 | #define TEE_ERROR_AE_INVALID_EPIDBLOB SGX_MK_ERROR(0x4003) 62 | #define TEE_ERROR_SERVICE_INVALID_PRIVILEGE SGX_MK_ERROR(0x4004) 63 | #define TEE_ERROR_EPID_MEMBER_REVOKED SGX_MK_ERROR(0x4005) 64 | #define TEE_ERROR_UPDATE_NEEDED SGX_MK_ERROR(0x4006) 65 | #define TEE_ERROR_NETWORK_FAILURE SGX_MK_ERROR(0x4007) 66 | #define TEE_ERROR_AE_SESSION_INVALID SGX_MK_ERROR(0x4008) 67 | #define TEE_ERROR_BUSY SGX_MK_ERROR(0x400a) 68 | #define TEE_ERROR_MC_NOT_FOUND SGX_MK_ERROR(0x400c) 69 | #define TEE_ERROR_MC_NO_ACCESS_RIGHT SGX_MK_ERROR(0x400d) 70 | #define TEE_ERROR_MC_USED_UP SGX_MK_ERROR(0x400e) 71 | #define TEE_ERROR_MC_OVER_QUOTA SGX_MK_ERROR(0x400f) 72 | #define TEE_ERROR_KDF_MISMATCH SGX_MK_ERROR(0x4011) 73 | #define TEE_ERROR_UNRECOGNIZED_PLATFORM SGX_MK_ERROR(0x4012) 74 | 75 | #define TEE_ERROR_NO_PRIVILEGE SGX_MK_ERROR(0x5002) 76 | 77 | #define TEE_ERROR_PCL_ENCRYPTED SGX_MK_ERROR(0x6001) 78 | #define TEE_ERROR_PCL_NOT_ENCRYPTED SGX_MK_ERROR(0x6002) 79 | #define TEE_ERROR_PCL_MAC_MISMATCH SGX_MK_ERROR(0x6003) 80 | #define TEE_ERROR_PCL_SHA_MISMATCH SGX_MK_ERROR(0x6004) 81 | #define TEE_ERROR_PCL_GUID_MISMATCH SGX_MK_ERROR(0x6005) 82 | 83 | #define TEE_ERROR_FILE_BAD_STATUS SGX_MK_ERROR(0x7001) 84 | #define TEE_ERROR_FILE_NO_KEY_ID SGX_MK_ERROR(0x7002) 85 | #define TEE_ERROR_FILE_NAME_MISMATCH SGX_MK_ERROR(0x7003) 86 | #define TEE_ERROR_FILE_NOT_RA_FILE SGX_MK_ERROR(0x7004) 87 | #define TEE_ERROR_FILE_CANT_OPEN_RECOVERY_FILE SGX_MK_ERROR(0x7005) 88 | #define TEE_ERROR_FILE_CANT_WRITE_RECOVERY_FILE SGX_MK_ERROR(0x7006) 89 | #define TEE_ERROR_FILE_RECOVERY_NEEDED SGX_MK_ERROR(0x7007) 90 | #define TEE_ERROR_FILE_FLUSH_FAILED SGX_MK_ERROR(0x7008) 91 | #define TEE_ERROR_FILE_CLOSE_FAILED SGX_MK_ERROR(0x7009) 92 | 93 | #define RA_INTERNAL_ERROR_ENCLAVE_CREATE_INTERRUPTED SGX_MK_ERROR(0xF001) 94 | 95 | // The following error code are used in tee code 96 | #define TEE_ERROR_SGX_GENERIC TEE_MK_ERROR(0x0000) 97 | #define TEE_ERROR_GENERIC TEE_MK_ERROR(0x0001) 98 | #define TEE_ERROR_PARAMETERS TEE_MK_ERROR(0x0002) 99 | #define TEE_ERROR_MALLOC TEE_MK_ERROR(0x0003) 100 | #define TEE_ERROR_ENCLAVE_NOTINITIALIZED TEE_MK_ERROR(0x0004) 101 | #define TEE_ERROR_REPORT_DATA_SIZE TEE_MK_ERROR(0x0005) 102 | #define TEE_ERROR_PARSE_CONFIGURATIONS TEE_MK_ERROR(0x0006) 103 | #define TEE_ERROR_PARSE_COMMANDLINE TEE_MK_ERROR(0x0007) 104 | #define TEE_ERROR_SMALL_BUFFER TEE_MK_ERROR(0x0008) 105 | #define TEE_ERROR_NOT_IMPLEMENTED TEE_MK_ERROR(0x0009) 106 | #define TEE_ERROR_CREATE_ENCLAVE TEE_MK_ERROR(0x000A) 107 | 108 | #define TEE_ERROR_FILE_OPEN TEE_MK_ERROR(0x0101) 109 | #define TEE_ERROR_FILE_READ TEE_MK_ERROR(0x0102) 110 | #define TEE_ERROR_FILE_WRITE TEE_MK_ERROR(0x0103) 111 | #define TEE_ERROR_FILE_EXIST TEE_MK_ERROR(0x0104) 112 | 113 | #define TEE_ERROR_CONF_LOAD TEE_MK_ERROR(0x0201) 114 | #define TEE_ERROR_CONF_NOTEXIST TEE_MK_ERROR(0x0202) 115 | 116 | #define TEE_ERROR_RA_NOTINITIALIZED TEE_MK_ERROR(0x0301) 117 | #define TEE_ERROR_RA_LOAD_CA_CERT TEE_MK_ERROR(0x0302) 118 | #define TEE_ERROR_RA_INVALID_AS_CERTS TEE_MK_ERROR(0x0303) 119 | #define TEE_ERROR_RA_TOO_MUCH_REPORT_DATA TEE_MK_ERROR(0x0304) 120 | #define TEE_ERROR_RA_IDENTITY_NOTINITIALIZED TEE_MK_ERROR(0x0305) 121 | 122 | #define TEE_ERROR_RA_VERIFY_SIG_INIT TEE_MK_ERROR(0x0310) 123 | #define TEE_ERROR_RA_VERIFY_CERT_DENIED TEE_MK_ERROR(0x0311) 124 | #define TEE_ERROR_RA_VERIFY_LOAD_CERT TEE_MK_ERROR(0x0312) 125 | #define TEE_ERROR_RA_VERIFY_GET_PUBKEY TEE_MK_ERROR(0x0313) 126 | #define TEE_ERROR_RA_VERIFY_GET_RSAKEY TEE_MK_ERROR(0x0314) 127 | #define TEE_ERROR_RA_VERIFY_SIGNATURE TEE_MK_ERROR(0x0315) 128 | #define TEE_ERROR_RA_VERIFY_QUOTE_STATUS TEE_MK_ERROR(0x0316) 129 | #define TEE_ERROR_RA_VERIFY_SIGNING_TYPE TEE_MK_ERROR(0x0317) 130 | #define TEE_ERROR_RA_VERIFY_SPID_NAME TEE_MK_ERROR(0x0318) 131 | #define TEE_ERROR_RA_VERIFY_PUBKEY TEE_MK_ERROR(0x0319) 132 | #define TEE_ERROR_RA_VERIFY_MRENCLAVE TEE_MK_ERROR(0x031A) 133 | #define TEE_ERROR_RA_VERIFY_MRSIGNER TEE_MK_ERROR(0x031B) 134 | #define TEE_ERROR_RA_VERIFY_USER_DATA TEE_MK_ERROR(0x031C) 135 | #define TEE_ERROR_RA_VERIFY_ISV_PORDID TEE_MK_ERROR(0x031D) 136 | #define TEE_ERROR_RA_VERIFY_ISV_SVN TEE_MK_ERROR(0x031E) 137 | 138 | #define TEE_ERROR_CRYPTO_SHA256 TEE_MK_ERROR(0x0401) 139 | #define TEE_ERROR_CRYPTO_BASE64 TEE_MK_ERROR(0x0402) 140 | #define TEE_ERROR_CRYPTO_RSA TEE_MK_ERROR(0x0403) 141 | #define TEE_ERROR_CRYPTO_CERT TEE_MK_ERROR(0x0404) 142 | #define TEE_ERROR_CRYPTO_RAND TEE_MK_ERROR(0x0405) 143 | #define TEE_ERROR_CRYPTO_RSA_SIGN TEE_MK_ERROR(0x0406) 144 | #define TEE_ERROR_CRYPTO_RSA_VERIFY TEE_MK_ERROR(0x0407) 145 | #define TEE_ERROR_CRYPTO_RSA_ENCRYPT TEE_MK_ERROR(0x0408) 146 | #define TEE_ERROR_CRYPTO_RSA_DECRYPT TEE_MK_ERROR(0x0409) 147 | 148 | #define TEE_ERROR_CRYPTO_AES_OUT_OF_MEMORY TEE_MK_ERROR(0x0440) 149 | #define TEE_ERROR_CRYPTO_AES_KEY_INVALID TEE_MK_ERROR(0x0441) 150 | #define TEE_ERROR_CRYPTO_AES_KEY_GENERATE TEE_MK_ERROR(0x0442) 151 | #define TEE_ERROR_CRYPTO_AES_IV_GENERATE TEE_MK_ERROR(0x0443) 152 | #define TEE_ERROR_CRYPTO_AES_ENCRYPT TEE_MK_ERROR(0x0444) 153 | #define TEE_ERROR_CRYPTO_AES_DECRYPT TEE_MK_ERROR(0x0445) 154 | 155 | #define TEE_ERROR_IAS_CLIENT_INIT TEE_MK_ERROR(0x0501) 156 | #define TEE_ERROR_IAS_CLIENT_CONNECT TEE_MK_ERROR(0x0502) 157 | #define TEE_ERROR_IAS_CLIENT_GETSIGRL TEE_MK_ERROR(0x0503) 158 | #define TEE_ERROR_IAS_CLIENT_GETREPORT TEE_MK_ERROR(0x0504) 159 | #define TEE_ERROR_IAS_CLIENT_UNESCAPE TEE_MK_ERROR(0x0505) 160 | #define TEE_ERROR_IAS_LOAD_CACHED_REPORT TEE_MK_ERROR(0x0506) 161 | 162 | #define TEE_ERROR_PROTOBUF_IFSTREAM TEE_MK_ERROR(0x0601) 163 | #define TEE_ERROR_PROTOBUF_OFSTREAM TEE_MK_ERROR(0x0602) 164 | #define TEE_ERROR_PROTOBUF_SERIALIZE TEE_MK_ERROR(0x0603) 165 | #define TEE_ERROR_PROTOBUF_PARSE TEE_MK_ERROR(0x0604) 166 | 167 | #define TEE_ERROR_PBCALL_FUNCTION TEE_MK_ERROR(0x0701) 168 | #define TEE_ERROR_PBCALL_ENCLAVE_ID TEE_MK_ERROR(0x0702) 169 | 170 | #define TEE_ERROR_KV_NOTEXIST TEE_MK_ERROR(0x0801) 171 | #define TEE_ERROR_KV_SET TEE_MK_ERROR(0x0802) 172 | #define TEE_ERROR_KV_GET TEE_MK_ERROR(0x0803) 173 | 174 | #define TEE_ERROR_LA_SESSION_NOT_EXISTS TEE_MK_ERROR(0x0901) 175 | #define TEE_ERROR_LA_INVALID_SESSION_STATUS TEE_MK_ERROR(0x0902) 176 | #define TEE_ERROR_LA_CHECK_IDENTITY TEE_MK_ERROR(0x0903) 177 | #define TEE_ERROR_LA_CLOSE_SESSION TEE_MK_ERROR(0x0904) 178 | #define TEE_ERROR_LA_GET_SECRET TEE_MK_ERROR(0x0905) 179 | #define TEE_ERROR_LA_PROCESS_SECRET TEE_MK_ERROR(0x0906) 180 | 181 | #define TEE_ERROR_SDK_UNEXPECTED TEE_MK_ERROR(0x0FFF) 182 | 183 | #define TEE_ERROR_CODE(rc) (rc) 184 | #define TEE_ERROR_MERGE(ecallcode, retcode) ((ecallcode) | (retcode)) 185 | 186 | // clang-format on 187 | 188 | #endif // SDK_INCLUDE_TEE_COMMON_ERROR_H_ 189 | -------------------------------------------------------------------------------- /sdk/include/tee/common/log.h: -------------------------------------------------------------------------------- 1 | #ifndef SDK_INCLUDE_TEE_COMMON_LOG_H_ 2 | #define SDK_INCLUDE_TEE_COMMON_LOG_H_ 3 | 4 | #include 5 | 6 | extern "C" int tee_printf(const char* fmt, ...); 7 | 8 | // Uncomment the line to enable buffer print 9 | // #define DEBUG_BUFFER 10 | 11 | #ifdef NOLOG 12 | #define TEE_LOG_DEBUG(fmt, ...) 13 | #define TEE_LOG_INFO(fmt, ...) 14 | #define TEE_LOG_WARN(fmt, ...) 15 | #define TEE_LOG_ERROR(fmt, ...) 16 | #define TEE_LOG_ERROR_TRACE() 17 | #define TEE_LOG_BUFFER(name, ptr, len) 18 | #define ELOG_DEBUG(fmt, ...) 19 | #define ELOG_INFO(fmt, ...) 20 | #define ELOG_WARN(fmt, ...) 21 | #define ELOG_ERROR(fmt, ...) 22 | #define ELOG_ERROR_TRACE() 23 | #define ELOG_BUFFER(name, ptr, len) 24 | 25 | #else // NOLOG 26 | 27 | // TEE_LOG_XXX are used in untrusted code, only disable 28 | // TEE_LOG_DEBUG and TEE_LOG_BUFFER in release mode. 29 | #ifdef DEBUG 30 | #define TEE_LOG_DEBUG(fmt, ...) \ 31 | tee_printf("[DEBUG][%s:%d] " fmt "\n", __FILE__, __LINE__, ##__VA_ARGS__) 32 | 33 | #ifdef DEBUG_BUFFER 34 | #define TEE_LOG_BUFFER(name, ptr, size) \ 35 | do { \ 36 | const uint8_t* buffer = reinterpret_cast(ptr); \ 37 | int len = static_cast((size)); \ 38 | tee_printf("Buffer %s, length: %d(0x%x)\n", (name), (len), (len)); \ 39 | for (int i = 0; i < len; i++) { \ 40 | if (i && (0 == i % 16)) tee_printf("\n"); \ 41 | tee_printf("%02x ", buffer[i]); \ 42 | } \ 43 | tee_printf("\n"); \ 44 | } while (0) 45 | #else 46 | #define TEE_LOG_BUFFER(name, ptr, len) 47 | #endif 48 | 49 | #else // not DEBUG for TEE_LOG_XXX 50 | #define TEE_LOG_DEBUG(fmt, ...) 51 | #define TEE_LOG_BUFFER(name, ptr, len) 52 | #endif // end DEBUG for TEE_LOG_XXX 53 | 54 | // Always enable INFO/WARN/ERROR for untrusted log message 55 | #define TEE_LOG_INFO(fmt, ...) \ 56 | tee_printf("[INFO][%s:%d] " fmt "\n", __FILE__, __LINE__, ##__VA_ARGS__) 57 | #define TEE_LOG_WARN(fmt, ...) \ 58 | tee_printf("[WARN][%s:%d] " fmt "\n", __FILE__, __LINE__, ##__VA_ARGS__) 59 | #define TEE_LOG_ERROR(fmt, ...) \ 60 | tee_printf("[ERROR][%s:%d] " fmt "\n", __FILE__, __LINE__, ##__VA_ARGS__) 61 | #define TEE_LOG_ERROR_TRACE() TEE_LOG_ERROR("[Function] %s", __FUNCTION__) 62 | 63 | // ELOG_XXX are used in common code and also trusted code 64 | // Only ELOG_ERROR is still enabled when enclave is release mode 65 | #ifdef DEBUG 66 | 67 | #define ELOG_DEBUG(fmt, ...) \ 68 | tee_printf("[DEBUG][%s:%d] " fmt "\n", __FILE__, __LINE__, ##__VA_ARGS__) 69 | #define ELOG_INFO(fmt, ...) \ 70 | tee_printf("[INFO][%s:%d] " fmt "\n", __FILE__, __LINE__, ##__VA_ARGS__) 71 | #define ELOG_WARN(fmt, ...) \ 72 | tee_printf("[WARN][%s:%d] " fmt "\n", __FILE__, __LINE__, ##__VA_ARGS__) 73 | 74 | #ifdef DEBUG_BUFFER 75 | #define ELOG_BUFFER(name, ptr, size) TEE_LOG_BUFFER(name, ptr, size) 76 | #else 77 | #define ELOG_BUFFER(name, ptr, len) 78 | #endif 79 | 80 | #else // not DEBUG for ELOG_XXX 81 | #define ELOG_DEBUG(fmt, ...) 82 | #define ELOG_INFO(fmt, ...) 83 | #define ELOG_WARN(fmt, ...) 84 | #define ELOG_BUFFER(name, ptr, len) 85 | #endif 86 | 87 | // Always enalbe ERROR for trusted log message 88 | #define ELOG_ERROR(fmt, ...) \ 89 | tee_printf("[ERROR][%s:%d] " fmt "\n", __FILE__, __LINE__, ##__VA_ARGS__) 90 | #define ELOG_ERROR_TRACE() ELOG_ERROR("[Function] %s", __FUNCTION__) 91 | 92 | #endif // NOLOG 93 | 94 | #endif // SDK_INCLUDE_TEE_COMMON_LOG_H_ 95 | -------------------------------------------------------------------------------- /sdk/include/tee/common/protobuf.h: -------------------------------------------------------------------------------- 1 | #ifndef SDK_INCLUDE_TEE_COMMON_PROTOBUF_H_ 2 | #define SDK_INCLUDE_TEE_COMMON_PROTOBUF_H_ 3 | 4 | #define PB_PARSE(pbmsg, pbstr) \ 5 | do { \ 6 | if (!(pbmsg).ParseFromString(pbstr)) { \ 7 | ELOG_ERROR("Fail to parse protobuf message: %s", #pbmsg); \ 8 | return TEE_ERROR_PROTOBUF_PARSE; \ 9 | } \ 10 | } while (0) 11 | 12 | #define PB_SERIALIZE(pbmsg, p_pbstr) \ 13 | do { \ 14 | if (!(pbmsg).SerializeToString(p_pbstr)) { \ 15 | ELOG_ERROR("Fail to serialize protobuf message: %s", #pbmsg); \ 16 | return TEE_ERROR_PROTOBUF_SERIALIZE; \ 17 | } \ 18 | } while (0) 19 | 20 | #endif // SDK_INCLUDE_TEE_COMMON_PROTOBUF_H_ 21 | -------------------------------------------------------------------------------- /sdk/include/tee/common/rsa.h: -------------------------------------------------------------------------------- 1 | #ifndef SDK_INCLUDE_TEE_COMMON_RSA_H_ 2 | #define SDK_INCLUDE_TEE_COMMON_RSA_H_ 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | #include "openssl/rsa.h" // RSA_PKCS1_OAEP_PADDING 10 | #include "tee/common/error.h" 11 | 12 | constexpr bool kIsPublicKey = true; 13 | constexpr bool kIsPrivateKey = false; 14 | constexpr char kRsaKeypairSeparator[] = "-----BEGIN RSA PRIVATE KEY-----"; 15 | constexpr char kRsaPubKeyEnd[] = "-----END RSA PUBLIC KEY-----"; 16 | 17 | namespace tee { 18 | namespace common { 19 | 20 | // Typedefs for memory management 21 | // Specify type and destroy function type for unique_ptrs 22 | typedef std::unique_ptr BIO_ptr; 23 | typedef std::unique_ptr BIGNUM_ptr; 24 | typedef std::unique_ptr RSA_ptr; 25 | 26 | class RsaCrypto { 27 | public: 28 | /// @brief Generate RSA key pair 29 | /// 30 | /// Generate public key and private key in PEM format. 31 | /// 32 | /// @param public_key 33 | /// @param private_key 34 | /// 35 | /// @return TEE_SUCCESS on success 36 | static TeeErrorCode GenerateKeyPair(std::string* public_key, 37 | std::string* private_key); 38 | 39 | /// @brief Encrypt 40 | /// 41 | /// @param public_key 42 | /// @param src 43 | /// @param dst, dst.length() will be the multiples of kRSAEncryptedTextLength. 44 | /// 45 | /// @return TEE_SUCCESS on success 46 | static TeeErrorCode Encrypt(const std::string& public_key, 47 | const std::string& src, std::string* dst); 48 | 49 | /// @brief Decrypt 50 | /// 51 | /// @param private_key 52 | /// @param src, src.length() should be the multiples of 53 | /// kRSAEncryptedTextLength 54 | /// @param dst 55 | /// 56 | /// @return TEE_SUCCESS on success 57 | static TeeErrorCode Decrypt(const std::string& private_key, 58 | const std::string& src, std::string* dst); 59 | 60 | /// @brief Sign 61 | /// 62 | /// @param private_key 63 | /// @param msg, the input message to be signed 64 | /// @param sigret, return the signature. 65 | /// @parem digest_type 66 | /// 67 | /// @return TEE_SUCCESS on success 68 | static TeeErrorCode Sign(const std::string& private_key, 69 | const std::string& msg, std::string* sigret); 70 | 71 | /// @brief Verify 72 | /// 73 | /// @param public_key 74 | /// @param msg, the input message to be signed 75 | /// @param sigbuf, signature data 76 | /// @param digest_type 77 | /// 78 | /// @return TEE_SUCCESS on success 79 | static TeeErrorCode Verify(const std::string& public_key, 80 | const std::string& msg, const std::string& sigbuf); 81 | 82 | /// @brief get_pem_public_key_size 83 | /// 84 | /// @param void 85 | /// 86 | /// @return the max size of buffer which is used to save pem type public key. 87 | static size_t get_pem_public_key_size() { 88 | return kPubKeyPemSize; 89 | } 90 | 91 | private: 92 | // TODO(junxian) USE 3072 for long term security 93 | // Inside enclave, With every doubling of the RSA key length, 94 | // decryption is 6-7 times times slower 95 | static const size_t kPubKeyPemSize = 4096; 96 | static const int kRSAKeySize = 2048; 97 | static const int kRSAPaddingSize = 41; 98 | static const int kRSAPaddingScheme = RSA_PKCS1_OAEP_PADDING; 99 | static const int kRSAPlainTextLength = 214; 100 | static constexpr int kRSAEncryptedTextLength = (kRSAKeySize / 8); 101 | static constexpr int kRSASignatureLength = (kRSAKeySize / 8); 102 | // OpenSSL Error string buffer size 103 | // ERR_error_string() generates a human-readable string 104 | // representing the error code e, and places it at buf. 105 | // buf must be at least 120 bytes long. 106 | // https://www.openssl.org/docs/man1.0.2/man3/ERR_error_string.html */ 107 | static const int kErrorBufferLength = 128; 108 | 109 | static TeeErrorCode GetKeyFromRSA(bool is_public_key, std::string* key, 110 | const RSA_ptr& rsa_ptr); 111 | static TeeErrorCode GetRSAFromKey(bool is_public_key, const std::string& key, 112 | RSA_ptr* rsa_ptr); 113 | 114 | /// @brief RSAEncrypt 115 | /// 116 | /// @param public_key 117 | /// @param src, src.length() should less than kRSAPlainTextLength 118 | /// @param dst, dst.length() should equal to kRSAEncryptedTextLength 119 | /// 120 | /// @return OASIS_SUCCESS on success 121 | static TeeErrorCode RSAEncrypt(const std::string& public_key, 122 | const std::string& src, std::string* dst); 123 | 124 | /// @brief RSADecrypt 125 | /// 126 | /// @param private_key 127 | /// @param src, src.length() should equal to kRSAEncryptedTextLength 128 | /// @param dst, dst.length() should less than kRSAPlainTextLength 129 | /// 130 | /// @return OASIS_SUCCESS on success 131 | static TeeErrorCode RSADecrypt(const std::string& private_key, 132 | const std::string& src, std::string* dst); 133 | /// @brief GetDecryptBufferSize 134 | /// 135 | /// @param 136 | /// 137 | /// @return Decrypt buffer size 138 | static int GetDecryptBufferSize(); 139 | 140 | /// @brief GetMaxEncryptBufferSize 141 | /// 142 | /// @param 143 | /// 144 | /// @return Max encrypt buffer size 145 | static int GetMaxEncryptBufferSize(); 146 | }; 147 | 148 | } // namespace common 149 | } // namespace tee 150 | 151 | #endif // SDK_INCLUDE_TEE_COMMON_RSA_H_ 152 | -------------------------------------------------------------------------------- /sdk/include/tee/common/scope.h: -------------------------------------------------------------------------------- 1 | #ifndef SDK_INCLUDE_TEE_COMMON_SCOPE_H_ 2 | #define SDK_INCLUDE_TEE_COMMON_SCOPE_H_ 3 | 4 | #include 5 | #include 6 | 7 | namespace tee { 8 | namespace common { 9 | 10 | class ScopeGuard { 11 | public: 12 | explicit ScopeGuard(std::function&& f) : f_(std::move(f)) {} 13 | ScopeGuard(const ScopeGuard&) = delete; 14 | ScopeGuard& operator=(const ScopeGuard&) = delete; 15 | ~ScopeGuard() { 16 | if (f_) { 17 | f_(); 18 | } 19 | } 20 | 21 | void release() { 22 | f_ = nullptr; 23 | } 24 | 25 | private: 26 | std::function f_; 27 | }; 28 | 29 | } // namespace common 30 | } // namespace tee 31 | 32 | #define SCOPEGUARD_LINENAME_CAT(name, line) name##line 33 | #define SCOPEGUARD_LINENAME(name, line) SCOPEGUARD_LINENAME_CAT(name, line) 34 | #define ON_SCOPE_EXIT(...) \ 35 | tee::common::ScopeGuard SCOPEGUARD_LINENAME(EXIT, __LINE__)(__VA_ARGS__) 36 | 37 | #endif // SDK_INCLUDE_TEE_COMMON_SCOPE_H_ 38 | -------------------------------------------------------------------------------- /sdk/include/tee/common/table.h: -------------------------------------------------------------------------------- 1 | #ifndef SDK_INCLUDE_TEE_COMMON_TABLE_H_ 2 | #define SDK_INCLUDE_TEE_COMMON_TABLE_H_ 3 | 4 | #include 5 | #include 6 | 7 | #include "tee/common/error.h" 8 | #include "tee/common/log.h" 9 | 10 | namespace tee { 11 | namespace common { 12 | 13 | template 14 | class DataTable { 15 | public: 16 | DataTable() {} 17 | ~DataTable() {} 18 | 19 | bool Exist(const std::string& key_name) { 20 | return (table_.find(key_name) != table_.end()) ? true : false; 21 | } 22 | 23 | T Get(const std::string& key_name) { 24 | return Exist(key_name) ? table_[key_name] : nullptr; 25 | } 26 | 27 | TeeErrorCode Add(const std::string& key_name, T value) { 28 | if (table_[key_name]) { 29 | ELOG_ERROR("Conflict name: %s", key_name.c_str()); 30 | return TEE_ERROR_PARAMETERS; 31 | } 32 | ELOG_DEBUG("Add: %s", key_name.c_str()); 33 | table_[key_name] = value; 34 | return TEE_SUCCESS; 35 | } 36 | 37 | private: 38 | std::map table_; 39 | }; 40 | 41 | } // namespace common 42 | } // namespace tee 43 | 44 | #endif // SDK_INCLUDE_TEE_COMMON_TABLE_H_ 45 | -------------------------------------------------------------------------------- /sdk/include/tee/common/type.h: -------------------------------------------------------------------------------- 1 | #ifndef SDK_INCLUDE_TEE_COMMON_TYPE_H_ 2 | #define SDK_INCLUDE_TEE_COMMON_TYPE_H_ 3 | 4 | #include 5 | #include "tee/common/error.h" 6 | #include "tee/common/log.h" 7 | 8 | #define RCAST(t, v) reinterpret_cast((v)) 9 | #define SCAST(t, v) static_cast((v)) 10 | #define CCAST(t, v) const_cast((v)) 11 | #define RCCAST(t, v) reinterpret_cast(const_cast((v))) 12 | 13 | // To ignore the parameters which is not used 14 | #define TEE_UNREFERENCED_PARAMETER(p) \ 15 | do { \ 16 | static_cast((p)); \ 17 | } while (0) 18 | 19 | // The template of one line code to check the function return value in 20 | // TeeErrorCode type. Usage: TEE_CHECK_RETURN(functionName(arg-list)); 21 | #define TEE_CHECK_RETURN(r) \ 22 | do { \ 23 | TeeErrorCode ret = (r); \ 24 | if (ret != TEE_SUCCESS) { \ 25 | ELOG_ERROR_TRACE(); \ 26 | return ret; \ 27 | } \ 28 | } while (0) 29 | 30 | typedef uint64_t EnclaveIdentity; 31 | 32 | // Generic format of trusted/untrusted function with serialized 33 | // protobuffer message type in/out parameters 34 | typedef TeeErrorCode (*PbFunction)(const std::string& req_str, 35 | std::string* res_str); 36 | 37 | #endif // SDK_INCLUDE_TEE_COMMON_TYPE_H_ 38 | -------------------------------------------------------------------------------- /sdk/include/tee/trusted/trusted_instance.h: -------------------------------------------------------------------------------- 1 | #ifndef SDK_INCLUDE_TEE_TRUSTED_TRUSTED_INSTANCE_H_ 2 | #define SDK_INCLUDE_TEE_TRUSTED_TRUSTED_INSTANCE_H_ 3 | 4 | #include 5 | #include 6 | 7 | #include "tee/common/error.h" 8 | #include "tee/common/log.h" 9 | #include "tee/common/protobuf.h" 10 | #include "tee/common/table.h" 11 | #include "tee/common/type.h" 12 | 13 | #include "./kubetee.pb.h" 14 | 15 | namespace tee { 16 | namespace trusted { 17 | 18 | class TeeInstance { 19 | public: 20 | static TeeInstance& GetInstance() { 21 | static TeeInstance instance_; 22 | return instance_; 23 | } 24 | 25 | TeeErrorCode ReeRun(const std::string& function_name, 26 | const google::protobuf::Message& request, 27 | google::protobuf::Message* response); 28 | 29 | TeeErrorCode SetOrCheckAttr(const tee::PbCallAttributes& attr); 30 | 31 | int64_t GetEnclaveID() { 32 | return enclave_id_; 33 | } 34 | 35 | void SetEnclaveID(int64_t id) { 36 | enclave_id_ = id; 37 | } 38 | 39 | std::string GetEnclaveName() { 40 | return enclave_name_; 41 | } 42 | 43 | void SetEnclaveName(const std::string& name) { 44 | enclave_name_ = name; 45 | } 46 | 47 | tee::KeyPair& GetIdentity() { 48 | return identity_keys_; 49 | } 50 | 51 | tee::EnclaveInformation& GetEnclaveInfo() { 52 | return enclave_info_; 53 | } 54 | 55 | TeeErrorCode CreateIdentity(); 56 | TeeErrorCode ImportIdentity(const tee::KeyPair& identity); 57 | TeeErrorCode CreateReport(const std::string& target_info, 58 | const std::string& user_data, 59 | const std::string& hex_spid, 60 | std::string* enclave_report); 61 | 62 | tee::common::DataTable& Functions() { 63 | return pb_ecall_functions_; 64 | } 65 | 66 | TeeErrorCode RegisterTrustedPbFunctions(); 67 | 68 | private: 69 | // Hide construction functions 70 | TeeInstance() { 71 | is_functions_registed_ = false; 72 | } 73 | TeeInstance(const TeeInstance&); 74 | void operator=(TeeInstance const&); 75 | 76 | int64_t enclave_id_; 77 | std::string enclave_name_; 78 | bool is_functions_registed_; 79 | tee::KeyPair identity_keys_; 80 | tee::EnclaveInformation enclave_info_; 81 | tee::common::DataTable pb_ecall_functions_; 82 | }; 83 | 84 | } // namespace trusted 85 | } // namespace tee 86 | 87 | #endif // SDK_INCLUDE_TEE_TRUSTED_TRUSTED_INSTANCE_H_ 88 | -------------------------------------------------------------------------------- /sdk/include/tee/trusted/trusted_pbcall.h: -------------------------------------------------------------------------------- 1 | #ifndef SDK_INCLUDE_TEE_TRUSTED_TRUSTED_PBCALL_H_ 2 | #define SDK_INCLUDE_TEE_TRUSTED_TRUSTED_PBCALL_H_ 3 | 4 | #include "tee/trusted/trusted_instance.h" 5 | 6 | #define ADD_TRUSTED_PBCALL_FUNCTION(f) \ 7 | tee::trusted::TeeInstance::GetInstance().Functions().Add(#f, f) 8 | 9 | #endif // SDK_INCLUDE_TEE_TRUSTED_TRUSTED_PBCALL_H_ 10 | -------------------------------------------------------------------------------- /sdk/include/tee/trusted/trusted_pbfunctions.h: -------------------------------------------------------------------------------- 1 | #ifndef SDK_INCLUDE_TEE_TRUSTED_TRUSTED_PBFUNCTIONS_H_ 2 | #define SDK_INCLUDE_TEE_TRUSTED_TRUSTED_PBFUNCTIONS_H_ 3 | 4 | #include 5 | 6 | #include "tee/common/error.h" 7 | 8 | #ifdef __cplusplus 9 | extern "C" { 10 | #endif 11 | 12 | extern TeeErrorCode RegisterTrustedPbFunctionsInternal(); 13 | extern TeeErrorCode RegisterTrustedPbFunctionsEx(); 14 | 15 | #ifdef __cplusplus 16 | } 17 | #endif 18 | 19 | #endif // SDK_INCLUDE_TEE_TRUSTED_TRUSTED_PBFUNCTIONS_H_ 20 | -------------------------------------------------------------------------------- /sdk/include/tee/trusted/utils/trusted_seal.h: -------------------------------------------------------------------------------- 1 | #ifndef SDK_INCLUDE_TEE_TRUSTED_UTILS_TRUSTED_SEAL_H_ 2 | #define SDK_INCLUDE_TEE_TRUSTED_UTILS_TRUSTED_SEAL_H_ 3 | 4 | #include 5 | 6 | #include "./sgx_attributes.h" 7 | #include "./sgx_tseal.h" 8 | 9 | #include "tee/common/error.h" 10 | 11 | namespace tee { 12 | namespace trusted { 13 | 14 | // clang-format off 15 | 16 | // Copy the following macros from SDK2.5 internal header files to use 17 | // sgx_seal_data_ex with SGX_KEYPOLICY_MRENCLAVE policy. sgx_seal_data 18 | // only support MISIGNER way, which will share data in all the enclaves 19 | // with the same signing key. See also tseal_migration_attr.h 20 | #define FLAGS_NON_SECURITY_BITS (0xFFFFFFFFFFFFC0ULL | \ 21 | SGX_FLAGS_MODE64BIT | \ 22 | SGX_FLAGS_PROVISION_KEY | \ 23 | SGX_FLAGS_EINITTOKEN_KEY) 24 | #define TSEAL_DEFAULT_FLAGSMASK (~FLAGS_NON_SECURITY_BITS) 25 | #define KEY_POLICY_KSS (SGX_KEYPOLICY_CONFIGID | \ 26 | SGX_KEYPOLICY_ISVFAMILYID | \ 27 | SGX_KEYPOLICY_ISVEXTPRODID) 28 | #define MISC_NON_SECURITY_BITS 0x0FFFFFFF 29 | #define TSEAL_DEFAULT_MISCMASK (~MISC_NON_SECURITY_BITS) 30 | 31 | // clang-format on 32 | 33 | class Sealer { 34 | public: 35 | Sealer() {} 36 | 37 | // Seal data with SGX_KEYPOLICY_MRSIGNER policy, the sealed data 38 | // can be unsealed by all enclaves with same MRSINGER and ProdID value. 39 | TeeErrorCode SealSignerData(const std::string& data, std::string* sealed); 40 | 41 | // Seal data with SGX_KEYPOLICY_MRENCLAVE policy, the sealed data 42 | // can be unsealed only by enclaves with same MRENCLAVE value. 43 | TeeErrorCode SealEnclaveData(const std::string& data, std::string* sealed); 44 | TeeErrorCode UnsealData(const std::string& sealed, std::string* data); 45 | 46 | private: 47 | const sgx_attributes_t attributes_ = {TSEAL_DEFAULT_FLAGSMASK, 0x0}; 48 | const sgx_misc_select_t misc_select_ = TSEAL_DEFAULT_MISCMASK; 49 | }; 50 | 51 | } // namespace trusted 52 | } // namespace tee 53 | 54 | #endif // SDK_INCLUDE_TEE_TRUSTED_UTILS_TRUSTED_SEAL_H_ 55 | -------------------------------------------------------------------------------- /sdk/include/tee/untrusted/enclave/untrusted_enclave.h: -------------------------------------------------------------------------------- 1 | #ifndef SDK_INCLUDE_TEE_UNTRUSTED_ENCLAVE_UNTRUSTED_ENCLAVE_H_ 2 | #define SDK_INCLUDE_TEE_UNTRUSTED_ENCLAVE_UNTRUSTED_ENCLAVE_H_ 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | #include "./sgx_uae_epid.h" 9 | #include "./sgx_urts.h" 10 | #include "./sgx_utils.h" 11 | 12 | #include "tee/common/bytes.h" 13 | #include "tee/common/error.h" 14 | #include "tee/common/table.h" 15 | #include "tee/common/type.h" 16 | 17 | #include "./kubetee.pb.h" 18 | 19 | namespace tee { 20 | namespace untrusted { 21 | 22 | // EnclaveInstance create one class instance for each enclave instance. 23 | // enclave instance include untrusted part and trusted part, the trusted 24 | // part is managed by TeeInstance 25 | class EnclaveInstance { 26 | public: 27 | // Create the normal enclave by name 28 | EnclaveInstance(const std::string& name, const std::string& filename); 29 | 30 | // Create the Protected Code Loader mode encrypted enclave by name 31 | EnclaveInstance(const std::string& name, const std::string& filename, 32 | const uint8_t* sealed_key); 33 | 34 | ~EnclaveInstance(); 35 | 36 | // Initialize method creates the identity RSA key pair inside enclave 37 | // and also prepare the enclave information for generating quote later 38 | TeeErrorCode Initialize(); 39 | 40 | // Initialize method with the cached identity RSA key pair. 41 | TeeErrorCode Initialize(const std::string& identity_sealed); 42 | 43 | // FetchQuote method is to get enclave quote 44 | // The result quote will be the input of the remote attestation. 45 | TeeErrorCode FetchQuote(std::string* pquote_b64); 46 | 47 | // Fetch RA report from Intel Attestation Service 48 | TeeErrorCode FetchIasReport(bool use_cache = true); 49 | 50 | // Run ECall Function based on serialized protobuf message parameters 51 | TeeErrorCode TeeRun(const std::string& function_name, 52 | const google::protobuf::Message& request, 53 | google::protobuf::Message* response); 54 | 55 | // Get the enclave EID, usually it's should be greater than 2 56 | EnclaveIdentity GetEnclaveID() { 57 | return eid_; 58 | } 59 | 60 | // Get the enclave name, the name should be unique, otherwise maybe the 61 | // wrong enclave instance will be found when GetEnclave(name) 62 | std::string GetEnclaveName() { 63 | return enclave_name_; 64 | } 65 | 66 | // Get the enclave identity public key, it should not be empty after 67 | // enclave instance is successfully initialized. 68 | std::string GetPublicKey() { 69 | return enclave_public_key_; 70 | } 71 | 72 | // Get the enclave information handler 73 | tee::EnclaveInformation& GetEnclaveInfo() { 74 | return enclave_info_; 75 | } 76 | 77 | // Get the local information handler 78 | tee::IasReport& GetLocalIasReport() { 79 | return ias_report_; 80 | } 81 | 82 | private: 83 | // service provider special settings 84 | const sgx_quote_sign_type_t quote_type_ = SGX_LINKABLE_SIGNATURE; 85 | 86 | // internal functions 87 | TeeErrorCode InitTargetInfo(std::string* target_info); 88 | TeeErrorCode GetQuote(std::string* pquote_b64); 89 | 90 | sgx_enclave_id_t eid_ = 0; 91 | sgx_epid_group_id_t gid_; 92 | sgx_target_info_t target_info_; 93 | std::string enclave_name_; 94 | std::string enclave_public_key_; 95 | std::string enclave_report_; 96 | tee::EnclaveInformation enclave_info_; 97 | tee::IasReport ias_report_; 98 | }; 99 | 100 | typedef std::shared_ptr EnclaveInstancePtr; 101 | typedef std::map EnclaveInstancesMap; 102 | 103 | // EnclavesManager is to manage enclaves instances together 104 | class EnclavesManager { 105 | public: 106 | // Gets the singleton enclave manager instance handler 107 | static EnclavesManager& GetInstance() { 108 | static EnclavesManager instance_; 109 | return instance_; 110 | } 111 | 112 | /// Create a new enclave instance and return the handler which points to it 113 | /// 114 | /// @param name specifies the name of this enclave instance 115 | /// @param filename specifies the name of the enclave so file 116 | /// 117 | /// @return EnclaveInstance pointer, nullptr on fail 118 | EnclaveInstance* CreateEnclave(const std::string& name, 119 | const std::string& filename); 120 | 121 | /// @brief Load encrypted enclave so file and create the enclave instance 122 | /// 123 | /// This is for the Protected Code Loader mode enclave work flow. 124 | /// @param name specifies the name of this enclave instance 125 | /// @param filename specifies the name of the enclave so file 126 | /// @param sealed_key specifies the key to decrypt encrypted enclave file 127 | /// 128 | /// @return TeeErrorCode type error code, TEE_SUCCESS or other error 129 | EnclaveInstance* CreateEnclave(const std::string& name, 130 | const std::string& filename, 131 | const uint8_t* sealed_key); 132 | 133 | /// @brief Simply destroy the enclave instance via its EID 134 | /// 135 | /// @param enclave specifies the pointer of the enclave instance 136 | /// 137 | /// @return TeeErrorCode type error code, TEE_SUCCESS or other error 138 | TeeErrorCode DestroyEnclave(EnclaveInstance* enclave); 139 | 140 | /// @brief Get the enclave instance pointer via its EID 141 | /// 142 | /// @param eid specifies the successfully created enclave instance ID 143 | /// 144 | /// @return The pointer to EnclaveInstance or nullptr 145 | EnclaveInstance* GetEnclave(const EnclaveIdentity eid); 146 | 147 | /// @brief Get the enclave instance pointer via its EID 148 | /// 149 | /// @param name specifies the enclave name 150 | /// 151 | /// @return The pointer to EnclaveInstance or nullptr 152 | EnclaveInstance* GetEnclave(const std::string& name); 153 | 154 | /// Get the ocall functions table 155 | tee::common::DataTable& Functions() { 156 | return pb_ocall_functions_; 157 | } 158 | 159 | /// Register all the untrusted PbFunctions (ocall functions) 160 | TeeErrorCode RegisterUntrustedPbFunctions(); 161 | 162 | private: 163 | // Hide construction functions 164 | EnclavesManager() { 165 | is_functions_registed_ = false; 166 | } 167 | EnclavesManager(const EnclavesManager&); 168 | void operator=(EnclavesManager const&); 169 | 170 | EnclaveInstancesMap enclaves_; 171 | bool is_functions_registed_; 172 | tee::common::DataTable pb_ocall_functions_; 173 | }; 174 | 175 | } // namespace untrusted 176 | } // namespace tee 177 | 178 | using tee::untrusted::EnclaveInstance; 179 | using tee::untrusted::EnclavesManager; 180 | 181 | #endif // SDK_INCLUDE_TEE_UNTRUSTED_ENCLAVE_UNTRUSTED_ENCLAVE_H_ 182 | -------------------------------------------------------------------------------- /sdk/include/tee/untrusted/ra/untrusted_challenger.h: -------------------------------------------------------------------------------- 1 | #ifndef SDK_INCLUDE_TEE_UNTRUSTED_RA_UNTRUSTED_CHALLENGER_H_ 2 | #define SDK_INCLUDE_TEE_UNTRUSTED_RA_UNTRUSTED_CHALLENGER_H_ 3 | 4 | #include 5 | #include 6 | 7 | #include "./sgx_quote.h" 8 | #include "./sgx_report.h" 9 | 10 | #include "tee/common/challenger.h" 11 | #include "tee/common/error.h" 12 | #include "tee/common/type.h" 13 | 14 | #include "./kubetee.pb.h" 15 | 16 | #ifdef __cplusplus 17 | extern "C" { 18 | #endif 19 | 20 | extern TeeErrorCode VerifyRaReport(const std::string& public_key, 21 | const tee::IasReport& ias_report); 22 | 23 | #ifdef __cplusplus 24 | } 25 | #endif 26 | 27 | #endif // SDK_INCLUDE_TEE_UNTRUSTED_RA_UNTRUSTED_CHALLENGER_H_ 28 | -------------------------------------------------------------------------------- /sdk/include/tee/untrusted/ra/untrusted_ias.h: -------------------------------------------------------------------------------- 1 | #ifndef SDK_INCLUDE_TEE_UNTRUSTED_RA_UNTRUSTED_IAS_H_ 2 | #define SDK_INCLUDE_TEE_UNTRUSTED_RA_UNTRUSTED_IAS_H_ 3 | 4 | #include 5 | #include 6 | 7 | #include "./sgx_quote.h" 8 | #include "./sgx_urts.h" 9 | #include "./sgx_utils.h" 10 | 11 | #include "curl/curl.h" 12 | 13 | #include "tee/common/bytes.h" 14 | #include "tee/common/error.h" 15 | #include "tee/common/type.h" 16 | 17 | #include "./kubetee.pb.h" 18 | 19 | namespace tee { 20 | namespace untrusted { 21 | 22 | class RaIasClient { 23 | public: 24 | RaIasClient(); 25 | ~RaIasClient(); 26 | 27 | TeeErrorCode GetSigRL(const sgx_epid_group_id_t* gid, DataBytes* sigrl); 28 | TeeErrorCode FetchReport(const std::string& b64_quote, 29 | tee::IasReport* ias_report); 30 | 31 | private: 32 | static std::string GetIasUrl(); 33 | static std::string GetHeaderValue(const std::string& header); 34 | static size_t ParseSigrlResponseBody(const char* contents, size_t size, 35 | size_t nmemb, void* response); 36 | static size_t ParseSigrlResponseHeader(const char* contents, size_t size, 37 | size_t nmemb, void* response); 38 | static size_t ParseReportResponseBody(const char* contents, size_t size, 39 | size_t nmemb, void* response); 40 | static size_t ParseReportResponseHeader(const char* contents, size_t size, 41 | size_t nmemb, void* response); 42 | 43 | CURL* curl_ = NULL; 44 | curl_slist* headers_ = NULL; 45 | 46 | static std::mutex init_mutex_; 47 | }; 48 | 49 | } // namespace untrusted 50 | } // namespace tee 51 | 52 | #endif // SDK_INCLUDE_TEE_UNTRUSTED_RA_UNTRUSTED_IAS_H_ 53 | -------------------------------------------------------------------------------- /sdk/include/tee/untrusted/untrusted_config.h: -------------------------------------------------------------------------------- 1 | #ifndef SDK_INCLUDE_TEE_UNTRUSTED_UNTRUSTED_CONFIG_H_ 2 | #define SDK_INCLUDE_TEE_UNTRUSTED_UNTRUSTED_CONFIG_H_ 3 | 4 | #include 5 | 6 | #include "tee/common/error.h" 7 | #include "tee/common/log.h" 8 | #include "tee/untrusted/utils/untrusted_json.h" 9 | 10 | namespace tee { 11 | namespace untrusted { 12 | 13 | constexpr char kConfFile[] = "kubetee.json"; 14 | 15 | constexpr char kConfIasURL[] = "ias_url"; 16 | constexpr char kConfIasAccessKey[] = "ias_access_key"; 17 | constexpr char kConfIasResponse[] = "ias_response_file"; 18 | constexpr char kConfIasResponseCache[] = "ias_response_cache"; 19 | 20 | constexpr char kConfSPID[] = "enclave_spid"; 21 | constexpr char kConfUserData[] = "enclave_user_data"; 22 | constexpr char kConfIdentity[] = "enclave_identity_file"; 23 | constexpr char kConfIdentityCache[] = "enclave_identity_cache"; 24 | 25 | constexpr char kConfRpcRemoteServer[] = "rpc_remote_server"; 26 | constexpr char kConfRpcRemotePort[] = "rpc_remote_port"; 27 | constexpr char kConfRpcServer[] = "rpc_server"; 28 | constexpr char kConfRpcPort[] = "rpc_port"; 29 | constexpr char kConfRpcCaPath[] = "rpc_ca_path"; 30 | constexpr char kConfRpcCertPath[] = "rpc_cert_path"; 31 | constexpr char kConfRpcKeyPath[] = "rpc_key_path"; 32 | 33 | } // namespace untrusted 34 | } // namespace tee 35 | 36 | #define GET_CONF_STR(name) JSON_CONF_STR(tee::untrusted::kConfFile, name) 37 | #define GET_CONF_INT(name, value) \ 38 | JSON_CONF_INT(tee::untrusted::kConfFile, name, value) 39 | #define GET_CONF_ARRARY(name, value) \ 40 | JSON_CONF_ARRAY(tee::untrusted::kConfFile, name, value) 41 | 42 | #endif // SDK_INCLUDE_TEE_UNTRUSTED_UNTRUSTED_CONFIG_H_ 43 | -------------------------------------------------------------------------------- /sdk/include/tee/untrusted/untrusted_pbcall.h: -------------------------------------------------------------------------------- 1 | #ifndef SDK_INCLUDE_TEE_UNTRUSTED_UNTRUSTED_PBCALL_H_ 2 | #define SDK_INCLUDE_TEE_UNTRUSTED_UNTRUSTED_PBCALL_H_ 3 | 4 | #include 5 | 6 | #include "tee/common/error.h" 7 | #include "tee/common/log.h" 8 | #include "tee/common/protobuf.h" 9 | 10 | #include "tee/untrusted/enclave/untrusted_enclave.h" 11 | 12 | #define ADD_UNTRUSTED_PBCALL_FUNCTION(f) \ 13 | tee::untrusted::EnclavesManager::GetInstance().Functions().Add(#f, f) 14 | 15 | #ifdef __cplusplus 16 | extern "C" { 17 | #endif 18 | 19 | extern TeeErrorCode RegisterUnTrustedPbFunctionsEx(); 20 | extern TeeErrorCode UntrustedMemoryMalloc(size_t size, char** buf); 21 | extern TeeErrorCode UntrustedMemoryFree(char** buf); 22 | 23 | #ifdef __cplusplus 24 | } 25 | #endif 26 | 27 | #endif // SDK_INCLUDE_TEE_UNTRUSTED_UNTRUSTED_PBCALL_H_ 28 | -------------------------------------------------------------------------------- /sdk/include/tee/untrusted/utils/untrusted_fs.h: -------------------------------------------------------------------------------- 1 | #ifndef SDK_INCLUDE_TEE_UNTRUSTED_UTILS_UNTRUSTED_FS_H_ 2 | #define SDK_INCLUDE_TEE_UNTRUSTED_UTILS_UNTRUSTED_FS_H_ 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | #include "tee/common/error.h" 9 | 10 | namespace tee { 11 | namespace untrusted { 12 | 13 | TeeErrorCode FsWriteString(const std::string& filename, const std::string& str); 14 | TeeErrorCode FsReadString(const std::string& filename, std::string* str); 15 | TeeErrorCode FsGetFileSize(const std::string& filename, size_t* size); 16 | bool FsFileExists(const std::string& filename); 17 | std::string GetFsString(const std::string& filename); 18 | 19 | } // namespace untrusted 20 | } // namespace tee 21 | 22 | #endif // SDK_INCLUDE_TEE_UNTRUSTED_UTILS_UNTRUSTED_FS_H_ 23 | -------------------------------------------------------------------------------- /sdk/include/tee/untrusted/utils/untrusted_json.h: -------------------------------------------------------------------------------- 1 | #ifndef SDK_INCLUDE_TEE_UNTRUSTED_UTILS_UNTRUSTED_JSON_H_ 2 | #define SDK_INCLUDE_TEE_UNTRUSTED_UTILS_UNTRUSTED_JSON_H_ 3 | 4 | #include 5 | #include 6 | 7 | #include "tee/common/error.h" 8 | #include "tee/common/log.h" 9 | #include "tee/common/type.h" 10 | 11 | #define JSON_CONF_STR(filename, name) GetConfStr((filename), (name)) 12 | #define JSON_CONF_ARRAY(filename, name, value) \ 13 | GetConfStrArray((filename), (name), (value)) 14 | #define JSON_CONF_INT(filename, name, value) \ 15 | GetConfInt((filename), (name), (value)) 16 | 17 | constexpr char kConfValueEnable[] = "enable"; 18 | constexpr char kConfValueDisable[] = "disable"; 19 | constexpr char kConfValueTrue[] = "true"; 20 | constexpr char kConfValueFalse[] = "false"; 21 | 22 | std::string GetConfStr(const std::string& conf_file, const char* name, 23 | const std::string& default_value = ""); 24 | TeeErrorCode GetConfStrArray(const std::string& conf_file, const char* name, 25 | std::vector* values); 26 | TeeErrorCode GetConfInt(const std::string& conf_file, const char* name, 27 | int* value); 28 | 29 | #endif // SDK_INCLUDE_TEE_UNTRUSTED_UTILS_UNTRUSTED_JSON_H_ 30 | -------------------------------------------------------------------------------- /sdk/trusted/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11") 2 | 3 | set(SGXSSL_INC /opt/intel/sgxssl/include) 4 | 5 | find_package(Protobuf REQUIRED) 6 | set(TEE_PROTO_FILES 7 | ${TEE_TOP_DIR}/proto/kubetee.proto 8 | ) 9 | PROTOBUF_GENERATE_CPP( 10 | TEE_PROTO_SRCS 11 | TEE_PROTO_HDRS 12 | ${CMAKE_BINARY_DIR} 13 | ${TEE_PROTO_FILES} 14 | ) 15 | 16 | file(GLOB COMMON_SRCS ${TOP_SRC_DIR}/common/*.cpp) 17 | file(GLOB TRUSTED_RA_SRCS ${CMAKE_CURRENT_SOURCE_DIR}/ra/*.cpp) 18 | file(GLOB TRUSTED_UTILS_SRCS ${CMAKE_CURRENT_SOURCE_DIR}/utils/*.cpp) 19 | file(GLOB TRUSTED_SRCS ${CMAKE_CURRENT_SOURCE_DIR}/*.cpp) 20 | 21 | set(EDL_FILE ${TOP_SRC_DIR}/edl/kubetee.edl) 22 | set(T_SRCS 23 | ${COMMON_SRCS} 24 | ${TRUSTED_SRCS} 25 | ${TRUSTED_RA_SRCS} 26 | ${TRUSTED_UTILS_SRCS} 27 | ${TEE_PROTO_SRCS} 28 | ) 29 | 30 | include_directories( 31 | ${TOP_SRC_DIR} 32 | ${TOP_SRC_DIR}/include 33 | ${TOP_SRC_DIR}/include/tee 34 | ${CMAKE_BINARY_DIR} 35 | ${CMAKE_CURRENT_BINARY_DIR} 36 | ${SGXSSL_INC} 37 | ${TEE_TOP_DIR}/third_party/cppcodec 38 | ${TEE_TOP_DIR}/third_party/protobuf-cpp/src/ 39 | ) 40 | 41 | set(TRUSTED_LIB tkubetee) 42 | add_trusted_library( 43 | ${TRUSTED_LIB} 44 | SRCS ${T_SRCS} 45 | EDL ${EDL_FILE} 46 | EDL_SEARCH_PATHS ${TOP_SRC_DIR}/edl 47 | ) 48 | 49 | target_link_libraries( 50 | ${TRUSTED_LIB} 51 | -ltprotobuf 52 | ) 53 | 54 | add_dependencies(${TRUSTED_LIB} tprotobuf) 55 | -------------------------------------------------------------------------------- /sdk/trusted/ra/trusted_ra.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | #include "./sgx_report.h" 8 | #include "./sgx_trts.h" 9 | #include "./sgx_utils.h" 10 | 11 | #include "tee/common/bytes.h" 12 | #include "tee/common/error.h" 13 | #include "tee/common/log.h" 14 | #include "tee/common/rsa.h" 15 | #include "tee/common/type.h" 16 | #include "tee/trusted/trusted_pbcall.h" 17 | #include "tee/trusted/utils/trusted_seal.h" 18 | 19 | #include "./kubetee_t.h" 20 | 21 | #ifdef __cplusplus 22 | extern "C" { 23 | #endif 24 | 25 | TeeErrorCode ecall_RaVerifyReport(sgx_target_info_t* target_info, 26 | sgx_report_t* target_report) { 27 | if (memcmp(target_info->mr_enclave.m, target_report->body.mr_enclave.m, 28 | sizeof(sgx_measurement_t)) != 0) { 29 | ELOG_ERROR("MRENCALVE mismatch when verify the target report"); 30 | return TEE_ERROR_GENERIC; 31 | } 32 | sgx_status_t sgx_ret = sgx_verify_report(target_report); 33 | if (sgx_ret != SGX_SUCCESS) { 34 | ELOG_ERROR("Fail to verify the target report"); 35 | return sgx_ret; 36 | } 37 | 38 | ELOG_DEBUG("Success to verify the target report"); 39 | return sgx_ret; 40 | } 41 | 42 | #ifdef __cplusplus 43 | } 44 | #endif 45 | -------------------------------------------------------------------------------- /sdk/trusted/trusted_instance.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #include "./sgx_trts.h" 6 | #include "./sgx_utils.h" 7 | 8 | #include "tee/common/aes.h" 9 | #include "tee/common/bytes.h" 10 | #include "tee/common/error.h" 11 | #include "tee/common/log.h" 12 | #include "tee/common/protobuf.h" 13 | #include "tee/common/rsa.h" 14 | #include "tee/common/type.h" 15 | #include "tee/trusted/trusted_pbcall.h" 16 | #include "tee/trusted/trusted_pbfunctions.h" 17 | 18 | #include "./kubetee.pb.h" 19 | #include "./kubetee_t.h" 20 | 21 | namespace tee { 22 | namespace trusted { 23 | 24 | TeeErrorCode TeeInstance::RegisterTrustedPbFunctions() { 25 | if (is_functions_registed_) { 26 | return TEE_SUCCESS; 27 | } 28 | 29 | ELOG_DEBUG("Register trusted functions ..."); 30 | TeeErrorCode ret = RegisterTrustedPbFunctionsInternal(); 31 | if (ret != TEE_SUCCESS) { 32 | ELOG_ERROR_TRACE(); 33 | return ret; 34 | } 35 | ret = RegisterTrustedPbFunctionsEx(); 36 | if (ret != TEE_SUCCESS) { 37 | ELOG_ERROR_TRACE(); 38 | return ret; 39 | } 40 | is_functions_registed_ = true; 41 | return TEE_SUCCESS; 42 | } 43 | 44 | TeeErrorCode TeeInstance::SetOrCheckAttr(const tee::PbCallAttributes& attr) { 45 | if (enclave_id_ == 0) { 46 | enclave_id_ = attr.enclave_id(); 47 | enclave_name_ = attr.enclave_name(); 48 | } else if (enclave_id_ != attr.enclave_id()) { 49 | ELOG_ERROR("Mismatched enclave ID: %ld", attr.enclave_id()); 50 | return TEE_ERROR_PBCALL_ENCLAVE_ID; 51 | } 52 | return TEE_SUCCESS; 53 | } 54 | 55 | TeeErrorCode TeeInstance::ReeRun(const std::string& function_name, 56 | const google::protobuf::Message& request, 57 | google::protobuf::Message* response) { 58 | std::string attr_str; 59 | tee::PbCallAttributes attr; 60 | attr.set_enclave_id(enclave_id_); 61 | attr.set_enclave_name(enclave_name_); 62 | attr.set_function_name(function_name); 63 | PB_SERIALIZE(attr, &attr_str); 64 | 65 | std::string req_str; 66 | PB_SERIALIZE(request, &req_str); 67 | 68 | char* res_buf = 0; 69 | size_t res_len = 0; 70 | TeeErrorCode ret = TEE_ERROR_GENERIC; 71 | sgx_status_t oc = SGX_ERROR_UNEXPECTED; 72 | oc = ocall_ReeRun(&ret, attr_str.data(), attr_str.length(), req_str.data(), 73 | req_str.size(), &res_buf, &res_len); 74 | if ((TEE_ERROR_MERGE(oc, ret)) != TEE_SUCCESS) { 75 | ELOG_ERROR("Fail to do ocall_ReeRun: 0x%x/0x%x", ret, oc); 76 | return TEE_ERROR_MERGE(oc, ret); 77 | } 78 | // The response may be empty 79 | if (res_buf && res_len) { 80 | std::string res_str(res_buf, res_len); 81 | PB_PARSE(*response, res_str); 82 | oc = ocall_UntrustedMemoryFree(&ret, &res_buf); 83 | if ((TEE_ERROR_MERGE(oc, ret)) != TEE_SUCCESS) { 84 | ELOG_ERROR("Fail to do ocall_UntrustedMemoryFree: 0x%x/0x%x", ret, oc); 85 | return TEE_ERROR_MERGE(oc, ret); 86 | } 87 | } else { 88 | ELOG_DEBUG("There is not response for ReeRun: %s", function_name.c_str()); 89 | } 90 | 91 | return TEE_SUCCESS; 92 | } 93 | 94 | TeeErrorCode TeeInstance::CreateIdentity() { 95 | tee::common::RsaCrypto rsa; 96 | std::string* public_key = identity_keys_.mutable_public_key(); 97 | std::string* private_key = identity_keys_.mutable_private_key(); 98 | TeeErrorCode ret = rsa.GenerateKeyPair(public_key, private_key); 99 | if (ret != TEE_SUCCESS) { 100 | ELOG_ERROR("Fail to create identity RSA key pair"); 101 | return ret; 102 | } 103 | 104 | size_t aes_key_size = tee::common::AesGcmCrypto::get_key_size(); 105 | std::string* aes_key = identity_keys_.mutable_aes_key(); 106 | aes_key->resize(aes_key_size, '\0'); 107 | uint8_t* pdata = RCAST(uint8_t*, CCAST(char*, aes_key->data())); 108 | sgx_status_t sgx_ret = sgx_read_rand(pdata, aes_key->size()); 109 | if (sgx_ret != SGX_SUCCESS) { 110 | ELOG_ERROR("Fail to create identity AES key"); 111 | return TEE_ERROR_CODE(sgx_ret); 112 | } 113 | 114 | return TEE_SUCCESS; 115 | } 116 | 117 | TeeErrorCode TeeInstance::ImportIdentity(const tee::KeyPair& identity) { 118 | if (identity.public_key().empty() || identity.private_key().empty() || 119 | identity.aes_key().empty()) { 120 | ELOG_ERROR("Invalid identity keys"); 121 | return TEE_ERROR_PARAMETERS; 122 | } 123 | identity_keys_ = identity; 124 | return TEE_SUCCESS; 125 | } 126 | 127 | TeeErrorCode TeeInstance::CreateReport(const std::string& target_info, 128 | const std::string& user_data, 129 | const std::string& hex_spid, 130 | std::string* enclave_report) { 131 | // Get the enclave identity public key 132 | using tee::trusted::TeeInstance; 133 | TeeInstance& ti = TeeInstance::GetInstance(); 134 | std::string enclave_public_key = ti.GetIdentity().public_key(); 135 | if (enclave_public_key.empty()) { 136 | ELOG_ERROR("Invalid enclave identity public key, maybe not initialized."); 137 | return TEE_ERROR_RA_IDENTITY_NOTINITIALIZED; 138 | } 139 | 140 | // calculate the public SHA256 HASH and copy it to report data 141 | sgx_report_data_t report_data; 142 | memset(&report_data, 0, sizeof(sgx_report_data_t)); 143 | tee::common::DataBytes pubkey_hash(enclave_public_key); 144 | if (pubkey_hash.ToSHA256().Export(report_data.d, SGX_HASH_SIZE).empty()) { 145 | ELOG_ERROR("Fail to compute sha256 for enclave public key"); 146 | return pubkey_hash.GetError(); 147 | } 148 | if (!user_data.empty() && (user_data.size() <= SGX_HASH_SIZE)) { 149 | memcpy(report_data.d + SGX_HASH_SIZE, user_data.data(), user_data.size()); 150 | } 151 | 152 | // create the enclave report with target info and report_data 153 | sgx_target_info_t* pinfo = RCCAST(sgx_target_info_t*, target_info.data()); 154 | sgx_report_t report; 155 | TeeErrorCode ret = sgx_create_report(pinfo, &report_data, &report); 156 | if (ret != TEE_SUCCESS) { 157 | ELOG_ERROR("Fail to create report"); 158 | return ret; 159 | } 160 | 161 | // save the enclave information 162 | tee::common::DataBytes mrenclave(report.body.mr_enclave.m, 163 | sizeof(sgx_measurement_t)); 164 | tee::common::DataBytes mrsigner(report.body.mr_signer.m, 165 | sizeof(sgx_measurement_t)); 166 | enclave_info_.set_hex_mrenclave(mrenclave.ToHexStr().GetStr()); 167 | enclave_info_.set_hex_mrsigner(mrsigner.ToHexStr().GetStr()); 168 | enclave_info_.set_hex_prod_id(std::to_string(report.body.isv_prod_id)); 169 | enclave_info_.set_hex_min_isvsvn(std::to_string(report.body.isv_svn)); 170 | enclave_info_.set_hex_user_data(user_data); 171 | enclave_info_.set_hex_spid(hex_spid); 172 | 173 | // return the report 174 | enclave_report->assign(RCAST(char*, &report), sizeof(sgx_report_t)); 175 | return TEE_SUCCESS; 176 | } 177 | 178 | } // namespace trusted 179 | } // namespace tee 180 | -------------------------------------------------------------------------------- /sdk/trusted/trusted_pbcall.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include "tee/common/bytes.h" 5 | #include "tee/common/error.h" 6 | #include "tee/common/log.h" 7 | #include "tee/common/protobuf.h" 8 | #include "tee/common/type.h" 9 | 10 | #include "./kubetee.pb.h" 11 | #include "./kubetee_t.h" 12 | 13 | #include "tee/trusted/trusted_pbcall.h" 14 | #include "tee/trusted/trusted_pbfunctions.h" 15 | 16 | #ifdef __cplusplus 17 | extern "C" { 18 | #endif 19 | 20 | // This week function may be overwritten in application enclave. 21 | TeeErrorCode __attribute__((weak)) RegisterTrustedPbFunctionsEx() { 22 | TEE_LOG_INFO("[WEAK] Register application trusted functions ..."); 23 | return TEE_SUCCESS; 24 | } 25 | 26 | TeeErrorCode ecall_TeeRun(const char* attr_buf, size_t attr_len, 27 | const char* req_buf, size_t req_len, char** res_buf, 28 | size_t* res_len) { 29 | // check and register functions firstly if they are not registered 30 | using tee::trusted::TeeInstance; 31 | TeeInstance& ti = TeeInstance::GetInstance(); 32 | TeeErrorCode ret = ti.RegisterTrustedPbFunctions(); 33 | if (ret != TEE_SUCCESS) { 34 | ELOG_ERROR_TRACE(); 35 | return ret; 36 | } 37 | 38 | // Default response length is zero if there is any thing wrong. 39 | *res_len = 0; 40 | *res_buf = 0; 41 | 42 | // Get the ecall attributes 43 | std::string attr_str(attr_buf, attr_len); 44 | tee::PbCallAttributes attr; 45 | if (!attr.ParseFromString(attr_str)) { 46 | ELOG_ERROR("Fail to parse ecall attributes"); 47 | return TEE_ERROR_PROTOBUF_PARSE; 48 | } 49 | 50 | // Get the ecall function handler 51 | ret = ti.SetOrCheckAttr(attr); 52 | if (ret != TEE_SUCCESS) { 53 | ELOG_ERROR_TRACE(); 54 | return ret; 55 | } 56 | 57 | // Find the function handler 58 | PbFunction function = ti.Functions().Get(attr.function_name()); 59 | if (!function) { 60 | ELOG_ERROR("Cannot find function: %s", attr.function_name().c_str()); 61 | return TEE_ERROR_PBCALL_FUNCTION; 62 | } 63 | 64 | // Execute the protobuf ecall function 65 | std::string req_str(req_buf, req_len); 66 | std::string res_str; 67 | ret = (*function)(req_str, &res_str); 68 | if (ret != TEE_SUCCESS) { 69 | ELOG_ERROR_TRACE(); 70 | return ret; 71 | } 72 | 73 | // Allocate the untrusted memory to return the response 74 | // !!! Need to free outside of enclave 75 | if (res_str.length()) { 76 | sgx_status_t sc = SGX_ERROR_UNEXPECTED; 77 | sc = ocall_UntrustedMemoryAlloc(&ret, res_str.length(), res_buf); 78 | if ((TEE_ERROR_MERGE(ret, sc) != TEE_SUCCESS) || !(*res_buf)) { 79 | ELOG_ERROR("Fail to allocate untrusted memory: len=%ld", 80 | res_str.length()); 81 | return TEE_ERROR_MERGE(ret, sc); 82 | } 83 | memcpy(*res_buf, res_str.data(), res_str.size()); 84 | } 85 | 86 | *res_len = res_str.length(); 87 | return TEE_SUCCESS; 88 | } 89 | 90 | #ifdef __cplusplus 91 | } 92 | #endif 93 | -------------------------------------------------------------------------------- /sdk/trusted/trusted_pbfunctions.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | #include "./sgx_trts.h" 7 | #include "./sgx_utils.h" 8 | 9 | #include "tee/common/bytes.h" 10 | #include "tee/common/error.h" 11 | #include "tee/common/log.h" 12 | #include "tee/common/type.h" 13 | #include "tee/trusted/trusted_instance.h" 14 | #include "tee/trusted/trusted_pbcall.h" 15 | #include "tee/trusted/trusted_pbfunctions.h" 16 | #include "tee/trusted/utils/trusted_seal.h" 17 | 18 | #include "./kubetee_t.h" 19 | 20 | #ifdef __cplusplus 21 | extern "C" { 22 | #endif 23 | 24 | using tee::trusted::TeeInstance; 25 | 26 | TeeErrorCode TeeInitializeEnclave(const std::string& req_str, 27 | std::string* res_str) { 28 | tee::PbInitializeEnclaveRequest req; 29 | tee::PbInitializeEnclaveResponse res; 30 | PB_PARSE(req, req_str); 31 | 32 | TeeInstance& ti = TeeInstance::GetInstance(); 33 | ti.SetEnclaveID(req.enclave_id()); 34 | ti.SetEnclaveName(req.enclave_name()); 35 | 36 | tee::trusted::Sealer sealer; 37 | std::string identity_str; 38 | if (!req.sealed_identity().empty()) { 39 | TEE_CHECK_RETURN(sealer.UnsealData(req.sealed_identity(), &identity_str)); 40 | tee::KeyPair identity; 41 | PB_PARSE(identity, identity_str); 42 | TEE_CHECK_RETURN(ti.ImportIdentity(identity)); 43 | ELOG_INFO("Reload local identity key pair successfully"); 44 | } else { 45 | TEE_CHECK_RETURN(ti.CreateIdentity()); 46 | std::string sealed_identity; 47 | PB_SERIALIZE(ti.GetIdentity(), &identity_str); 48 | TEE_CHECK_RETURN(sealer.SealSignerData(identity_str, &sealed_identity)); 49 | res.set_enclave_identity(sealed_identity); 50 | ELOG_INFO("Generate new identity key pair successfully"); 51 | } 52 | 53 | // Return identity public key by response 54 | res.set_enclave_public_key(ti.GetIdentity().public_key()); 55 | // Create the enclave report and return by response 56 | TEE_CHECK_RETURN(ti.CreateReport(req.target_info(), req.user_data(), 57 | req.hex_spid(), 58 | res.mutable_enclave_report())); 59 | res.mutable_enclave_info()->CopyFrom(ti.GetEnclaveInfo()); 60 | PB_SERIALIZE(res, res_str); 61 | return TEE_SUCCESS; 62 | } 63 | 64 | // Please register all above functions here 65 | TeeErrorCode RegisterTrustedPbFunctionsInternal() { 66 | ADD_TRUSTED_PBCALL_FUNCTION(TeeInitializeEnclave); 67 | return TEE_SUCCESS; 68 | } 69 | 70 | #ifdef __cplusplus 71 | } 72 | #endif 73 | -------------------------------------------------------------------------------- /sdk/trusted/utils/trusted_crypto.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include "./sgx_trts.h" 4 | 5 | #include "tee/common/error.h" 6 | #include "tee/common/type.h" 7 | 8 | #include "./kubetee_t.h" 9 | 10 | #ifdef __cplusplus 11 | extern "C" { 12 | #endif 13 | 14 | TeeErrorCode ecall_GetRand(uint8_t* rand, uint32_t len) { 15 | return TEE_ERROR_CODE(sgx_read_rand(rand, len)); 16 | } 17 | 18 | #ifdef __cplusplus 19 | } 20 | #endif 21 | -------------------------------------------------------------------------------- /sdk/trusted/utils/trusted_log.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include "./kubetee_t.h" 5 | #include "tee/common/log.h" 6 | 7 | #ifdef __cplusplus 8 | extern "C" { 9 | #endif 10 | 11 | int tee_printf(const char* fmt, ...) { 12 | constexpr size_t kMaxLogBufSzie = 4096; 13 | char buf[kMaxLogBufSzie] = {'\0'}; 14 | va_list ap; 15 | 16 | va_start(ap, fmt); 17 | vsnprintf(buf, kMaxLogBufSzie, fmt, ap); 18 | va_end(ap); 19 | 20 | // Add the special suffix to notify the limitation of buffer length 21 | if (strlen(buf) >= (kMaxLogBufSzie - 4)) { 22 | buf[kMaxLogBufSzie - 4] = '.'; 23 | buf[kMaxLogBufSzie - 3] = '.'; 24 | buf[kMaxLogBufSzie - 2] = '.'; 25 | buf[kMaxLogBufSzie - 1] = 0; 26 | } 27 | 28 | return ocall_PrintMessage(buf); 29 | } 30 | 31 | /// Because the protobuf files include the std headers and use printf 32 | /// So there must be a implement of printf 33 | int printf(const char* fmt, ...) { 34 | constexpr size_t kMaxLogBufSzie = 4096; 35 | char buf[kMaxLogBufSzie] = {'\0'}; 36 | va_list ap; 37 | 38 | va_start(ap, fmt); 39 | vsnprintf(buf, kMaxLogBufSzie, fmt, ap); 40 | va_end(ap); 41 | 42 | // Add the special suffix to notify the limitation of buffer length 43 | if (strlen(buf) >= (kMaxLogBufSzie - 4)) { 44 | buf[kMaxLogBufSzie - 4] = '.'; 45 | buf[kMaxLogBufSzie - 3] = '.'; 46 | buf[kMaxLogBufSzie - 2] = '.'; 47 | buf[kMaxLogBufSzie - 1] = 0; 48 | } 49 | 50 | return ocall_PrintMessage(buf); 51 | } 52 | 53 | #ifdef __cplusplus 54 | } 55 | #endif 56 | -------------------------------------------------------------------------------- /sdk/trusted/utils/trusted_seal.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include "./sgx_utils.h" 5 | 6 | #include "tee/common/bytes.h" 7 | #include "tee/common/error.h" 8 | #include "tee/common/log.h" 9 | #include "tee/common/type.h" 10 | #include "tee/trusted/utils/trusted_seal.h" 11 | 12 | namespace tee { 13 | namespace trusted { 14 | 15 | TeeErrorCode Sealer::SealSignerData(const std::string& data, 16 | std::string* sealed) { 17 | if (data.empty()) { 18 | ELOG_ERROR("Empty data to be sealed!"); 19 | return TEE_ERROR_PARAMETERS; 20 | } 21 | 22 | // Allocate the sealed buffer 23 | uint32_t data_size = SCAST(uint32_t, data.size()); 24 | uint32_t sealed_size = sgx_calc_sealed_data_size(0, data_size); 25 | sealed->resize(sealed_size); 26 | 27 | // Seal data 28 | uint8_t* pdata = RCAST(uint8_t*, CCAST(char*, data.data())); 29 | uint8_t* psealed = RCAST(uint8_t*, CCAST(char*, sealed->data())); 30 | sgx_status_t ret = sgx_seal_data(0, nullptr, data_size, pdata, sealed_size, 31 | RCAST(sgx_sealed_data_t*, psealed)); 32 | if (ret != SGX_SUCCESS) { 33 | ELOG_ERROR("Failed to seal data of signer: 0x%x", ret); 34 | return TEE_ERROR_CODE(ret); 35 | } 36 | 37 | return TEE_SUCCESS; 38 | } 39 | 40 | TeeErrorCode Sealer::SealEnclaveData(const std::string& data, 41 | std::string* sealed) { 42 | if (data.empty()) { 43 | ELOG_ERROR("Empty data to be sealed!"); 44 | return TEE_ERROR_PARAMETERS; 45 | } 46 | 47 | // Allocate the sealed buffer 48 | uint32_t data_size = SCAST(uint32_t, data.size()); 49 | uint32_t sealed_size = sgx_calc_sealed_data_size(0, data_size); 50 | sealed->resize(sealed_size); 51 | 52 | // Seal data 53 | uint8_t* pdata = RCAST(uint8_t*, CCAST(char*, data.data())); 54 | uint8_t* psealed = RCAST(uint8_t*, CCAST(char*, sealed->data())); 55 | sgx_status_t ret = sgx_seal_data_ex( 56 | SGX_KEYPOLICY_MRENCLAVE, attributes_, misc_select_, 0, nullptr, data_size, 57 | pdata, sealed_size, RCAST(sgx_sealed_data_t*, psealed)); 58 | if (ret != SGX_SUCCESS) { 59 | ELOG_ERROR("Failed to seal data of enclave: 0x%x", ret); 60 | return TEE_ERROR_CODE(ret); 61 | } 62 | 63 | return TEE_SUCCESS; 64 | } 65 | 66 | TeeErrorCode Sealer::UnsealData(const std::string& sealed, std::string* data) { 67 | if (sealed.empty()) { 68 | ELOG_ERROR("Empty sealed data to be unsealed!"); 69 | return TEE_ERROR_PARAMETERS; 70 | } 71 | 72 | const sgx_sealed_data_t* psealed = 73 | RCAST(const sgx_sealed_data_t*, sealed.data()); 74 | uint32_t data_size = sgx_get_encrypt_txt_len(psealed); 75 | data->resize(data_size); 76 | 77 | uint8_t* pdata = RCAST(uint8_t*, CCAST(char*, data->data())); 78 | uint32_t returned_size = data_size; 79 | sgx_status_t ret = sgx_unseal_data(psealed, NULL, 0, pdata, &returned_size); 80 | if ((ret != SGX_SUCCESS) || (data_size != returned_size)) { 81 | ELOG_ERROR("Fail to unseal data: 0x%x\n", ret); 82 | return TEE_ERROR_CODE(ret); 83 | } 84 | 85 | return TEE_SUCCESS; 86 | } 87 | 88 | } // namespace trusted 89 | } // namespace tee 90 | -------------------------------------------------------------------------------- /sdk/untrusted/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | list(APPEND CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake) 2 | find_package(SGX REQUIRED) 3 | find_package(Protobuf REQUIRED) 4 | find_package(GRPC REQUIRED) 5 | 6 | set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11") 7 | 8 | file(GLOB COMMON_SRCS ${TOP_SRC_DIR}/common/*.cpp) 9 | file(GLOB UNTRUSTED_SRCS ${CMAKE_CURRENT_SOURCE_DIR}/*.cpp) 10 | file(GLOB UNTRUSTED_ENCLAVE_SRCS ${CMAKE_CURRENT_SOURCE_DIR}/enclave/*.cpp) 11 | file(GLOB UNTRUSTED_RA_SRCS ${CMAKE_CURRENT_SOURCE_DIR}/ra/*.cpp) 12 | file(GLOB UNTRUSTED_UTILS_SRCS ${CMAKE_CURRENT_SOURCE_DIR}/utils/*.cpp) 13 | file(GLOB PROTO_FILES ${TEE_TOP_DIR}/proto/*.proto) 14 | PROTOBUF_GENERATE_CPP(PROTO_SRCS PROTO_HDRS ${CMAKE_BINARY_DIR} ${PROTO_FILES}) 15 | 16 | set(EDL_SEARCH_PATHS ${TOP_SRC_DIR}/edl) 17 | set(EDL_FILE ${TOP_SRC_DIR}/edl/kubetee.edl) 18 | set(U_SRCS 19 | ${COMMON_SRCS} 20 | ${UNTRUSTED_SRCS} 21 | ${UNTRUSTED_ENCLAVE_SRCS} 22 | ${UNTRUSTED_RA_SRCS} 23 | ${UNTRUSTED_UTILS_SRCS} 24 | ${PROTO_SRCS} 25 | ) 26 | 27 | set(UNTRUSTED_LIB ukubetee) 28 | add_untrusted_library( 29 | ${UNTRUSTED_LIB} SHARED 30 | SRCS ${U_SRCS} 31 | EDL ${EDL_FILE} 32 | EDL_SEARCH_PATHS ${EDL_SEARCH_PATHS} 33 | ) 34 | target_include_directories( 35 | ${UNTRUSTED_LIB} PUBLIC 36 | ${TOP_SRC_DIR} 37 | ${TOP_SRC_DIR}/include 38 | ${TOP_SRC_DIR}/include/tee 39 | ${CMAKE_BINARY_DIR} 40 | ${CMAKE_CURRENT_BINARY_DIR} 41 | /usr/include/openssl/../ 42 | ${TEE_TOP_DIR}/third_party/cppcodec 43 | ${TEE_TOP_DIR}/third_party/rapidjson/include 44 | ) 45 | target_link_libraries( 46 | ${UNTRUSTED_LIB} 47 | -lcurl -lprotobuf 48 | -Wl,-rpath=.:/lib64:/usr/local/lib:/usr/local/lib64:${SGX_LIBRARY_DIR} 49 | ) 50 | -------------------------------------------------------------------------------- /sdk/untrusted/challenger/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | list(APPEND CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake) 2 | find_package(Protobuf REQUIRED) 3 | 4 | file(GLOB COMMON_SRCS ${TOP_SRC_DIR}/common/*.cpp) 5 | file(GLOB UTILS_SRCS ${TOP_SRC_DIR}/untrusted/utils/*.cpp) 6 | file(GLOB CHALLENGER_SRCS ${CMAKE_CURRENT_SOURCE_DIR}/*.cpp) 7 | file(GLOB PROTO_FILES ${TEE_TOP_DIR}/proto/*.proto) 8 | PROTOBUF_GENERATE_CPP(PROTO_SRCS PROTO_HDRS ${CMAKE_BINARY_DIR} ${PROTO_FILES}) 9 | 10 | set(C_SRCS 11 | ${COMMON_SRCS} 12 | ${UTILS_SRCS} 13 | ${CHALLENGER_SRCS} 14 | ${TOP_SRC_DIR/untrusted/ra/untrusted_config.cpp} 15 | ${PROTO_SRCS} 16 | ) 17 | 18 | add_library(challenger SHARED ${C_SRCS}) 19 | target_include_directories( 20 | challenger PUBLIC 21 | ${TOP_SRC_DIR} 22 | ${TOP_SRC_DIR}/include 23 | ${TOP_SRC_DIR}/include/tee 24 | ${CMAKE_BINARY_DIR} 25 | ${CMAKE_CURRENT_BINARY_DIR} 26 | ${SGX_INCLUDE_DIR} 27 | /usr/include/openssl/../ 28 | ${TEE_TOP_DIR}/third_party/cppcodec 29 | ${TEE_TOP_DIR}/third_party/rapidjson/include 30 | ) 31 | -------------------------------------------------------------------------------- /sdk/untrusted/challenger/untrusted_challenger.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include "tee/common/challenger.h" 4 | #include "tee/common/error.h" 5 | 6 | #include "tee/untrusted/ra/untrusted_challenger.h" 7 | 8 | #include "untrusted/challenger/untrusted_challenger_config.h" 9 | 10 | #ifdef __cplusplus 11 | extern "C" { 12 | #endif 13 | 14 | TeeErrorCode VerifyRaReport(const std::string& public_key, 15 | const tee::IasReport& ias_report) { 16 | // Fill the match rules 17 | tee::EnclaveMatchRules rules; 18 | tee::EnclaveInformation* enclave_info = rules.add_entries(); 19 | enclave_info->set_hex_mrenclave(VERIFY_CONF_STR(kConfVerifyMRENCLAVE)); 20 | enclave_info->set_hex_mrsigner(VERIFY_CONF_STR(kConfVerifyMRSIGNER)); 21 | enclave_info->set_hex_prod_id(VERIFY_CONF_STR(kConfVerifyProdID)); 22 | enclave_info->set_hex_min_isvsvn(VERIFY_CONF_STR(kConfVerifySVN)); 23 | enclave_info->set_hex_user_data(VERIFY_CONF_STR(kConfVerifyUserData)); 24 | enclave_info->set_hex_spid(VERIFY_CONF_STR(kConfVerifySPID)); 25 | 26 | // Verify the RA report 27 | tee::common::RaChallenger ch(public_key, rules); 28 | return ch.VerifyReport(ias_report); 29 | } 30 | 31 | #ifdef __cplusplus 32 | } 33 | #endif 34 | -------------------------------------------------------------------------------- /sdk/untrusted/challenger/untrusted_challenger_config.h: -------------------------------------------------------------------------------- 1 | #ifndef SDK_UNTRUSTED_CHALLENGER_UNTRUSTED_CHALLENGER_CONFIG_H_ 2 | #define SDK_UNTRUSTED_CHALLENGER_UNTRUSTED_CHALLENGER_CONFIG_H_ 3 | 4 | #include 5 | 6 | #include "tee/common/error.h" 7 | #include "tee/common/log.h" 8 | #include "tee/untrusted/utils/untrusted_json.h" 9 | 10 | constexpr char kVerifyConf[] = "kubetee.json"; 11 | 12 | constexpr char kConfVerifyMRENCLAVE[] = "verify_mrenclave"; 13 | constexpr char kConfVerifyMRSIGNER[] = "verify_mrsigner"; 14 | constexpr char kConfVerifySPID[] = "verify_spid"; 15 | constexpr char kConfVerifyUserData[] = "verify_user_hash"; 16 | constexpr char kConfVerifyProdID[] = "verify_prodid"; 17 | constexpr char kConfVerifySVN[] = "verify_min_svn"; 18 | 19 | #define VERIFY_CONF_STR(name) JSON_CONF_STR(kVerifyConf, (name)) 20 | #define VERIFY_CONF_INT(name, value) JSON_CONF_INT(kVerifyConf, (name), (value)) 21 | #define VERIFY_CONF_ARRARY(name, value) \ 22 | JSON_CONF_ARRAY(kVerifyConf, (name), (value)) 23 | 24 | #endif // SDK_UNTRUSTED_CHALLENGER_UNTRUSTED_CHALLENGER_CONFIG_H_ 25 | -------------------------------------------------------------------------------- /sdk/untrusted/untrusted_pbcall.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include "./sgx_urts.h" 4 | #include "./sgx_utils.h" 5 | 6 | #include "tee/common/bytes.h" 7 | #include "tee/common/error.h" 8 | #include "tee/common/log.h" 9 | #include "tee/common/type.h" 10 | 11 | #include "./kubetee.pb.h" 12 | #include "./kubetee_u.h" 13 | 14 | #include "tee/untrusted/untrusted_pbcall.h" 15 | 16 | #ifdef __cplusplus 17 | extern "C" { 18 | #endif 19 | 20 | #ifdef DEBUG 21 | static size_t m_count = 0; 22 | #endif 23 | 24 | TeeErrorCode UntrustedMemoryAlloc(size_t size, char** buf) { 25 | if (size == 0) { 26 | return TEE_ERROR_PARAMETERS; 27 | } 28 | 29 | char* buf_allocated = static_cast(malloc(size)); 30 | if (!buf_allocated) { 31 | TEE_LOG_ERROR("Fail to allocate memory: len=%ld", size); 32 | return TEE_ERROR_MALLOC; 33 | } 34 | 35 | #ifdef DEBUG 36 | TEE_LOG_DEBUG("Untrusted Alloc[%ld]: +%p", ++m_count, buf_allocated); 37 | #endif 38 | *buf = buf_allocated; 39 | return TEE_SUCCESS; 40 | } 41 | 42 | TeeErrorCode UntrustedMemoryFree(char** buf) { 43 | if (*buf == nullptr) { 44 | TEE_LOG_ERROR("Try to UntrustedMemoryFree nullptr"); 45 | return TEE_ERROR_PARAMETERS; 46 | } 47 | 48 | #ifdef DEBUG 49 | TEE_LOG_DEBUG("Untrusted Free[%ld]: -%p", --m_count, *buf); 50 | #endif 51 | free(*buf); 52 | *buf = 0; 53 | return TEE_SUCCESS; 54 | } 55 | 56 | TeeErrorCode ocall_UntrustedMemoryAlloc(size_t size, char** buf) { 57 | return UntrustedMemoryAlloc(size, buf); 58 | } 59 | 60 | TeeErrorCode ocall_UntrustedMemoryFree(char** buf) { 61 | UntrustedMemoryFree(buf); 62 | return TEE_SUCCESS; 63 | } 64 | 65 | TeeErrorCode ocall_ReeRun(const char* attr_buf, size_t attr_len, 66 | const char* req_buf, size_t req_len, char** res_buf, 67 | size_t* res_len) { 68 | // Initialize the return buffer to be empty 69 | *res_buf = 0; 70 | *res_len = 0; 71 | 72 | // When the first time to call ReeRun, register all untrusted functions 73 | using tee::untrusted::EnclavesManager; 74 | EnclavesManager& em = EnclavesManager::GetInstance(); 75 | TeeErrorCode ret = em.RegisterUntrustedPbFunctions(); 76 | if (ret != TEE_SUCCESS) { 77 | TEE_LOG_ERROR_TRACE(); 78 | return ret; 79 | } 80 | 81 | // Get the function name 82 | std::string attr_str(attr_buf, attr_len); 83 | tee::PbCallAttributes attr; 84 | PB_PARSE(attr, attr_str); 85 | PbFunction function = em.Functions().Get(attr.function_name()); 86 | if (!function) { 87 | ELOG_ERROR("Cannot find function: %s", attr.function_name().c_str()); 88 | return TEE_ERROR_PBCALL_FUNCTION; 89 | } 90 | 91 | // Execute the untrusted function 92 | std::string req_str(req_buf, req_len); 93 | std::string res_str; 94 | ret = (*function)(req_str, &res_str); 95 | if (ret != TEE_SUCCESS) { 96 | ELOG_ERROR_TRACE(); 97 | return ret; 98 | } 99 | // And set the return buffer the response is not empty 100 | if (res_str.size()) { 101 | TEE_CHECK_RETURN(UntrustedMemoryAlloc(res_str.size(), res_buf)); 102 | memcpy(*res_buf, res_str.data(), res_str.size()); 103 | *res_len = res_str.size(); 104 | } 105 | 106 | TEE_LOG_DEBUG("Ocall ReeRun, response addr/len=%p/%ld", *res_buf, *res_len); 107 | return TEE_SUCCESS; 108 | } 109 | 110 | #ifdef __cplusplus 111 | } 112 | #endif 113 | -------------------------------------------------------------------------------- /sdk/untrusted/utils/untrusted_fs.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | #include "tee/common/error.h" 7 | #include "tee/common/log.h" 8 | 9 | #include "tee/untrusted/utils/untrusted_fs.h" 10 | 11 | namespace tee { 12 | namespace untrusted { 13 | 14 | TeeErrorCode FsWriteString(const std::string& filename, 15 | const std::string& str) { 16 | std::ofstream ofs(filename, 17 | std::ios::binary | std::ios::out | std::ios::trunc); 18 | if (!ofs) { 19 | TEE_LOG_ERROR("Fail to open file \"%s\"\n", filename.c_str()); 20 | return TEE_ERROR_FILE_OPEN; 21 | } 22 | 23 | ofs.write(str.c_str(), str.length()); 24 | if (ofs.fail()) { 25 | TEE_LOG_ERROR("Fail to write file \"%s\"\n", filename.c_str()); 26 | return TEE_ERROR_FILE_WRITE; 27 | } 28 | 29 | return TEE_SUCCESS; 30 | } 31 | 32 | TeeErrorCode FsReadString(const std::string& filename, std::string* str) { 33 | std::ifstream ifs(filename, std::ios::binary | std::ios::in); 34 | if (!ifs) { 35 | // TEE_LOG_ERROR("Fail to open file \"%s\"\n", filename.c_str()); 36 | return TEE_ERROR_FILE_OPEN; 37 | } 38 | 39 | ifs.seekg(0, std::ios::end); 40 | int length = ifs.tellg(); 41 | ifs.seekg(0, std::ios::beg); 42 | 43 | std::vector buf(length); 44 | ifs.read(buf.data(), length); 45 | if (ifs.fail()) { 46 | TEE_LOG_ERROR("Fail to read file \"%s\"\n", filename.c_str()); 47 | return TEE_ERROR_FILE_READ; 48 | } 49 | 50 | str->assign(buf.data(), length); 51 | return TEE_SUCCESS; 52 | } 53 | 54 | TeeErrorCode FsGetFileSize(const std::string& filename, size_t* size) { 55 | std::ifstream ifs(filename, std::ios::binary | std::ios::in); 56 | if (!ifs.good()) { 57 | TEE_LOG_ERROR("Fail to open file \"%s\"\n", filename.c_str()); 58 | return TEE_ERROR_FILE_OPEN; 59 | } 60 | 61 | ifs.seekg(0, std::ios::end); 62 | *size = ifs.tellg(); 63 | ifs.close(); 64 | return TEE_SUCCESS; 65 | } 66 | 67 | bool FsFileExists(const std::string& filename) { 68 | std::ifstream ifs(filename, std::ios::binary | std::ios::in); 69 | return ifs.good(); 70 | } 71 | 72 | std::string GetFsString(const std::string& filename) { 73 | std::string str; 74 | std::ifstream ifs(filename, std::ios::binary | std::ios::in); 75 | if (!ifs) { 76 | TEE_LOG_DEBUG("Fail to open file \"%s\"\n", filename.c_str()); 77 | return str; 78 | } 79 | 80 | ifs.seekg(0, std::ios::end); 81 | int length = ifs.tellg(); 82 | ifs.seekg(0, std::ios::beg); 83 | 84 | std::vector buf(length); 85 | ifs.read(buf.data(), length); 86 | if (ifs.fail()) { 87 | TEE_LOG_DEBUG("Fail to read file \"%s\"\n", filename.c_str()); 88 | return str; 89 | } 90 | 91 | str.assign(buf.data(), length); 92 | return str; 93 | } 94 | 95 | } // namespace untrusted 96 | } // namespace tee 97 | -------------------------------------------------------------------------------- /sdk/untrusted/utils/untrusted_json_internal.h: -------------------------------------------------------------------------------- 1 | #ifndef SDK_UNTRUSTED_UTILS_UNTRUSTED_JSON_INTERNAL_H_ 2 | #define SDK_UNTRUSTED_UTILS_UNTRUSTED_JSON_INTERNAL_H_ 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | #include "rapidjson/document.h" 10 | 11 | #include "tee/common/error.h" 12 | #include "tee/common/log.h" 13 | #include "tee/common/type.h" 14 | 15 | namespace tee { 16 | namespace untrusted { 17 | 18 | constexpr char kConfSignedCheck[] = "configurations_is_signed"; 19 | constexpr char kConfSignedConf[] = "configurations"; 20 | constexpr char kConfSignedHash[] = "hash"; 21 | constexpr char kConfSignedSig[] = "signature"; 22 | 23 | typedef std::shared_ptr JsonDocumentPtr; 24 | typedef std::map JsonConfigurationsMap; 25 | 26 | class JsonConfig { 27 | public: 28 | // Gets the singleton UnitTest object. 29 | static JsonConfig* GetInstance(); 30 | 31 | // To support both rapidjson::Document and rapidjson::Value 32 | static bool CheckString(const rapidjson::Document& conf, const char* name); 33 | static bool CheckString(const rapidjson::Value& conf, const char* name); 34 | static bool CheckArray(const rapidjson::Document& conf, const char* name); 35 | static bool CheckArray(const rapidjson::Value& conf, const char* name); 36 | static bool CheckInt(const rapidjson::Document& conf, const char* name); 37 | static bool CheckInt(const rapidjson::Value& conf, const char* name); 38 | static bool CheckObj(const rapidjson::Document& conf, const char* name); 39 | static bool CheckObj(const rapidjson::Value& conf, const char* name); 40 | static std::string GetStr(const rapidjson::Document& conf, const char* name, 41 | const std::string& default_val = ""); 42 | static std::string GetStr(const rapidjson::Value& conf, const char* name, 43 | const std::string& default_val = ""); 44 | static TeeErrorCode GetStrArray(const rapidjson::Document& conf, 45 | const char* name, 46 | std::vector* values); 47 | static TeeErrorCode GetStrArray(const rapidjson::Value& conf, 48 | const char* name, 49 | std::vector* values); 50 | static TeeErrorCode GetInt(const rapidjson::Document& conf, const char* name, 51 | int* value); 52 | static TeeErrorCode GetInt(const rapidjson::Value& conf, const char* name, 53 | int* value); 54 | 55 | // Load configuration files and then parse and get value(s) 56 | std::string ConfGetStr(const std::string& conf_file, const char* name, 57 | const std::string& default_val = ""); 58 | TeeErrorCode ConfGetStrArray(const std::string& conf_file, const char* name, 59 | std::vector* values); 60 | TeeErrorCode ConfGetInt(const std::string& conf_file, const char* name, 61 | int* value); 62 | rapidjson::Document* GetJsonConf(const std::string& conf_file); 63 | 64 | private: 65 | // Hide construction functions 66 | JsonConfig() {} 67 | JsonConfig(const JsonConfig&); 68 | void operator=(JsonConfig const&); 69 | 70 | std::string GetConfigFilename(const std::string& filename); 71 | TeeErrorCode LoadConfiguration(const std::string& filename); 72 | std::string ParseSignedConfiguration(const JsonDocumentPtr& doc); 73 | 74 | JsonConfigurationsMap cfgs_; 75 | }; 76 | 77 | } // namespace untrusted 78 | } // namespace tee 79 | 80 | #endif // SDK_UNTRUSTED_UTILS_UNTRUSTED_JSON_INTERNAL_H_ 81 | -------------------------------------------------------------------------------- /sdk/untrusted/utils/untrusted_log.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | #ifdef __cplusplus 7 | extern "C" { 8 | #endif 9 | 10 | int tee_printf(const char* fmt, ...) { 11 | constexpr size_t kMaxLogBufSzie = 4096; 12 | char buf[kMaxLogBufSzie] = {'\0'}; 13 | va_list ap; 14 | 15 | va_start(ap, fmt); 16 | vsnprintf(buf, kMaxLogBufSzie, fmt, ap); 17 | va_end(ap); 18 | 19 | // Add the special suffix to notify the limitation of buffer length 20 | if (strlen(buf) >= (kMaxLogBufSzie - 4)) { 21 | buf[kMaxLogBufSzie - 4] = '.'; 22 | buf[kMaxLogBufSzie - 3] = '.'; 23 | buf[kMaxLogBufSzie - 2] = '.'; 24 | buf[kMaxLogBufSzie - 1] = 0; 25 | } 26 | 27 | int ret = printf("%s", buf); 28 | fflush(stdout); 29 | return ret; 30 | } 31 | 32 | #ifdef __cplusplus 33 | } 34 | #endif 35 | -------------------------------------------------------------------------------- /tools/clang_format.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | CLANG_WHITE_LIST_FILE=".clang-dirs" 4 | 5 | do_file_format() { 6 | echo "[FORMAT] $1" 7 | clang-format -style=file -i $1 8 | } 9 | 10 | do_dir_format() { 11 | local dir="$1" 12 | local sub_dirs="" 13 | 14 | #echo "-------- $dir --------" 15 | if [ -e "$dir/$CLANG_WHITE_LIST_FILE" ] ; then 16 | sub_dirs="$(cat $dir/$CLANG_WHITE_LIST_FILE | xargs)" 17 | for d in $sub_dirs ; do 18 | do_dir_format $dir/$d; 19 | done 20 | else 21 | for f in $(find $dir -iname "*.cpp" -o -iname "*.cc" -o -iname "*.h") ; do 22 | # Anyway, we always ignore these two directories 23 | echo $f | grep -q "third_party\/" && continue 24 | echo $f | grep -q "build\/" && continue 25 | do_file_format $f 26 | done 27 | fi 28 | } 29 | 30 | # Show the help menu 31 | if [ "$1" == "-h" -o "$1" == "--help" ] ; then 32 | echo "Usage: $0 [file-or-directory[, file-or-directory[, ...]]]" 33 | exit 0 34 | fi 35 | 36 | # Get the list of files or directories to be formatted 37 | if [ -n "$1" ] ; then 38 | FORMATITEMS="$@" 39 | elif [ -e "$CLANG_WHITE_LIST_FILE" ] ; then 40 | FORMATITEMS="$(cat $CLANG_WHITE_LIST_FILE | xargs)" 41 | else 42 | FORMATITEMS="." 43 | fi 44 | 45 | # Fromat all files and directories 46 | for item in $FORMATITEMS ; do 47 | if [ -f "$item" ] ; then 48 | if echo "$item" | grep -q -E ".*\.cpp|.*\.cc|.*\.h" ; then 49 | do_file_format $item 50 | else 51 | echo "[IGNORE] Invalid C++ source or header file: $item" 52 | fi 53 | elif [ -d "$item" ] ; then 54 | do_dir_format $item 55 | else 56 | echo "[IGNORE] Invalid file or directory: $item" 57 | fi 58 | done 59 | -------------------------------------------------------------------------------- /tools/cpplint_all.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | TOPDIR="$(readlink -f $(dirname $0)/..)" 4 | [ -n "$1" ] && DIRS="$@" || DIRS="." 5 | CPPLINT=$(dirname $0)/cpplint.py 6 | 7 | if [ -z "$DIRS" ] ; then 8 | echo "Usage $0 dir1 [dir2 [...]]" 9 | exit 1 10 | fi 11 | 12 | ret=0 13 | for item in $DIRS ; do 14 | if [ -f "$item" ] ; then 15 | echo "----[CPPLINT] $item" 16 | $CPPLINT $item 17 | exit $? 18 | elif [ -d "$item" ] ; then 19 | echo "Do cpplint check in directory $item" 20 | for f in $(find $item -type f -iname "*.h" -o -iname "*.cpp") ; do 21 | echo $f | grep -q ".*\.pb\.[cc|h]" && continue 22 | echo $f | grep -q ".*\.grpc\.pb\.[cc|h]" && continue 23 | echo $f | grep -q "third_party\/" && continue 24 | echo $f | grep -q "build\/" && continue 25 | echo "----[CPPLINT] $f" 26 | $CPPLINT $f | grep -o '^${f}:.*$' && ret=1 27 | done 28 | else 29 | echo "Usage: $0 " 30 | exit 1 31 | fi 32 | done 33 | 34 | exit $ret 35 | -------------------------------------------------------------------------------- /tools/dockerenv.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | CURRDIR="$(pwd)" 4 | REPONAME="$(basename $CURRDIR)" 5 | 6 | IMAGE="antkubetee/kubetee-dev-ubuntu18.04-grpc-sgx-ssl:1.0" 7 | CONTAINERNAME=${2:-"kubetee-dev-ubuntu1804-$REPONAME"} 8 | 9 | show_help() { 10 | echo "Usage: $(basename $0) --init|--exec|--delete [container-name]" 11 | } 12 | 13 | docker_init() { 14 | sudo docker run -itd \ 15 | --name $CONTAINERNAME \ 16 | --device=/dev/isgx \ 17 | -v /var/run/aesmd/aesm.socket:/var/run/aesmd/aesm.socket \ 18 | --net=host \ 19 | -v $CURRDIR:/root/$REPONAME \ 20 | -w /root/$REPONAME \ 21 | --cap-add=SYS_PTRACE \ 22 | --security-opt seccomp=unconfined \ 23 | $IMAGE \ 24 | bash 25 | } 26 | 27 | docker_exec() { 28 | sudo docker exec -it $CONTAINERNAME bash 29 | } 30 | 31 | docker_delete() { 32 | sudo docker rm -f $CONTAINERNAME 33 | } 34 | 35 | case "$1" in 36 | --init) docker_init ;; 37 | --exec) docker_exec ;; 38 | --delete) docker_delete ;; 39 | -h|--help) show_help ; exit 0 ;; 40 | *) show_help ; exit 1 ;; 41 | esac 42 | -------------------------------------------------------------------------------- /tools/dump_enclave_info.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | if [ -z "$1" ] ; then 4 | echo "Usage: $0 enclave.signed.so" 5 | exit 1 6 | fi 7 | 8 | enclave=$1 9 | tmpprefix="/tmp/$(basename $enclave)" 10 | dumpfile="${tmpprefix}.dump" 11 | mrenclavefile="${tmpprefix}.mrenclave" 12 | mrsignerfile="${tmpprefix}.mrsigner" 13 | sgxsign="/opt/intel/sgxsdk/bin/x64/sgx_sign" 14 | 15 | rm -rf $dumpfile 16 | $sgxsign dump -enclave $enclave -dumpfile $dumpfile >/dev/null 2>&1 17 | [ "$?" -eq 0 ] || exit 1 18 | 19 | rm -rf $mrsignerfile 20 | mrsignerstr="" 21 | echo -e -n "Enclave mrsigner hexstr: " 22 | for i in $(grep -A 2 "mrsigner->value:" $dumpfile | tail -2 | xargs | sed 's/0x//g' | tr 'a-z' 'A-Z') ; do 23 | mrsignerstr="${mrsignerstr}${i}" 24 | echo -e -n $i 25 | echo $i | xxd -r -ps >> $mrsignerfile 26 | done 27 | echo "" 28 | echo -e -n "Enclave mrsigner base64: " 29 | base64 -w 0 $mrsignerfile 30 | echo "" 31 | echo "Enclave mrsigner hexhash: $(echo -n $mrsignerstr | sha256sum | sed 's/\ \ -//g' | tr 'a-z' 'A-Z')" 32 | 33 | rm -rf $mrenclavefile 34 | mrenclavestr="" 35 | echo -e -n "Enclave mrenclave hexstr: " 36 | for i in $(grep -A 2 "enclave_hash.m:" $dumpfile | tail -2 | xargs | sed 's/0x//g' | tr 'a-z' 'A-Z') ; do 37 | mrenclavestr="${mrenclavestr}${i}" 38 | echo -e -n $i 39 | echo $i | xxd -r -ps >> $mrenclavefile 40 | done 41 | echo "" 42 | echo -e -n "Enclave mrenclave base64: " 43 | base64 -w 0 $mrenclavefile 44 | echo "" 45 | echo "Enclave mrsigner hexhash: $(echo -n $mrenclavestr | sha256sum | sed 's/\ \ -//g' | tr 'a-z' 'A-Z') " 46 | 47 | rm -rf $dumpfile $mrenclavefile $mrsignerfile 48 | -------------------------------------------------------------------------------- /tools/gencert: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | RSABITS=4096 4 | CAKEY="ca.key" 5 | CACRT="ca.crt" 6 | DEBUG="${DEBUG:-0}" 7 | 8 | 9 | generate_key() { 10 | local keyfile="$1" 11 | 12 | if [ -z "$keyfile" ] ; then 13 | echo "Please specify a key file path!" 14 | exit 1 15 | fi 16 | 17 | openssl genrsa -out $keyfile $RSABITS && \ 18 | echo "Generate key file here: $crtfile" 19 | } 20 | 21 | generate_ca() { 22 | local subject="/CN=${1:-SigningCA}" 23 | 24 | generate_key $CAKEY && \ 25 | openssl req -x509 -new -nodes -key $CAKEY \ 26 | -subj "$subject" -days 7300 -out $CACRT 27 | 28 | [ "$?" == 0 ] || return 1 29 | [ "$DEBUG" == "1" ] && openssl x509 -in $CACRT -text -noout 30 | echo "Generate CA certificate file here: $CACRT" 31 | } 32 | 33 | generate_csr() { 34 | local keyfile="$1" 35 | local csrfile="$2" 36 | local subject="/CN=${3}" 37 | 38 | openssl req -new -key $keyfile -subj "$subject" -out $csrfile 39 | 40 | [ "$?" == 0 ] || return 1 41 | [ "$DEBUG" == "1" ] && openssl req -text -noout -subject -in $csrfile 42 | echo "Generate certificate signing request file here: $csrfile" 43 | } 44 | 45 | sign_csr() { 46 | local csrfile="$1" 47 | local crtfile="$2" 48 | local crtdays="${3:-365}" 49 | 50 | openssl x509 -req -CA $CACRT -CAkey $CAKEY -CAcreateserial \ 51 | -in $csrfile -out $crtfile -days $crtdays 52 | 53 | [ "$?" == 0 ] || return 1 54 | [ "$DEBUG" == "1" ] && openssl x509 -in $crtfile -text -noout 55 | echo "Generate certificate file here: $crtfile" 56 | } 57 | 58 | generate_crt() { 59 | local name="$1" 60 | local cn="$2" 61 | local dir="${name}_${cn}" 62 | 63 | mkdir -p $dir 64 | prefix="$dir/$name" 65 | generate_key ${prefix}.key && \ 66 | generate_csr ${prefix}.key ${prefix}.csr $cn && \ 67 | sign_csr ${prefix}.csr ${prefix}.crt 68 | 69 | if [ "$?" == 0 ] ; then 70 | rm -rf ${prefix}.csr 71 | cp ./ca.crt ./$dir/ 72 | [ "$DEBUG" == "1" ] && openssl x509 -in ${prefix}.crt -text -noout 73 | return 0 74 | else 75 | rm -rf ${prefix}.key ${prefix}.csr ${prefix}.crt 76 | return 1 77 | fi 78 | } 79 | 80 | show_crt() { 81 | openssl x509 -in $1 -text -noout 82 | } 83 | 84 | revoke_cert() { 85 | #openssl ca -revoke cert.pem -config openssl.cnf 86 | #openssl ca -gencrl -out cacert.crl -config openssl.cnf 87 | #openssl crl -in cacert.crl -text -noout 88 | return 0 89 | } 90 | 91 | generate_test_all() { 92 | local workdir="${1:-./}" 93 | local testCA="TestCertificateCenter" 94 | local server="test1" 95 | local client="test2" 96 | local ret=0 97 | 98 | cd $workdir 99 | echo "--[CA key&crt]-----------------------------------------------" 100 | generate_ca $testCA && \ 101 | echo "--[server key]-----------------------------------------------" && \ 102 | generate_key ${server}.key && \ 103 | echo "--[server csr]-----------------------------------------------" && \ 104 | generate_csr ${server}.key ${server}.csr "enclave-service" && \ 105 | echo "--[server crt]-----------------------------------------------" && \ 106 | sign_csr ${server}.csr ${server}.crt && \ 107 | echo "--[client key]-----------------------------------------------" && \ 108 | generate_key ${client}.key && \ 109 | echo "--[client csr]-----------------------------------------------" && \ 110 | generate_csr ${client}.key ${client}.csr "enclave-service" && \ 111 | echo "--[client crt]-----------------------------------------------" && \ 112 | sign_csr ${client}.csr ${client}.crt 113 | ret=$? 114 | echo "-------------------------------------------------------------" 115 | 116 | if [ "$ret" == 0 ] ; then 117 | rm -rf ./*.csr ./ca.key ./ca.srl 118 | return 0 119 | else 120 | rm -rf ca\.* ${server}\.* ${client}\.* 121 | return 1 122 | fi 123 | } 124 | 125 | show_help() { 126 | echo "Usage: $(basename $0) " 127 | echo " genca [CN]" 128 | echo " genkey " 129 | echo " gencsr " 130 | echo " gencrt " 131 | echo " signcsr [days|or-default-365]" 132 | echo " showcrt " 133 | echo " gentest [outdir] #This command generate all ca/key/cert for test" 134 | } 135 | 136 | case $1 in 137 | genca) generate_ca $2 ;; 138 | genkey) generate_key "$2" ;; 139 | gencsr) generate_csr "$2" "$3" "$4" ;; 140 | gencrt) generate_crt "$2" "$3" ;; 141 | signcsr) sign_csr "$2" "$3" "$4" ;; 142 | showcrt) show_crt "$2" ;; 143 | gentest) generate_test_all $2 ;; 144 | -h|--help|help) show_help ; exit 0 ;; 145 | *) show_help ; exit 1 ;; 146 | esac 147 | --------------------------------------------------------------------------------