Skip to content

Commit

Permalink
TDX collateral API update (#176)
Browse files Browse the repository at this point in the history
Problem:

New APIs for fetching TDX collateral were added by intel and we need parity.

What was done:

Added the following TDX API functions and the unit tests associated with them.

quote3_error_t tdx_ql_get_quote_verification_collateral(const uint8_t *fmspc, uint16_t fmspc_size, const char *pck_ca, tdx_ql_qve_collateral_t **pp_quote_collateral);

quote3_error_t tdx_ql_free_quote_verification_collateral(tdx_ql_qve_collateral_t *p_quote_collateral);

How the code was tested:

E2E test and OE tests ran successfully
  • Loading branch information
FranciscoJavierOrtegaPalacios authored Apr 12, 2023
1 parent 39e0381 commit 828f00e
Show file tree
Hide file tree
Showing 17 changed files with 901 additions and 116 deletions.
10 changes: 2 additions & 8 deletions .github/workflows/buildPipeline.yml
Original file line number Diff line number Diff line change
Expand Up @@ -493,7 +493,7 @@ jobs:
uses: ./.github/actions/actionAzVmRunCommand
with:
commandName: "makeDcapTests"
script: "cd /AzureDCAP/src/Linux/ext/intel/ && sudo cp * /usr/include/ && cd ../.. && make"
script: "cd /AzureDCAP/src/ && sudo cp sgx_ql_lib_common.h /usr/include/ && cd /AzureDCAP/src/Linux/ext/intel/ && sudo cp * /usr/include/ && cd ../.. && make"

- name: Run DCAP tests
uses: ./.github/actions/actionAzVmRunCommand
Expand Down Expand Up @@ -579,12 +579,6 @@ jobs:
- name: Sleep to let the VM start
run: sleep 60

- name: Update dnf
uses: ./.github/actions/actionAzVmRunCommand
with:
commandName: "updateDNF"
script: "sudo dnf check-update -y"

- name: Update packages through dnf
uses: ./.github/actions/actionAzVmRunCommand
Expand Down Expand Up @@ -740,7 +734,7 @@ jobs:
uses: ./.github/actions/actionAzVmRunCommand
with:
commandName: "makeDcapTests"
script: "cd /AzureDCAP/src/Linux/ext/intel/ && sudo cp * /usr/include/ && cd ../.. && make"
script: "cd /AzureDCAP/src/ && sudo cp sgx_ql_lib_common.h /usr/include/ && cd /AzureDCAP/src/Linux/ext/intel/ && sudo cp * /usr/include/ && cd ../.. && make"

- name: Run DCAP tests
uses: ./.github/actions/actionAzVmRunCommand
Expand Down
2 changes: 1 addition & 1 deletion src/Linux/configure
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ fi
CURLHPATH=`dirname $CURLHFILE`
cat Makefile.in | sed "s|##CURLINC##|$CURLHPATH|g" > Makefile

fetch_from_intel_github SGXDataCenterAttestationPrimitives/0436284f12f1bd5da7e7a06f6274d36b4c8d39f9/QuoteGeneration/quote_wrapper/common/inc/sgx_ql_lib_common.h
#fetch_from_intel_github SGXDataCenterAttestationPrimitives/0436284f12f1bd5da7e7a06f6274d36b4c8d39f9/QuoteGeneration/quote_wrapper/common/inc/sgx_ql_lib_common.h
fetch_from_intel_github linux-sgx/1ccf25b64abd1c2eff05ead9d14b410b3c9ae7be/common/inc/sgx_report.h
fetch_from_intel_github linux-sgx/1ccf25b64abd1c2eff05ead9d14b410b3c9ae7be/common/inc/sgx_key.h
fetch_from_intel_github linux-sgx/1ccf25b64abd1c2eff05ead9d14b410b3c9ae7be/common/inc/sgx_attributes.h
Expand Down
16 changes: 12 additions & 4 deletions src/Linux/curl_easy.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ static std::string to_lower(const std::string& inout)
c = std::tolower(c, loc);
}

return inout;
return retval;
}

