Skip to content

Commit 508d500

Browse files
authored
Merge pull request #1 from bvavala/bruno.241216.firstcommit
First commit with attestation API from PDO's pull request #501
2 parents 8dbb6a2 + 43ff713 commit 508d500

102 files changed

Lines changed: 5875 additions & 0 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.gitmodules

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
[submodule "common/jwt-cpp"]
2+
path = common/jwt-cpp
3+
url = https://github.com/Thalhammer/jwt-cpp
4+
[submodule "common/nlohmann/json"]
5+
path = common/nlohmann/json
6+
url = https://github.com/nlohmann/json

CMakeLists.txt

Lines changed: 219 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,219 @@
1+
# Copyright 2023 Intel Corporation
2+
#
3+
# SPDX-License-Identifier: Apache-2.0
4+
5+
cmake_minimum_required(VERSION 3.13)
6+
7+
PROJECT(ATTESTATION-API)
8+
9+
set(CMAKE_CXX_STANDARD 14)
10+
set(CMAKE_CXX_STANDARD_REQUIRED ON)
11+
set(CMAKE_CXX_EXTENSIONS OFF)
12+
13+
INCLUDE(CMakeVariables.txt)
14+
15+
IF (NOT DEFINED ENV{DCAP_PRIMITIVES})
16+
MESSAGE(FATAL_ERROR "DCAP_PRIMITIVES variable with source repo path not defined")
17+
ENDIF()
18+
19+
###################################################################################################
20+
# First run cmake in common
21+
###################################################################################################
22+
# This patches the jwt repo for sgx use
23+
ADD_SUBDIRECTORY(common)
24+
25+
###################################################################################################
26+
# Set up trusted certificates in headers
27+
###################################################################################################
28+
29+
# This creates the necessary headers which include the trusted certificates
30+
# and returns sets CERTIFICATE_INCLUDE_PATH to find them
31+
ADD_SUBDIRECTORY(common/crypto/verify_ias_report)
32+
LIST(APPEND CERTIFICATE_INCLUDE_PATHS "${CERTIFICATE_INCLUDE_PATH}")
33+
34+
ADD_SUBDIRECTORY(common/crypto/verify_ita_token)
35+
LIST(APPEND CERTIFICATE_INCLUDE_PATHS "${CERTIFICATE_INCLUDE_PATH}")
36+
37+
ADD_SUBDIRECTORY(common/crypto/verify_dcap_direct)
38+
LIST(APPEND CERTIFICATE_INCLUDE_PATHS "${CERTIFICATE_INCLUDE_PATH}")
39+
40+
###################################################################################################
41+
# Logging
42+
###################################################################################################
43+
44+
# Prepare the logging libs.
45+
# Note: by default, no trusted logging and untrusted logging is printf.
46+
# This returns the variables: LOGGING_UNTRUSTED_INCLUDE_PATH, LOGGING_TRUSTED_INCLUDE_PATH
47+
ADD_SUBDIRECTORY(common/logging)
48+
49+
###################################################################################################
50+
# Project files and headers
51+
###################################################################################################
52+
53+
FILE(GLOB PROJECT_HEADERS
54+
"include/*.h"
55+
"${CERTIFICATE_INCLUDE_PATH}/*.h"
56+
)
57+
58+
FILE(GLOB PROJECT_SOURCES
59+
"evidence/*.cpp"
60+
"common/base64/base64.cpp"
61+
"common/types/*.cpp"
62+
"common/crypto/*.cpp"
63+
"common/crypto/verify_ias_report/*.cpp"
64+
"common/crypto/verify_ita_token/*.cpp"
65+
"common/crypto/verify_dcap_direct/*.cpp"
66+
)
67+
68+
FILE(GLOB PROJECT_OCALLS
69+
"ocalls/*.c"
70+
)
71+
72+
FILE(GLOB PROJECT_TRUSTED_SOURCES
73+
"attestation/*.cpp"
74+
$ENV{DCAP_PRIMITIVES}/QuoteVerification/QVL/Src/AttestationLibrary/src/*.cpp
75+
$ENV{DCAP_PRIMITIVES}/QuoteVerification/QVL/Src/AttestationLibrary/src/OpensslHelpers/*.cpp
76+
$ENV{DCAP_PRIMITIVES}/QuoteVerification/QVL/Src/AttestationLibrary/src/PckParser/*.cpp
77+
$ENV{DCAP_PRIMITIVES}/QuoteVerification/QVL/Src/AttestationLibrary/src/CertVerification/*.cpp
78+
$ENV{DCAP_PRIMITIVES}/QuoteVerification/QVL/Src/AttestationLibrary/src/QuoteVerification/*.cpp
79+
$ENV{DCAP_PRIMITIVES}/QuoteVerification/QVL/Src/AttestationLibrary/src/Verifiers/*.cpp
80+
$ENV{DCAP_PRIMITIVES}/QuoteVerification/QVL/Src/AttestationLibrary/src/Verifiers/Checks/*.cpp
81+
$ENV{DCAP_PRIMITIVES}/QuoteVerification/QVL/Src/AttestationLibrary/src/Utils/*.cpp
82+
$ENV{DCAP_PRIMITIVES}/QuoteVerification/QVL/Src/AttestationLibrary/include/SgxEcdsaAttestation/*.h
83+
)
84+
85+
SET(DCAP_QG_PATH "$ENV{DCAP_PRIMITIVES}/QuoteGeneration")
86+
SET(DCAP_QV_PATH "$ENV{DCAP_PRIMITIVES}/QuoteVerification")
87+
88+
###################################################################################################
89+
# Tools
90+
###################################################################################################
91+
SET(B64ATTESTATION_TO_B64COLLATERAL "b64attestation_to_b64collateral")
92+
ADD_EXECUTABLE(${B64ATTESTATION_TO_B64COLLATERAL}
93+
conversion/dcap-direct/b64attestation2b64collateral.cpp
94+
common/base64/base64.cpp)
95+
ADD_CUSTOM_COMMAND(TARGET ${B64ATTESTATION_TO_B64COLLATERAL}
96+
POST_BUILD
97+
COMMAND mkdir -p ${CMAKE_CURRENT_BINARY_DIR}/conversion/dcap-direct/ &&
98+
mv $<TARGET_FILE:${B64ATTESTATION_TO_B64COLLATERAL}> ${CMAKE_CURRENT_BINARY_DIR}/conversion/dcap-direct/)
99+
100+
TARGET_INCLUDE_DIRECTORIES(${B64ATTESTATION_TO_B64COLLATERAL} PRIVATE common)
101+
102+
# newer DCAP (1.22) libs need the qal (older, 1.19, don't)
103+
SET(DCAP_LINK_LIBS ${DCAP_QV_PATH}/appraisal/qal/libdcap_qal.a)
104+
105+
TARGET_LINK_LIBRARIES(${B64ATTESTATION_TO_B64COLLATERAL}
106+
#${DCAP_QV_PATH}/dcap_quoteverify/linux/libsgx_dcap_quoteverify.a
107+
#${DCAP_QG_PATH}/build/linux/libdcap_quoteprov.a
108+
#${DCAP_QG_PATH}/build/linux/libsgx_default_qcnl_wrapper.a
109+
#sgx_dcap_quoteverify dcap_quoteprov sgx_default_qcnl_wrapper
110+
sgx_dcap_quoteverify
111+
# sgx_dcap_ql dcap_quoteprov necessary for the callbacks
112+
sgx_dcap_ql
113+
dcap_quoteprov
114+
)
115+
116+
###################################################################################################
117+
# Untrusted one-attestation library
118+
###################################################################################################
119+
120+
SET(U_OA_LIB_STATIC ${U_ONE_ATTESTATION_LIB_NAME}_Static)
121+
122+
ADD_LIBRARY(${U_OA_LIB_STATIC} STATIC ${PROJECT_HEADERS} ${PROJECT_SOURCES} ${PROJECT_OCALLS})
123+
124+
TARGET_INCLUDE_DIRECTORIES(${U_OA_LIB_STATIC} PRIVATE "$ENV{SGX_SDK}/include")
125+
TARGET_INCLUDE_DIRECTORIES(${U_OA_LIB_STATIC} PRIVATE "include")
126+
TARGET_INCLUDE_DIRECTORIES(${U_OA_LIB_STATIC} BEFORE PRIVATE "common")
127+
TARGET_INCLUDE_DIRECTORIES(${U_OA_LIB_STATIC} PRIVATE "common/nlohmann/json/include")
128+
TARGET_INCLUDE_DIRECTORIES(${U_OA_LIB_STATIC} PRIVATE "common/jwt-cpp/include")
129+
TARGET_INCLUDE_DIRECTORIES(${U_OA_LIB_STATIC} PRIVATE ${CERTIFICATE_INCLUDE_PATHS})
130+
TARGET_INCLUDE_DIRECTORIES(${U_OA_LIB_STATIC} PRIVATE ${LOGGING_UNTRUSTED_INCLUDE_PATH})
131+
132+
TARGET_INCLUDE_DIRECTORIES(${U_OA_LIB_STATIC} PRIVATE "$ENV{DCAP_PRIMITIVES}/QuoteVerification/QVL/Src/Build/Release/dist/include/")
133+
TARGET_INCLUDE_DIRECTORIES(${U_OA_LIB_STATIC} PRIVATE "$ENV{DCAP_PRIMITIVES}")
134+
TARGET_INCLUDE_DIRECTORIES(${U_OA_LIB_STATIC} PRIVATE "$ENV{DCAP_PRIMITIVES}/QuoteVerification/QVL/Src/AttestationLibrary/src")
135+
TARGET_INCLUDE_DIRECTORIES(${U_OA_LIB_STATIC} PRIVATE "$ENV{DCAP_PRIMITIVES}/QuoteVerification/QVL/Src/AttestationCommons/include")
136+
137+
TARGET_COMPILE_OPTIONS(${U_OA_LIB_STATIC} PRIVATE -fvisibility=hidden)
138+
TARGET_COMPILE_OPTIONS(${U_OA_LIB_STATIC} PRIVATE -fpie)
139+
TARGET_COMPILE_OPTIONS(${U_OA_LIB_STATIC} PRIVATE -fstack-protector)
140+
141+
SET(QVL_LIB_PATH "$ENV{DCAP_PRIMITIVES}/QuoteVerification/QVL/Src/Build/Release/dist/lib")
142+
143+
add_custom_target(combined_u_static_target ALL
144+
COMMAND mkdir -p oals_objs lqvs_objs lacs_objs laps_objs
145+
COMMAND ar -x --output oals_objs $<TARGET_FILE:${U_OA_LIB_STATIC}>
146+
COMMAND ar -x --output lqvs_objs ${QVL_LIB_PATH}/libQuoteVerificationStatic.a
147+
COMMAND ar -x --output lacs_objs ${QVL_LIB_PATH}/libAttestationCommonsStatic.a
148+
COMMAND ar -x --output laps_objs ${QVL_LIB_PATH}/libAttestationParsersStatic.a
149+
COMMAND ar -qcs lib${U_ONE_ATTESTATION_LIB_NAME}.a oals_objs/*.o lqvs_objs/*.o lacs_objs/*.o laps_objs/*.o
150+
WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
151+
DEPENDS ${U_OA_LIB_STATIC}
152+
)
153+
ADD_LIBRARY(${U_ONE_ATTESTATION_LIB_NAME} STATIC IMPORTED)
154+
ADD_DEPENDENCIES(${U_ONE_ATTESTATION_LIB_NAME} combined_u_static_target)
155+
SET_TARGET_PROPERTIES(${U_ONE_ATTESTATION_LIB_NAME}
156+
PROPERTIES
157+
IMPORTED_LOCATION lib${U_ONE_ATTESTATION_LIB_NAME}.a
158+
)
159+
160+
###################################################################################################
161+
# Trusted one-attestation library
162+
###################################################################################################
163+
164+
SET(T_OA_LIB_STATIC ${T_ONE_ATTESTATION_LIB_NAME}_Static)
165+
ADD_LIBRARY(${T_OA_LIB_STATIC} STATIC
166+
${PROJECT_HEADERS} ${PROJECT_TRUSTED_HEADERS} ${PROJECT_SOURCES} ${PROJECT_TRUSTED_SOURCES})
167+
168+
#dependency in common to ensure the jwt lib is patched for building the trusted lib in SGX
169+
ADD_DEPENDENCIES(${T_OA_LIB_STATIC} patch_jwt)
170+
171+
TARGET_INCLUDE_DIRECTORIES(${T_OA_LIB_STATIC} PRIVATE "common/sgx-support") # for clocale, before sgxsdk includes
172+
TARGET_INCLUDE_DIRECTORIES(${T_OA_LIB_STATIC} PRIVATE "$ENV{SGX_SDK}/include")
173+
TARGET_INCLUDE_DIRECTORIES(${T_OA_LIB_STATIC} PRIVATE "$ENV{SGX_SDK}/include/libcxx")
174+
TARGET_INCLUDE_DIRECTORIES(${T_OA_LIB_STATIC} PRIVATE "$ENV{SGX_SDK}/include/tlibc")
175+
TARGET_INCLUDE_DIRECTORIES(${T_OA_LIB_STATIC} PRIVATE "$ENV{SGX_SSL}/include")
176+
TARGET_INCLUDE_DIRECTORIES(${T_OA_LIB_STATIC} PRIVATE "include")
177+
TARGET_INCLUDE_DIRECTORIES(${T_OA_LIB_STATIC} BEFORE PRIVATE "common")
178+
TARGET_INCLUDE_DIRECTORIES(${T_OA_LIB_STATIC} PRIVATE "common/nlohmann/json/include")
179+
TARGET_INCLUDE_DIRECTORIES(${T_OA_LIB_STATIC} PRIVATE "common/jwt-cpp/include")
180+
TARGET_INCLUDE_DIRECTORIES(${T_OA_LIB_STATIC} PRIVATE ${CERTIFICATE_INCLUDE_PATHS})
181+
TARGET_INCLUDE_DIRECTORIES(${T_OA_LIB_STATIC} PRIVATE ${LOGGING_TRUSTED_INCLUDE_PATH})
182+
183+
TARGET_INCLUDE_DIRECTORIES(${T_OA_LIB_STATIC} PRIVATE "$ENV{DCAP_PRIMITIVES}/QuoteVerification/QVL/Src/Build/Release/dist/include/")
184+
TARGET_INCLUDE_DIRECTORIES(${T_OA_LIB_STATIC} PRIVATE "$ENV{DCAP_PRIMITIVES}")
185+
TARGET_INCLUDE_DIRECTORIES(${T_OA_LIB_STATIC} PRIVATE "$ENV{DCAP_PRIMITIVES}/QuoteVerification/QVL/Src/AttestationLibrary/src")
186+
TARGET_INCLUDE_DIRECTORIES(${T_OA_LIB_STATIC} PRIVATE "$ENV{DCAP_PRIMITIVES}/QuoteVerification/QVL/Src/AttestationCommons/include")
187+
TARGET_INCLUDE_DIRECTORIES(${T_OA_LIB_STATIC} PRIVATE "$ENV{DCAP_PRIMITIVES}/QuoteVerification/QVL/Src/ThirdParty/rapidjson/include")
188+
189+
TARGET_COMPILE_OPTIONS(${T_OA_LIB_STATIC} PRIVATE -nostdinc++)
190+
TARGET_COMPILE_OPTIONS(${T_OA_LIB_STATIC} PRIVATE -fvisibility=hidden)
191+
TARGET_COMPILE_OPTIONS(${T_OA_LIB_STATIC} PRIVATE -fpie)
192+
TARGET_COMPILE_OPTIONS(${T_OA_LIB_STATIC} PRIVATE -fstack-protector)
193+
194+
#remove time-related code from jwt tool (as dcap primitives do)
195+
TARGET_COMPILE_OPTIONS(${T_OA_LIB_STATIC} PRIVATE -DSGX_JWT)
196+
197+
add_custom_target(combined_t_static_target ALL
198+
COMMAND mkdir -p toals_objs lacse_objs lapse_objs
199+
COMMAND ar -x --output toals_objs $<TARGET_FILE:${T_OA_LIB_STATIC}>
200+
COMMAND ar -x --output lacse_objs ${QVL_LIB_PATH}/libAttestationCommonsStaticEnclave.a
201+
COMMAND ar -x --output lapse_objs ${QVL_LIB_PATH}/libAttestationParsersStaticEnclave.a
202+
COMMAND ar -qcs lib${T_ONE_ATTESTATION_LIB_NAME}.a toals_objs/*.o lacse_objs/*.o lapse_objs/*.o
203+
WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
204+
DEPENDS ${U_OA_LIB_STATIC}
205+
)
206+
ADD_LIBRARY(${T_ONE_ATTESTATION_LIB_NAME} STATIC IMPORTED)
207+
ADD_DEPENDENCIES(${T_ONE_ATTESTATION_LIB_NAME} combined_t_static_target)
208+
SET_TARGET_PROPERTIES(${T_ONE_ATTESTATION_LIB_NAME}
209+
PROPERTIES
210+
IMPORTED_LOCATION lib${T_ONE_ATTESTATION_LIB_NAME}.a
211+
)
212+
213+
214+
###################################################################################################
215+
# Local Tests
216+
###################################################################################################
217+
ENABLE_TESTING()
218+
ADD_SUBDIRECTORY (test)
219+

CMakeVariables.txt

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
# Copyright 2023 Intel Corporation
2+
#
3+
# SPDX-License-Identifier: Apache-2.0
4+
5+
SET(U_ONE_ATTESTATION_LIB_NAME u-one-attestation)
6+
SET(T_ONE_ATTESTATION_LIB_NAME t-one-attestation)
7+

README.md

Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
# Attestation API
2+
3+
This library implements a single API for generating and verifying hardware-based attestation (e.g., Intel SGX EPID/DCAP attestations).
4+
The library implementation originally started as part of the Fabric Private Chaincode project, and later spun off and extended.
5+
6+
The library works with Intel SGX EPID attestations, verified through Intel Attestation Service (IAS), and DCAP attestations, verified through Intel Trust Authority (ITA).
7+
8+
## Build
9+
10+
Build the docker image to create an environment with all necessaty dependencies.
11+
```bash
12+
cd docker
13+
make
14+
```
15+
16+
### Simulation mode
17+
Start the dev container:
18+
```bash
19+
docker run -v <project root>:/project -e SGX_MODE=SIM -it oaa-dev
20+
```
21+
22+
Simulation mode is the default mode. It does not use actual Intel SGX operations, and tests are conducted on simulated-type attestations.
23+
24+
```bash
25+
source /opt/intel/sgxsdk/environment
26+
mkdir build
27+
cd build
28+
cmake ..
29+
make
30+
```
31+
32+
### Hardware mode
33+
Start the dev container, here is an example:
34+
```bash
35+
docker run --network host -v <project root>:/project -e SGX_MODE=HW -it oaa-dev
36+
```
37+
The container is attached to the host network to download the root certificates.
38+
Also, enabling the HW mode makes the generated artifacts use actual Intel SGX operations -- and tests are conducted on real attestations.
39+
40+
DCAP support with ITA is built by default, but requires the URL to the ITA CA root certificates (in JWK format). If the URL is not specified, the build will succeed but it won't be able to verify DCAP attestations.
41+
```bash
42+
export ITA_ROOT_CACERT_URL=<certificate url>
43+
```
44+
45+
EPID support and DCAP support for direct verificaiton (without ITA) are built by default, and require an internet connection to download the Intel CA root certificates.
46+
47+
```bash
48+
source /opt/intel/sgxsdk/environment
49+
mkdir build
50+
cd build
51+
cmake ..
52+
make
53+
```
54+
55+
#### Collateral (for usage and testing)
56+
Using (or testing) SGX attestation requires some collateral. The folder to such collateral must be provided as:
57+
```bash
58+
export COLLATERAL_FOLDER=<path to the folder>
59+
```
60+
61+
EPID collateral files:
62+
* `spid_type.txt`, a text file containing the SPID type ("epid-linkable" or "epid-unlinkable")
63+
* `spid.txt`, a text file containing the SPID (a 32-byte long hex string)
64+
* `api_key.txt`, a text file containing the API key to use IAS (a 32-byte long hex string)
65+
66+
DCAP collateral files:
67+
* `ita_api_key.txt`, a text file containing the API key to use ITA
68+
* `attestation_type.txt`, a text file containing the attestation type ("dcap-sgx")
69+
70+
71+
#### Testing
72+
73+
To run the tests in HW mode, the collateral (see above) and the SGX devices are necessary.
74+
Assuming a default system configuration, you may want to start the dev docker image as follows:
75+
```bash
76+
docker run --network host --device /dev/sgx_enclave:/dev/sgx_enclave --device /dev/sgx_provision:/dev/sgx_provision -v /var/run/aesmd:/var/run/aesmd -v <project root>:/project -v <local collateral folder>:/collateral -e SGX_MODE=HW -e COLLATERAL_FOLDER=/collateral -it oaa-dev
77+
```
78+
79+
To test everything (simulated attestations in SIM mode, and all supported attestations in HW mode for platforms that support both EPID and DCAP):
80+
```bash
81+
make test
82+
```
83+
84+
To test everything except DCAP with ITA:
85+
```bash
86+
SKIP_TEST_DCAP= make test
87+
```
88+
89+
To test everything except DCAP with direct verification:
90+
```bash
91+
SKIP_TEST_DCAP_DIRECT= make test
92+
```
93+
For SGX platform that do not support DCAP or FLC, both DCAP tests must be disabled.
94+
95+
96+
To test everything except EPID (for SGX platforms that do not support EPID):
97+
```bash
98+
SKIP_TEST_EPID= make test
99+
```
100+
101+
If tests fail, you may want to output some logs with:
102+
```bash
103+
env CTEST_OUTPUT_ON_FAILURE=1 make test
104+
```

0 commit comments

Comments
 (0)