Beispiel #1
0
/* Get the headers from the buffer.
 * Return -1 in the event of an error.
 * The section headers are optional; if NULL
 * is passed in for pshdr they won't be parsed.
 * We don't (yet) make payload parsing optional
 * because we've never seen a use case.
 */
int
elf_headers(const struct buffer *pinput,
	    uint32_t arch,
	    Elf64_Ehdr *ehdr,
	    Elf64_Phdr **pphdr,
	    Elf64_Shdr **pshdr)
{

	struct parsed_elf pelf;
	int flags;

	flags = ELF_PARSE_PHDR;

	if (pshdr != NULL)
		flags |= ELF_PARSE_SHDR;

	if (parse_elf(pinput, &pelf, flags))
		return -1;

	/* Copy out the parsed elf header. */
	memcpy(ehdr, &pelf.ehdr, sizeof(*ehdr));

	*pphdr = calloc(ehdr->e_phnum, sizeof(Elf64_Phdr));
	memcpy(*pphdr, pelf.phdr, ehdr->e_phnum * sizeof(Elf64_Phdr));

	if (pshdr != NULL) {
		*pshdr = calloc(ehdr->e_shnum, sizeof(Elf64_Shdr));
		memcpy(*pshdr, pelf.shdr, ehdr->e_shnum * sizeof(Elf64_Shdr));
	}

	parsed_elf_destroy(&pelf);

	return 0;
}
int main(int argc, char *argv[])
{
	FILE *fp;
	u8 bfr[ALIGNMENT];

	get_args(argc, argv);

	elf_size = get_filesize(elf_name);
	elf = mmap_file(elf_name);

	parse_elf();

	meta_header_size = 0x80 + ehdr.e_phnum * (0x30 + 0x20 + 0x60) + 0x30;
	info_offset = 0x70;
	elf_offset = 0x90;
	phdr_offset = elf_offset + ehdr.e_ehsize;
	sec_offset = round_up(phdr_offset + ehdr.e_phentsize * ehdr.e_phnum, ALIGNMENT);
	version_offset = round_up(sec_offset + ehdr.e_phnum *  0x20, ALIGNMENT);
	ctrl_offset = round_up(version_offset + 0x10, ALIGNMENT);
	meta_offset = round_up(ctrl_offset + 0x70, ALIGNMENT);
	header_size = round_up(meta_offset + meta_header_size, 0x80);

	if (compression)
		compress_elf();
	else
		fill_phdr_map();
	
	build_sce_hdr();
	build_info_hdr();
	build_ctrl_hdr();
	build_sec_hdr();
	build_version_hdr();
	build_meta_hdr();

	self = malloc(header_size + elf_size);
	memset(self, 0, header_size + elf_size);

	build_hdr();
	write_elf();
	calculate_hashes();
	sign_hdr();

	sce_encrypt_data(self);
	sce_encrypt_header(self, &ks);

	fp = fopen(self_name, "wb");
	if (fp == NULL)
		fail("fopen(%s) failed", self_name);

	if (fwrite(self, header_size + compressed_size, 1, fp) != 1)
		fail("unable to write self");

	memset(bfr, 0, sizeof bfr);
	fwrite(bfr, round_up(compressed_size, ALIGNMENT) - compressed_size, 1, fp);

	fclose(fp);

	return 0;
}
Beispiel #3
0
int main(int argc,char **argv)
{
	if(argc!=2){
		printf("Invalid Usage!!!\n");
		printf("%s elf_file\n",argv[0]);
		return 1;
		}
	parse_elf(argv[1]);
	return 0;
}
Beispiel #4
0
void start(uint32_t* modulep, void* physbase, void* physfree)
{
	struct smap_t {
		uint64_t base, length;
		uint32_t type;
	}__attribute__((packed)) *smap;
	while(modulep[0] != 0x9001) modulep += modulep[1]+2;
	for(smap = (struct smap_t*)(modulep+2); smap < (struct smap_t*)((char*)modulep+modulep[1]+2*4); ++smap) {
		if (smap->type == 1 /* memory */ && smap->length != 0) {
			//print_out("Available Physical Memory [%x-%x]\n", smap->base, smap->base + smap->length);
			total = smap->base + smap->length;
		}
	}
	//print_out("tarfs in [%p:%p]\n", &_binary_tarfs_start, &_binary_tarfs_end);
	
	total = (total/1048576) +1;
        //print_out(" The Highest memory is %d ",total);
        //print_out("This is the address of physfree -- %p             ", physfree);
        initialize_free_pages();
        initialize_tasks();
	register_fs((uint64_t)&_binary_tarfs_start);
        create_page_tables(physfree);
        //print_out("     Successfully created page tables");

	__asm__("cli;");

	file = parse_elf("bin/shell");
        load_file_list = file->load_list;
        load_shell();
	/*
	file = parse_elf("bin/hello");
	load_file_list = file->load_list;	
	load_file();
	*/
	file = parse_elf("bin/try");
	load_file_list = file->load_list;	
	load_file();

	switch_to(0);
	// kernel starts here
	while(1);
}
Beispiel #5
0
int rmodule_init(struct rmod_context *ctx, const struct buffer *elfin)
{
	struct parsed_elf *pelf;
	size_t i;
	int ret;

	ret = -1;
	memset(ctx, 0, sizeof(*ctx));
	pelf = &ctx->pelf;

	if (parse_elf(elfin, pelf, ELF_PARSE_ALL)) {
		ERROR("Couldn't parse ELF!\n");
		return -1;
	}

	/* Only allow executables to be turned into rmodules. */
	if (pelf->ehdr.e_type != ET_EXEC) {
		ERROR("ELF is not an executable: %u.\n", pelf->ehdr.e_type);
		goto out;
	}

	/* Determine if architecture is supported. */
	for (i = 0; i < ARRAY_SIZE(reloc_ops); i++) {
		if (reloc_ops[i].arch == pelf->ehdr.e_machine) {
			ctx->ops = &reloc_ops[i];
			break;
		}
	}

	if (ctx->ops == NULL) {
		ERROR("ELF is unsupported arch: %u.\n", pelf->ehdr.e_machine);
		goto out;
	}

	/* Set the endian ops. */
	if (ctx->pelf.ehdr.e_ident[EI_DATA] == ELFDATA2MSB)
		ctx->xdr = &xdr_be;
	else
		ctx->xdr = &xdr_le;

	if (find_program_segment(ctx))
		goto out;

	if (filter_relocation_sections(ctx))
		goto out;

	ret = 0;

out:
	return ret;
}
Beispiel #6
0
/* Get the headers from the buffer.
 * Return -1 in the event of an error.
 * The section headers are optional; if NULL
 * is passed in for pshdr they won't be parsed.
 * We don't (yet) make payload parsing optional
 * because we've never seen a use case.
 */
