Skip to content

Commit

Permalink
verifiers: generate built-in claims from quotes
Browse files Browse the repository at this point in the history
In order to simplify the process of matching of Attestation Policy in user code, and to avoid user code dependencies on TEE-specific headers files / structs definitions, we convert quotes into built-in claims. These claims will be checked by user's verifier callback (verify_claims_callback) along with the user-defined claims.

Now that we have categorized these claims into (user defined) custom claims and built-in claims.

For built-in claims, they are:

- `common_quote_type`, `common_quote`
- `tdx_*`
- `sgx_*`
- `sev_snp_*`
- `csv_*`

Note that some break changes are interduced in this commit:

The old claim name in tdx verifier
```c
    #define TDX_CLAIM_RTMR0 "rtmr0"
    #define TDX_CLAIM_RTMR1 "rtmr1"
    #define TDX_CLAIM_RTMR2 "rtmr2"
    #define TDX_CLAIM_RTMR3 "rtmr3"
```
are renamed to "tdx_rtmr0", "tdx_rtmr1", "tdx_rtmr2", "tdx_rtmr3".

Signed-off-by: Kun Lai <me@imlk.top>
  • Loading branch information
imlk0 committed Sep 1, 2023
1 parent 5d7c8f0 commit b2a81b5
Show file tree
Hide file tree
Showing 11 changed files with 443 additions and 89 deletions.
2 changes: 1 addition & 1 deletion attesters/sev-snp/collect_evidence.c
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ rats_attester_err_t sev_snp_collect_evidence(rats_attester_ctx_t *ctx,
snprintf(evidence->type, sizeof(evidence->type), "sev_snp");

rats_attester_err_t err = sev_snp_get_vcek_der(report.chip_id, sizeof(report.chip_id),
&report.platform_version, snp_report);
&report.current_tcb, snp_report);
if (err != RATS_ATTESTER_ERR_NONE) {
return err;
}
Expand Down
2 changes: 1 addition & 1 deletion attesters/sev-snp/sev_snp.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ typedef struct snp_attestation_report {
uint8_t image_id[16]; /* 0x020 */
uint32_t vmpl; /* 0x030 */
uint32_t signature_algo; /* 0x034 */
snp_tcb_version_t platform_version; /* 0x038 */
snp_tcb_version_t current_tcb; /* 0x038 */
uint64_t platform_info; /* 0x040 */
uint32_t flags; /* 0x048 */
uint32_t reserved0; /* 0x04C */
Expand Down
4 changes: 2 additions & 2 deletions core/claim.c
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,9 @@ void free_claims_list(claim_t *claims, size_t claims_length)
free(claims);
}

