mirror of
https://github.com/corda/corda.git
synced 2025-02-09 20:31:18 +00:00
* 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
128 lines
3.8 KiB
C++
128 lines
3.8 KiB
C++
#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 = §ions[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, §ions[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", §ion);
|
|
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(¬e, 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;
|
|
}
|