int
elf_headers(const struct buffer *pinput,
	    uint32_t arch,
	    Elf64_Ehdr *ehdr,
	    Elf64_Phdr **pphdr,
	    Elf64_Shdr **pshdr)
{

	struct parsed_elf pelf;
	int flags;

	flags = ELF_PARSE_PHDR;

	if (pshdr != NULL)
		flags |= ELF_PARSE_SHDR;

	if (parse_elf(pinput, &pelf, flags))
		return -1;

	/* Copy out the parsed elf header. */
	memcpy(ehdr, &pelf.ehdr, sizeof(*ehdr));

	// The tool may work in architecture-independent way.
	if (arch != CBFS_ARCHITECTURE_UNKNOWN &&
	    !((ehdr->e_machine == EM_ARM) && (arch == CBFS_ARCHITECTURE_ARMV7)) &&
	    !((ehdr->e_machine == EM_386) && (arch == CBFS_ARCHITECTURE_X86))) {
		ERROR("The stage file has the wrong architecture\n");
		return -1;
	}

	*pphdr = calloc(ehdr->e_phnum, sizeof(Elf64_Phdr));
	memcpy(*pphdr, pelf.phdr, ehdr->e_phnum * sizeof(Elf64_Phdr));

	if (pshdr != NULL) {
		*pshdr = calloc(ehdr->e_shnum, sizeof(Elf64_Shdr));
		memcpy(*pshdr, pelf.shdr, ehdr->e_shnum * sizeof(Elf64_Shdr));
	}

	parsed_elf_destroy(&pelf);

	return 0;
}
Beispiel #7
0
static void walk_directory(const char *dirname) {
	assert(dirname);

	DIR *dir = opendir(dirname);
	if (dir) {
		struct dirent *entry;
		while ((entry = readdir(dir)) != NULL) {
			if (strcmp(entry->d_name, ".") == 0)
				continue;
			if (strcmp(entry->d_name, "..") == 0)
				continue;

			// build full path
			char *path;
			if (asprintf(&path, "%s/%s", dirname, entry->d_name) == -1)
				errExit("asprintf");

			// check regular so library
			char *ptr = strstr(entry->d_name, ".so");
			if (ptr && is_lib_64(path)) {
				if (*(ptr + 3) == '\0' || *(ptr + 3) == '.') {
					parse_elf(path);
					free(path);
					continue;
				}
			}

			// check directory
			// entry->d_type field is supported  in glibc since version 2.19 (Feb 2014)
			// we'll use stat to check for directories
			struct stat s;
			if (stat(path, &s) == -1)
				errExit("stat");
			if (S_ISDIR(s.st_mode))
				walk_directory(path);
		}
		closedir(dir);
	}
}
Beispiel #8
0
static void copy_libs_for_lib(const char *lib) {
	Storage *lib_path;
	for (lib_path = lib_paths; lib_path; lib_path = lib_path->next) {
		char *fname;
		if (asprintf(&fname, "%s/%s", lib_path->name, lib) == -1)
			errExit("asprintf");
		if (access(fname, R_OK) == 0 && is_lib_64(fname)) {
			if (!storage_find(libs, fname)) {
				storage_add(&libs, fname);
				// libs may need other libs
				parse_elf(fname);
			}
			free(fname);
			return;
		}
		free(fname);
	}

	// log a  warning and continue
	if (!arg_quiet)
		fprintf(stderr, "Warning fldd: cannot find %s, skipping...\n", lib);
}
act_rv_t act_memleak_mq_maps(act_memleak_mq_maps_t *p_mq_ref1)
{
    act_int_t i;
    act_memleak_avl_node_t **pp_func_root;
    act_memleak_avl_node_t **pp_file_line_root;
    act_memleak_ref_root_t *p_ref_root;

    if (big2little){
        p_mq_ref1->pid = int_big2little(p_mq_ref1->pid);
    }

    for(i = 0; i < MAPS_MAX; i++){
            if (big2little){
                    p_mq_ref1->u.maps[i].add1 = int_big2little(p_mq_ref1->u.maps[i].add1);
                    p_mq_ref1->u.maps[i].add2 = int_big2little(p_mq_ref1->u.maps[i].add2);
                    p_mq_ref1->u.maps[i].add3 = int_big2little(p_mq_ref1->u.maps[i].add3);
                    p_mq_ref1->u.maps[i].add4 = int_big2little(p_mq_ref1->u.maps[i].add4);
            }
            act_printf("add1=0x%x add2=0x%x add3=0x%x add4=0x%x name:%s\n",
               p_mq_ref1->u.maps[i].add1, 
               p_mq_ref1->u.maps[i].add2,
               p_mq_ref1->u.maps[i].add3,
               p_mq_ref1->u.maps[i].add4,
               p_mq_ref1->u.maps[i].name);
    }        
    
    p_ref_root = act_memleak_ref_root_find(p_mq_ref1->pid);
    pp_func_root = &p_ref_root->p_func_ref_root;
    pp_file_line_root = &p_ref_root->p_file_line_ref_root;
    
    
    if (p_mq_ref1->u.maps[MAPS_MAIN].add1 != 0){
        parse_elf(pp_func_root, pp_file_line_root, p_mq_ref1->u.maps[MAPS_MAIN].name, 0, 0, 0);
        //sprintf(p_name, "%s", p_mq_ref1->u.maps[MAPS_MAIN].name);
    }

    if (p_mq_ref1->u.maps[MAPS_LIB_CMS_CORE].add1 != 0){
        parse_elf(pp_func_root, pp_file_line_root, 
                  "./libdbus.so", 
                  p_mq_ref1->u.maps[MAPS_LIB_CMS_CORE].add1, 
                  p_mq_ref1->u.maps[MAPS_LIB_CMS_CORE].add2, 
                  p_mq_ref1->u.maps[MAPS_LIB_CMS_CORE].add3);
    }

    if (p_mq_ref1->u.maps[MAPS_LIB_CMS_UTIL].add1 != 0){
        parse_elf(pp_func_root, pp_file_line_root, 
                  "./libuClibc-0.9.30.1.so", 
                  p_mq_ref1->u.maps[MAPS_LIB_CMS_UTIL].add1, 
                  p_mq_ref1->u.maps[MAPS_LIB_CMS_UTIL].add2, 
                  p_mq_ref1->u.maps[MAPS_LIB_CMS_UTIL].add3);
    }



    if (p_mq_ref1->u.maps[MAPS_LIB_CMS_CORE].add1 != 0){
        parse_elf(pp_func_root, pp_file_line_root, 
                  "./libcms_core.so", 
                  p_mq_ref1->u.maps[MAPS_LIB_CMS_CORE].add1, 
                  p_mq_ref1->u.maps[MAPS_LIB_CMS_CORE].add2, 
                  p_mq_ref1->u.maps[MAPS_LIB_CMS_CORE].add3);
    }

    if (p_mq_ref1->u.maps[MAPS_LIB_CMS_UTIL].add1 != 0){
        parse_elf(pp_func_root, pp_file_line_root, 
                  "./libcms_util.so", 
                  p_mq_ref1->u.maps[MAPS_LIB_CMS_UTIL].add1, 
                  p_mq_ref1->u.maps[MAPS_LIB_CMS_UTIL].add2, 
                  p_mq_ref1->u.maps[MAPS_LIB_CMS_UTIL].add3);
    }

    if (p_mq_ref1->u.maps[MAPS_LIB_CMS_DAL].add1 != 0){
        parse_elf(pp_func_root, pp_file_line_root, 
                  "./libcms_dal.so", 
                  p_mq_ref1->u.maps[MAPS_LIB_CMS_DAL].add1, 
                  p_mq_ref1->u.maps[MAPS_LIB_CMS_DAL].add2, 
                  p_mq_ref1->u.maps[MAPS_LIB_CMS_DAL].add3);
    }

    if (p_mq_ref1->u.maps[MAPS_LIB_CMS_MSG].add1 != 0){
        parse_elf(pp_func_root, pp_file_line_root, 
                  "./libcms_msg.so", 
                  p_mq_ref1->u.maps[MAPS_LIB_CMS_MSG].add1, 
                  p_mq_ref1->u.maps[MAPS_LIB_CMS_MSG].add2, 
                  p_mq_ref1->u.maps[MAPS_LIB_CMS_MSG].add3);
    }
    
    if (p_mq_ref1->u.maps[MAPS_LIB_NANO_XML].add1 != 0){
        parse_elf(pp_func_root, pp_file_line_root, 
                  "./libnanoxml.so", 
                  p_mq_ref1->u.maps[MAPS_LIB_NANO_XML].add1, 
                  p_mq_ref1->u.maps[MAPS_LIB_NANO_XML].add2, 
                  p_mq_ref1->u.maps[MAPS_LIB_NANO_XML].add3);
    }

    if (p_mq_ref1->u.maps[MAPS_LIB_XDSL_CTL].add1 != 0){
        parse_elf(pp_func_root, pp_file_line_root, 
                  "./libxdslctl.so", 
                  p_mq_ref1->u.maps[MAPS_LIB_XDSL_CTL].add1, 
                  p_mq_ref1->u.maps[MAPS_LIB_XDSL_CTL].add2, 
                  p_mq_ref1->u.maps[MAPS_LIB_XDSL_CTL].add3);
    }

    if (p_mq_ref1->u.maps[MAPS_LIB_ATM_CTL].add1 != 0){
        parse_elf(pp_func_root, pp_file_line_root, 
                  "./libatmctl.so", 
                  p_mq_ref1->u.maps[MAPS_LIB_ATM_CTL].add1, 
                  p_mq_ref1->u.maps[MAPS_LIB_ATM_CTL].add2, 
                  p_mq_ref1->u.maps[MAPS_LIB_ATM_CTL].add3);
    }

    if (p_mq_ref1->u.maps[MAPS_LIB_CMS_BOARD_CTL].add1 != 0){
        parse_elf(pp_func_root, pp_file_line_root, 
                  "./libcms_boardctl.so", 
                  p_mq_ref1->u.maps[MAPS_LIB_CMS_BOARD_CTL].add1, 
                  p_mq_ref1->u.maps[MAPS_LIB_CMS_BOARD_CTL].add2, 
                  p_mq_ref1->u.maps[MAPS_LIB_CMS_BOARD_CTL].add3);
    }

    if (p_mq_ref1->u.maps[MAPS_LIB_WL_MNGR].add1 != 0){
        parse_elf(pp_func_root, pp_file_line_root, 
                  "./libwlmngr.so", 
                  p_mq_ref1->u.maps[MAPS_LIB_WL_MNGR].add1, 
                  p_mq_ref1->u.maps[MAPS_LIB_WL_MNGR].add2, 
                  p_mq_ref1->u.maps[MAPS_LIB_WL_MNGR].add3);
    }

    if (p_mq_ref1->u.maps[MAPS_LIB_WL_CTL].add1 != 0){
        parse_elf(pp_func_root, pp_file_line_root, 
                  "./libwlctl.so", 
                  p_mq_ref1->u.maps[MAPS_LIB_WL_CTL].add1, 
                  p_mq_ref1->u.maps[MAPS_LIB_WL_CTL].add2, 
                  p_mq_ref1->u.maps[MAPS_LIB_WL_CTL].add3);
    }

    if (p_mq_ref1->u.maps[MAPS_LIB_NVRAM].add1 != 0){
        parse_elf(pp_func_root, pp_file_line_root, 
                  "./libnvram.so", 
                  p_mq_ref1->u.maps[MAPS_LIB_NVRAM].add1, 
                  p_mq_ref1->u.maps[MAPS_LIB_NVRAM].add2, 
                  p_mq_ref1->u.maps[MAPS_LIB_NVRAM].add3);
    }

    if (p_mq_ref1->u.maps[MAPS_LIB_CGI].add1 != 0){
        parse_elf(pp_func_root, pp_file_line_root, 
                  "./libcgi.so", 
                  p_mq_ref1->u.maps[MAPS_LIB_CGI].add1, 
                  p_mq_ref1->u.maps[MAPS_LIB_CGI].add2, 
                  p_mq_ref1->u.maps[MAPS_LIB_CGI].add3);
    }

    act_printf("END MQPS pid:%d name:%s\n", p_mq_ref1->pid, p_mq_ref1->u.maps[MAPS_MAIN].name);

    act_memleak_add_pid(p_mq_ref1->pid, p_mq_ref1->u.maps[MAPS_MAIN].name);

    return ACT_RV_SUC;
}
Beispiel #10
0
int main(int argc, char *argv[])
{
	FILE *fp;
	u8 bfr[ALIGNMENT];

	if (argc != 9)
		fail("usage: makeself [type] [version suffix] [version] [vendor id] [auth id] [sdk type] [elf] [self]");

	get_type(argv[1]);
	get_keys(argv[2]);
	get_version(argv[3]);
	get_vendor(argv[4]);
	get_auth(argv[5]);
	get_sdktype(argv[6]);

	elf_size = get_filesize(argv[7]);
	elf = mmap_file(argv[7]);

	parse_elf();

	meta_header_size = 0x80 + ehdr.e_phnum * (0x30 + 0x20 + 0x60) + 0x30;
	info_offset = 0x70;
	elf_offset = 0x90;
	phdr_offset = elf_offset + ehdr.e_ehsize;
	sec_offset = round_up(phdr_offset + ehdr.e_phentsize * ehdr.e_phnum, ALIGNMENT);
	version_offset = round_up(sec_offset + ehdr.e_phnum *  0x20, ALIGNMENT);
	ctrl_offset = round_up(version_offset + 0x10, ALIGNMENT);
	meta_offset = round_up(ctrl_offset + 0x70, ALIGNMENT);
	header_size = round_up(meta_offset + meta_header_size, 0x80);
	shdr_offset = ehdr.e_shoff + header_size;

	build_sce_hdr();
	build_info_hdr();
	build_ctrl_hdr();
	build_sec_hdr();
	build_version_hdr();
	build_meta_hdr();

	self = malloc(header_size + elf_size);
	memset(self, 0, header_size + elf_size);

	build_hdr();
	calculate_hashes();
	sign_hdr();

	sce_encrypt_data(self);
	sce_encrypt_header(self, &ks);

	fp = fopen(argv[8], "wb");
	if (fp == NULL)
		fail("fopen(%s) failed", argv[4]);

	if (fwrite(self, header_size + elf_size, 1, fp) != 1)
		fail("unable to write self");

	memset(bfr, 0, sizeof bfr);
	fwrite(bfr, round_up(elf_size, ALIGNMENT) - elf_size, 1, fp);

	fclose(fp);

	return 0;
}
Beispiel #11
0
int main(int argc, char **argv) {
#if 0
{
//system("cat /proc/self/status");
int i;
for (i = 0; i < argc; i++)
        printf("*%s* ", argv[i]);
printf("\n");
}
#endif
	if (argc < 2) {
		fprintf(stderr, "Error fldd: invalid arguments\n");
		usage();
		exit(1);
	}


	if (strcmp(argv[1], "--help") == 0) {
		usage();
		return 0;
	}

	// check program access
	if (access(argv[1], R_OK)) {
		fprintf(stderr, "Error fldd: cannot access %s\n", argv[1]);
		exit(1);
	}

	char *quiet = getenv("FIREJAIL_QUIET");
	if (quiet && strcmp(quiet, "yes") == 0)
		arg_quiet = 1;

	if (strcmp(argv[1], "-h") == 0 || strcmp(argv[1], "--help") == 0 || strcmp(argv[1], "-?") ==0) {
		usage();
		return 0;
	}

	int fd = STDOUT_FILENO;
	// attempt to open the file
	if (argc == 3) {
		fd = open(argv[2], O_CREAT | O_TRUNC | O_WRONLY, 0644);
		if (!fd) {
			fprintf(stderr, "Error fldd: invalid arguments\n");
			usage();
			exit(1);
		}
	}

	// initialize local storage
	lib_paths_init();

	// process files
	struct stat s;
	if (stat(argv[1], &s) == -1)
		errExit("stat");
	if (S_ISDIR(s.st_mode))
		walk_directory(argv[1]);
	else {
		if (is_lib_64(argv[1]))
			parse_elf(argv[1]);
		else
			fprintf(stderr, "Warning fldd: %s is not a 64bit program/library\n", argv[1]);
	}


	// print libraries and exit
	storage_print(libs, fd);
	if (argc == 3)
		close(fd);
	return 0;
}
Beispiel #12
0
/*
 * @func encrypt_ip modifies the content of some sections. 
 * @param INOUT uint8_t* elf_buf, buffer of ELF binary
 * @param size_t elf_size, size of ELF binary in bytes
 * @param IN uint8_t* key, AES-GCM-128 key
 * @param bool debug, true iff enclave is requried to support debug
 * @return encip_ret_e:
 * ENCIP_ERROR_ENCRYPTIP_INVALID_PARAM if any input parameter is NULL
 * Respective error results in case any of the following functions fail: 
 * parse_elf, get_pcl_tbl init_random_iv, encrypt_or_clear_ip_sections or sha256
 * ENCIP_ERROR_MEM_ALLOC if memory allocation fails
 * ENCIP_ERROR_SEALED_BUF_SIZE if sealed buf size exceeds the size allocated for it in PCL table
 * ENCIP_SUCCESS if success
 */
