Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

First commit with attestation API from PDO's pull request #501 #1

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
[submodule "common/jwt-cpp"]
path = common/jwt-cpp
url = https://github.com/Thalhammer/jwt-cpp
[submodule "common/nlohmann/json"]
path = common/nlohmann/json
url = https://github.com/nlohmann/json
219 changes: 219 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,219 @@
# Copyright 2023 Intel Corporation
#
# SPDX-License-Identifier: Apache-2.0

cmake_minimum_required(VERSION 3.13)

PROJECT(ATTESTATION-API)

set(CMAKE_CXX_STANDARD 14)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)

INCLUDE(CMakeVariables.txt)

IF (NOT DEFINED ENV{DCAP_PRIMITIVES})
MESSAGE(FATAL_ERROR "DCAP_PRIMITIVES variable with source repo path not defined")
ENDIF()

###################################################################################################
# First run cmake in common
###################################################################################################
# This patches the jwt repo for sgx use
ADD_SUBDIRECTORY(common)

###################################################################################################
# Set up trusted certificates in headers
###################################################################################################

# This creates the necessary headers which include the trusted certificates
# and returns sets CERTIFICATE_INCLUDE_PATH to find them
ADD_SUBDIRECTORY(common/crypto/verify_ias_report)
LIST(APPEND CERTIFICATE_INCLUDE_PATHS "${CERTIFICATE_INCLUDE_PATH}")

ADD_SUBDIRECTORY(common/crypto/verify_ita_token)
LIST(APPEND CERTIFICATE_INCLUDE_PATHS "${CERTIFICATE_INCLUDE_PATH}")

ADD_SUBDIRECTORY(common/crypto/verify_dcap_direct)
LIST(APPEND CERTIFICATE_INCLUDE_PATHS "${CERTIFICATE_INCLUDE_PATH}")

###################################################################################################
# Logging
###################################################################################################

# Prepare the logging libs.
# Note: by default, no trusted logging and untrusted logging is printf.
# This returns the variables: LOGGING_UNTRUSTED_INCLUDE_PATH, LOGGING_TRUSTED_INCLUDE_PATH
ADD_SUBDIRECTORY(common/logging)

###################################################################################################
# Project files and headers
###################################################################################################

FILE(GLOB PROJECT_HEADERS
"include/*.h"
"${CERTIFICATE_INCLUDE_PATH}/*.h"
)

FILE(GLOB PROJECT_SOURCES
"evidence/*.cpp"
"common/base64/base64.cpp"
"common/types/*.cpp"
"common/crypto/*.cpp"
"common/crypto/verify_ias_report/*.cpp"
"common/crypto/verify_ita_token/*.cpp"
"common/crypto/verify_dcap_direct/*.cpp"
)

FILE(GLOB PROJECT_OCALLS
"ocalls/*.c"
)

