Skip to content

Commit

Permalink
Added command in oesign to dump oeinfo and signature information #564
Browse files Browse the repository at this point in the history
  • Loading branch information
berinpaul committed Oct 17, 2018
1 parent 49cfd0b commit 7b58cec
Show file tree
Hide file tree
Showing 3 changed files with 278 additions and 5 deletions.
2 changes: 1 addition & 1 deletion tools/oesign/CMakeLists.txt
@@ -1,7 +1,7 @@
# Copyright (c) Microsoft Corporation. All rights reserved.
# Licensed under the MIT License.

add_executable(oesign main.c)
add_executable(oesign main.c oedump.c)

target_link_libraries(oesign oehost)

Expand Down
32 changes: 28 additions & 4 deletions tools/oesign/main.c
Expand Up @@ -13,6 +13,7 @@
#include "../host/enclave.h"

static const char* arg0;
void oedump(const char*, const char*, const char*);

OE_PRINTF_FORMAT(1, 2)
void Err(const char* format, ...)
Expand Down Expand Up @@ -523,7 +524,17 @@ static const char _usage[] =
" -----BEGIN RSA PRIVATE KEY-----\n"
"\n"
" The resulting image is written to <EnclaveImage>.signed.so.\n"
"\n";
"\n"
" ---- OR-----\n"
"\n"
"Usage: %s EnclaveImage --oedump\n"
"\n"
"Where:\n"
" EnclaveImage -- path of an enclave image file\n"
"\n"
"Description:\n"
" This option dumps the oeinfo and signature information of an "
"enclave\n";