encip_ret_e encrypt_ip(INOUT uint8_t* elf_buf, size_t elf_size, IN uint8_t* key, bool debug)
{
    if(NULL == elf_buf || NULL == key)
        return ENCIP_ERROR_ENCRYPTIP_INVALID_PARAM;
    encip_ret_e ret = ENCIP_ERROR_FAIL;
    pcl_data_t dat = {
        .elf_sec = 0,
        .shstrndx = 0,
        .sections_names = NULL,
        .phdr = NULL,
        .nsections = 0, 
        .nsegments = 0,
    };
    pcl_table_t* tbl = NULL;

    ret = parse_elf(elf_buf, elf_size, &dat);
    if(ENCIP_ERROR(ret))
        return ret;

    ret = get_pcl_tbl(elf_buf, elf_size, &dat, &tbl);
    if(ENCIP_ERROR(ret))
        return ret;

    // Verify state of binary:
    if(PCL_CIPHER == tbl->pcl_state) 
        return ENCIP_ERROR_ALREADY_ENCRYPTED;
    if(PCL_PLAIN  != tbl->pcl_state)
        return ENCIP_ERROR_IMPROPER_STATE;

    // Encrypt or clear IP sections: 
    uint32_t num_rvas = 0;
    ret = encrypt_or_clear_ip_sections(&dat, key, elf_buf, elf_size, tbl, &num_rvas, debug);
    if(ENCIP_ERROR(ret))
        return ret;

    // Set GUID:
    memcpy(tbl->pcl_guid, g_pcl_guid, sizeof(tbl->pcl_guid));

    // Set sealed blob size:
    tbl->sealed_blob_size = (size_t)sgx_calc_sealed_data_size(SGX_PCL_GUID_SIZE, SGX_AESGCM_KEY_SIZE);
    // Verify calculated size equals hard coded size of buffer in PCL table:
    if(PCL_SEALED_BLOB_SIZE != tbl->sealed_blob_size)
        return ENCIP_ERROR_SEALED_BUF_SIZE;

    // Set num RVAs:
    tbl->num_rvas = num_rvas;

    // Set decryption key sha256 hash result:
    ret = sha256(key, SGX_AESGCM_KEY_SIZE, tbl->decryption_key_hash);
    if(ENCIP_ERROR(ret))
        return ret;

    // Set PCL state
    tbl->pcl_state = PCL_CIPHER;

    return ENCIP_SUCCESS;
}