// OWS is defined in RFC 7230 as "OWS = *( SP / HTAB )"
Expand All @@ -43,9 +43,17 @@ static bool is_optional_whitespace(char c)

static bool is_http_version(const char* buffer, size_t buffer_size)
{
static constexpr char HTTP_VERSION[] = "HTTP/1.1";
return buffer_size >= sizeof(HTTP_VERSION) - 1 &&
0 == memcmp(buffer, HTTP_VERSION, sizeof(HTTP_VERSION) - 1);
bool result = false;

static constexpr char HTTP_VERSION1[] = "HTTP/1.1";
static constexpr char HTTP_VERSION2[] = "HTTP/2";
static constexpr char HTTP_VERSION3[] = "HTTP/3";
if((buffer_size >= sizeof(HTTP_VERSION1) - 1 && 0 == memcmp(buffer, HTTP_VERSION1, sizeof(HTTP_VERSION1) - 1)) ||
(buffer_size >= sizeof(HTTP_VERSION2) - 1 && 0 == memcmp(buffer, HTTP_VERSION2, sizeof(HTTP_VERSION2) - 1)) ||
(buffer_size >= sizeof(HTTP_VERSION3) - 1 && 0 == memcmp(buffer, HTTP_VERSION3, sizeof(HTTP_VERSION3) - 1)))
result = true;

return result;
}

///////////////////////////////////////////////////////////////////////////////
Expand Down
4 changes: 2 additions & 2 deletions src/Linux/local_cache.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -343,7 +343,7 @@ void local_cache_add(
}