int main(int argc, const char* argv[])
{
Expand All @@ -533,6 +544,7 @@ int main(int argc, const char* argv[])
const char* enclave;
const char* conffile;
const char* keyfile;
const char* arg;
oe_enclave_t enc;
void* pem_data = NULL;
size_t pem_size;
Expand All @@ -541,13 +553,25 @@ int main(int argc, const char* argv[])
oe_sgx_load_context_t context;

/* Check arguments */
if (argc != 4)
if (argc > 4 || argc < 3)
{
fprintf(stderr, _usage, arg0, arg0);
exit(1);
}

/* Check for --oedump option and dump oeinfo and signature information */
if (argc == 3)
{
fprintf(stderr, _usage, arg0);
/* Collect arguments for dump */
enclave = argv[1];
arg = argv[2];

/* dump oeinfo and signature information */
oedump(arg0, enclave, arg);
exit(1);
}

/* Collect arguments */
/* Collect arguments for signing*/
enclave = argv[1];
conffile = argv[2];
keyfile = argv[3];
Expand Down
249 changes: 249 additions & 0 deletions tools/oesign/oedump.c
@@ -0,0 +1,249 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.

#include <openenclave/bits/defs.h>
#include <openenclave/internal/elf.h>
#include <openenclave/internal/hexdump.h>
#include <openenclave/internal/sgxcreate.h>
#include <openenclave/internal/sgxtypes.h>
#include <openenclave/internal/utils.h>
#include <stdarg.h>
#include <string.h>

size_t errors = 0;

static bool verbose_opt = false;

OE_PRINTF_FORMAT(1, 2)
void err(const char* fmt, ...)
{
va_list ap;
va_start(ap, fmt);
fprintf(stderr, "*** Error: ");
vfprintf(stderr, fmt, ap);
fprintf(stderr, "\n");
va_end(ap);
errors++;
}

void dump_entry_point(elf64_t* elf)
{
elf64_sym_t sym;
const char* name;

if (elf64_find_dynamic_symbol_by_address(
elf, elf64_get_header(elf)->e_entry, STT_FUNC, &sym) != 0)
{
err("cannot find entry point symbol");
return;
}

if (!(name = elf64_get_string_from_dynstr(elf, sym.st_name)))
{
err("cannot resolve entry point name");
return;
}

if (strcmp(name, "_start") != 0)
{
err("invalid entry point name: %s", name);
return;
}

printf("=== Entry point: \n");
printf("name=%s\n", name);
printf("address=%016llx\n", OE_LLX(sym.st_value));
printf("\n");
}

void dump_enclave_properties(const oe_sgx_enclave_properties_t* props)
{
const sgx_sigstruct_t* sigstruct;

printf("=== SGX Enclave Properties:\n");

printf("product_id=%u\n", props->config.product_id);

printf("security_version=%u\n", props->config.security_version);

bool debug = props->config.attributes & OE_SGX_FLAGS_DEBUG;
printf("debug=%u\n", debug);

printf(
"num_heap_pages=%llu\n",
OE_LLU(props->header.size_settings.num_heap_pages));

printf(
"num_stack_pages=%llu\n",
OE_LLU(props->header.size_settings.num_stack_pages));

printf("num_tcs=%llu\n", OE_LLU(props->header.size_settings.num_tcs));

sigstruct = (const sgx_sigstruct_t*)props->sigstruct;

printf("mrenclave=");
oe_hex_dump(sigstruct->enclavehash, sizeof(sigstruct->enclavehash));

printf("signature=");
oe_hex_dump(sigstruct->signature, sizeof(sigstruct->signature));

printf("\n");

if (verbose_opt)
__sgx_dump_sigstruct(sigstruct);
}

typedef struct _visit_sym_data
{
const elf64_t* elf;
const elf64_shdr_t* shdr;
oe_result_t result;
} visit_sym_data_t;

static int _visit_sym(const elf64_sym_t* sym, void* data_)
{
int rc = -1;
visit_sym_data_t* data = (visit_sym_data_t*)data_;
const elf64_shdr_t* shdr = data->shdr;
const char* name;

data->result = OE_UNEXPECTED;

/* Skip symbol if not a function */
if ((sym->st_info & 0x0F) != STT_FUNC)
{
rc = 0;
goto done;
}

/* Skip symbol if not in the ".ecall" section */
if (sym->st_value < shdr->sh_addr ||
sym->st_value + sym->st_size > shdr->sh_addr + shdr->sh_size)
{
rc = 0;
goto done;
}

/* Skip null names */
if (!(name = elf64_get_string_from_dynstr(data->elf, sym->st_name)))
{
rc = 0;
goto done;
}

/* Dump the ECALL name */
printf("%s (%016llx)\n", name, OE_LLX(sym->st_value));

rc = 0;

done:
return rc;
}

void dump_ecall_section(elf64_t* elf)
{
elf64_shdr_t shdr;

printf("=== ECALLs:\n");

/* Find the .ecall section */
if (elf64_find_section_header(elf, ".ecall", &shdr) != 0)
{
err("missing .ecall section");
return;
}

/* Dump all the ECALLs */
{
visit_sym_data_t data;
data.elf = elf;
data.shdr = &shdr;

if (elf64_visit_symbols(elf, _visit_sym, &data) != 0)
{
err("failed to find ECALLs in .ecall section");
return;
}
}

printf("\n");
}

void check_global(elf64_t* elf, const char* name)
{
elf64_sym_t sym;

if (elf64_find_dynamic_symbol_by_name(elf, name, &sym) != 0)
{
err("failed to find required symbol: %s\n", name);
return;
}

printf("%s (%016llx)\n", name, OE_LLX(sym.st_value));
}

void check_globals(elf64_t* elf)
{
printf("=== Globals:\n");

check_global(elf, "oe_num_pages");
check_global(elf, "oe_virtual_base_addr");
check_global(elf, "oe_base_reloc_page");
check_global(elf, "oe_num_reloc_pages");
check_global(elf, "oe_base_ecall_page");
check_global(elf, "oe_num_ecall_pages");
check_global(elf, "oe_base_heap_page");
check_global(elf, "oe_num_heap_pages");

printf("\n");
}

void oedump(const char* arg0, const char* enc_bin, const char* option)
{
elf64_t elf;
oe_sgx_enclave_properties_t props;

if ((strcmp(option, "--oedump") != 0))
{
fprintf(stderr, "Usage: %s EnclaveImage --oedump\n", arg0);
return;
}

/* Load the ELF-64 object */
if (elf64_load(enc_bin, &elf) != 0)
{
fprintf(stderr, "failed to load %s\n", enc_bin);
goto done;
}

/* Load the SGX enclave properties */
if (oe_sgx_load_properties(&elf, OE_INFO_SECTION_NAME, &props) != OE_OK)
{
err("failed to load SGX enclave properties from %s section",
OE_INFO_SECTION_NAME);
}

printf("\n");

/* Dump the entry point */
dump_entry_point(&elf);

/* Dump the signature section */
dump_enclave_properties(&props);

/* Dump the ECALL section */
dump_ecall_section(&elf);

/* Check globals */
check_globals(&elf);

if (errors)
{
fprintf(stderr, "*** Found %zu errors\n", errors);
goto done;
}

done:
elf64_unload(&elf);
return;
}

0 comments on commit 7b58cec

Please sign in to comment.