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

5.0.x allow SGX attestation checking on SNP and Virtual #6821

Open
wants to merge 5 commits into
base: release/5.x
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
205 changes: 115 additions & 90 deletions include/ccf/pal/attestation.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,9 @@

#if !defined(INSIDE_ENCLAVE) || defined(VIRTUAL_ENCLAVE)
# include <sys/ioctl.h>
# ifdef SGX_ATTESTATION_VERIFICATION
# include <ccf/pal/attestation_sgx.h>
# endif
#else
# include "ccf/pal/attestation_sgx.h"
#endif
Expand Down Expand Up @@ -207,6 +210,113 @@ namespace ccf::pal
}
}

#if (defined(INSIDE_ENCLAVE) && !defined(VIRTUAL_ENCLAVE)) || \
defined(SGX_ATTESTATION_VERIFICATION)
static void verify_sgx_quote(
const QuoteInfo& quote_info,
PlatformAttestationMeasurement& measurement,
PlatformAttestationReportData& report_data)
{
if (quote_info.format != QuoteFormat::oe_sgx_v1)
{
throw std::logic_error(fmt::format(
"Unexpected attestation quote to verify for SGX: {}",
quote_info.format));
}

sgx::Claims claims;

auto rc = oe_verify_evidence(
&sgx::oe_quote_format,
quote_info.quote.data(),
quote_info.quote.size(),
quote_info.endorsements.data(),
quote_info.endorsements.size(),
nullptr,
0,
&claims.data,
&claims.length);
if (rc != OE_OK)
{
throw std::logic_error(fmt::format(
"Failed to verify evidence in SGX attestation report: {}",
oe_result_str(rc)));
}

std::optional<SgxAttestationMeasurement> claim_measurement = std::nullopt;
std::optional<SgxAttestationReportData> custom_claim_report_data =
std::nullopt;
for (size_t i = 0; i < claims.length; i++)
{
auto& claim = claims.data[i];
auto claim_name = std::string(claim.name);
if (claim_name == OE_CLAIM_UNIQUE_ID)
{
if (claim.value_size != SgxAttestationMeasurement::size())
{
throw std::logic_error(
fmt::format("SGX measurement claim is not of expected size"));
}

claim_measurement =
SgxAttestationMeasurement({claim.value, claim.value_size});
}
else if (claim_name == OE_CLAIM_CUSTOM_CLAIMS_BUFFER)
{
// Find sgx report data in custom claims
sgx::CustomClaims custom_claims;
rc = oe_deserialize_custom_claims(
claim.value,
claim.value_size,
&custom_claims.data,
&custom_claims.length);
if (rc != OE_OK)
{
throw std::logic_error(fmt::format(
"Failed to deserialise custom claims in SGX attestation report",
oe_result_str(rc)));
}

for (size_t j = 0; j < custom_claims.length; j++)
{
const auto& custom_claim = custom_claims.data[j];
if (std::string(custom_claim.name) == sgx::report_data_claim_name)
{
if (custom_claim.value_size != SgxAttestationReportData::size())
{
throw std::logic_error(fmt::format(
"Expected claim {} of size {}, had size {}",
sgx::report_data_claim_name,
SgxAttestationReportData::size(),
custom_claim.value_size));
}

custom_claim_report_data = SgxAttestationReportData(
{custom_claim.value, custom_claim.value_size});

break;
}
}
}
}

if (!claim_measurement.has_value())
{
throw std::logic_error(
"Could not find measurement in SGX attestation report");
}

if (!custom_claim_report_data.has_value())
{
throw std::logic_error(
"Could not find report data in SGX attestation report");
}

measurement = claim_measurement.value();
report_data = custom_claim_report_data.value();
}
#endif

#if defined(PLATFORM_VIRTUAL)

static void generate_quote(
Expand Down Expand Up @@ -276,6 +386,9 @@ namespace ccf::pal
}
else
{
# if defined(SGX_ATTESTATION_VERIFICATION)
verify_sgx_quote(quote_info, measurement, report_data);
# else
if (is_sev_snp)
{
throw std::logic_error(
Expand All @@ -286,6 +399,7 @@ namespace ccf::pal
throw std::logic_error(
"Cannot verify SGX attestation report if node is virtual");
}
# endif
}
}

