core: add embedded data region
Until this patch hashes has been supplied as a single blob following the
init part when configured for paging. To facilitate storing additional
data when OP-TEE is initializing a struct boot_embdata is added. This
struct is populated gen_tee_bin.py and later interpreted by
assembly boot code and init_runtime().
Previous memory allocation for hashes in the linker script is replaced
by this new mechanism.
Acked-by: Jerome Forissier <jerome@forissier.org>
Signed-off-by: Jens Wiklander <jens.wiklander@linaro.org>
diff --git a/scripts/gen_tee_bin.py b/scripts/gen_tee_bin.py
index 3afacf5..675ae24 100755
--- a/scripts/gen_tee_bin.py
+++ b/scripts/gen_tee_bin.py
@@ -35,12 +35,30 @@
elffile_symbols = None
tee_pageable_bin = None
tee_pager_bin = None
+tee_embdata_bin = None
def eprint(*args, **kwargs):
print(*args, file=sys.stderr, **kwargs)
+def round_up(n, m):
+ if n == 0:
+ return 0
+ else:
+ return (((n - 1) // m) + 1) * m
+
+
+def get_arch_id(elffile):
+ e_machine = elffile.header['e_machine']
+ if e_machine == 'EM_ARM':
+ return 0
+ if e_machine == 'EM_AARCH64':
+ return 1
+ eprint('Unknown e_machine "%s"' % e_machine)
+ sys.exit(1)
+
+
def get_symbol(elffile, name):
global elffile_symbols
if elffile_symbols is None:
@@ -59,14 +77,13 @@
sys.exit(1)
-def get_sections(elffile, pad_to, skip_names, dump_names):
+def get_sections(elffile, pad_to, dump_names):
last_end = 0
bin_data = bytearray()
for section in elffile.iter_sections():
if (section['sh_type'] == 'SHT_NOBITS' or
not (section['sh_flags'] & SH_FLAGS.SHF_ALLOC) or
- skip_names.match(section.name) or
not dump_names.match(section.name)):
continue
@@ -90,10 +107,8 @@
global tee_pageable_bin
if tee_pageable_bin is None:
pad_to = 0
- skip_names = re.compile(r'^$')
dump_names = re.compile(r'^\..*_(pageable|init)$')
- tee_pageable_bin = get_sections(elffile, pad_to, skip_names,
- dump_names)
+ tee_pageable_bin = get_sections(elffile, pad_to, dump_names)
return tee_pageable_bin
@@ -101,13 +116,59 @@
global tee_pager_bin
if tee_pager_bin is None:
pad_to = get_symbol(elffile, '__data_end')['st_value']
- skip_names = re.compile(r'^\..*_(pageable|init)$')
- dump_names = re.compile(r'')
- tee_pager_bin = get_sections(elffile, pad_to, skip_names, dump_names)
+ dump_names = re.compile(
+ r'^\.(text|rodata|got|data|ARM\.exidx|ARM\.extab|rel|rela)$')
+ tee_pager_bin = get_sections(elffile, pad_to, dump_names)
return tee_pager_bin
+def get_hashes_bin(elffile):
+ pageable_bin = get_pageable_bin(elffile)
+ if len(pageable_bin) % small_page_size != 0:
+ eprint("pageable size not a multiple of 4K: "
+ "{}".format(paged_area_size))
+ sys.exit(1)
+
+ data = bytearray()
+ for n in range(0, len(pageable_bin), small_page_size):
+ page = pageable_bin[n:n + small_page_size]
+ data += hashlib.sha256(page).digest()
+
+ return data
+
+
+def get_embdata_bin(elffile):
+ global tee_embdata_bin
+ if tee_embdata_bin is None:
+ hashes_bin = get_hashes_bin(elffile)
+
+ num_entries = 1
+ hash_offs = 2 * 4 + num_entries * (2 * 4)
+ hash_pad = round_up(len(hashes_bin), 8) - len(hashes_bin)
+ total_len = hash_offs + len(hashes_bin) + hash_pad
+
+ tee_embdata_bin = struct.pack('<IIII', total_len, num_entries,
+ hash_offs, len(hashes_bin))
+ tee_embdata_bin += hashes_bin + bytearray(hash_pad)
+
+ # The embedded data region is designed to be easy to extend when
+ # needed, it's formatted as:
+ # +--------------------------------------------------------+
+ # | uint32_t: Length of entire area including this field |
+ # +--------------------------------------------------------+
+ # | uint32_t: Number of entries "1" |
+ # +--------------------------------------------------------+
+ # | uint32_t: Offset of hashes from beginning of table |
+ # +--------------------------------------------------------+
+ # | uint32_t: Length of hashes |
+ # +--------------------------------------------------------+
+ # | Data of hashes + eventual padding |
+ # +--------------------------------------------------------+
+
+ return tee_embdata_bin
+
+
def output_pager_bin(elffile, outf):
outf.write(get_pager_bin(elffile))
@@ -116,16 +177,6 @@
outf.write(get_pageable_bin(elffile))
-def get_arch_id(elffile):
- e_machine = elffile.header['e_machine']
- if e_machine == 'EM_ARM':
- return 0
- if e_machine == 'EM_AARCH64':
- return 1
- eprint('Unknown e_machine "%s"' % e_machine)
- sys.exit(1)
-
-
def get_init_load_addr(elffile):
init_load_addr = get_symbol(elffile, '_start')['st_value']
init_load_addr_hi = init_load_addr >> 32
@@ -137,23 +188,20 @@
arch_id = get_arch_id(elffile)
pager_bin = get_pager_bin(elffile)
pageable_bin = get_pageable_bin(elffile)
- init_mem_usage = get_symbol(elffile, '__init_mem_usage')['st_value']
+ embdata_bin = get_embdata_bin(elffile)
init_load_addr = get_init_load_addr(elffile)
init_bin_size = get_symbol(elffile, '__init_size')['st_value']
pager_bin_size = len(pager_bin)
paged_area_size = len(pageable_bin)
- hash_size = (paged_area_size // small_page_size *
- hashlib.sha256().digest_size)
+
+ init_mem_usage = (get_symbol(elffile, '__init_end')['st_value'] -
+ get_symbol(elffile, '__text_start')['st_value'] +
+ len(embdata_bin))
init_size = (pager_bin_size + min(init_bin_size, paged_area_size) +
- hash_size)
+ len(embdata_bin))
paged_size = paged_area_size - min(init_bin_size, paged_area_size)
- if paged_area_size % small_page_size != 0:
- eprint("pageable size not a multiple of 4K: "
- "{}".format(paged_area_size))
- sys.exit(1)
-
magic = 0x4554504f # 'OPTE'
version = 1
flags = 0
@@ -162,9 +210,7 @@
init_mem_usage, paged_size))
outf.write(pager_bin)
outf.write(pageable_bin[:init_bin_size])
- for n in range(0, len(pageable_bin), small_page_size):
- page = pageable_bin[n:n + small_page_size]
- outf.write(hashlib.sha256(page).digest())
+ outf.write(embdata_bin)
outf.write(pageable_bin[init_bin_size:])
@@ -174,16 +220,10 @@
init_bin_size = get_symbol(elffile, '__init_size')['st_value']
pager_bin_size = len(get_pager_bin(elffile))
paged_area_size = len(get_pageable_bin(elffile))
- hash_size = (paged_area_size // small_page_size *
- hashlib.sha256().digest_size)
-
- if paged_area_size % small_page_size != 0:
- eprint("pageable size not a multiple of 4K: "
- "{}".format(paged_area_size))
- sys.exit(1)
+ embdata_bin_size = len(get_embdata_bin(elffile))
init_size = (pager_bin_size + min(init_bin_size, paged_area_size) +
- hash_size)
+ embdata_bin_size)
paged_size = paged_area_size - min(init_bin_size, paged_area_size)
magic = 0x4554504f # 'OPTE'
@@ -200,18 +240,13 @@
def output_pager_v2(elffile, outf):
init_bin_size = get_symbol(elffile, '__init_size')['st_value']
+ pager_bin = get_pager_bin(elffile)
pageable_bin = get_pageable_bin(elffile)
+ embdata_bin = get_embdata_bin(elffile)
- if len(pageable_bin) % small_page_size != 0:
- eprint("pageable size not a multiple of 4K: "
- "{}".format(paged_area_size))
- sys.exit(1)
-
- outf.write(get_pager_bin(elffile))
+ outf.write(pager_bin)
outf.write(pageable_bin[:init_bin_size])
- for n in range(0, len(pageable_bin), small_page_size):
- page = pageable_bin[n:n + small_page_size]
- outf.write(hashlib.sha256(page).digest())
+ outf.write(embdata_bin)
def output_pageable_v2(elffile, outf):