std::unique_ptr<std::vector<uint8_t>> local_cache_get(
const std::string& id)
const std::string& id, bool checkExpiration)
{
throw_if(id.empty(), "The 'id' parameter must not be empty.");

Expand All @@ -362,7 +362,7 @@ std::unique_ptr<std::vector<uint8_t>> local_cache_get(
CacheEntryHeaderV1 header{};
cache_file.read(reinterpret_cast<char*>(&header), sizeof(header));

if (header.expiry <= time(nullptr))
if (checkExpiration && header.expiry <= time(nullptr))
{
cache_file.close();
unlink(file_name.c_str());
Expand Down
133 changes: 129 additions & 4 deletions src/UnitTest/test_quote_prov.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,9 @@ typedef quote3_error_t (*sgx_ql_free_quote_config_t)(
typedef quote3_error_t (*sgx_ql_free_quote_verification_collateral_t)(
sgx_ql_qve_collateral_t* p_quote_collateral);

typedef quote3_error_t (*tdx_ql_free_quote_verification_collateral_t)(
tdx_ql_qve_collateral_t* p_quote_collateral);

typedef quote3_error_t (*sgx_ql_free_qve_identity_t)(
char* p_qve_identity,
char* p_qve_identity_issuer_chain);
Expand All @@ -76,6 +79,12 @@ typedef quote3_error_t (*sgx_ql_get_quote_verification_collateral_with_params_t)
const uint16_t custom_param_length,
sgx_ql_qve_collateral_t** pp_quote_collateral);

typedef quote3_error_t (*tdx_ql_get_quote_verification_collateral_t)(
const uint8_t* fmspc,
const uint16_t fmspc_size,
const char* pck_ca,
tdx_ql_qve_collateral_t** pp_quote_collateral);

typedef quote3_error_t (*sgx_ql_get_qve_identity_t)(
char** pp_qve_identity,
uint32_t* p_qve_identity_size,
Expand All @@ -97,18 +106,24 @@ static sgx_ql_get_quote_config_t sgx_ql_get_quote_config;
static sgx_ql_set_logging_function_t sgx_ql_set_logging_function;
static sgx_ql_free_quote_verification_collateral_t
sgx_ql_free_quote_verification_collateral;
static tdx_ql_free_quote_verification_collateral_t
tdx_ql_free_quote_verification_collateral;
static sgx_ql_free_qve_identity_t sgx_ql_free_qve_identity;
static sgx_ql_free_root_ca_crl_t sgx_ql_free_root_ca_crl;
static sgx_ql_get_quote_verification_collateral_t
sgx_ql_get_quote_verification_collateral;
static sgx_ql_get_quote_verification_collateral_with_params_t
sgx_ql_get_quote_verification_collateral_with_params;
static tdx_ql_get_quote_verification_collateral_t
tdx_ql_get_quote_verification_collateral;
static sgx_ql_get_qve_identity_t sgx_ql_get_qve_identity;
static sgx_ql_get_root_ca_crl_t sgx_ql_get_root_ca_crl;

// Test FMSPC
static constexpr uint8_t TEST_FMSPC[] = {0x00, 0x90, 0x6E, 0xA1, 0x00, 0x00};
static constexpr uint8_t ICX_TEST_FMSPC[] = {0x00, 0x60, 0x6a, 0x00, 0x00, 0x00};
static constexpr uint8_t TDX_TEST_FMSPC[] =
{0x00, 0x80, 0x6F, 0x05, 0x00, 0x00};

const uint16_t custom_param_length = 45;
const char *custom_param = "tcbEvaluationDataNumber=11;region=us central";
Expand Down Expand Up @@ -264,6 +279,11 @@ static void* LoadFunctions()
dlsym(library, "sgx_ql_free_quote_verification_collateral"));
EXPECT_NE(sgx_ql_free_quote_verification_collateral, nullptr);

tdx_ql_free_quote_verification_collateral =
reinterpret_cast<tdx_ql_free_quote_verification_collateral_t>(
dlsym(library, "tdx_ql_free_quote_verification_collateral"));
EXPECT_NE(tdx_ql_free_quote_verification_collateral, nullptr);

sgx_ql_free_qve_identity = reinterpret_cast<sgx_ql_free_qve_identity_t>(
dlsym(library, "sgx_ql_free_qve_identity"));
EXPECT_NE(sgx_ql_free_qve_identity, nullptr);
Expand All @@ -282,6 +302,11 @@ static void* LoadFunctions()
dlsym(library, "sgx_ql_get_quote_verification_collateral"));
EXPECT_NE(sgx_ql_get_quote_verification_collateral, nullptr);

tdx_ql_get_quote_verification_collateral =
reinterpret_cast<tdx_ql_get_quote_verification_collateral_t>(
dlsym(library, "tdx_ql_get_quote_verification_collateral"));
EXPECT_NE(tdx_ql_get_quote_verification_collateral, nullptr);

sgx_ql_get_qve_identity = reinterpret_cast<sgx_ql_get_qve_identity_t>(
dlsym(library, "sgx_ql_get_qve_identity"));
EXPECT_NE(sgx_ql_get_qve_identity, nullptr);
Expand Down Expand Up @@ -331,6 +356,12 @@ static HINSTANCE LoadFunctions()
hLibCapdll, "sgx_ql_free_quote_verification_collateral"));
EXPECT_NE(sgx_ql_free_quote_verification_collateral, nullptr);

tdx_ql_free_quote_verification_collateral =
reinterpret_cast<tdx_ql_free_quote_verification_collateral_t>(
GetProcAddress(
hLibCapdll, "tdx_ql_free_quote_verification_collateral"));
EXPECT_NE(tdx_ql_free_quote_verification_collateral, nullptr);

sgx_ql_free_qve_identity = reinterpret_cast<sgx_ql_free_qve_identity_t>(
GetProcAddress(hLibCapdll, "sgx_ql_free_qve_identity"));
EXPECT_NE(sgx_ql_free_qve_identity, nullptr);
Expand All @@ -350,6 +381,12 @@ static HINSTANCE LoadFunctions()
hLibCapdll, "sgx_ql_get_quote_verification_collateral_with_params"));
EXPECT_NE(sgx_ql_get_quote_verification_collateral_with_params, nullptr);

tdx_ql_get_quote_verification_collateral =
reinterpret_cast<tdx_ql_get_quote_verification_collateral_t>(
GetProcAddress(
hLibCapdll, "tdx_ql_get_quote_verification_collateral"));
EXPECT_NE(tdx_ql_get_quote_verification_collateral, nullptr);

