From dc1606adde087b068bdb2503c92d289d287847ee Mon Sep 17 00:00:00 2001 From: Qiucheng Wang Date: Mon, 2 Nov 2020 19:25:09 +0000 Subject: [PATCH] Expose sgx report body fields by oe claims Signed-off-by: Qiucheng Wang --- common/sgx/verifier.c | 105 ++++++++++++++++-- .../openenclave/attestation/sgx/evidence.h | 21 +++- include/openenclave/bits/sgx/sgxtypes.h | 21 +++- tests/attestation_plugin/plugin/tests.c | 83 ++++++++++++-- 4 files changed, 203 insertions(+), 27 deletions(-) diff --git a/common/sgx/verifier.c b/common/sgx/verifier.c index d4ed5dbc97..9c26569892 100644 --- a/common/sgx/verifier.c +++ b/common/sgx/verifier.c @@ -226,24 +226,34 @@ static oe_result_t _fill_with_known_claims( oe_result_t result = OE_UNEXPECTED; oe_report_t parsed_report = {0}; oe_identity_t* id = &parsed_report.identity; + const sgx_report_body_t* sgx_report_body = NULL; size_t claims_index = 0; oe_datetime_t valid_from = {0}; oe_datetime_t valid_until = {0}; + bool flag; - if (claims_length < OE_REQUIRED_CLAIMS_COUNT) + if (claims_length < OE_REQUIRED_CLAIMS_COUNT + OE_SGX_REQUIRED_CLAIMS_COUNT) OE_RAISE(OE_INVALID_PARAMETER); if (format_type == SGX_FORMAT_TYPE_LOCAL) - OE_CHECK(oe_parse_sgx_report_body( - &((sgx_report_t*)report_body)->body, false, &parsed_report)); + { + sgx_report_body = &((sgx_report_t*)report_body)->body; + OE_CHECK( + oe_parse_sgx_report_body(sgx_report_body, false, &parsed_report)); + } + else - OE_CHECK(oe_parse_sgx_report_body( - &((sgx_quote_t*)report_body)->report_body, true, &parsed_report)); + { + sgx_report_body = &((sgx_quote_t*)report_body)->report_body; + OE_CHECK( + oe_parse_sgx_report_body(sgx_report_body, true, &parsed_report)); + } // Optional claims are needed for SGX quotes for remote attestation if (format_type != SGX_FORMAT_TYPE_LOCAL && claims_length < OE_REQUIRED_CLAIMS_COUNT + OE_OPTIONAL_CLAIMS_COUNT + - OE_SGX_CLAIMS_COUNT) + OE_SGX_REQUIRED_CLAIMS_COUNT + + OE_SGX_OPTIONAL_CLAIMS_COUNT) OE_RAISE(OE_INVALID_PARAMETER); // ID version. @@ -302,6 +312,83 @@ static oe_result_t _fill_with_known_claims( format_id, sizeof(*format_id))); + // SGX Exit Info Reported to an SSA Frame or Not + flag = !!(sgx_report_body->miscselect & SGX_MISC_FLAGS_PF_GP_EXIT_INFO); + OE_CHECK(oe_sgx_add_claim( + &claims[claims_index++], + OE_CLAIM_SGX_PF_GP_EXINFO_ENABLED, + sizeof(OE_CLAIM_SGX_PF_GP_EXINFO_ENABLED), + &flag, + sizeof(flag))); + + // SGX Report ISV Extended Product ID + OE_CHECK(oe_sgx_add_claim( + &claims[claims_index++], + OE_CLAIM_SGX_ISV_EXTENDED_PRODUCT_ID, + sizeof(OE_CLAIM_SGX_ISV_EXTENDED_PRODUCT_ID), + sgx_report_body->isvextprodid, + sizeof(sgx_report_body->isvextprodid))); + + // SGX Report Is Mode 64bit or Not + flag = !!(sgx_report_body->attributes.flags & SGX_FLAGS_MODE64BIT); + OE_CHECK(oe_sgx_add_claim( + &claims[claims_index++], + OE_CLAIM_SGX_IS_MODE64BIT, + sizeof(OE_CLAIM_SGX_IS_MODE64BIT), + &flag, + sizeof(flag))); + + // SGX Report Has Provision Key or Not + flag = !!(sgx_report_body->attributes.flags & SGX_FLAGS_PROVISION_KEY); + OE_CHECK(oe_sgx_add_claim( + &claims[claims_index++], + OE_CLAIM_SGX_HAS_PROVISION_KEY, + sizeof(OE_CLAIM_SGX_HAS_PROVISION_KEY), + &flag, + sizeof(flag))); + + // SGX Report Has Einittoken Key or Not + flag = !!(sgx_report_body->attributes.flags & SGX_FLAGS_EINITTOKEN_KEY); + OE_CHECK(oe_sgx_add_claim( + &claims[claims_index++], + OE_CLAIM_SGX_HAS_EINITTOKEN_KEY, + sizeof(OE_CLAIM_SGX_HAS_EINITTOKEN_KEY), + &flag, + sizeof(flag))); + + // SGX Use KSS or Not + flag = !!(sgx_report_body->attributes.flags & SGX_FLAGS_KSS); + OE_CHECK(oe_sgx_add_claim( + &claims[claims_index++], + OE_CLAIM_SGX_USES_KSS, + sizeof(OE_CLAIM_SGX_USES_KSS), + &flag, + sizeof(flag))); + + // SGX Report Config ID + OE_CHECK(oe_sgx_add_claim( + &claims[claims_index++], + OE_CLAIM_SGX_CONFIG_ID, + sizeof(OE_CLAIM_SGX_CONFIG_ID), + sgx_report_body->configid, + sizeof(sgx_report_body->configid))); + + // SGX Report Config SVN + OE_CHECK(oe_sgx_add_claim( + &claims[claims_index++], + OE_CLAIM_SGX_CONFIG_SVN, + sizeof(OE_CLAIM_SGX_CONFIG_SVN), + &sgx_report_body->configsvn, + sizeof(sgx_report_body->configsvn))); + + // SGX Report ISV Family ID + OE_CHECK(oe_sgx_add_claim( + &claims[claims_index++], + OE_CLAIM_SGX_ISV_FAMILY_ID, + sizeof(OE_CLAIM_SGX_ISV_FAMILY_ID), + sgx_report_body->isvfamilyid, + sizeof(sgx_report_body->isvfamilyid))); + if (format_type != SGX_FORMAT_TYPE_LOCAL) { // Get quote validity periods to get validity from and until claims. @@ -481,13 +568,15 @@ oe_result_t oe_sgx_extract_claims( // Get the number of claims we need and allocate the claims. OE_CHECK(oe_safe_add_u64( - OE_REQUIRED_CLAIMS_COUNT, additional_claim, &claims_length)); + OE_REQUIRED_CLAIMS_COUNT + OE_SGX_REQUIRED_CLAIMS_COUNT, + additional_claim, + &claims_length)); if (format_type != SGX_FORMAT_TYPE_LOCAL) { OE_CHECK(oe_safe_add_u64( claims_length, - OE_OPTIONAL_CLAIMS_COUNT + OE_SGX_CLAIMS_COUNT, + OE_OPTIONAL_CLAIMS_COUNT + OE_SGX_OPTIONAL_CLAIMS_COUNT, &claims_length)); } diff --git a/include/openenclave/attestation/sgx/evidence.h b/include/openenclave/attestation/sgx/evidence.h index f62c0bc0ee..1fb1e2e303 100644 --- a/include/openenclave/attestation/sgx/evidence.h +++ b/include/openenclave/attestation/sgx/evidence.h @@ -122,8 +122,23 @@ OE_EXTERNC_BEGIN 0x00, 0x00, 0x00, 0x00, 0x00 \ } -// SGX specific claims: SGX Quote verification collateral. - +// SGX specific claims +// Required: SGX report body fields that every SQX Quote verification should +// output. +// 1 boolean flag indicated by "sgx_misc_select_t" +#define OE_CLAIM_SGX_PF_GP_EXINFO_ENABLED "sgx_pf_gp_exit_info_enabled" +#define OE_CLAIM_SGX_ISV_EXTENDED_PRODUCT_ID "sgx_isv_extended_product_id" +// 4 boolean flags indicated by "sgx_attributes_t" +#define OE_CLAIM_SGX_IS_MODE64BIT "sgx_is_mode64bit" +#define OE_CLAIM_SGX_HAS_PROVISION_KEY "sgx_has_provision_key" +#define OE_CLAIM_SGX_HAS_EINITTOKEN_KEY "sgx_has_einittoken_key" +#define OE_CLAIM_SGX_USES_KSS "sgx_uses_kss" +#define OE_CLAIM_SGX_CONFIG_ID "sgx_config_id" +#define OE_CLAIM_SGX_CONFIG_SVN "sgx_config_svn" +#define OE_CLAIM_SGX_ISV_FAMILY_ID "sgx_isv_family_id" +#define OE_SGX_REQUIRED_CLAIMS_COUNT 9 + +// Optional: SQX Quote verification collaterals. #define OE_CLAIM_SGX_TCB_INFO "sgx_tcb_info" #define OE_CLAIM_SGX_TCB_ISSUER_CHAIN "sgx_tcb_issuer_chain" #define OE_CLAIM_SGX_PCK_CRL "sgx_pck_crl" @@ -131,7 +146,7 @@ OE_EXTERNC_BEGIN #define OE_CLAIM_SGX_CRL_ISSUER_CHAIN "sgx_crl_issuer_chain" #define OE_CLAIM_SGX_QE_ID_INFO "sgx_qe_id_info" #define OE_CLAIM_SGX_QE_ID_ISSUER_CHAIN "sgx_qe_id_issuer_chain" -#define OE_SGX_CLAIMS_COUNT 7 +#define OE_SGX_OPTIONAL_CLAIMS_COUNT 7 // Additional SGX specific claim: for the report data embedded in the SGX quote. diff --git a/include/openenclave/bits/sgx/sgxtypes.h b/include/openenclave/bits/sgx/sgxtypes.h index 4b2f692328..af315268cc 100644 --- a/include/openenclave/bits/sgx/sgxtypes.h +++ b/include/openenclave/bits/sgx/sgxtypes.h @@ -597,14 +597,17 @@ typedef struct _sgx_report_body /* (64) Enclave measurement */ uint8_t mrenclave[OE_SHA256_SIZE]; - /* (96) */ + /* (96) Reserved */ uint8_t reserved2[32]; /* (128) The value of the enclave's SIGNER measurement */ uint8_t mrsigner[OE_SHA256_SIZE]; - /* (160) */ - uint8_t reserved3[96]; + /* (160) Reserved */ + uint8_t reserved3[32]; + + /* (192) Enclave Configuration ID*/ + uint8_t configid[64]; /* (256) Enclave product ID */ uint16_t isvprodid; @@ -612,8 +615,11 @@ typedef struct _sgx_report_body /* (258) Enclave security version */ uint16_t isvsvn; - /* (260) Reserved */ - uint8_t reserved4[44]; + /* (260) Enclave Configuration Security Version*/ + uint16_t configsvn; + + /* (262) Reserved */ + uint8_t reserved4[42]; /* (304) Enclave family ID */ uint8_t isvfamilyid[16]; @@ -1042,6 +1048,11 @@ typedef struct _sgx_key uint8_t buf[16]; } sgx_key_t; +/* Enclave MISCSELECT Flags Bit Masks, additional information to an SSA frame */ +/* If set, then the enclave page fault and general protection exception are + * reported*/ +#define SGX_MISC_FLAGS_PF_GP_EXIT_INFO 0x0000000000000001ULL + /* Enclave Flags Bit Masks */ /* If set, then the enclave is initialized */ #define SGX_FLAGS_INITTED 0x0000000000000001ULL diff --git a/tests/attestation_plugin/plugin/tests.c b/tests/attestation_plugin/plugin/tests.c index 3126a9a2e3..5e830f54eb 100644 --- a/tests/attestation_plugin/plugin/tests.c +++ b/tests/attestation_plugin/plugin/tests.c @@ -575,10 +575,12 @@ void verify_sgx_evidence( void* from; void* until; bool is_local; + bool flag; sgx_evidence_format_type_t format_type = SGX_FORMAT_TYPE_UNKNOWN; const uint8_t* report_body = NULL; size_t report_body_size = 0; + const sgx_report_body_t* sgx_report_body = NULL; const uint8_t* endorsements_body = NULL; size_t endorsements_body_size = 0; @@ -727,16 +729,14 @@ void verify_sgx_evidence( &claims_size), OE_OK); - // Make sure that the identity info matches with the regular oe report. + // Check SGX report identity and OE claims + sgx_report_body = format_type == SGX_FORMAT_TYPE_LOCAL + ? &((sgx_report_t*)report_body)->body + : &((sgx_quote_t*)report_body)->report_body; + // Make sure that the identity info matches with the regular oe report. OE_TEST_CODE( - oe_parse_sgx_report_body( - (format_type == SGX_FORMAT_TYPE_LOCAL - ? &((sgx_report_t*)report_body)->body - : &((sgx_quote_t*)report_body)->report_body), - !is_local, - &report), - OE_OK); + oe_parse_sgx_report_body(sgx_report_body, !is_local, &report), OE_OK); // Check id version. value = _find_claim(claims, claims_size, OE_CLAIM_ID_VERSION); @@ -780,6 +780,65 @@ void verify_sgx_evidence( value = _find_claim(claims, claims_size, OE_CLAIM_FORMAT_UUID); OE_TEST(value != NULL && memcmp(value, format_id, sizeof(*format_id)) == 0); + // Check SGX Page Fault, General Protection Exception Reported to an SSA + // Frame or Not + flag = !!(sgx_report_body->miscselect & SGX_MISC_FLAGS_PF_GP_EXIT_INFO); + value = _find_claim(claims, claims_size, OE_CLAIM_SGX_PF_GP_EXINFO_ENABLED); + OE_TEST(value != NULL && memcmp(value, &flag, sizeof(flag)) == 0); + + // Check SGX Report ISV Extended Product ID + value = + _find_claim(claims, claims_size, OE_CLAIM_SGX_ISV_EXTENDED_PRODUCT_ID); + OE_TEST( + value != NULL && memcmp( + value, + sgx_report_body->isvextprodid, + sizeof(sgx_report_body->isvextprodid)) == 0); + + // Check SGX Report Is Mode 64bit or Not + flag = !!(sgx_report_body->attributes.flags & SGX_FLAGS_MODE64BIT); + value = _find_claim(claims, claims_size, OE_CLAIM_SGX_IS_MODE64BIT); + OE_TEST(value != NULL && memcmp(value, &flag, sizeof(flag)) == 0); + + // Check SGX Report Has Provision Key or Not + flag = !!(sgx_report_body->attributes.flags & SGX_FLAGS_PROVISION_KEY); + value = _find_claim(claims, claims_size, OE_CLAIM_SGX_HAS_PROVISION_KEY); + OE_TEST(value != NULL && memcmp(value, &flag, sizeof(flag)) == 0); + + // Check SGX Report Has Einittoken Key or Not + flag = !!(sgx_report_body->attributes.flags & SGX_FLAGS_EINITTOKEN_KEY); + value = _find_claim(claims, claims_size, OE_CLAIM_SGX_HAS_EINITTOKEN_KEY); + OE_TEST(value != NULL && memcmp(value, &flag, sizeof(flag)) == 0); + + // Check SGX Use KSS or Not + flag = !!(sgx_report_body->attributes.flags & SGX_FLAGS_KSS); + value = _find_claim(claims, claims_size, OE_CLAIM_SGX_USES_KSS); + OE_TEST(value != NULL && memcmp(value, &flag, sizeof(flag)) == 0); + + // Check SGX Report Configuration ID + value = _find_claim(claims, claims_size, OE_CLAIM_SGX_CONFIG_ID); + OE_TEST( + value != NULL && memcmp( + value, + sgx_report_body->configid, + sizeof(sgx_report_body->configid)) == 0); + + // Check SGX Report Configuration Security Version + value = _find_claim(claims, claims_size, OE_CLAIM_SGX_CONFIG_SVN); + OE_TEST( + value != NULL && memcmp( + value, + &sgx_report_body->configsvn, + sizeof(sgx_report_body->configsvn)) == 0); + + // Check SGX Report ISV Family ID + value = _find_claim(claims, claims_size, OE_CLAIM_SGX_ISV_FAMILY_ID); + OE_TEST( + value != NULL && memcmp( + value, + sgx_report_body->isvfamilyid, + sizeof(sgx_report_body->isvfamilyid)) == 0); + // Check date time. from = _find_claim(claims, claims_size, OE_CLAIM_VALIDITY_FROM); OE_TEST(is_local || from != NULL); @@ -787,12 +846,14 @@ void verify_sgx_evidence( until = _find_claim(claims, claims_size, OE_CLAIM_VALIDITY_UNTIL); OE_TEST(is_local || until != NULL); - // Check SGX endorsements related claims: + // Check SGX optional claims: if (expected_endorsements) { - for (uint32_t i = OE_REQUIRED_CLAIMS_COUNT + OE_OPTIONAL_CLAIMS_COUNT, + for (uint32_t i = OE_REQUIRED_CLAIMS_COUNT + + OE_SGX_REQUIRED_CLAIMS_COUNT + + OE_OPTIONAL_CLAIMS_COUNT, j = 1; - j <= OE_SGX_CLAIMS_COUNT; + j <= OE_SGX_OPTIONAL_CLAIMS_COUNT; i++, j++) { value = claims[i].value;