ENT-1263 - Use MRENCLAVE instead of enclave ID in create_thread (#487)

* ENT-1263 - Use MRENCLAVE instead of enclave_id for create_thread

* ENT-1263 - Dedup dependencies in JAR

* ENT-1263 - Ensure C++ 11 is used for enclave inspection tool

* ENT-1263 - Throw exception if enclave ID mapping does not exist
This commit is contained in:
Tommy Lillehagen 2018-04-24 17:11:33 +01:00 committed by GitHub
parent e3c792c93d
commit 25bee1903a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
20 changed files with 13364 additions and 15 deletions

2
sgx-jvm/jvm-enclave/.gitignore vendored Normal file
View File

@ -0,0 +1,2 @@
test/tests
tools/enclave-inspector

View File

@ -30,7 +30,7 @@ add_custom_target(
DEPENDS ${GENERATED_EDL_FILES}
)
set(SOURCE_FILES sgx_utilities.cpp untrusted_start_thread.cpp untrusted_debug_print.cpp ${GENERATED_RPC_DIR}/java_u.c)
set(SOURCE_FILES sgx_utilities.cpp untrusted_start_thread.cpp untrusted_debug_print.cpp enclave_map.cpp enclave_metadata.cpp ${GENERATED_RPC_DIR}/java_u.c)
add_library(common OBJECT ${SOURCE_FILES})
set_property(TARGET common PROPERTY POSITION_INDEPENDENT_CODE ON)
target_include_directories(common PUBLIC ${SGX_SDK_INCLUDE} ${GENERATED_RPC_DIR})

View File

@ -0,0 +1,58 @@
#ifndef __ELF_TYPES_H__
#define __ELF_TYPES_H__
typedef uint64_t Elf64_Addr;
typedef uint16_t Elf64_Quarter;
typedef uint32_t Elf64_Half;
typedef uint64_t Elf64_Off;
typedef uint32_t Elf64_Word;
typedef uint64_t Elf64_Xword;
#define ELFMAG0 0x7f // e_ident[EI_MAG0]
#define ELFMAG1 'E' // e_ident[EI_MAG1]
#define ELFMAG2 'L' // e_ident[EI_MAG2]
#define ELFMAG3 'F' // e_ident[EI_MAG3]
#define EI_NIDENT 16 // Size of e_ident array
#define EI_CLASS 4 // Class of machine
#define ELFCLASSNONE 0 // Unknown class
#define ELFCLASS32 1 // 32-bit architecture
#define ELFCLASS64 2 // 64-bit architecture
typedef struct {
unsigned char e_ident[EI_NIDENT]; // File identification
Elf64_Quarter e_type; // File type
Elf64_Quarter e_machine; // Machine architecture
Elf64_Word e_version; // ELF format version
Elf64_Addr e_entry; // Entry point
Elf64_Off e_phoff; // Program header file offset
Elf64_Off e_shoff; // Section header file offset
Elf64_Word e_flags; // Architecture-specific flags
Elf64_Quarter e_ehsize; // Size of ELF header in bytes
Elf64_Quarter e_phentsize; // Size of program header entry
Elf64_Quarter e_phnum; // Number of program header entries
Elf64_Quarter e_shentsize; // Size of section header entry
Elf64_Quarter e_shnum; // Number of section header entries
Elf64_Quarter e_shstrndx; // Section name strings section
} Elf64_Ehdr;
typedef struct {
Elf64_Word sh_name; // Section name (index into section header string table)
Elf64_Word sh_type; // Section type
Elf64_Xword sh_flags; // Section flags
Elf64_Addr sh_addr; // Address in memory image
Elf64_Off sh_offset; // Offset in file
Elf64_Xword sh_size; // Size in bytes
Elf64_Word sh_link; // Index of a related section
Elf64_Word sh_info; // Depends on section type
Elf64_Xword sh_addralign; // Alignment in bytes
Elf64_Xword sh_entsize; // Size of each entry in section
} Elf64_Shdr;
typedef struct {
Elf64_Half namesz; // Length of note name string
Elf64_Half descsz; // Length of note description string
Elf64_Half type; // Note type
} Elf64_Note;
#endif /* __ELF_TYPES_H__ */

View File

@ -0,0 +1,21 @@
#include <cstring>
#include <stdexcept>
#include "enclave_map.h"
static enclave_map_t map;
void add_enclave_mapping(sgx_measurement_t *mr_enclave, sgx_enclave_id_t enclave_id) {
// Note: The size of the enclave map is proportional to the number of unique
// enclaves a system is dealing with. For the time being we don't envision this
// number to be very big. Longer term, we might want to implement some form of
// pruning to avoid old entries taking up unnecessary memory space.
map[mr_enclave] = enclave_id;
}
sgx_enclave_id_t get_enclave_id(sgx_measurement_t *mr_enclave) {
auto result = map.find(mr_enclave);
if (result == map.end()) {
throw std::invalid_argument("no enclave ID associated with enclave measurement");
}
return result->second;
}

View File

@ -0,0 +1,21 @@
#ifndef __ENCLAVE_MAP_H__
#define __ENCLAVE_MAP_H__
#include <functional>
#include <map>
#include <sgx_eid.h>
#include <sgx_report.h>
struct enclave_hash_comparer : public std::binary_function<const sgx_measurement_t*, const sgx_measurement_t*, bool> {
public:
bool operator() (const sgx_measurement_t* a, const sgx_measurement_t* b) const
{ return memcmp(a->m, b->m, 32) < 0; }
};
class enclave_map_t : public std::map<sgx_measurement_t*, sgx_enclave_id_t, enclave_hash_comparer> { };
void add_enclave_mapping(sgx_measurement_t *mr_enclave, sgx_enclave_id_t enclave_id);
sgx_enclave_id_t get_enclave_id(sgx_measurement_t *mr_enclave);
#endif /* __ENCLAVE_MAP_H__ */

View File

@ -0,0 +1,127 @@
#include <iostream>
#include <cstddef>
#include <cstring>
#include "enclave_metadata.h"
#include "elf_types.h"
#include "sgx_types.h"
static enclave_hash_result_t read_header(FILE *fp, Elf64_Ehdr *header) {
if (0 != fseek(fp, 0, SEEK_SET)) {
return EHR_ERROR_READ_FILE;
}
size_t read = fread(header, sizeof(Elf64_Ehdr), 1, fp);
if (0 == read) {
return EHR_ERROR_READ_ELF_HEADER;
}
if (header->e_ident[0] != ELFMAG0
|| header->e_ident[1] != ELFMAG1
|| header->e_ident[2] != ELFMAG2
|| header->e_ident[3] != ELFMAG3) {
return EHR_ERROR_NOT_ELF_FORMAT;
}
if (header->e_ident[EI_CLASS] != ELFCLASS64) {
return EHR_ERROR_NOT_ELF64_FORMAT;
}
return EHR_SUCCESS;
}
static enclave_hash_result_t find_section(FILE *fp, Elf64_Ehdr *header, const char *name, Elf64_Shdr *metadata_section) {
fseek(fp, header->e_shoff, SEEK_SET);
Elf64_Shdr *sections = static_cast<Elf64_Shdr*>(calloc(header->e_shnum, sizeof(Elf64_Shdr)));
if (NULL == sections) {
return EHR_ERROR_OUT_OF_MEMORY;
}
if (header->e_shnum != fread(sections, sizeof(Elf64_Shdr), header->e_shnum, fp)) {
free(sections);
return EHR_ERROR_READ_SECTION_HEADERS;
}
Elf64_Shdr *name_section = &sections[header->e_shstrndx];
for (int i = 1; i < header->e_shnum; i++) { // Skip index 0, always empty
char name[16];
fseek(fp, name_section->sh_offset + sections[i].sh_name, SEEK_SET);
fread(name, 1, 16, fp);
if (0 == strncmp(name, ".note.sgxmeta", 16)) {
memcpy(metadata_section, &sections[i], sizeof(Elf64_Shdr));
free(sections);
return EHR_SUCCESS;
}
}
free(sections);
return EHR_ERROR_NO_SGX_META_DATA_SECTION;
}
enclave_hash_result_t retrieve_enclave_hash(const char *path, uint8_t *enclave_hash) {
FILE *fp = fopen(path, "rb");
if (!fp) {
return EHR_ERROR_READ_FILE;
}
Elf64_Ehdr header;
enclave_hash_result_t read_header_result = read_header(fp, &header);
if (EHR_SUCCESS != read_header_result) {
fclose(fp);
return read_header_result;
}
Elf64_Shdr section;
enclave_hash_result_t find_section_result = find_section(fp, &header, ".note.sgxmeta", &section);
if (EHR_SUCCESS != find_section_result) {
fclose(fp);
return find_section_result;
}
size_t metadata_offset = section.sh_offset;
size_t metadata_align = section.sh_addralign;
Elf64_Note note;
fseek(fp, section.sh_offset, SEEK_SET);
fread(&note, sizeof(Elf64_Note), 1, fp);
if (section.sh_size != ROUND_TO(sizeof(Elf64_Note) + note.namesz + note.descsz, section.sh_addralign)) {
fclose(fp);
return EHR_ERROR_INVALID_SECTION_SIZE;
}
const char *meta_name = "sgx_metadata";
const size_t meta_name_len = strlen(meta_name);
char meta_name_buffer[16] = { 0 };
fseek(fp, section.sh_offset + sizeof(Elf64_Note), SEEK_SET);
fread(meta_name_buffer, 1, 16, fp);
if (meta_name_len + 1 != note.namesz || 0 != strncmp(meta_name, meta_name_buffer, meta_name_len)) {
fclose(fp);
return EHR_ERROR_INVALID_SECTION_NAME;
}
size_t meta_data_offset = section.sh_offset + sizeof(Elf64_Note) + note.namesz;
metadata_t *metadata = static_cast<metadata_t*>(malloc(sizeof(metadata_t)));
if (NULL == metadata) {
fclose(fp);
return EHR_ERROR_OUT_OF_MEMORY;
}
fseek(fp, meta_data_offset, SEEK_SET);
if (1 != fread(metadata, sizeof(metadata_t), 1, fp)) {
free(metadata);
fclose(fp);
return EHR_ERROR_READ_META_DATA;
}
if (NULL != enclave_hash) {
memcpy(enclave_hash, metadata->enclave_css.body.enclave_hash, MRE_SIZE);
}
free(metadata);
fclose(fp);
return EHR_SUCCESS;
}

View File

@ -0,0 +1,20 @@
#ifndef __ENCLAVE_METADATA_H__
#define __ENCLAVE_METADATA_H__
typedef enum _enclave_hash_result_t {
EHR_SUCCESS, // The hash of the enclave was retrieved successfully
EHR_ERROR_READ_FILE, // Unable to read the file
EHR_ERROR_READ_ELF_HEADER, // Unable to read the file header
EHR_ERROR_NOT_ELF_FORMAT, // The file is not an ELF file
EHR_ERROR_NOT_ELF64_FORMAT, // The file is an ELF file, but only 64-bit ELF files are supported
EHR_ERROR_OUT_OF_MEMORY, // Unable to allocate memory
EHR_ERROR_READ_SECTION_HEADERS, // Unable to read section headers from file
EHR_ERROR_NO_SGX_META_DATA_SECTION, // Unable to find note section named ".note.sgxmeta"
EHR_ERROR_INVALID_SECTION_NAME, // Invalid name of note section
EHR_ERROR_INVALID_SECTION_SIZE, // Invalid size of note section
EHR_ERROR_READ_META_DATA, // Unable to read meta data from file
} enclave_hash_result_t;
extern "C" enclave_hash_result_t retrieve_enclave_hash(const char *path, uint8_t *enclave_hash);
#endif /* __ENCLAVE_METADATA_H__ */

View File

@ -1,9 +1,10 @@
enclave {
from "sgx_tstdc.edl" import *;
include "sgx_report.h"
trusted {
public void create_new_thread(unsigned int nonce);
};
untrusted {
void request_new_thread(uint64_t enclave_id, uint32_t nonce);
void request_new_thread(sgx_measurement_t mr_enclave, uint32_t nonce);
};
};

View File

@ -0,0 +1,81 @@
#ifndef __SGX_TYPES_H__
#define __SGX_TYPES_H__
#pragma pack(push, 1)
#define ROUND_TO(x, align) \
(((x) + ((align)-1)) & ~((align)-1))
#define MRE_SIZE 32 // Size of MRENCLAVE (in bytes)
#define SE_KEY_SIZE 384 // Size of keys (in bytes)
#define SE_EXP_SIZE 4 // RSA public key exponent size in bytes
typedef struct {
uint64_t flags;
uint64_t xfrm;
} sgx_attributes_t;
typedef uint32_t sgx_misc_select_t;
typedef struct {
sgx_attributes_t secs_attr;
sgx_misc_select_t misc_select;
} sgx_misc_attribute_t;
typedef struct { // 128 bytes
uint8_t header[12]; // (0) must be (06000000E100000000000100H)
uint32_t type; // (12) bit 31: 0 = prod, 1 = debug; Bit 30-0: Must be zero
uint32_t module_vendor; // (16) Intel=0x8086, ISV=0x0000
uint32_t date; // (20) build date as yyyymmdd
uint8_t header2[16]; // (24) must be (01010000600000006000000001000000H)
uint32_t hw_version; // (40) For Launch Enclaves: HWVERSION != 0. Others, HWVERSION = 0
uint8_t reserved[84]; // (44) Must be 0
} css_header_t;
typedef struct { // 772 bytes
uint8_t modulus[SE_KEY_SIZE]; // (128) Module Public Key (keylength=3072 bits)
uint8_t exponent[SE_EXP_SIZE]; // (512) RSA Exponent = 3
uint8_t signature[SE_KEY_SIZE]; // (516) Signature over Header and Body
} css_key_t;
typedef struct { // 128 bytes
sgx_misc_select_t misc_select; // (900) The MISCSELECT that must be set
sgx_misc_select_t misc_mask; // (904) Mask of MISCSELECT to enforce
uint8_t reserved[20]; // (908) Reserved. Must be 0.
sgx_attributes_t attributes; // (928) Enclave Attributes that must be set
sgx_attributes_t attribute_mask; // (944) Mask of Attributes to Enforce
uint8_t enclave_hash[MRE_SIZE]; // (960) MRENCLAVE - (32 bytes)
uint8_t reserved2[32]; // (992) Must be 0
uint16_t isv_prod_id; // (1024) ISV assigned Product ID
uint16_t isv_svn; // (1026) ISV assigned SVN
} css_body_t;
typedef struct { // 780 bytes
uint8_t reserved[12]; // (1028) Must be 0
uint8_t q1[SE_KEY_SIZE]; // (1040) Q1 value for RSA Signature Verification
uint8_t q2[SE_KEY_SIZE]; // (1424) Q2 value for RSA Signature Verification
} css_buffer_t;
typedef struct { // 1808 bytes
css_header_t header; // (0)
css_key_t key; // (128)
css_body_t body; // (900)
css_buffer_t buffer; // (1028)
} enclave_css_t;
typedef struct {
uint64_t magic_num; // The magic number identifying the file as a signed enclave image
uint64_t version; // The metadata version
uint32_t size; // The size of this structure
uint32_t tcs_policy; // TCS management policy
uint32_t ssa_frame_size; // The size of SSA frame in page
uint32_t max_save_buffer_size; // Max buffer size is 2632
uint32_t desired_misc_select;
uint32_t tcs_min_pool; // TCS min pool*/
uint64_t enclave_size; // enclave virtual size
sgx_attributes_t attributes; // XFeatureMask to be set in SECS.
enclave_css_t enclave_css; // The enclave signature
} metadata_t;
#endif /* __SGX_TYPES_H__ */

View File

@ -2,20 +2,22 @@
#include <pthread.h>
#include "java_u.h"
#include "sgx_utilities.h"
#include "enclave_map.h"
extern "C" {
struct new_thread_data {
sgx_enclave_id_t enclave_id;
sgx_measurement_t mr_enclave;
unsigned int nonce;
};
void *create_new_enclave_thread(void *param) {
auto thread_data = (new_thread_data*) param;
CHECK_SGX(create_new_thread(thread_data->enclave_id, thread_data->nonce));
sgx_enclave_id_t enclave_id = get_enclave_id(&thread_data->mr_enclave);
CHECK_SGX(create_new_thread(enclave_id, thread_data->nonce));
delete thread_data;
}
void request_new_thread(sgx_enclave_id_t enclave_id, unsigned int nonce) {
void request_new_thread(sgx_measurement_t mr_enclave, unsigned int nonce) {
pthread_t enclave_thread;
new_thread_data *thread_data = new new_thread_data { enclave_id, nonce };
new_thread_data *thread_data = new new_thread_data { mr_enclave, nonce };
int ret = pthread_create(&enclave_thread, NULL, create_new_enclave_thread, (void *)thread_data);
assert(!ret);
}

View File

@ -2,6 +2,7 @@
#include <sgx_thread_mutex_guard.h>
#include <sgx_thread_completion.h>
#include <sgx_trts.h>
#include <sgx_utils.h>
#include <java_t.h>
#include "aex_assert.h"
@ -28,7 +29,21 @@ struct ThreadMutexInit {
};
static ThreadMutexInit _thread_mutex_init;
static sgx_status_t get_mr_enclave(sgx_measurement_t *mr_enclave) {
sgx_report_t report;
sgx_status_t ret = sgx_create_report(NULL, NULL, &report);
if (ret == SGX_SUCCESS) {
memcpy(mr_enclave, &report.body.mr_enclave, sizeof(sgx_measurement_t));
}
return ret;
}
thread_data_t *start_thread(void (*routine)(void *), void *param, sgx_thread_completion *thread_completed) {
sgx_measurement_t mr_enclave = { 0 };
if (SGX_SUCCESS != get_mr_enclave(&mr_enclave)) {
return NULL;
}
nonce_t nonce;
aex_assert(SGX_SUCCESS == sgx_read_rand((unsigned char*)&nonce, sizeof(nonce)));
sgx_thread_cond_t thread_started;
@ -47,11 +62,7 @@ thread_data_t *start_thread(void (*routine)(void *), void *param, sgx_thread_com
aex_assert(new_thread_map.find(nonce) == new_thread_map.end());
new_thread_map[nonce] = thread_init_data;
}
// TODO use MRENCLAVE instead of enclave_id (this is currently not used)
uint64_t enclave_id = 0L;
request_new_thread(enclave_id, nonce);
request_new_thread(mr_enclave, nonce);
sgx_thread_cond_wait(&thread_started, &thread_started_mutex);
sgx_thread_mutex_guard started_thread_data_map_guard(&started_thread_data_map_mutex);
auto thread_data_iter = started_thread_data_map.find(nonce);

View File

@ -2,6 +2,8 @@
#include "java_u.h"
#include "sgx_utilities.h"
#include "enclave_map.h"
#include "enclave_metadata.h"
#include <sgx_urts.h>
extern "C" {
@ -14,7 +16,14 @@ JNIEXPORT jstring JNICALL Java_com_r3_enclaves_txverify_NativeSgxApi_verify(JNIE
const char *enclave_path_sz = env->GetStringUTFChars(enclave_path, NULL);
jbyte *transaction_bytes = env->GetByteArrayElements(transaction, NULL);
sgx_measurement_t mr_enclave;
enclave_hash_result_t hash_result = retrieve_enclave_hash(enclave_path_sz, mr_enclave.m);
if (EHR_SUCCESS != hash_result) {
return NULL;
}
CHECK_SGX(sgx_create_enclave(enclave_path_sz, SGX_DEBUG_FLAG, &token, &updated, &enclave_id, NULL));
add_enclave_mapping(&mr_enclave, enclave_id);
char error[1024] = {0};
printf("Array length %d\n", env->GetArrayLength(transaction));

View File

@ -4,13 +4,25 @@
#include <fstream>
#include "sgx_utilities.h"
#include "java_u.h"
#include "enclave_map.h"
#include "enclave_metadata.h"
static sgx_measurement_t mr_enclave;
int main(int argc, char **argv) {
sgx_launch_token_t token = {0};
sgx_enclave_id_t enclave_id = {0};
int updated = 0;
CHECK_SGX(sgx_create_enclave("../../enclave/build/cordaenclave.signed.so", SGX_DEBUG_FLAG, &token, &updated, &enclave_id, NULL));
const char *enclave_path = "../../enclave/build/cordaenclave.signed.so";
enclave_hash_result_t hash_result = retrieve_enclave_hash(enclave_path, mr_enclave.m);
if (EHR_SUCCESS != hash_result) {
printf("Unable to retrieve MRENCLAVE from enclave\n");
exit(1);
}
CHECK_SGX(sgx_create_enclave(enclave_path, SGX_DEBUG_FLAG, &token, &updated, &enclave_id, NULL));
add_enclave_mapping(&mr_enclave, enclave_id);
if (argc < 2) {
printf("Usage: <executable> /path/to/req/file\n");

View File

@ -0,0 +1,18 @@
.PHONY: all test clean
LIBDIR = ../common
SDKDIR = ../../linux-sgx/common/inc
SOURCE = tests.cpp ${LIBDIR}/enclave_map.cpp
HEADERS = ${LIBDIR}/enclave_map.h ${LIBDIR}/elf_types.h ${LIBDIR}/sgx_types.h
RESULT = tests
all: ${RESULT}
${RESULT}: ${SOURCE} ${HEADERS}
g++ -std=c++11 -o $@ -I${LIBDIR} -I${SDKDIR} ${SOURCE}
test: ${RESULT}
./${RESULT}
clean:
@rm -f ${RESULT}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,103 @@
#define CATCH_CONFIG_MAIN
#include "catch.hpp"
#include "enclave_map.h"
SCENARIO(
"enclave identifiers can be looked up based on enclaves' measurements",
"[enclave-map]"
) {
GIVEN( "an empty map" ) {
enclave_map_t map;
REQUIRE( map.size() == 0 );
WHEN( "a new entry gets added" ) {
sgx_measurement_t mr_enclave = { 0 };
sgx_enclave_id_t enclave_id = 1L;
map[&mr_enclave] = enclave_id;
THEN( "the size of the map increases" ) {
REQUIRE( map.size() == 1 );
}
THEN( "the mapping can be found" ) {
auto result = map.find(&mr_enclave);
REQUIRE( result != map.end() );
}
THEN( "the mapping returns the correct value" ) {
auto result = map.find(&mr_enclave);
REQUIRE( result->second == 1L );
}
THEN( "a non-existent mapping cannot be looked up" ) {
sgx_measurement_t non_existent_mr_enclave = { 1 };
auto result = map.find(&non_existent_mr_enclave);
REQUIRE( result == map.end() );
}
}
}
GIVEN( "a populated map" ) {
enclave_map_t map;
sgx_measurement_t mr_enclave_orig = { 0 };
sgx_enclave_id_t enclave_id = 1L;
map[&mr_enclave_orig] = enclave_id;
REQUIRE( map.size() == 1 );
WHEN( "a new entry gets added" ) {
sgx_measurement_t mr_enclave = { 1 };
sgx_enclave_id_t enclave_id = 2L;
map[&mr_enclave] = enclave_id;
THEN( "the size of the map increases" ) {
REQUIRE( map.size() == 2 );
}
THEN( "the mapping can be found" ) {
auto result = map.find(&mr_enclave);
REQUIRE( result != map.end() );
}
THEN( "the mapping returns the correct value" ) {
auto result = map.find(&mr_enclave);
REQUIRE( result->second == 2L );
}
THEN( "the value for the pre-existing entry is correct" ) {
auto result = map.find(&mr_enclave_orig);
REQUIRE( result->second == 1L );
}
THEN( "a non-existent mapping cannot be looked up" ) {
sgx_measurement_t non_existent_mr_enclave = { 2 };
auto result = map.find(&non_existent_mr_enclave);
REQUIRE( result == map.end() );
}
}
WHEN( "a existing entry gets overwritten" ) {
sgx_measurement_t mr_enclave = { 0 };
sgx_enclave_id_t enclave_id = 2L;
map[&mr_enclave] = enclave_id;
THEN( "the size of the map stays the same" ) {
REQUIRE( map.size() == 1 );
}
THEN( "the mapping can be found" ) {
auto result = map.find(&mr_enclave);
REQUIRE( result != map.end() );
}
THEN( "the mapping returns the correct value" ) {
auto result = map.find(&mr_enclave);
REQUIRE( result->second == 2L );
}
}
}
}

View File

@ -0,0 +1,14 @@
.PHONY: all clean
LIBDIR = ../common
SOURCE = enclave-inspector.cpp ${LIBDIR}/enclave_metadata.cpp
HEADERS = ${LIBDIR}/enclave_metadata.h ${LIBDIR}/elf_types.h ${LIBDIR}/sgx_types.h
RESULT = enclave-inspector
all: ${RESULT}
${RESULT}: ${SOURCE} ${HEADERS}
g++ -std=c++11 -o $@ ${SOURCE}
clean:
@rm -f ${RESULT}

View File

@ -0,0 +1,48 @@
#include <iostream>
#include <iomanip>
#include <cstddef>
#include "../common/enclave_metadata.h"
using namespace std;
static const char *status_messages[] = {
"Success",
"Unable to read the file",
"Unable to read the file header",
"The file is not an ELF file",
"The file is an ELF file, but only 64-bit ELF files are supported",
"Unable to allocate memory",
"Unable to read section headers from file",
"Unable to find note section named \".note.sgxmeta\"",
"Invalid name of note section",
"Invalid size of note section",
"Unable to read meta data from file",
};
static void print_hex(uint8_t *buffer, size_t len) {
for (int i = 0; i < len; i++) {
cout << setfill('0') << setw(2) << setbase(16) << static_cast<int>(buffer[i]) << " ";
}
cout << endl;
}
int main(int argc, char *argv[]) {
if (argc != 2) {
cout << "SGX Enclave Inspector" << endl;
cout << "Usage: " << argv[0] << " <enclave-object>" << endl;
return 1;
}
uint8_t enclave_hash[32] = { 0 };
enclave_hash_result_t result = retrieve_enclave_hash(argv[1], enclave_hash);
cout << "Outcome: " << status_messages[result] << endl;
if (EHR_SUCCESS == result) {
cout << " Path = " << argv[1] << endl;
cout << " Hash = ";
print_hex(enclave_hash, 32);
}
return 0;
}

View File

@ -57,6 +57,11 @@ dependencies {
}
jar {
// De-duplicate dependencies - otherwise, they will appear multiple times in the resulting JAR file, which in turn
// will confuse ProGuard in the processing step in sgx-jvm/jvm-enclave.
duplicatesStrategy = DuplicatesStrategy.EXCLUDE
from '../node/capsule/NOTICE' // Copy CDDL notice
// Create a fat jar by packing all deps into the output
from {