From ad8216a785a81de985e51c7a0a4bbb49f906e644 Mon Sep 17 00:00:00 2001 From: hanliyang Date: Wed, 24 Aug 2022 23:51:08 -0400 Subject: [PATCH 1/2] attester/csv: Check the mnonce of attestation report to avoid replay attack from other entities Signed-off-by: hanliyang --- src/attesters/csv/collect_evidence.c | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/src/attesters/csv/collect_evidence.c b/src/attesters/csv/collect_evidence.c index 9abc6da8..f741a4a4 100644 --- a/src/attesters/csv/collect_evidence.c +++ b/src/attesters/csv/collect_evidence.c @@ -253,6 +253,10 @@ static int collect_attestation_evidence(uint8_t *hash, uint32_t hash_len, goto err_munmap; } + /* Save user_data->mnonce to check the timeliness of attestation report later */ + unsigned char cur_mnonce[CSV_ATTESTATION_MNONCE_SIZE]; + memcpy(cur_mnonce, user_data->mnonce, CSV_ATTESTATION_MNONCE_SIZE); + /* Request ATTESTATION */ user_data_pa = (uint64_t)gva_to_gpa(user_data); ret = do_hypercall(KVM_HC_VM_ATTESTATION, (unsigned long)user_data_pa, CSV_GUEST_MAP_LEN); @@ -262,6 +266,20 @@ static int collect_attestation_evidence(uint8_t *hash, uint32_t hash_len, goto err_munmap; } + /* Check whether the attestation report is fresh */ + unsigned char report_mnonce[CSV_ATTESTATION_MNONCE_SIZE]; + csv_attestation_report *attestation_report = (csv_attestation_report *)user_data; + int i; + + for (i = 0; i < CSV_ATTESTATION_MNONCE_SIZE / sizeof(uint32_t); i++) + ((uint32_t *)report_mnonce)[i] = ((uint32_t *)attestation_report->mnonce)[i] ^ + attestation_report->anonce; + ret = memcmp(cur_mnonce, report_mnonce, CSV_ATTESTATION_MNONCE_SIZE); + if (ret) { + RTLS_ERR("mnonce is not fresh\n"); + goto err_munmap; + } + /* Fill evidence buffer with attestation report */ assert(sizeof(csv_attestation_report) <= CSV_GUEST_MAP_LEN); memcpy(evidence->report, (void *)user_data, sizeof(csv_attestation_report)); @@ -272,11 +290,10 @@ static int collect_attestation_evidence(uint8_t *hash, uint32_t hash_len, assert(sizeof(csv_evidence) <= sizeof(evidence->report)); /* Retreive ChipId from attestation report */ - csv_attestation_report *attestation_report = &evidence_buffer->attestation_report; uint8_t chip_id[CSV_ATTESTATION_CHIP_SN_SIZE + 1] = { 0, }; - int i; + attestation_report = &evidence_buffer->attestation_report; for (i = 0; i < CSV_ATTESTATION_CHIP_SN_SIZE / sizeof(uint32_t); i++) ((uint32_t *)chip_id)[i] = ((uint32_t *)attestation_report->chip_id)[i] ^ From 7e2fd9702d00181fed22e0580ab53c54d51ec8d5 Mon Sep 17 00:00:00 2001 From: hanliyang Date: Sat, 9 Sep 2023 20:44:11 +0000 Subject: [PATCH 2/2] rats-tls: csv: validate the hmac of PEK and ChipId in attester Signed-off-by: hanliyang --- src/attesters/csv/collect_evidence.c | 26 +++++++++++++++++++ src/attesters/csv/csv_utils.c | 32 +++++++++++++++++++++++ src/attesters/csv/csv_utils.h | 2 ++ src/verifiers/csv/CMakeLists.txt | 1 - src/verifiers/csv/csv_utils.c | 39 ---------------------------- src/verifiers/csv/csv_utils.h | 10 ------- src/verifiers/csv/verify_evidence.c | 29 +-------------------- 7 files changed, 61 insertions(+), 78 deletions(-) delete mode 100644 src/verifiers/csv/csv_utils.c delete mode 100644 src/verifiers/csv/csv_utils.h diff --git a/src/attesters/csv/collect_evidence.c b/src/attesters/csv/collect_evidence.c index f741a4a4..d7079c89 100644 --- a/src/attesters/csv/collect_evidence.c +++ b/src/attesters/csv/collect_evidence.c @@ -282,6 +282,32 @@ static int collect_attestation_evidence(uint8_t *hash, uint32_t hash_len, /* Fill evidence buffer with attestation report */ assert(sizeof(csv_attestation_report) <= CSV_GUEST_MAP_LEN); + + /* The PEK and ChipId are stored in csv_attestation_report, it's necessary + * to validate PEK and ChipId before transfer to verifier. + */ + hash_block_t hmac; + + memset((void *)&hmac, 0, sizeof(hash_block_t)); + ret = sm3_hmac((const char *)report_mnonce, CSV_ATTESTATION_MNONCE_SIZE, + (const unsigned char *)attestation_report + + CSV_ATTESTATION_REPORT_HMAC_DATA_OFFSET, + CSV_ATTESTATION_REPORT_HMAC_DATA_SIZE, (unsigned char *)&hmac, + sizeof(hash_block_t)); + if (ret) { + RTLS_ERR("failed to compute sm3 hmac\n"); + goto err_munmap; + } + ret = memcmp(&hmac, &attestation_report->hmac, sizeof(hash_block_t)); + if (ret) { + RTLS_ERR("PEK and ChipId may have been tampered with\n"); + goto err_munmap; + } + RTLS_DEBUG("check PEK and ChipId successfully\n"); + + /* Reserved1 field should be filled with 0 */ + memset(attestation_report->reserved1, 0, sizeof(attestation_report->reserved1)); + memcpy(evidence->report, (void *)user_data, sizeof(csv_attestation_report)); /* Fill in CEK cert and HSK cert */ diff --git a/src/attesters/csv/csv_utils.c b/src/attesters/csv/csv_utils.c index 190988d3..755cd8ad 100644 --- a/src/attesters/csv/csv_utils.c +++ b/src/attesters/csv/csv_utils.c @@ -7,6 +7,7 @@ #include #include #include +#include void gen_random_bytes(void *buf, size_t len) { @@ -46,3 +47,34 @@ int sm3_hash(const unsigned char *data, size_t len, unsigned char *hash, size_t return ret; } + +int sm3_hmac(const char *key, size_t key_len, const unsigned char *data, size_t data_len, + unsigned char *hmac, size_t expected_hmac_len) +{ + HMAC_CTX *hmac_ctx = HMAC_CTX_new(); + const EVP_MD *evp_md = EVP_sm3(); + int sm3_hmac_out_size = 0; + int ret = -1; + + if (hmac_ctx == NULL) + return ret; + + if (!HMAC_Init_ex(hmac_ctx, key, key_len, evp_md, NULL)) + goto err_free_hmac_ctx; + + if (!HMAC_Update(hmac_ctx, data, data_len)) + goto err_free_hmac_ctx; + + if (!HMAC_Final(hmac_ctx, hmac, &sm3_hmac_out_size)) + goto err_free_hmac_ctx; + + if (sm3_hmac_out_size != expected_hmac_len) + goto err_free_hmac_ctx; + + ret = 0; + +err_free_hmac_ctx: + HMAC_CTX_free(hmac_ctx); + + return ret; +} diff --git a/src/attesters/csv/csv_utils.h b/src/attesters/csv/csv_utils.h index 2ab74870..45f26d1d 100644 --- a/src/attesters/csv/csv_utils.h +++ b/src/attesters/csv/csv_utils.h @@ -8,3 +8,5 @@ void gen_random_bytes(void *buf, size_t len); int sm3_hash(const unsigned char *data, size_t len, unsigned char *hash, size_t expected_hash_len); +int sm3_hmac(const char *key, size_t key_len, const unsigned char *data, size_t data_len, + unsigned char *hmac, size_t expected_hmac_len); diff --git a/src/verifiers/csv/CMakeLists.txt b/src/verifiers/csv/CMakeLists.txt index c6e76f04..f7772383 100644 --- a/src/verifiers/csv/CMakeLists.txt +++ b/src/verifiers/csv/CMakeLists.txt @@ -16,7 +16,6 @@ link_directories(${LIBRARY_DIRS}) # Set source file set(SOURCES cleanup.c - csv_utils.c hygoncert.c init.c main.c diff --git a/src/verifiers/csv/csv_utils.c b/src/verifiers/csv/csv_utils.c deleted file mode 100644 index 79180f6e..00000000 --- a/src/verifiers/csv/csv_utils.c +++ /dev/null @@ -1,39 +0,0 @@ -/* Copyright (c) 2022 Hygon Corporation - * Copyright (c) 2020-2022 Alibaba Cloud - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include -#include - -int sm3_hmac(const char *key, size_t key_len, const unsigned char *data, size_t data_len, - unsigned char *hmac, size_t expected_hmac_len) -{ - HMAC_CTX *hmac_ctx = HMAC_CTX_new(); - const EVP_MD *evp_md = EVP_sm3(); - int sm3_hmac_out_size = 0; - int ret = -1; - - if (hmac_ctx == NULL) - return ret; - - if (!HMAC_Init_ex(hmac_ctx, key, key_len, evp_md, NULL)) - goto err_free_hmac_ctx; - - if (!HMAC_Update(hmac_ctx, data, data_len)) - goto err_free_hmac_ctx; - - if (!HMAC_Final(hmac_ctx, hmac, &sm3_hmac_out_size)) - goto err_free_hmac_ctx; - - if (sm3_hmac_out_size != expected_hmac_len) - goto err_free_hmac_ctx; - - ret = 0; - -err_free_hmac_ctx: - HMAC_CTX_free(hmac_ctx); - - return ret; -} diff --git a/src/verifiers/csv/csv_utils.h b/src/verifiers/csv/csv_utils.h deleted file mode 100644 index 3afa875f..00000000 --- a/src/verifiers/csv/csv_utils.h +++ /dev/null @@ -1,10 +0,0 @@ -/* Copyright (c) 2022 Hygon Corporation - * Copyright (c) 2020-2022 Alibaba Cloud - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include - -int sm3_hmac(const char *key, size_t key_len, const unsigned char *data, size_t data_len, - unsigned char *hmac, size_t expected_hmac_len); diff --git a/src/verifiers/csv/verify_evidence.c b/src/verifiers/csv/verify_evidence.c index 03a560d3..2b061fdc 100644 --- a/src/verifiers/csv/verify_evidence.c +++ b/src/verifiers/csv/verify_evidence.c @@ -10,7 +10,6 @@ #include #include #include "hygoncert.h" -#include "csv_utils.h" static enclave_verifier_err_t verify_cert_chain(csv_evidence *evidence) { @@ -24,35 +23,9 @@ static enclave_verifier_err_t verify_cert_chain(csv_evidence *evidence) assert(sizeof(hygon_root_cert_t) == HYGON_CERT_SIZE); assert(sizeof(csv_cert_t) == HYGON_CSV_CERT_SIZE); - /* The PEK and ChipId are stored in csv_attestation_report, it's necessary - * to check whether PEK and ChipId have been tampered with. - */ - hash_block_t hmac; - uint8_t mnonce[CSV_ATTESTATION_MNONCE_SIZE] = { - 0, - }; + /* Retrieve PEK cert and ChipId */ int i, j; - /* Retrieve mnonce which is the key of sm3-hmac */ - j = CSV_ATTESTATION_MNONCE_SIZE / sizeof(uint32_t); - for (i = 0; i < j; i++) - ((uint32_t *)mnonce)[i] = ((uint32_t *)report->mnonce)[i] ^ report->anonce; - - memset((void *)&hmac, 0, sizeof(hash_block_t)); - if (sm3_hmac((const char *)mnonce, CSV_ATTESTATION_MNONCE_SIZE, - (const unsigned char *)report + CSV_ATTESTATION_REPORT_HMAC_DATA_OFFSET, - CSV_ATTESTATION_REPORT_HMAC_DATA_SIZE, (unsigned char *)&hmac, - sizeof(hash_block_t))) { - RTLS_ERR("failed to compute sm3 hmac\n"); - return err; - } - if (memcmp(&hmac, &report->hmac, sizeof(hash_block_t))) { - RTLS_ERR("PEK and ChipId may have been tampered with\n"); - return err; - } - RTLS_DEBUG("check PEK and ChipId successfully\n"); - - /* Retrieve PEK cert and ChipId */ j = (offsetof(csv_attestation_report, reserved1) - offsetof(csv_attestation_report, pek_cert)) / sizeof(uint32_t);