int librats_add_claim(claim_t *claim, const void *name, size_t name_size, const void *value,
size_t value_size)
int librats_add_claim(claim_t *claim, const char *name, const void *value, size_t value_size)
{
size_t name_size = strlen(name) + 1;
claim->name = (char *)malloc(name_size);
if (claim->name == NULL)
return 1;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,6 @@
#include "internal/verifier.h"
#include "internal/dice.h"

#include <librats/csv.h>
// clang-format off
#ifdef SGX
#include "sgx_report.h"
#endif
#include "sgx_quote_3.h"
// clang-format on

crypto_wrapper_err_t
crypto_wrapper_verify_evidence(crypto_wrapper_ctx_t *crypto_ctx, attestation_evidence_t *evidence,
uint8_t *hash, uint32_t hash_len,
Expand Down
86 changes: 84 additions & 2 deletions include/librats/claim.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,89 @@
#include <librats/err.h>
#include <librats/log.h>

/* Common built-in claims */
#define BUILT_IN_CLAIM_COMMON_QUOTE "common_quote"
#define BUILT_IN_CLAIM_COMMON_QUOTE_TYPE "common_quote_type"

/* SGX built-in claims */
/* Refer to: https://github.com/intel/linux-sgx/blob/a1eeccba5a72b3b9b342569d2cc469ece106d3e9/common/inc/sgx_report.h#L93-L111 */
/* Security Version of the CPU */
#define BUILT_IN_CLAIM_SGX_CPU_SVN "sgx_cpu_svn"
/* ISV assigned Extended Product ID */
#define BUILT_IN_CLAIM_SGX_ISV_EXT_PROD_ID "sgx_isv_ext_prod_id"
/* Any special Capabilities the Enclave possess */
#define BUILT_IN_CLAIM_SGX_ATTRIBUTES "sgx_attributes"
/* The value of the enclave's ENCLAVE measurement */
#define BUILT_IN_CLAIM_SGX_MR_ENCLAVE "sgx_mr_enclave"
/* The value of the enclave's SIGNER measurement */
#define BUILT_IN_CLAIM_SGX_MR_SIGNER "sgx_mr_signer"
/* CONFIGID */
#define BUILT_IN_CLAIM_SGX_CONFIG_ID "sgx_config_id"
/* Product ID of the Enclave */
#define BUILT_IN_CLAIM_SGX_ISV_PROD_ID "sgx_isv_prod_id"
/* Security Version of the Enclave */
#define BUILT_IN_CLAIM_SGX_ISV_SVN "sgx_isv_svn"
/* CONFIGSVN */
#define BUILT_IN_CLAIM_SGX_CONFIG_SVN "sgx_config_svn"
/* ISV assigned Family ID */
#define BUILT_IN_CLAIM_SGX_ISV_FAMILY_ID "sgx_isv_family_id"

/* TDX built-in claims */
/* Refer to: https://github.com/intel/linux-sgx/blob/a1eeccba5a72b3b9b342569d2cc469ece106d3e9/common/inc/sgx_report.h#L93-L111 */
/// TEE_TCB_SVN Array
#define BUILT_IN_CLAIM_TDX_TEE_TCB_SVN "tdx_tee_tcb_svn"
/// Measurement of the SEAM module
#define BUILT_IN_CLAIM_TDX_MR_SEAM "tdx_mr_seam"
/// Measurement of a 3rd party SEAM module’s signer (SHA384 hash). The value is 0’ed for Intel SEAM module
#define BUILT_IN_CLAIM_TDX_MRSIGNER_SEAM "tdx_mrsigner_seam"
/// MBZ: TDX 1.0
#define BUILT_IN_CLAIM_TDX_SEAM_ATTRIBUTES "tdx_seam_attributes"
/// TD's attributes
#define BUILT_IN_CLAIM_TDX_TD_ATTRIBUTES "tdx_td_attributes"
/// TD's XFAM
#define BUILT_IN_CLAIM_TDX_XFAM "tdx_xfam"
/// Measurement of the initial contents of the TD
#define BUILT_IN_CLAIM_TDX_MR_TD "tdx_mr_td"
/// Software defined ID for non-owner-defined configuration on the guest TD. e.g., runtime or OS configuration
#define BUILT_IN_CLAIM_TDX_MR_CONFIG_ID "tdx_mr_config_id"
/// Software defined ID for the guest TD's owner
#define BUILT_IN_CLAIM_TDX_MR_OWNER "tdx_mr_owner"
/// Software defined ID for owner-defined configuration of the guest TD, e.g., specific to the workload rather than the runtime or OS
#define BUILT_IN_CLAIM_TDX_MR_OWNER_CONFIG "tdx_mr_owner_config"
/// Array of 4(TDX1: NUM_RTMRS is 4) runtime extendable measurement registers
#define BUILT_IN_CLAIM_TDX_RT_MR0 "tdx_rt_mr0"
#define BUILT_IN_CLAIM_TDX_RT_MR1 "tdx_rt_mr1"
#define BUILT_IN_CLAIM_TDX_RT_MR2 "tdx_rt_mr2"
#define BUILT_IN_CLAIM_TDX_RT_MR3 "tdx_rt_mr3"

/* sev-snp built-in claims */
#define BUILT_IN_CLAIM_SEV_SNP_GUEST_SVN "sev_snp_guest_svn" /* 0x004 */
#define BUILT_IN_CLAIM_SEV_SNP_POLICY "sev_snp_policy" /* 0x008 */
#define BUILT_IN_CLAIM_SEV_SNP_FAMILY_ID "sev_snp_family_id" /* 0x010 */
#define BUILT_IN_CLAIM_SEV_SNP_IMAGE_ID "sev_snp_image_id" /* 0x020 */
#define BUILT_IN_CLAIM_SEV_SNP_VMPL "sev_snp_vmpl" /* 0x030 */
#define BUILT_IN_CLAIM_SEV_SNP_CURRENT_TCB "sev_snp_current_tcb" /* 0x038 */
#define BUILT_IN_CLAIM_SEV_SNP_PLATFORM_INFO "sev_snp_platform_info" /* 0x040 */
#define BUILT_IN_CLAIM_SEV_SNP_MEASUREMENT "sev_snp_measurement" /* 0x090 */
#define BUILT_IN_CLAIM_SEV_SNP_HOST_DATA "sev_snp_host_data" /* 0x0C0 */
#define BUILT_IN_CLAIM_SEV_SNP_ID_KEY_DIGEST "sev_snp_id_key_digest" /* 0x0E0 */
#define BUILT_IN_CLAIM_SEV_SNP_REPORT_ID "sev_snp_report_id" /* 0x140 */
#define BUILT_IN_CLAIM_SEV_SNP_REPORT_ID_MA "sev_snp_report_id_ma" /* 0x160 */
#define BUILT_IN_CLAIM_SEV_SNP_REPORTED_TCB "sev_snp_reported_tcb" /* 0x180 */
#define BUILT_IN_CLAIM_SEV_SNP_CHIP_ID "sev_snp_chip_id" /* 0x1A0 */

/* csv built-in claims */
#define BUILT_IN_CLAIM_CSV_USER_PUBKEY_DIGEST "csv_user_pubkey_digest"
#define BUILT_IN_CLAIM_CSV_VM_ID "csv_vm_id"
#define BUILT_IN_CLAIM_CSV_VM_VERSION "csv_vm_version"
#define BUILT_IN_CLAIM_CSV_USER_DATA "csv_user_data"
#define BUILT_IN_CLAIM_CSV_MNONCE "csv_mnonce"
#define BUILT_IN_CLAIM_CSV_MEASURE "csv_measure"
#define BUILT_IN_CLAIM_CSV_POLICY "csv_policy"
#define BUILT_IN_CLAIM_CSV_SIG_USAGE "csv_sig_usage"
#define BUILT_IN_CLAIM_CSV_SIG_ALGO "csv_sig_algo"
#define BUILT_IN_CLAIM_CSV_CHIP_ID "csv_chip_id"

/**
* Claims struct used for claims parameters.
*/
Expand All @@ -23,8 +106,7 @@ struct claim {
} __attribute__((packed));

void free_claims_list(claim_t *claims, size_t claims_length);
int librats_add_claim(claim_t *claim, const void *name, size_t name_size, const void *value,
size_t value_size);
int librats_add_claim(claim_t *claim, const char *name, const void *value, size_t value_size);

/* This macro checks whether the expression argument evaluates to RATS_ERR_NONE */
#define CLAIM_CHECK(EXPRESSION) \
Expand Down
37 changes: 30 additions & 7 deletions samples/cert-app/common.c
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
#include <openssl/pem.h>
#include <openssl/evp.h>
#include <unistd.h>
#include <ctype.h>

int generate_key_pairs(uint8_t **private_key_out, size_t *private_key_size_out)
{
Expand Down Expand Up @@ -74,16 +75,36 @@ int generate_key_pairs(uint8_t **private_key_out, size_t *private_key_size_out)
return ret;
}

void print_claim_value(uint8_t *value, size_t value_size)
{
bool hex = false;
for (size_t i = 0; i < value_size; ++i) {
if (!isprint(value[i])) {
hex = true;
break;
}
}
if (hex) {
printf("(hex)");
for (size_t i = 0; i < value_size; ++i) {
printf("%02X", value[i]);
}
} else {
printf("'%.*s'", (int)value_size, value);
}
}

int verify_callback(claim_t *claims, size_t claims_size, void *args_in)
{
int ret = 0;
printf("----------------------------------------\n");
printf("verify_callback called, claims %p, claims_size %zu, args %p\n", claims, claims_size,
args_in);
for (size_t i = 0; i < claims_size; ++i) {
printf("claims[%zu] -> name: '%s' value_size: %zu value: '%.*s'\n", i,
claims[i].name, claims[i].value_size, (int)claims[i].value_size,
claims[i].value);
printf("claims[%zu] -> name: '%s' value_size: %zu value: ", i, claims[i].name,
claims[i].value_size);
print_claim_value(claims[i].value, claims[i].value_size);
printf("\n");
}

/* Let's check all custom claims exits and unchanged */
Expand All @@ -110,10 +131,12 @@ int verify_callback(claim_t *claims, size_t claims_size, void *args_in)
}

if (memcmp(claim->value, claims[j].value, claim->value_size)) {
printf("different claim detected -> name: '%s' value_size: %zu expected value: '%.*s' got: '%.*s'\n",
claim->name, claim->value_size,
(int)claim->value_size, claim->value,
(int)claim->value_size, claims[j].value);
printf("different claim detected -> name: '%s' value_size: %zu expected value: ",
claim->name, claim->value_size);
print_claim_value(claim->value, claim->value_size);
printf(" got: ");
print_claim_value(claims[j].value, claim->value_size);
printf("\n");
ret = 1;
break;
}
Expand Down
80 changes: 78 additions & 2 deletions verifiers/csv/verify_evidence.c
Original file line number Diff line number Diff line change
Expand Up @@ -97,12 +97,79 @@ static rats_verifier_err_t verify_attestation_report(csv_attestation_report *rep
return RATS_VERIFIER_ERR_NONE;
}

rats_verifier_err_t convert_quote_to_claims(csv_attestation_report *report, uint32_t report_size,
claim_t **claims_out, size_t *claims_length_out)
{
if (!claims_out || !claims_length_out)
return RATS_VERIFIER_ERR_NONE;
if (!report || !report_size)
return RATS_VERIFIER_ERR_INVALID_PARAMETER;

claim_t *claims = NULL;
size_t claims_length = 0;
rats_verifier_err_t err = RATS_VERIFIER_ERR_UNKNOWN;
if (claims == NULL)
return RATS_VERIFIER_ERR_NO_MEM;

claims_length = 2 + 10; /* 2 common claims + 10 csv claims */
claims = malloc(sizeof(claim_t) * claims_length);

size_t claims_index = 0;

/* common claims */
CLAIM_CHECK(librats_add_claim(&claims[claims_index++], BUILT_IN_CLAIM_COMMON_QUOTE, report,
report_size));
CLAIM_CHECK(librats_add_claim(&claims[claims_index++], BUILT_IN_CLAIM_COMMON_QUOTE_TYPE,
"csv", sizeof("csv")));

/* Clear nonce on the range from field `user_pubkey_digest` to field `anonce`, note that
pek_cert and chip_id have been retrieved in function verify_cert_chain(). */
int cnt = (offsetof(csv_attestation_report, anonce) -
offsetof(csv_attestation_report, user_pubkey_digest)) /
sizeof(uint32_t);
for (int i = 0; i < cnt; i++) {
((uint32_t *)report)[i] ^= report->anonce;
}

/* csv claims */
CLAIM_CHECK(librats_add_claim(
&claims[claims_index++], BUILT_IN_CLAIM_CSV_USER_PUBKEY_DIGEST,
(uint8_t *)&report->user_pubkey_digest, sizeof(report->user_pubkey_digest)));
CLAIM_CHECK(librats_add_claim(&claims[claims_index++], BUILT_IN_CLAIM_CSV_VM_ID,
(uint8_t *)&report->vm_id, sizeof(report->vm_id)));
CLAIM_CHECK(librats_add_claim(&claims[claims_index++], BUILT_IN_CLAIM_CSV_VM_VERSION,
(uint8_t *)&report->vm_version, sizeof(report->vm_version)));
CLAIM_CHECK(librats_add_claim(&claims[claims_index++], BUILT_IN_CLAIM_CSV_USER_DATA,
(uint8_t *)&report->user_data, sizeof(report->user_data)));
CLAIM_CHECK(librats_add_claim(&claims[claims_index++], BUILT_IN_CLAIM_CSV_MNONCE,
(uint8_t *)&report->mnonce, sizeof(report->mnonce)));
CLAIM_CHECK(librats_add_claim(&claims[claims_index++], BUILT_IN_CLAIM_CSV_MEASURE,
(uint8_t *)&report->measure, sizeof(report->measure)));
CLAIM_CHECK(librats_add_claim(&claims[claims_index++], BUILT_IN_CLAIM_CSV_POLICY,
(uint8_t *)&report->policy, sizeof(report->policy)));
CLAIM_CHECK(librats_add_claim(&claims[claims_index++], BUILT_IN_CLAIM_CSV_SIG_USAGE,
(uint8_t *)&report->sig_usage, sizeof(report->sig_usage)));
CLAIM_CHECK(librats_add_claim(&claims[claims_index++], BUILT_IN_CLAIM_CSV_SIG_ALGO,
(uint8_t *)&report->sig_algo, sizeof(report->sig_algo)));
CLAIM_CHECK(librats_add_claim(&claims[claims_index++], BUILT_IN_CLAIM_CSV_CHIP_ID,
(uint8_t *)&report->chip_id, sizeof(report->chip_id)));

*claims_out = claims;
*claims_length_out = claims_length;
claims = NULL;

err = RATS_VERIFIER_ERR_NONE;
done:
if (claims)
free_claims_list(claims, claims_index);
return err;
}

rats_verifier_err_t csv_verify_evidence(rats_verifier_ctx_t *ctx, attestation_evidence_t *evidence,
const uint8_t *hash, uint32_t hash_len,
__attribute__((unused))
attestation_endorsement_t *endorsements,
__attribute__((unused)) claim_t **claims,
__attribute__((unused)) size_t *claims_length)
claim_t **claims, size_t *claims_length)
{
RATS_DEBUG("ctx %p, evidence %p, hash %p\n", ctx, evidence, hash);

Expand All @@ -116,6 +183,7 @@ rats_verifier_err_t csv_verify_evidence(rats_verifier_ctx_t *ctx, attestation_ev
};
int i;

/* add nonce on new user_data buffer */
for (i = 0; i < sizeof(user_data) / sizeof(uint32_t); i++)
((uint32_t *)user_data)[i] = ((uint32_t *)attestation_report->user_data)[i] ^
attestation_report->anonce;
Expand All @@ -139,5 +207,13 @@ rats_verifier_err_t csv_verify_evidence(rats_verifier_ctx_t *ctx, attestation_ev
if (err != RATS_VERIFIER_ERR_NONE)
RATS_ERR("failed to verify csv attestation report\n");

if (err == RATS_VERIFIER_ERR_NONE) {
err = convert_quote_to_claims(attestation_report, sizeof(*attestation_report),
claims, claims_length);
if (err != RATS_VERIFIER_ERR_NONE)
RATS_ERR(
"failed to convert csv attestation report to builtin claims: %#x\n",
err);
}
return err;
}
Loading

0 comments on commit b2a81b5

Please sign in to comment.