sgx_ql_get_qve_identity = reinterpret_cast<sgx_ql_get_qve_identity_t>(
GetProcAddress(hLibCapdll, "sgx_ql_get_qve_identity"));
EXPECT_NE(sgx_ql_get_qve_identity, nullptr);
Expand Down Expand Up @@ -519,11 +556,11 @@ static void GetCrlTestICXV3()
VerifyCrlOutput(params);
}

static inline void VerifyCollateral(sgx_ql_qve_collateral_t* collateral)
static inline void VerifyCollateralCommon(sgx_ql_qve_collateral_t* collateral)
{
boolean TEST_SUCCESS = false;
ASSERT_TRUE(collateral != nullptr);
ASSERT_TRUE(collateral->version == 1);
ASSERT_TRUE(collateral->version == 1 || (collateral->major_version == 4 && collateral->minor_version == 0));
ASSERT_TRUE(collateral->tee_type == 0x0 || collateral->tee_type == 0x81);
ASSERT_TRUE(collateral->pck_crl != nullptr);
ASSERT_TRUE(collateral->pck_crl_size > 0);
ASSERT_TRUE(collateral->pck_crl_issuer_chain != nullptr);
Expand All @@ -547,11 +584,26 @@ static inline void VerifyCollateral(sgx_ql_qve_collateral_t* collateral)
ASSERT_TRUE(collateral->root_ca_crl[collateral->root_ca_crl_size - 1] == '\0');
ASSERT_TRUE(collateral->tcb_info[collateral->tcb_info_size - 1] == '\0');
ASSERT_TRUE(collateral->tcb_info_issuer_chain[collateral->tcb_info_issuer_chain_size - 1] == '\0');
}

static inline void VerifyCollateral(sgx_ql_qve_collateral_t* collateral)
{
boolean TEST_SUCCESS = false;
VerifyCollateralCommon(collateral);
sgx_ql_free_quote_verification_collateral(collateral);
TEST_SUCCESS = true;
ASSERT_TRUE(TEST_SUCCESS);
}

static inline void VerifyCollateralTDX(tdx_ql_qve_collateral_t* collateral)
{
boolean TEST_SUCCESS = false;
VerifyCollateralCommon(collateral);
tdx_ql_free_quote_verification_collateral(collateral);
TEST_SUCCESS = true;
ASSERT_TRUE(TEST_SUCCESS);
}

//
// Fetches and validates verification APIs of QPL
//
Expand All @@ -573,7 +625,6 @@ static void GetVerificationCollateralTest()
static void GetVerificationCollateralTestWithParams()
{
// Test input (choose an arbitrary Azure server)

sgx_ql_qve_collateral_t* collateral = nullptr;
std::string tcbInfoTcbEvaluationDataNumber;
std::string enclaveIdentityTcbEvaluationDataNumber;
Expand Down Expand Up @@ -683,6 +734,16 @@ static void GetVerificationCollateralTestICXV3WithIncorrectParams()
ASSERT_TRUE(SGX_QL_NO_QUOTE_COLLATERAL_DATA == result);
}

static void GetVerificationCollateralTestTDX()
{
local_cache_clear();
tdx_ql_qve_collateral_t* collateral = nullptr;
quote3_error_t result = tdx_ql_get_quote_verification_collateral(
TDX_TEST_FMSPC, sizeof(TDX_TEST_FMSPC), "processor", &collateral);
ASSERT_TRUE(SGX_QL_SUCCESS == result);
VerifyCollateralTDX(collateral);
}

static boolean GetQveIdentityTest()
{
boolean TEST_SUCCESS = false;
Expand Down Expand Up @@ -1153,6 +1214,52 @@ void SetupEnvironment(std::string version)
#endif
}

