linux-sgx: Improve the remote attestation (#1695)
The current implementation of remote attestation does not take into account the integrity of the wasm module. The SHA256 of the wasm module has been put into user_data to generate the quote, and more parameters are exposed for further verification.
This commit is contained in:
@ -4,9 +4,19 @@
|
||||
|
||||
set (LIB_RATS_DIR ${CMAKE_CURRENT_LIST_DIR})
|
||||
|
||||
if ("$ENV{SGX_SSL_DIR}" STREQUAL "")
|
||||
set (SGX_SSL_DIR "/opt/intel/sgxssl")
|
||||
else()
|
||||
set (SGX_SSL_DIR $ENV{SGX_SSL_DIR})
|
||||
endif()
|
||||
|
||||
if (NOT EXISTS ${SGX_SSL_DIR})
|
||||
message(FATAL_ERROR "Can not find SGX_SSL, please install it first")
|
||||
endif()
|
||||
|
||||
add_definitions (-DWASM_ENABLE_LIB_RATS=1)
|
||||
|
||||
include_directories(${LIB_RATS_DIR})
|
||||
include_directories(${LIB_RATS_DIR} ${SGX_SSL_DIR}/include)
|
||||
|
||||
include(FetchContent)
|
||||
|
||||
|
||||
31
core/iwasm/libraries/lib-rats/lib_rats_common.h
Normal file
31
core/iwasm/libraries/lib-rats/lib_rats_common.h
Normal file
@ -0,0 +1,31 @@
|
||||
/*
|
||||
* Copyright (c) 2022 Intel Corporation
|
||||
* Copyright (c) 2020-2021 Alibaba Cloud
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
*/
|
||||
|
||||
#ifndef _RATS_WAMR_COMMON_H
|
||||
#define _RATS_WAMR_COMMON_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
|
||||
#define SGX_QUOTE_MAX_SIZE 8192
|
||||
#define SGX_USER_DATA_SIZE 64
|
||||
#define SGX_MEASUREMENT_SIZE 32
|
||||
/* clang-format off */
|
||||
typedef struct rats_sgx_evidence {
|
||||
uint8_t quote[SGX_QUOTE_MAX_SIZE]; /* The quote of the Enclave */
|
||||
uint32_t quote_size; /* The size of the quote */
|
||||
uint8_t user_data[SGX_USER_DATA_SIZE]; /* The custom data in the quote */
|
||||
uint32_t product_id; /* Product ID of the Enclave */
|
||||
uint8_t mr_enclave[SGX_MEASUREMENT_SIZE]; /* The MRENCLAVE of the Enclave */
|
||||
uint32_t security_version; /* Security Version of the Enclave */
|
||||
uint8_t mr_signer[SGX_MEASUREMENT_SIZE]; /* The MRSIGNER of the Enclave */
|
||||
uint64_t att_flags; /* Flags of the Enclave in attributes */
|
||||
uint64_t att_xfrm; /* XSAVE Feature Request Mask */
|
||||
} rats_sgx_evidence_t;
|
||||
/* clang-format on */
|
||||
|
||||
#endif
|
||||
@ -8,48 +8,103 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <librats/api.h>
|
||||
#include <string.h>
|
||||
#include <openssl/sha.h>
|
||||
|
||||
#include "sgx_quote_3.h"
|
||||
#include "wasm_export.h"
|
||||
#include "bh_common.h"
|
||||
#include "lib_rats_common.h"
|
||||
|
||||
static uint32
|
||||
librats_collect_wrapper(wasm_exec_env_t exec_env, const uint8_t *hash)
|
||||
extern char wasm_module_hash[SHA256_DIGEST_LENGTH];
|
||||
|
||||
static int
|
||||
librats_collect_wrapper(wasm_exec_env_t exec_env, char **evidence_json,
|
||||
const char *buffer, uint32_t buffer_size)
|
||||
{
|
||||
char *json = NULL;
|
||||
char *str_ret;
|
||||
uint32 len;
|
||||
uint32 str_ret_offset = 0;
|
||||
wasm_module_inst_t module_inst = get_module_inst(exec_env);
|
||||
int code = librats_collect_evidence_to_json(hash, &json);
|
||||
if (code != 0) {
|
||||
return str_ret_offset;
|
||||
}
|
||||
if (json) {
|
||||
len = (uint32)strlen(json) + 1;
|
||||
|
||||
str_ret_offset = module_malloc(len, (void **)&str_ret);
|
||||
if (str_ret_offset) {
|
||||
bh_memcpy_s(str_ret, len, json, len);
|
||||
}
|
||||
char *json, *str_ret;
|
||||
uint32_t str_ret_offset;
|
||||
uint8_t final_hash[SHA256_DIGEST_LENGTH];
|
||||
|
||||
SHA256_CTX sha256;
|
||||
SHA256_Init(&sha256);
|
||||
SHA256_Update(&sha256, wasm_module_hash, SHA256_DIGEST_LENGTH);
|
||||
if (buffer != NULL)
|
||||
SHA256_Update(&sha256, buffer, buffer_size);
|
||||
SHA256_Final(final_hash, &sha256);
|
||||
|
||||
int ret_code = librats_collect_evidence_to_json(final_hash, &json);
|
||||
if (ret_code != 0) {
|
||||
return ret_code;
|
||||
}
|
||||
return str_ret_offset;
|
||||
|
||||
uint32_t json_size = strlen(json) + 1;
|
||||
str_ret_offset = module_malloc(json_size, (void **)&str_ret);
|
||||
if (!str_ret_offset) {
|
||||
free(json);
|
||||
return (int)RATS_ATTESTER_ERR_NO_MEM;
|
||||
}
|
||||
bh_memcpy_s(str_ret, json_size, json, json_size);
|
||||
*((int *)evidence_json) = str_ret_offset;
|
||||
free(json);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
librats_verify_wrapper(wasm_exec_env_t exec_env, const char *evidence_json,
|
||||
const uint8_t *hash)
|
||||
uint32_t evidence_size, const uint8_t *hash,
|
||||
uint32_t hash_size)
|
||||
{
|
||||
return librats_verify_evidence_from_json(evidence_json, hash);
|
||||
}
|
||||
|
||||
static int
|
||||
librats_parse_evidence_wrapper(wasm_exec_env_t exec_env,
|
||||
const char *evidence_json, uint32_t json_size,
|
||||
rats_sgx_evidence_t *evidence,
|
||||
uint32_t evidence_size)
|
||||
{
|
||||
attestation_evidence_t att_ev;
|
||||
|
||||
if (get_evidence_from_json(evidence_json, &att_ev) != 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Only supports parsing sgx evidence currently
|
||||
if (strcmp(att_ev.type, "sgx_ecdsa") != 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
sgx_quote3_t *quote_ptr = (sgx_quote3_t *)att_ev.ecdsa.quote;
|
||||
bh_memcpy_s(evidence->quote, att_ev.ecdsa.quote_len, att_ev.ecdsa.quote,
|
||||
att_ev.ecdsa.quote_len);
|
||||
evidence->quote_size = att_ev.ecdsa.quote_len;
|
||||
bh_memcpy_s(evidence->user_data, SGX_REPORT_DATA_SIZE,
|
||||
quote_ptr->report_body.report_data.d, SGX_REPORT_DATA_SIZE);
|
||||
bh_memcpy_s(evidence->mr_enclave, sizeof(sgx_measurement_t),
|
||||
quote_ptr->report_body.mr_enclave.m, sizeof(sgx_measurement_t));
|
||||
bh_memcpy_s(evidence->mr_signer, sizeof(sgx_measurement_t),
|
||||
quote_ptr->report_body.mr_signer.m, sizeof(sgx_measurement_t));
|
||||
evidence->product_id = quote_ptr->report_body.isv_prod_id;
|
||||
evidence->security_version = quote_ptr->report_body.isv_svn;
|
||||
evidence->att_flags = quote_ptr->report_body.attributes.flags;
|
||||
evidence->att_xfrm = quote_ptr->report_body.attributes.flags;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* clang-format off */
|
||||
#define REG_NATIVE_FUNC(func_name, signature) \
|
||||
{ #func_name, func_name##_wrapper, signature, NULL }
|
||||
/* clang-format on */
|
||||
|
||||
static NativeSymbol native_symbols_lib_rats[] = {
|
||||
REG_NATIVE_FUNC(librats_collect, "($)i"),
|
||||
REG_NATIVE_FUNC(librats_verify, "($$)i")
|
||||
REG_NATIVE_FUNC(librats_collect, "(**~)i"),
|
||||
REG_NATIVE_FUNC(librats_verify, "(*~*~)i"),
|
||||
REG_NATIVE_FUNC(librats_parse_evidence, "(*~*~)i")
|
||||
};
|
||||
|
||||
uint32_t
|
||||
|
||||
@ -9,10 +9,39 @@
|
||||
#define _RATS_WAMR_API_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include "lib_rats_common.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
char *
|
||||
librats_collect(const uint8_t *hash);
|
||||
int
|
||||
librats_verify(const char *json_string, const uint8_t *hash);
|
||||
librats_collect(char **evidence_json, const char *buffer, uint32_t buffer_size);
|
||||
|
||||
int
|
||||
librats_verify(const char *evidence_json, uint32_t evidence_size,
|
||||
const uint8_t *hash, uint32_t hash_size);
|
||||
|
||||
int
|
||||
librats_parse_evidence(const char *evidence_json, uint32_t json_size,
|
||||
rats_sgx_evidence_t *evidence, uint32_t evidence_size);
|
||||
|
||||
#define librats_collect(evidence_json, buffer) \
|
||||
librats_collect(evidence_json, buffer, buffer ? strlen(buffer) + 1 : 0)
|
||||
|
||||
#define librats_verify(evidence_json, hash) \
|
||||
librats_verify(evidence_json, \
|
||||
evidence_json ? strlen(evidence_json) + 1 : 0, hash, \
|
||||
hash ? strlen((const char *)hash) + 1 : 0)
|
||||
|
||||
#define librats_parse_evidence(evidence_json, evidence) \
|
||||
librats_parse_evidence(evidence_json, \
|
||||
evidence_json ? strlen(evidence_json) + 1 : 0, \
|
||||
evidence, sizeof(rats_sgx_evidence_t))
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user