|
@@ -1,7 +1,9 @@
|
|
|
#!/usr/bin/env python3
|
|
|
+# pylint: disable=invalid-name
|
|
|
|
|
|
import argparse
|
|
|
import datetime
|
|
|
+import functools
|
|
|
import hashlib
|
|
|
import os
|
|
|
import struct
|
|
@@ -9,47 +11,48 @@ import subprocess
|
|
|
import sys
|
|
|
|
|
|
sys.path.insert(0, os.path.dirname(os.path.dirname(__file__)))
|
|
|
-from generated_offsets import *
|
|
|
+import generated_offsets as offs # pylint: disable=import-error,wrong-import-position
|
|
|
|
|
|
+# pylint: enable=invalid-name
|
|
|
|
|
|
# Default / Architectural Options
|
|
|
|
|
|
ARCHITECTURE = "amd64"
|
|
|
|
|
|
-SSAFRAMESIZE = PAGESIZE
|
|
|
+SSAFRAMESIZE = offs.PAGESIZE
|
|
|
|
|
|
DEFAULT_ENCLAVE_SIZE = '256M'
|
|
|
DEFAULT_THREAD_NUM = 4
|
|
|
-enclave_heap_min = DEFAULT_HEAP_MIN
|
|
|
+ENCLAVE_HEAP_MIN = offs.DEFAULT_HEAP_MIN
|
|
|
|
|
|
|
|
|
# Utilities
|
|
|
|
|
|
-ZERO_PAGE = bytes(PAGESIZE)
|
|
|
+ZERO_PAGE = bytes(offs.PAGESIZE)
|
|
|
|
|
|
|
|
|
def roundup(addr):
|
|
|
- remaining = addr % PAGESIZE
|
|
|
+ remaining = addr % offs.PAGESIZE
|
|
|
if remaining:
|
|
|
- return addr + (PAGESIZE - remaining)
|
|
|
+ return addr + (offs.PAGESIZE - remaining)
|
|
|
return addr
|
|
|
|
|
|
|
|
|
def rounddown(addr):
|
|
|
- return addr - addr % PAGESIZE
|
|
|
+ return addr - addr % offs.PAGESIZE
|
|
|
|
|
|
|
|
|
-def parse_size(s):
|
|
|
+def parse_size(value):
|
|
|
scale = 1
|
|
|
- if s.endswith("K"):
|
|
|
+ if value.endswith("K"):
|
|
|
scale = 1024
|
|
|
- if s.endswith("M"):
|
|
|
+ if value.endswith("M"):
|
|
|
scale = 1024 * 1024
|
|
|
- if s.endswith("G"):
|
|
|
+ if value.endswith("G"):
|
|
|
scale = 1024 * 1024 * 1024
|
|
|
if scale != 1:
|
|
|
- s = s[:-1]
|
|
|
- return int(s, 0) * scale
|
|
|
+ value = value[:-1]
|
|
|
+ return int(value, 0) * scale
|
|
|
|
|
|
|
|
|
# Reading / Writing Manifests
|
|
@@ -57,8 +60,8 @@ def parse_size(s):
|
|
|
def read_manifest(filename):
|
|
|
manifest = dict()
|
|
|
manifest_layout = []
|
|
|
- with open(filename, "r") as f:
|
|
|
- for line in f.readlines():
|
|
|
+ with open(filename, "r") as file:
|
|
|
+ for line in file:
|
|
|
if line == "":
|
|
|
manifest_layout.append((None, None))
|
|
|
break
|
|
@@ -114,10 +117,10 @@ def exec_sig_manifest(args, manifest):
|
|
|
|
|
|
|
|
|
def output_manifest(filename, manifest, manifest_layout):
|
|
|
- with open(filename, 'w') as f:
|
|
|
+ with open(filename, 'w') as file:
|
|
|
written = []
|
|
|
|
|
|
- f.write("# DO NOT MODIFY. THIS FILE WAS AUTO-GENERATED.\n\n")
|
|
|
+ file.write('# DO NOT MODIFY. THIS FILE WAS AUTO-GENERATED.\n\n')
|
|
|
|
|
|
for (key, comment) in manifest_layout:
|
|
|
line = ''
|
|
@@ -128,35 +131,35 @@ def output_manifest(filename, manifest, manifest_layout):
|
|
|
if line != '':
|
|
|
line += ' '
|
|
|
line += comment
|
|
|
- f.write(line)
|
|
|
- f.write('\n')
|
|
|
+ file.write(line)
|
|
|
+ file.write('\n')
|
|
|
|
|
|
- f.write('\n')
|
|
|
- f.write("# Generated by Graphene\n")
|
|
|
- f.write('\n')
|
|
|
+ file.write('\n')
|
|
|
+ file.write('# Generated by Graphene\n')
|
|
|
+ file.write('\n')
|
|
|
|
|
|
for key in sorted(manifest):
|
|
|
if key not in written:
|
|
|
- f.write("%s = %s\n" % (key, manifest[key]))
|
|
|
+ file.write("%s = %s\n" % (key, manifest[key]))
|
|
|
|
|
|
|
|
|
# Loading Enclave Attributes
|
|
|
|
|
|
def get_enclave_attributes(manifest):
|
|
|
sgx_flags = {
|
|
|
- 'FLAG_DEBUG': struct.pack("<Q", SGX_FLAGS_DEBUG),
|
|
|
- 'FLAG_MODE64BIT': struct.pack("<Q", SGX_FLAGS_MODE64BIT),
|
|
|
+ 'FLAG_DEBUG': struct.pack("<Q", offs.SGX_FLAGS_DEBUG),
|
|
|
+ 'FLAG_MODE64BIT': struct.pack("<Q", offs.SGX_FLAGS_MODE64BIT),
|
|
|
}
|
|
|
|
|
|
sgx_xfrms = {
|
|
|
- 'XFRM_LEGACY': struct.pack("<Q", SGX_XFRM_LEGACY),
|
|
|
- 'XFRM_AVX': struct.pack("<Q", SGX_XFRM_AVX),
|
|
|
- 'XFRM_AVX512': struct.pack("<Q", SGX_XFRM_AVX512),
|
|
|
- 'XFRM_MPX': struct.pack("<Q", SGX_XFRM_MPX),
|
|
|
+ 'XFRM_LEGACY': struct.pack("<Q", offs.SGX_XFRM_LEGACY),
|
|
|
+ 'XFRM_AVX': struct.pack("<Q", offs.SGX_XFRM_AVX),
|
|
|
+ 'XFRM_AVX512': struct.pack("<Q", offs.SGX_XFRM_AVX512),
|
|
|
+ 'XFRM_MPX': struct.pack("<Q", offs.SGX_XFRM_MPX),
|
|
|
}
|
|
|
|
|
|
sgx_miscs = {
|
|
|
- 'MISC_EXINFO': struct.pack("<L", SGX_MISCSELECT_EXINFO),
|
|
|
+ 'MISC_EXINFO': struct.pack("<L", offs.SGX_MISCSELECT_EXINFO),
|
|
|
}
|
|
|
|
|
|
default_attributes = {
|
|
@@ -217,10 +220,10 @@ def resolve_uri(uri, check_exist=True):
|
|
|
return target
|
|
|
|
|
|
|
|
|
-def get_checksum(file):
|
|
|
+def get_checksum(filename):
|
|
|
digest = hashlib.sha256()
|
|
|
- with open(file, 'rb') as f:
|
|
|
- digest.update(f.read())
|
|
|
+ with open(filename, 'rb') as file:
|
|
|
+ digest.update(file.read())
|
|
|
return digest.digest()
|
|
|
|
|
|
|
|
@@ -269,8 +272,8 @@ def get_trusted_children(manifest, check_exist=True, do_checksum=True):
|
|
|
target += '.sig'
|
|
|
if do_checksum:
|
|
|
sig = open(target, 'rb').read()[
|
|
|
- SGX_ARCH_ENCLAVE_CSS_ENCLAVE_HASH:
|
|
|
- SGX_ARCH_ENCLAVE_CSS_ENCLAVE_HASH + SGX_HASH_SIZE].hex()
|
|
|
+ offs.SGX_ARCH_ENCLAVE_CSS_ENCLAVE_HASH:
|
|
|
+ offs.SGX_ARCH_ENCLAVE_CSS_ENCLAVE_HASH + offs.SGX_HASH_SIZE].hex()
|
|
|
targets[key] = (val, target, sig)
|
|
|
else:
|
|
|
targets[key] = (val, target)
|
|
@@ -288,10 +291,10 @@ PAGEINFO_REG = 0x200
|
|
|
|
|
|
def get_loadcmds(filename):
|
|
|
loadcmds = []
|
|
|
- p = subprocess.Popen(['readelf', '-l', '-W', filename],
|
|
|
+ proc = subprocess.Popen(['readelf', '-l', '-W', filename],
|
|
|
stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
|
|
while True:
|
|
|
- line = p.stdout.readline()
|
|
|
+ line = proc.stdout.readline()
|
|
|
if not line:
|
|
|
break
|
|
|
line = line.decode()
|
|
@@ -304,12 +307,12 @@ def get_loadcmds(filename):
|
|
|
if len(tokens) >= 7 and tokens[7] == "E":
|
|
|
tokens[6] += tokens[7]
|
|
|
prot = 0
|
|
|
- for t in tokens[6]:
|
|
|
- if t == "R":
|
|
|
+ for token in tokens[6]:
|
|
|
+ if token == "R":
|
|
|
prot = prot | 4
|
|
|
- if t == "W":
|
|
|
+ if token == "W":
|
|
|
prot = prot | 2
|
|
|
- if t == "E":
|
|
|
+ if token == "E":
|
|
|
prot = prot | 1
|
|
|
|
|
|
loadcmds.append((int(tokens[1][2:], 16), # offset
|
|
@@ -317,15 +320,17 @@ def get_loadcmds(filename):
|
|
|
int(tokens[4][2:], 16), # filesize
|
|
|
int(tokens[5][2:], 16), # memsize
|
|
|
prot))
|
|
|
- p.wait()
|
|
|
- if p.returncode != 0:
|
|
|
+ proc.wait()
|
|
|
+ if proc.returncode != 0:
|
|
|
return None
|
|
|
return loadcmds
|
|
|
|
|
|
|
|
|
class MemoryArea:
|
|
|
+ # pylint: disable=too-few-public-methods,too-many-instance-attributes
|
|
|
def __init__(self, desc, file=None, content=None, addr=None, size=None,
|
|
|
flags=None, measure=True):
|
|
|
+ # pylint: disable=too-many-arguments
|
|
|
self.desc = desc
|
|
|
self.file = file
|
|
|
self.content = content
|
|
@@ -363,15 +368,15 @@ def get_memory_areas(attr, args):
|
|
|
areas = []
|
|
|
areas.append(
|
|
|
MemoryArea('ssa',
|
|
|
- size=attr['thread_num'] * SSAFRAMESIZE * SSAFRAMENUM,
|
|
|
+ size=attr['thread_num'] * SSAFRAMESIZE * offs.SSAFRAMENUM,
|
|
|
flags=PAGEINFO_R | PAGEINFO_W | PAGEINFO_REG))
|
|
|
- areas.append(MemoryArea('tcs', size=attr['thread_num'] * TCS_SIZE,
|
|
|
+ areas.append(MemoryArea('tcs', size=attr['thread_num'] * offs.TCS_SIZE,
|
|
|
flags=PAGEINFO_TCS))
|
|
|
- areas.append(MemoryArea('tls', size=attr['thread_num'] * PAGESIZE,
|
|
|
+ areas.append(MemoryArea('tls', size=attr['thread_num'] * offs.PAGESIZE,
|
|
|
flags=PAGEINFO_R | PAGEINFO_W | PAGEINFO_REG))
|
|
|
|
|
|
for _ in range(attr['thread_num']):
|
|
|
- areas.append(MemoryArea('stack', size=ENCLAVE_STACK_SIZE,
|
|
|
+ areas.append(MemoryArea('stack', size=offs.ENCLAVE_STACK_SIZE,
|
|
|
flags=PAGEINFO_R | PAGEINFO_W | PAGEINFO_REG))
|
|
|
|
|
|
areas.append(MemoryArea('pal', file=args['libpal'], flags=PAGEINFO_REG))
|
|
@@ -412,12 +417,13 @@ def entry_point(elf_path):
|
|
|
|
|
|
|
|
|
def baseaddr():
|
|
|
- if enclave_heap_min == 0:
|
|
|
- return ENCLAVE_HIGH_ADDRESS
|
|
|
+ if ENCLAVE_HEAP_MIN == 0:
|
|
|
+ return offs.ENCLAVE_HIGH_ADDRESS
|
|
|
return 0
|
|
|
|
|
|
|
|
|
def gen_area_content(attr, areas):
|
|
|
+ # pylint: disable=too-many-locals
|
|
|
manifest_area = find_area(areas, 'manifest')
|
|
|
exec_area = find_area(areas, 'exec', True)
|
|
|
pal_area = find_area(areas, 'pal')
|
|
@@ -429,19 +435,19 @@ def gen_area_content(attr, areas):
|
|
|
tcs_data = bytearray(tcs_area.size)
|
|
|
|
|
|
def set_tcs_field(t, offset, pack_fmt, value):
|
|
|
- struct.pack_into(pack_fmt, tcs_data, t * TCS_SIZE + offset, value)
|
|
|
+ struct.pack_into(pack_fmt, tcs_data, t * offs.TCS_SIZE + offset, value)
|
|
|
|
|
|
tls_data = bytearray(tls_area.size)
|
|
|
|
|
|
def set_tls_field(t, offset, value):
|
|
|
- struct.pack_into('<Q', tls_data, t * PAGESIZE + offset, value)
|
|
|
+ struct.pack_into('<Q', tls_data, t * offs.PAGESIZE + offset, value)
|
|
|
|
|
|
- enclave_heap_max = pal_area.addr - MEMORY_GAP
|
|
|
+ enclave_heap_max = pal_area.addr - offs.MEMORY_GAP
|
|
|
|
|
|
# Sanity check that we measure everything except the heap which is zeroed
|
|
|
# on enclave startup.
|
|
|
for area in areas:
|
|
|
- if (area.addr + area.size <= enclave_heap_min or
|
|
|
+ if (area.addr + area.size <= ENCLAVE_HEAP_MIN or
|
|
|
area.addr >= enclave_heap_max or area is exec_area):
|
|
|
if not area.measure:
|
|
|
raise ValueError("Memory area, which is not the heap, "
|
|
@@ -450,31 +456,31 @@ def gen_area_content(attr, areas):
|
|
|
raise ValueError("Unexpected memory area is in heap range")
|
|
|
|
|
|
for t in range(0, attr['thread_num']):
|
|
|
- ssa_offset = ssa_area.addr + SSAFRAMESIZE * SSAFRAMENUM * t
|
|
|
+ ssa_offset = ssa_area.addr + SSAFRAMESIZE * offs.SSAFRAMENUM * t
|
|
|
ssa = baseaddr() + ssa_offset
|
|
|
- set_tcs_field(t, TCS_OSSA, '<Q', ssa_offset)
|
|
|
- set_tcs_field(t, TCS_NSSA, '<L', SSAFRAMENUM)
|
|
|
- set_tcs_field(t, TCS_OENTRY, '<Q',
|
|
|
+ set_tcs_field(t, offs.TCS_OSSA, '<Q', ssa_offset)
|
|
|
+ set_tcs_field(t, offs.TCS_NSSA, '<L', offs.SSAFRAMENUM)
|
|
|
+ set_tcs_field(t, offs.TCS_OENTRY, '<Q',
|
|
|
pal_area.addr + entry_point(pal_area.file))
|
|
|
- set_tcs_field(t, TCS_OGS_BASE, '<Q', tls_area.addr + PAGESIZE * t)
|
|
|
- set_tcs_field(t, TCS_OFS_LIMIT, '<L', 0xfff)
|
|
|
- set_tcs_field(t, TCS_OGS_LIMIT, '<L', 0xfff)
|
|
|
-
|
|
|
- set_tls_field(t, SGX_COMMON_SELF,
|
|
|
- tls_area.addr + PAGESIZE * t + baseaddr())
|
|
|
- set_tls_field(t, SGX_ENCLAVE_SIZE, attr['enclave_size'])
|
|
|
- set_tls_field(t, SGX_TCS_OFFSET, tcs_area.addr + TCS_SIZE * t)
|
|
|
- set_tls_field(t, SGX_INITIAL_STACK_OFFSET,
|
|
|
+ set_tcs_field(t, offs.TCS_OGS_BASE, '<Q', tls_area.addr + offs.PAGESIZE * t)
|
|
|
+ set_tcs_field(t, offs.TCS_OFS_LIMIT, '<L', 0xfff)
|
|
|
+ set_tcs_field(t, offs.TCS_OGS_LIMIT, '<L', 0xfff)
|
|
|
+
|
|
|
+ set_tls_field(t, offs.SGX_COMMON_SELF,
|
|
|
+ tls_area.addr + offs.PAGESIZE * t + baseaddr())
|
|
|
+ set_tls_field(t, offs.SGX_ENCLAVE_SIZE, attr['enclave_size'])
|
|
|
+ set_tls_field(t, offs.SGX_TCS_OFFSET, tcs_area.addr + offs.TCS_SIZE * t)
|
|
|
+ set_tls_field(t, offs.SGX_INITIAL_STACK_OFFSET,
|
|
|
stacks[t].addr + stacks[t].size)
|
|
|
- set_tls_field(t, SGX_SSA, ssa)
|
|
|
- set_tls_field(t, SGX_GPR, ssa + SSAFRAMESIZE - SGX_GPR_SIZE)
|
|
|
- set_tls_field(t, SGX_MANIFEST_SIZE,
|
|
|
+ set_tls_field(t, offs.SGX_SSA, ssa)
|
|
|
+ set_tls_field(t, offs.SGX_GPR, ssa + SSAFRAMESIZE - offs.SGX_GPR_SIZE)
|
|
|
+ set_tls_field(t, offs.SGX_MANIFEST_SIZE,
|
|
|
os.stat(manifest_area.file).st_size)
|
|
|
- set_tls_field(t, SGX_HEAP_MIN, baseaddr() + enclave_heap_min)
|
|
|
- set_tls_field(t, SGX_HEAP_MAX, baseaddr() + enclave_heap_max)
|
|
|
+ set_tls_field(t, offs.SGX_HEAP_MIN, baseaddr() + ENCLAVE_HEAP_MIN)
|
|
|
+ set_tls_field(t, offs.SGX_HEAP_MAX, baseaddr() + enclave_heap_max)
|
|
|
if exec_area is not None:
|
|
|
- set_tls_field(t, SGX_EXEC_ADDR, baseaddr() + exec_area.addr)
|
|
|
- set_tls_field(t, SGX_EXEC_SIZE, exec_area.size)
|
|
|
+ set_tls_field(t, offs.SGX_EXEC_ADDR, baseaddr() + exec_area.addr)
|
|
|
+ set_tls_field(t, offs.SGX_EXEC_SIZE, exec_area.size)
|
|
|
|
|
|
tcs_area.content = tcs_data
|
|
|
tls_area.content = tls_data
|
|
@@ -488,25 +494,25 @@ def populate_memory_areas(attr, areas):
|
|
|
continue
|
|
|
|
|
|
area.addr = populating - area.size
|
|
|
- if area.addr < enclave_heap_min:
|
|
|
+ if area.addr < ENCLAVE_HEAP_MIN:
|
|
|
raise Exception("Enclave size is not large enough")
|
|
|
- populating = max(area.addr - MEMORY_GAP, 0)
|
|
|
+ populating = max(area.addr - offs.MEMORY_GAP, 0)
|
|
|
|
|
|
free_areas = []
|
|
|
for area in areas:
|
|
|
- if area.addr + area.size + MEMORY_GAP < populating:
|
|
|
- addr = area.addr + area.size + MEMORY_GAP
|
|
|
+ if area.addr + area.size + offs.MEMORY_GAP < populating:
|
|
|
+ addr = area.addr + area.size + offs.MEMORY_GAP
|
|
|
flags = PAGEINFO_R | PAGEINFO_W | PAGEINFO_X | PAGEINFO_REG
|
|
|
free_areas.append(
|
|
|
MemoryArea('free', addr=addr, size=populating - addr,
|
|
|
flags=flags, measure=False))
|
|
|
- populating = max(area.addr - MEMORY_GAP, 0)
|
|
|
+ populating = max(area.addr - offs.MEMORY_GAP, 0)
|
|
|
|
|
|
- if populating > enclave_heap_min:
|
|
|
+ if populating > ENCLAVE_HEAP_MIN:
|
|
|
flags = PAGEINFO_R | PAGEINFO_W | PAGEINFO_X | PAGEINFO_REG
|
|
|
free_areas.append(
|
|
|
- MemoryArea('free', addr=enclave_heap_min,
|
|
|
- size=populating - enclave_heap_min, flags=flags,
|
|
|
+ MemoryArea('free', addr=ENCLAVE_HEAP_MIN,
|
|
|
+ size=populating - ENCLAVE_HEAP_MIN, flags=flags,
|
|
|
measure=False))
|
|
|
|
|
|
gen_area_content(attr, areas)
|
|
@@ -515,9 +521,10 @@ def populate_memory_areas(attr, areas):
|
|
|
|
|
|
|
|
|
def generate_measurement(attr, areas):
|
|
|
+ # pylint: disable=too-many-statements,too-many-branches,too-many-locals
|
|
|
|
|
|
def do_ecreate(digest, size):
|
|
|
- data = struct.pack("<8sLQ44s", b"ECREATE", SSAFRAMESIZE // PAGESIZE,
|
|
|
+ data = struct.pack("<8sLQ44s", b"ECREATE", SSAFRAMESIZE // offs.PAGESIZE,
|
|
|
size, b"")
|
|
|
digest.update(data)
|
|
|
|
|
@@ -534,12 +541,12 @@ def generate_measurement(attr, areas):
|
|
|
digest.update(content)
|
|
|
|
|
|
def include_page(digest, offset, flags, content, measure):
|
|
|
- if len(content) != PAGESIZE:
|
|
|
+ if len(content) != offs.PAGESIZE:
|
|
|
raise ValueError("Exactly one page expected")
|
|
|
|
|
|
do_eadd(digest, offset, flags)
|
|
|
if measure:
|
|
|
- for i in range(0, PAGESIZE, 256):
|
|
|
+ for i in range(0, offs.PAGESIZE, 256):
|
|
|
do_eextend(digest, offset + i, content[i:i + 256])
|
|
|
|
|
|
mrenclave = hashlib.sha256()
|
|
@@ -563,49 +570,50 @@ def generate_measurement(attr, areas):
|
|
|
if measured:
|
|
|
desc += ' measured'
|
|
|
|
|
|
- if size == PAGESIZE:
|
|
|
+ if size == offs.PAGESIZE:
|
|
|
print(" %016x [%s:%s] %s" % (addr, type_, prot, desc))
|
|
|
else:
|
|
|
print(" %016x-%016lx [%s:%s] %s" %
|
|
|
(addr, addr + size, type_, prot, desc))
|
|
|
|
|
|
- def load_file(digest, f, offset, addr, filesize, memsize, desc, flags):
|
|
|
+ def load_file(digest, file, offset, addr, filesize, memsize, desc, flags):
|
|
|
+ # pylint: disable=too-many-arguments
|
|
|
f_addr = rounddown(offset)
|
|
|
m_addr = rounddown(addr)
|
|
|
m_size = roundup(addr + memsize) - m_addr
|
|
|
|
|
|
print_area(m_addr, m_size, flags, desc, True)
|
|
|
|
|
|
- for pg in range(m_addr, m_addr + m_size, PAGESIZE):
|
|
|
- start = pg - m_addr + f_addr
|
|
|
- end = start + PAGESIZE
|
|
|
+ for page in range(m_addr, m_addr + m_size, offs.PAGESIZE):
|
|
|
+ start = page - m_addr + f_addr
|
|
|
+ end = start + offs.PAGESIZE
|
|
|
start_zero = b""
|
|
|
if start < offset:
|
|
|
- if offset - start >= PAGESIZE:
|
|
|
+ if offset - start >= offs.PAGESIZE:
|
|
|
start_zero = ZERO_PAGE
|
|
|
else:
|
|
|
start_zero = bytes(offset - start)
|
|
|
end_zero = b""
|
|
|
if end > offset + filesize:
|
|
|
- if end - offset - filesize >= PAGESIZE:
|
|
|
+ if end - offset - filesize >= offs.PAGESIZE:
|
|
|
end_zero = ZERO_PAGE
|
|
|
else:
|
|
|
end_zero = bytes(end - offset - filesize)
|
|
|
start += len(start_zero)
|
|
|
end -= len(end_zero)
|
|
|
if start < end:
|
|
|
- f.seek(start)
|
|
|
- data = f.read(end - start)
|
|
|
+ file.seek(start)
|
|
|
+ data = file.read(end - start)
|
|
|
else:
|
|
|
data = b""
|
|
|
- if len(start_zero + data + end_zero) != PAGESIZE:
|
|
|
+ if len(start_zero + data + end_zero) != offs.PAGESIZE:
|
|
|
raise Exception("wrong calculation")
|
|
|
|
|
|
- include_page(digest, pg, flags, start_zero + data + end_zero, True)
|
|
|
+ include_page(digest, page, flags, start_zero + data + end_zero, True)
|
|
|
|
|
|
for area in areas:
|
|
|
if area.file:
|
|
|
- with open(area.file, 'rb') as f:
|
|
|
+ with open(area.file, 'rb') as file:
|
|
|
if area.is_binary:
|
|
|
loadcmds = get_loadcmds(area.file)
|
|
|
if loadcmds:
|
|
@@ -628,21 +636,21 @@ def generate_measurement(attr, areas):
|
|
|
desc = 'code'
|
|
|
else:
|
|
|
desc = 'data'
|
|
|
- load_file(mrenclave, f, offset, baseaddr_ + addr,
|
|
|
+ load_file(mrenclave, file, offset, baseaddr_ + addr,
|
|
|
filesize, memsize, desc, flags)
|
|
|
else:
|
|
|
- load_file(mrenclave, f, 0, area.addr,
|
|
|
+ load_file(mrenclave, file, 0, area.addr,
|
|
|
os.stat(area.file).st_size, area.size,
|
|
|
area.desc, area.flags)
|
|
|
else:
|
|
|
- for a in range(area.addr, area.addr + area.size, PAGESIZE):
|
|
|
+ for addr in range(area.addr, area.addr + area.size, offs.PAGESIZE):
|
|
|
data = ZERO_PAGE
|
|
|
if area.content is not None:
|
|
|
- start = a - area.addr
|
|
|
- end = start + PAGESIZE
|
|
|
+ start = addr - area.addr
|
|
|
+ end = start + offs.PAGESIZE
|
|
|
data = area.content[start:end]
|
|
|
|
|
|
- include_page(mrenclave, a, area.flags, data, area.measure)
|
|
|
+ include_page(mrenclave, addr, area.flags, data, area.measure)
|
|
|
|
|
|
print_area(area.addr, area.size, area.flags, area.desc,
|
|
|
area.measure)
|
|
@@ -651,47 +659,50 @@ def generate_measurement(attr, areas):
|
|
|
|
|
|
|
|
|
def generate_sigstruct(attr, args, mrenclave):
|
|
|
- """Generate Sigstruct."""
|
|
|
- # field format: (offset, type, value)
|
|
|
+ '''Generate Sigstruct.
|
|
|
+
|
|
|
+ field format: (offset, type, value)
|
|
|
+ ''' # pylint: disable=too-many-locals
|
|
|
+
|
|
|
fields = {
|
|
|
- 'header': (SGX_ARCH_ENCLAVE_CSS_HEADER,
|
|
|
+ 'header': (offs.SGX_ARCH_ENCLAVE_CSS_HEADER,
|
|
|
"<4L", 0x00000006, 0x000000e1, 0x00010000, 0x00000000),
|
|
|
- 'module_vendor': (SGX_ARCH_ENCLAVE_CSS_MODULE_VENDOR, "<L", 0x00000000),
|
|
|
- 'date': (SGX_ARCH_ENCLAVE_CSS_DATE, "<HBB", attr['year'], attr['month'], attr['day']),
|
|
|
- 'header2': (SGX_ARCH_ENCLAVE_CSS_HEADER2,
|
|
|
+ 'module_vendor': (offs.SGX_ARCH_ENCLAVE_CSS_MODULE_VENDOR, "<L", 0x00000000),
|
|
|
+ 'date': (offs.SGX_ARCH_ENCLAVE_CSS_DATE, "<HBB", attr['year'], attr['month'], attr['day']),
|
|
|
+ 'header2': (offs.SGX_ARCH_ENCLAVE_CSS_HEADER2,
|
|
|
"<4L", 0x00000101, 0x00000060, 0x00000060, 0x00000001),
|
|
|
- 'hw_version': (SGX_ARCH_ENCLAVE_CSS_HW_VERSION, "<L", 0x00000000),
|
|
|
- 'misc_select': (SGX_ARCH_ENCLAVE_CSS_MISC_SELECT, "4s", attr['misc_select']),
|
|
|
- 'misc_mask': (SGX_ARCH_ENCLAVE_CSS_MISC_MASK, "4s", attr['misc_select']),
|
|
|
- 'attributes': (SGX_ARCH_ENCLAVE_CSS_ATTRIBUTES, "8s8s", attr['flags'], attr['xfrms']),
|
|
|
- 'attribute_mask': (SGX_ARCH_ENCLAVE_CSS_ATTRIBUTE_MASK,
|
|
|
+ 'hw_version': (offs.SGX_ARCH_ENCLAVE_CSS_HW_VERSION, "<L", 0x00000000),
|
|
|
+ 'misc_select': (offs.SGX_ARCH_ENCLAVE_CSS_MISC_SELECT, "4s", attr['misc_select']),
|
|
|
+ 'misc_mask': (offs.SGX_ARCH_ENCLAVE_CSS_MISC_MASK, "4s", attr['misc_select']),
|
|
|
+ 'attributes': (offs.SGX_ARCH_ENCLAVE_CSS_ATTRIBUTES, "8s8s", attr['flags'], attr['xfrms']),
|
|
|
+ 'attribute_mask': (offs.SGX_ARCH_ENCLAVE_CSS_ATTRIBUTE_MASK,
|
|
|
"8s8s", attr['flags'], attr['xfrms']),
|
|
|
- 'enclave_hash': (SGX_ARCH_ENCLAVE_CSS_ENCLAVE_HASH, "32s", mrenclave),
|
|
|
- 'isv_prod_id': (SGX_ARCH_ENCLAVE_CSS_ISV_PROD_ID, "<H", attr['isv_prod_id']),
|
|
|
- 'isv_svn': (SGX_ARCH_ENCLAVE_CSS_ISV_SVN, "<H", attr['isv_svn']),
|
|
|
+ 'enclave_hash': (offs.SGX_ARCH_ENCLAVE_CSS_ENCLAVE_HASH, "32s", mrenclave),
|
|
|
+ 'isv_prod_id': (offs.SGX_ARCH_ENCLAVE_CSS_ISV_PROD_ID, "<H", attr['isv_prod_id']),
|
|
|
+ 'isv_svn': (offs.SGX_ARCH_ENCLAVE_CSS_ISV_SVN, "<H", attr['isv_svn']),
|
|
|
}
|
|
|
|
|
|
sign_buffer = bytearray(128 + 128)
|
|
|
|
|
|
for field in fields.values():
|
|
|
- if field[0] >= SGX_ARCH_ENCLAVE_CSS_MISC_SELECT:
|
|
|
+ if field[0] >= offs.SGX_ARCH_ENCLAVE_CSS_MISC_SELECT:
|
|
|
struct.pack_into(field[1], sign_buffer,
|
|
|
- field[0] - SGX_ARCH_ENCLAVE_CSS_MISC_SELECT + 128,
|
|
|
+ field[0] - offs.SGX_ARCH_ENCLAVE_CSS_MISC_SELECT + 128,
|
|
|
*field[2:])
|
|
|
else:
|
|
|
struct.pack_into(field[1], sign_buffer, field[0], *field[2:])
|
|
|
|
|
|
- p = subprocess.Popen(
|
|
|
+ proc = subprocess.Popen(
|
|
|
['openssl', 'rsa', '-modulus', '-in', args['key'], '-noout'],
|
|
|
stdout=subprocess.PIPE)
|
|
|
- modulus_out = p.communicate()[0]
|
|
|
- modulus = bytes.fromhex(modulus_out[8:8+SE_KEY_SIZE*2].decode())
|
|
|
+ modulus_out, _ = proc.communicate()
|
|
|
+ modulus = bytes.fromhex(modulus_out[8:8+offs.SE_KEY_SIZE*2].decode())
|
|
|
modulus = bytes(reversed(modulus))
|
|
|
|
|
|
- p = subprocess.Popen(
|
|
|
+ proc = subprocess.Popen(
|
|
|
['openssl', 'sha256', '-binary', '-sign', args['key']],
|
|
|
stdin=subprocess.PIPE, stdout=subprocess.PIPE)
|
|
|
- signature = p.communicate(sign_buffer)[0]
|
|
|
+ signature, _ = proc.communicate(sign_buffer)
|
|
|
signature = signature[::-1]
|
|
|
|
|
|
modulus_int = int.from_bytes(modulus, byteorder='little')
|
|
@@ -702,19 +713,19 @@ def generate_sigstruct(attr, args, mrenclave):
|
|
|
tmp2 = tmp1 % modulus_int
|
|
|
q2_int = tmp2 * signature_int // modulus_int
|
|
|
|
|
|
- q1 = q1_int.to_bytes(384, byteorder='little')
|
|
|
- q2 = q2_int.to_bytes(384, byteorder='little')
|
|
|
+ q1 = q1_int.to_bytes(384, byteorder='little') # pylint: disable=invalid-name
|
|
|
+ q2 = q2_int.to_bytes(384, byteorder='little') # pylint: disable=invalid-name
|
|
|
|
|
|
fields.update({
|
|
|
- 'modulus': (SGX_ARCH_ENCLAVE_CSS_MODULUS, "384s", modulus),
|
|
|
- 'exponent': (SGX_ARCH_ENCLAVE_CSS_EXPONENT, "<L", 3),
|
|
|
- 'signature': (SGX_ARCH_ENCLAVE_CSS_SIGNATURE, "384s", signature),
|
|
|
+ 'modulus': (offs.SGX_ARCH_ENCLAVE_CSS_MODULUS, "384s", modulus),
|
|
|
+ 'exponent': (offs.SGX_ARCH_ENCLAVE_CSS_EXPONENT, "<L", 3),
|
|
|
+ 'signature': (offs.SGX_ARCH_ENCLAVE_CSS_SIGNATURE, "384s", signature),
|
|
|
|
|
|
- 'q1': (SGX_ARCH_ENCLAVE_CSS_Q1, "384s", q1),
|
|
|
- 'q2': (SGX_ARCH_ENCLAVE_CSS_Q2, "384s", q2),
|
|
|
+ 'q1': (offs.SGX_ARCH_ENCLAVE_CSS_Q1, "384s", q1),
|
|
|
+ 'q2': (offs.SGX_ARCH_ENCLAVE_CSS_Q2, "384s", q2),
|
|
|
})
|
|
|
|
|
|
- buffer = bytearray(SGX_ARCH_ENCLAVE_CSS_SIZE)
|
|
|
+ buffer = bytearray(offs.SGX_ARCH_ENCLAVE_CSS_SIZE)
|
|
|
|
|
|
for field in fields.values():
|
|
|
struct.pack_into(field[1], buffer, field[0], *field[2:])
|
|
@@ -772,7 +783,8 @@ def parse_args(args):
|
|
|
|
|
|
|
|
|
def main_sign(args):
|
|
|
- (manifest, manifest_layout) = read_manifest(args['manifest'])
|
|
|
+ # pylint: disable=too-many-statements,too-many-branches,too-many-locals
|
|
|
+ manifest, manifest_layout = read_manifest(args['manifest'])
|
|
|
|
|
|
if exec_sig_manifest(args, manifest) != 0:
|
|
|
return 1
|
|
@@ -780,8 +792,7 @@ def main_sign(args):
|
|
|
# Get attributes from manifest
|
|
|
attr = dict()
|
|
|
|
|
|
- def parse_int(s):
|
|
|
- return int(s, 0)
|
|
|
+ parse_int = functools.partial(int, base=0)
|
|
|
|
|
|
for key, default, parse, attr_key in [
|
|
|
('enclave_size', DEFAULT_ENCLAVE_SIZE, parse_size, 'enclave_size'),
|
|
@@ -848,8 +859,8 @@ def main_sign(args):
|
|
|
if any([a.addr is not None for a in memory_areas]):
|
|
|
manifest['sgx.static_address'] = '1'
|
|
|
else:
|
|
|
- global enclave_heap_min
|
|
|
- enclave_heap_min = 0
|
|
|
+ global ENCLAVE_HEAP_MIN # pylint: disable=global-statement
|
|
|
+ ENCLAVE_HEAP_MIN = 0
|
|
|
manifest['sgx.static_address'] = '0'
|
|
|
|
|
|
if manifest.get('sgx.allow_file_creation', None) is None:
|
|
@@ -892,14 +903,14 @@ def make_depend(args):
|
|
|
do_checksum=False).values():
|
|
|
dependencies.add(filename[1])
|
|
|
|
|
|
- with open(output, 'w') as f:
|
|
|
+ with open(output, 'w') as file:
|
|
|
manifest_sgx = output
|
|
|
if manifest_sgx.endswith('.d'):
|
|
|
manifest_sgx = manifest_sgx[:-len('.d')]
|
|
|
- f.write('%s %s:' % (manifest_sgx, args['sigfile']))
|
|
|
+ file.write('%s %s:' % (manifest_sgx, args['sigfile']))
|
|
|
for filename in dependencies:
|
|
|
- f.write(' \\\n\t%s' % filename)
|
|
|
- f.write('\n')
|
|
|
+ file.write(' \\\n\t%s' % filename)
|
|
|
+ file.write('\n')
|
|
|
|
|
|
return 0
|
|
|
|