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

Move the validation of hmac of the PEK and chipId to attester #182

Merged
merged 2 commits into from
Sep 7, 2023
Merged
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
47 changes: 45 additions & 2 deletions src/attesters/csv/collect_evidence.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand All @@ -262,8 +266,48 @@ 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);

/* 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 */
Expand All @@ -272,11 +316,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] ^
Expand Down
32 changes: 32 additions & 0 deletions src/attesters/csv/csv_utils.c
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
#include <stddef.h>
#include <rats-tls/log.h>
#include <openssl/evp.h>
#include <openssl/hmac.h>

void gen_random_bytes(void *buf, size_t len)
{
Expand Down Expand Up @@ -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;
}
2 changes: 2 additions & 0 deletions src/attesters/csv/csv_utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);
1 change: 0 additions & 1 deletion src/verifiers/csv/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ link_directories(${LIBRARY_DIRS})

# Set source file
set(SOURCES cleanup.c
csv_utils.c
hygoncert.c
init.c
main.c
Expand Down
39 changes: 0 additions & 39 deletions src/verifiers/csv/csv_utils.c

This file was deleted.

10 changes: 0 additions & 10 deletions src/verifiers/csv/csv_utils.h

This file was deleted.

29 changes: 1 addition & 28 deletions src/verifiers/csv/verify_evidence.c
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@
#include <rats-tls/verifier.h>
#include <rats-tls/csv.h>
#include "hygoncert.h"
#include "csv_utils.h"

static enclave_verifier_err_t verify_cert_chain(csv_evidence *evidence)
{
Expand All @@ -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);
Expand Down
Loading