210 lines
6.2 KiB
C++
210 lines
6.2 KiB
C++
#include <errno.h>
|
|
#include <fcntl.h>
|
|
#include <stdio.h>
|
|
#include <sys/ioctl.h>
|
|
#include <sys/stat.h>
|
|
#include <sys/types.h>
|
|
#include <termios.h>
|
|
#include <unistd.h>
|
|
|
|
#include <algorithm>
|
|
#include <cstring>
|
|
#include <string>
|
|
#include <vector>
|
|
|
|
#include "tee/common/log.h"
|
|
|
|
#include "tee/ra_ias.h"
|
|
#include "tee/ra_quote.h"
|
|
|
|
#include "cppcodec/base64_rfc4648.hpp"
|
|
#include "openssl/rand.h"
|
|
using base64 = cppcodec::base64_rfc4648;
|
|
|
|
#define SGXIOC_GET_EPID_GROUP_ID _IOR('s', 1, sgx_epid_group_id_t)
|
|
#define SGXIOC_GEN_QUOTE _IOWR('s', 2, EnclaveQuoteArgs)
|
|
|
|
constexpr char kSgxDeviceName[] = "/dev/sgx";
|
|
|
|
namespace ra {
|
|
namespace occlum {
|
|
|
|
TeeErrorCode RaEnclaveQuote::SgxDeviceInitQuote(sgx_epid_group_id_t* gid) {
|
|
int sgx_fd;
|
|
if ((sgx_fd = open(kSgxDeviceName, O_RDONLY)) < 0) {
|
|
TEE_LOG_ERROR("Fail to open %s", kSgxDeviceName);
|
|
return TEE_ERROR_FILE_OPEN;
|
|
}
|
|
|
|
TeeErrorCode ret = TEE_SUCCESS;
|
|
if (ioctl(sgx_fd, SGXIOC_GET_EPID_GROUP_ID, gid) < 0) {
|
|
TEE_LOG_ERROR("Fail to get group id from %s", kSgxDeviceName);
|
|
ret = TEE_ERROR_SDK_UNEXPECTED;
|
|
}
|
|
|
|
close(sgx_fd);
|
|
return ret;
|
|
}
|
|
|
|
TeeErrorCode RaEnclaveQuote::SgxDeviceGetQuote(EnclaveQuoteArgs* quote_args) {
|
|
if (!quote_args->quote.as_buf || (quote_args->quote_buf_len == 0)) {
|
|
TEE_LOG_ERROR("Invalid quote buffer or len");
|
|
return TEE_ERROR_PARAMETERS;
|
|
}
|
|
|
|
int sgx_fd;
|
|
if ((sgx_fd = open(kSgxDeviceName, O_RDONLY)) < 0) {
|
|
TEE_LOG_ERROR("Fail to open %s", kSgxDeviceName);
|
|
return TEE_ERROR_FILE_OPEN;
|
|
}
|
|
|
|
TeeErrorCode ret = TEE_SUCCESS;
|
|
int count = 3;
|
|
while (count--) {
|
|
if (ioctl(sgx_fd, SGXIOC_GEN_QUOTE, quote_args) == 0) {
|
|
uint32_t signature_len = quote_args->quote.as_quote->signature_len;
|
|
TEE_LOG_DEBUG("SgxDeviceGetQuote length=%ld", signature_len);
|
|
if (signature_len == 0) {
|
|
TEE_LOG_ERROR("Invalid quote from %s", kSgxDeviceName);
|
|
ret = TEE_ERROR_SDK_UNEXPECTED;
|
|
}
|
|
break;
|
|
} else if (errno != EAGAIN) {
|
|
TEE_LOG_ERROR("Fail to get quote from %s", kSgxDeviceName);
|
|
ret = TEE_ERROR_SDK_UNEXPECTED;
|
|
break;
|
|
} else {
|
|
TEE_LOG_WARN("/dev/sgx is temporarily busy. Try again after 1s.");
|
|
sleep(1);
|
|
}
|
|
}
|
|
|
|
close(sgx_fd);
|
|
return ret;
|
|
}
|
|
|
|
uint8_t RaEnclaveQuote::Hex2Dec(const char hex) {
|
|
if (('0' <= hex) && (hex <= '9')) {
|
|
return hex - '0';
|
|
} else if (('a' <= hex) && (hex <= 'f')) {
|
|
return hex - 'a' + 10;
|
|
} else if (('A' <= hex) && (hex <= 'F')) {
|
|
return hex - 'A' + 10;
|
|
} else {
|
|
// Otherwise return zero for none HEX charactor
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
TeeErrorCode RaEnclaveQuote::GetSpidFromHexStr(const std::string& spid_str) {
|
|
const char* src = spid_str.data();
|
|
const int len = sizeof(sgx_spid_t);
|
|
uint8_t* dst = RCAST(uint8_t*, quote_args_.spid.id);
|
|
|
|
if ((spid_str.empty()) || ((len * 2) != spid_str.length())) {
|
|
TEE_LOG_ERROR("Empty SPID or Invalid SPID hexstring length!\n");
|
|
return TEE_ERROR_PARAMETERS;
|
|
}
|
|
|
|
for (int i = 0; i < len; i++) {
|
|
dst[i] =
|
|
(Hex2Dec(src[i * 2] & 0xFF) << 4) + (Hex2Dec(src[i * 2 + 1] & 0xFF));
|
|
}
|
|
return TEE_SUCCESS;
|
|
}
|
|
|
|
TeeErrorCode RaEnclaveQuote::GetIasSigRL(const RaIasServerCfg& ias_server) {
|
|
// Initialize the quote firstly
|
|
sgx_epid_group_id_t gid = {0};
|
|
TEE_CHECK_RETURN(SgxDeviceInitQuote(&gid));
|
|
|
|
// Try to Get the IAS SigRL, do nothing if failed
|
|
RaIasClient ias_client(ias_server);
|
|
std::string sigrl_str;
|
|
TEE_CHECK_RETURN(ias_client.GetSigRL(gid, &sigrl_str));
|
|
|
|
// If there is valid SigRL
|
|
if (!sigrl_str.empty()) {
|
|
TEE_LOG_DEBUG("Set the SigRL, length=%ld", sigrl_str.size());
|
|
quote_args_.sigrl_ptr = RCAST(const uint8_t*, sigrl_str.data());
|
|
quote_args_.sigrl_len = sigrl_str.size();
|
|
}
|
|
return TEE_SUCCESS;
|
|
}
|
|
|
|
TeeErrorCode RaEnclaveQuote::GetEnclaveQuote(
|
|
const RaIasServerCfg& ias_server, const std::string& spid,
|
|
const sgx_report_data_t& report_data) {
|
|
// Firstly, eset all the data
|
|
constexpr int kMaxQuoteLen = 4096;
|
|
quote_buf_.resize(kMaxQuoteLen, 0);
|
|
memset(RCAST(void*, "e_args_), 0, sizeof(EnclaveQuoteArgs));
|
|
|
|
// Initialize the arguments
|
|
quote_args_.quote.as_buf = quote_buf_.data();
|
|
quote_args_.quote_buf_len = quote_buf_.size();
|
|
quote_args_.quote_type = SGX_LINKABLE_SIGNATURE;
|
|
std::memcpy(RCAST(void*, quote_args_.report_data.d),
|
|
RCAST(const void*, report_data.d), sizeof(sgx_report_data_t));
|
|
RAND_bytes(quote_args_.nonce.rand, sizeof(sgx_quote_nonce_t));
|
|
TEE_CHECK_RETURN(GetSpidFromHexStr(spid));
|
|
TEE_CHECK_RETURN(GetIasSigRL(ias_server));
|
|
|
|
// Finally, get quote via ioctl device
|
|
TEE_CHECK_RETURN(SgxDeviceGetQuote("e_args_));
|
|
|
|
return TEE_SUCCESS;
|
|
}
|
|
|
|
TeeErrorCode RaEnclaveQuote::GetEnclaveQuoteB64(
|
|
const RaIasServerCfg& ias_server, const std::string& spid,
|
|
const sgx_report_data_t& report_data, std::string* quote_b64) {
|
|
// Get the enclave quote
|
|
TEE_CHECK_RETURN(GetEnclaveQuote(ias_server, spid, report_data));
|
|
|
|
// Convert the quote data to base64 format
|
|
char* quote_ptr = RCAST(char*, quote_args_.quote.as_quote);
|
|
size_t quote_len =
|
|
sizeof(sgx_quote_t) + quote_args_.quote.as_quote->signature_len;
|
|
std::string tmp_quote_b64 = base64::encode(quote_ptr, quote_len);
|
|
quote_b64->assign(tmp_quote_b64);
|
|
TEE_LOG_DEBUG("QuoteB64[%lu]: %s", quote_b64->length(), quote_b64->c_str());
|
|
|
|
return TEE_SUCCESS;
|
|
}
|
|
|
|
TeeErrorCode RaEnclaveQuote::GetEnclaveIasReport(
|
|
const RaIasServerCfg& ias_server, const std::string& spid,
|
|
const sgx_report_data_t& report_data, RaIasReport* ias_report) {
|
|
// Get the enclave quote
|
|
TEE_CHECK_RETURN(GetEnclaveQuote(ias_server, spid, report_data));
|
|
|
|
// Convert the quote data to a new string for calling IAS client method
|
|
ra::occlum::RaIasClient ias_client(ias_server);
|
|
size_t quote_len =
|
|
sizeof(sgx_quote_t) + quote_args_.quote.as_quote->signature_len;
|
|
std::string quote_str(RCAST(char*, quote_args_.quote.as_quote), quote_len);
|
|
TEE_CHECK_RETURN(ias_client.FetchReport(quote_str, ias_report));
|
|
|
|
return TEE_SUCCESS;
|
|
}
|
|
|
|
} // namespace occlum
|
|
} // namespace ra
|
|
|
|
#ifdef __cplusplus
|
|
extern "C" {
|
|
#endif
|
|
|
|
TeeErrorCode InitializeQuote(sgx_epid_group_id_t* gid) {
|
|
return ra::occlum::RaEnclaveQuote::SgxDeviceInitQuote(gid);
|
|
}
|
|
|
|
TeeErrorCode GetQuote(EnclaveQuoteArgs* quote_args) {
|
|
return ra::occlum::RaEnclaveQuote::SgxDeviceGetQuote(quote_args);
|
|
}
|
|
|
|
#ifdef __cplusplus
|
|
}
|
|
#endif
|