FILE(GLOB PROJECT_TRUSTED_SOURCES
"attestation/*.cpp"
$ENV{DCAP_PRIMITIVES}/QuoteVerification/QVL/Src/AttestationLibrary/src/*.cpp
$ENV{DCAP_PRIMITIVES}/QuoteVerification/QVL/Src/AttestationLibrary/src/OpensslHelpers/*.cpp
$ENV{DCAP_PRIMITIVES}/QuoteVerification/QVL/Src/AttestationLibrary/src/PckParser/*.cpp
$ENV{DCAP_PRIMITIVES}/QuoteVerification/QVL/Src/AttestationLibrary/src/CertVerification/*.cpp
$ENV{DCAP_PRIMITIVES}/QuoteVerification/QVL/Src/AttestationLibrary/src/QuoteVerification/*.cpp
$ENV{DCAP_PRIMITIVES}/QuoteVerification/QVL/Src/AttestationLibrary/src/Verifiers/*.cpp
$ENV{DCAP_PRIMITIVES}/QuoteVerification/QVL/Src/AttestationLibrary/src/Verifiers/Checks/*.cpp
$ENV{DCAP_PRIMITIVES}/QuoteVerification/QVL/Src/AttestationLibrary/src/Utils/*.cpp
$ENV{DCAP_PRIMITIVES}/QuoteVerification/QVL/Src/AttestationLibrary/include/SgxEcdsaAttestation/*.h
)

SET(DCAP_QG_PATH "$ENV{DCAP_PRIMITIVES}/QuoteGeneration")
SET(DCAP_QV_PATH "$ENV{DCAP_PRIMITIVES}/QuoteVerification")

###################################################################################################
# Tools
###################################################################################################
SET(B64ATTESTATION_TO_B64COLLATERAL "b64attestation_to_b64collateral")
ADD_EXECUTABLE(${B64ATTESTATION_TO_B64COLLATERAL}
conversion/dcap-direct/b64attestation2b64collateral.cpp
common/base64/base64.cpp)
ADD_CUSTOM_COMMAND(TARGET ${B64ATTESTATION_TO_B64COLLATERAL}
POST_BUILD
COMMAND mkdir -p ${CMAKE_CURRENT_BINARY_DIR}/conversion/dcap-direct/ &&
mv $<TARGET_FILE:${B64ATTESTATION_TO_B64COLLATERAL}> ${CMAKE_CURRENT_BINARY_DIR}/conversion/dcap-direct/)

TARGET_INCLUDE_DIRECTORIES(${B64ATTESTATION_TO_B64COLLATERAL} PRIVATE common)

# newer DCAP (1.22) libs need the qal (older, 1.19, don't)
SET(DCAP_LINK_LIBS ${DCAP_QV_PATH}/appraisal/qal/libdcap_qal.a)

TARGET_LINK_LIBRARIES(${B64ATTESTATION_TO_B64COLLATERAL}
#${DCAP_QV_PATH}/dcap_quoteverify/linux/libsgx_dcap_quoteverify.a
#${DCAP_QG_PATH}/build/linux/libdcap_quoteprov.a
#${DCAP_QG_PATH}/build/linux/libsgx_default_qcnl_wrapper.a
#sgx_dcap_quoteverify dcap_quoteprov sgx_default_qcnl_wrapper
sgx_dcap_quoteverify
# sgx_dcap_ql dcap_quoteprov necessary for the callbacks
sgx_dcap_ql
dcap_quoteprov
)

###################################################################################################
# Untrusted one-attestation library
###################################################################################################

SET(U_OA_LIB_STATIC ${U_ONE_ATTESTATION_LIB_NAME}_Static)

ADD_LIBRARY(${U_OA_LIB_STATIC} STATIC ${PROJECT_HEADERS} ${PROJECT_SOURCES} ${PROJECT_OCALLS})

TARGET_INCLUDE_DIRECTORIES(${U_OA_LIB_STATIC} PRIVATE "$ENV{SGX_SDK}/include")
TARGET_INCLUDE_DIRECTORIES(${U_OA_LIB_STATIC} PRIVATE "include")
TARGET_INCLUDE_DIRECTORIES(${U_OA_LIB_STATIC} BEFORE PRIVATE "common")
TARGET_INCLUDE_DIRECTORIES(${U_OA_LIB_STATIC} PRIVATE "common/nlohmann/json/include")
TARGET_INCLUDE_DIRECTORIES(${U_OA_LIB_STATIC} PRIVATE "common/jwt-cpp/include")
TARGET_INCLUDE_DIRECTORIES(${U_OA_LIB_STATIC} PRIVATE ${CERTIFICATE_INCLUDE_PATHS})
TARGET_INCLUDE_DIRECTORIES(${U_OA_LIB_STATIC} PRIVATE ${LOGGING_UNTRUSTED_INCLUDE_PATH})

TARGET_INCLUDE_DIRECTORIES(${U_OA_LIB_STATIC} PRIVATE "$ENV{DCAP_PRIMITIVES}/QuoteVerification/QVL/Src/Build/Release/dist/include/")
TARGET_INCLUDE_DIRECTORIES(${U_OA_LIB_STATIC} PRIVATE "$ENV{DCAP_PRIMITIVES}")
TARGET_INCLUDE_DIRECTORIES(${U_OA_LIB_STATIC} PRIVATE "$ENV{DCAP_PRIMITIVES}/QuoteVerification/QVL/Src/AttestationLibrary/src")
TARGET_INCLUDE_DIRECTORIES(${U_OA_LIB_STATIC} PRIVATE "$ENV{DCAP_PRIMITIVES}/QuoteVerification/QVL/Src/AttestationCommons/include")

TARGET_COMPILE_OPTIONS(${U_OA_LIB_STATIC} PRIVATE -fvisibility=hidden)
TARGET_COMPILE_OPTIONS(${U_OA_LIB_STATIC} PRIVATE -fpie)
TARGET_COMPILE_OPTIONS(${U_OA_LIB_STATIC} PRIVATE -fstack-protector)

SET(QVL_LIB_PATH "$ENV{DCAP_PRIMITIVES}/QuoteVerification/QVL/Src/Build/Release/dist/lib")

add_custom_target(combined_u_static_target ALL
COMMAND mkdir -p oals_objs lqvs_objs lacs_objs laps_objs
COMMAND ar -x --output oals_objs $<TARGET_FILE:${U_OA_LIB_STATIC}>
COMMAND ar -x --output lqvs_objs ${QVL_LIB_PATH}/libQuoteVerificationStatic.a
COMMAND ar -x --output lacs_objs ${QVL_LIB_PATH}/libAttestationCommonsStatic.a
COMMAND ar -x --output laps_objs ${QVL_LIB_PATH}/libAttestationParsersStatic.a
COMMAND ar -qcs lib${U_ONE_ATTESTATION_LIB_NAME}.a oals_objs/*.o lqvs_objs/*.o lacs_objs/*.o laps_objs/*.o
WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
DEPENDS ${U_OA_LIB_STATIC}
)
ADD_LIBRARY(${U_ONE_ATTESTATION_LIB_NAME} STATIC IMPORTED)
ADD_DEPENDENCIES(${U_ONE_ATTESTATION_LIB_NAME} combined_u_static_target)
SET_TARGET_PROPERTIES(${U_ONE_ATTESTATION_LIB_NAME}
PROPERTIES
IMPORTED_LOCATION lib${U_ONE_ATTESTATION_LIB_NAME}.a
)

###################################################################################################
# Trusted one-attestation library
###################################################################################################

SET(T_OA_LIB_STATIC ${T_ONE_ATTESTATION_LIB_NAME}_Static)
ADD_LIBRARY(${T_OA_LIB_STATIC} STATIC
${PROJECT_HEADERS} ${PROJECT_TRUSTED_HEADERS} ${PROJECT_SOURCES} ${PROJECT_TRUSTED_SOURCES})

#dependency in common to ensure the jwt lib is patched for building the trusted lib in SGX
ADD_DEPENDENCIES(${T_OA_LIB_STATIC} patch_jwt)

TARGET_INCLUDE_DIRECTORIES(${T_OA_LIB_STATIC} PRIVATE "common/sgx-support") # for clocale, before sgxsdk includes
TARGET_INCLUDE_DIRECTORIES(${T_OA_LIB_STATIC} PRIVATE "$ENV{SGX_SDK}/include")
TARGET_INCLUDE_DIRECTORIES(${T_OA_LIB_STATIC} PRIVATE "$ENV{SGX_SDK}/include/libcxx")
TARGET_INCLUDE_DIRECTORIES(${T_OA_LIB_STATIC} PRIVATE "$ENV{SGX_SDK}/include/tlibc")
TARGET_INCLUDE_DIRECTORIES(${T_OA_LIB_STATIC} PRIVATE "$ENV{SGX_SSL}/include")
TARGET_INCLUDE_DIRECTORIES(${T_OA_LIB_STATIC} PRIVATE "include")
TARGET_INCLUDE_DIRECTORIES(${T_OA_LIB_STATIC} BEFORE PRIVATE "common")
TARGET_INCLUDE_DIRECTORIES(${T_OA_LIB_STATIC} PRIVATE "common/nlohmann/json/include")
TARGET_INCLUDE_DIRECTORIES(${T_OA_LIB_STATIC} PRIVATE "common/jwt-cpp/include")
TARGET_INCLUDE_DIRECTORIES(${T_OA_LIB_STATIC} PRIVATE ${CERTIFICATE_INCLUDE_PATHS})
TARGET_INCLUDE_DIRECTORIES(${T_OA_LIB_STATIC} PRIVATE ${LOGGING_TRUSTED_INCLUDE_PATH})

TARGET_INCLUDE_DIRECTORIES(${T_OA_LIB_STATIC} PRIVATE "$ENV{DCAP_PRIMITIVES}/QuoteVerification/QVL/Src/Build/Release/dist/include/")
TARGET_INCLUDE_DIRECTORIES(${T_OA_LIB_STATIC} PRIVATE "$ENV{DCAP_PRIMITIVES}")
TARGET_INCLUDE_DIRECTORIES(${T_OA_LIB_STATIC} PRIVATE "$ENV{DCAP_PRIMITIVES}/QuoteVerification/QVL/Src/AttestationLibrary/src")
TARGET_INCLUDE_DIRECTORIES(${T_OA_LIB_STATIC} PRIVATE "$ENV{DCAP_PRIMITIVES}/QuoteVerification/QVL/Src/AttestationCommons/include")
TARGET_INCLUDE_DIRECTORIES(${T_OA_LIB_STATIC} PRIVATE "$ENV{DCAP_PRIMITIVES}/QuoteVerification/QVL/Src/ThirdParty/rapidjson/include")

TARGET_COMPILE_OPTIONS(${T_OA_LIB_STATIC} PRIVATE -nostdinc++)
TARGET_COMPILE_OPTIONS(${T_OA_LIB_STATIC} PRIVATE -fvisibility=hidden)
TARGET_COMPILE_OPTIONS(${T_OA_LIB_STATIC} PRIVATE -fpie)
TARGET_COMPILE_OPTIONS(${T_OA_LIB_STATIC} PRIVATE -fstack-protector)

#remove time-related code from jwt tool (as dcap primitives do)
TARGET_COMPILE_OPTIONS(${T_OA_LIB_STATIC} PRIVATE -DSGX_JWT)

add_custom_target(combined_t_static_target ALL
COMMAND mkdir -p toals_objs lacse_objs lapse_objs
COMMAND ar -x --output toals_objs $<TARGET_FILE:${T_OA_LIB_STATIC}>
COMMAND ar -x --output lacse_objs ${QVL_LIB_PATH}/libAttestationCommonsStaticEnclave.a
COMMAND ar -x --output lapse_objs ${QVL_LIB_PATH}/libAttestationParsersStaticEnclave.a
COMMAND ar -qcs lib${T_ONE_ATTESTATION_LIB_NAME}.a toals_objs/*.o lacse_objs/*.o lapse_objs/*.o
WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
DEPENDS ${U_OA_LIB_STATIC}
)
ADD_LIBRARY(${T_ONE_ATTESTATION_LIB_NAME} STATIC IMPORTED)
ADD_DEPENDENCIES(${T_ONE_ATTESTATION_LIB_NAME} combined_t_static_target)
SET_TARGET_PROPERTIES(${T_ONE_ATTESTATION_LIB_NAME}
PROPERTIES
IMPORTED_LOCATION lib${T_ONE_ATTESTATION_LIB_NAME}.a
)


###################################################################################################
# Local Tests
###################################################################################################
ENABLE_TESTING()
ADD_SUBDIRECTORY (test)

7 changes: 7 additions & 0 deletions CMakeVariables.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# Copyright 2023 Intel Corporation
#
# SPDX-License-Identifier: Apache-2.0

SET(U_ONE_ATTESTATION_LIB_NAME u-one-attestation)
SET(T_ONE_ATTESTATION_LIB_NAME t-one-attestation)

104 changes: 104 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
# Attestation API

This library implements a single API for generating and verifying hardware-based attestation (e.g., Intel SGX EPID/DCAP attestations).
The library implementation originally started as part of the Fabric Private Chaincode project, and later spun off and extended.

The library works with Intel SGX EPID attestations, verified through Intel Attestation Service (IAS), and DCAP attestations, verified through Intel Trust Authority (ITA).

## Build

Build the docker image to create an environment with all necessaty dependencies.
```bash
cd docker
make
```

### Simulation mode
Start the dev container:
```bash
docker run -v <project root>:/project -e SGX_MODE=SIM -it oaa-dev
```

Simulation mode is the default mode. It does not use actual Intel SGX operations, and tests are conducted on simulated-type attestations.

```bash
source /opt/intel/sgxsdk/environment
mkdir build
cd build
cmake ..
make
```

### Hardware mode
Start the dev container, here is an example:
```bash
docker run --network host -v <project root>:/project -e SGX_MODE=HW -it oaa-dev
```
The container is attached to the host network to download the root certificates.
Also, enabling the HW mode makes the generated artifacts use actual Intel SGX operations -- and tests are conducted on real attestations.

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.
```bash
export ITA_ROOT_CACERT_URL=<certificate url>
```

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.

```bash
source /opt/intel/sgxsdk/environment
mkdir build
cd build
cmake ..
make
```

#### Collateral (for usage and testing)
Using (or testing) SGX attestation requires some collateral. The folder to such collateral must be provided as:
```bash
export COLLATERAL_FOLDER=<path to the folder>
```

EPID collateral files:
* `spid_type.txt`, a text file containing the SPID type ("epid-linkable" or "epid-unlinkable")
* `spid.txt`, a text file containing the SPID (a 32-byte long hex string)
* `api_key.txt`, a text file containing the API key to use IAS (a 32-byte long hex string)

DCAP collateral files:
* `ita_api_key.txt`, a text file containing the API key to use ITA
* `attestation_type.txt`, a text file containing the attestation type ("dcap-sgx")


#### Testing

To run the tests in HW mode, the collateral (see above) and the SGX devices are necessary.
Assuming a default system configuration, you may want to start the dev docker image as follows:
```bash
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
```

To test everything (simulated attestations in SIM mode, and all supported attestations in HW mode for platforms that support both EPID and DCAP):
```bash
make test
```

To test everything except DCAP with ITA:
```bash
SKIP_TEST_DCAP= make test
```

To test everything except DCAP with direct verification:
```bash
SKIP_TEST_DCAP_DIRECT= make test
```
For SGX platform that do not support DCAP or FLC, both DCAP tests must be disabled.


To test everything except EPID (for SGX platforms that do not support EPID):
```bash
SKIP_TEST_EPID= make test
```

If tests fail, you may want to output some logs with:
```bash
env CTEST_OUTPUT_ON_FAILURE=1 make test
```
Loading