Skip to content

Commit

Permalink
librats: remove system() and bugfix
Browse files Browse the repository at this point in the history
1. Remove system(), like using libcurl instead of "wget", etc.
2. Embed vcek into sev-snp evidence instead of acquired by the verifier.
3. Bugfix: replace rats_verifier_err_t with rats_attester_err_t in csv attester.

Signed-off-by: wangya <wangya.zs@alibaba-inc.com>
  • Loading branch information
zeuson0 authored and YangLiang3 committed Jul 8, 2022
1 parent 4ef56ce commit 989b8f0
Show file tree
Hide file tree
Showing 23 changed files with 303 additions and 285 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
- make
- autoconf
- libtool
- libcurl
- gcc
- g++ (ubuntu 18.04)
- SGX driver, Intel SGX SDK & PSW: Please refer to this [guide](https://download.01.org/intel-sgx/sgx-linux/2.14/docs/Intel_SGX_SW_Installation_Guide_for_Linux.pdf) to install.
Expand Down
2 changes: 1 addition & 1 deletion attesters/csv/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ set(SOURCES cleanup.c

# Generate library
add_library(${PROJECT_NAME} SHARED ${SOURCES})
target_link_libraries(${PROJECT_NAME} ${RATS_LDFLAGS} ${RATS_LIB} crypto)
target_link_libraries(${PROJECT_NAME} ${RATS_LDFLAGS} ${RATS_LIB} crypto curl)
set_target_properties(${PROJECT_NAME} PROPERTIES VERSION ${VERSION} SOVERSION ${VERSION_MAJOR})

# Install library
Expand Down
2 changes: 1 addition & 1 deletion attesters/csv/cleanup.c
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
#include <librats/attester.h>
#include <librats/log.h>

rats_verifier_err_t csv_attester_cleanup(rats_attester_ctx_t *ctx)
rats_attester_err_t csv_attester_cleanup(rats_attester_ctx_t *ctx)
{
RATS_DEBUG("called\n");

Expand Down
13 changes: 6 additions & 7 deletions attesters/csv/collect_evidence.c
Original file line number Diff line number Diff line change
Expand Up @@ -95,14 +95,13 @@ static int load_hsk_cek_cert(uint8_t *hsk_cek_cert, const char *chip_id)
{
/* Download HSK and CEK cert by ChipId */
const char filename[] = HYGON_HSK_CEK_CERT_FILENAME;
char cmdline_str[200] = {
char url[200] = {
0,
};
int count = snprintf(cmdline_str, sizeof(cmdline_str), "wget -O %s %s%s", filename,
HYGON_KDS_SERVER_SITE, chip_id);
cmdline_str[count] = '\0';
int count = snprintf(url, sizeof(url), "%s%s", HYGON_KDS_SERVER_SITE, chip_id);
url[count] = '\0';

if (system(cmdline_str) != 0) {
if (download_from_url(url, filename) != 0) {
RATS_ERR("failed to download %s by %s\n", filename, chip_id);
return -1;
}
Expand Down Expand Up @@ -177,7 +176,7 @@ static int collect_attestation_evidence(uint8_t *hash, uint32_t hash_len,
/* Prepare user defined data (challenge and mnonce) */
memcpy(user_data->data, hash,
hash_len <= CSV_ATTESTATION_USER_DATA_SIZE ? hash_len :
CSV_ATTESTATION_USER_DATA_SIZE);
CSV_ATTESTATION_USER_DATA_SIZE);
gen_random_bytes(user_data->mnonce, CSV_ATTESTATION_MNONCE_SIZE);

/* Prepare hash of user defined data */
Expand Down Expand Up @@ -232,7 +231,7 @@ static int collect_attestation_evidence(uint8_t *hash, uint32_t hash_len,
return ret;
}

rats_verifier_err_t csv_collect_evidence(rats_attester_ctx_t *ctx, attestation_evidence_t *evidence,
rats_attester_err_t csv_collect_evidence(rats_attester_ctx_t *ctx, attestation_evidence_t *evidence,
uint8_t *hash, __attribute__((unused)) uint32_t hash_len)
{
RATS_DEBUG("ctx %p, evidence %p, hash %p\n", ctx, evidence, hash);
Expand Down
2 changes: 1 addition & 1 deletion attesters/csv/init.c
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@

static unsigned int dummy_private;

rats_verifier_err_t csv_attester_init(rats_attester_ctx_t *ctx)
rats_attester_err_t csv_attester_init(rats_attester_ctx_t *ctx)
{
RATS_DEBUG("ctx %p\n", ctx);

Expand Down
12 changes: 6 additions & 6 deletions attesters/csv/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,13 @@
#include <librats/attester.h>
#include <librats/log.h>

extern rats_verifier_err_t rats_attester_register(rats_attester_opts_t *opts);
extern rats_verifier_err_t csv_attester_pre_init(void);
extern rats_verifier_err_t csv_attester_init(rats_attester_ctx_t *ctx);
extern rats_verifier_err_t csv_collect_evidence(rats_attester_ctx_t *ctx,
extern rats_attester_err_t rats_attester_register(rats_attester_opts_t *opts);
extern rats_attester_err_t csv_attester_pre_init(void);
extern rats_attester_err_t csv_attester_init(rats_attester_ctx_t *ctx);
extern rats_attester_err_t csv_collect_evidence(rats_attester_ctx_t *ctx,
attestation_evidence_t *evidence, uint8_t *hash,
uint32_t hash_len);
extern rats_verifier_err_t csv_attester_cleanup(rats_attester_ctx_t *ctx);
extern rats_attester_err_t csv_attester_cleanup(rats_attester_ctx_t *ctx);

static rats_attester_opts_t csv_attester_opts = {
.api_version = RATS_ATTESTER_API_VERSION_DEFAULT,
Expand All @@ -31,7 +31,7 @@ void __attribute__((constructor)) libattester_csv_init(void)
{
RATS_DEBUG("called\n");

rats_verifier_err_t err = rats_attester_register(&csv_attester_opts);
rats_attester_err_t err = rats_attester_register(&csv_attester_opts);
if (err != RATS_ATTESTER_ERR_NONE)
RATS_DEBUG("failed to register the rats register 'csv' %#x\n", err);
}
12 changes: 2 additions & 10 deletions attesters/csv/pre_init.c
Original file line number Diff line number Diff line change
Expand Up @@ -7,17 +7,9 @@
#include <librats/attester.h>
#include <librats/log.h>

rats_verifier_err_t csv_attester_pre_init(void)
rats_attester_err_t csv_attester_pre_init(void)
{
RATS_DEBUG("called\n");

rats_verifier_err_t err = RATS_ATTESTER_ERR_NONE;

char *cmdline_str = "which wget 1> /dev/null 2> /dev/null";
if (system(cmdline_str) != 0) {
RATS_ERR("please install wget for csv attest\n");
err = -RATS_ATTESTER_ERR_NO_TOOL;
}

return err;
return RATS_ATTESTER_ERR_NONE;
}
3 changes: 1 addition & 2 deletions attesters/sev-snp/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ set(INCLUDE_DIRS ${CMAKE_CURRENT_SOURCE_DIR}/../../include
${CMAKE_CURRENT_SOURCE_DIR}/../../include/librats
${CMAKE_CURRENT_SOURCE_DIR}/../../include/internal
${CMAKE_CURRENT_SOURCE_DIR}
/usr/include
)
include_directories(${INCLUDE_DIRS})

Expand All @@ -27,7 +26,7 @@ set(SOURCES cleanup.c

# Generate library
add_library(${PROJECT_NAME} SHARED ${SOURCES})
target_link_libraries(${PROJECT_NAME} ${RATS_LDFLAGS} ${RATS_LIB})
target_link_libraries(${PROJECT_NAME} ${RATS_LDFLAGS} ${RATS_LIB} curl)
set_target_properties(${PROJECT_NAME} PROPERTIES VERSION ${VERSION} SOVERSION ${VERSION_MAJOR})
# Install library
install(TARGETS ${PROJECT_NAME}
Expand Down
100 changes: 96 additions & 4 deletions attesters/sev-snp/collect_evidence.c
Original file line number Diff line number Diff line change
Expand Up @@ -15,24 +15,28 @@
#include <linux/sev-guest.h>
#include <librats/attester.h>
#include <librats/log.h>
#include <curl/curl.h>
#include "sev_snp.h"

#define SEV_GUEST_DEVICE "/dev/sev-guest"
#define KDS_CERT_SITE "https://kdsintf.amd.com"
#define KDS_VCEK KDS_CERT_SITE "/vcek/v1/"
#define CURL_RETRY_TIMES 5

static int snp_get_report(const uint8_t *data, size_t data_size, snp_attestation_report_t *report)
{
struct snp_report_req req;
struct snp_report_resp resp;
struct snp_guest_request_ioctl guest_req;
snp_msg_report_rsp_t *report_resp = (struct msg_report_resp *)&resp.data;
snp_msg_report_rsp_t *report_resp = (struct snp_msg_report_rsp *)&resp.data;

if (data && (data_size > sizeof(req.user_data) || data_size == 0) || !data || !report)
if ((data && data_size > sizeof(req.user_data)) || !report)
return -1;

/* Initialize data structures */
memset(&req, 0, sizeof(req));
req.vmpl = 1;
if (data)
if (data && data_size)
memcpy(&req.user_data, data, data_size);

memset(&resp, 0, sizeof(resp));
Expand Down Expand Up @@ -80,6 +84,90 @@ static int snp_get_report(const uint8_t *data, size_t data_size, snp_attestation
return -1;
}

static size_t curl_writefunc_callback(void *contents, size_t size, size_t nmemb, void *userp)
{
size_t realsize = size * nmemb;
snp_attestation_evidence_t *snp_report = (snp_attestation_evidence_t *)userp;

if (snp_report->vcek_len + realsize > VECK_MAX_SIZE) {
RATS_ERR("vcek size is larger than %d bytes.", VECK_MAX_SIZE);
return 0;
}
memcpy(&(snp_report->vcek[snp_report->vcek_len]), contents, realsize);
snp_report->vcek_len += realsize;
snp_report->vcek[snp_report->vcek_len] = 0;

return realsize;
}

rats_attester_err_t sev_snp_get_vcek_der(const uint8_t *chip_id, size_t chip_id_size,
const snp_tcb_version_t *tcb,
snp_attestation_evidence_t *snp_report)
{
/* clear the vcek in snp_report */
memset(snp_report->vcek, 0, VECK_MAX_SIZE);
snp_report->vcek_len = 0;

/* 2 chars per byte +1 for null term */
char id_buf[chip_id_size * 2 + 1];
memset(id_buf, 0, sizeof(id_buf));
for (uint8_t i = 0; i < chip_id_size; i++) {
sprintf(id_buf + 2 * i * sizeof(uint8_t), "%02x", chip_id[i]);
}

int count = 0;
char url[256] = {
0,
};

count = snprintf(url, sizeof(url), "%sMilan/%s", KDS_VCEK, id_buf);

char *TCBStringArray[8];
TCBStringArray[0] = "blSPL=";
TCBStringArray[1] = "teeSPL=";
TCBStringArray[2] = "reserved0SPL=";
TCBStringArray[3] = "reserved1SPL=";
TCBStringArray[4] = "reserved2SPL=";
TCBStringArray[5] = "reserved3SPL=";
TCBStringArray[6] = "snpSPL=";
TCBStringArray[7] = "ucodeSPL=";

/* Generate VCEK cert correspond to @chip_id and @tcb */
count += snprintf((char *)&url[count], sizeof(url) - count, "?%s%02u&%s%02u&%s%02u&%s%02u",
TCBStringArray[0], (unsigned)tcb->f.boot_loader, TCBStringArray[1],
(unsigned)tcb->f.tee, TCBStringArray[6], (unsigned)tcb->f.snp,
TCBStringArray[7], (unsigned)tcb->f.microcode);

url[count] = '\0';
// init curl
CURLcode curl_ret = CURLE_OK;
CURL *curl = curl_easy_init();
if (!curl) {
RATS_ERR("failed to init curl.");
return RATS_ATTESTER_ERR_NO_TOOL;
}

curl_easy_setopt(curl, CURLOPT_URL, url);
curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, 5);
curl_easy_setopt(curl, CURLOPT_TIMEOUT, 10);
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, curl_writefunc_callback);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *)snp_report);
for (int i = 0; i < CURL_RETRY_TIMES; i++) {
if ((curl_ret = curl_easy_perform(curl)) == CURLE_OK) {
break;
}
RATS_DEBUG("failed to download vcek_der, try again.");
}
curl_easy_cleanup(curl);
if (curl_ret != CURLE_OK) {
RATS_ERR("failed to download vcek_der after %d retries,%s\n", CURL_RETRY_TIMES,
curl_easy_strerror(curl_ret));
return RATS_ATTESTER_ERR_CURL;
}

return RATS_ATTESTER_ERR_NONE;
}

rats_attester_err_t sev_snp_collect_evidence(rats_attester_ctx_t *ctx,
attestation_evidence_t *evidence, uint8_t *hash,
uint32_t hash_len)
Expand All @@ -100,7 +188,11 @@ rats_attester_err_t sev_snp_collect_evidence(rats_attester_ctx_t *ctx,

snprintf(evidence->type, sizeof(evidence->type), "sev_snp");

RATS_DEBUG("ctx %p, evidence %p, report_len %d\n", ctx, evidence, evidence->snp.report_len);
rats_attester_err_t err = sev_snp_get_vcek_der(report.chip_id, sizeof(report.chip_id),
&report.platform_version, snp_report);
if (err != RATS_ATTESTER_ERR_NONE) {
return err;
}

return RATS_ATTESTER_ERR_NONE;
}
1 change: 1 addition & 0 deletions include/librats/err.h
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ typedef enum {
RATS_ATTESTER_ERR_INVALID,
RATS_ATTESTER_ERR_CPU_UNSUPPORTED,
RATS_ATTESTER_ERR_NO_TOOL,
RATS_ATTESTER_ERR_CURL,
} rats_attester_err_t;

typedef enum {
Expand Down
4 changes: 4 additions & 0 deletions include/librats/evidence.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@
#ifndef _LIBRATS_EVIDENCE_H
#define _LIBRATS_EVIDENCE_H

#define VECK_MAX_SIZE 2*1024

typedef struct attestation_evidence attestation_evidence_t;

typedef struct attestation_verification_report {
Expand Down Expand Up @@ -38,6 +40,8 @@ typedef struct tdx_attestation_evidence {
typedef struct snp_attestation_evidence {
uint8_t report[8192];
uint32_t report_len;
uint8_t vcek[VECK_MAX_SIZE];
uint32_t vcek_len;
} snp_attestation_evidence_t;

typedef struct sev_attestation_evidence {
Expand Down
1 change: 0 additions & 1 deletion verifiers/sev-snp/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ set(INCLUDE_DIRS ${CMAKE_CURRENT_SOURCE_DIR}/../../include
${CMAKE_CURRENT_SOURCE_DIR}/../../include/librats
${CMAKE_CURRENT_SOURCE_DIR}/../../include/internal
${CMAKE_CURRENT_SOURCE_DIR}
/usr/include
)
include_directories(${INCLUDE_DIRS})

Expand Down
21 changes: 1 addition & 20 deletions verifiers/sev-snp/pre_init.c
Original file line number Diff line number Diff line change
Expand Up @@ -14,24 +14,5 @@ rats_verifier_err_t sev_snp_verifier_pre_init(void)
{
RATS_DEBUG("called\n");

rats_verifier_err_t err = RATS_VERIFIER_ERR_NONE;

/* These tools are used to verify SEV-SNP report */
char tools_name[TOOL_NUM][TOOL_NAME] = { "openssl", "wget", "csplit" };
char cmdline_str[50] = {
0,
};

for (int i = 0; i < TOOL_NUM; i++) {
int count = snprintf(cmdline_str, sizeof(cmdline_str),
"which %s 1> /dev/null 2> /dev/null", tools_name[i]);
cmdline_str[count] = '\0';

if (system(cmdline_str) != 0) {
RATS_ERR("please install tool %s\n", tools_name[i]);
err = -RATS_VERIFIER_ERR_NO_TOOL;
}
}

return err;
return RATS_VERIFIER_ERR_NONE;
}
10 changes: 0 additions & 10 deletions verifiers/sev-snp/utils.c
Original file line number Diff line number Diff line change
Expand Up @@ -11,16 +11,6 @@
#include <sys/stat.h>
#include "utils.h"

int get_file_size(char *name)
{
struct stat statbuf;

if (stat(name, &statbuf) == 0)
return statbuf.st_size;

return 0;
}

bool reverse_bytes(uint8_t *bytes, size_t size)
{
uint8_t *start = bytes;
Expand Down
15 changes: 0 additions & 15 deletions verifiers/sev-snp/utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,21 +10,6 @@
#include <stdbool.h>
#include <stdint.h>

/* Store the SEV-SNP certs downloaded from AMD KDS */
#define SEV_SNP_DEFAULT_DIR "/opt/sev-snp/"

#define KDS_CERT_SITE "https://kdsintf.amd.com"
#define KDS_CEK KDS_CERT_SITE "/cek/id/"
#define KDS_VCEK KDS_CERT_SITE "/vcek/v1/"

#define KDS_VCEK_CERT_CHAIN "cert_chain"
#define VCEK_CERT_CHAIN_PEM_FILENAME "cert_chain.pem"
#define VCEK_DER_FILENAME "vcek.der"
#define VCEK_PEM_FILENAME "vcek.pem"
#define VCEK_ASK_PEM_FILENAME "ask.pem"
#define VCEK_ARK_PEM_FILENAME "ark.pem"

int get_file_size(char *name);
bool reverse_bytes(uint8_t *bytes, size_t size);

#endif /* _UTILS_H */
Loading

0 comments on commit 989b8f0

Please sign in to comment.