Expand Down Expand Up @@ -365,96 +479,7 @@ namespace ccf::pal
return;
}

sgx::Claims claims;

auto rc = oe_verify_evidence(
&sgx::oe_quote_format,
quote_info.quote.data(),
quote_info.quote.size(),
quote_info.endorsements.data(),
quote_info.endorsements.size(),
nullptr,
0,
&claims.data,
&claims.length);
if (rc != OE_OK)
{
throw std::logic_error(fmt::format(
"Failed to verify evidence in SGX attestation report: {}",
oe_result_str(rc)));
}

std::optional<SgxAttestationMeasurement> claim_measurement = std::nullopt;
std::optional<SgxAttestationReportData> custom_claim_report_data =
std::nullopt;
for (size_t i = 0; i < claims.length; i++)
{
auto& claim = claims.data[i];
auto claim_name = std::string(claim.name);
if (claim_name == OE_CLAIM_UNIQUE_ID)
{
if (claim.value_size != SgxAttestationMeasurement::size())
{
throw std::logic_error(
fmt::format("SGX measurement claim is not of expected size"));
}

claim_measurement =
SgxAttestationMeasurement({claim.value, claim.value_size});
}
else if (claim_name == OE_CLAIM_CUSTOM_CLAIMS_BUFFER)
{
// Find sgx report data in custom claims
sgx::CustomClaims custom_claims;
rc = oe_deserialize_custom_claims(
claim.value,
claim.value_size,
&custom_claims.data,
&custom_claims.length);
if (rc != OE_OK)
{
throw std::logic_error(fmt::format(
"Failed to deserialise custom claims in SGX attestation report",
oe_result_str(rc)));
}

for (size_t j = 0; j < custom_claims.length; j++)
{
auto& custom_claim = custom_claims.data[j];
if (std::string(custom_claim.name) == sgx::report_data_claim_name)
{
if (custom_claim.value_size != SgxAttestationReportData::size())
{
throw std::logic_error(fmt::format(
"Expected claim {} of size {}, had size {}",
sgx::report_data_claim_name,
SgxAttestationReportData::size(),
custom_claim.value_size));
}

custom_claim_report_data = SgxAttestationReportData(
{custom_claim.value, custom_claim.value_size});

break;
}
}
}
}

if (!claim_measurement.has_value())
{
throw std::logic_error(
"Could not find measurement in SGX attestation report");
}

if (!custom_claim_report_data.has_value())
{
throw std::logic_error(
"Could not find report data in SGX attestation report");
}

measurement = claim_measurement.value();
report_data = custom_claim_report_data.value();
verify_sgx_quote(quote_info, measurement, report_data);
}

#endif
Expand Down
9 changes: 7 additions & 2 deletions include/ccf/pal/attestation_sgx.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,16 @@
// Licensed under the Apache 2.0 License.
#pragma once

#if defined(INSIDE_ENCLAVE) && !defined(VIRTUAL_ENCLAVE)
#if (defined(INSIDE_ENCLAVE) && !defined(VIRTUAL_ENCLAVE)) || \
defined(SGX_ATTESTATION_VERIFICATION)

# include <array>
# include <openenclave/attestation/attester.h>
# include <openenclave/attestation/custom_claims.h>
# include <openenclave/attestation/sgx/evidence.h>
# include <openenclave/attestation/verifier.h>
# if defined(INSIDE_ENCLAVE) && !defined(VIRTUAL_ENCLAVE)
# include <openenclave/attestation/attester.h>
# endif

namespace ccf::pal
{
Expand Down Expand Up @@ -48,6 +51,7 @@ namespace ccf::pal
}
};

# if defined(INSIDE_ENCLAVE) && !defined(VIRTUAL_ENCLAVE)
struct Evidence
{
uint8_t* buffer = NULL;
Expand All @@ -69,6 +73,7 @@ namespace ccf::pal
oe_free_endorsements(buffer);
}
};
# endif

static constexpr oe_uuid_t oe_quote_format = {OE_FORMAT_UUID_SGX_ECDSA};
static constexpr auto report_data_claim_name = OE_CLAIM_SGX_REPORT_DATA;
Expand Down