void SetupEnvironmentTDX(std::string version)
{
#if defined __LINUX__
setenv(
"AZDCAP_PRIMARY_BASE_CERT_URL",
"",
1);
setenv(
"ENV_AZDCAP_SECONDARY_BASE_CERT_URL",
"",
1);
setenv(
"AZDCAP_BASE_CERT_URL_TDX",
"",
1);
setenv(
"AZDCAP_REGION_URL",
"eastus2euap",
1);
setenv("AZDCAP_CLIENT_ID", "AzureDCAPTestsLinux", 1);
if (!version.empty())
{
setenv("AZDCAP_COLLATERAL_VERSION_TDX", version.c_str(), 1);
}
#else
std::stringstream version_var;
EXPECT_TRUE(SetEnvironmentVariableA(
"AZDCAP_PRIMARY_BASE_CERT_URL",
""));
EXPECT_TRUE(SetEnvironmentVariableA(
"AZDCAP_SECONDARY_BASE_CERT_URL", ""));
EXPECT_TRUE(SetEnvironmentVariableA(
"AZDCAP_BASE_CERT_URL_TDX", ""));
EXPECT_TRUE(SetEnvironmentVariableA(
"AZDCAP_REGION_URL",
"eastus2euap"));
EXPECT_TRUE(
SetEnvironmentVariableA("AZDCAP_CLIENT_ID", "AzureDCAPTestsWindows"));
if (!version.empty())
{
EXPECT_TRUE(SetEnvironmentVariableA(
"AZDCAP_COLLATERAL_VERSION_TDX", version.c_str()));
}
#endif
}

void SetupEnvironmentToReachSecondary()
{
#if defined __LINUX__
Expand Down Expand Up @@ -1264,6 +1371,24 @@ TEST(testQuoteProv, quoteProviderTestsV3Data)
#endif
}

TEST(testQuoteProv, quoteProviderTestsGetVerificationCollateralTDX)
{
libary_type_t library = LoadFunctions();
ASSERT_TRUE(SGX_PLAT_ERROR_OK == sgx_ql_set_logging_function(Log));

//
// Get the data from the service
//
SetupEnvironmentTDX("v4");
GetVerificationCollateralTestTDX();

#if defined __LINUX__
dlclose(library);
#else
FreeLibrary(library);
#endif
}

TEST(testQuoteProv, quoteProviderTestsWithIncorrectCustomParam)
{
libary_type_t library = LoadFunctions();
Expand Down
9 changes: 6 additions & 3 deletions src/Windows/GeneratePackage/Azure.DCAP.Windows.nuspec
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,15 @@
<package xmlns="http://schemas.microsoft.com/packaging/2013/05/nuspec.xsd">
<metadata>
<id>Microsoft.Azure.DCAP</id>
<version>1.11.2</version>
<version>1.12.0</version>
<!-- Authors contain text that appears directly on the gallery -->
<authors>Microsoft</authors>
<owners>Microsoft</owners>
<requireLicenseAcceptance>false</requireLicenseAcceptance>
<releaseNotes>
*Enable certificate fetch from host agent for quote generation
*Enable customer to provide tcb baseline for evidence verification
Added support for TDX quote validation through the following API
*quote3_error_t tdx_ql_get_quote_verification_collateral(const uint8_t *fmspc, uint16_t fmspc_size, const char *pck_ca, tdx_ql_qve_collateral_t **pp_quote_collateral)
*quote3_error_t tdx_ql_free_quote_verification_collateral(tdx_ql_qve_collateral_t *p_quote_collateral)
</releaseNotes>
<description>
This library serves as a quoting data provider plugin for the Intel SGX Data Center Attestation Primitives (DCAP). Specifically, the Intel DCAP library will search out and load provider plugins, such as the Azure DCAP Client.
Expand All @@ -28,5 +29,7 @@
<file src=".\InstallAzureDCAP.ps1" target="tools" />
<!-- A readme.txt to display when the package is installed -->
<file src=".\README.txt" target="" />
<!-- NOTICE.txt with the distribution licenses of the open source files used in dcap-->
<file src=".\NOTICE.txt" target="" />
</files>
</package>
39 changes: 39 additions & 0 deletions src/Windows/GeneratePackage/NOTICE.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
NOTICES

This repository incorporates material as listed below or described in the code.

Components.
sgx_ql_lib_common.h, sgx_attributes.h, sgx_key.h, sgx_report.h

Open Source License/Copyright Notice.

/*
* Copyright (C) 2011-2019 Intel Corporation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Intel Corporation nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
Loading

0 comments on commit 828f00e

Please sign in to comment.