/*
 * @func print_usage prints sgx_encrypt usage instructions 
 * @param IN char* encip_name is the name of the application
 */
void print_usage(IN char* encip_name)
{
    printf("\n");
    printf("\tUsage: \n");
    printf("\t  %s -i <input enclave so file name> -o <output enclave so file name> -k <key file name> [-d]\n",
            encip_name);
    printf("\t  -d (optional) prevents the tool from disabling the debug capabilities\n");
    printf("\n");
}
Beispiel #13
0
/* returns size of result, or -1 if error.
 * Note that, with the new code, this function
 * works for all elf files, not just the restricted set.
 */
int parse_elf_to_stage(const struct buffer *input, struct buffer *output,
		       enum comp_algo algo, uint32_t *location,
		       const char *ignore_section)
{
	struct parsed_elf pelf;
	Elf64_Phdr *phdr;
	Elf64_Ehdr *ehdr;
	Elf64_Shdr *shdr_ignored;
	Elf64_Addr virt_to_phys;
	char *buffer;
	struct buffer outheader;
	int ret = -1;

	int headers;
	int i, outlen;
	uint32_t data_start, data_end, mem_end;

	comp_func_ptr compress = compression_function(algo);
	if (!compress)
		return -1;

	DEBUG("start: parse_elf_to_stage(location=0x%x)\n", *location);

	int flags = ELF_PARSE_PHDR | ELF_PARSE_SHDR | ELF_PARSE_STRTAB;

	if (parse_elf(input, &pelf, flags)) {
		ERROR("Couldn't parse ELF\n");
		return -1;
	}

	ehdr = &pelf.ehdr;
	phdr = &pelf.phdr[0];

	/* Find the section header corresponding to ignored-section */
	shdr_ignored = find_ignored_section_header(&pelf, ignore_section);

	if (ignore_section && (shdr_ignored == NULL))
		WARN("Ignore section not found\n");

	headers = ehdr->e_phnum;

	/* Ignore the program header containing ignored section */
	for (i = 0; i < headers; i++) {
		if (is_phdr_ignored(&phdr[i], shdr_ignored))
			phdr[i].p_type = PT_NULL;
	}

	data_start = ~0;
	data_end = 0;
	mem_end = 0;
	virt_to_phys = 0;

	for (i = 0; i < headers; i++) {
		unsigned int start, mend, rend;

		if (phdr[i].p_type != PT_LOAD)
			continue;

		/* Empty segments are never interesting */
		if (phdr[i].p_memsz == 0)
			continue;

		/* BSS */

		start = phdr[i].p_paddr;

		mend = start + phdr[i].p_memsz;
		rend = start + phdr[i].p_filesz;

		if (start < data_start)
			data_start = start;

		if (rend > data_end)
			data_end = rend;

		if (mend > mem_end)
			mem_end = mend;

		if (virt_to_phys == 0)
			virt_to_phys = phdr[i].p_paddr - phdr[i].p_vaddr;
	}

	if (data_start < *location) {
		data_start = *location;
	}

	if (data_end <= data_start) {
		ERROR("data ends (%08lx) before it starts (%08lx). Make sure "
		      "the ELF file is correct and resides in ROM space.\n",
		      (unsigned long)data_end, (unsigned long)data_start);
		exit(1);
	}

	/* allocate an intermediate buffer for the data */
	buffer = calloc(data_end - data_start, 1);

	if (buffer == NULL) {
		ERROR("Unable to allocate memory: %m\n");
		goto err;
	}

	/* Copy the file data into the buffer */

	for (i = 0; i < headers; i++) {
		unsigned int l_start, l_offset = 0;

		if (phdr[i].p_type != PT_LOAD)
			continue;

		if (phdr[i].p_memsz == 0)
			continue;

		l_start = phdr[i].p_paddr;
		if (l_start < *location) {
			l_offset = *location - l_start;
			l_start = *location;
		}

		/* A legal ELF file can have a program header with
		 * non-zero length but zero-length file size and a
		 * non-zero offset which, added together, are > than
		 * input->size (i.e. the total file size).  So we need
		 * to not even test in the case that p_filesz is zero.
		 */
		if (! phdr[i].p_filesz)
			continue;
		if (input->size < (phdr[i].p_offset + phdr[i].p_filesz)){
			ERROR("Underflow copying out the segment."
			      "File has %zu bytes left, segment end is %zu\n",
			      input->size, (size_t)(phdr[i].p_offset + phdr[i].p_filesz));
			free(buffer);
			goto err;
		}
		memcpy(buffer + (l_start - data_start),
		       &input->data[phdr[i].p_offset + l_offset],
		       phdr[i].p_filesz - l_offset);
	}

	/* Now make the output buffer */
	if (buffer_create(output, sizeof(struct cbfs_stage) + data_end - data_start,
			  input->name) != 0) {
		ERROR("Unable to allocate memory: %m\n");
		free(buffer);
		goto err;
	}
	memset(output->data, 0, output->size);

	/* Compress the data, at which point we'll know information
	 * to fill out the header. This seems backward but it works because
	 * - the output header is a known size (not always true in many xdr's)
	 * - we do need to know the compressed output size first
	 * If compression fails or makes the data bigger, we'll warn about it
	 * and use the original data.
	 */
	if (compress(buffer, data_end - data_start,
		     (output->data + sizeof(struct cbfs_stage)),
		     &outlen) < 0 || (unsigned)outlen > data_end - data_start) {
		WARN("Compression failed or would make the data bigger "
		     "- disabled.\n");
		memcpy(output->data + sizeof(struct cbfs_stage),
		       buffer, data_end - data_start);
		algo = CBFS_COMPRESS_NONE;
	}
	free(buffer);

	/* Set up for output marshaling. */
	outheader.data = output->data;
	outheader.size = 0;

	/* Coreboot expects entry point to be physical address. Thus, adjust the
	 * entry point accordingly.
	 */
	fill_cbfs_stage(&outheader, algo, ehdr->e_entry + virt_to_phys,
			data_start, outlen, mem_end - data_start);

	if (*location)
		*location -= sizeof(struct cbfs_stage);
	output->size = sizeof(struct cbfs_stage) + outlen;
	ret = 0;

err:
	parsed_elf_destroy(&pelf);
	return ret;
}