|
@@ -1,19 +1,19 @@
|
|
|
-#!/usr/bin/env python2
|
|
|
+#!/usr/bin/env python3
|
|
|
|
|
|
-import os
|
|
|
-import sys
|
|
|
-import re
|
|
|
+import argparse
|
|
|
import datetime
|
|
|
-import struct
|
|
|
-import subprocess
|
|
|
import hashlib
|
|
|
-import binascii
|
|
|
+import os
|
|
|
import shutil
|
|
|
+import struct
|
|
|
+import subprocess
|
|
|
+import sys
|
|
|
|
|
|
sys.path.insert(0, os.path.dirname(os.path.dirname(__file__)))
|
|
|
from generated_offsets import *
|
|
|
|
|
|
-""" Default / Architectural Options """
|
|
|
+
|
|
|
+# Default / Architectural Options
|
|
|
|
|
|
ARCHITECTURE = "amd64"
|
|
|
|
|
@@ -23,44 +23,22 @@ DEFAULT_ENCLAVE_SIZE = '256M'
|
|
|
DEFAULT_THREAD_NUM = 4
|
|
|
enclave_heap_min = DEFAULT_HEAP_MIN
|
|
|
|
|
|
-""" Utilities """
|
|
|
|
|
|
-ZERO_PAGE = "\0" * PAGESIZE
|
|
|
+# Utilities
|
|
|
+
|
|
|
+ZERO_PAGE = bytes(PAGESIZE)
|
|
|
+
|
|
|
|
|
|
def roundup(addr):
|
|
|
remaining = addr % PAGESIZE
|
|
|
if remaining:
|
|
|
return addr + (PAGESIZE - remaining)
|
|
|
- else:
|
|
|
- return addr
|
|
|
+ return addr
|
|
|
+
|
|
|
|
|
|
def rounddown(addr):
|
|
|
return addr - addr % PAGESIZE
|
|
|
|
|
|
-def roundup_data(data):
|
|
|
- return data + '\0' * (roundup(len(data)) - len(data))
|
|
|
-
|
|
|
-def int_to_bytes(i):
|
|
|
- b = ""
|
|
|
- l = 0
|
|
|
- while i > 0:
|
|
|
- b = b + chr(i % 256)
|
|
|
- i = i // 256
|
|
|
- l = l + 1
|
|
|
- return b
|
|
|
-
|
|
|
-def bytes_to_int(b):
|
|
|
- i = 0
|
|
|
- for c in b:
|
|
|
- i = i * 256 + ord(c)
|
|
|
- return i
|
|
|
-
|
|
|
-def parse_int(s):
|
|
|
- if len(s) > 2 and s.startswith("0x"):
|
|
|
- return int(s[2:], 16)
|
|
|
- if len(s) > 1 and s.startswith("0"):
|
|
|
- return int(s[1:], 8)
|
|
|
- return int(s)
|
|
|
|
|
|
def parse_size(s):
|
|
|
scale = 1
|
|
@@ -72,10 +50,10 @@ def parse_size(s):
|
|
|
scale = 1024 * 1024 * 1024
|
|
|
if scale != 1:
|
|
|
s = s[:-1]
|
|
|
- return parse_int(s) * scale
|
|
|
+ return int(s, 0) * scale
|
|
|
|
|
|
|
|
|
-""" Reading / Writing Manifests """
|
|
|
+# Reading / Writing Manifests
|
|
|
|
|
|
def read_manifest(filename):
|
|
|
manifest = dict()
|
|
@@ -105,6 +83,7 @@ def read_manifest(filename):
|
|
|
|
|
|
return (manifest, manifest_layout)
|
|
|
|
|
|
+
|
|
|
def output_manifest(filename, manifest, manifest_layout):
|
|
|
with open(filename, 'w') as f:
|
|
|
written = []
|
|
@@ -118,34 +97,35 @@ def output_manifest(filename, manifest, manifest_layout):
|
|
|
if line != '':
|
|
|
line += ' '
|
|
|
line += comment
|
|
|
- print >>f, line
|
|
|
+ f.write(line)
|
|
|
+ f.write('\n')
|
|
|
|
|
|
- print >>f
|
|
|
- print >>f, "# Generated by Graphene"
|
|
|
- print >>f
|
|
|
+ f.write('\n')
|
|
|
+ f.write("# Generated by Graphene\n")
|
|
|
+ f.write('\n')
|
|
|
|
|
|
- for key in sorted(manifest.keys()):
|
|
|
+ for key in sorted(manifest):
|
|
|
if key not in written:
|
|
|
- print >>f, key, '=', manifest[key]
|
|
|
+ f.write("%s = %s\n" % (key, manifest[key]))
|
|
|
|
|
|
|
|
|
-""" Loading Enclave Attributes """
|
|
|
+# 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", SGX_FLAGS_DEBUG),
|
|
|
+ 'FLAG_MODE64BIT': struct.pack("<Q", 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", 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),
|
|
|
}
|
|
|
|
|
|
sgx_miscs = {
|
|
|
- 'MISC_EXINFO' : struct.pack("<L", SGX_MISCSELECT_EXINFO),
|
|
|
+ 'MISC_EXINFO': struct.pack("<L", SGX_MISCSELECT_EXINFO),
|
|
|
}
|
|
|
|
|
|
default_attributes = {
|
|
@@ -166,7 +146,7 @@ def get_enclave_attributes(manifest):
|
|
|
|
|
|
attributes = default_attributes
|
|
|
|
|
|
- for opt in manifest_options.keys():
|
|
|
+ for opt in manifest_options:
|
|
|
key = 'sgx.' + opt
|
|
|
if key in manifest:
|
|
|
if manifest[key] == '1':
|
|
@@ -180,16 +160,19 @@ def get_enclave_attributes(manifest):
|
|
|
|
|
|
for attr in attributes:
|
|
|
if attr in sgx_flags:
|
|
|
- flags_raw = ''.join([chr(ord(a)|ord(b)) for a, b in zip(flags_raw, sgx_flags[attr])])
|
|
|
+ flags_raw = bytes([a | b for a, b in
|
|
|
+ zip(flags_raw, sgx_flags[attr])])
|
|
|
if attr in sgx_xfrms:
|
|
|
- xfrms_raw = ''.join([chr(ord(a)|ord(b)) for a, b in zip(xfrms_raw, sgx_xfrms[attr])])
|
|
|
+ xfrms_raw = bytes([a | b for a, b in
|
|
|
+ zip(xfrms_raw, sgx_xfrms[attr])])
|
|
|
if attr in sgx_miscs:
|
|
|
- miscs_raw = ''.join([chr(ord(a)|ord(b)) for a, b in zip(miscs_raw, sgx_miscs[attr])])
|
|
|
+ miscs_raw = bytes([a | b for a, b in
|
|
|
+ zip(miscs_raw, sgx_miscs[attr])])
|
|
|
|
|
|
return flags_raw, xfrms_raw, miscs_raw
|
|
|
|
|
|
|
|
|
-""" Generate Checksums / Measurement """
|
|
|
+# Generate Checksums / Measurement
|
|
|
|
|
|
def resolve_uri(uri, check_exist=True):
|
|
|
orig_uri = uri
|
|
@@ -198,15 +181,18 @@ def resolve_uri(uri, check_exist=True):
|
|
|
else:
|
|
|
target = os.path.normpath(uri)
|
|
|
if check_exist and not os.path.exists(target):
|
|
|
- raise Exception('Cannot resolve ' + orig_uri + ' or the file does not exist.')
|
|
|
+ raise Exception(
|
|
|
+ 'Cannot resolve ' + orig_uri + ' or the file does not exist.')
|
|
|
return target
|
|
|
|
|
|
+
|
|
|
def get_checksum(file):
|
|
|
digest = hashlib.sha256()
|
|
|
with open(file, 'rb') as f:
|
|
|
digest.update(f.read())
|
|
|
return digest.digest()
|
|
|
|
|
|
+
|
|
|
def get_trusted_files(manifest, args):
|
|
|
targets = dict()
|
|
|
|
|
@@ -226,17 +212,19 @@ def get_trusted_files(manifest, args):
|
|
|
continue
|
|
|
key = key[len('sgx.trusted_files.'):]
|
|
|
if key in targets:
|
|
|
- raise Exception('repeated key in manifest: sgx.trusted_files.' + key)
|
|
|
+ raise Exception(
|
|
|
+ 'repeated key in manifest: sgx.trusted_files.' + key)
|
|
|
targets[key] = (val, resolve_uri(val))
|
|
|
|
|
|
for (key, val) in targets.items():
|
|
|
(uri, target) = val
|
|
|
- checksum = get_checksum(target).encode('hex')
|
|
|
+ checksum = get_checksum(target).hex()
|
|
|
targets[key] = (uri, target, checksum)
|
|
|
|
|
|
return targets
|
|
|
|
|
|
-def get_trusted_children(manifest, args):
|
|
|
+
|
|
|
+def get_trusted_children(manifest):
|
|
|
targets = dict()
|
|
|
|
|
|
for (key, val) in manifest.items():
|
|
@@ -244,17 +232,21 @@ def get_trusted_children(manifest, args):
|
|
|
continue
|
|
|
key = key[len('sgx.trusted_children.'):]
|
|
|
if key in targets:
|
|
|
- raise Exception('repeated key in manifest: sgx.trusted_children.' + key)
|
|
|
+ raise Exception(
|
|
|
+ 'repeated key in manifest: sgx.trusted_children.' + key)
|
|
|
|
|
|
target = resolve_uri(val)
|
|
|
if not target.endswith('.sig'):
|
|
|
target += '.sig'
|
|
|
- sig = open(target, 'rb').read()[960:992].encode('hex')
|
|
|
+ sig = open(target, 'rb').read()[
|
|
|
+ SGX_ARCH_SIGSTRUCT_ENCLAVE_HASH:
|
|
|
+ SGX_ARCH_SIGSTRUCT_ENCLAVE_HASH + SGX_ARCH_HASH_SIZE].hex()
|
|
|
targets[key] = (val, target, sig)
|
|
|
|
|
|
return targets
|
|
|
|
|
|
-""" Populate Enclave Memory """
|
|
|
+
|
|
|
+# Populate Enclave Memory
|
|
|
|
|
|
PAGEINFO_R = 0x1
|
|
|
PAGEINFO_W = 0x2
|
|
@@ -262,15 +254,16 @@ PAGEINFO_X = 0x4
|
|
|
PAGEINFO_TCS = 0x100
|
|
|
PAGEINFO_REG = 0x200
|
|
|
|
|
|
+
|
|
|
def get_loadcmds(filename):
|
|
|
loadcmds = []
|
|
|
p = subprocess.Popen(['readelf', '-l', '-W', filename],
|
|
|
- stdout=subprocess.PIPE,
|
|
|
- stderr=subprocess.PIPE)
|
|
|
+ stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
|
|
while True:
|
|
|
line = p.stdout.readline()
|
|
|
- if line == '':
|
|
|
+ if not line:
|
|
|
break
|
|
|
+ line = line.decode()
|
|
|
stripped = line.strip()
|
|
|
if not stripped.startswith('LOAD'):
|
|
|
continue
|
|
@@ -298,8 +291,10 @@ def get_loadcmds(filename):
|
|
|
return None
|
|
|
return loadcmds
|
|
|
|
|
|
+
|
|
|
class MemoryArea:
|
|
|
- def __init__(self, desc, file=None, content=None, addr=None, size=None, flags=None, measure=True):
|
|
|
+ def __init__(self, desc, file=None, content=None, addr=None, size=None,
|
|
|
+ flags=None, measure=True):
|
|
|
self.desc = desc
|
|
|
self.file = file
|
|
|
self.content = content
|
|
@@ -314,11 +309,11 @@ class MemoryArea:
|
|
|
if loadcmds:
|
|
|
mapaddr = 0xffffffffffffffff
|
|
|
mapaddr_end = 0
|
|
|
- for (offset, addr, filesize, memsize, prot) in loadcmds:
|
|
|
- if rounddown(addr) < mapaddr:
|
|
|
- mapaddr = rounddown(addr)
|
|
|
- if roundup(addr + memsize) > mapaddr_end:
|
|
|
- mapaddr_end = roundup(addr + memsize)
|
|
|
+ for (_, addr_, _, memsize, _) in loadcmds:
|
|
|
+ if rounddown(addr_) < mapaddr:
|
|
|
+ mapaddr = rounddown(addr_)
|
|
|
+ if roundup(addr_ + memsize) > mapaddr_end:
|
|
|
+ mapaddr_end = roundup(addr_ + memsize)
|
|
|
|
|
|
self.is_binary = True
|
|
|
self.size = mapaddr_end - mapaddr
|
|
@@ -332,54 +327,64 @@ class MemoryArea:
|
|
|
if self.size is not None:
|
|
|
self.size = roundup(self.size)
|
|
|
|
|
|
-def get_memory_areas(manifest, attr, args):
|
|
|
+
|
|
|
+def get_memory_areas(attr, args):
|
|
|
areas = []
|
|
|
- areas.append(MemoryArea('ssa', size=attr['thread_num'] * SSAFRAMESIZE * SSAFRAMENUM,
|
|
|
- flags=PAGEINFO_R|PAGEINFO_W|PAGEINFO_REG))
|
|
|
+ areas.append(
|
|
|
+ MemoryArea('ssa',
|
|
|
+ size=attr['thread_num'] * SSAFRAMESIZE * SSAFRAMENUM,
|
|
|
+ flags=PAGEINFO_R | PAGEINFO_W | PAGEINFO_REG))
|
|
|
areas.append(MemoryArea('tcs', size=attr['thread_num'] * TCS_SIZE,
|
|
|
flags=PAGEINFO_TCS))
|
|
|
areas.append(MemoryArea('tls', size=attr['thread_num'] * PAGESIZE,
|
|
|
- flags=PAGEINFO_R|PAGEINFO_W|PAGEINFO_REG))
|
|
|
+ flags=PAGEINFO_R | PAGEINFO_W | PAGEINFO_REG))
|
|
|
|
|
|
- for t in range(attr['thread_num']):
|
|
|
+ for _ in range(attr['thread_num']):
|
|
|
areas.append(MemoryArea('stack', size=ENCLAVE_STACK_SIZE,
|
|
|
- flags=PAGEINFO_R|PAGEINFO_W|PAGEINFO_REG))
|
|
|
+ flags=PAGEINFO_R | PAGEINFO_W | PAGEINFO_REG))
|
|
|
|
|
|
areas.append(MemoryArea('pal', file=args['libpal'], flags=PAGEINFO_REG))
|
|
|
|
|
|
if 'exec' in args:
|
|
|
areas.append(MemoryArea('exec', file=args['exec'],
|
|
|
- flags=PAGEINFO_W|PAGEINFO_REG))
|
|
|
+ flags=PAGEINFO_W | PAGEINFO_REG))
|
|
|
return areas
|
|
|
|
|
|
+
|
|
|
def find_areas(areas, desc):
|
|
|
- return filter(lambda area: area.desc == desc, areas)
|
|
|
+ return [area for area in areas if area.desc == desc]
|
|
|
+
|
|
|
|
|
|
def find_area(areas, desc, allow_none=False):
|
|
|
matching = find_areas(areas, desc)
|
|
|
|
|
|
- if len(matching) == 0 and allow_none:
|
|
|
+ if not matching and allow_none:
|
|
|
return None
|
|
|
|
|
|
if len(matching) != 1:
|
|
|
- raise KeyError("Could not find exactly one MemoryArea '{}'".format(desc))
|
|
|
+ raise KeyError(
|
|
|
+ "Could not find exactly one MemoryArea '{}'".format(desc))
|
|
|
|
|
|
return matching[0]
|
|
|
|
|
|
+
|
|
|
def entry_point(elf_path):
|
|
|
env = os.environ
|
|
|
env['LC_ALL'] = 'C'
|
|
|
- out = subprocess.check_output(['readelf', '-l', '--', elf_path], env = env)
|
|
|
+ out = subprocess.check_output(
|
|
|
+ ['readelf', '-l', '--', elf_path], env=env)
|
|
|
for line in out.splitlines():
|
|
|
+ line = line.decode()
|
|
|
if line.startswith("Entry point "):
|
|
|
- return parse_int(line[12:])
|
|
|
+ return int(line[12:], 0)
|
|
|
raise ValueError("Could not find entry point of elf file")
|
|
|
|
|
|
+
|
|
|
def baseaddr():
|
|
|
if enclave_heap_min == 0:
|
|
|
return ENCLAVE_HIGH_ADDRESS
|
|
|
- else:
|
|
|
- return 0
|
|
|
+ return 0
|
|
|
+
|
|
|
|
|
|
def gen_area_content(attr, areas):
|
|
|
manifest_area = find_area(areas, 'manifest')
|
|
@@ -391,10 +396,12 @@ def gen_area_content(attr, areas):
|
|
|
stacks = find_areas(areas, 'stack')
|
|
|
|
|
|
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)
|
|
|
|
|
|
tls_data = bytearray(tls_area.size)
|
|
|
+
|
|
|
def set_tls_field(t, offset, value):
|
|
|
struct.pack_into('<Q', tls_data, t * PAGESIZE + offset, value)
|
|
|
|
|
@@ -403,29 +410,35 @@ def gen_area_content(attr, areas):
|
|
|
# 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 area.addr >= enclave_heap_max or area is exec_area:
|
|
|
+ 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, is not measured")
|
|
|
+ raise ValueError("Memory area, which is not the heap, "
|
|
|
+ "is not measured")
|
|
|
elif area.desc != 'free':
|
|
|
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 * 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', pal_area.addr + entry_point(pal_area.file))
|
|
|
+ set_tcs_field(t, TCS_OENTRY, '<Q',
|
|
|
+ pal_area.addr + entry_point(pal_area.file))
|
|
|
set_tcs_field(t, TCS_OGSBASGX, '<Q', tls_area.addr + PAGESIZE * t)
|
|
|
set_tcs_field(t, TCS_FSLIMIT, '<L', 0xfff)
|
|
|
set_tcs_field(t, TCS_GSLIMIT, '<L', 0xfff)
|
|
|
|
|
|
- set_tls_field(t, SGX_COMMON_SELF, tls_area.addr + PAGESIZE * t + baseaddr())
|
|
|
+ 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, stacks[t].addr + stacks[t].size)
|
|
|
+ set_tls_field(t, 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, os.stat(manifest_area.file).st_size)
|
|
|
+ set_tls_field(t, 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)
|
|
|
if exec_area is not None:
|
|
@@ -435,7 +448,8 @@ def gen_area_content(attr, areas):
|
|
|
tcs_area.content = tcs_data
|
|
|
tls_area.content = tls_data
|
|
|
|
|
|
-def populate_memory_areas(manifest, attr, areas):
|
|
|
+
|
|
|
+def populate_memory_areas(attr, areas):
|
|
|
populating = attr['enclave_size']
|
|
|
|
|
|
for area in areas:
|
|
@@ -446,7 +460,7 @@ def populate_memory_areas(manifest, attr, areas):
|
|
|
if area.addr < enclave_heap_min:
|
|
|
raise Exception("Enclave size is not large enough")
|
|
|
if area.desc == 'exec':
|
|
|
- populating = area.addr;
|
|
|
+ populating = area.addr
|
|
|
else:
|
|
|
populating = area.addr - MEMORY_GAP
|
|
|
|
|
@@ -454,36 +468,40 @@ def populate_memory_areas(manifest, attr, areas):
|
|
|
for area in areas:
|
|
|
if area.addr + area.size < populating:
|
|
|
addr = area.addr + area.size
|
|
|
- free_areas.append(MemoryArea('free', addr=addr, size=populating - addr,
|
|
|
- flags=PAGEINFO_R|PAGEINFO_W|PAGEINFO_X|PAGEINFO_REG,
|
|
|
- measure=False))
|
|
|
+ flags = PAGEINFO_R | PAGEINFO_W | PAGEINFO_X | PAGEINFO_REG
|
|
|
+ free_areas.append(
|
|
|
+ MemoryArea('free', addr=addr, size=populating - addr,
|
|
|
+ flags=flags, measure=False))
|
|
|
populating = area.addr
|
|
|
|
|
|
if populating > enclave_heap_min:
|
|
|
- free_areas.append(MemoryArea('free', addr=enclave_heap_min,
|
|
|
- size=populating - enclave_heap_min,
|
|
|
- flags=PAGEINFO_R|PAGEINFO_W|PAGEINFO_X|PAGEINFO_REG,
|
|
|
- measure=False))
|
|
|
+ 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,
|
|
|
+ measure=False))
|
|
|
|
|
|
gen_area_content(attr, areas)
|
|
|
|
|
|
return areas + free_areas
|
|
|
|
|
|
+
|
|
|
def generate_measurement(attr, areas):
|
|
|
|
|
|
def do_ecreate(digest, size):
|
|
|
- data = struct.pack("<8sLQ44s", "ECREATE", SSAFRAMESIZE / PAGESIZE, size, "")
|
|
|
+ data = struct.pack("<8sLQ44s", b"ECREATE", SSAFRAMESIZE // PAGESIZE,
|
|
|
+ size, b"")
|
|
|
digest.update(data)
|
|
|
|
|
|
def do_eadd(digest, offset, flags):
|
|
|
- data = struct.pack("<8sQQ40s", "EADD", offset, flags, "")
|
|
|
+ data = struct.pack("<8sQQ40s", b"EADD", offset, flags, b"")
|
|
|
digest.update(data)
|
|
|
|
|
|
def do_eextend(digest, offset, content):
|
|
|
if len(content) != 256:
|
|
|
raise ValueError("Exactly 256 bytes expected")
|
|
|
|
|
|
- data = struct.pack("<8sQ48s", "EEXTEND", offset, "")
|
|
|
+ data = struct.pack("<8sQ48s", b"EEXTEND", offset, b"")
|
|
|
digest.update(data)
|
|
|
digest.update(content)
|
|
|
|
|
@@ -501,9 +519,9 @@ def generate_measurement(attr, areas):
|
|
|
|
|
|
def print_area(addr, size, flags, desc, measured):
|
|
|
if flags & PAGEINFO_REG:
|
|
|
- type = 'REG'
|
|
|
+ type_ = 'REG'
|
|
|
if flags & PAGEINFO_TCS:
|
|
|
- type = 'TCS'
|
|
|
+ type_ = 'TCS'
|
|
|
prot = ['-', '-', '-']
|
|
|
if flags & PAGEINFO_R:
|
|
|
prot[0] = 'R'
|
|
@@ -518,14 +536,14 @@ def generate_measurement(attr, areas):
|
|
|
desc += ' measured'
|
|
|
|
|
|
if size == PAGESIZE:
|
|
|
- print >>sys.stderr, " %016x [%s:%s] %s" % (addr, type, prot, desc)
|
|
|
+ print(" %016x [%s:%s] %s" % (addr, type_, prot, desc))
|
|
|
else:
|
|
|
- print >>sys.stderr, " %016x-%016lx [%s:%s] %s" % (addr, addr + size, type, prot, desc)
|
|
|
+ print(" %016x-%016lx [%s:%s] %s" %
|
|
|
+ (addr, addr + size, type_, prot, desc))
|
|
|
|
|
|
def load_file(digest, f, offset, addr, filesize, memsize, desc, flags):
|
|
|
f_addr = rounddown(offset)
|
|
|
m_addr = rounddown(addr)
|
|
|
- f_size = roundup(offset + filesize) - f_addr
|
|
|
m_size = roundup(addr + memsize) - m_addr
|
|
|
|
|
|
print_area(m_addr, m_size, flags, desc, True)
|
|
@@ -533,27 +551,27 @@ def generate_measurement(attr, areas):
|
|
|
for pg in range(m_addr, m_addr + m_size, PAGESIZE):
|
|
|
start = pg - m_addr + f_addr
|
|
|
end = start + PAGESIZE
|
|
|
- start_zero = ""
|
|
|
+ start_zero = b""
|
|
|
if start < offset:
|
|
|
if offset - start >= PAGESIZE:
|
|
|
start_zero = ZERO_PAGE
|
|
|
else:
|
|
|
- start_zero = chr(0) * (offset - start)
|
|
|
- end_zero = ""
|
|
|
+ start_zero = bytes(offset - start)
|
|
|
+ end_zero = b""
|
|
|
if end > offset + filesize:
|
|
|
if end - offset - filesize >= PAGESIZE:
|
|
|
end_zero = ZERO_PAGE
|
|
|
else:
|
|
|
- end_zero = chr(0) * (end - offset - filesize)
|
|
|
+ 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)
|
|
|
else:
|
|
|
- data = ""
|
|
|
+ data = b""
|
|
|
if len(start_zero + data + end_zero) != PAGESIZE:
|
|
|
- raise Exception("wrong calculation")
|
|
|
+ raise Exception("wrong calculation")
|
|
|
|
|
|
include_page(digest, pg, flags, start_zero + data + end_zero, True)
|
|
|
|
|
@@ -564,10 +582,11 @@ def generate_measurement(attr, areas):
|
|
|
loadcmds = get_loadcmds(area.file)
|
|
|
if loadcmds:
|
|
|
mapaddr = 0xffffffffffffffff
|
|
|
- for (offset, addr, filesize, memsize, prot) in loadcmds:
|
|
|
+ for (offset, addr, filesize, memsize,
|
|
|
+ prot) in loadcmds:
|
|
|
if rounddown(addr) < mapaddr:
|
|
|
mapaddr = rounddown(addr)
|
|
|
- baseaddr = area.addr - mapaddr
|
|
|
+ baseaddr_ = area.addr - mapaddr
|
|
|
for (offset, addr, filesize, memsize, prot) in loadcmds:
|
|
|
flags = area.flags
|
|
|
if prot & 4:
|
|
@@ -581,7 +600,7 @@ def generate_measurement(attr, areas):
|
|
|
desc = 'code'
|
|
|
else:
|
|
|
desc = 'data'
|
|
|
- load_file(mrenclave, f, offset, baseaddr + addr,
|
|
|
+ load_file(mrenclave, f, offset, baseaddr_ + addr,
|
|
|
filesize, memsize, desc, flags)
|
|
|
else:
|
|
|
load_file(mrenclave, f, 0, area.addr,
|
|
@@ -597,177 +616,128 @@ def generate_measurement(attr, areas):
|
|
|
|
|
|
include_page(mrenclave, a, area.flags, data, area.measure)
|
|
|
|
|
|
- print_area(area.addr, area.size, area.flags, area.desc, area.measure)
|
|
|
+ print_area(area.addr, area.size, area.flags, area.desc,
|
|
|
+ area.measure)
|
|
|
|
|
|
return mrenclave.digest()
|
|
|
|
|
|
-""" Generate Sigstruct """
|
|
|
|
|
|
def generate_sigstruct(attr, args, mrenclave):
|
|
|
+ """Generate Sigstruct."""
|
|
|
today = datetime.date.today()
|
|
|
|
|
|
# field format: (offset, type, value)
|
|
|
- fields = dict()
|
|
|
-
|
|
|
- fields['header'] = (SGX_ARCH_SIGSTRUCT_HEADER,
|
|
|
- "<4L", 0x00000006, 0x000000e1, 0x00010000, 0x00000000)
|
|
|
- fields['vendor'] = (SGX_ARCH_SIGSTRUCT_VENDOR,
|
|
|
- "<L", 0x00000000)
|
|
|
- fields['date'] = (SGX_ARCH_SIGSTRUCT_DATE,
|
|
|
- "<HBB", today.year, today.month, today.day)
|
|
|
- fields['header2'] = (SGX_ARCH_SIGSTRUCT_HEADER2,
|
|
|
- "<4L", 0x00000101, 0x00000060, 0x00000060, 0x00000001)
|
|
|
- fields['swdefined'] = (SGX_ARCH_SIGSTRUCT_SWDEFINED,
|
|
|
- "<L", 0x00000000)
|
|
|
-
|
|
|
- fields['miscs'] = (SGX_ARCH_SIGSTRUCT_MISCSELECT,
|
|
|
- "4s", attr['miscs'])
|
|
|
- fields['miscmask'] = (SGX_ARCH_SIGSTRUCT_MISCSELECT_MASK,
|
|
|
- "4s", attr['miscs'])
|
|
|
- fields['attrs'] = (SGX_ARCH_SIGSTRUCT_ATTRIBUTES,
|
|
|
- "8s8s", attr['flags'], attr['xfrms'])
|
|
|
- fields['attrmask'] = (SGX_ARCH_SIGSTRUCT_ATTRIBUTES_MASK,
|
|
|
- "8s8s", attr['flags'], attr['xfrms'])
|
|
|
- fields['mrenclave'] = (SGX_ARCH_SIGSTRUCT_ENCLAVE_HASH,
|
|
|
- "32s", mrenclave)
|
|
|
- fields['isvprodid'] = (SGX_ARCH_SIGSTRUCT_ISVPRODID,
|
|
|
- "<H", attr['isvprodid'])
|
|
|
- fields['isvsvn'] = (SGX_ARCH_SIGSTRUCT_ISVSVN,
|
|
|
- "<H", attr['isvsvn'])
|
|
|
+ fields = {
|
|
|
+ 'header': (SGX_ARCH_SIGSTRUCT_HEADER,
|
|
|
+ "<4L", 0x00000006, 0x000000e1, 0x00010000, 0x00000000),
|
|
|
+ 'vendor': (SGX_ARCH_SIGSTRUCT_VENDOR, "<L", 0x00000000),
|
|
|
+ 'date': (SGX_ARCH_SIGSTRUCT_DATE,
|
|
|
+ "<HBB", today.year, today.month, today.day),
|
|
|
+ 'header2': (SGX_ARCH_SIGSTRUCT_HEADER2,
|
|
|
+ "<4L", 0x00000101, 0x00000060, 0x00000060, 0x00000001),
|
|
|
+ 'swdefined': (SGX_ARCH_SIGSTRUCT_SWDEFINED, "<L", 0x00000000),
|
|
|
+
|
|
|
+ 'miscs': (SGX_ARCH_SIGSTRUCT_MISCSELECT, "4s", attr['miscs']),
|
|
|
+ 'miscmask': (SGX_ARCH_SIGSTRUCT_MISCSELECT_MASK, "4s", attr['miscs']),
|
|
|
+ 'attrs': (SGX_ARCH_SIGSTRUCT_ATTRIBUTES,
|
|
|
+ "8s8s", attr['flags'], attr['xfrms']),
|
|
|
+ 'attrmask': (SGX_ARCH_SIGSTRUCT_ATTRIBUTES_MASK,
|
|
|
+ "8s8s", attr['flags'], attr['xfrms']),
|
|
|
+ 'mrenclave': (SGX_ARCH_SIGSTRUCT_ENCLAVE_HASH, "32s", mrenclave),
|
|
|
+ 'isvprodid': (SGX_ARCH_SIGSTRUCT_ISVPRODID, "<H", attr['isvprodid']),
|
|
|
+ 'isvsvn': (SGX_ARCH_SIGSTRUCT_ISVSVN, "<H", attr['isvsvn']),
|
|
|
+ }
|
|
|
|
|
|
sign_buffer = bytearray(128 + 128)
|
|
|
|
|
|
- for key, field in fields.items():
|
|
|
- if field[0] >= 900:
|
|
|
- struct.pack_into(field[1], sign_buffer, field[0] - 900 + 128, *field[2:])
|
|
|
+ for field in fields.values():
|
|
|
+ if field[0] >= SGX_ARCH_SIGSTRUCT_MISCSELECT:
|
|
|
+ struct.pack_into(field[1], sign_buffer,
|
|
|
+ field[0] - SGX_ARCH_SIGSTRUCT_MISCSELECT + 128,
|
|
|
+ *field[2:])
|
|
|
else:
|
|
|
struct.pack_into(field[1], sign_buffer, field[0], *field[2:])
|
|
|
|
|
|
- p = subprocess.Popen(['openssl', 'rsa', '-modulus', '-in', args['key'], '-noout'], stdout=subprocess.PIPE)
|
|
|
+ p = subprocess.Popen(
|
|
|
+ ['openssl', 'rsa', '-modulus', '-in', args['key'], '-noout'],
|
|
|
+ stdout=subprocess.PIPE)
|
|
|
modulus_out = p.communicate()[0]
|
|
|
- modulus = modulus_out[8:8+384*2].lower().decode('hex')
|
|
|
- modulus = modulus[::-1]
|
|
|
+ modulus = bytes.fromhex(modulus_out[8:8+SGX_ARCH_KEY_SIZE*2].decode())
|
|
|
+ modulus = bytes(reversed(modulus))
|
|
|
|
|
|
- p = subprocess.Popen(['openssl', 'sha256', '-binary', '-sign', args['key']],
|
|
|
- stdin=subprocess.PIPE, stdout=subprocess.PIPE)
|
|
|
+ p = subprocess.Popen(
|
|
|
+ ['openssl', 'sha256', '-binary', '-sign', args['key']],
|
|
|
+ stdin=subprocess.PIPE, stdout=subprocess.PIPE)
|
|
|
signature = p.communicate(sign_buffer)[0]
|
|
|
signature = signature[::-1]
|
|
|
|
|
|
- def bytes_to_int(bytes):
|
|
|
- i = 0
|
|
|
- q = 1
|
|
|
- for digit in bytes:
|
|
|
- if ord(digit) != 0:
|
|
|
- i = i + ord(digit) * q
|
|
|
- q = q * 256
|
|
|
- return i
|
|
|
-
|
|
|
- def int_to_bytes(i):
|
|
|
- b = ""
|
|
|
- l = 0
|
|
|
- while i > 0:
|
|
|
- b = b + chr(i % 256)
|
|
|
- i = i // 256
|
|
|
- l = l + 1
|
|
|
- return b
|
|
|
-
|
|
|
- modulus_int = bytes_to_int(modulus)
|
|
|
- signature_int = bytes_to_int(signature)
|
|
|
-
|
|
|
- tmp1 = signature_int * signature_int
|
|
|
+ modulus_int = int.from_bytes(modulus, byteorder='little')
|
|
|
+ signature_int = int.from_bytes(signature, byteorder='little')
|
|
|
+
|
|
|
+ tmp1 = signature_int * signature_int
|
|
|
q1_int = tmp1 // modulus_int
|
|
|
- tmp2 = tmp1 % modulus_int
|
|
|
+ tmp2 = tmp1 % modulus_int
|
|
|
q2_int = tmp2 * signature_int // modulus_int
|
|
|
|
|
|
- q1 = int_to_bytes(q1_int)
|
|
|
- q2 = int_to_bytes(q2_int)
|
|
|
+ q1 = q1_int.to_bytes(384, byteorder='little')
|
|
|
+ q2 = q2_int.to_bytes(384, byteorder='little')
|
|
|
|
|
|
- fields['modulus'] = (SGX_ARCH_SIGSTRUCT_MODULUS, "384s", modulus)
|
|
|
- fields['exponent'] = (SGX_ARCH_SIGSTRUCT_EXPONENT, "<L", 3)
|
|
|
- fields['signature'] = (SGX_ARCH_SIGSTRUCT_SIGNATURE, "384s", signature)
|
|
|
+ fields.update({
|
|
|
+ 'modulus': (SGX_ARCH_SIGSTRUCT_MODULUS, "384s", modulus),
|
|
|
+ 'exponent': (SGX_ARCH_SIGSTRUCT_EXPONENT, "<L", 3),
|
|
|
+ 'signature': (SGX_ARCH_SIGSTRUCT_SIGNATURE, "384s", signature),
|
|
|
|
|
|
- fields['q1'] = (SGX_ARCH_SIGSTRUCT_Q1, "384s", q1)
|
|
|
- fields['q2'] = (SGX_ARCH_SIGSTRUCT_Q2, "384s", q2)
|
|
|
+ 'q1': (SGX_ARCH_SIGSTRUCT_Q1, "384s", q1),
|
|
|
+ 'q2': (SGX_ARCH_SIGSTRUCT_Q2, "384s", q2),
|
|
|
+ })
|
|
|
|
|
|
buffer = bytearray(SGX_ARCH_SIGSTRUCT_SIZE)
|
|
|
|
|
|
- for key, field in fields.items():
|
|
|
+ for field in fields.values():
|
|
|
struct.pack_into(field[1], buffer, field[0], *field[2:])
|
|
|
|
|
|
return buffer
|
|
|
|
|
|
-""" Main Program """
|
|
|
-
|
|
|
-options = {
|
|
|
-# Option name : (Required Value)
|
|
|
- 'output': (True, 'output'),
|
|
|
- 'libpal': (True, 'libpal path'),
|
|
|
- 'key': (True, 'signing key'),
|
|
|
- 'manifest': (True, 'manifest'),
|
|
|
- 'exec': (False, 'executable'),
|
|
|
+# Main Program
|
|
|
+
|
|
|
+argparser = argparse.ArgumentParser()
|
|
|
+argparser.add_argument('--output', '-output', metavar='OUTPUT',
|
|
|
+ type=str, required=True,
|
|
|
+ help='Output .manifest.sgx file '
|
|
|
+ '(manifest augmented with autogenerated fields)')
|
|
|
+argparser.add_argument('--libpal', '-libpal', metavar='LIBPAL',
|
|
|
+ type=str, required=True,
|
|
|
+ help='Input libpal file '
|
|
|
+ '(required as part of the enclave measurement)')
|
|
|
+argparser.add_argument('--key', '-key', metavar='KEY',
|
|
|
+ type=str, required=True,
|
|
|
+ help='specify signing key(.pem) file')
|
|
|
+argparser.add_argument('--manifest', '-manifest', metavar='MANIFEST',
|
|
|
+ type=str, required=True,
|
|
|
+ help='Input .manifest file '
|
|
|
+ '(user-prepared manifest template)')
|
|
|
+argparser.add_argument('--exec', '-exec', metavar='EXEC',
|
|
|
+ type=str, required=False,
|
|
|
+ help='Input executable file '
|
|
|
+ '(required as part of the enclave measurement)')
|
|
|
+
|
|
|
+
|
|
|
+def parse_args(args):
|
|
|
+ args = argparser.parse_args(args)
|
|
|
+ args_dict = {
|
|
|
+ 'output': args.output,
|
|
|
+ 'libpal': args.libpal,
|
|
|
+ 'key': args.key,
|
|
|
+ 'manifest': args.manifest,
|
|
|
}
|
|
|
+ if args.exec is not None:
|
|
|
+ args_dict['exec'] = args.exec
|
|
|
|
|
|
-def usage():
|
|
|
- usage_message = 'USAGE: ' + sys.argv[0] + ' -help|-h'
|
|
|
-
|
|
|
- for opt, optval in options.items():
|
|
|
- if not optval[0]:
|
|
|
- usage_message += '['
|
|
|
- usage_message += '|-' + opt
|
|
|
- if optval[1]:
|
|
|
- usage_message += ' <' + optval[1] + '>'
|
|
|
- if not optval[0]:
|
|
|
- usage_message += ']'
|
|
|
-
|
|
|
- print >> sys.stderr, usage_message
|
|
|
- os._exit(-1)
|
|
|
-
|
|
|
-def parse_args():
|
|
|
- args = dict()
|
|
|
- for opt, optval in options.items():
|
|
|
- if not optval[1]:
|
|
|
- args[opt] = False
|
|
|
-
|
|
|
- i = 1
|
|
|
- while i < len(sys.argv):
|
|
|
- got = sys.argv[i]
|
|
|
-
|
|
|
- if got == '-help' or got == '-h':
|
|
|
- usage()
|
|
|
-
|
|
|
- invalid = True
|
|
|
- for opt, optval in options.items():
|
|
|
- if got != '-' + opt:
|
|
|
- continue
|
|
|
-
|
|
|
- if optval[1] is not None:
|
|
|
- i += 1
|
|
|
- if i == len(sys.argv):
|
|
|
- print >>sys.stderr, "Option %s needs a value." % (opt)
|
|
|
- usage()
|
|
|
- args[opt] = sys.argv[i]
|
|
|
- else:
|
|
|
- args[opt] = True
|
|
|
-
|
|
|
- invalid = False
|
|
|
- break
|
|
|
-
|
|
|
- if invalid:
|
|
|
- print >>sys.stderr, "Unknown option: %s." % (got[1:])
|
|
|
- usage()
|
|
|
- i += 1
|
|
|
+ return args_dict
|
|
|
|
|
|
- for opt, optval in options.items():
|
|
|
- if optval[0] and opt not in args:
|
|
|
- print >>sys.stderr, "Must specify %s <%s>." % (opt, optval[1])
|
|
|
- usage()
|
|
|
-
|
|
|
- return args
|
|
|
-
|
|
|
-if __name__ == "__main__":
|
|
|
|
|
|
- # Parse arguments
|
|
|
- args = parse_args()
|
|
|
+def main(args=None):
|
|
|
+ args = parse_args(args)
|
|
|
|
|
|
(manifest, manifest_layout) = read_manifest(args['manifest'])
|
|
|
|
|
@@ -775,10 +745,11 @@ if __name__ == "__main__":
|
|
|
if 'loader.exec' in manifest:
|
|
|
exec_url = manifest['loader.exec']
|
|
|
if exec_url[:5] != 'file:':
|
|
|
- print "executable must be a local file"
|
|
|
- os._exit(-1)
|
|
|
+ print("executable must be a local file", file=sys.stderr)
|
|
|
+ return -1
|
|
|
|
|
|
- args['exec'] = os.path.join(os.path.dirname(args['manifest']), exec_url[5:])
|
|
|
+ args['exec'] = os.path.join(os.path.dirname(args['manifest']),
|
|
|
+ exec_url[5:])
|
|
|
|
|
|
args['root'] = os.path.dirname(os.path.abspath(args['output']))
|
|
|
|
|
@@ -795,69 +766,69 @@ if __name__ == "__main__":
|
|
|
|
|
|
# Get attributes from manifest
|
|
|
attr = dict()
|
|
|
+ parse_int = lambda s: int(s, 0)
|
|
|
|
|
|
for key, default, parse in [
|
|
|
- ('enclave_size', DEFAULT_ENCLAVE_SIZE, parse_size),
|
|
|
- ('thread_num', str(DEFAULT_THREAD_NUM), parse_int),
|
|
|
- ('isvprodid', '0', parse_int),
|
|
|
- ('isvsvn', '0', parse_int),
|
|
|
+ ('enclave_size', DEFAULT_ENCLAVE_SIZE, parse_size),
|
|
|
+ ('thread_num', str(DEFAULT_THREAD_NUM), parse_int),
|
|
|
+ ('isvprodid', '0', parse_int),
|
|
|
+ ('isvsvn', '0', parse_int),
|
|
|
]:
|
|
|
- if 'sgx.' + key not in manifest:
|
|
|
- manifest['sgx.' + key] = default
|
|
|
- attr[key] = parse(manifest['sgx.' + key])
|
|
|
-
|
|
|
- (attr['flags'], attr['xfrms'], attr['miscs']) = get_enclave_attributes(manifest)
|
|
|
-
|
|
|
- print >>sys.stderr, "Attributes:"
|
|
|
- print >>sys.stderr, " size: %d" % (attr['enclave_size'])
|
|
|
- print >>sys.stderr, " threadnum: %d" % (attr['thread_num'])
|
|
|
- print >>sys.stderr, " isvprodid: %d" % (attr['isvprodid'])
|
|
|
- print >>sys.stderr, " isvsvn: %d" % (attr['isvsvn'])
|
|
|
- print >>sys.stderr, " flags: %016x" % (bytes_to_int(attr['flags']))
|
|
|
- print >>sys.stderr, " xfrms: %016x" % (bytes_to_int(attr['xfrms']))
|
|
|
- print >>sys.stderr, " miscs: %08x" % (bytes_to_int(attr['miscs']))
|
|
|
-
|
|
|
- # Check client info for remote attestation. Skip and warn if sgx.ra_client.spid is not provided.
|
|
|
- print >>sys.stderr, "Attestation:"
|
|
|
+ attr[key] = parse(manifest.setdefault('sgx.' + key, default))
|
|
|
+
|
|
|
+ (attr['flags'], attr['xfrms'], attr['miscs']) = get_enclave_attributes(
|
|
|
+ manifest)
|
|
|
+
|
|
|
+ print("Attributes:")
|
|
|
+ print(" size: %d" % attr['enclave_size'])
|
|
|
+ print(" threadnum: %d" % attr['thread_num'])
|
|
|
+ print(" isvprodid: %d" % attr['isvprodid'])
|
|
|
+ print(" isvsvn: %d" % attr['isvsvn'])
|
|
|
+ print(" flags: %016x" % int.from_bytes(attr['flags'],
|
|
|
+ byteorder='big'))
|
|
|
+ print(" xfrms: %016x" % int.from_bytes(attr['xfrms'],
|
|
|
+ byteorder='big'))
|
|
|
+ print(" miscs: %08x" % int.from_bytes(attr['miscs'],
|
|
|
+ byteorder='big'))
|
|
|
+
|
|
|
+ # Check client info for remote attestation (if sgx.ra_client.spid is provided)
|
|
|
+ print("Attestation:")
|
|
|
if 'sgx.ra_client_spid' in manifest and manifest['sgx.ra_client_spid']:
|
|
|
- print >>sys.stderr, " spid: " + manifest['sgx.ra_client_spid']
|
|
|
- need_client_info = False
|
|
|
- if 'sgx.ra_client_key' not in manifest or not manifest['sgx.ra_client_key']:
|
|
|
- print >>sys.stderr, " *** sgx.ra_client_key not specified ***"
|
|
|
- need_client_info = True
|
|
|
+ print(" spid: " + manifest['sgx.ra_client_spid'])
|
|
|
+ if 'sgx.ra_client_key' in manifest and manifest['sgx.ra_client_key']:
|
|
|
+ print(" key: " + manifest['sgx.ra_client_key'])
|
|
|
else:
|
|
|
- print >>sys.stderr, " key: " + manifest['sgx.ra_client_key']
|
|
|
+ print(" *** sgx.ra_client_key not specified ***")
|
|
|
+ return -1
|
|
|
if 'sgx.ra_client_linkable' in manifest:
|
|
|
- print >>sys.stderr, " linkable: " + manifest['sgx.ra_client_linkable']
|
|
|
+ print(" linkable: " + manifest['sgx.ra_client_linkable'])
|
|
|
else:
|
|
|
- print >>sys.stderr, " linkable: 0"
|
|
|
- if need_client_info: sys.exit(-1)
|
|
|
-
|
|
|
+ print(" linkable: 0")
|
|
|
else:
|
|
|
- print >>sys.stderr, " *** Client info is not specified. Graphene" + \
|
|
|
- " will not perform remote attestation before execution." + \
|
|
|
- " Please provide sgx.ra_client_spid and sgx.ra_client_key in the manifest. ***"
|
|
|
-
|
|
|
+ print(" *** Client info is not specified. Graphene will not perform"
|
|
|
+ " remote attestation before execution. Please provide"
|
|
|
+ " sgx.ra_client_spid and sgx.ra_client_key in the manifest. ***")
|
|
|
|
|
|
# Get trusted checksums and measurements
|
|
|
- print >>sys.stderr, "Trusted files:"
|
|
|
+ print("Trusted files:")
|
|
|
for key, val in get_trusted_files(manifest, args).items():
|
|
|
- (uri, target, checksum) = val
|
|
|
- print >>sys.stderr, " %s %s" % (checksum, uri)
|
|
|
+ (uri, _, checksum) = val
|
|
|
+ print(" %s %s" % (checksum, uri))
|
|
|
manifest['sgx.trusted_checksum.' + key] = checksum
|
|
|
|
|
|
- print >>sys.stderr, "Trusted children:"
|
|
|
- for key, val in get_trusted_children(manifest, args).items():
|
|
|
- (uri, target, mrenclave) = val
|
|
|
- print >>sys.stderr, " %s %s" % (mrenclave, uri)
|
|
|
+ print("Trusted children:")
|
|
|
+ for key, val in get_trusted_children(manifest).items():
|
|
|
+ (uri, _, mrenclave) = val
|
|
|
+ print(" %s %s" % (mrenclave, uri))
|
|
|
manifest['sgx.trusted_mrenclave.' + key] = mrenclave
|
|
|
|
|
|
# Try populate memory areas
|
|
|
- memory_areas = get_memory_areas(manifest, attr, args)
|
|
|
+ memory_areas = get_memory_areas(attr, args)
|
|
|
|
|
|
- if len([a for a in memory_areas if a.addr is not None]) > 0:
|
|
|
+ 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
|
|
|
|
|
|
# Add manifest at the top
|
|
@@ -865,18 +836,23 @@ if __name__ == "__main__":
|
|
|
output_manifest(args['output'], manifest, manifest_layout)
|
|
|
|
|
|
memory_areas = [
|
|
|
- MemoryArea('manifest', file=args['output'],
|
|
|
- flags=PAGEINFO_R|PAGEINFO_REG)
|
|
|
- ] + memory_areas
|
|
|
+ MemoryArea('manifest', file=args['output'],
|
|
|
+ flags=PAGEINFO_R | PAGEINFO_REG)
|
|
|
+ ] + memory_areas
|
|
|
|
|
|
- memory_areas = populate_memory_areas(manifest, attr, memory_areas)
|
|
|
+ memory_areas = populate_memory_areas(attr, memory_areas)
|
|
|
|
|
|
- print >>sys.stderr, "Memory:"
|
|
|
+ print("Memory:")
|
|
|
# Generate measurement
|
|
|
mrenclave = generate_measurement(attr, memory_areas)
|
|
|
-
|
|
|
- print >>sys.stderr, "Measurement:"
|
|
|
- print >>sys.stderr, " " + mrenclave.encode('hex')
|
|
|
+ print("Measurement:")
|
|
|
+ print(" %s" % mrenclave.hex())
|
|
|
|
|
|
# Generate sigstruct
|
|
|
- open(args['sigfile'], 'wb').write(generate_sigstruct(attr, args, mrenclave))
|
|
|
+ open(args['sigfile'], 'wb').write(
|
|
|
+ generate_sigstruct(attr, args, mrenclave))
|
|
|
+ return 0
|
|
|
+
|
|
|
+
|
|
|
+if __name__ == "__main__":
|
|
|
+ sys.exit(main())
|